diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index ecf35d9dd6d7e..89034981cbd64 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -134,6 +134,7 @@ impl<'tcx> TyCtxt<'tcx> { // If we don't *only* FCW anon consts we can wind up incorrectly FCW'ing uses of assoc // consts in pattern positions. #140447 && self.def_kind(cid.instance.def_id()) == DefKind::AnonConst + && !self.is_trivial_const(cid.instance.def_id()) { let mir_body = self.mir_for_ctfe(cid.instance.def_id()); if mir_body.is_polymorphic { diff --git a/compiler/rustc_mir_transform/src/trivial_const.rs b/compiler/rustc_mir_transform/src/trivial_const.rs index af096f2b04689..3b80ae30be42d 100644 --- a/compiler/rustc_mir_transform/src/trivial_const.rs +++ b/compiler/rustc_mir_transform/src/trivial_const.rs @@ -3,8 +3,8 @@ use std::ops::Deref; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::mir::{ - Body, ConstValue, Operand, Place, RETURN_PLACE, Rvalue, START_BLOCK, StatementKind, - TerminatorKind, + Body, Const, ConstValue, Operand, Place, RETURN_PLACE, Rvalue, START_BLOCK, StatementKind, + TerminatorKind, UnevaluatedConst, }; use rustc_middle::ty::{Ty, TyCtxt, TypeVisitableExt}; @@ -13,7 +13,9 @@ use rustc_middle::ty::{Ty, TyCtxt, TypeVisitableExt}; /// A "trivial const" is a const which can be easily proven to evaluate successfully, and the value /// that it evaluates to can be easily found without going through the usual MIR phases for a const. /// -/// Currently the only form of trivial const that is supported is this: +/// Currently, we support two forms of trivial const. +/// +/// The base case is this: /// ``` /// const A: usize = 0; /// ``` @@ -34,6 +36,13 @@ use rustc_middle::ty::{Ty, TyCtxt, TypeVisitableExt}; /// This scenario meets the required criteria because: /// * Control flow cannot panic, we don't have any calls or assert terminators /// * The value of the const is already computed, so it cannot fail +/// +/// In addition to assignment of literals, assignments of trivial consts are also considered +/// trivial consts. In this case, both `A` and `B` are trivial: +/// ``` +/// const A: usize = 0; +/// const B: usize = A; +/// ``` pub(crate) fn trivial_const<'a, 'tcx: 'a, F, B>( tcx: TyCtxt<'tcx>, def: LocalDefId, @@ -74,13 +83,19 @@ where return None; } - if let Rvalue::Use(Operand::Constant(c)) = rvalue { - if let rustc_middle::mir::Const::Val(v, ty) = c.const_ { - return Some((v, ty)); + let Rvalue::Use(Operand::Constant(c)) = rvalue else { + return None; + }; + match c.const_ { + Const::Ty(..) => None, + Const::Unevaluated(UnevaluatedConst { def, args, .. }, _ty) => { + if !args.is_empty() { + return None; + } + tcx.trivial_const(def) } + Const::Val(v, ty) => Some((v, ty)), } - - return None; } // The query provider is based on calling the free function trivial_const, which calls mir_built, diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr index bf37f537a4976..718854c59f4ff 100644 --- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr +++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr @@ -1,36 +1,30 @@ -error[E0391]: cycle detected when simplifying constant for the type system `IMPL_REF_BAR` +error[E0391]: cycle detected when checking if `IMPL_REF_BAR` is a trivial const --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 | LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `IMPL_REF_BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:27 +note: ...which requires building MIR for `IMPL_REF_BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 | LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; - | ^^^^^^^^^^^^^^^^^^ -note: ...which requires simplifying constant for the type system `::BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 - | -LL | const BAR: u32 = IMPL_REF_BAR; - | ^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `::BAR`... + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires checking if `::BAR` is a trivial const... --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 | LL | const BAR: u32 = IMPL_REF_BAR; | ^^^^^^^^^^^^^^ -note: ...which requires caching mir of `::BAR` for CTFE... +note: ...which requires building MIR for `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 | LL | const BAR: u32 = IMPL_REF_BAR; | ^^^^^^^^^^^^^^ -note: ...which requires elaborating drops for `::BAR`... - --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:22 + = note: ...which again requires checking if `IMPL_REF_BAR` is a trivial const, completing the cycle +note: cycle used when simplifying constant for the type system `IMPL_REF_BAR` + --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 | -LL | const BAR: u32 = IMPL_REF_BAR; - | ^^^^^^^^^^^^ - = note: ...which again requires simplifying constant for the type system `IMPL_REF_BAR`, completing the cycle - = note: cycle used when running analysis passes on this crate +LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-17252.stderr b/tests/ui/issues/issue-17252.stderr index 56bc32b19ab73..b0d9d94e07ddf 100644 --- a/tests/ui/issues/issue-17252.stderr +++ b/tests/ui/issues/issue-17252.stderr @@ -1,31 +1,39 @@ -error[E0391]: cycle detected when simplifying constant for the type system `FOO` +error[E0391]: cycle detected when checking if `FOO` is a trivial const --> $DIR/issue-17252.rs:1:1 | LL | const FOO: usize = FOO; | ^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `FOO`... - --> $DIR/issue-17252.rs:1:20 +note: ...which requires building MIR for `FOO`... + --> $DIR/issue-17252.rs:1:1 + | +LL | const FOO: usize = FOO; + | ^^^^^^^^^^^^^^^^ + = note: ...which again requires checking if `FOO` is a trivial const, completing the cycle +note: cycle used when simplifying constant for the type system `FOO` + --> $DIR/issue-17252.rs:1:1 | LL | const FOO: usize = FOO; - | ^^^ - = note: ...which again requires simplifying constant for the type system `FOO`, completing the cycle - = note: cycle used when running analysis passes on this crate + | ^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error[E0391]: cycle detected when simplifying constant for the type system `main::BAR` +error[E0391]: cycle detected when checking if `main::BAR` is a trivial const --> $DIR/issue-17252.rs:6:9 | LL | const BAR: usize = BAR; | ^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `main::BAR`... - --> $DIR/issue-17252.rs:6:28 +note: ...which requires building MIR for `main::BAR`... + --> $DIR/issue-17252.rs:6:9 + | +LL | const BAR: usize = BAR; + | ^^^^^^^^^^^^^^^^ + = note: ...which again requires checking if `main::BAR` is a trivial const, completing the cycle +note: cycle used when simplifying constant for the type system `main::BAR` + --> $DIR/issue-17252.rs:6:9 | LL | const BAR: usize = BAR; - | ^^^ - = note: ...which again requires simplifying constant for the type system `main::BAR`, completing the cycle - = note: cycle used when running analysis passes on this crate + | ^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 2 previous errors diff --git a/tests/ui/parallel-rustc/cycle_crash-issue-135870.rs b/tests/ui/parallel-rustc/cycle_crash-issue-135870.rs index 4407e3aca802d..d199bc14842a0 100644 --- a/tests/ui/parallel-rustc/cycle_crash-issue-135870.rs +++ b/tests/ui/parallel-rustc/cycle_crash-issue-135870.rs @@ -3,6 +3,6 @@ //@ compile-flags: -Z threads=2 //@ compare-output-by-lines -const FOO: usize = FOO; //~ ERROR cycle detected when simplifying constant for the type system `FOO` +const FOO: usize = FOO; //~ ERROR cycle detected fn main() {} diff --git a/tests/ui/parallel-rustc/cycle_crash-issue-135870.stderr b/tests/ui/parallel-rustc/cycle_crash-issue-135870.stderr index 6e588d1f89466..b80d0f92fcfa4 100644 --- a/tests/ui/parallel-rustc/cycle_crash-issue-135870.stderr +++ b/tests/ui/parallel-rustc/cycle_crash-issue-135870.stderr @@ -1,18 +1,12 @@ -error[E0391]: cycle detected when simplifying constant for the type system `FOO` --> $DIR/cycle_crash-issue-135870.rs:6:1 | LL | const FOO: usize = FOO; | ^^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `FOO`... - --> $DIR/cycle_crash-issue-135870.rs:6:20 | LL | const FOO: usize = FOO; - | ^^^ - = note: ...which again requires simplifying constant for the type system `FOO`, completing the cycle - = note: cycle used when running analysis passes on this crate = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0391`. +For more information about this error, try `rustc --explain E0391`. \ No newline at end of file diff --git a/tests/ui/recursion/issue-23302-3.stderr b/tests/ui/recursion/issue-23302-3.stderr index 8a152f5896634..ddca746e165b5 100644 --- a/tests/ui/recursion/issue-23302-3.stderr +++ b/tests/ui/recursion/issue-23302-3.stderr @@ -1,26 +1,30 @@ -error[E0391]: cycle detected when simplifying constant for the type system `A` +error[E0391]: cycle detected when checking if `A` is a trivial const --> $DIR/issue-23302-3.rs:1:1 | LL | const A: i32 = B; | ^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `A`... - --> $DIR/issue-23302-3.rs:1:16 +note: ...which requires building MIR for `A`... + --> $DIR/issue-23302-3.rs:1:1 | LL | const A: i32 = B; - | ^ -note: ...which requires simplifying constant for the type system `B`... + | ^^^^^^^^^^^^ +note: ...which requires checking if `B` is a trivial const... --> $DIR/issue-23302-3.rs:3:1 | LL | const B: i32 = A; | ^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `B`... - --> $DIR/issue-23302-3.rs:3:16 +note: ...which requires building MIR for `B`... + --> $DIR/issue-23302-3.rs:3:1 | LL | const B: i32 = A; - | ^ - = note: ...which again requires simplifying constant for the type system `A`, completing the cycle - = note: cycle used when running analysis passes on this crate + | ^^^^^^^^^^^^ + = note: ...which again requires checking if `A` is a trivial const, completing the cycle +note: cycle used when simplifying constant for the type system `A` + --> $DIR/issue-23302-3.rs:1:1 + | +LL | const A: i32 = B; + | ^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 1 previous error