Skip to content

Commit 2fde99e

Browse files
committed
Add new query just for static initializers
1 parent 093b9d5 commit 2fde99e

File tree

12 files changed

+58
-37
lines changed

12 files changed

+58
-37
lines changed

compiler/rustc_const_eval/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ pub fn provide(providers: &mut Providers) {
4646
const_eval::provide(providers);
4747
providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
4848
providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
49+
providers.eval_static_initializer_raw = |tcx, def_id| {
50+
assert!(tcx.is_static(def_id.to_def_id()));
51+
let instance = ty::Instance::mono(tcx, def_id.to_def_id());
52+
let gid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
53+
let param_env = ty::ParamEnv::reveal_all();
54+
Ok(tcx.eval_to_allocation_raw(param_env.and(gid))?.alloc_id)
55+
};
4956
providers.const_caller_location = const_eval::const_caller_location;
5057
providers.eval_to_valtree = |tcx, param_env_and_value| {
5158
let (param_env, raw) = param_env_and_value.into_parts();

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ impl Into<ErrorGuaranteed> for ReportedErrorInfo {
8585
TrivialTypeTraversalImpls! { ErrorHandled }
8686

8787
pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>;
88+
pub type EvalStaticInitializerRawResult = Result<AllocId, ErrorHandled>;
8889
pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
8990
/// `Ok(None)` indicates the constant was fine, but the valtree couldn't be constructed.
9091
/// This is needed in `thir::pattern::lower_inline_const`.

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,11 @@ use crate::ty::GenericArgKind;
142142
use crate::ty::{self, Instance, Ty, TyCtxt};
143143

144144
pub use self::error::{
145-
struct_error, BadBytesAccess, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult,
146-
EvalToConstValueResult, EvalToValTreeResult, ExpectedKind, InterpError, InterpErrorInfo,
147-
InterpResult, InvalidMetaKind, InvalidProgramInfo, MachineStopType, PointerKind,
148-
ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo,
149-
UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind,
145+
struct_error, BadBytesAccess, CheckInAllocMsg, ErrorHandled, EvalStaticInitializerRawResult,
146+
EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, ExpectedKind,
147+
InterpError, InterpErrorInfo, InterpResult, InvalidMetaKind, InvalidProgramInfo,
148+
MachineStopType, PointerKind, ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch,
149+
UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind,
150150
};
151151

152152
pub use self::value::Scalar;

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

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -194,22 +194,8 @@ impl<'tcx> TyCtxtAt<'tcx> {
194194
) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
195195
trace!("eval_static_initializer: Need to compute {:?}", def_id);
196196
assert!(self.is_static(def_id));
197-
let instance = ty::Instance::mono(*self, def_id);
198-
let gid = GlobalId { instance, promoted: None };
199-
self.eval_to_allocation(gid, ty::ParamEnv::reveal_all())
200-
}
201-
202-
/// Evaluate anything constant-like, returning the allocation of the final memory.
203-
///
204-
/// The span is entirely ignored here, but still helpful for better query cycle errors.
205-
fn eval_to_allocation(
206-
self,
207-
gid: GlobalId<'tcx>,
208-
param_env: ty::ParamEnv<'tcx>,
209-
) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
210-
trace!("eval_to_allocation: Need to compute {:?}", gid);
211-
let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
212-
Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())
197+
let alloc_id = self.eval_static_initializer_raw(def_id)?;
198+
Ok(self.global_alloc(alloc_id).unwrap_memory())
213199
}
214200
}
215201

@@ -237,10 +223,6 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
237223
pub fn eval_static_initializer(self, def_id: DefId) {
238224
trace!("eval_static_initializer: Need to compute {:?}", def_id);
239225
assert!(self.tcx.is_static(def_id));
240-
let instance = ty::Instance::mono(self.tcx, def_id);
241-
let gid = GlobalId { instance, promoted: None };
242-
let param_env = ty::ParamEnv::reveal_all();
243-
trace!("eval_to_allocation: Need to compute {:?}", gid);
244-
self.eval_to_allocation_raw(param_env.and(gid))
226+
self.eval_static_initializer_raw(def_id);
245227
}
246228
}

