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::ty::layout::{HasTypingEnv, TyAndLayout};
10use rustc_middle::ty::print::with_no_trimmed_paths;
11use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
12use rustc_middle::{bug, throw_inval};
13use rustc_span::Span;
14use rustc_span::def_id::LocalDefId;
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 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::PostAnalysis => {}
48 }
49
50 None
51}
52
53fn setup_for_eval<'tcx>(
54 ecx: &mut CompileTimeInterpCx<'tcx>,
55 cid: GlobalId<'tcx>,
56 layout: TyAndLayout<'tcx>,
57) -> InterpResult<'tcx, (InternKind, MPlaceTy<'tcx>)> {
58 let tcx = *ecx.tcx;
59 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!(
60 cid.promoted.is_some()
61 || matches!(
62 ecx.tcx.def_kind(cid.instance.def_id()),
63 DefKind::Const { .. }
64 | DefKind::Static { .. }
65 | DefKind::ConstParam
66 | DefKind::AnonConst
67 | DefKind::AssocConst { .. }
68 ),
69 "Unexpected DefKind: {:?}",
70 ecx.tcx.def_kind(cid.instance.def_id())
71 );
72 if !layout.is_sized() {
::core::panicking::panic("assertion failed: layout.is_sized()")
};assert!(layout.is_sized());
73
74 let intern_kind = if cid.promoted.is_some() {
75 InternKind::Promoted
76 } else {
77 match tcx.static_mutability(cid.instance.def_id()) {
78 Some(m) => InternKind::Static(m),
79 None => InternKind::Constant,
80 }
81 };
82
83 let return_place = if let InternKind::Static(_) = intern_kind {
84 create_static_alloc(ecx, cid.instance.def_id().expect_local(), layout)
85 } else {
86 ecx.allocate(layout, MemoryKind::Stack)
87 };
88
89 return_place.map(|ret| (intern_kind, ret))
90}
91
92#[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("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(92u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["cid"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&cid)
as &dyn 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 layout =
ecx.layout_of(body.bound_return_ty(tcx).instantiate(tcx,
cid.instance.args).skip_norm_wip())?;
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 compiler/rustc_const_eval/src/const_eval/eval_queries.rs:103",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(103u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::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 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))]
93fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
94 ecx: &mut CompileTimeInterpCx<'tcx>,
95 cid: GlobalId<'tcx>,
96 body: &'tcx mir::Body<'tcx>,
97) -> InterpResult<'tcx, R> {
98 let tcx = *ecx.tcx;
99 let layout = ecx
100 .layout_of(body.bound_return_ty(tcx).instantiate(tcx, cid.instance.args).skip_norm_wip())?;
101 let (intern_kind, ret) = setup_for_eval(ecx, cid, layout)?;
102
103 trace!(
104 "eval_body_using_ecx: pushing stack frame for global: {}{}",
105 with_no_trimmed_paths!(ecx.tcx.def_path_str(cid.instance.def_id())),
106 cid.promoted.map_or_else(String::new, |p| format!("::{p:?}"))
107 );
108
109 ecx.push_stack_frame_raw(
112 cid.instance,
113 body,
114 &ret.clone().into(),
115 ReturnContinuation::Stop { cleanup: false },
116 )?;
117 ecx.push_stack_frame_done()?;
118
119 while ecx.step()? {
121 if CTRL_C_RECEIVED.load(Relaxed) {
122 throw_exhaust!(Interrupted);
123 }
124 }
125
126 intern_and_validate(ecx, cid, intern_kind, ret)
127}
128
129#[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("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(129u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["cid", "val", "ty"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&cid)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&val)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
as &dyn 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))]
130fn eval_trivial_const_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
131 ecx: &mut CompileTimeInterpCx<'tcx>,
132 cid: GlobalId<'tcx>,
133 val: ConstValue,
134 ty: Ty<'tcx>,
135) -> InterpResult<'tcx, R> {
136 let layout = ecx.layout_of(ty)?;
137 let (intern_kind, return_place) = setup_for_eval(ecx, cid, layout)?;
138
139 let opty = ecx.const_val_to_op(val, ty, Some(layout))?;
140 ecx.copy_op(&opty, &return_place)?;
141
142 intern_and_validate(ecx, cid, intern_kind, return_place)
143}
144
145fn intern_and_validate<'tcx, R: InterpretationResult<'tcx>>(
146 ecx: &mut CompileTimeInterpCx<'tcx>,
147 cid: GlobalId<'tcx>,
148 intern_kind: InternKind,
149 ret: MPlaceTy<'tcx>,
150) -> InterpResult<'tcx, R> {
151 let intern_result = intern_const_alloc_recursive(ecx, intern_kind, &ret);
153
154 const_validate_mplace(ecx, &ret, cid)?;
156
157 match intern_result {
161 Ok(()) => {}
162 Err(InternError::DanglingPointer) => {
163 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(
164 ecx.tcx.dcx().emit_err(diagnostics::DanglingPtrInFinal {
165 span: ecx.tcx.span,
166 kind: intern_kind
167 }),
168 )));
169 }
170 Err(InternError::BadMutablePointer) => {
171 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(
172 ecx.tcx.dcx().emit_err(diagnostics::MutablePtrInFinal {
173 span: ecx.tcx.span,
174 kind: intern_kind
175 }),
176 )));
177 }
178 Err(InternError::ConstAllocNotGlobal) => {
179 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(
180 ecx.tcx.dcx().emit_err(diagnostics::ConstHeapPtrInFinal { span: ecx.tcx.span }),
181 )));
182 }
183 Err(InternError::PartialPointer) => {
184 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(
185 ecx.tcx.dcx().emit_err(diagnostics::PartialPtrInFinal {
186 span: ecx.tcx.span,
187 kind: intern_kind
188 }),
189 )));
190 }
191 }
192
193 interp_ok(R::make_result(ret, ecx))
194}
195
196pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
207 tcx: TyCtxt<'tcx>,
208 root_span: Span,
209 typing_env: ty::TypingEnv<'tcx>,
210 can_access_mut_global: CanAccessMutGlobal,
211) -> CompileTimeInterpCx<'tcx> {
212 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_const_eval/src/const_eval/eval_queries.rs:212",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(212u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("mk_eval_cx: {0:?}",
typing_env) as &dyn Value))])
});
} else { ; }
};debug!("mk_eval_cx: {:?}", typing_env);
213 InterpCx::new(
214 tcx,
215 root_span,
216 typing_env,
217 CompileTimeMachine::new(can_access_mut_global, CheckAlignment::No),
218 )
219}
220
221pub fn mk_eval_cx_for_const_val<'tcx>(
224 tcx: TyCtxtAt<'tcx>,
225 typing_env: ty::TypingEnv<'tcx>,
226 val: mir::ConstValue,
227 ty: Ty<'tcx>,
228) -> Option<(CompileTimeInterpCx<'tcx>, OpTy<'tcx>)> {
229 let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, typing_env, CanAccessMutGlobal::No);
230 let op = ecx.const_val_to_op(val, ty, None).discard_err()?;
232 Some((ecx, op))
233}
234
235#[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("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(241u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["op",
"for_diagnostics"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&op)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&for_diagnostics as
&dyn 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 compiler/rustc_const_eval/src/const_eval/eval_queries.rs:284",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(284u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["immediate"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&immediate)
as &dyn 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 compiler/rustc_const_eval/src/const_eval/eval_queries.rs:297",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(297u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("ScalarPair(a: {0:?}, b: {1:?})",
a, b) as &dyn 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).expect(msg);
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 =>
::rustc_middle::util::bug::bug_fmt(format_args!("`Uninit` is not a valid value for {0}",
op.layout.ty)),
},
}
}
}
}#[instrument(skip(ecx), level = "debug")]
242pub(super) fn op_to_const<'tcx>(
243 ecx: &CompileTimeInterpCx<'tcx>,
244 op: &OpTy<'tcx>,
245 for_diagnostics: bool,
246) -> ConstValue {
247 if op.layout.is_zst() {
249 return ConstValue::ZeroSized;
250 }
251
252 let force_as_immediate = match op.layout.backend_repr {
258 BackendRepr::Scalar(abi::Scalar::Initialized { .. }) => true,
259 _ => false,
267 };
268 let immediate = if force_as_immediate {
269 match ecx.read_immediate(op).report_err() {
270 Ok(imm) => Right(imm),
271 Err(err) => {
272 if for_diagnostics {
273 op.as_mplace_or_imm()
275 } else {
276 panic!("normalization works on validated constants: {err:?}")
277 }
278 }
279 }
280 } else {
281 op.as_mplace_or_imm()
282 };
283
284 debug!(?immediate);
285
286 match immediate {
287 Left(ref mplace) => {
288 let (prov, offset) =
289 mplace.ptr().into_pointer_or_addr().unwrap().prov_and_relative_offset();
290 let alloc_id = prov.alloc_id();
291 ConstValue::Indirect { alloc_id, offset }
292 }
293 Right(imm) => match *imm {
295 Immediate::Scalar(x) => ConstValue::Scalar(x),
296 Immediate::ScalarPair(a, b) => {
297 debug!("ScalarPair(a: {:?}, b: {:?})", a, b);
298 let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap(); debug_assert!(
303 matches!(
304 ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.typing_env()).kind(),
305 ty::Str | ty::Slice(..),
306 ),
307 "`ConstValue::Slice` is for slice-tailed types only, but got {}",
308 imm.layout.ty,
309 );
310 let msg = "`op_to_const` on an immediate scalar pair must only be used on slice references to the beginning of an actual allocation";
311 let ptr = a.to_pointer(ecx).expect(msg);
312 let (prov, offset) =
313 ptr.into_pointer_or_addr().expect(msg).prov_and_relative_offset();
314 let alloc_id = prov.alloc_id();
315 assert!(offset == abi::Size::ZERO, "{}", msg);
316 let meta = b.to_target_usize(ecx).expect(msg);
317 ConstValue::Slice { alloc_id, meta }
318 }
319 Immediate::Uninit => bug!("`Uninit` is not a valid value for {}", op.layout.ty),
320 },
321 }
322}
323
324x;#[instrument(skip(tcx), level = "debug", ret)]
325pub(crate) fn turn_into_const_value<'tcx>(
326 tcx: TyCtxt<'tcx>,
327 constant: ConstAlloc<'tcx>,
328 key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
329) -> ConstValue {
330 let cid = key.value;
331 let def_id = cid.instance.def.def_id();
332 let is_static = tcx.is_static(def_id);
333 let ecx = mk_eval_cx_to_read_const_val(
335 tcx,
336 tcx.def_span(key.value.instance.def_id()),
337 key.typing_env,
338 CanAccessMutGlobal::from(is_static),
339 );
340
341 let mplace = ecx.raw_const_to_mplace(constant).expect(
342 "can only fail if layout computation failed, \
343 which should have given a good error before ever invoking this function",
344 );
345 assert!(
346 !is_static || cid.promoted.is_some(),
347 "the `eval_to_const_value_raw` query should not be used for statics, use `eval_to_allocation` instead"
348 );
349
350 op_to_const(&ecx, &mplace.into(), false)
352}
353
354#[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("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(354u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["key"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&key)
as &dyn 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")]
355pub fn eval_to_const_value_raw_provider<'tcx>(
356 tcx: TyCtxt<'tcx>,
357 key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
358) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
359 crate::assert_typing_mode(key.typing_env.typing_mode());
360
361 if let Some((value, _ty)) = tcx.trivial_const(key.value.instance.def_id()) {
362 return Ok(value);
363 }
364
365 if let Some(retry) =
366 retry_codegen_mode_with_postanalysis(key, |key| tcx.eval_to_const_value_raw(key))
367 {
368 return retry;
369 }
370
371 tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key))
372}
373
374#[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("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(374u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["def_id"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn 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")]
375pub fn eval_static_initializer_provider<'tcx>(
376 tcx: TyCtxt<'tcx>,
377 def_id: LocalDefId,
378) -> ::rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'tcx> {
379 assert!(tcx.is_static(def_id.to_def_id()));
380
381 let instance = ty::Instance::mono(tcx, def_id.to_def_id());
382 let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
383 eval_in_interpreter(tcx, cid, ty::TypingEnv::fully_monomorphized())
384}
385
386pub trait InterpretationResult<'tcx> {
387 fn make_result(
391 mplace: MPlaceTy<'tcx>,
392 ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
393 ) -> Self;
394}
395
396impl<'tcx> InterpretationResult<'tcx> for ConstAlloc<'tcx> {
397 fn make_result(
398 mplace: MPlaceTy<'tcx>,
399 _ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
400 ) -> Self {
401 ConstAlloc { alloc_id: mplace.ptr().provenance.unwrap().alloc_id(), ty: mplace.layout.ty }
402 }
403}
404
405#[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("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(405u32),
::tracing_core::__macro_support::Option::Some("rustc_const_eval::const_eval::eval_queries"),
::tracing_core::field::FieldSet::new(&["key"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&key)
as &dyn 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 compiler/rustc_const_eval/src/const_eval/eval_queries.rs:428",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(428u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("const eval: {0:?} ({1})",
key, instance) as &dyn Value))])
});
} else { ; }
};
}
eval_in_interpreter(tcx, key.value, key.typing_env)
}
}
}#[instrument(skip(tcx), level = "debug")]
406pub fn eval_to_allocation_raw_provider<'tcx>(
407 tcx: TyCtxt<'tcx>,
408 key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
409) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
410 crate::assert_typing_mode(key.typing_env.typing_mode());
411 if let Some(retry) =
412 retry_codegen_mode_with_postanalysis(key, |key| tcx.eval_to_allocation_raw(key))
413 {
414 return retry;
415 }
416
417 assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));
420
421 if cfg!(debug_assertions) {
422 let instance = with_no_trimmed_paths!(key.value.instance.to_string());
428 trace!("const eval: {:?} ({})", key, instance);
429 }
430
431 eval_in_interpreter(tcx, key.value, key.typing_env)
432}
433
434fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
435 tcx: TyCtxt<'tcx>,
436 cid: GlobalId<'tcx>,
437 typing_env: ty::TypingEnv<'tcx>,
438) -> Result<R, ErrorHandled> {
439 let def = cid.instance.def.def_id();
440 if true {
if !!tcx.is_type_const(def) {
{
::core::panicking::panic_fmt(format_args!("CTFE tried to evaluate type-const: {0:?}",
def));
}
};
};debug_assert!(!tcx.is_type_const(def), "CTFE tried to evaluate type-const: {:?}", def);
442
443 let is_static = tcx.is_static(def);
444 let mut ecx = InterpCx::new(
445 tcx,
446 tcx.def_span(def),
447 typing_env,
448 CompileTimeMachine::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
453 );
454
455 let result = if let Some((value, ty)) = tcx.trivial_const(def) {
456 eval_trivial_const_using_ecx(&mut ecx, cid, value, ty)
457 } else {
458 ecx.load_mir(cid.instance.def, cid.promoted)
459 .and_then(|body| eval_body_using_ecx(&mut ecx, cid, body))
460 };
461 result.report_err().map_err(|error| report_eval_error(&ecx, cid, error))
462}
463
464#[inline(always)]
465fn const_validate_mplace<'tcx>(
466 ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
467 mplace: &MPlaceTy<'tcx>,
468 cid: GlobalId<'tcx>,
469) -> Result<(), ErrorHandled> {
470 let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
471 let mut ref_tracking = RefTracking::new(mplace.clone(), mplace.layout.ty);
472 let mut inner = false;
473 while let Some((mplace, path)) = ref_tracking.next() {
474 let mode = match ecx.tcx.static_mutability(cid.instance.def_id()) {
475 _ if cid.promoted.is_some() => CtfeValidationMode::Promoted,
476 Some(mutbl) => CtfeValidationMode::Static { mutbl }, None => {
478 CtfeValidationMode::Const { allow_immutable_unsafe_cell: !inner }
482 }
483 };
484 ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)
485 .report_err()
486 .map_err(|error| report_validation_error(&ecx, cid, error, alloc_id))?;
489 inner = true;
490 }
491
492 Ok(())
493}
494
495#[inline(never)]
496fn report_eval_error<'tcx>(
497 ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
498 cid: GlobalId<'tcx>,
499 error: InterpErrorInfo<'tcx>,
500) -> ErrorHandled {
501 let (error, backtrace) = error.into_parts();
502 backtrace.print_backtrace();
503
504 super::report(ecx, error, |diag, span, frames| {
505 let num_frames = frames.len();
506 diag.span_label(
507 span,
508 ::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!(
509 "evaluation of `{instance}` failed {where_}",
510 instance = with_no_trimmed_paths!(cid.instance.to_string()),
511 where_ = if num_frames == 0 { "here" } else { "inside this call" },
512 ),
513 );
514 for frame in frames {
515 diag.subdiagnostic(frame);
516 }
517 })
518}
519
520#[inline(never)]
521fn report_validation_error<'tcx>(
522 ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
523 cid: GlobalId<'tcx>,
524 error: InterpErrorInfo<'tcx>,
525 alloc_id: AllocId,
526) -> ErrorHandled {
527 if !#[allow(non_exhaustive_omitted_patterns)] match error.kind() {
InterpErrorKind::UndefinedBehavior(_) => true,
_ => false,
}matches!(error.kind(), InterpErrorKind::UndefinedBehavior(_)) {
528 return report_eval_error(ecx, cid, error);
530 }
531
532 let (error, backtrace) = error.into_parts();
533 backtrace.print_backtrace();
534
535 let bytes = ecx.print_alloc_bytes_for_diagnostics(alloc_id);
536 let info = ecx.get_alloc_info(alloc_id);
537 let raw_bytes =
538 diagnostics::RawBytesNote { size: info.size.bytes(), align: info.align.bytes(), bytes };
539
540 crate::const_eval::report(ecx, error, move |diag, span, frames| {
541 diag.span_label(span, "it is undefined behavior to use this value");
542 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.");
543 if !frames.is_empty() {
::core::panicking::panic("assertion failed: frames.is_empty()")
};assert!(frames.is_empty()); diag.subdiagnostic(raw_bytes);
545 })
546}