Skip to main content

rustc_const_eval/const_eval/
eval_queries.rs

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};
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, errors};
25
26fn setup_for_eval<'tcx>(
27    ecx: &mut CompileTimeInterpCx<'tcx>,
28    cid: GlobalId<'tcx>,
29    layout: TyAndLayout<'tcx>,
30) -> InterpResult<'tcx, (InternKind, MPlaceTy<'tcx>)> {
31    let tcx = *ecx.tcx;
32    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::InlineConst | DefKind::AssocConst { .. } => true,
                _ => false,
            }) {
    {
        ::core::panicking::panic_fmt(format_args!("Unexpected DefKind: {0:?}",
                ecx.tcx.def_kind(cid.instance.def_id())));
    }
};assert!(
33        cid.promoted.is_some()
34            || matches!(
35                ecx.tcx.def_kind(cid.instance.def_id()),
36                DefKind::Const { .. }
37                    | DefKind::Static { .. }
38                    | DefKind::ConstParam
39                    | DefKind::AnonConst
40                    | DefKind::InlineConst
41                    | DefKind::AssocConst { .. }
42            ),
43        "Unexpected DefKind: {:?}",
44        ecx.tcx.def_kind(cid.instance.def_id())
45    );
46    if !layout.is_sized() {
    ::core::panicking::panic("assertion failed: layout.is_sized()")
};assert!(layout.is_sized());
47
48    let intern_kind = if cid.promoted.is_some() {
49        InternKind::Promoted
50    } else {
51        match tcx.static_mutability(cid.instance.def_id()) {
52            Some(m) => InternKind::Static(m),
53            None => InternKind::Constant,
54        }
55    };
56
57    let return_place = if let InternKind::Static(_) = intern_kind {
58        create_static_alloc(ecx, cid.instance.def_id().expect_local(), layout)
59    } else {
60        ecx.allocate(layout, MemoryKind::Stack)
61    };
62
63    return_place.map(|ret| (intern_kind, ret))
64}
65
66#[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(66u32),
                                    ::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().instantiate(tcx,
                            cid.instance.args))?;
            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:76",
                                    "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(76u32),
                                    ::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))]
67fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
68    ecx: &mut CompileTimeInterpCx<'tcx>,
69    cid: GlobalId<'tcx>,
70    body: &'tcx mir::Body<'tcx>,
71) -> InterpResult<'tcx, R> {
72    let tcx = *ecx.tcx;
73    let layout = ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args))?;
74    let (intern_kind, ret) = setup_for_eval(ecx, cid, layout)?;
75
76    trace!(
77        "eval_body_using_ecx: pushing stack frame for global: {}{}",
78        with_no_trimmed_paths!(ecx.tcx.def_path_str(cid.instance.def_id())),
79        cid.promoted.map_or_else(String::new, |p| format!("::{p:?}"))
80    );
81
82    // This can't use `init_stack_frame` since `body` is not a function,
83    // so computing its ABI would fail. It's also not worth it since there are no arguments to pass.
84    ecx.push_stack_frame_raw(
85        cid.instance,
86        body,
87        &ret.clone().into(),
88        ReturnContinuation::Stop { cleanup: false },
89    )?;
90    ecx.push_stack_frame_done()?;
91
92    // The main interpreter loop.
93    while ecx.step()? {
94        if CTRL_C_RECEIVED.load(Relaxed) {
95            throw_exhaust!(Interrupted);
96        }
97    }
98
99    intern_and_validate(ecx, cid, intern_kind, ret)
100}
101
102#[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(102u32),
                                    ::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))]
