Auto merge of #148182 - saethlin:trivial-consts-recursive, r=eholk
Accept trivial consts based on trivial consts This is an expansion of https://github.com/rust-lang/rust/pull/148040. The previous implementation only accepted trivial consts that assign a literal. For example: ```rust const A: usize = 0; const B: usize = A; ``` Before this PR, only `A` was a trivial const. Now `B` is too.
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires checking if `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::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 const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
|
||||
note: ...which requires building MIR for `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
|
||||
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
||||
|
|
||||
LL | const BAR: u32 = IMPL_REF_BAR;
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: ...which requires caching mir of `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR` for CTFE...
|
||||
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
||||
= 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 requires elaborating drops for `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
|
||||
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:22
|
||||
|
|
||||
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
|
||||
|
||||
@@ -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 simplifying constant for the type system `FOO`, completing the cycle
|
||||
= note: cycle used when running analysis passes on this crate
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= 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: 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 simplifying constant for the type system `main::BAR`, completing the cycle
|
||||
= note: cycle used when running analysis passes on this crate
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= 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: 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
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user