Return ConstAllocation from eval_static_initializer query directly
This commit is contained in:
parent
be6ccf13e3
commit
e2386270df
18 changed files with 53 additions and 82 deletions
|
@ -8,6 +8,7 @@ use rustc_middle::traits::Reveal;
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::abi::{self, Abi};
|
use rustc_target::abi::{self, Abi};
|
||||||
|
|
||||||
|
@ -249,11 +250,36 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
|
||||||
tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key))
|
tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(tcx), level = "debug")]
|
||||||
|
pub fn eval_static_initializer_provider<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
) -> ::rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'tcx> {
|
||||||
|
assert!(tcx.is_static(def_id.to_def_id()));
|
||||||
|
|
||||||
|
let instance = ty::Instance::mono(tcx, def_id.to_def_id());
|
||||||
|
let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
|
||||||
|
let ecx = InterpCx::new(
|
||||||
|
tcx,
|
||||||
|
tcx.def_span(def_id),
|
||||||
|
ty::ParamEnv::reveal_all(),
|
||||||
|
// Statics (and promoteds inside statics) may access other statics, because unlike consts
|
||||||
|
// they do not have to behave "as if" they were evaluated at runtime.
|
||||||
|
CompileTimeInterpreter::new(CanAccessMutGlobal::Yes, CheckAlignment::Error),
|
||||||
|
);
|
||||||
|
let alloc_id = eval_in_interpreter(ecx, cid, true)?.alloc_id;
|
||||||
|
let alloc = tcx.global_alloc(alloc_id).unwrap_memory();
|
||||||
|
Ok(alloc)
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(skip(tcx), level = "debug")]
|
#[instrument(skip(tcx), level = "debug")]
|
||||||
pub fn eval_to_allocation_raw_provider<'tcx>(
|
pub fn eval_to_allocation_raw_provider<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
||||||
) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
|
) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
|
||||||
|
// This shouldn't be used for statics, since statics are conceptually places,
|
||||||
|
// not values -- so what we do here could break pointer identity.
|
||||||
|
assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));
|
||||||
// Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
|
// Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
|
||||||
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
|
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
|
||||||
// types that are not specified in the opaque type.
|
// types that are not specified in the opaque type.
|
||||||
|
|
|
@ -40,13 +40,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
const_eval::provide(providers);
|
const_eval::provide(providers);
|
||||||
providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
|
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_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
|
||||||
providers.eval_static_initializer_raw = |tcx, def_id| {
|
providers.eval_static_initializer = const_eval::eval_static_initializer_provider;
|
||||||
assert!(tcx.is_static(def_id.to_def_id()));
|
|
||||||
let instance = ty::Instance::mono(tcx, def_id.to_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.hooks.const_caller_location = util::caller_location::const_caller_location_provider;
|
||||||
providers.eval_to_valtree = |tcx, param_env_and_value| {
|
providers.eval_to_valtree = |tcx, param_env_and_value| {
|
||||||
let (param_env, raw) = param_env_and_value.into_parts();
|
let (param_env, raw) = param_env_and_value.into_parts();
|
||||||
|
|
|
@ -250,14 +250,14 @@ provide! { tcx, def_id, other, cdata,
|
||||||
fn_arg_names => { table }
|
fn_arg_names => { table }
|
||||||
coroutine_kind => { table_direct }
|
coroutine_kind => { table_direct }
|
||||||
coroutine_for_closure => { table }
|
coroutine_for_closure => { table }
|
||||||
eval_static_initializer_raw => {
|
eval_static_initializer => {
|
||||||
Ok(cdata
|
Ok(cdata
|
||||||
.root
|
.root
|
||||||
.tables
|
.tables
|
||||||
.eval_static_initializer_raw
|
.eval_static_initializer
|
||||||
.get(cdata, def_id.index)
|
.get(cdata, def_id.index)
|
||||||
.map(|lazy| lazy.decode((cdata, tcx)))
|
.map(|lazy| lazy.decode((cdata, tcx)))
|
||||||
.unwrap_or_else(|| panic!("{def_id:?} does not have eval_static_initializer_raw")))
|
.unwrap_or_else(|| panic!("{def_id:?} does not have eval_static_initializer")))
|
||||||
}
|
}
|
||||||
trait_def => { table }
|
trait_def => { table }
|
||||||
deduced_param_attrs => { table }
|
deduced_param_attrs => { table }
|
||||||
|
|
|
@ -1454,8 +1454,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
if let DefKind::Static(_) = def_kind {
|
if let DefKind::Static(_) = def_kind {
|
||||||
if !self.tcx.is_foreign_item(def_id) {
|
if !self.tcx.is_foreign_item(def_id) {
|
||||||
let data = self.tcx.eval_static_initializer_raw(def_id).unwrap();
|
let data = self.tcx.eval_static_initializer(def_id).unwrap();
|
||||||
record!(self.tables.eval_static_initializer_raw[def_id] <- data);
|
record!(self.tables.eval_static_initializer[def_id] <- data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
|
if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
|
||||||
|
|
|
@ -443,7 +443,7 @@ define_tables! {
|
||||||
fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
|
fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
|
||||||
coroutine_kind: Table<DefIndex, hir::CoroutineKind>,
|
coroutine_kind: Table<DefIndex, hir::CoroutineKind>,
|
||||||
coroutine_for_closure: Table<DefIndex, RawDefId>,
|
coroutine_for_closure: Table<DefIndex, RawDefId>,
|
||||||
eval_static_initializer_raw: Table<DefIndex, LazyValue<mir::interpret::AllocId>>,
|
eval_static_initializer: Table<DefIndex, LazyValue<mir::interpret::ConstAllocation<'static>>>,
|
||||||
trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
|
trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
|
||||||
trait_item_def_id: Table<DefIndex, RawDefId>,
|
trait_item_def_id: Table<DefIndex, RawDefId>,
|
||||||
expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
|
expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{AllocId, AllocRange, Pointer, Scalar};
|
use super::{AllocId, AllocRange, ConstAllocation, Pointer, Scalar};
|
||||||
|
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use crate::mir::{ConstAlloc, ConstValue};
|
use crate::mir::{ConstAlloc, ConstValue};
|
||||||
|
@ -83,7 +83,7 @@ impl Into<ErrorGuaranteed> for ReportedErrorInfo {
|
||||||
TrivialTypeTraversalImpls! { ErrorHandled }
|
TrivialTypeTraversalImpls! { ErrorHandled }
|
||||||
|
|
||||||
pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>;
|
pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>;
|
||||||
pub type EvalStaticInitializerRawResult = Result<AllocId, ErrorHandled>;
|
pub type EvalStaticInitializerRawResult<'tcx> = Result<ConstAllocation<'tcx>, ErrorHandled>;
|
||||||
pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
|
pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
|
||||||
/// `Ok(None)` indicates the constant was fine, but the valtree couldn't be constructed.
|
/// `Ok(None)` indicates the constant was fine, but the valtree couldn't be constructed.
|
||||||
/// This is needed in `thir::pattern::lower_inline_const`.
|
/// This is needed in `thir::pattern::lower_inline_const`.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId};
|
use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId};
|
||||||
|
|
||||||
use crate::mir;
|
use crate::mir;
|
||||||
use crate::query::{TyCtxtAt, TyCtxtEnsure};
|
use crate::query::TyCtxtEnsure;
|
||||||
use crate::ty::visit::TypeVisitableExt;
|
use crate::ty::visit::TypeVisitableExt;
|
||||||
use crate::ty::GenericArgs;
|
use crate::ty::GenericArgs;
|
||||||
use crate::ty::{self, TyCtxt};
|
use crate::ty::{self, TyCtxt};
|
||||||
|
@ -173,30 +173,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self.eval_to_valtree(inputs)
|
self.eval_to_valtree(inputs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn eval_static_initializer(
|
|
||||||
self,
|
|
||||||
def_id: DefId,
|
|
||||||
) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
|
|
||||||
self.at(DUMMY_SP).eval_static_initializer(def_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TyCtxtAt<'tcx> {
|
|
||||||
/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
|
|
||||||
///
|
|
||||||
/// The span is entirely ignored here, but still helpful for better query cycle errors.
|
|
||||||
pub fn eval_static_initializer(
|
|
||||||
self,
|
|
||||||
def_id: DefId,
|
|
||||||
) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
|
|
||||||
trace!("eval_static_initializer: Need to compute {:?}", def_id);
|
|
||||||
assert!(self.is_static(def_id));
|
|
||||||
let alloc_id = self.eval_static_initializer_raw(def_id)?;
|
|
||||||
Ok(self.global_alloc(alloc_id).unwrap_memory())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TyCtxtEnsure<'tcx> {
|
impl<'tcx> TyCtxtEnsure<'tcx> {
|
||||||
|
@ -218,11 +194,4 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
|
||||||
let inputs = self.tcx.erase_regions(param_env.and(cid));
|
let inputs = self.tcx.erase_regions(param_env.and(cid));
|
||||||
self.eval_to_const_value_raw(inputs)
|
self.eval_to_const_value_raw(inputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
|
|
||||||
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));
|
|
||||||
self.eval_static_initializer_raw(def_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
|
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
|
||||||
|
|
||||||
use crate::mir::interpret::{AllocRange, ConstAllocation, Scalar};
|
use crate::mir::interpret::{AllocRange, Scalar};
|
||||||
use crate::mir::visit::MirVisitable;
|
use crate::mir::visit::MirVisitable;
|
||||||
use crate::ty::codec::{TyDecoder, TyEncoder};
|
use crate::ty::codec::{TyDecoder, TyEncoder};
|
||||||
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
|
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
|
||||||
|
|
|
@ -4,6 +4,8 @@ use std::fs;
|
||||||
use std::io::{self, Write as _};
|
use std::io::{self, Write as _};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use crate::mir::interpret::ConstAllocation;
|
||||||
|
|
||||||
use super::graphviz::write_mir_fn_graphviz;
|
use super::graphviz::write_mir_fn_graphviz;
|
||||||
use rustc_ast::InlineAsmTemplatePiece;
|
use rustc_ast::InlineAsmTemplatePiece;
|
||||||
use rustc_middle::mir::interpret::{
|
use rustc_middle::mir::interpret::{
|
||||||
|
|
|
@ -277,7 +277,6 @@ trivial! {
|
||||||
rustc_middle::mir::interpret::CtfeProvenance,
|
rustc_middle::mir::interpret::CtfeProvenance,
|
||||||
rustc_middle::mir::interpret::ErrorHandled,
|
rustc_middle::mir::interpret::ErrorHandled,
|
||||||
rustc_middle::mir::interpret::LitToConstError,
|
rustc_middle::mir::interpret::LitToConstError,
|
||||||
rustc_middle::mir::interpret::EvalStaticInitializerRawResult,
|
|
||||||
rustc_middle::thir::ExprId,
|
rustc_middle::thir::ExprId,
|
||||||
rustc_middle::traits::CodegenObligationError,
|
rustc_middle::traits::CodegenObligationError,
|
||||||
rustc_middle::traits::EvaluationResult,
|
rustc_middle::traits::EvaluationResult,
|
||||||
|
@ -338,6 +337,7 @@ tcx_lifetime! {
|
||||||
rustc_middle::mir::ConstValue,
|
rustc_middle::mir::ConstValue,
|
||||||
rustc_middle::mir::interpret::GlobalId,
|
rustc_middle::mir::interpret::GlobalId,
|
||||||
rustc_middle::mir::interpret::LitToConstInput,
|
rustc_middle::mir::interpret::LitToConstInput,
|
||||||
|
rustc_middle::mir::interpret::EvalStaticInitializerRawResult,
|
||||||
rustc_middle::traits::query::MethodAutoderefStepsResult,
|
rustc_middle::traits::query::MethodAutoderefStepsResult,
|
||||||
rustc_middle::traits::query::type_op::AscribeUserType,
|
rustc_middle::traits::query::type_op::AscribeUserType,
|
||||||
rustc_middle::traits::query::type_op::Eq,
|
rustc_middle::traits::query::type_op::Eq,
|
||||||
|
|
|
@ -1073,7 +1073,7 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
|
/// Evaluate a static's initializer, returning the allocation of the initializer's memory.
|
||||||
query eval_static_initializer_raw(key: DefId) -> EvalStaticInitializerRawResult {
|
query eval_static_initializer(key: DefId) -> EvalStaticInitializerRawResult<'tcx> {
|
||||||
desc { |tcx|
|
desc { |tcx|
|
||||||
"evaluating initializer of static `{}`",
|
"evaluating initializer of static `{}`",
|
||||||
tcx.def_path_str(key)
|
tcx.def_path_str(key)
|
||||||
|
|
|
@ -63,7 +63,6 @@ trivially_parameterized_over_tcx! {
|
||||||
crate::middle::lib_features::FeatureStability,
|
crate::middle::lib_features::FeatureStability,
|
||||||
crate::middle::resolve_bound_vars::ObjectLifetimeDefault,
|
crate::middle::resolve_bound_vars::ObjectLifetimeDefault,
|
||||||
crate::mir::ConstQualifs,
|
crate::mir::ConstQualifs,
|
||||||
crate::mir::interpret::AllocId,
|
|
||||||
ty::AssocItemContainer,
|
ty::AssocItemContainer,
|
||||||
ty::Asyncness,
|
ty::Asyncness,
|
||||||
ty::DeducedParamAttrs,
|
ty::DeducedParamAttrs,
|
||||||
|
@ -127,6 +126,7 @@ parameterized_over_tcx! {
|
||||||
crate::middle::exported_symbols::ExportedSymbol,
|
crate::middle::exported_symbols::ExportedSymbol,
|
||||||
crate::mir::Body,
|
crate::mir::Body,
|
||||||
crate::mir::CoroutineLayout,
|
crate::mir::CoroutineLayout,
|
||||||
|
crate::mir::interpret::ConstAllocation,
|
||||||
ty::Ty,
|
ty::Ty,
|
||||||
ty::FnSig,
|
ty::FnSig,
|
||||||
ty::GenericPredicates,
|
ty::GenericPredicates,
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
error[E0391]: cycle detected when evaluating initializer of static `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
|
--> $DIR/recursive-zst-static.rs:10:18
|
||||||
|
|
|
|
||||||
LL | static FOO: () = FOO;
|
LL | static FOO: () = FOO;
|
||||||
| ^^^
|
| ^^^
|
||||||
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
|
|
|
||||||
|
= note: ...which immediately requires evaluating initializer of static `FOO` again
|
||||||
note: cycle used when linting top-level module
|
note: cycle used when linting top-level module
|
||||||
--> $DIR/recursive-zst-static.rs:10:1
|
--> $DIR/recursive-zst-static.rs:10:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
error[E0391]: cycle detected when evaluating initializer of static `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
|
--> $DIR/recursive-zst-static.rs:10:18
|
||||||
|
|
|
|
||||||
LL | static FOO: () = FOO;
|
LL | static FOO: () = FOO;
|
||||||
| ^^^
|
| ^^^
|
||||||
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
|
|
|
||||||
|
= note: ...which immediately requires evaluating initializer of static `FOO` again
|
||||||
note: cycle used when linting top-level module
|
note: cycle used when linting top-level module
|
||||||
--> $DIR/recursive-zst-static.rs:10:1
|
--> $DIR/recursive-zst-static.rs:10:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -5,17 +5,12 @@ LL | pub static mut B: () = unsafe { A = 1; };
|
||||||
| ^^^^^ modifying a static's initial value from another static's initializer
|
| ^^^^^ modifying a static's initial value from another static's initializer
|
||||||
|
|
||||||
error[E0391]: cycle detected when evaluating initializer of static `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
|
--> $DIR/write-to-static-mut-in-static.rs:5:34
|
||||||
|
|
|
|
||||||
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
|
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
= note: ...which again requires evaluating initializer of static `C`, completing the cycle
|
|
|
||||||
|
= note: ...which immediately requires evaluating initializer of static `C` again
|
||||||
note: cycle used when linting top-level module
|
note: cycle used when linting top-level module
|
||||||
--> $DIR/write-to-static-mut-in-static.rs:1:1
|
--> $DIR/write-to-static-mut-in-static.rs:1:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
error[E0391]: cycle detected when evaluating initializer of static `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
|
--> $DIR/recursive-static-definition.rs:1:23
|
||||||
|
|
|
|
||||||
LL | pub static FOO: u32 = FOO;
|
LL | pub static FOO: u32 = FOO;
|
||||||
| ^^^
|
| ^^^
|
||||||
= note: ...which again requires evaluating initializer of static `FOO`, completing the cycle
|
|
|
||||||
|
= note: ...which immediately requires evaluating initializer of static `FOO` again
|
||||||
note: cycle used when linting top-level module
|
note: cycle used when linting top-level module
|
||||||
--> $DIR/recursive-static-definition.rs:1:1
|
--> $DIR/recursive-static-definition.rs:1:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// compile-flags: -Ztreat-err-as-bug
|
// compile-flags: -Ztreat-err-as-bug
|
||||||
// failure-status: 101
|
// failure-status: 101
|
||||||
// error-pattern: aborting due to `-Z treat-err-as-bug=1`
|
// error-pattern: aborting due to `-Z treat-err-as-bug=1`
|
||||||
// error-pattern: [eval_to_allocation_raw] const-evaluating + checking `C`
|
// error-pattern: [eval_static_initializer] evaluating initializer of static `C`
|
||||||
// normalize-stderr-test "note: .*\n\n" -> ""
|
// normalize-stderr-test "note: .*\n\n" -> ""
|
||||||
// normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> ""
|
// normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> ""
|
||||||
// rustc-env:RUST_BACKTRACE=0
|
// rustc-env:RUST_BACKTRACE=0
|
||||||
|
|
|
@ -7,6 +7,6 @@ LL | pub static C: u32 = 0 - 1;
|
||||||
error: the compiler unexpectedly panicked. this is a bug.
|
error: the compiler unexpectedly panicked. this is a bug.
|
||||||
|
|
||||||
query stack during panic:
|
query stack during panic:
|
||||||
#0 [eval_to_allocation_raw] const-evaluating + checking `C`
|
#0 [eval_static_initializer] evaluating initializer of static `C`
|
||||||
#1 [eval_static_initializer_raw] evaluating initializer of static `C`
|
#1 [lint_mod] linting top-level module
|
||||||
end of query stack
|
end of query stack
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue