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