Skip to content

Commit

Permalink
skip const-eval if evaluatable predicate is trivial
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Jul 2, 2024
1 parent 7d97c59 commit 05c8ece
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 20 deletions.
25 changes: 23 additions & 2 deletions compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
Expand Down Expand Up @@ -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>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//@ known-bug: #123959
//@ check-pass
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

fn foo<T>(_: [(); std::mem::offset_of!((T,), 0)]) {}

pub fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -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<const v10: usize, const v7: v11> {
//~^ 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: (),
}

Expand All @@ -25,10 +25,9 @@ mod v20 {
}

impl<const v10: usize> v17<v10, v2> {
//~^ ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
//~| ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
//~^ ERROR maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{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
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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};
| ^^^
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -78,15 +78,7 @@ error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{consta
LL | impl<const v10: usize> v17<v10, v2> {
| ^^

error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
--> $DIR/unevaluated-const-ice-119731.rs:27:37
|
LL | impl<const v10: usize> v17<v10, v2> {
| ^^
|
= 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`.

0 comments on commit 05c8ece

Please sign in to comment.