103fn eval_trivial_const_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
104    ecx: &mut CompileTimeInterpCx<'tcx>,
105    cid: GlobalId<'tcx>,
106    val: ConstValue,
107    ty: Ty<'tcx>,
108) -> InterpResult<'tcx, R> {
109    let layout = ecx.layout_of(ty)?;
110    let (intern_kind, return_place) = setup_for_eval(ecx, cid, layout)?;
111
112    let opty = ecx.const_val_to_op(val, ty, Some(layout))?;
113    ecx.copy_op(&opty, &return_place)?;
114
115    intern_and_validate(ecx, cid, intern_kind, return_place)
116}
117
118fn intern_and_validate<'tcx, R: InterpretationResult<'tcx>>(
119    ecx: &mut CompileTimeInterpCx<'tcx>,
120    cid: GlobalId<'tcx>,
121    intern_kind: InternKind,
122    ret: MPlaceTy<'tcx>,
123) -> InterpResult<'tcx, R> {
124    // Intern the result
125    let intern_result = intern_const_alloc_recursive(ecx, intern_kind, &ret);
126
127    // Since evaluation had no errors, validate the resulting constant.
128    const_validate_mplace(ecx, &ret, cid)?;
129
130    // Only report this after validation, as validation produces much better diagnostics.
131    // FIXME: ensure validation always reports this and stop making interning care about it.
132
133    match intern_result {
134        Ok(()) => {}
135        Err(InternError::DanglingPointer) => {
136            do yeet ::rustc_middle::mir::interpret::InterpErrorKind::InvalidProgram(::rustc_middle::mir::interpret::InvalidProgramInfo::AlreadyReported(ReportedErrorInfo::non_const_eval_error(ecx.tcx.dcx().emit_err(errors::DanglingPtrInFinal {
                        span: ecx.tcx.span,
                        kind: intern_kind,
                    }))));throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
137                ecx.tcx
138                    .dcx()
139                    .emit_err(errors::DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind }),
140            )));
141        }
142        Err(InternError::BadMutablePointer) => {
143            do yeet ::rustc_middle::mir::interpret::InterpErrorKind::InvalidProgram(::rustc_middle::mir::interpret::InvalidProgramInfo::AlreadyReported(ReportedErrorInfo::non_const_eval_error(ecx.tcx.dcx().emit_err(errors::MutablePtrInFinal {
                        span: ecx.tcx.span,
                        kind: intern_kind,
                    }))));throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
144                ecx.tcx
145                    .dcx()
146                    .emit_err(errors::MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind }),
147            )));
148        }
149        Err(InternError::ConstAllocNotGlobal) => {
150            do yeet ::rustc_middle::mir::interpret::InterpErrorKind::InvalidProgram(::rustc_middle::mir::interpret::InvalidProgramInfo::AlreadyReported(ReportedErrorInfo::non_const_eval_error(ecx.tcx.dcx().emit_err(errors::ConstHeapPtrInFinal {
                        span: ecx.tcx.span,
                    }))));throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
151                ecx.tcx.dcx().emit_err(errors::ConstHeapPtrInFinal { span: ecx.tcx.span }),
152            )));
153        }
154        Err(InternError::PartialPointer) => {
155            do yeet ::rustc_middle::mir::interpret::InterpErrorKind::InvalidProgram(::rustc_middle::mir::interpret::InvalidProgramInfo::AlreadyReported(ReportedErrorInfo::non_const_eval_error(ecx.tcx.dcx().emit_err(errors::PartialPtrInFinal {
                        span: ecx.tcx.span,
                        kind: intern_kind,
                    }))));throw_inval!(AlreadyReported(ReportedErrorInfo::non_const_eval_error(
156                ecx.tcx
157                    .dcx()
158                    .emit_err(errors::PartialPtrInFinal { span: ecx.tcx.span, kind: intern_kind }),
159            )));
160        }
161    }
162
163    interp_ok(R::make_result(ret, ecx))
164}
165
166/// The `InterpCx` is only meant to be used to do field and index projections into constants for
167/// `simd_shuffle` and const patterns in match arms.
168///
169/// This should *not* be used to do any actual interpretation. In particular, alignment checks are
170/// turned off!
171///
172/// The function containing the `match` that is currently being analyzed may have generic bounds
173/// that inform us about the generic bounds of the constant. E.g., using an associated constant
174/// of a function's generic parameter will require knowledge about the bounds on the generic
175/// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument.
176pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
177    tcx: TyCtxt<'tcx>,
178    root_span: Span,
179    typing_env: ty::TypingEnv<'tcx>,
180    can_access_mut_global: CanAccessMutGlobal,
181) -> CompileTimeInterpCx<'tcx> {
182    {
    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:182",
                        "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(182u32),
                        ::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);
