diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 3d758cd01d348..46727831a37ec 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -212,6 +212,10 @@ pub fn eval_to_const_value_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> { + assert!( + key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()), + "use `eval_static_initializer` instead" + ); // see comment in eval_to_allocation_raw_provider for what we're doing here if key.param_env.reveal() == Reveal::All { let mut key = key; diff --git a/tests/ui/statics/auxiliary/bad_alloc_id.rs b/tests/ui/statics/auxiliary/bad_alloc_id.rs new file mode 100644 index 0000000000000..059b4d6c6d14a --- /dev/null +++ b/tests/ui/statics/auxiliary/bad_alloc_id.rs @@ -0,0 +1 @@ +pub static mut FOO: Option = Some(42); diff --git a/tests/ui/statics/bad_alloc_id.rs b/tests/ui/statics/bad_alloc_id.rs new file mode 100644 index 0000000000000..11cf8c1bda5ee --- /dev/null +++ b/tests/ui/statics/bad_alloc_id.rs @@ -0,0 +1,28 @@ +// aux-build: bad_alloc_id.rs +// run-pass + +//! This test checks that we do not accidentally duplicate static items' base +//! allocation, even if we go through some projections. This is achieved by +//! never exposing a static item's "memory alloc id". Every static item has two +//! `AllocId`s: One which is backed by `GlobalAlloc::Static` and allows us to +//! figure out the static item. Then we can evaluate that static item, giving us +//! the static's memory-id, which is backed by `GlobalAlloc::Memory`. We always +//! immediately convert to the memory representation and throw away the memory +//! alloc id. + +#![feature(const_mut_refs)] + +extern crate bad_alloc_id; + +static mut BAR: &mut u32 = unsafe { + match &mut bad_alloc_id::FOO { + Some(x) => x, + None => panic!(), + } +}; + +fn main() { + unsafe { + assert_eq!(BAR as *mut u32, bad_alloc_id::FOO.as_mut().unwrap() as *mut u32); + } +}