Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store static initializers in metadata instead of the MIR of statics. #116564

Merged
merged 6 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add new query just for static initializers
  • Loading branch information
oli-obk committed Feb 15, 2024
commit 95004e5ae285c1f514b908250db319c2c086141c
7 changes: 7 additions & 0 deletions compiler/rustc_const_eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ pub fn provide(providers: &mut Providers) {
const_eval::provide(providers);
providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
providers.eval_static_initializer_raw = |tcx, def_id| {
assert!(tcx.is_static(def_id));
let instance = ty::Instance::mono(tcx, def_id);
let gid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
let param_env = ty::ParamEnv::reveal_all();
Ok(tcx.eval_to_allocation_raw(param_env.and(gid))?.alloc_id)
};
providers.hooks.const_caller_location = util::caller_location::const_caller_location_provider;
providers.eval_to_valtree = |tcx, param_env_and_value| {
let (param_env, raw) = param_env_and_value.into_parts();
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ impl Into<ErrorGuaranteed> for ReportedErrorInfo {
TrivialTypeTraversalImpls! { ErrorHandled }

pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>;
pub type EvalStaticInitializerRawResult = Result<AllocId, ErrorHandled>;
pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
/// `Ok(None)` indicates the constant was fine, but the valtree couldn't be constructed.
/// This is needed in `thir::pattern::lower_inline_const`.
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_middle/src/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,12 @@ use crate::ty::GenericArgKind;
use crate::ty::{self, Instance, Ty, TyCtxt};

pub use self::error::{
BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult,
EvalToConstValueResult, EvalToValTreeResult, ExpectedKind, InterpError, InterpErrorInfo,
InterpResult, InvalidMetaKind, InvalidProgramInfo, MachineStopType, Misalignment, PointerKind,
ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo,
UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind,
BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, EvalStaticInitializerRawResult,
EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, ExpectedKind,
InterpError, InterpErrorInfo, InterpResult, InvalidMetaKind, InvalidProgramInfo,
MachineStopType, Misalignment, PointerKind, ReportedErrorInfo, ResourceExhaustionInfo,
ScalarSizeMismatch, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo,
ValidationErrorKind,
};

pub use self::value::Scalar;
Expand Down
24 changes: 3 additions & 21 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,22 +194,8 @@ impl<'tcx> TyCtxtAt<'tcx> {
) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
trace!("eval_static_initializer: Need to compute {:?}", def_id);
assert!(self.is_static(def_id));
let instance = ty::Instance::mono(*self, def_id);
let gid = GlobalId { instance, promoted: None };
self.eval_to_allocation(gid, ty::ParamEnv::reveal_all())
}

/// Evaluate anything constant-like, returning the allocation of the final memory.
///
/// The span is entirely ignored here, but still helpful for better query cycle errors.
fn eval_to_allocation(
self,
gid: GlobalId<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
trace!("eval_to_allocation: Need to compute {:?}", gid);
let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())
let alloc_id = self.eval_static_initializer_raw(def_id)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling eval_to_allocation to eval a static would be wrong now, right?

Should we hide eval_to_allocation better? It should probably only be called internally by the eval_const queries now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm adding asserts right now 😆 CI is failing because of "mis-use" (after this PR it would be mis-use) of the other queries for statics

Ok(self.global_alloc(alloc_id).unwrap_memory())
}
}