183    InterpCx::new(
184        tcx,
185        root_span,
186        typing_env,
187        CompileTimeMachine::new(can_access_mut_global, CheckAlignment::No),
188    )
189}
190
191/// Create an interpreter context to inspect the given `ConstValue`.
192/// Returns both the context and an `OpTy` that represents the constant.
193pub fn mk_eval_cx_for_const_val<'tcx>(
194    tcx: TyCtxtAt<'tcx>,
195    typing_env: ty::TypingEnv<'tcx>,
196    val: mir::ConstValue,
197    ty: Ty<'tcx>,
198) -> Option<(CompileTimeInterpCx<'tcx>, OpTy<'tcx>)> {
199    let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, typing_env, CanAccessMutGlobal::No);
200    // FIXME: is it a problem to discard the error here?
201    let op = ecx.const_val_to_op(val, ty, None).discard_err()?;
202    Some((ecx, op))
203}
204
205/// This function converts an interpreter value into a MIR constant.
206///
207/// The `for_diagnostics` flag turns the usual rules for returning `ConstValue::Scalar` into a
208/// best-effort attempt. This is not okay for use in const-eval sine it breaks invariants rustc
209/// relies on, but it is okay for diagnostics which will just give up gracefully when they
210/// encounter an `Indirect` they cannot handle.
211#[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(211u32),
                                    ::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:254",
                                    "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(254u32),
                                    ::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:267",
                                                    "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(267u32),
                                                    ::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")]
