Skip to content

Commit 05c8ece

Browse files
skip const-eval if evaluatable predicate is trivial
1 parent 7d97c59 commit 05c8ece

File tree

4 files changed

+34
-20
lines changed

4 files changed

+34
-20
lines changed

compiler/rustc_trait_selection/src/traits/const_evaluatable.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,17 @@ pub fn is_const_evaluatable<'tcx>(
3737
| ty::ConstKind::Value(_, _)
3838
| ty::ConstKind::Error(_) => return Ok(()),
3939
ty::ConstKind::Infer(_) => return Err(NotConstEvaluatable::MentionsInfer),
40-
};
40+
}
4141

4242
if tcx.features().generic_const_exprs {
4343
let ct = tcx.expand_abstract_consts(unexpanded_ct);
4444

45+
if trivially_satisfied_from_param_env(ct, param_env) {
46+
return Ok(());
47+
}
48+
4549
let is_anon_ct = if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
46-
tcx.def_kind(uv.def) == DefKind::AnonConst
50+
matches!(tcx.def_kind(uv.def), DefKind::AnonConst)
4751
} else {
4852
false
4953
};
@@ -150,6 +154,23 @@ pub fn is_const_evaluatable<'tcx>(
150154
}
151155
}
152156

157+
fn trivially_satisfied_from_param_env<'tcx>(
158+
ct: ty::Const<'tcx>,
159+
param_env: ty::ParamEnv<'tcx>,
160+
) -> bool {
161+
for pred in param_env.caller_bounds() {
162+
if let ty::ClauseKind::ConstEvaluatable(ce) = pred.kind().skip_binder() {
163+
if let ty::ConstKind::Unevaluated(uv_env) = ce.kind()
164+
&& let ty::ConstKind::Unevaluated(uv) = ct.kind()
165+
&& uv == uv_env
166+
{
167+
return true;
168+
}
169+
}
170+
}
171+
false
172+
}
173+
153174
#[instrument(skip(infcx, tcx), level = "debug")]
154175
fn satisfied_from_param_env<'tcx>(
155176
tcx: TyCtxt<'tcx>,
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
//@ known-bug: #123959
1+
//@ check-pass
22
#![feature(generic_const_exprs)]
3+
#![allow(incomplete_features)]
4+
35
fn foo<T>(_: [(); std::mem::offset_of!((T,), 0)]) {}
46

57
pub fn main() {}

tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ mod v20 {
1414
//~^ ERROR cannot find value `v8` in this scope
1515
//~| ERROR cannot find function `v6` in this scope
1616
pub struct v17<const v10: usize, const v7: v11> {
17-
//~^ WARN type `v17` should have an upper camel case name
18-
//~| ERROR `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter
17+
//~^ WARN type `v17` should have an upper camel case name
18+
//~| ERROR `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter
1919
_p: (),
2020
}
2121

@@ -25,10 +25,9 @@ mod v20 {
2525
}
2626

2727
impl<const v10: usize> v17<v10, v2> {
28-
//~^ ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
29-
//~| ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
28+
//~^ ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
3029
pub const fn v21() -> v18 {
31-
//~^ ERROR cannot find type `v18` in this scope
30+
//~^ ERROR cannot find type `v18` in this scope
3231
v18 { _p: () }
3332
//~^ ERROR cannot find struct, variant or union type `v18` in this scope
3433
}

tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0432]: unresolved import `v20::v13`
2-
--> $DIR/unevaluated-const-ice-119731.rs:37:15
2+
--> $DIR/unevaluated-const-ice-119731.rs:36:15
33
|
44
LL | pub use v20::{v13, v17};
55
| ^^^
@@ -23,7 +23,7 @@ LL | pub const fn v21() -> v18 {}
2323
| ^^^ help: a type alias with a similar name exists: `v11`
2424

2525
error[E0412]: cannot find type `v18` in this scope
26-
--> $DIR/unevaluated-const-ice-119731.rs:30:31
26+
--> $DIR/unevaluated-const-ice-119731.rs:29:31
2727
|
2828
LL | pub type v11 = [[usize; v4]; v4];
2929
| --------------------------------- similarly named type alias `v11` defined here
@@ -32,7 +32,7 @@ LL | pub const fn v21() -> v18 {
3232
| ^^^ help: a type alias with a similar name exists: `v11`
3333

3434
error[E0422]: cannot find struct, variant or union type `v18` in this scope
35-
--> $DIR/unevaluated-const-ice-119731.rs:32:13
35+
--> $DIR/unevaluated-const-ice-119731.rs:31:13
3636
|
3737
LL | pub type v11 = [[usize; v4]; v4];
3838
| --------------------------------- similarly named type alias `v11` defined here
@@ -78,15 +78,7 @@ error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{consta
7878
LL | impl<const v10: usize> v17<v10, v2> {
7979
| ^^
8080

81-
error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
82-
--> $DIR/unevaluated-const-ice-119731.rs:27:37
83-
|
84-
LL | impl<const v10: usize> v17<v10, v2> {
85-
| ^^
86-
|
87-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
88-
89-
error: aborting due to 9 previous errors; 2 warnings emitted
81+
error: aborting due to 8 previous errors; 2 warnings emitted
9082

9183
Some errors have detailed explanations: E0412, E0422, E0425, E0432.
9284
For more information about an error, try `rustc --explain E0412`.

0 commit comments

Comments
 (0)