Expand Down Expand Up @@ -237,10 +223,6 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
pub fn eval_static_initializer(self, def_id: DefId) {
trace!("eval_static_initializer: Need to compute {:?}", def_id);
assert!(self.tcx.is_static(def_id));
let instance = ty::Instance::mono(self.tcx, def_id);
let gid = GlobalId { instance, promoted: None };
let param_env = ty::ParamEnv::reveal_all();
trace!("eval_to_allocation: Need to compute {:?}", gid);
self.eval_to_allocation_raw(param_env.and(gid))
self.eval_static_initializer_raw(def_id);
}
}
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/query/erase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ trivial! {
rustc_middle::mir::interpret::CtfeProvenance,
rustc_middle::mir::interpret::ErrorHandled,
rustc_middle::mir::interpret::LitToConstError,
rustc_middle::mir::interpret::EvalStaticInitializerRawResult,
rustc_middle::thir::ExprId,
rustc_middle::traits::CodegenObligationError,
rustc_middle::traits::EvaluationResult,
Expand Down
14 changes: 12 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ use crate::middle::stability::{self, DeprecationEntry};
use crate::mir;
use crate::mir::interpret::GlobalId;
use crate::mir::interpret::{
EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult,
EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
EvalToValTreeResult,
};
use crate::mir::interpret::{LitToConstError, LitToConstInput};
use crate::mir::mono::CodegenUnit;
Expand Down Expand Up @@ -1061,7 +1062,7 @@ rustc_queries! {

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

/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
query eval_static_initializer_raw(key: DefId) -> EvalStaticInitializerRawResult {
desc { |tcx|
"evaluating initializer of static `{}`",
tcx.def_path_str(key)
}
cache_on_disk_if { key.is_local() }
}

/// Evaluates const items or anonymous constants
/// (such as enum variant explicit discriminants or array lengths)
/// into a representation suitable for the type system and const generics.
Expand Down
11 changes: 8 additions & 3 deletions tests/ui/consts/recursive-zst-static.default.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
error[E0391]: cycle detected when const-evaluating + checking `FOO`
error[E0391]: cycle detected when evaluating initializer of static `FOO`
--> $DIR/recursive-zst-static.rs:10:1
|
LL | static FOO: () = FOO;
| ^^^^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `FOO`...
--> $DIR/recursive-zst-static.rs:10:18
|
LL | static FOO: () = FOO;
| ^^^
|
= note: ...which immediately requires const-evaluating + checking `FOO` again
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
note: cycle used when linting top-level module
--> $DIR/recursive-zst-static.rs:10:1
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/consts/recursive-zst-static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// can depend on this fact and will thus do unsound things when it is violated.
// See https://github.com/rust-lang/rust/issues/71078 for more details.

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

fn main() {
FOO
Expand Down
11 changes: 8 additions & 3 deletions tests/ui/consts/recursive-zst-static.unleash.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
error[E0391]: cycle detected when const-evaluating + checking `FOO`
error[E0391]: cycle detected when evaluating initializer of static `FOO`
--> $DIR/recursive-zst-static.rs:10:1
|
LL | static FOO: () = FOO;
| ^^^^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `FOO`...
--> $DIR/recursive-zst-static.rs:10:18
|
LL | static FOO: () = FOO;
| ^^^
|
= note: ...which immediately requires const-evaluating + checking `FOO` again
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
note: cycle used when linting top-level module
--> $DIR/recursive-zst-static.rs:10:1
|
Expand Down
11 changes: 8 additions & 3 deletions tests/ui/consts/write-to-static-mut-in-static.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ error[E0080]: could not evaluate static initializer
LL | pub static mut B: () = unsafe { A = 1; };
| ^^^^^ modifying a static's initial value from another static's initializer

error[E0391]: cycle detected when const-evaluating + checking `C`
error[E0391]: cycle detected when evaluating initializer of static `C`
--> $DIR/write-to-static-mut-in-static.rs:5:1
|
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
| ^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `C`...
--> $DIR/write-to-static-mut-in-static.rs:5:34
|
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
| ^^^^^
|
= note: ...which immediately requires const-evaluating + checking `C` again
= note: ...which again requires evaluating initializer of static `C`, completing the cycle
note: cycle used when linting top-level module
--> $DIR/write-to-static-mut-in-static.rs:1:1
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/recursion/recursive-static-definition.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub static FOO: u32 = FOO;
//~^ ERROR cycle detected when const-evaluating + checking `FOO`
//~^ ERROR cycle detected when evaluating initializer of static `FOO`

fn main() {}
11 changes: 8 additions & 3 deletions tests/ui/recursion/recursive-static-definition.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
error[E0391]: cycle detected when const-evaluating + checking `FOO`
error[E0391]: cycle detected when evaluating initializer of static `FOO`
--> $DIR/recursive-static-definition.rs:1:1
|
LL | pub static FOO: u32 = FOO;
| ^^^^^^^^^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `FOO`...
--> $DIR/recursive-static-definition.rs:1:23
|
LL | pub static FOO: u32 = FOO;
| ^^^
|
= note: ...which immediately requires const-evaluating + checking `FOO` again
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
note: cycle used when linting top-level module
--> $DIR/recursive-static-definition.rs:1:1
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/treat-err-as-bug/err.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ error: the compiler unexpectedly panicked. this is a bug.

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