212pub(super) fn op_to_const<'tcx>(
213    ecx: &CompileTimeInterpCx<'tcx>,
214    op: &OpTy<'tcx>,
215    for_diagnostics: bool,
216) -> ConstValue {
217    // Handle ZST consistently and early.
218    if op.layout.is_zst() {
219        return ConstValue::ZeroSized;
220    }
221
222    // All scalar types should be stored as `ConstValue::Scalar`. This is needed to make
223    // `ConstValue::try_to_scalar` efficient; we want that to work for *all* constants of scalar
224    // type (it's used throughout the compiler and having it work just on literals is not enough)
225    // and we want it to be fast (i.e., don't go to an `Allocation` and reconstruct the `Scalar`
226    // from its byte-serialized form).
227    let force_as_immediate = match op.layout.backend_repr {
228        BackendRepr::Scalar(abi::Scalar::Initialized { .. }) => true,
229        // We don't *force* `ConstValue::Slice` for `ScalarPair`. This has the advantage that if the
230        // input `op` is a place, then turning it into a `ConstValue` and back into a `OpTy` will
231        // not have to generate any duplicate allocations (we preserve the original `AllocId` in
232        // `ConstValue::Indirect`). It means accessing the contents of a slice can be slow (since
233        // they can be stored as `ConstValue::Indirect`), but that's not relevant since we barely
234        // ever have to do this. (`try_get_slice_bytes_for_diagnostics` exists to provide this
235        // functionality.)
236        _ => false,
237    };
238    let immediate = if force_as_immediate {
239        match ecx.read_immediate(op).report_err() {
240            Ok(imm) => Right(imm),
241            Err(err) => {
242                if for_diagnostics {
243                    // This discard the error, but for diagnostics that's okay.
244                    op.as_mplace_or_imm()
245                } else {
246                    panic!("normalization works on validated constants: {err:?}")
247                }
248            }
249        }
250    } else {
251        op.as_mplace_or_imm()
252    };
253
254    debug!(?immediate);
255
256    match immediate {
257        Left(ref mplace) => {
258            let (prov, offset) =
259                mplace.ptr().into_pointer_or_addr().unwrap().prov_and_relative_offset();
260            let alloc_id = prov.alloc_id();
261            ConstValue::Indirect { alloc_id, offset }
262        }
263        // see comment on `let force_as_immediate` above
264        Right(imm) => match *imm {
265            Immediate::Scalar(x) => ConstValue::Scalar(x),
266            Immediate::ScalarPair(a, b) => {
267                debug!("ScalarPair(a: {:?}, b: {:?})", a, b);
268                // This codepath solely exists for `valtree_to_const_value` to not need to generate
269                // a `ConstValue::Indirect` for wide references, so it is tightly restricted to just
270                // that case.
271                let pointee_ty = imm.layout.ty.builtin_deref(false).unwrap(); // `false` = no raw ptrs
272                debug_assert!(
273                    matches!(
274                        ecx.tcx.struct_tail_for_codegen(pointee_ty, ecx.typing_env()).kind(),
275                        ty::Str | ty::Slice(..),
276                    ),
277                    "`ConstValue::Slice` is for slice-tailed types only, but got {}",
278                    imm.layout.ty,
279                );
280                let msg = "`op_to_const` on an immediate scalar pair must only be used on slice references to the beginning of an actual allocation";
281                let ptr = a.to_pointer(ecx).expect(msg);
282                let (prov, offset) =
283                    ptr.into_pointer_or_addr().expect(msg).prov_and_relative_offset();
284                let alloc_id = prov.alloc_id();
285                assert!(offset == abi::Size::ZERO, "{}", msg);
286                let meta = b.to_target_usize(ecx).expect(msg);
287                ConstValue::Slice { alloc_id, meta }
288            }
289            Immediate::Uninit => bug!("`Uninit` is not a valid value for {}", op.layout.ty),
290        },
291    }
292}
293
294x;#[instrument(skip(tcx), level = "debug", ret)]
295pub(crate) fn turn_into_const_value<'tcx>(
296    tcx: TyCtxt<'tcx>,
297    constant: ConstAlloc<'tcx>,
298    key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
299) -> ConstValue {
300    let cid = key.value;
301    let def_id = cid.instance.def.def_id();
302    let is_static = tcx.is_static(def_id);
303    // This is just accessing an already computed constant, so no need to check alignment here.
304    let ecx = mk_eval_cx_to_read_const_val(
305        tcx,
306        tcx.def_span(key.value.instance.def_id()),
307        key.typing_env,
308        CanAccessMutGlobal::from(is_static),
309    );
310
311    let mplace = ecx.raw_const_to_mplace(constant).expect(
312        "can only fail if layout computation failed, \
313        which should have given a good error before ever invoking this function",
314    );
315    assert!(
316        !is_static || cid.promoted.is_some(),
317        "the `eval_to_const_value_raw` query should not be used for statics, use `eval_to_allocation` instead"
318    );
319
320    // Turn this into a proper constant.
321    op_to_const(&ecx, &mplace.into(), /* for diagnostics */ false)
322}
323
324#[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(324u32),
                                    ::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;
        }
        {
            if let Some((value, _ty)) =
                    tcx.trivial_const(key.value.instance.def_id()) {
                return Ok(value);
            }
            tcx.eval_to_allocation_raw(key).map(|val|
                    turn_into_const_value(tcx, val, key))
        }
    }
}#[instrument(skip(tcx), level = "debug")]
325pub fn eval_to_const_value_raw_provider<'tcx>(
326    tcx: TyCtxt<'tcx>,
327    key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
328) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
329    if let Some((value, _ty)) = tcx.trivial_const(key.value.instance.def_id()) {
330        return Ok(value);
331    }
332    tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key))
333}
334
335#[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(335u32),
                                    ::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")]
