diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index f93bd0a396ddf..e2af7dac44f9d 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -37,13 +37,17 @@ pub fn is_const_evaluatable<'tcx>( | ty::ConstKind::Value(_, _) | ty::ConstKind::Error(_) => return Ok(()), ty::ConstKind::Infer(_) => return Err(NotConstEvaluatable::MentionsInfer), - }; + } if tcx.features().generic_const_exprs { let ct = tcx.expand_abstract_consts(unexpanded_ct); + if trivially_satisfied_from_param_env(ct, param_env) { + return Ok(()); + } + let is_anon_ct = if let ty::ConstKind::Unevaluated(uv) = ct.kind() { - tcx.def_kind(uv.def) == DefKind::AnonConst + matches!(tcx.def_kind(uv.def), DefKind::AnonConst) } else { false }; @@ -150,6 +154,23 @@ pub fn is_const_evaluatable<'tcx>( } } +fn trivially_satisfied_from_param_env<'tcx>( + ct: ty::Const<'tcx>, + param_env: ty::ParamEnv<'tcx>, +) -> bool { + for pred in param_env.caller_bounds() { + if let ty::ClauseKind::ConstEvaluatable(ce) = pred.kind().skip_binder() { + if let ty::ConstKind::Unevaluated(uv_env) = ce.kind() + && let ty::ConstKind::Unevaluated(uv) = ct.kind() + && uv == uv_env + { + return true; + } + } + } + false +} + #[instrument(skip(infcx, tcx), level = "debug")] fn satisfied_from_param_env<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/tests/crashes/123959.rs b/tests/ui/const-generics/generic_const_exprs/ice-123959.rs similarity index 68% rename from tests/crashes/123959.rs rename to tests/ui/const-generics/generic_const_exprs/ice-123959.rs index fe22c0225ed1c..eb9f20df51f60 100644 --- a/tests/crashes/123959.rs +++ b/tests/ui/const-generics/generic_const_exprs/ice-123959.rs @@ -1,5 +1,7 @@ -//@ known-bug: #123959 +//@ check-pass #![feature(generic_const_exprs)] +#![allow(incomplete_features)] + fn foo(_: [(); std::mem::offset_of!((T,), 0)]) {} pub fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs index 51cae20df84d4..dda60e70eaddb 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs @@ -14,8 +14,8 @@ mod v20 { //~^ ERROR cannot find value `v8` in this scope //~| ERROR cannot find function `v6` in this scope pub struct v17 { - //~^ WARN type `v17` should have an upper camel case name - //~| ERROR `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter + //~^ WARN type `v17` should have an upper camel case name + //~| ERROR `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter _p: (), } @@ -25,10 +25,9 @@ mod v20 { } impl v17 { - //~^ ERROR maximum number of nodes exceeded in constant v20::v17::::{constant#1} - //~| ERROR maximum number of nodes exceeded in constant v20::v17::::{constant#1} + //~^ ERROR maximum number of nodes exceeded in constant v20::v17::::{constant#1} pub const fn v21() -> v18 { - //~^ ERROR cannot find type `v18` in this scope + //~^ ERROR cannot find type `v18` in this scope v18 { _p: () } //~^ ERROR cannot find struct, variant or union type `v18` in this scope } diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index 39f022fbee9db..4bfad3bfeaac8 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -1,5 +1,5 @@ error[E0432]: unresolved import `v20::v13` - --> $DIR/unevaluated-const-ice-119731.rs:37:15 + --> $DIR/unevaluated-const-ice-119731.rs:36:15 | LL | pub use v20::{v13, v17}; | ^^^ @@ -23,7 +23,7 @@ LL | pub const fn v21() -> v18 {} | ^^^ help: a type alias with a similar name exists: `v11` error[E0412]: cannot find type `v18` in this scope - --> $DIR/unevaluated-const-ice-119731.rs:30:31 + --> $DIR/unevaluated-const-ice-119731.rs:29:31 | LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here @@ -32,7 +32,7 @@ LL | pub const fn v21() -> v18 { | ^^^ help: a type alias with a similar name exists: `v11` error[E0422]: cannot find struct, variant or union type `v18` in this scope - --> $DIR/unevaluated-const-ice-119731.rs:32:13 + --> $DIR/unevaluated-const-ice-119731.rs:31:13 | LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here @@ -78,15 +78,7 @@ error: maximum number of nodes exceeded in constant v20::v17::::{consta LL | impl v17 { | ^^ -error: maximum number of nodes exceeded in constant v20::v17::::{constant#1} - --> $DIR/unevaluated-const-ice-119731.rs:27:37 - | -LL | impl v17 { - | ^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 9 previous errors; 2 warnings emitted +error: aborting due to 8 previous errors; 2 warnings emitted Some errors have detailed explanations: E0412, E0422, E0425, E0432. For more information about an error, try `rustc --explain E0412`.