Skip to content

Commit 95004e5

Browse files
committed
Add new query just for static initializers
1 parent fc9d1a8 commit 95004e5

13 files changed

+65
-43
lines changed

compiler/rustc_const_eval/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ pub fn provide(providers: &mut Providers) {
4040
const_eval::provide(providers);
4141
providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
4242
providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
43+
providers.eval_static_initializer_raw = |tcx, def_id| {
44+
assert!(tcx.is_static(def_id));
45+
let instance = ty::Instance::mono(tcx, def_id);
46+
let gid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
47+
let param_env = ty::ParamEnv::reveal_all();
48+
Ok(tcx.eval_to_allocation_raw(param_env.and(gid))?.alloc_id)
49+
};
4350
providers.hooks.const_caller_location = util::caller_location::const_caller_location_provider;
4451
providers.eval_to_valtree = |tcx, param_env_and_value| {
4552
let (param_env, raw) = param_env_and_value.into_parts();

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

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ impl Into<ErrorGuaranteed> for ReportedErrorInfo {
8383
TrivialTypeTraversalImpls! { ErrorHandled }
8484

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

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

+6-5
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,12 @@ use crate::ty::GenericArgKind;
142142
use crate::ty::{self, Instance, Ty, TyCtxt};
143143

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

152153
pub use self::value::Scalar;

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

+3-21
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

+1
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ trivial! {
277277
rustc_middle::mir::interpret::CtfeProvenance,
278278
rustc_middle::mir::interpret::ErrorHandled,
279279
rustc_middle::mir::interpret::LitToConstError,
280+
rustc_middle::mir::interpret::EvalStaticInitializerRawResult,
280281
rustc_middle::thir::ExprId,
281282
rustc_middle::traits::CodegenObligationError,
282283
rustc_middle::traits::EvaluationResult,

compiler/rustc_middle/src/query/mod.rs

+12-2
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;
@@ -1061,7 +1062,7 @@ rustc_queries! {
10611062

10621063
/// Evaluates a constant and returns the computed allocation.
10631064
///
1064-
/// **Do not use this** directly, use the `tcx.eval_static_initializer` wrapper.
1065+
/// **Do not use this** directly, use the `eval_to_const_value` or `eval_to_valtree` instead.
10651066
query eval_to_allocation_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
10661067
-> EvalToAllocationRawResult<'tcx> {
10671068
desc { |tcx|
@@ -1071,6 +1072,15 @@ rustc_queries! {
10711072
cache_on_disk_if { true }
10721073
}
10731074

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

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

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
error[E0391]: cycle detected when const-evaluating + checking `FOO`
1+
error[E0391]: cycle detected when evaluating initializer of static `FOO`
2+
--> $DIR/recursive-zst-static.rs:10:1
3+
|
4+
LL | static FOO: () = FOO;
5+
| ^^^^^^^^^^^^^^
6+
|
7+
note: ...which requires const-evaluating + checking `FOO`...
28
--> $DIR/recursive-zst-static.rs:10:18
39
|
410
LL | static FOO: () = FOO;
511
| ^^^
6-
|
7-
= note: ...which immediately requires const-evaluating + checking `FOO` again
12+
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
813
note: cycle used when linting top-level module
914
--> $DIR/recursive-zst-static.rs:10:1
1015
|

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

+1-1
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

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
error[E0391]: cycle detected when const-evaluating + checking `FOO`
1+
error[E0391]: cycle detected when evaluating initializer of static `FOO`
2+
--> $DIR/recursive-zst-static.rs:10:1
3+
|
4+
LL | static FOO: () = FOO;
5+
| ^^^^^^^^^^^^^^
6+
|
7+
note: ...which requires const-evaluating + checking `FOO`...
28
--> $DIR/recursive-zst-static.rs:10:18
39
|
410
LL | static FOO: () = FOO;
511
| ^^^
6-
|
7-
= note: ...which immediately requires const-evaluating + checking `FOO` again
12+
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
813
note: cycle used when linting top-level module
914
--> $DIR/recursive-zst-static.rs:10:1
1015
|

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

+8-3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@ 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`
8+
--> $DIR/write-to-static-mut-in-static.rs:5:1
9+
|
10+
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
11+
| ^^^^^^^^^^^^^^^^^^^^^
12+
|
13+
note: ...which requires const-evaluating + checking `C`...
814
--> $DIR/write-to-static-mut-in-static.rs:5:34
915
|
1016
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
1117
| ^^^^^
12-
|
13-
= note: ...which immediately requires const-evaluating + checking `C` again
18+
= note: ...which again requires evaluating initializer of static `C`, completing the cycle
1419
note: cycle used when linting top-level module
1520
--> $DIR/write-to-static-mut-in-static.rs:1:1
1621
|
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

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
error[E0391]: cycle detected when const-evaluating + checking `FOO`
1+
error[E0391]: cycle detected when evaluating initializer of static `FOO`
2+
--> $DIR/recursive-static-definition.rs:1:1
3+
|
4+
LL | pub static FOO: u32 = FOO;
5+
| ^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: ...which requires const-evaluating + checking `FOO`...
28
--> $DIR/recursive-static-definition.rs:1:23
39
|
410
LL | pub static FOO: u32 = FOO;
511
| ^^^
6-
|
7-
= note: ...which immediately requires const-evaluating + checking `FOO` again
12+
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
813
note: cycle used when linting top-level module
914
--> $DIR/recursive-static-definition.rs:1:1
1015
|

tests/ui/treat-err-as-bug/err.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ error: the compiler unexpectedly panicked. this is a bug.
88

99
query stack during panic:
1010
#0 [eval_to_allocation_raw] const-evaluating + checking `C`
11-
#1 [lint_mod] linting top-level module
11+
#1 [eval_static_initializer_raw] evaluating initializer of static `C`
1212
end of query stack

0 commit comments

Comments
 (0)