336pub fn eval_static_initializer_provider<'tcx>(
337    tcx: TyCtxt<'tcx>,
338    def_id: LocalDefId,
339) -> ::rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'tcx> {
340    assert!(tcx.is_static(def_id.to_def_id()));
341
342    let instance = ty::Instance::mono(tcx, def_id.to_def_id());
343    let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
344    eval_in_interpreter(tcx, cid, ty::TypingEnv::fully_monomorphized())
345}
346
347pub trait InterpretationResult<'tcx> {
348    /// This function takes the place where the result of the evaluation is stored
349    /// and prepares it for returning it in the appropriate format needed by the specific
350    /// evaluation query.
351    fn make_result(
352        mplace: MPlaceTy<'tcx>,
353        ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
354    ) -> Self;
355}
356
357impl<'tcx> InterpretationResult<'tcx> for ConstAlloc<'tcx> {
358    fn make_result(
359        mplace: MPlaceTy<'tcx>,
360        _ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
361    ) -> Self {
362        ConstAlloc { alloc_id: mplace.ptr().provenance.unwrap().alloc_id(), ty: mplace.layout.ty }
363    }
364}
365
366#[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(366u32),
                                    ::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;
        }
        {
            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 {
                match key.typing_env.typing_mode() {
                    ty::TypingMode::PostAnalysis => {}
                    ty::TypingMode::Coherence | ty::TypingMode::Analysis { .. }
                        | ty::TypingMode::Borrowck { .. } |
                        ty::TypingMode::PostBorrowckAnalysis { .. } => {
                        ::rustc_middle::util::bug::bug_fmt(format_args!("Const eval should always happens in PostAnalysis mode. See the comment in `InterpCx::new` for more details."))
                    }
                }
                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:394",
                                        "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(394u32),
                                        ::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")]
367pub fn eval_to_allocation_raw_provider<'tcx>(
368    tcx: TyCtxt<'tcx>,
369    key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
370) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
371    // This shouldn't be used for statics, since statics are conceptually places,
372    // not values -- so what we do here could break pointer identity.
373    assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));
374
375    if cfg!(debug_assertions) {
376        match key.typing_env.typing_mode() {
377            ty::TypingMode::PostAnalysis => {}
378            ty::TypingMode::Coherence
379            | ty::TypingMode::Analysis { .. }
380            | ty::TypingMode::Borrowck { .. }
381            | ty::TypingMode::PostBorrowckAnalysis { .. } => {
382                bug!(
383                    "Const eval should always happens in PostAnalysis mode. See the comment in `InterpCx::new` for more details."
384                )
385            }
386        }
387
388        // Make sure we format the instance even if we do not print it.
389        // This serves as a regression test against an ICE on printing.
390        // The next two lines concatenated contain some discussion:
391        // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/
392        // subject/anon_const_instance_printing/near/135980032
393        let instance = with_no_trimmed_paths!(key.value.instance.to_string());
394        trace!("const eval: {:?} ({})", key, instance);
395    }
396
397    eval_in_interpreter(tcx, key.value, key.typing_env)
398}
399
400fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
401    tcx: TyCtxt<'tcx>,
402    cid: GlobalId<'tcx>,
403    typing_env: ty::TypingEnv<'tcx>,
404) -> Result<R, ErrorHandled> {
405    let def = cid.instance.def.def_id();
406    // `type const` don't have bodys
407    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);
408
409    let is_static = tcx.is_static(def);
410    let mut ecx = InterpCx::new(
411        tcx,
412        tcx.def_span(def),
413        typing_env,
414        // Statics (and promoteds inside statics) may access mutable global memory, because unlike consts
415        // they do not have to behave "as if" they were evaluated at runtime.
416        // For consts however we want to ensure they behave "as if" they were evaluated at runtime,
417        // so we have to reject reading mutable global memory.
418        CompileTimeMachine::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
419    );
420
421    let result = if let Some((value, ty)) = tcx.trivial_const(def) {
422        eval_trivial_const_using_ecx(&mut ecx, cid, value, ty)
423    } else {
424        ecx.load_mir(cid.instance.def, cid.promoted)
425            .and_then(|body| eval_body_using_ecx(&mut ecx, cid, body))
426    };
427    result.report_err().map_err(|error| report_eval_error(&ecx, cid, error))
428}
429
430#[inline(always)]
431fn const_validate_mplace<'tcx>(
432    ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
433    mplace: &MPlaceTy<'tcx>,
434    cid: GlobalId<'tcx>,
435) -> Result<(), ErrorHandled> {
436    let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
437    let mut ref_tracking = RefTracking::new(mplace.clone(), mplace.layout.ty);
438    let mut inner = false;
439    while let Some((mplace, path)) = ref_tracking.next() {
440        let mode = match ecx.tcx.static_mutability(cid.instance.def_id()) {
441            _ if cid.promoted.is_some() => CtfeValidationMode::Promoted,
442            Some(mutbl) => CtfeValidationMode::Static { mutbl }, // a `static`
443            None => {
444                // This is a normal `const` (not promoted).
445                // The outermost allocation is always only copied, so having `UnsafeCell` in there
446                // is okay despite them being in immutable memory.
447                CtfeValidationMode::Const { allow_immutable_unsafe_cell: !inner }
448            }
449        };
450        ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)
451            .report_err()
452            // Instead of just reporting the `InterpError` via the usual machinery, we give a more targeted
453            // error about the validation failure.
454            .map_err(|error| report_validation_error(&ecx, cid, error, alloc_id))?;
455        inner = true;
456    }
457
458    Ok(())
459}
460
461#[inline(never)]
462fn report_eval_error<'tcx>(
463    ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
464    cid: GlobalId<'tcx>,
465    error: InterpErrorInfo<'tcx>,
466) -> ErrorHandled {
467    let (error, backtrace) = error.into_parts();
468    backtrace.print_backtrace();
469
470    super::report(ecx, error, |diag, span, frames| {
471        let num_frames = frames.len();
472        diag.span_label(
473            span,
474            ::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!(
475                "evaluation of `{instance}` failed {where_}",
476                instance = with_no_trimmed_paths!(cid.instance.to_string()),
477                where_ = if num_frames == 0 { "here" } else { "inside this call" },
478            ),
479        );
480        for frame in frames {
481            diag.subdiagnostic(frame);
482        }
483    })
484}
485
486#[inline(never)]
487fn report_validation_error<'tcx>(
488    ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
489    cid: GlobalId<'tcx>,
490    error: InterpErrorInfo<'tcx>,
491    alloc_id: AllocId,
492) -> ErrorHandled {
493    if !#[allow(non_exhaustive_omitted_patterns)] match error.kind() {
    InterpErrorKind::UndefinedBehavior(_) => true,
    _ => false,
}matches!(error.kind(), InterpErrorKind::UndefinedBehavior(_)) {
494        // Some other error happened during validation, e.g. an unsupported operation.
495        return report_eval_error(ecx, cid, error);
496    }
497
498    let (error, backtrace) = error.into_parts();
499    backtrace.print_backtrace();
500
501    let bytes = ecx.print_alloc_bytes_for_diagnostics(alloc_id);
502    let info = ecx.get_alloc_info(alloc_id);
503    let raw_bytes =
504        errors::RawBytesNote { size: info.size.bytes(), align: info.align.bytes(), bytes };
505
506    crate::const_eval::report(ecx, error, move |diag, span, frames| {
507        diag.span_label(span, "it is undefined behavior to use this value");
508        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.");
509        if !frames.is_empty() {
    ::core::panicking::panic("assertion failed: frames.is_empty()")
};assert!(frames.is_empty()); // we just report validation errors for the final const here
510        diag.subdiagnostic(raw_bytes);
511    })
512}