compiler/rustc_middle/src/query/erase.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ trivial! {
256256
rustc_middle::mir::interpret::AllocId,
257257
rustc_middle::mir::interpret::ErrorHandled,
258258
rustc_middle::mir::interpret::LitToConstError,
259+
rustc_middle::mir::interpret::EvalStaticInitializerRawResult,
259260
rustc_middle::thir::ExprId,
260261
rustc_middle::traits::CodegenObligationError,
261262
rustc_middle::traits::EvaluationResult,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use crate::middle::stability::{self, DeprecationEntry};
2020
use crate::mir;
2121
use crate::mir::interpret::GlobalId;
2222
use crate::mir::interpret::{
23-
EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult,
23+
EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
24+
EvalToValTreeResult,
2425
};
2526
use crate::mir::interpret::{LitToConstError, LitToConstInput};
2627
use crate::mir::mono::CodegenUnit;
@@ -1073,6 +1074,15 @@ rustc_queries! {
10731074
cache_on_disk_if { true }
10741075
}
10751076

1077+
/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
1078+
query eval_static_initializer_raw(key: DefId) -> EvalStaticInitializerRawResult {
1079+
desc { |tcx|
1080+
"evaluating initializer of static `{}`",
1081+
tcx.def_path_str(key)
1082+
}
1083+
cache_on_disk_if { true }
1084+
}
1085+
10761086
/// Evaluates const items or anonymous constants
10771087
/// (such as enum variant explicit discriminants or array lengths)
10781088
/// into a representation suitable for the type system and const generics.

tests/ui/consts/recursive-zst-static.default.stderr

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
error[E0391]: cycle detected when const-evaluating + checking `FOO`
1+
error[E0391]: cycle detected when evaluating initializer of static `FOO`
22
--> $DIR/recursive-zst-static.rs:10:1
33
|
44
LL | static FOO: () = FOO;
55
| ^^^^^^^^^^^^^^
66
|
7+
note: ...which requires const-evaluating + checking `FOO`...
8+
--> $DIR/recursive-zst-static.rs:10:1
9+
|
10+
LL | static FOO: () = FOO;
11+
| ^^^^^^^^^^^^^^
712
note: ...which requires const-evaluating + checking `FOO`...
813
--> $DIR/recursive-zst-static.rs:10:18
914
|
1015
LL | static FOO: () = FOO;
1116
| ^^^
12-
= note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
17+
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
1318
note: cycle used when linting top-level module
1419
--> $DIR/recursive-zst-static.rs:10:1
1520
|

tests/ui/consts/recursive-zst-static.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// can depend on this fact and will thus do unsound things when it is violated.
88
// See https://github.com/rust-lang/rust/issues/71078 for more details.
99

10-
static FOO: () = FOO; //~ cycle detected when const-evaluating + checking `FOO`
10+
static FOO: () = FOO; //~ cycle detected when evaluating initializer of static `FOO`
1111

1212
fn main() {
1313
FOO

tests/ui/consts/recursive-zst-static.unleash.stderr

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
error[E0391]: cycle detected when const-evaluating + checking `FOO`
1+
error[E0391]: cycle detected when evaluating initializer of static `FOO`
22
--> $DIR/recursive-zst-static.rs:10:1
33
|
44
LL | static FOO: () = FOO;
55
| ^^^^^^^^^^^^^^
66
|
7+
note: ...which requires const-evaluating + checking `FOO`...
8+
--> $DIR/recursive-zst-static.rs:10:1
9+
|
10+
LL | static FOO: () = FOO;
11+
| ^^^^^^^^^^^^^^
712
note: ...which requires const-evaluating + checking `FOO`...
813
--> $DIR/recursive-zst-static.rs:10:18
914
|
1015
LL | static FOO: () = FOO;
1116
| ^^^
12-
= note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
17+
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
1318
note: cycle used when linting top-level module
1419
--> $DIR/recursive-zst-static.rs:10:1
1520
|

tests/ui/consts/write-to-static-mut-in-static.stderr

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,23 @@ error[E0080]: could not evaluate static initializer
44
LL | pub static mut B: () = unsafe { A = 1; };
55
| ^^^^^ modifying a static's initial value from another static's initializer
66

7-
error[E0391]: cycle detected when const-evaluating + checking `C`
7+
error[E0391]: cycle detected when evaluating initializer of static `C`
88
--> $DIR/write-to-static-mut-in-static.rs:5:1
99
|
1010
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
1111
| ^^^^^^^^^^^^^^^^^^^^^
1212
|
13+
note: ...which requires const-evaluating + checking `C`...
14+
--> $DIR/write-to-static-mut-in-static.rs:5:1
15+
|
16+
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
17+
| ^^^^^^^^^^^^^^^^^^^^^
1318
note: ...which requires const-evaluating + checking `C`...
1419
--> $DIR/write-to-static-mut-in-static.rs:5:34
1520
|
1621
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
1722
| ^^^^^
18-
= note: ...which again requires const-evaluating + checking `C`, completing the cycle
23+
= note: ...which again requires evaluating initializer of static `C`, completing the cycle
1924
note: cycle used when linting top-level module
2025
--> $DIR/write-to-static-mut-in-static.rs:1:1
2126
|
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
pub static FOO: u32 = FOO;
2-
//~^ ERROR cycle detected when const-evaluating + checking `FOO`
2+
//~^ ERROR cycle detected when evaluating initializer of static `FOO`
33

44
fn main() {}

tests/ui/recursion/recursive-static-definition.stderr

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
error[E0391]: cycle detected when const-evaluating + checking `FOO`
1+
error[E0391]: cycle detected when evaluating initializer of static `FOO`
22
--> $DIR/recursive-static-definition.rs:1:1
33
|
44
LL | pub static FOO: u32 = FOO;
55
| ^^^^^^^^^^^^^^^^^^^
66
|
7+
note: ...which requires const-evaluating + checking `FOO`...
8+
--> $DIR/recursive-static-definition.rs:1:1
9+
|
10+
LL | pub static FOO: u32 = FOO;
11+
| ^^^^^^^^^^^^^^^^^^^
712
note: ...which requires const-evaluating + checking `FOO`...
813
--> $DIR/recursive-static-definition.rs:1:23
914
|
1015
LL | pub static FOO: u32 = FOO;
1116
| ^^^
12-
= note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
17+
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
1318
note: cycle used when linting top-level module
1419
--> $DIR/recursive-static-definition.rs:1:1
1520
|

0 commit comments

Comments
 (0)