Rollup merge of #133518 - compiler-errors:structurally-resolve-never, r=lcnr

Structurally resolve before checking `!` in HIR typeck

Some more missing structural resolves in HIR typeck :>

r? lcnr
This commit is contained in:
Matthias Krüger 2024-11-27 22:23:26 +01:00 committed by GitHub
commit 5d0ee56e88
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 125 additions and 47 deletions

View file

@ -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,
@ -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));
}

View file

@ -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() {

View file

@ -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

View file

@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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`
@ -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>() }>;
| ^
@ -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>(&()) }>;
| ^^
@ -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>(&()) }>;
| ^^
@ -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>()];
| ^
@ -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>(&())];
| ^^
@ -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>(&())];
| ^^
@ -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>() }>;
| ^
@ -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>(&()) }>;
| ^^
@ -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>(&()) }>;
| ^^
@ -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`.

View file

@ -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

View file

@ -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
|
@ -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

View file

@ -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]`
}
}

View file

@ -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
|
@ -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`.

View file

@ -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 {

View file

@ -261,8 +261,11 @@ error[E0746]: return type cannot have an unboxed trait object
LL | fn bat() -> 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 bat() -> impl Trait {
| ~~~~
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
LL ~ fn bat() -> Box<dyn Trait> {
LL | if true {
@ -277,8 +280,11 @@ error[E0746]: return type cannot have an unboxed trait object
LL | fn bay() -> 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 bay() -> impl Trait {
| ~~~~
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
LL ~ fn bay() -> Box<dyn Trait> {
LL | if true {

View file

@ -8,6 +8,7 @@ trait Mat {
fn m<M: Mat>() {
let a = [3; M::Row::DIM];
//~^ ERROR constant expression depends on a generic parameter
//~| ERROR constant expression depends on a generic parameter
}
fn main() {
}

View file

@ -6,5 +6,13 @@ LL | let a = [3; M::Row::DIM];
|
= 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/issue-39211.rs:9:13
|
LL | let a = [3; M::Row::DIM];
| ^^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes
error: aborting due to 2 previous errors

View file

@ -28,5 +28,6 @@ fn main() {
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
//~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
println!("{x}");
}

View file

@ -24,6 +24,14 @@ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
LL | drop(<() as Foo>::copy_me(&x));
| ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
--> $DIR/alias-bound-unsound.rs:24:10
|
LL | drop(<() as Foo>::copy_me(&x));
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed`
--> $DIR/alias-bound-unsound.rs:24:31
|
@ -50,6 +58,6 @@ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
LL | drop(<() as Foo>::copy_me(&x));
| ^^
error: aborting due to 7 previous errors
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0275`.

View file

@ -0,0 +1,20 @@
//@ check-pass
//@ compile-flags: -Znext-solver
#![feature(never_type)]
trait Mirror {
type Assoc;
}
impl<T> Mirror for T {
type Assoc = T;
}
fn diverge() -> <! as Mirror>::Assoc { todo!() }
fn main() {
let close = || {
diverge();
};
let x: u32 = close();
}