Skip to content

Commit 044d68c

Browse files
committed
Auto merge of #148182 - saethlin:trivial-consts-recursive, r=eholk
Accept trivial consts based on trivial consts This is an expansion of #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.
2 parents 278a909 + 9cbfbb1 commit 044d68c

File tree

7 files changed

+71
-55
lines changed

7 files changed

+71
-55
lines changed

compiler/rustc_middle/src/mir/interpret/queries.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ impl<'tcx> TyCtxt<'tcx> {
134134
// If we don't *only* FCW anon consts we can wind up incorrectly FCW'ing uses of assoc
135135
// consts in pattern positions. #140447
136136
&& self.def_kind(cid.instance.def_id()) == DefKind::AnonConst
137+
&& !self.is_trivial_const(cid.instance.def_id())
137138
{
138139
let mir_body = self.mir_for_ctfe(cid.instance.def_id());
139140
if mir_body.is_polymorphic {

compiler/rustc_mir_transform/src/trivial_const.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use std::ops::Deref;
33
use rustc_hir::def::DefKind;
44
use rustc_hir::def_id::LocalDefId;
55
use rustc_middle::mir::{
6-
Body, ConstValue, Operand, Place, RETURN_PLACE, Rvalue, START_BLOCK, StatementKind,
7-
TerminatorKind,
6+
Body, Const, ConstValue, Operand, Place, RETURN_PLACE, Rvalue, START_BLOCK, StatementKind,
7+
TerminatorKind, UnevaluatedConst,
88
};
99
use rustc_middle::ty::{Ty, TyCtxt, TypeVisitableExt};
1010

@@ -13,7 +13,9 @@ use rustc_middle::ty::{Ty, TyCtxt, TypeVisitableExt};
1313
/// A "trivial const" is a const which can be easily proven to evaluate successfully, and the value
1414
/// that it evaluates to can be easily found without going through the usual MIR phases for a const.
1515
///
16-
/// Currently the only form of trivial const that is supported is this:
16+
/// Currently, we support two forms of trivial const.
17+
///
18+
/// The base case is this:
1719
/// ```
1820
/// const A: usize = 0;
1921
/// ```
@@ -34,6 +36,13 @@ use rustc_middle::ty::{Ty, TyCtxt, TypeVisitableExt};
3436
/// This scenario meets the required criteria because:
3537
/// * Control flow cannot panic, we don't have any calls or assert terminators
3638
/// * The value of the const is already computed, so it cannot fail
39+
///
40+
/// In addition to assignment of literals, assignments of trivial consts are also considered
41+
/// trivial consts. In this case, both `A` and `B` are trivial:
42+
/// ```
43+
/// const A: usize = 0;
44+
/// const B: usize = A;
45+
/// ```
3746
pub(crate) fn trivial_const<'a, 'tcx: 'a, F, B>(
3847
tcx: TyCtxt<'tcx>,
3948
def: LocalDefId,
@@ -74,13 +83,19 @@ where
7483
return None;
7584
}
7685

77-
if let Rvalue::Use(Operand::Constant(c)) = rvalue {
78-
if let rustc_middle::mir::Const::Val(v, ty) = c.const_ {
79-
return Some((v, ty));
86+
let Rvalue::Use(Operand::Constant(c)) = rvalue else {
87+
return None;
88+
};
89+
match c.const_ {
90+
Const::Ty(..) => None,
91+
Const::Unevaluated(UnevaluatedConst { def, args, .. }, _ty) => {
92+
if !args.is_empty() {
93+
return None;
94+
}
95+
tcx.trivial_const(def)
8096
}
97+
Const::Val(v, ty) => Some((v, ty)),
8198
}
82-
83-
return None;
8499
}
85100

86101
// The query provider is based on calling the free function trivial_const, which calls mir_built,

tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,30 @@
1-
error[E0391]: cycle detected when simplifying constant for the type system `IMPL_REF_BAR`
1+
error[E0391]: cycle detected when checking if `IMPL_REF_BAR` is a trivial const
22
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
33
|
44
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
55
| ^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
note: ...which requires const-evaluating + checking `IMPL_REF_BAR`...
8-
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:27
7+
note: ...which requires building MIR for `IMPL_REF_BAR`...
8+
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
99
|
1010
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
11-
| ^^^^^^^^^^^^^^^^^^
12-
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`...
13-
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
14-
|
15-
LL | const BAR: u32 = IMPL_REF_BAR;
16-
| ^^^^^^^^^^^^^^
17-
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
11+
| ^^^^^^^^^^^^^^^^^^^^^^^
12+
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...
1813
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
1914
|
2015
LL | const BAR: u32 = IMPL_REF_BAR;
2116
| ^^^^^^^^^^^^^^
22-
note: ...which requires caching mir of `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR` for CTFE...
17+
note: ...which requires building MIR for `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
2318
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
2419
|
2520
LL | const BAR: u32 = IMPL_REF_BAR;
2621
| ^^^^^^^^^^^^^^
27-
note: ...which requires elaborating drops for `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
28-
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:22
22+
= note: ...which again requires checking if `IMPL_REF_BAR` is a trivial const, completing the cycle
23+
note: cycle used when simplifying constant for the type system `IMPL_REF_BAR`
24+
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
2925
|
30-
LL | const BAR: u32 = IMPL_REF_BAR;
31-
| ^^^^^^^^^^^^
32-
= note: ...which again requires simplifying constant for the type system `IMPL_REF_BAR`, completing the cycle
33-
= note: cycle used when running analysis passes on this crate
26+
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
27+
| ^^^^^^^^^^^^^^^^^^^^^^^
3428
= 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
3529

3630
error: aborting due to 1 previous error

tests/ui/issues/issue-17252.stderr

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,39 @@
1-
error[E0391]: cycle detected when simplifying constant for the type system `FOO`
1+
error[E0391]: cycle detected when checking if `FOO` is a trivial const
22
--> $DIR/issue-17252.rs:1:1
33
|
44
LL | const FOO: usize = FOO;
55
| ^^^^^^^^^^^^^^^^
66
|
7-
note: ...which requires const-evaluating + checking `FOO`...
8-
--> $DIR/issue-17252.rs:1:20
7+
note: ...which requires building MIR for `FOO`...
8+
--> $DIR/issue-17252.rs:1:1
9+
|
10+
LL | const FOO: usize = FOO;
11+
| ^^^^^^^^^^^^^^^^
12+
= note: ...which again requires checking if `FOO` is a trivial const, completing the cycle
13+
note: cycle used when simplifying constant for the type system `FOO`
14+
--> $DIR/issue-17252.rs:1:1
915
|
1016
LL | const FOO: usize = FOO;
11-
| ^^^
12-
= note: ...which again requires simplifying constant for the type system `FOO`, completing the cycle
13-
= note: cycle used when running analysis passes on this crate
17+
| ^^^^^^^^^^^^^^^^
1418
= 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
1519

16-
error[E0391]: cycle detected when simplifying constant for the type system `main::BAR`
20+
error[E0391]: cycle detected when checking if `main::BAR` is a trivial const
1721
--> $DIR/issue-17252.rs:6:9
1822
|
1923
LL | const BAR: usize = BAR;
2024
| ^^^^^^^^^^^^^^^^
2125
|
22-
note: ...which requires const-evaluating + checking `main::BAR`...
23-
--> $DIR/issue-17252.rs:6:28
26+
note: ...which requires building MIR for `main::BAR`...
27+
--> $DIR/issue-17252.rs:6:9
28+
|
29+
LL | const BAR: usize = BAR;
30+
| ^^^^^^^^^^^^^^^^
31+
= note: ...which again requires checking if `main::BAR` is a trivial const, completing the cycle
32+
note: cycle used when simplifying constant for the type system `main::BAR`
33+
--> $DIR/issue-17252.rs:6:9
2434
|
2535
LL | const BAR: usize = BAR;
26-
| ^^^
27-
= note: ...which again requires simplifying constant for the type system `main::BAR`, completing the cycle
28-
= note: cycle used when running analysis passes on this crate
36+
| ^^^^^^^^^^^^^^^^
2937
= 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
3038

3139
error: aborting due to 2 previous errors

tests/ui/parallel-rustc/cycle_crash-issue-135870.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
//@ compile-flags: -Z threads=2
44
//@ compare-output-by-lines
55

6-
const FOO: usize = FOO; //~ ERROR cycle detected when simplifying constant for the type system `FOO`
6+
const FOO: usize = FOO; //~ ERROR cycle detected
77

88
fn main() {}
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1-
error[E0391]: cycle detected when simplifying constant for the type system `FOO`
21
--> $DIR/cycle_crash-issue-135870.rs:6:1
32
|
43
LL | const FOO: usize = FOO;
54
| ^^^^^^^^^^^^^^^^
65
|
7-
note: ...which requires const-evaluating + checking `FOO`...
8-
--> $DIR/cycle_crash-issue-135870.rs:6:20
96
|
107
LL | const FOO: usize = FOO;
11-
| ^^^
12-
= note: ...which again requires simplifying constant for the type system `FOO`, completing the cycle
13-
= note: cycle used when running analysis passes on this crate
148
= 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
159

1610
error: aborting due to 1 previous error
1711

18-
For more information about this error, try `rustc --explain E0391`.
12+
For more information about this error, try `rustc --explain E0391`.

tests/ui/recursion/issue-23302-3.stderr

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
1-
error[E0391]: cycle detected when simplifying constant for the type system `A`
1+
error[E0391]: cycle detected when checking if `A` is a trivial const
22
--> $DIR/issue-23302-3.rs:1:1
33
|
44
LL | const A: i32 = B;
55
| ^^^^^^^^^^^^
66
|
7-
note: ...which requires const-evaluating + checking `A`...
8-
--> $DIR/issue-23302-3.rs:1:16
7+
note: ...which requires building MIR for `A`...
8+
--> $DIR/issue-23302-3.rs:1:1
99
|
1010
LL | const A: i32 = B;
11-
| ^
12-
note: ...which requires simplifying constant for the type system `B`...
11+
| ^^^^^^^^^^^^
12+
note: ...which requires checking if `B` is a trivial const...
1313
--> $DIR/issue-23302-3.rs:3:1
1414
|
1515
LL | const B: i32 = A;
1616
| ^^^^^^^^^^^^
17-
note: ...which requires const-evaluating + checking `B`...
18-
--> $DIR/issue-23302-3.rs:3:16
17+
note: ...which requires building MIR for `B`...
18+
--> $DIR/issue-23302-3.rs:3:1
1919
|
2020
LL | const B: i32 = A;
21-
| ^
22-
= note: ...which again requires simplifying constant for the type system `A`, completing the cycle
23-
= note: cycle used when running analysis passes on this crate
21+
| ^^^^^^^^^^^^
22+
= note: ...which again requires checking if `A` is a trivial const, completing the cycle
23+
note: cycle used when simplifying constant for the type system `A`
24+
--> $DIR/issue-23302-3.rs:1:1
25+
|
26+
LL | const A: i32 = B;
27+
| ^^^^^^^^^^^^
2428
= 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
2529

2630
error: aborting due to 1 previous error

0 commit comments

Comments
 (0)