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::PostTypeckThroughBorrowck { .. }
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/f5cedb83a788ea9581097abc36a2a8503a7f541c/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/f5cedb83a788ea9581097abc36a2a8503a7f541c/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/f5cedb83a788ea9581097abc36a2a8503a7f541c/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 { ; }
};
{
match (&body.arg_count, &0) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
if cid.promoted.is_none() &&
cid.instance.def.requires_caller_location(tcx) {
do yeet ::rustc_middle::mir::interpret::InterpErrorKind::InvalidProgram(::rustc_middle::mir::interpret::InvalidProgramInfo::AlreadyReported(ReportedErrorInfo::non_const_eval_error(tcx.dcx().span_delayed_bug(body.span,
"can't evaluate body with `#[track_caller]`"))));
}
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 assert_eq!(body.arg_count, 0);
118 if cid.promoted.is_none() && cid.instance.def.requires_caller_location(tcx) {
119 throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
121 tcx.dcx().span_delayed_bug(body.span, "can't evaluate body with `#[track_caller]`")
122 )));
123 }
124
125 ecx.push_stack_frame_raw(
128 cid.instance,
129 body,
130 &ret.clone().into(),
131 ReturnContinuation::Stop { cleanup: false },
132 )?;
133 ecx.push_stack_frame_done()?;
134
135 while ecx.step()? {
137 if CTRL_C_RECEIVED.load(Relaxed) {
138 throw_exhaust!(Interrupted);
139 }
140 }
141
142 intern_and_validate(ecx, cid, intern_kind, ret)
143}
144
145{}
#[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/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(145u32),
::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))]
146fn eval_trivial_const_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
147 ecx: &mut CompileTimeInterpCx<'tcx>,
148 cid: GlobalId<'tcx>,
149 val: ConstValue,
150 ty: Ty<'tcx>,
151) -> InterpResult<'tcx, R> {
152 let layout = ecx.layout_of(ty)?;
153 let (intern_kind, return_place) = setup_for_eval(ecx, cid, layout)?;
154
155 let opty = ecx.const_val_to_op(val, ty, Some(layout))?;
156 ecx.copy_op(&opty, &return_place)?;
157
158 intern_and_validate(ecx, cid, intern_kind, return_place)
159}
160
161fn intern_and_validate<'tcx, R: InterpretationResult<'tcx>>(
162 ecx: &mut CompileTimeInterpCx<'tcx>,
163 cid: GlobalId<'tcx>,
164 intern_kind: InternKind,
165 ret: MPlaceTy<'tcx>,
166) -> InterpResult<'tcx, R> {
167 let intern_result = intern_const_alloc_recursive(ecx, intern_kind, &ret);
169
170 const_validate_mplace(ecx, &ret, cid)?;
172
173 match intern_result {
177 Ok(()) => {}
178 Err(InternError::DanglingPointer) => {
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::DanglingPtrInFinal {
span: ecx.tcx.span,
kind: intern_kind,
}))));throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
180 ecx.tcx.dcx().emit_err(diagnostics::DanglingPtrInFinal {
181 span: ecx.tcx.span,
182 kind: intern_kind
183 }),
184 )));
185 }
186 Err(InternError::BadMutablePointer) => {
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::MutablePtrInFinal {
span: ecx.tcx.span,
kind: intern_kind,
}))));throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
188 ecx.tcx.dcx().emit_err(diagnostics::MutablePtrInFinal {
189 span: ecx.tcx.span,
190 kind: intern_kind
191 }),
192 )));
193 }
194 Err(InternError::ConstAllocNotGlobal) => {
195 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(
196 ecx.tcx.dcx().emit_err(diagnostics::ConstHeapPtrInFinal { span: ecx.tcx.span }),
197 )));
198 }
199 Err(InternError::PartialPointer) => {
200 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(
201 ecx.tcx.dcx().emit_err(diagnostics::PartialPtrInFinal {
202 span: ecx.tcx.span,
203 kind: intern_kind
204 }),
205 )));
206 }
207 }
208
209 interp_ok(R::make_result(ret, ecx))
210}
211
212pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
223 tcx: TyCtxt<'tcx>,
224 root_span: Span,
225 typing_env: ty::TypingEnv<'tcx>,
226 can_access_mut_global: CanAccessMutGlobal,
227) -> CompileTimeInterpCx<'tcx> {
228 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs:228",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(228u32),
::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);
229 InterpCx::new(
230 tcx,
231 root_span,
232 typing_env,
233 CompileTimeMachine::new(can_access_mut_global, CheckAlignment::No),
234 )
235}
236
237pub fn mk_eval_cx_for_const_val<'tcx>(
240 tcx: TyCtxtAt<'tcx>,
241 typing_env: ty::TypingEnv<'tcx>,
242 val: mir::ConstValue,
243 ty: Ty<'tcx>,
244) -> Option<(CompileTimeInterpCx<'tcx>, OpTy<'tcx>)> {
245 let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, typing_env, CanAccessMutGlobal::No);
246 let op = ecx.const_val_to_op(val, ty, None).discard_err()?;
248 Some((ecx, op))
249}
250
251{}
#[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/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(257u32),
::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/f5cedb83a788ea9581097abc36a2a8503a7f541c/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/f5cedb83a788ea9581097abc36a2a8503a7f541c/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(&[{
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/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs:313",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(313u32),
::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 =>
::rustc_span::macros::bug_impl(None,
format_args!("`Uninit` is not a valid value for {0}",
op.layout.ty), Location::caller()),
},
}
}
}
}#[instrument(skip(ecx), level = "debug")]
258pub(super) fn op_to_const<'tcx>(
259 ecx: &CompileTimeInterpCx<'tcx>,
260 op: &OpTy<'tcx>,
261 for_diagnostics: bool,
262) -> ConstValue {
263 if op.layout.is_zst() {
265 return ConstValue::ZeroSized;
266 }
267
268 let force_as_immediate = match op.layout.backend_repr {
274 BackendRepr::Scalar(abi::Scalar::Initialized { .. }) => true,
275 _ => false,
283 };
284 let immediate = if force_as_immediate {
285 match ecx.read_immediate(op).report_err() {
286 Ok(imm) => Right(imm),
287 Err(err) => {
288 if for_diagnostics {
289 op.as_mplace_or_imm()
291 } else {
292 panic!("normalization works on validated constants: {err:?}")
293 }
294 }
295 }
296 } else {
297 op.as_mplace_or_imm()
298 };
299
300 debug!(?immediate);
301
302 match immediate {
303 Left(ref mplace) => {
304 let (prov, offset) =
305 mplace.ptr().into_pointer_or_addr().unwrap().prov_and_relative_offset();
306 let alloc_id = prov.alloc_id();
307 ConstValue::Indirect { alloc_id, offset }
308 }
309 Right(imm) => match *imm {
311 Immediate::Scalar(x) => ConstValue::Scalar(x),
312 Immediate::ScalarPair(a, b) => {
313 debug!("ScalarPair(a: {:?}, b: {:?})", a, b);
314 let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap(); debug_assert!(
319 matches!(
320 ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.typing_env()).kind(),
321 ty::Str | ty::Slice(..),
322 ),
323 "`ConstValue::Slice` is for slice-tailed types only, but got {}",
324 imm.layout.ty,
325 );
326 let msg = "`op_to_const` on an immediate scalar pair must only be used on slice references to the beginning of an actual allocation";
327 let ptr = a.to_pointer(ecx);
328 let (prov, offset) =
329 ptr.into_pointer_or_addr().expect(msg).prov_and_relative_offset();
330 let alloc_id = prov.alloc_id();
331 assert!(offset == abi::Size::ZERO, "{}", msg);
332 let meta = b.to_target_usize(ecx).expect(msg);
333 ConstValue::Slice { alloc_id, meta }
334 }
335 Immediate::Uninit => bug!("`Uninit` is not a valid value for {}", op.layout.ty),
336 },
337 }
338}
339
340{}
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/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(340u32),
::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/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs:340",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(340u32),
::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)]
341pub(crate) fn turn_into_const_value<'tcx>(
342 tcx: TyCtxt<'tcx>,
343 constant: ConstAlloc<'tcx>,
344 key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
345) -> ConstValue {
346 let cid = key.value;
347 let def_id = cid.instance.def.def_id();
348 let is_static = tcx.is_static(def_id);
349 let ecx = mk_eval_cx_to_read_const_val(
351 tcx,
352 tcx.def_span(key.value.instance.def_id()),
353 key.typing_env,
354 CanAccessMutGlobal::from(is_static),
355 );
356
357 let mplace = ecx.raw_const_to_mplace(constant).expect(
358 "can only fail if layout computation failed, \
359 which should have given a good error before ever invoking this function",
360 );
361 assert!(
362 !is_static || cid.promoted.is_some(),
363 "the `eval_to_const_value_raw` query should not be used for statics, use `eval_to_allocation` instead"
364 );
365
366 op_to_const(&ecx, &mplace.into(), false)
368}
369
370{}
#[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/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(370u32),
::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")]
371pub fn eval_to_const_value_raw_provider<'tcx>(
372 tcx: TyCtxt<'tcx>,
373 key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
374) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
375 crate::assert_typing_mode(key.typing_env.typing_mode());
376
377 if let Some((value, _ty)) = tcx.trivial_const(key.value.instance.def_id()) {
378 return Ok(value);
379 }
380
381 if let Some(retry) =
382 retry_codegen_mode_with_postanalysis(key, |key| tcx.eval_to_const_value_raw(key))
383 {
384 return retry;
385 }
386
387 tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key))
388}
389
390{}
#[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/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(390u32),
::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")]
391pub fn eval_static_initializer_provider<'tcx>(
392 tcx: TyCtxt<'tcx>,
393 def_id: LocalDefId,
394) -> ::rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'tcx> {
395 assert!(tcx.is_static(def_id.to_def_id()));
396
397 let instance = ty::Instance::mono(tcx, def_id.to_def_id());
398 let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
399 eval_in_interpreter(tcx, cid, ty::TypingEnv::fully_monomorphized())
400}
401
402pub trait InterpretationResult<'tcx> {
403 fn make_result(
407 mplace: MPlaceTy<'tcx>,
408 ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
409 ) -> Self;
410}
411
412impl<'tcx> InterpretationResult<'tcx> for ConstAlloc<'tcx> {
413 fn make_result(
414 mplace: MPlaceTy<'tcx>,
415 _ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
416 ) -> Self {
417 ConstAlloc { alloc_id: mplace.ptr().provenance.unwrap().alloc_id(), ty: mplace.layout.ty }
418 }
419}
420
421{}
#[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/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(421u32),
::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/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs:444",
"rustc_const_eval::const_eval::eval_queries",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_const_eval/src/const_eval/eval_queries.rs"),
::tracing_core::__macro_support::Option::Some(444u32),
::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")]
422pub fn eval_to_allocation_raw_provider<'tcx>(
423 tcx: TyCtxt<'tcx>,
424 key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
425) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
426 crate::assert_typing_mode(key.typing_env.typing_mode());
427 if let Some(retry) =
428 retry_codegen_mode_with_postanalysis(key, |key| tcx.eval_to_allocation_raw(key))
429 {
430 return retry;
431 }
432
433 assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));
436
437 if cfg!(debug_assertions) {
438 let instance = with_no_trimmed_paths!(key.value.instance.to_string());
444 trace!("const eval: {:?} ({})", key, instance);
445 }
446
447 eval_in_interpreter(tcx, key.value, key.typing_env)
448}
449
450fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
451 tcx: TyCtxt<'tcx>,
452 cid: GlobalId<'tcx>,
453 typing_env: ty::TypingEnv<'tcx>,
454) -> Result<R, ErrorHandled> {
455 let def = cid.instance.def.def_id();
456 let is_static = tcx.is_static(def);
457 let mut ecx = InterpCx::new(
458 tcx,
459 tcx.def_span(def),
460 typing_env,
461 CompileTimeMachine::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
466 );
467
468 let result = if let Some((value, ty)) = tcx.trivial_const(def) {
469 eval_trivial_const_using_ecx(&mut ecx, cid, value, ty)
470 } else {
471 ecx.load_mir(cid.instance.def, cid.promoted)
472 .and_then(|body| eval_body_using_ecx(&mut ecx, cid, body))
473 };
474 result.report_err().map_err(|error| report_eval_error(&ecx, cid, error))
475}
476
477#[inline(always)]
478fn const_validate_mplace<'tcx>(
479 ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
480 mplace: &MPlaceTy<'tcx>,
481 cid: GlobalId<'tcx>,
482) -> Result<(), ErrorHandled> {
483 let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
484 let mut ref_tracking = RefTracking::new(mplace.clone(), mplace.layout.ty);
485 let mut inner = false;
486 while let Some((mplace, path)) = ref_tracking.next() {
487 let mode = match ecx.tcx.static_mutability(cid.instance.def_id()) {
488 _ if cid.promoted.is_some() => CtfeValidationMode::Promoted,
489 Some(mutbl) => CtfeValidationMode::Static { mutbl }, None => {
491 CtfeValidationMode::Const { allow_immutable_unsafe_cell: !inner }
495 }
496 };
497 ecx.const_validate_place(&mplace.into(), path, &mut ref_tracking, mode)
498 .report_err()
499 .map_err(|error| report_validation_error(&ecx, cid, error, alloc_id))?;
502 inner = true;
503 }
504
505 Ok(())
506}
507
508#[inline(never)]
509fn report_eval_error<'tcx>(
510 ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
511 cid: GlobalId<'tcx>,
512 error: InterpErrorInfo<'tcx>,
513) -> ErrorHandled {
514 let (error, backtrace) = error.into_parts();
515 backtrace.print_backtrace();
516
517 super::report(ecx, error, |diag, span, frames| {
518 let num_frames = frames.len();
519 diag.span_label(
520 span,
521 ::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!(
522 "evaluation of `{instance}` failed {where_}",
523 instance = with_no_trimmed_paths!(cid.instance.to_string()),
524 where_ = if num_frames == 0 { "here" } else { "inside this call" },
525 ),
526 );
527 for span in crate::util::context_spans(*ecx.tcx, span, cid.instance.def_id()) {
528 diag.span_context(span);
529 }
530 for frame in frames {
531 diag.subdiagnostic(frame);
532 }
533 })
534}
535
536#[inline(never)]
537fn report_validation_error<'tcx>(
538 ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
539 cid: GlobalId<'tcx>,
540 error: InterpErrorInfo<'tcx>,
541 alloc_id: AllocId,
542) -> ErrorHandled {
543 if !#[allow(non_exhaustive_omitted_patterns)] match error.kind() {
InterpErrorKind::UndefinedBehavior(_) => true,
_ => false,
}matches!(error.kind(), InterpErrorKind::UndefinedBehavior(_)) {
544 return report_eval_error(ecx, cid, error);
546 }
547
548 let (error, backtrace) = error.into_parts();
549 backtrace.print_backtrace();
550
551 let bytes = ecx.print_alloc_bytes_for_diagnostics(alloc_id);
552 let info = ecx.get_alloc_info(alloc_id);
553 let raw_bytes =
554 diagnostics::RawBytesNote { size: info.size.bytes(), align: info.align.bytes(), bytes };
555
556 crate::const_eval::report(ecx, error, move |diag, span, frames| {
557 diag.span_label(span, "it is undefined behavior to use this value");
558 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.");
559 if !frames.is_empty() {
::core::panicking::panic("assertion failed: frames.is_empty()")
};assert!(frames.is_empty()); diag.subdiagnostic(raw_bytes);
561 })
562}