Skip to content

Commit

Permalink
Rollup merge of rust-lang#133518 - compiler-errors:structurally-resol…
Browse files Browse the repository at this point in the history
…ve-never, r=lcnr

Structurally resolve before checking `!` in HIR typeck

Some more missing structural resolves in HIR typeck :>

r? lcnr
  • Loading branch information
joboet authored Nov 27, 2024
2 parents bf0d7c8 + 4c0ea55 commit 2b35555
Show file tree
Hide file tree
Showing 15 changed files with 125 additions and 47 deletions.
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

0 comments on commit 2b35555

Please sign in to comment.