Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structurally resolve before checking ! in HIR typeck #133518

Merged
merged 2 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// While we don't allow *arbitrary* coercions here, we *do* allow
// coercions from ! to `expected`.
if ty.is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) {
if self.try_structurally_resolve_type(expr.span, ty).is_never()
&& self.expr_guaranteed_to_constitute_read_for_never(expr)
{
if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
let reported = self.dcx().span_delayed_bug(
expr.span,
Expand Down Expand Up @@ -274,7 +276,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// unless it's a place expression that isn't being read from, in which case
// diverging would be unsound since we may never actually read the `!`.
// e.g. `let _ = *never_ptr;` with `never_ptr: *const !`.
if ty.is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) {
if self.try_structurally_resolve_type(expr.span, ty).is_never()
&& self.expr_guaranteed_to_constitute_read_for_never(expr)
{
self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ impl Foo for Def {
pub fn test<A: Foo, B: Foo>() {
let _array = [4; <A as Foo>::Y];
//~^ ERROR constant expression depends on a generic parameter
//~| ERROR constant expression depends on a generic parameter
}

fn main() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,13 @@ LL | let _array = [4; <A as Foo>::Y];
|
= note: this may fail depending on what value the parameter takes

error: aborting due to 1 previous error
error: constant expression depends on a generic parameter
--> $DIR/associated-const-type-parameter-arrays-2.rs:16:18
|
LL | let _array = [4; <A as Foo>::Y];
| ^^^^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes

error: aborting due to 2 previous errors

62 changes: 35 additions & 27 deletions tests/ui/const-generics/const-arg-in-const-arg.min.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ LL | let _: [u8; baz::<'b>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:26:23
--> $DIR/const-arg-in-const-arg.rs:27:23
|
LL | let _ = [0; bar::<N>()];
| ^ cannot perform const operation using `N`
Expand All @@ -62,7 +62,7 @@ LL | let _ = [0; bar::<N>()];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:28:23
--> $DIR/const-arg-in-const-arg.rs:29:23
|
LL | let _ = [0; faz::<'a>(&())];
| ^^ cannot perform const operation using `'a`
Expand All @@ -71,7 +71,7 @@ LL | let _ = [0; faz::<'a>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:30:23
--> $DIR/const-arg-in-const-arg.rs:31:23
|
LL | let _ = [0; baz::<'a>(&())];
| ^^ cannot perform const operation using `'a`
Expand All @@ -80,7 +80,7 @@ LL | let _ = [0; baz::<'a>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:31:23
--> $DIR/const-arg-in-const-arg.rs:32:23
|
LL | let _ = [0; faz::<'b>(&())];
| ^^ cannot perform const operation using `'b`
Expand All @@ -89,7 +89,7 @@ LL | let _ = [0; faz::<'b>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:33:23
--> $DIR/const-arg-in-const-arg.rs:34:23
|
LL | let _ = [0; baz::<'b>(&())];
| ^^ cannot perform const operation using `'b`
Expand All @@ -98,7 +98,7 @@ LL | let _ = [0; baz::<'b>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:34:24
--> $DIR/const-arg-in-const-arg.rs:35:24
|
LL | let _: Foo<{ foo::<T>() }>;
| ^ cannot perform const operation using `T`
Expand All @@ -107,7 +107,7 @@ LL | let _: Foo<{ foo::<T>() }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:35:24
--> $DIR/const-arg-in-const-arg.rs:36:24
|
LL | let _: Foo<{ bar::<N>() }>;
| ^ cannot perform const operation using `N`
Expand All @@ -116,7 +116,7 @@ LL | let _: Foo<{ bar::<N>() }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:37:24
--> $DIR/const-arg-in-const-arg.rs:38:24
|
LL | let _: Foo<{ faz::<'a>(&()) }>;
| ^^ cannot perform const operation using `'a`
Expand All @@ -125,7 +125,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:39:24
--> $DIR/const-arg-in-const-arg.rs:40:24
|
LL | let _: Foo<{ baz::<'a>(&()) }>;
| ^^ cannot perform const operation using `'a`
Expand All @@ -134,7 +134,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:40:24
--> $DIR/const-arg-in-const-arg.rs:41:24
|
LL | let _: Foo<{ faz::<'b>(&()) }>;
| ^^ cannot perform const operation using `'b`
Expand All @@ -143,7 +143,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:42:24
--> $DIR/const-arg-in-const-arg.rs:43:24
|
LL | let _: Foo<{ baz::<'b>(&()) }>;
| ^^ cannot perform const operation using `'b`
Expand All @@ -152,7 +152,7 @@ LL | let _: Foo<{ baz::<'b>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:43:27
--> $DIR/const-arg-in-const-arg.rs:44:27
|
LL | let _ = Foo::<{ foo::<T>() }>;
| ^ cannot perform const operation using `T`
Expand All @@ -161,7 +161,7 @@ LL | let _ = Foo::<{ foo::<T>() }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:44:27
--> $DIR/const-arg-in-const-arg.rs:45:27
|
LL | let _ = Foo::<{ bar::<N>() }>;
| ^ cannot perform const operation using `N`
Expand All @@ -170,7 +170,7 @@ LL | let _ = Foo::<{ bar::<N>() }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:46:27
--> $DIR/const-arg-in-const-arg.rs:47:27
|
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
| ^^ cannot perform const operation using `'a`
Expand All @@ -179,7 +179,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:48:27
--> $DIR/const-arg-in-const-arg.rs:49:27
|
LL | let _ = Foo::<{ baz::<'a>(&()) }>;
| ^^ cannot perform const operation using `'a`
Expand All @@ -188,7 +188,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:49:27
--> $DIR/const-arg-in-const-arg.rs:50:27
|
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
| ^^ cannot perform const operation using `'b`
Expand All @@ -197,7 +197,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:51:27
--> $DIR/const-arg-in-const-arg.rs:52:27
|
LL | let _ = Foo::<{ baz::<'b>(&()) }>;
| ^^ cannot perform const operation using `'b`
Expand Down Expand Up @@ -241,7 +241,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^

error[E0747]: unresolved item provided when a constant was expected
--> $DIR/const-arg-in-const-arg.rs:35:24
--> $DIR/const-arg-in-const-arg.rs:36:24
|
LL | let _: Foo<{ bar::<N>() }>;
| ^
Expand All @@ -252,7 +252,7 @@ LL | let _: Foo<{ bar::<{ N }>() }>;
| + +

error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:37:24
--> $DIR/const-arg-in-const-arg.rs:38:24
|
LL | let _: Foo<{ faz::<'a>(&()) }>;
| ^^
Expand All @@ -264,7 +264,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^

error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:40:24
--> $DIR/const-arg-in-const-arg.rs:41:24
|
LL | let _: Foo<{ faz::<'b>(&()) }>;
| ^^
Expand All @@ -283,8 +283,16 @@ LL | let _ = [0; foo::<T>()];
|
= note: this may fail depending on what value the parameter takes

error: constant expression depends on a generic parameter
--> $DIR/const-arg-in-const-arg.rs:25:13
|
LL | let _ = [0; foo::<T>()];
| ^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes

error[E0747]: unresolved item provided when a constant was expected
--> $DIR/const-arg-in-const-arg.rs:26:23
--> $DIR/const-arg-in-const-arg.rs:27:23
|
LL | let _ = [0; bar::<N>()];
| ^
Expand All @@ -295,7 +303,7 @@ LL | let _ = [0; bar::<{ N }>()];
| + +

error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:28:23
--> $DIR/const-arg-in-const-arg.rs:29:23
|
LL | let _ = [0; faz::<'a>(&())];
| ^^
Expand All @@ -307,7 +315,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^

error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:31:23
--> $DIR/const-arg-in-const-arg.rs:32:23
|
LL | let _ = [0; faz::<'b>(&())];
| ^^
Expand All @@ -319,7 +327,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^

error[E0747]: unresolved item provided when a constant was expected
--> $DIR/const-arg-in-const-arg.rs:44:27
--> $DIR/const-arg-in-const-arg.rs:45:27
|
LL | let _ = Foo::<{ bar::<N>() }>;
| ^
Expand All @@ -330,7 +338,7 @@ LL | let _ = Foo::<{ bar::<{ N }>() }>;
| + +

error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:46:27
--> $DIR/const-arg-in-const-arg.rs:47:27
|
LL | let _ = Foo::<{ faz::<'a>(&()) }>;
| ^^
Expand All @@ -342,7 +350,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^

error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:49:27
--> $DIR/const-arg-in-const-arg.rs:50:27
|
LL | let _ = Foo::<{ faz::<'b>(&()) }>;
| ^^
Expand All @@ -353,7 +361,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^

error: aborting due to 36 previous errors
error: aborting due to 37 previous errors

Some errors have detailed explanations: E0747, E0794.
For more information about an error, try `rustc --explain E0747`.
1 change: 1 addition & 0 deletions tests/ui/const-generics/const-arg-in-const-arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized {
let _: [u8; baz::<'b>(&())]; //[min]~ ERROR generic parameters may not

let _ = [0; foo::<T>()]; //[min]~ ERROR constant expression depends on a generic parameter
//[min]~^ ERROR constant expression depends on a generic parameter
let _ = [0; bar::<N>()]; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR unresolved item provided when a constant was expected
let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
error: overly complex generic constant
--> $DIR/dependence_lint.rs:17:9
|
LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
|
= help: consider moving this anonymous constant into a `const` function

error: overly complex generic constant
--> $DIR/dependence_lint.rs:21:17
|
Expand Down Expand Up @@ -36,5 +28,13 @@ help: try adding a `where` bound
LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
| ++++++++++++++++++++++++++++++++

error: overly complex generic constant
--> $DIR/dependence_lint.rs:17:9
|
LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
|
= help: consider moving this anonymous constant into a `const` function

error: aborting due to 4 previous errors

1 change: 1 addition & 0 deletions tests/ui/consts/too_generic_eval_ice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ impl<A, B> Foo<A, B> {
[5; Self::HOST_SIZE] == [6; 0]
//~^ ERROR constant expression depends on a generic parameter
//~| ERROR constant expression depends on a generic parameter
//~| ERROR constant expression depends on a generic parameter
//~| ERROR can't compare `[{integer}; Self::HOST_SIZE]` with `[{integer}; 0]`
}
}
Expand Down
10 changes: 9 additions & 1 deletion tests/ui/consts/too_generic_eval_ice.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ LL | [5; Self::HOST_SIZE] == [6; 0]
|
= note: this may fail depending on what value the parameter takes

error: constant expression depends on a generic parameter
--> $DIR/too_generic_eval_ice.rs:7:9
|
LL | [5; Self::HOST_SIZE] == [6; 0]
| ^^^^^^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes

error: constant expression depends on a generic parameter
--> $DIR/too_generic_eval_ice.rs:7:30
|
Expand All @@ -32,6 +40,6 @@ LL | [5; Self::HOST_SIZE] == [6; 0]
`[T; N]` implements `PartialEq<[U]>`
and 3 others

error: aborting due to 3 previous errors
error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0277`.
7 changes: 5 additions & 2 deletions tests/ui/error-codes/E0746.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ error[E0746]: return type cannot have an unboxed trait object
LL | fn bar() -> dyn Trait {
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= help: if there were a single returned type, you could use `impl Trait` instead
help: box the return type, and wrap all of the returned values in `Box::new`
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
LL | fn bar() -> impl Trait {
| ~~~~
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
LL ~ fn bar() -> Box<dyn Trait> {
LL | if true {
Expand Down
Loading
Loading