1use std::sync::atomic::Ordering::Relaxed;
2
3use either::{Left, Right};
4use rustc_abi::{self as abi, BackendRepr};
5use rustc_hir::def::DefKind;
6use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo, ReportedErrorInfo};
7use rustc_middle::mir::{self, ConstAlloc, ConstValue};
8use rustc_middle::query::TyCtxtAt;
9use rustc_middle::throw_inval;
10use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout};
11use rustc_middle::ty::print::with_no_trimmed_paths;
12use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
13use rustc_span::def_id::LocalDefId;
14use rustc_span::{Span, bug};
15use tracing::{debug, instrument, trace};
16
17use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
18use crate::const_eval::CheckAlignment;
19use crate::interpret::{
20 CtfeValidationMode, GlobalId, Immediate, InternError, InternKind, InterpCx, InterpErrorKind,
21 InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, ReturnContinuation, create_static_alloc,
22 ensure_monomorphic_enough, intern_const_alloc_recursive, interp_ok, throw_exhaust,
23};
24use crate::{CTRL_C_RECEIVED, diagnostics};
25
26fn retry_codegen_mode_with_postanalysis<'tcx, K: TypeVisitable<TyCtxt<'tcx>>, V>(
27 key: ty::PseudoCanonicalInput<'tcx, K>,
28 f: impl FnOnce(ty::PseudoCanonicalInput<'tcx, K>) -> Result<V, ErrorHandled>,
29) -> Option<Result<V, ErrorHandled>> {
30 let ty::PseudoCanonicalInput { typing_env, value } = key;
31 match typing_env.typing_mode().assert_not_erased() {
32 ty::TypingMode::Codegen => {
35 let with_postanalysis =
36 ty::TypingEnv::new(typing_env.param_env, ty::TypingMode::PostAnalysis);
37 let with_postanalysis = f(with_postanalysis.as_query_input(value));
38 match with_postanalysis {
39 Ok(_) | Err(ErrorHandled::Reported(..)) => return Some(with_postanalysis),
40 Err(ErrorHandled::TooGeneric(_)) => {}
41 }
42 }
43 ty::TypingMode::Coherence
44 | ty::TypingMode::Typeck { .. }
45 | ty::TypingMode::PostTypeckUntilBorrowck { .. }
46 | ty::TypingMode::PostBorrowck { .. }
47 | ty::TypingMode::Reflection
48 | ty::TypingMode::PostAnalysis => {}
49 }
50
51 None
52}
53
54fn setup_for_eval<'tcx>(
55 ecx: &mut CompileTimeInterpCx<'tcx>,
56 cid: GlobalId<'tcx>,
57 layout: TyAndLayout<'tcx>,
58) -> InterpResult<'tcx, (InternKind, MPlaceTy<'tcx>)> {
59 let tcx = *ecx.tcx;
60 if !(cid.promoted.is_some() ||
#[allow(non_exhaustive_omitted_patterns)] match ecx.tcx.def_kind(cid.instance.def_id())
{
DefKind::Const | DefKind::Static { .. } | DefKind::ConstParam
| DefKind::AnonConst | DefKind::AssocConst => true,
_ => false,
}) {
{
::core::panicking::panic_fmt(format_args!("Unexpected DefKind: {0:?}",
ecx.tcx.def_kind(cid.instance.def_id())));
}
};assert!(
61 cid.promoted.is_some()
62 || matches!(
63 ecx.tcx.def_kind(cid.instance.def_id()),
64 DefKind::Const
65 | DefKind::Static { .. }
66 | DefKind::ConstParam
67 | DefKind::AnonConst
68 | DefKind::AssocConst
69 ),
70 "Unexpected DefKind: {:?}",
71 ecx.tcx.def_kind(cid.instance.def_id())
72 );
73 if !layout.is_sized() {
::core::panicking::panic("assertion failed: layout.is_sized()")
};assert!(layout.is_sized());
74
75 let intern_kind = if cid.promoted.is_some() {
76 InternKind::Promoted
77 } else {
78 match tcx.static_mutability(cid.instance.def_id()) {
79 Some(m) => InternKind::Static(m),
80 None => InternKind::Constant,
81 }
82 };
83
84 let return_place = if let InternKind::Static(_) = intern_kind {
85 create_static_alloc(ecx, cid.instance.def_id().expect_local(), layout)
86 } else {
87 ecx.allocate(layout, MemoryKind::Stack)
88 };
89
90 return_place.map(|ret| (intern_kind, ret))
91}
92
93{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("eval_body_using_ecx",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(93u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("cid")
}> =
::tracing::__macro_support::FieldName::new("cid");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&cid)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: InterpResult<'tcx, R> = loop {};
return __tracing_attr_fake_return;
}
{
let tcx = *ecx.tcx;
let ty =
body.bound_return_ty(tcx).instantiate(tcx,
cid.instance.args).skip_norm_wip();
ensure_monomorphic_enough(ty)?;
let layout = ecx.layout_of(ty)?;
let (intern_kind, ret) = setup_for_eval(ecx, cid, layout)?;
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs:106",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(106u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("eval_body_using_ecx: pushing stack frame for global: {0}{1}",
{
let _guard = NoTrimmedGuard::new();
ecx.tcx.def_path_str(cid.instance.def_id())
},
cid.promoted.map_or_else(String::new,
|p|
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("::{0:?}", p))
}))) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
ecx.push_stack_frame_raw(cid.instance, body, &ret.clone().into(),
ReturnContinuation::Stop { cleanup: false })?;
ecx.push_stack_frame_done()?;
while ecx.step()? {
if CTRL_C_RECEIVED.load(Relaxed) {
do yeet ::rustc_middle::mir::interpret::InterpErrorKind::ResourceExhaustion(::rustc_middle::mir::interpret::ResourceExhaustionInfo::Interrupted);
}
}
intern_and_validate(ecx, cid, intern_kind, ret)
}
}
}#[instrument(level = "trace", skip(ecx, body))]
94fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
95 ecx: &mut CompileTimeInterpCx<'tcx>,
96 cid: GlobalId<'tcx>,
97 body: &'tcx mir::Body<'tcx>,
98) -> InterpResult<'tcx, R> {
99 let tcx = *ecx.tcx;
100 let ty = body.bound_return_ty(tcx).instantiate(tcx, cid.instance.args).skip_norm_wip();
101 ensure_monomorphic_enough(ty)?;
102
103 let layout = ecx.layout_of(ty)?;
104 let (intern_kind, ret) = setup_for_eval(ecx, cid, layout)?;
105
106 trace!(
107 "eval_body_using_ecx: pushing stack frame for global: {}{}",
108 with_no_trimmed_paths!(ecx.tcx.def_path_str(cid.instance.def_id())),
109 cid.promoted.map_or_else(String::new, |p| format!("::{p:?}"))
110 );
111
112 ecx.push_stack_frame_raw(
115 cid.instance,
116 body,
117 &ret.clone().into(),
118 ReturnContinuation::Stop { cleanup: false },
119 )?;
120 ecx.push_stack_frame_done()?;
121
122 while ecx.step()? {
124 if CTRL_C_RECEIVED.load(Relaxed) {
125 throw_exhaust!(Interrupted);
126 }
127 }
128
129 intern_and_validate(ecx, cid, intern_kind, ret)
130}
131
132{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("eval_trivial_const_using_ecx",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(132u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("cid")
}> =
::tracing::__macro_support::FieldName::new("cid");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("val")
}> =
::tracing::__macro_support::FieldName::new("val");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("ty")
}> =
::tracing::__macro_support::FieldName::new("ty");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&cid)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&val)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: InterpResult<'tcx, R> = loop {};
return __tracing_attr_fake_return;
}
{
let layout = ecx.layout_of(ty)?;
let (intern_kind, return_place) =
setup_for_eval(ecx, cid, layout)?;
let opty = ecx.const_val_to_op(val, ty, Some(layout))?;
ecx.copy_op(&opty, &return_place)?;
intern_and_validate(ecx, cid, intern_kind, return_place)
}
}
}#[instrument(level = "trace", skip(ecx))]
133fn eval_trivial_const_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
134 ecx: &mut CompileTimeInterpCx<'tcx>,
135 cid: GlobalId<'tcx>,
136 val: ConstValue,
137 ty: Ty<'tcx>,
138) -> InterpResult<'tcx, R> {
139 let layout = ecx.layout_of(ty)?;
140 let (intern_kind, return_place) = setup_for_eval(ecx, cid, layout)?;
141
142 let opty = ecx.const_val_to_op(val, ty, Some(layout))?;
143 ecx.copy_op(&opty, &return_place)?;
144
145 intern_and_validate(ecx, cid, intern_kind, return_place)
146}
147
148fn intern_and_validate<'tcx, R: InterpretationResult<'tcx>>(
149 ecx: &mut CompileTimeInterpCx<'tcx>,
150 cid: GlobalId<'tcx>,
151 intern_kind: InternKind,
152 ret: MPlaceTy<'tcx>,
153) -> InterpResult<'tcx, R> {
154 let intern_result = intern_const_alloc_recursive(ecx, intern_kind, &ret);
156
157 const_validate_mplace(ecx, &ret, cid)?;
159
160 match intern_result {
164 Ok(()) => {}
165 Err(InternError::DanglingPointer) => {
166 do yeet ::rustc_middle::mir::interpret::InterpErrorKind::InvalidProgram(::rustc_middle::mir::interpret::InvalidProgramInfo::AlreadyReported(ReportedErrorInfo::non_const_eval_error(ecx.tcx.dcx().emit_err(diagnostics::DanglingPtrInFinal {
span: ecx.tcx.span,
kind: intern_kind,
}))));throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
167 ecx.tcx.dcx().emit_err(diagnostics::DanglingPtrInFinal {
168 span: ecx.tcx.span,
169 kind: intern_kind
170 }),
171 )));
172 }
173 Err(InternError::BadMutablePointer) => {
174 do yeet ::rustc_middle::mir::interpret::InterpErrorKind::InvalidProgram(::rustc_middle::mir::interpret::InvalidProgramInfo::AlreadyReported(ReportedErrorInfo::non_const_eval_error(ecx.tcx.dcx().emit_err(diagnostics::MutablePtrInFinal {
span: ecx.tcx.span,
kind: intern_kind,
}))));throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
175 ecx.tcx.dcx().emit_err(diagnostics::MutablePtrInFinal {
176 span: ecx.tcx.span,
177 kind: intern_kind
178 }),
179 )));
180 }
181 Err(InternError::ConstAllocNotGlobal) => {
182 do yeet ::rustc_middle::mir::interpret::InterpErrorKind::InvalidProgram(::rustc_middle::mir::interpret::InvalidProgramInfo::AlreadyReported(ReportedErrorInfo::non_const_eval_error(ecx.tcx.dcx().emit_err(diagnostics::ConstHeapPtrInFinal {
span: ecx.tcx.span,
}))));throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
183 ecx.tcx.dcx().emit_err(diagnostics::ConstHeapPtrInFinal { span: ecx.tcx.span }),
184 )));
185 }
186 Err(InternError::PartialPointer) => {
187 do yeet ::rustc_middle::mir::interpret::InterpErrorKind::InvalidProgram(::rustc_middle::mir::interpret::InvalidProgramInfo::AlreadyReported(ReportedErrorInfo::non_const_eval_error(ecx.tcx.dcx().emit_err(diagnostics::PartialPtrInFinal {
span: ecx.tcx.span,
kind: intern_kind,
}))));throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
188 ecx.tcx.dcx().emit_err(diagnostics::PartialPtrInFinal {
189 span: ecx.tcx.span,
190 kind: intern_kind
191 }),
192 )));
193 }
194 }
195
196 interp_ok(R::make_result(ret, ecx))
197}
198
199pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
210 tcx: TyCtxt<'tcx>,
211 root_span: Span,
212 typing_env: ty::TypingEnv<'tcx>,
213 can_access_mut_global: CanAccessMutGlobal,
214) -> CompileTimeInterpCx<'tcx> {
215 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs:215",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(215u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("mk_eval_cx: {0:?}",
typing_env) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("mk_eval_cx: {:?}", typing_env);
216 InterpCx::new(
217 tcx,
218 root_span,
219 typing_env,
220 CompileTimeMachine::new(can_access_mut_global, CheckAlignment::No),
221 )
222}
223
224pub fn mk_eval_cx_for_const_val<'tcx>(
227 tcx: TyCtxtAt<'tcx>,
228 typing_env: ty::TypingEnv<'tcx>,
229 val: mir::ConstValue,
230 ty: Ty<'tcx>,
231) -> Option<(CompileTimeInterpCx<'tcx>, OpTy<'tcx>)> {
232 let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, typing_env, CanAccessMutGlobal::No);
233 let op = ecx.const_val_to_op(val, ty, None).discard_err()?;
235 Some((ecx, op))
236}
237
238{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("op_to_const",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(244u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("op")
}> =
::tracing::__macro_support::FieldName::new("op");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("for_diagnostics")
}> =
::tracing::__macro_support::FieldName::new("for_diagnostics");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&op)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&for_diagnostics
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: ConstValue = loop {};
return __tracing_attr_fake_return;
}
{
if op.layout.is_zst() { return ConstValue::ZeroSized; }
let force_as_immediate =
match op.layout.backend_repr {
BackendRepr::Scalar(abi::Scalar::Initialized { .. }) =>
true,
_ => false,
};
let immediate =
if force_as_immediate {
match ecx.read_immediate(op).report_err() {
Ok(imm) => Right(imm),
Err(err) => {
if for_diagnostics {
op.as_mplace_or_imm()
} else {
{
::core::panicking::panic_fmt(format_args!("normalization works on validated constants: {0:?}",
err));
}
}
}
}
} else { op.as_mplace_or_imm() };
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs:287",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(287u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("immediate")
}> =
::tracing::__macro_support::FieldName::new("immediate");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&immediate)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
match immediate {
Left(ref mplace) => {
let (prov, offset) =
mplace.ptr().into_pointer_or_addr().unwrap().prov_and_relative_offset();
let alloc_id = prov.alloc_id();
ConstValue::Indirect { alloc_id, offset }
}
Right(imm) =>
match *imm {
Immediate::Scalar(x) => ConstValue::Scalar(x),
Immediate::ScalarPair(a, b) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs:300",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(300u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("ScalarPair(a: {0:?}, b: {1:?})",
a, b) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let pointee_ty =
imm.layout.ty.builtin_deref(false).unwrap();
if true {
if !#[allow(non_exhaustive_omitted_patterns)] match ecx.tcx.struct_tail_for_codegen(pointee_ty,
ecx.typing_env()).kind() {
ty::Str | ty::Slice(..) => true,
_ => false,
} {
{
::core::panicking::panic_fmt(format_args!("`ConstValue::Slice` is for slice-tailed types only, but got {0}",
imm.layout.ty));
}
};
};
let msg =
"`op_to_const` on an immediate scalar pair must only be used on slice references to the beginning of an actual allocation";
let ptr = a.to_pointer(ecx);
let (prov, offset) =
ptr.into_pointer_or_addr().expect(msg).prov_and_relative_offset();
let alloc_id = prov.alloc_id();
if !(offset == abi::Size::ZERO) {
{ ::core::panicking::panic_display(&msg); }
};
let meta = b.to_target_usize(ecx).expect(msg);
ConstValue::Slice { alloc_id, meta }
}
Immediate::Uninit =>
bug_impl(None,
format_args!("`Uninit` is not a valid value for {0}",
op.layout.ty), Location::caller()),
},
}
}
}
}#[instrument(skip(ecx), level = "debug")]
245pub(super) fn op_to_const<'tcx>(
246 ecx: &CompileTimeInterpCx<'tcx>,
247 op: &OpTy<'tcx>,
248 for_diagnostics: bool,
249) -> ConstValue {
250 if op.layout.is_zst() {
252 return ConstValue::ZeroSized;
253 }
254
255 let force_as_immediate = match op.layout.backend_repr {
261 BackendRepr::Scalar(abi::Scalar::Initialized { .. }) => true,
262 _ => false,
270 };
271 let immediate = if force_as_immediate {
272 match ecx.read_immediate(op).report_err() {
273 Ok(imm) => Right(imm),
274 Err(err) => {
275 if for_diagnostics {
276 op.as_mplace_or_imm()
278 } else {
279 panic!("normalization works on validated constants: {err:?}")
280 }
281 }
282 }
283 } else {
284 op.as_mplace_or_imm()
285 };
286
287 debug!(?immediate);
288
289 match immediate {
290 Left(ref mplace) => {
291 let (prov, offset) =
292 mplace.ptr().into_pointer_or_addr().unwrap().prov_and_relative_offset();
293 let alloc_id = prov.alloc_id();
294 ConstValue::Indirect { alloc_id, offset }
295 }
296 Right(imm) => match *imm {
298 Immediate::Scalar(x) => ConstValue::Scalar(x),
299 Immediate::ScalarPair(a, b) => {
300 debug!("ScalarPair(a: {:?}, b: {:?})", a, b);
301 let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap(); debug_assert!(
306 matches!(
307 ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.typing_env()).kind(),
308 ty::Str | ty::Slice(..),
309 ),
310 "`ConstValue::Slice` is for slice-tailed types only, but got {}",
311 imm.layout.ty,
312 );
313 let msg = "`op_to_const` on an immediate scalar pair must only be used on slice references to the beginning of an actual allocation";
314 let ptr = a.to_pointer(ecx);
315 let (prov, offset) =
316 ptr.into_pointer_or_addr().expect(msg).prov_and_relative_offset();
317 let alloc_id = prov.alloc_id();
318 assert!(offset == abi::Size::ZERO, "{}", msg);
319 let meta = b.to_target_usize(ecx).expect(msg);
320 ConstValue::Slice { alloc_id, meta }
321 }
322 Immediate::Uninit => bug!("`Uninit` is not a valid value for {}", op.layout.ty),
323 },
324 }
325}
326
327{}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("turn_into_const_value",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(327u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("constant")
}> =
::tracing::__macro_support::FieldName::new("constant");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("key")
}> =
::tracing::__macro_support::FieldName::new("key");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&constant)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&key)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: ConstValue = loop {};
return __tracing_attr_fake_return;
}
{
let cid = key.value;
let def_id = cid.instance.def.def_id();
let is_static = tcx.is_static(def_id);
let ecx =
mk_eval_cx_to_read_const_val(tcx,
tcx.def_span(key.value.instance.def_id()), key.typing_env,
CanAccessMutGlobal::from(is_static));
let mplace =
ecx.raw_const_to_mplace(constant).expect("can only fail if layout computation failed, \
which should have given a good error before ever invoking this function");
if !(!is_static || cid.promoted.is_some()) {
{
::core::panicking::panic_fmt(format_args!("the `eval_to_const_value_raw` query should not be used for statics, use `eval_to_allocation` instead"));
}
};
op_to_const(&ecx, &mplace.into(), false)
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs:327",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(327u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(skip(tcx), level = "debug", ret)]
328pub(crate) fn turn_into_const_value<'tcx>(
329 tcx: TyCtxt<'tcx>,
330 constant: ConstAlloc<'tcx>,
331 key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
332) -> ConstValue {
333 let cid = key.value;
334 let def_id = cid.instance.def.def_id();
335 let is_static = tcx.is_static(def_id);
336 let ecx = mk_eval_cx_to_read_const_val(
338 tcx,
339 tcx.def_span(key.value.instance.def_id()),
340 key.typing_env,
341 CanAccessMutGlobal::from(is_static),
342 );
343
344 let mplace = ecx.raw_const_to_mplace(constant).expect(
345 "can only fail if layout computation failed, \
346 which should have given a good error before ever invoking this function",
347 );
348 assert!(
349 !is_static || cid.promoted.is_some(),
350 "the `eval_to_const_value_raw` query should not be used for statics, use `eval_to_allocation` instead"
351 );
352
353 op_to_const(&ecx, &mplace.into(), false)
355}
356
357{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("eval_to_const_value_raw_provider",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(357u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("key")
}> =
::tracing::__macro_support::FieldName::new("key");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&key)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> =
loop {};
return __tracing_attr_fake_return;
}
{
crate::assert_typing_mode(key.typing_env.typing_mode());
if let Some((value, _ty)) =
tcx.trivial_const(key.value.instance.def_id()) {
return Ok(value);
}
if let Some(retry) =
retry_codegen_mode_with_postanalysis(key,
|key| tcx.eval_to_const_value_raw(key)) {
return retry;
}
tcx.eval_to_allocation_raw(key).map(|val|
turn_into_const_value(tcx, val, key))
}
}
}#[instrument(skip(tcx), level = "debug")]
358pub fn eval_to_const_value_raw_provider<'tcx>(
359 tcx: TyCtxt<'tcx>,
360 key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
361) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
362 crate::assert_typing_mode(key.typing_env.typing_mode());
363
364 if let Some((value, _ty)) = tcx.trivial_const(key.value.instance.def_id()) {
365 return Ok(value);
366 }
367
368 if let Some(retry) =
369 retry_codegen_mode_with_postanalysis(key, |key| tcx.eval_to_const_value_raw(key))
370 {
371 return retry;
372 }
373
374 tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key))
375}
376
377{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("eval_static_initializer_provider",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(377u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("def_id")
}> =
::tracing::__macro_support::FieldName::new("def_id");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
::rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'tcx> =
loop {};
return __tracing_attr_fake_return;
}
{
if !tcx.is_static(def_id.to_def_id()) {
::core::panicking::panic("assertion failed: 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,
};
eval_in_interpreter(tcx, cid,
ty::TypingEnv::fully_monomorphized())
}
}
}#[instrument(skip(tcx), level = "debug")]
378pub fn eval_static_initializer_provider<'tcx>(
379 tcx: TyCtxt<'tcx>,
380 def_id: LocalDefId,
381) -> ::rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'tcx> {
382 assert!(tcx.is_static(def_id.to_def_id()));
383
384 let instance = ty::Instance::mono(tcx, def_id.to_def_id());
385 let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
386 eval_in_interpreter(tcx, cid, ty::TypingEnv::fully_monomorphized())
387}
388
389pub trait InterpretationResult<'tcx> {
390 fn make_result(
394 mplace: MPlaceTy<'tcx>,
395 ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
396 ) -> Self;
397}
398
399impl<'tcx> InterpretationResult<'tcx> for ConstAlloc<'tcx> {
400 fn make_result(
401 mplace: MPlaceTy<'tcx>,
402 _ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
403 ) -> Self {
404 ConstAlloc { alloc_id: mplace.ptr().provenance.unwrap().alloc_id(), ty: mplace.layout.ty }
405 }
406}
407
408{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("eval_to_allocation_raw_provider",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(408u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("key")
}> =
::tracing::__macro_support::FieldName::new("key");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&key)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> =
loop {};
return __tracing_attr_fake_return;
}
{
crate::assert_typing_mode(key.typing_env.typing_mode());
if let Some(retry) =
retry_codegen_mode_with_postanalysis(key,
|key| tcx.eval_to_allocation_raw(key)) {
return retry;
}
if !(key.value.promoted.is_some() ||
!tcx.is_static(key.value.instance.def_id())) {
::core::panicking::panic("assertion failed: key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id())")
};
if true {
let instance =
{
let _guard = NoTrimmedGuard::new();
key.value.instance.to_string()
};
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs:431",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(431u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("const eval: {0:?} ({1})",
key, instance) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
}
eval_in_interpreter(tcx, key.value, key.typing_env)
}
}
}#[instrument(skip(tcx), level = "debug")]
409pub fn eval_to_allocation_raw_provider<'tcx>(
410 tcx: TyCtxt<'tcx>,
411 key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
412) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
413 crate::assert_typing_mode(key.typing_env.typing_mode());
414 if let Some(retry) =
415 retry_codegen_mode_with_postanalysis(key, |key| tcx.eval_to_allocation_raw(key))
416 {
417 return retry;
418 }
419
420 assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));
423
424 if cfg!(debug_assertions) {
425 let instance = with_no_trimmed_paths!(key.value.instance.to_string());
431 trace!("const eval: {:?} ({})", key, instance);
432 }
433
434 eval_in_interpreter(tcx, key.value, key.typing_env)
435}
436
437fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
438 tcx: TyCtxt<'tcx>,
439 cid: GlobalId<'tcx>,
440 typing_env: ty::TypingEnv<'tcx>,
441) -> Result<R, ErrorHandled> {
442 let def = cid.instance.def.def_id();
443 if truecfg!(debug_assertions) && #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(def) {
DefKind::Const | DefKind::AssocConst => true,
_ => false,
}matches!(tcx.def_kind(def), DefKind::Const | DefKind::AssocConst) {
445 if true {
if !tcx.const_of_item(def).is_none() {
{
::core::panicking::panic_fmt(format_args!("CTFE tried to evaluate directly represented const item: {0:?}",
def));
}
};
};debug_assert!(
446 tcx.const_of_item(def).is_none(),
447 "CTFE tried to evaluate directly represented const item: {def:?}"
448 );
449 }
450
451 let is_static = tcx.is_static(def);
452 let mut ecx = InterpCx::new(
453 tcx,
454 tcx.def_span(def),
455 typing_env,
456 CompileTimeMachine::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
461 );
462
463 let result = if let Some((value, ty)) = tcx.trivial_const(def) {
464 eval_trivial_const_using_ecx(&mut ecx, cid, value, ty)
465 } else {
466 ecx.load_mir(cid.instance.def, cid.promoted)
467 .and_then(|body| eval_body_using_ecx(&mut ecx, cid, body))
468 };
469 result.report_err().map_err(|error| report_eval_error(&ecx, cid, error))
470}
471
472#[inline(always)]
473fn const_validate_mplace<'tcx>(
474 ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
475 mplace: &MPlaceTy<'tcx>,
476 cid: GlobalId<'tcx>,
477) -> Result<(), ErrorHandled> {
478 let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
479 let mut ref_tracking = RefTracking::new(mplace.clone(), mplace.layout.ty);
480 let mut inner = false;
481 while let Some((mplace, path)) = ref_tracking.next() {
482 let mode = match ecx.tcx.static_mutability(cid.instance.def_id()) {
483 _ if cid.promoted.is_some() => CtfeValidationMode::Promoted,
484 Some(mutbl) => CtfeValidationMode::Static { mutbl }, None => {
486 CtfeValidationMode::Const { allow_immutable_unsafe_cell: !inner }
490 }
491 };
492 ecx.const_validate_place(&mplace.into(), path, &mut ref_tracking, mode)
493 .report_err()
494 .map_err(|error| report_validation_error(&ecx, cid, error, alloc_id))?;
497 inner = true;
498 }
499
500 Ok(())
501}
502
503#[inline(never)]
504fn report_eval_error<'tcx>(
505 ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
506 cid: GlobalId<'tcx>,
507 error: InterpErrorInfo<'tcx>,
508) -> ErrorHandled {
509 let (error, backtrace) = error.into_parts();
510 backtrace.print_backtrace();
511
512 super::report(ecx, error, |diag, span, frames| {
513 let num_frames = frames.len();
514 diag.span_label(
515 span,
516 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("evaluation of `{0}` failed {1}",
{
let _guard = NoTrimmedGuard::new();
cid.instance.to_string()
}, if num_frames == 0 { "here" } else { "inside this call" }))
})format!(
517 "evaluation of `{instance}` failed {where_}",
518 instance = with_no_trimmed_paths!(cid.instance.to_string()),
519 where_ = if num_frames == 0 { "here" } else { "inside this call" },
520 ),
521 );
522 for frame in frames {
523 diag.subdiagnostic(frame);
524 }
525 })
526}
527
528#[inline(never)]
529fn report_validation_error<'tcx>(
530 ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
531 cid: GlobalId<'tcx>,
532 error: InterpErrorInfo<'tcx>,
533 alloc_id: AllocId,
534) -> ErrorHandled {
535 if !#[allow(non_exhaustive_omitted_patterns)] match error.kind() {
InterpErrorKind::UndefinedBehavior(_) => true,
_ => false,
}matches!(error.kind(), InterpErrorKind::UndefinedBehavior(_)) {
536 return report_eval_error(ecx, cid, error);
538 }
539
540 let (error, backtrace) = error.into_parts();
541 backtrace.print_backtrace();
542
543 let bytes = ecx.print_alloc_bytes_for_diagnostics(alloc_id);
544 let info = ecx.get_alloc_info(alloc_id);
545 let raw_bytes =
546 diagnostics::RawBytesNote { size: info.size.bytes(), align: info.align.bytes(), bytes };
547
548 crate::const_eval::report(ecx, error, move |diag, span, frames| {
549 diag.span_label(span, "it is undefined behavior to use this value");
550 diag.note("the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.");
551 if !frames.is_empty() {
::core::panicking::panic("assertion failed: frames.is_empty()")
};assert!(frames.is_empty()); diag.subdiagnostic(raw_bytes);
553 })
554}