Skip to main content

rustc_mir_build/thir/cx/
expr.rs

1use itertools::Itertools;
2use rustc_abi::{FIRST_VARIANT, FieldIdx, Size, VariantIdx};
3use rustc_ast::UnsafeBinderCastKind;
4use rustc_attr_ir::lang_items::LangItem;
5use rustc_attr_ir::{AttributeKind, HasAttrs, find_attr};
6use rustc_data_structures::thin_vec::ThinVec;
7use rustc_hir as hir;
8use rustc_hir::HirId;
9use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
10use rustc_index::Idx;
11use rustc_middle::hir::place::{
12    Place as HirPlace, PlaceBase as HirPlaceBase, ProjectionKind as HirProjectionKind,
13};
14use rustc_middle::middle::region;
15use rustc_middle::mir::{self, AssignOp, BinOp, BorrowKind, UnOp};
16use rustc_middle::thir::*;
17use rustc_middle::ty::adjustment::{
18    Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, DerefAdjustKind, PointerCoercion,
19};
20use rustc_middle::ty::{
21    self, AdtKind, GenericArgs, InlineConstArgs, InlineConstArgsParts, ScalarInt, SplattedDef, Ty,
22    TyCtxt, UpvarArgs,
23};
24use rustc_span::{DesugaringKind, Span, bug, span_bug};
25use tracing::{debug, info, instrument, trace};
26
27use crate::diagnostics::*;
28use crate::thir::cx::ThirBuildCx;
29
30/// The receiver of a splatted method, or the expression for a splatted function call.
31#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for SplattedFunc<'tcx> { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for SplattedFunc<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for SplattedFunc<'tcx> {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<&'tcx hir::Expr<'tcx>>;
        let _: ::core::clone::AssertParamIsClone<&'tcx hir::Expr<'tcx>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for SplattedFunc<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::FnDefReceiver(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "FnDefReceiver", &__self_0),
            Self::FnExpression(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "FnExpression", &__self_0),
        }
    }
}Debug)]
32enum SplattedFunc<'tcx> {
33    /// The expression for a method receiver. Always a FnDef.
34    FnDefReceiver(&'tcx hir::Expr<'tcx>),
35    /// The expression or path for a function call.
36    /// This can be a FnDef or FnPtr.
37    FnExpression(&'tcx hir::Expr<'tcx>),
38}
39
40impl<'tcx> SplattedFunc<'tcx> {
41    fn has_receiver(&self) -> bool {
42        #[allow(non_exhaustive_omitted_patterns)] match self {
    SplattedFunc::FnDefReceiver(_) => true,
    _ => false,
}matches!(self, SplattedFunc::FnDefReceiver(_))
43    }
44
45    fn receiver(&self) -> Option<&'tcx hir::Expr<'tcx>> {
46        match self {
47            SplattedFunc::FnDefReceiver(receiver) => Some(receiver),
48            SplattedFunc::FnExpression(_fn_expression) => None,
49        }
50    }
51
52    fn fn_expression(&self) -> Option<&'tcx hir::Expr<'tcx>> {
53        match self {
54            SplattedFunc::FnDefReceiver(_receiver) => None,
55            SplattedFunc::FnExpression(fn_expression) => Some(fn_expression),
56        }
57    }
58}
59
60fn filter_loop_hint_attrs(id: HirId, tcx: TyCtxt<'_>) -> ThinVec<AttributeKind> {
61    HasAttrs::get_attrs(id, &tcx)
62        .into_iter()
63        .filter_map(|attr| match attr {
64            rustc_attr_ir::Attribute::Parsed(attrkind @ AttributeKind::Unroll(_)) => {
65                Some(attrkind.clone())
66            }
67            _ => None,
68        })
69        .collect()
70}
71
72impl<'tcx> ThirBuildCx<'tcx> {
73    pub(crate) fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> Box<[ExprId]> {
74        exprs.iter().map(|expr| self.mirror_expr(expr)).collect()
75    }
76
77    /// Create a THIR expression for the given HIR expression. This expands all
78    /// adjustments and directly adds the type information from the
79    /// `typeck_results`. See the [dev-guide] for more details.
80    ///
81    /// (The term "mirror" in this case does not refer to "flipped" or
82    /// "reversed".)
83    ///
84    /// [dev-guide]: https://rustc-dev-guide.rust-lang.org/thir.html
85    {}
#[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("mirror_expr",
                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                    ::tracing_core::__macro_support::Option::Some(85u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                    ::tracing_core::field::FieldSet::new(&[],
                                        ::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,
                        &{ meta.fields().value_set_all(&[]) })
                } 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: ExprId = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let expr_scope =
                region::Scope {
                    local_id: hir_expr.hir_id.local_id,
                    data: region::ScopeData::Node,
                };
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:90",
                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                    ::tracing_core::__macro_support::Option::Some(90u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("hir_expr.hir_id")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("hir_expr.hir_id");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("hir_expr.span")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("hir_expr.span");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hir_expr.hir_id)
                                                        as &dyn ::tracing::field::Value)),
                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hir_expr.span)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let mut expr = self.make_mirror_unadjusted(hir_expr);
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:94",
                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                    ::tracing_core::__macro_support::Option::Some(94u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("expr.ty")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("expr.ty");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr.ty)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let mut loop_hint_attrs = ThinVec::new();
            if let hir::ExprKind::Loop(_, _, _, span) = hir_expr.kind {
                match span.desugaring_kind() {
                    Some(DesugaringKind::ForLoop) => {
                        let arm =
                            self.tcx.parent_hir_node(hir_expr.hir_id).expect_arm();
                        let expr =
                            self.tcx.parent_hir_node(arm.hir_id).expect_expr();
                        {
                            match expr.kind {
                                hir::ExprKind::Match(..) => {}
                                ref left_val => {
                                    ::core::panicking::assert_matches_failed(left_val,
                                        "hir::ExprKind::Match(..)", ::core::option::Option::None);
                                }
                            }
                        };
                        if let hir::Node::Expr(expr) =
                                self.tcx.parent_hir_node(expr.hir_id) {
                            {
                                match expr.kind {
                                    hir::ExprKind::DropTemps(..) => {}
                                    ref left_val => {
                                        ::core::panicking::assert_matches_failed(left_val,
                                            "hir::ExprKind::DropTemps(..)",
                                            ::core::option::Option::None);
                                    }
                                }
                            };
                            loop_hint_attrs =
                                filter_loop_hint_attrs(expr.hir_id, self.tcx)
                        }
                    }
                    Some(DesugaringKind::WhileLoop) | None => {
                        loop_hint_attrs =
                            filter_loop_hint_attrs(hir_expr.hir_id, self.tcx);
                    }
                    _ => (),
                }
            }
            if self.apply_adjustments {
                for adjustment in
                    self.typeck_results.expr_adjustments(hir_expr) {
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:122",
                                            "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                            ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                            ::tracing_core::__macro_support::Option::Some(122u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                            ::tracing_core::field::FieldSet::new(&[{
                                                                const NAME:
                                                                    ::tracing::__macro_support::FieldName<{
                                                                        ::tracing::__macro_support::FieldName::len("expr")
                                                                    }> =
                                                                    ::tracing::__macro_support::FieldName::new("expr");
                                                                NAME.as_str()
                                                            },
                                                            {
                                                                const NAME:
                                                                    ::tracing::__macro_support::FieldName<{
                                                                        ::tracing::__macro_support::FieldName::len("adjustment")
                                                                    }> =
                                                                    ::tracing::__macro_support::FieldName::new("adjustment");
                                                                NAME.as_str()
                                                            }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::EVENT)
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let enabled =
                            ::tracing::Level::TRACE <=
                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                    ::tracing::Level::TRACE <=
                                        ::tracing::level_filters::LevelFilter::current() &&
                                {
                                    let interest = __CALLSITE.interest();
                                    !interest.is_never() &&
                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                            interest)
                                };
                        if enabled {
                            (|value_set: ::tracing::field::ValueSet|
                                        {
                                            let meta = __CALLSITE.metadata();
                                            ::tracing::Event::dispatch(meta, &value_set);
                                            ;
                                        })({
                                    #[allow(unused_imports)]
                                    use ::tracing::field::{debug, display, Value};
                                    __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr)
                                                                as &dyn ::tracing::field::Value)),
                                                    (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&adjustment)
                                                                as &dyn ::tracing::field::Value))])
                                });
                        } else { ; }
                    };
                    let span = expr.span;
                    expr =
                        self.apply_adjustment(hir_expr, expr, adjustment, span);
                }
            }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:128",
                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                    ::tracing_core::__macro_support::Option::Some(128u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                    ::tracing_core::field::FieldSet::new(&["message",
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("expr.ty")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("expr.ty");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("after adjustments")
                                                        as &dyn ::tracing::field::Value)),
                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr.ty)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let ty = expr.ty;
            let value = self.thir.exprs.push(expr);
            if !loop_hint_attrs.is_empty() {
                self.thir.loop_hint_attrs.insert(value, loop_hint_attrs);
            }
            expr =
                Expr {
                    temp_scope_id: expr_scope.local_id,
                    ty,
                    span: hir_expr.span,
                    kind: ExprKind::Scope {
                        region_scope: expr_scope,
                        value,
                        hir_id: hir_expr.hir_id,
                    },
                };
            self.thir.exprs.push(expr)
        }
    }
}#[instrument(level = "trace", skip(self, hir_expr))]
86    pub(crate) fn mirror_expr(&mut self, hir_expr: &'tcx hir::Expr<'tcx>) -> ExprId {
87        let expr_scope =
88            region::Scope { local_id: hir_expr.hir_id.local_id, data: region::ScopeData::Node };
89
90        trace!(?hir_expr.hir_id, ?hir_expr.span);
91
92        let mut expr = self.make_mirror_unadjusted(hir_expr);
93
94        trace!(?expr.ty);
95
96        let mut loop_hint_attrs = ThinVec::new();
97
98        if let hir::ExprKind::Loop(_, _, _, span) = hir_expr.kind {
99            match span.desugaring_kind() {
100                // `for` loop desugaring puts us pretty deep down the HIR tree
101                Some(DesugaringKind::ForLoop) => {
102                    let arm = self.tcx.parent_hir_node(hir_expr.hir_id).expect_arm();
103                    let expr = self.tcx.parent_hir_node(arm.hir_id).expect_expr();
104                    std::assert_matches!(expr.kind, hir::ExprKind::Match(..));
105                    // ignore async for loops
106                    if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(expr.hir_id) {
107                        std::assert_matches!(expr.kind, hir::ExprKind::DropTemps(..));
108                        loop_hint_attrs = filter_loop_hint_attrs(expr.hir_id, self.tcx)
109                    }
110                }
111                // For loops defined with `loop` and `while`, the expr already has the attrs
112                Some(DesugaringKind::WhileLoop) | None => {
113                    loop_hint_attrs = filter_loop_hint_attrs(hir_expr.hir_id, self.tcx);
114                }
115                _ => (),
116            }
117        }
118
119        // Now apply adjustments, if any.
120        if self.apply_adjustments {
121            for adjustment in self.typeck_results.expr_adjustments(hir_expr) {
122                trace!(?expr, ?adjustment);
123                let span = expr.span;
124                expr = self.apply_adjustment(hir_expr, expr, adjustment, span);
125            }
126        }
127
128        trace!(?expr.ty, "after adjustments");
129
130        let ty = expr.ty;
131        let value = self.thir.exprs.push(expr);
132
133        if !loop_hint_attrs.is_empty() {
134            self.thir.loop_hint_attrs.insert(value, loop_hint_attrs);
135        }
136
137        // Finally, wrap this up in the expr's scope.
138        //
139        // (In addition to marking scope, coverage instrumentation also uses this node
140        // to help mark the point in MIR where an expression is about to be evaluated.)
141        expr = Expr {
142            temp_scope_id: expr_scope.local_id,
143            ty,
144            span: hir_expr.span,
145            kind: ExprKind::Scope { region_scope: expr_scope, value, hir_id: hir_expr.hir_id },
146        };
147
148        // OK, all done!
149        self.thir.exprs.push(expr)
150    }
151
152    {}
#[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("apply_adjustment",
                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                    ::tracing_core::__macro_support::Option::Some(152u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("hir_expr")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("hir_expr");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("adjustment")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("adjustment");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hir_expr)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&adjustment)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: Expr<'tcx> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let Expr { temp_scope_id, .. } = expr;
            let mut adjust_span =
                |expr: &mut Expr<'tcx>|
                    {
                        if let ExprKind::Block { block } = expr.kind &&
                                let Some(last_expr) = self.thir[block].expr {
                            span = self.thir[last_expr].span;
                            expr.span = span;
                        }
                    };
            let kind =
                match adjustment.kind {
                    Adjust::Pointer(cast) => {
                        if cast == PointerCoercion::Unsize {
                            adjust_span(&mut expr);
                        }
                        let is_from_as_cast =
                            if let hir::Node::Expr(hir::Expr {
                                    kind: hir::ExprKind::Cast(..), span: cast_span, .. }) =
                                    self.tcx.parent_hir_node(hir_expr.hir_id) {
                                span = *cast_span;
                                true
                            } else { false };
                        ExprKind::PointerCoercion {
                            cast,
                            source: self.thir.exprs.push(expr),
                            is_from_as_cast,
                        }
                    }
                    Adjust::NeverToAny if adjustment.target.is_never() =>
                        return expr,
                    Adjust::NeverToAny =>
                        ExprKind::NeverToAny { source: self.thir.exprs.push(expr) },
                    Adjust::Deref(DerefAdjustKind::Builtin) => {
                        adjust_span(&mut expr);
                        ExprKind::Deref { arg: self.thir.exprs.push(expr) }
                    }
                    Adjust::Deref(DerefAdjustKind::Pin) => {
                        adjust_span(&mut expr);
                        let pin_ty =
                            expr.ty.pinned_ty().expect("Deref(Pin) with non-Pin type");
                        let pointer_target =
                            ExprKind::Field {
                                lhs: self.thir.exprs.push(expr),
                                variant_index: FIRST_VARIANT,
                                name: FieldIdx::ZERO,
                            };
                        let expr =
                            Expr {
                                temp_scope_id,
                                ty: pin_ty,
                                span,
                                kind: pointer_target,
                            };
                        ExprKind::Deref { arg: self.thir.exprs.push(expr) }
                    }
                    Adjust::Deref(DerefAdjustKind::Overloaded(deref)) => {
                        let call_def_id = deref.method_call(self.tcx);
                        let overloaded_callee =
                            self.tcx.type_of(call_def_id).instantiate(self.tcx,
                                    self.tcx.mk_args(&[expr.ty.into()])).skip_norm_wip();
                        expr =
                            Expr {
                                temp_scope_id,
                                ty: Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased,
                                    expr.ty, deref.mutbl),
                                span,
                                kind: ExprKind::Borrow {
                                    borrow_kind: deref.mutbl.to_borrow_kind(),
                                    arg: self.thir.exprs.push(expr),
                                },
                            };
                        let expr = Box::new([self.thir.exprs.push(expr)]);
                        self.overloaded_place(hir_expr, adjustment.target,
                            Some(overloaded_callee), expr, deref.span)
                    }
                    Adjust::Borrow(AutoBorrow::Ref(m)) =>
                        ExprKind::Borrow {
                            borrow_kind: m.to_borrow_kind(),
                            arg: self.thir.exprs.push(expr),
                        },
                    Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
                        ExprKind::RawBorrow {
                            mutability,
                            arg: self.thir.exprs.push(expr),
                        }
                    }
                    Adjust::Borrow(AutoBorrow::Pin(mutbl)) => {
                        let borrow_kind =
                            match mutbl {
                                hir::Mutability::Mut =>
                                    BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
                                hir::Mutability::Not => BorrowKind::Shared,
                            };
                        let new_pin_target =
                            Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty,
                                mutbl);
                        let arg = self.thir.exprs.push(expr);
                        let expr =
                            self.thir.exprs.push(Expr {
                                    temp_scope_id,
                                    ty: new_pin_target,
                                    span,
                                    kind: ExprKind::Borrow { borrow_kind, arg },
                                });
                        let pin_did =
                            self.tcx.require_lang_item(LangItem::Pin, span);
                        let args = self.tcx.mk_args(&[new_pin_target.into()]);
                        let kind =
                            ExprKind::Adt(Box::new(AdtExpr {
                                        adt_def: self.tcx.adt_def(pin_did),
                                        variant_index: FIRST_VARIANT,
                                        args,
                                        fields: Box::new([FieldExpr {
                                                        name: FieldIdx::ZERO,
                                                        expr,
                                                    }]),
                                        user_ty: None,
                                        base: AdtExprBase::None,
                                    }));
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:289",
                                                "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                                ::tracing_core::__macro_support::Option::Some(289u32),
                                                ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                                ::tracing_core::field::FieldSet::new(&[{
                                                                    const NAME:
                                                                        ::tracing::__macro_support::FieldName<{
                                                                            ::tracing::__macro_support::FieldName::len("kind")
                                                                        }> =
                                                                        ::tracing::__macro_support::FieldName::new("kind");
                                                                    NAME.as_str()
                                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                ::tracing::metadata::Kind::EVENT)
                                        };
                                    ::tracing::callsite::DefaultCallsite::new(&META)
                                };
                            let enabled =
                                ::tracing::Level::DEBUG <=
                                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                        ::tracing::Level::DEBUG <=
                                            ::tracing::level_filters::LevelFilter::current() &&
                                    {
                                        let interest = __CALLSITE.interest();
                                        !interest.is_never() &&
                                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                interest)
                                    };
                            if enabled {
                                (|value_set: ::tracing::field::ValueSet|
                                            {
                                                let meta = __CALLSITE.metadata();
                                                ::tracing::Event::dispatch(meta, &value_set);
                                                ;
                                            })({
                                        #[allow(unused_imports)]
                                        use ::tracing::field::{debug, display, Value};
                                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&kind)
                                                                    as &dyn ::tracing::field::Value))])
                                    });
                            } else { ; }
                        };
                        kind
                    }
                    Adjust::GenericReborrow(mutability) => {
                        let expr = self.thir.exprs.push(expr);
                        let kind =
                            ExprKind::Reborrow {
                                source: expr,
                                mutability,
                                target: adjustment.target,
                            };
                        kind
                    }
                };
            Expr { temp_scope_id, ty: adjustment.target, span, kind }
        }
    }
}#[instrument(level = "trace", skip(self, expr, span))]
153    fn apply_adjustment(
154        &mut self,
155        hir_expr: &'tcx hir::Expr<'tcx>,
156        mut expr: Expr<'tcx>,
157        adjustment: &Adjustment<'tcx>,
158        mut span: Span,
159    ) -> Expr<'tcx> {
160        let Expr { temp_scope_id, .. } = expr;
161
162        // Adjust the span from the block, to the last expression of the
163        // block. This is a better span when returning a mutable reference
164        // with too short a lifetime. The error message will use the span
165        // from the assignment to the return place, which should only point
166        // at the returned value, not the entire function body.
167        //
168        // fn return_short_lived<'a>(x: &'a mut i32) -> &'static mut i32 {
169        //      x
170        //   // ^ error message points at this expression.
171        // }
172        let mut adjust_span = |expr: &mut Expr<'tcx>| {
173            if let ExprKind::Block { block } = expr.kind
174                && let Some(last_expr) = self.thir[block].expr
175            {
176                span = self.thir[last_expr].span;
177                expr.span = span;
178            }
179        };
180
181        let kind = match adjustment.kind {
182            Adjust::Pointer(cast) => {
183                if cast == PointerCoercion::Unsize {
184                    adjust_span(&mut expr);
185                }
186
187                let is_from_as_cast = if let hir::Node::Expr(hir::Expr {
188                    kind: hir::ExprKind::Cast(..),
189                    span: cast_span,
190                    ..
191                }) = self.tcx.parent_hir_node(hir_expr.hir_id)
192                {
193                    // Use the whole span of the `x as T` expression for the coercion.
194                    span = *cast_span;
195                    true
196                } else {
197                    false
198                };
199                ExprKind::PointerCoercion {
200                    cast,
201                    source: self.thir.exprs.push(expr),
202                    is_from_as_cast,
203                }
204            }
205            Adjust::NeverToAny if adjustment.target.is_never() => return expr,
206            Adjust::NeverToAny => ExprKind::NeverToAny { source: self.thir.exprs.push(expr) },
207            Adjust::Deref(DerefAdjustKind::Builtin) => {
208                adjust_span(&mut expr);
209                ExprKind::Deref { arg: self.thir.exprs.push(expr) }
210            }
211            Adjust::Deref(DerefAdjustKind::Pin) => {
212                adjust_span(&mut expr);
213                // pointer = ($expr).pointer
214                let pin_ty = expr.ty.pinned_ty().expect("Deref(Pin) with non-Pin type");
215                let pointer_target = ExprKind::Field {
216                    lhs: self.thir.exprs.push(expr),
217                    variant_index: FIRST_VARIANT,
218                    name: FieldIdx::ZERO,
219                };
220                let expr = Expr { temp_scope_id, ty: pin_ty, span, kind: pointer_target };
221                // expr = *pointer
222                ExprKind::Deref { arg: self.thir.exprs.push(expr) }
223            }
224            Adjust::Deref(DerefAdjustKind::Overloaded(deref)) => {
225                // We don't need to do call adjust_span here since
226                // deref coercions always start with a built-in deref.
227                let call_def_id = deref.method_call(self.tcx);
228                let overloaded_callee = self
229                    .tcx
230                    .type_of(call_def_id)
231                    .instantiate(self.tcx, self.tcx.mk_args(&[expr.ty.into()]))
232                    .skip_norm_wip();
233
234                expr = Expr {
235                    temp_scope_id,
236                    ty: Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, deref.mutbl),
237                    span,
238                    kind: ExprKind::Borrow {
239                        borrow_kind: deref.mutbl.to_borrow_kind(),
240                        arg: self.thir.exprs.push(expr),
241                    },
242                };
243
244                let expr = Box::new([self.thir.exprs.push(expr)]);
245
246                self.overloaded_place(
247                    hir_expr,
248                    adjustment.target,
249                    Some(overloaded_callee),
250                    expr,
251                    deref.span,
252                )
253            }
254            Adjust::Borrow(AutoBorrow::Ref(m)) => ExprKind::Borrow {
255                borrow_kind: m.to_borrow_kind(),
256                arg: self.thir.exprs.push(expr),
257            },
258            Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
259                ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
260            }
261            Adjust::Borrow(AutoBorrow::Pin(mutbl)) => {
262                // expr = &pin (mut|const|) arget
263                let borrow_kind = match mutbl {
264                    hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
265                    hir::Mutability::Not => BorrowKind::Shared,
266                };
267                let new_pin_target =
268                    Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, mutbl);
269                let arg = self.thir.exprs.push(expr);
270                let expr = self.thir.exprs.push(Expr {
271                    temp_scope_id,
272                    ty: new_pin_target,
273                    span,
274                    kind: ExprKind::Borrow { borrow_kind, arg },
275                });
276
277                // kind = Pin { pointer }
278                let pin_did = self.tcx.require_lang_item(LangItem::Pin, span);
279                let args = self.tcx.mk_args(&[new_pin_target.into()]);
280                let kind = ExprKind::Adt(Box::new(AdtExpr {
281                    adt_def: self.tcx.adt_def(pin_did),
282                    variant_index: FIRST_VARIANT,
283                    args,
284                    fields: Box::new([FieldExpr { name: FieldIdx::ZERO, expr }]),
285                    user_ty: None,
286                    base: AdtExprBase::None,
287                }));
288
289                debug!(?kind);
290                kind
291            }
292            Adjust::GenericReborrow(mutability) => {
293                let expr = self.thir.exprs.push(expr);
294                let kind =
295                    ExprKind::Reborrow { source: expr, mutability, target: adjustment.target };
296
297                kind
298            }
299        };
300
301        Expr { temp_scope_id, ty: adjustment.target, span, kind }
302    }
303
304    /// Lowers a cast expression.
305    ///
306    /// Dealing with user type annotations is left to the caller.
307    fn mirror_expr_cast(
308        &mut self,
309        source: &'tcx hir::Expr<'tcx>,
310        temp_scope_id: hir::ItemLocalId,
311        span: Span,
312    ) -> ExprKind<'tcx> {
313        let tcx = self.tcx;
314
315        // Check to see if this cast is a "coercion cast", where the cast is actually done
316        // using a coercion (or is a no-op).
317        if self.typeck_results.is_coercion_cast(source.hir_id) {
318            // Convert the lexpr to a vexpr.
319            ExprKind::ValueExpr { source: self.mirror_expr(source) }
320        } else if self.typeck_results.expr_ty(source).is_ref() {
321            // Special cased so that we can type check that the element
322            // type of the source matches the pointed to type of the
323            // destination.
324            ExprKind::PointerCoercion {
325                source: self.mirror_expr(source),
326                cast: PointerCoercion::ArrayToPointer,
327                is_from_as_cast: true,
328            }
329        } else if let hir::ExprKind::Path(ref qpath) = source.kind
330            && let res = self.typeck_results.qpath_res(qpath, source.hir_id)
331            && let ty = self.typeck_results.node_type(source.hir_id)
332            && let ty::Adt(adt_def, _) = ty.kind()
333            && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
334        {
335            // Check whether this is casting an enum variant discriminant.
336            // To prevent cycles, we refer to the discriminant initializer,
337            // which is always an integer and thus doesn't need to know the
338            // enum's layout (or its tag type) to compute it during const eval.
339            // Example:
340            // enum Foo {
341            //     A,
342            //     B = A as isize + 4,
343            // }
344            // The correct solution would be to add symbolic computations to miri,
345            // so we wouldn't have to compute and store the actual value
346
347            let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
348            let (discr_did, discr_offset) = adt_def.discriminant_def_for_variant(idx);
349
350            use rustc_middle::ty::util::IntTypeExt;
351            let ty = adt_def.repr().discr_type();
352            let discr_ty = ty.to_ty(tcx);
353
354            let size = tcx
355                .layout_of(self.typing_env.as_query_input(discr_ty))
356                .unwrap_or_else(|e| {
    ::core::panicking::panic_fmt(format_args!("could not compute layout for {0:?}: {1:?}",
            discr_ty, e));
}panic!("could not compute layout for {discr_ty:?}: {e:?}"))
357                .size;
358
359            let (lit, overflowing) = ScalarInt::truncate_from_uint(discr_offset as u128, size);
360            if overflowing {
361                // An erroneous enum with too many variants for its repr will emit E0081 and E0370
362                self.tcx.dcx().span_delayed_bug(
363                    source.span,
364                    "overflowing enum wasn't rejected by hir analysis",
365                );
366            }
367            let kind = ExprKind::NonHirLiteral { lit, user_ty: None };
368            let offset = self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind });
369
370            let source = match discr_did {
371                // in case we are offsetting from a computed discriminant
372                // and not the beginning of discriminants (which is always `0`)
373                Some(did) => {
374                    let args = self.tcx.mk_args(&[]);
375                    self.tcx.debug_assert_args_compatible(did, args);
376                    let kind = ExprKind::NamedConst { def_id: did, args, user_ty: None };
377                    let lhs =
378                        self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind });
379                    let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset };
380                    self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind: bin })
381                }
382                None => offset,
383            };
384
385            ExprKind::Cast { source }
386        } else {
387            // Default to `ExprKind::Cast` for all explicit casts.
388            // MIR building then picks the right MIR casts based on the types.
389            ExprKind::Cast { source: self.mirror_expr(source) }
390        }
391    }
392
393    {}
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("make_mirror_unadjusted",
                                "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                ::tracing_core::__macro_support::Option::Some(393u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("expr")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("expr");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::SPAN)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let mut interest = ::tracing::subscriber::Interest::never();
            if ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        { interest = __CALLSITE.interest(); !interest.is_never() }
                    &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest) {
                let meta = __CALLSITE.metadata();
                ::tracing::Span::new(meta,
                    &{
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr)
                                                        as &dyn ::tracing::field::Value))])
                        })
            } else {
                let span =
                    ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                {};
                span
            }
        };
    __tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return: Expr<'tcx> = loop {};
                        return __tracing_attr_fake_return;
                    }
                    {
                        let tcx = self.tcx;
                        let expr_ty = self.typeck_results.expr_ty(expr);
                        let mk_expr =
                            |kind, ty|
                                Expr {
                                    temp_scope_id: expr.hir_id.local_id,
                                    span: expr.span,
                                    ty,
                                    kind,
                                };
                        let kind =
                            match expr.kind {
                                hir::ExprKind::MethodCall(segment, receiver, args, fn_span)
                                    => {
                                    if self.typeck_results.is_splatted_call(expr) {
                                        self.convert_splatted_callee(expr, fn_span, args,
                                            SplattedFunc::FnDefReceiver(receiver))
                                    } else {
                                        let expr =
                                            self.method_callee(expr, segment.ident.span, None);
                                        {
                                            use ::tracing::__macro_support::Callsite as _;
                                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                                {
                                                    static META: ::tracing::Metadata<'static> =
                                                        {
                                                            ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:415",
                                                                "rustc_mir_build::thir::cx::expr", ::tracing::Level::INFO,
                                                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                                                ::tracing_core::__macro_support::Option::Some(415u32),
                                                                ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                                                ::tracing_core::field::FieldSet::new(&["message"],
                                                                    ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                                ::tracing::metadata::Kind::EVENT)
                                                        };
                                                    ::tracing::callsite::DefaultCallsite::new(&META)
                                                };
                                            let enabled =
                                                ::tracing::Level::INFO <=
                                                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                                        ::tracing::Level::INFO <=
                                                            ::tracing::level_filters::LevelFilter::current() &&
                                                    {
                                                        let interest = __CALLSITE.interest();
                                                        !interest.is_never() &&
                                                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                                interest)
                                                    };
                                            if enabled {
                                                (|value_set: ::tracing::field::ValueSet|
                                                            {
                                                                let meta = __CALLSITE.metadata();
                                                                ::tracing::Event::dispatch(meta, &value_set);
                                                                ;
                                                            })({
                                                        #[allow(unused_imports)]
                                                        use ::tracing::field::{debug, display, Value};
                                                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("Using method span: {0:?}",
                                                                                            expr.span) as &dyn ::tracing::field::Value))])
                                                    });
                                            } else { ; }
                                        };
                                        let args =
                                            std::iter::once(receiver).chain(args.iter()).map(|expr|
                                                        self.mirror_expr(expr)).collect();
                                        ExprKind::Call {
                                            ty: expr.ty,
                                            fun: self.thir.exprs.push(expr),
                                            args,
                                            from_hir_call: true,
                                            fn_span,
                                        }
                                    }
                                }
                                hir::ExprKind::Call(fun, ref args) => {
                                    if self.typeck_results.is_method_call(expr) {
                                        let method = self.method_callee(expr, fun.span, None);
                                        let arg_tys =
                                            args.iter().map(|e|
                                                    self.typeck_results.expr_ty_adjusted(e));
                                        let tupled_args =
                                            Expr {
                                                ty: Ty::new_tup_from_iter(tcx, arg_tys),
                                                temp_scope_id: expr.hir_id.local_id,
                                                span: expr.span,
                                                kind: ExprKind::Tuple { fields: self.mirror_exprs(args) },
                                            };
                                        let tupled_args = self.thir.exprs.push(tupled_args);
                                        ExprKind::Call {
                                            ty: method.ty,
                                            fun: self.thir.exprs.push(method),
                                            args: Box::new([self.mirror_expr(fun), tupled_args]),
                                            from_hir_call: true,
                                            fn_span: expr.span,
                                        }
                                    } else if self.typeck_results.is_splatted_call(expr) {
                                        self.convert_splatted_callee(expr, fun.span, args,
                                            SplattedFunc::FnExpression(fun))
                                    } else {
                                        let adt_data =
                                            if let hir::ExprKind::Path(ref qpath) = fun.kind &&
                                                    let Some(adt_def) = expr_ty.ty_adt_def() {
                                                match qpath {
                                                    hir::QPath::Resolved(_, path) =>
                                                        match path.res {
                                                            Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
                                                                Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
                                                            }
                                                            Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
                                                            _ => None,
                                                        },
                                                    hir::QPath::TypeRelative(_ty, _) => {
                                                        if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
                                                                self.typeck_results.type_dependent_def(fun.hir_id) {
                                                            Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
                                                        } else { None }
                                                    }
                                                }
                                            } else { None };
                                        if let Some((adt_def, index)) = adt_data {
                                            let node_args = self.typeck_results.node_args(fun.hir_id);
                                            let user_provided_types =
                                                self.typeck_results.user_provided_types();
                                            let user_ty =
                                                user_provided_types.get(fun.hir_id).copied().map(|mut u_ty|
                                                        {
                                                            if let ty::UserTypeKind::TypeOf(did, _) =
                                                                    &mut u_ty.value.kind {
                                                                *did = adt_def.did();
                                                            }
                                                            Box::new(u_ty)
                                                        });
                                            {
                                                use ::tracing::__macro_support::Callsite as _;
                                                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                                    {
                                                        static META: ::tracing::Metadata<'static> =
                                                            {
                                                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:503",
                                                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                                                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                                                    ::tracing_core::__macro_support::Option::Some(503u32),
                                                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                                                    ::tracing_core::field::FieldSet::new(&["message"],
                                                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                                    ::tracing::metadata::Kind::EVENT)
                                                            };
                                                        ::tracing::callsite::DefaultCallsite::new(&META)
                                                    };
                                                let enabled =
                                                    ::tracing::Level::DEBUG <=
                                                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                                            ::tracing::Level::DEBUG <=
                                                                ::tracing::level_filters::LevelFilter::current() &&
                                                        {
                                                            let interest = __CALLSITE.interest();
                                                            !interest.is_never() &&
                                                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                                    interest)
                                                        };
                                                if enabled {
                                                    (|value_set: ::tracing::field::ValueSet|
                                                                {
                                                                    let meta = __CALLSITE.metadata();
                                                                    ::tracing::Event::dispatch(meta, &value_set);
                                                                    ;
                                                                })({
                                                            #[allow(unused_imports)]
                                                            use ::tracing::field::{debug, display, Value};
                                                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_mirror_unadjusted: (call) user_ty={0:?}",
                                                                                                user_ty) as &dyn ::tracing::field::Value))])
                                                        });
                                                } else { ; }
                                            };
                                            let field_refs =
                                                args.iter().enumerate().map(|(idx, e)|
                                                            FieldExpr {
                                                                name: FieldIdx::new(idx),
                                                                expr: self.mirror_expr(e),
                                                            }).collect();
                                            ExprKind::Adt(Box::new(AdtExpr {
                                                        adt_def,
                                                        args: node_args,
                                                        variant_index: index,
                                                        fields: field_refs,
                                                        user_ty,
                                                        base: AdtExprBase::None,
                                                    }))
                                        } else {
                                            ExprKind::Call {
                                                ty: self.typeck_results.node_type(fun.hir_id),
                                                fun: self.mirror_expr(fun),
                                                args: self.mirror_exprs(args),
                                                from_hir_call: true,
                                                fn_span: expr.span,
                                            }
                                        }
                                    }
                                }
                                hir::ExprKind::Use(expr, span) => {
                                    ExprKind::ByUse { expr: self.mirror_expr(expr), span }
                                }
                                hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, arg) => {
                                    ExprKind::Borrow {
                                        borrow_kind: mutbl.to_borrow_kind(),
                                        arg: self.mirror_expr(arg),
                                    }
                                }
                                hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutability, arg)
                                    => {
                                    ExprKind::RawBorrow {
                                        mutability,
                                        arg: self.mirror_expr(arg),
                                    }
                                }
                                hir::ExprKind::AddrOf(hir::BorrowKind::Pin, mutbl, arg_expr)
                                    =>
                                    match expr_ty.kind() {
                                        &ty::Adt(adt_def, args) if
                                            tcx.is_lang_item(adt_def.did(), LangItem::Pin) => {
                                            let ty = args.type_at(0);
                                            let arg_ty = self.typeck_results.expr_ty(arg_expr);
                                            let mut arg = self.mirror_expr(arg_expr);
                                            if mutbl.is_mut() &&
                                                    !arg_ty.is_unpin(self.tcx, self.typing_env) {
                                                let block =
                                                    self.thir.blocks.push(Block {
                                                            targeted_by_break: false,
                                                            region_scope: region::Scope {
                                                                local_id: arg_expr.hir_id.local_id,
                                                                data: region::ScopeData::Node,
                                                            },
                                                            span: arg_expr.span,
                                                            stmts: Box::new([]),
                                                            expr: Some(arg),
                                                            safety_mode: BlockSafety::Safe,
                                                        });
                                                arg =
                                                    self.thir.exprs.push(Expr {
                                                            temp_scope_id: arg_expr.hir_id.local_id,
                                                            ty: arg_ty,
                                                            span: arg_expr.span,
                                                            kind: ExprKind::Block { block },
                                                        });
                                            }
                                            let expr =
                                                self.thir.exprs.push(Expr {
                                                        temp_scope_id: expr.hir_id.local_id,
                                                        ty,
                                                        span: expr.span,
                                                        kind: ExprKind::Borrow {
                                                            borrow_kind: mutbl.to_borrow_kind(),
                                                            arg,
                                                        },
                                                    });
                                            ExprKind::Adt(Box::new(AdtExpr {
                                                        adt_def,
                                                        variant_index: FIRST_VARIANT,
                                                        args,
                                                        fields: Box::new([FieldExpr {
                                                                        name: FieldIdx::from(0u32),
                                                                        expr,
                                                                    }]),
                                                        user_ty: None,
                                                        base: AdtExprBase::None,
                                                    }))
                                        }
                                        _ =>
                                            ::rustc_span::macros::bug_impl(Some(expr.span),
                                                format_args!("unexpected type for pinned borrow: {0:?}",
                                                    expr_ty), Location::caller()),
                                    },
                                hir::ExprKind::Block(blk, _) =>
                                    ExprKind::Block { block: self.mirror_block(blk) },
                                hir::ExprKind::Assign(lhs, rhs, _) => {
                                    ExprKind::Assign {
                                        lhs: self.mirror_expr(lhs),
                                        rhs: self.mirror_expr(rhs),
                                    }
                                }
                                hir::ExprKind::AssignOp(op, lhs, rhs) => {
                                    if self.typeck_results.is_method_call(expr) {
                                        let lhs = self.mirror_expr(lhs);
                                        let rhs = self.mirror_expr(rhs);
                                        self.overloaded_operator(expr, Box::new([lhs, rhs]))
                                    } else {
                                        ExprKind::AssignOp {
                                            op: assign_op(op.node),
                                            lhs: self.mirror_expr(lhs),
                                            rhs: self.mirror_expr(rhs),
                                        }
                                    }
                                }
                                hir::ExprKind::Lit(lit) =>
                                    ExprKind::Literal { lit, neg: false },
                                hir::ExprKind::Binary(op, lhs, rhs) => {
                                    if self.typeck_results.is_method_call(expr) {
                                        let lhs = self.mirror_expr(lhs);
                                        let rhs = self.mirror_expr(rhs);
                                        self.overloaded_operator(expr, Box::new([lhs, rhs]))
                                    } else {
                                        match op.node {
                                            hir::BinOpKind::And =>
                                                ExprKind::LogicalOp {
                                                    op: LogicalOp::And,
                                                    lhs: self.mirror_expr(lhs),
                                                    rhs: self.mirror_expr(rhs),
                                                },
                                            hir::BinOpKind::Or =>
                                                ExprKind::LogicalOp {
                                                    op: LogicalOp::Or,
                                                    lhs: self.mirror_expr(lhs),
                                                    rhs: self.mirror_expr(rhs),
                                                },
                                            _ => {
                                                let op = bin_op(op.node);
                                                ExprKind::Binary {
                                                    op,
                                                    lhs: self.mirror_expr(lhs),
                                                    rhs: self.mirror_expr(rhs),
                                                }
                                            }
                                        }
                                    }
                                }
                                hir::ExprKind::Index(lhs, index, brackets_span) => {
                                    if self.typeck_results.is_method_call(expr) {
                                        let lhs = self.mirror_expr(lhs);
                                        let index = self.mirror_expr(index);
                                        self.overloaded_place(expr, expr_ty, None,
                                            Box::new([lhs, index]), brackets_span)
                                    } else {
                                        ExprKind::Index {
                                            lhs: self.mirror_expr(lhs),
                                            index: self.mirror_expr(index),
                                        }
                                    }
                                }
                                hir::ExprKind::Unary(hir::UnOp::Deref, arg) => {
                                    if self.typeck_results.is_method_call(expr) {
                                        let arg = self.mirror_expr(arg);
                                        self.overloaded_place(expr, expr_ty, None, Box::new([arg]),
                                            expr.span)
                                    } else { ExprKind::Deref { arg: self.mirror_expr(arg) } }
                                }
                                hir::ExprKind::Unary(hir::UnOp::Not, arg) => {
                                    if self.typeck_results.is_method_call(expr) {
                                        let arg = self.mirror_expr(arg);
                                        self.overloaded_operator(expr, Box::new([arg]))
                                    } else {
                                        ExprKind::Unary {
                                            op: UnOp::Not,
                                            arg: self.mirror_expr(arg),
                                        }
                                    }
                                }
                                hir::ExprKind::Unary(hir::UnOp::Neg, arg) => {
                                    if self.typeck_results.is_method_call(expr) {
                                        let arg = self.mirror_expr(arg);
                                        self.overloaded_operator(expr, Box::new([arg]))
                                    } else if let hir::ExprKind::Lit(lit) = arg.kind {
                                        ExprKind::Literal { lit, neg: true }
                                    } else {
                                        ExprKind::Unary {
                                            op: UnOp::Neg,
                                            arg: self.mirror_expr(arg),
                                        }
                                    }
                                }
                                hir::ExprKind::Struct(qpath, fields, ref base) =>
                                    match expr_ty.kind() {
                                        ty::Adt(adt, args) =>
                                            match adt.adt_kind() {
                                                AdtKind::Struct | AdtKind::Union => {
                                                    let user_provided_types =
                                                        self.typeck_results.user_provided_types();
                                                    let user_ty =
                                                        user_provided_types.get(expr.hir_id).copied().map(Box::new);
                                                    {
                                                        use ::tracing::__macro_support::Callsite as _;
                                                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                                            {
                                                                static META: ::tracing::Metadata<'static> =
                                                                    {
                                                                        ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:692",
                                                                            "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                                                                            ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                                                            ::tracing_core::__macro_support::Option::Some(692u32),
                                                                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                                                            ::tracing_core::field::FieldSet::new(&["message"],
                                                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                                            ::tracing::metadata::Kind::EVENT)
                                                                    };
                                                                ::tracing::callsite::DefaultCallsite::new(&META)
                                                            };
                                                        let enabled =
                                                            ::tracing::Level::DEBUG <=
                                                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                                                    ::tracing::Level::DEBUG <=
                                                                        ::tracing::level_filters::LevelFilter::current() &&
                                                                {
                                                                    let interest = __CALLSITE.interest();
                                                                    !interest.is_never() &&
                                                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                                            interest)
                                                                };
                                                        if enabled {
                                                            (|value_set: ::tracing::field::ValueSet|
                                                                        {
                                                                            let meta = __CALLSITE.metadata();
                                                                            ::tracing::Event::dispatch(meta, &value_set);
                                                                            ;
                                                                        })({
                                                                    #[allow(unused_imports)]
                                                                    use ::tracing::field::{debug, display, Value};
                                                                    __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_mirror_unadjusted: (struct/union) user_ty={0:?}",
                                                                                                        user_ty) as &dyn ::tracing::field::Value))])
                                                                });
                                                        } else { ; }
                                                    };
                                                    ExprKind::Adt(Box::new(AdtExpr {
                                                                adt_def: *adt,
                                                                variant_index: FIRST_VARIANT,
                                                                args,
                                                                user_ty,
                                                                fields: self.field_refs(fields),
                                                                base: match base {
                                                                    hir::StructTailExpr::Base(base) =>
                                                                        AdtExprBase::Base(FruInfo {
                                                                                base: self.mirror_expr(base),
                                                                                field_types: self.typeck_results.fru_field_types()[expr.hir_id].iter().copied().collect(),
                                                                            }),
                                                                    hir::StructTailExpr::DefaultFields(_) => {
                                                                        AdtExprBase::DefaultFields(self.typeck_results.fru_field_types()[expr.hir_id].iter().copied().collect())
                                                                    }
                                                                    hir::StructTailExpr::None |
                                                                        hir::StructTailExpr::NoneWithError(_) => AdtExprBase::None,
                                                                },
                                                            }))
                                                }
                                                AdtKind::Enum => {
                                                    let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
                                                    match res {
                                                        Res::Def(DefKind::Variant, variant_id) => {
                                                            if !#[allow(non_exhaustive_omitted_patterns)] match base {
                                                                        hir::StructTailExpr::None |
                                                                            hir::StructTailExpr::DefaultFields(_) |
                                                                            hir::StructTailExpr::NoneWithError(_) => true,
                                                                        _ => false,
                                                                    } {
                                                                ::core::panicking::panic("assertion failed: matches!(base, hir::StructTailExpr::None |\n    hir::StructTailExpr::DefaultFields(_) |\n    hir::StructTailExpr::NoneWithError(_))")
                                                            };
                                                            let index = adt.variant_index_with_id(variant_id);
                                                            let user_provided_types =
                                                                self.typeck_results.user_provided_types();
                                                            let user_ty =
                                                                user_provided_types.get(expr.hir_id).copied().map(Box::new);
                                                            {
                                                                use ::tracing::__macro_support::Callsite as _;
                                                                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                                                    {
                                                                        static META: ::tracing::Metadata<'static> =
                                                                            {
                                                                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:735",
                                                                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                                                                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                                                                    ::tracing_core::__macro_support::Option::Some(735u32),
                                                                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                                                                    ::tracing_core::field::FieldSet::new(&["message"],
                                                                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                                                    ::tracing::metadata::Kind::EVENT)
                                                                            };
                                                                        ::tracing::callsite::DefaultCallsite::new(&META)
                                                                    };
                                                                let enabled =
                                                                    ::tracing::Level::DEBUG <=
                                                                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                                                            ::tracing::Level::DEBUG <=
                                                                                ::tracing::level_filters::LevelFilter::current() &&
                                                                        {
                                                                            let interest = __CALLSITE.interest();
                                                                            !interest.is_never() &&
                                                                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                                                    interest)
                                                                        };
                                                                if enabled {
                                                                    (|value_set: ::tracing::field::ValueSet|
                                                                                {
                                                                                    let meta = __CALLSITE.metadata();
                                                                                    ::tracing::Event::dispatch(meta, &value_set);
                                                                                    ;
                                                                                })({
                                                                            #[allow(unused_imports)]
                                                                            use ::tracing::field::{debug, display, Value};
                                                                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_mirror_unadjusted: (variant) user_ty={0:?}",
                                                                                                                user_ty) as &dyn ::tracing::field::Value))])
                                                                        });
                                                                } else { ; }
                                                            };
                                                            ExprKind::Adt(Box::new(AdtExpr {
                                                                        adt_def: *adt,
                                                                        variant_index: index,
                                                                        args,
                                                                        user_ty,
                                                                        fields: self.field_refs(fields),
                                                                        base: match base {
                                                                            hir::StructTailExpr::DefaultFields(_) => {
                                                                                AdtExprBase::DefaultFields(self.typeck_results.fru_field_types()[expr.hir_id].iter().copied().collect())
                                                                            }
                                                                            hir::StructTailExpr::Base(base) => {
                                                                                ::rustc_span::macros::bug_impl(Some(base.span),
                                                                                    format_args!("unexpected res: {0:?}", res),
                                                                                    Location::caller());
                                                                            }
                                                                            hir::StructTailExpr::None |
                                                                                hir::StructTailExpr::NoneWithError(_) => {
                                                                                AdtExprBase::None
                                                                            }
                                                                        },
                                                                    }))
                                                        }
                                                        _ => {
                                                            ::rustc_span::macros::bug_impl(Some(expr.span),
                                                                format_args!("unexpected res: {0:?}", res),
                                                                Location::caller());
                                                        }
                                                    }
                                                }
                                            },
                                        _ => {
                                            ::rustc_span::macros::bug_impl(Some(expr.span),
                                                format_args!("unexpected type for struct literal: {0:?}",
                                                    expr_ty), Location::caller());
                                        }
                                    },
                                hir::ExprKind::Closure(hir::Closure { .. }) => {
                                    let closure_ty = self.typeck_results.expr_ty(expr);
                                    let (def_id, args, movability) =
                                        match *closure_ty.kind() {
                                            ty::Closure(def_id, args) =>
                                                (def_id, UpvarArgs::Closure(args), None),
                                            ty::Coroutine(def_id, args) => {
                                                (def_id, UpvarArgs::Coroutine(args),
                                                    Some(tcx.coroutine_movability(def_id)))
                                            }
                                            ty::CoroutineClosure(def_id, args) => {
                                                (def_id, UpvarArgs::CoroutineClosure(args), None)
                                            }
                                            _ => {
                                                ::rustc_span::macros::bug_impl(Some(expr.span),
                                                    format_args!("closure expr w/o closure type: {0:?}",
                                                        closure_ty), Location::caller());
                                            }
                                        };
                                    let def_id = def_id.expect_local();
                                    let upvars =
                                        self.tcx.closure_captures(def_id).iter().zip_eq(args.upvar_tys()).map(|(captured_place,
                                                        ty)|
                                                    {
                                                        let upvars = self.capture_upvar(expr, captured_place, ty);
                                                        self.thir.exprs.push(upvars)
                                                    }).collect();
                                    let fake_reads =
                                        match self.typeck_results.closure_fake_reads.get(&def_id) {
                                            Some(fake_reads) =>
                                                fake_reads.iter().map(|(place, cause, hir_id)|
                                                            {
                                                                let expr =
                                                                    self.convert_captured_hir_place(expr, place.clone());
                                                                (self.thir.exprs.push(expr), *cause, *hir_id)
                                                            }).collect(),
                                            None => Vec::new(),
                                        };
                                    ExprKind::Closure(Box::new(ClosureExpr {
                                                closure_id: def_id,
                                                args,
                                                upvars,
                                                movability,
                                                fake_reads,
                                            }))
                                }
                                hir::ExprKind::Path(ref qpath) => {
                                    let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
                                    self.convert_path_expr(expr, res)
                                }
                                hir::ExprKind::InlineAsm(asm) =>
                                    ExprKind::InlineAsm(Box::new(InlineAsmExpr {
                                                asm_macro: asm.asm_macro,
                                                template: asm.template,
                                                operands: asm.operands.iter().map(|(op, _op_sp)|
                                                            match *op {
                                                                hir::InlineAsmOperand::In { reg, expr } =>
                                                                    InlineAsmOperand::In {
                                                                        reg: reg.as_target(),
                                                                        expr: self.mirror_expr(expr),
                                                                    },
                                                                hir::InlineAsmOperand::Out { reg, late, ref expr } => {
                                                                    InlineAsmOperand::Out {
                                                                        reg: reg.as_target(),
                                                                        late,
                                                                        expr: expr.map(|expr| self.mirror_expr(expr)),
                                                                    }
                                                                }
                                                                hir::InlineAsmOperand::InOut { reg, late, expr } => {
                                                                    InlineAsmOperand::InOut {
                                                                        reg: reg.as_target(),
                                                                        late,
                                                                        expr: self.mirror_expr(expr),
                                                                    }
                                                                }
                                                                hir::InlineAsmOperand::SplitInOut {
                                                                    reg, late, in_expr, ref out_expr } => {
                                                                    InlineAsmOperand::SplitInOut {
                                                                        reg: reg.as_target(),
                                                                        late,
                                                                        in_expr: self.mirror_expr(in_expr),
                                                                        out_expr: out_expr.map(|expr| self.mirror_expr(expr)),
                                                                    }
                                                                }
                                                                hir::InlineAsmOperand::Const { ref anon_const } => {
                                                                    let ty = self.typeck_results.node_type(anon_const.hir_id);
                                                                    let did = anon_const.def_id;
                                                                    let typeck_root_def_id = tcx.typeck_root_def_id_local(did);
                                                                    let parent_args =
                                                                        tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(tcx,
                                                                                typeck_root_def_id));
                                                                    let args =
                                                                        InlineConstArgs::new(tcx,
                                                                                InlineConstArgsParts { parent_args, ty }).args;
                                                                    let uneval =
                                                                        mir::UnevaluatedConst::new(did.to_def_id(), args);
                                                                    let value = mir::Const::Unevaluated(uneval, ty);
                                                                    InlineAsmOperand::Const { value, span: tcx.def_span(did) }
                                                                }
                                                                hir::InlineAsmOperand::SymFn { expr } => {
                                                                    InlineAsmOperand::SymFn { value: self.mirror_expr(expr) }
                                                                }
                                                                hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
                                                                    InlineAsmOperand::SymStatic { def_id }
                                                                }
                                                                hir::InlineAsmOperand::Label { block } => {
                                                                    InlineAsmOperand::Label { block: self.mirror_block(block) }
                                                                }
                                                            }).collect(),
                                                options: asm.options,
                                                line_spans: asm.line_spans,
                                            })),
                                hir::ExprKind::OffsetOf(_, _) => {
                                    let offset_of_intrinsic =
                                        tcx.require_lang_item(LangItem::OffsetOf, expr.span);
                                    let mk_u32_kind =
                                        |val: u32|
                                            ExprKind::NonHirLiteral {
                                                lit: ScalarInt::try_from_uint(val,
                                                        Size::from_bits(32)).unwrap(),
                                                user_ty: None,
                                            };
                                    let mk_usize_kind =
                                        |val: u64|
                                            ExprKind::NonHirLiteral {
                                                lit: ScalarInt::try_from_target_usize(val, tcx).unwrap(),
                                                user_ty: None,
                                            };
                                    let mk_call =
                                        |thir: &mut Thir<'tcx>, ty: Ty<'tcx>, variant: VariantIdx,
                                            field: FieldIdx|
                                            {
                                                let fun_ty =
                                                    tcx.type_of(offset_of_intrinsic).instantiate(tcx,
                                                            &[ty.into()]).skip_norm_wip();
                                                let fun =
                                                    thir.exprs.push(mk_expr(ExprKind::ZstLiteral {
                                                                user_ty: None,
                                                            }, fun_ty));
                                                let variant =
                                                    thir.exprs.push(mk_expr(mk_u32_kind(variant.as_u32()),
                                                            tcx.types.u32));
                                                let field =
                                                    thir.exprs.push(mk_expr(mk_u32_kind(field.as_u32()),
                                                            tcx.types.u32));
                                                let args = Box::new([variant, field]);
                                                ExprKind::Call {
                                                    ty: fun_ty,
                                                    fun,
                                                    args,
                                                    from_hir_call: false,
                                                    fn_span: expr.span,
                                                }
                                            };
                                    let indices =
                                        self.typeck_results.offset_of_data().get(expr.hir_id).unwrap();
                                    let mut expr = None::<ExprKind<'_>>;
                                    for &(container, variant, field) in indices.iter() {
                                        let next =
                                            mk_call(&mut self.thir, container, variant, field);
                                        expr =
                                            Some(match expr.take() {
                                                    None => next,
                                                    Some(last) => {
                                                        let last =
                                                            self.thir.exprs.push(mk_expr(last, tcx.types.usize));
                                                        let next =
                                                            self.thir.exprs.push(mk_expr(next, tcx.types.usize));
                                                        ExprKind::Binary { op: BinOp::Add, lhs: last, rhs: next }
                                                    }
                                                });
                                    }
                                    expr.unwrap_or_else(|| mk_usize_kind(0))
                                }
                                hir::ExprKind::ConstBlock(ref anon_const) => {
                                    let ty = self.typeck_results.node_type(anon_const.hir_id);
                                    let did = anon_const.def_id;
                                    let typeck_root_def_id = tcx.typeck_root_def_id_local(did);
                                    let parent_args =
                                        tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(tcx,
                                                typeck_root_def_id));
                                    let args =
                                        InlineConstArgs::new(tcx,
                                                InlineConstArgsParts { parent_args, ty }).args;
                                    ExprKind::ConstBlock { did: did.to_def_id(), args }
                                }
                                hir::ExprKind::Repeat(v, _) => {
                                    let ty = self.typeck_results.expr_ty(expr);
                                    let ty::Array(_, count) =
                                        ty.kind() else {
                                            ::rustc_span::macros::bug_impl(Some(expr.span),
                                                format_args!("unexpected repeat expr ty: {0:?}", ty),
                                                Location::caller());
                                        };
                                    ExprKind::Repeat {
                                        value: self.mirror_expr(v),
                                        count: *count,
                                    }
                                }
                                hir::ExprKind::Ret(v) =>
                                    ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
                                hir::ExprKind::Become(call) =>
                                    ExprKind::Become { value: self.mirror_expr(call) },
                                hir::ExprKind::Break(dest, ref value) => {
                                    if {
                                                {
                                                    'done:
                                                        {
                                                        for i in
                                                            ::rustc_attr_ir::HasAttrs::get_attrs(expr.hir_id, &self.tcx)
                                                            {
                                                            #[allow(unused_imports)]
                                                            use ::rustc_attr_ir::AttributeKind::*;
                                                            let i: &::rustc_attr_ir::Attribute = i;
                                                            match i {
                                                                ::rustc_attr_ir::Attribute::Parsed(ConstContinue(_)) => {
                                                                    break 'done Some(());
                                                                }
                                                                ::rustc_attr_ir::Attribute::Unparsed(..) =>
                                                                    {}
                                                                    #[deny(unreachable_patterns)]
                                                                    _ => {}
                                                            }
                                                        }
                                                        None
                                                    }
                                                }
                                            }.is_some() {
                                        match dest.target_id {
                                            Ok(target_id) => {
                                                let (Some(value), Some(_)) =
                                                    (value,
                                                        dest.label) else {
                                                        let span = expr.span;
                                                        self.tcx.dcx().emit_fatal(ConstContinueMissingLabelOrValue {
                                                                span,
                                                            })
                                                    };
                                                ExprKind::ConstContinue {
                                                    label: region::Scope {
                                                        local_id: target_id.local_id,
                                                        data: region::ScopeData::Node,
                                                    },
                                                    value: self.mirror_expr(value),
                                                }
                                            }
                                            Err(err) =>
                                                ::rustc_span::macros::bug_impl(None,
                                                    format_args!("invalid loop id for break: {0}", err),
                                                    Location::caller()),
                                        }
                                    } else {
                                        match dest.target_id {
                                            Ok(target_id) =>
                                                ExprKind::Break {
                                                    label: region::Scope {
                                                        local_id: target_id.local_id,
                                                        data: region::ScopeData::Node,
                                                    },
                                                    value: value.map(|value| self.mirror_expr(value)),
                                                },
                                            Err(err) =>
                                                ::rustc_span::macros::bug_impl(None,
                                                    format_args!("invalid loop id for break: {0}", err),
                                                    Location::caller()),
                                        }
                                    }
                                }
                                hir::ExprKind::Continue(dest) =>
                                    match dest.target_id {
                                        Ok(loop_id) =>
                                            ExprKind::Continue {
                                                label: region::Scope {
                                                    local_id: loop_id.local_id,
                                                    data: region::ScopeData::Node,
                                                },
                                            },
                                        Err(err) =>
                                            ::rustc_span::macros::bug_impl(None,
                                                format_args!("invalid loop id for continue: {0}", err),
                                                Location::caller()),
                                    },
                                hir::ExprKind::Let(let_expr) =>
                                    ExprKind::Let {
                                        expr: self.mirror_expr(let_expr.init),
                                        pat: self.pattern_from_hir(let_expr.pat),
                                    },
                                hir::ExprKind::If(cond, then, else_opt) =>
                                    ExprKind::If {
                                        if_then_scope: region::Scope {
                                            local_id: then.hir_id.local_id,
                                            data: {
                                                if expr.span.at_least_rust_2024() {
                                                    region::ScopeData::IfThenRescope
                                                } else { region::ScopeData::IfThen }
                                            },
                                        },
                                        cond: self.mirror_expr(cond),
                                        then: self.mirror_expr(then),
                                        else_opt: else_opt.map(|el| self.mirror_expr(el)),
                                    },
                                hir::ExprKind::Match(discr, arms, match_source) =>
                                    ExprKind::Match {
                                        scrutinee: self.mirror_expr(discr),
                                        arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
                                        match_source,
                                    },
                                hir::ExprKind::Loop(body, ..) => {
                                    if {
                                                {
                                                    'done:
                                                        {
                                                        for i in
                                                            ::rustc_attr_ir::HasAttrs::get_attrs(expr.hir_id, &self.tcx)
                                                            {
                                                            #[allow(unused_imports)]
                                                            use ::rustc_attr_ir::AttributeKind::*;
                                                            let i: &::rustc_attr_ir::Attribute = i;
                                                            match i {
                                                                ::rustc_attr_ir::Attribute::Parsed(LoopMatch(_)) => {
                                                                    break 'done Some(());
                                                                }
                                                                ::rustc_attr_ir::Attribute::Unparsed(..) =>
                                                                    {}
                                                                    #[deny(unreachable_patterns)]
                                                                    _ => {}
                                                            }
                                                        }
                                                        None
                                                    }
                                                }
                                            }.is_some() {
                                        let dcx = self.tcx.dcx();
                                        let loop_body_expr =
                                            match body.stmts {
                                                [] =>
                                                    match body.expr {
                                                        Some(expr) => expr,
                                                        None =>
                                                            dcx.emit_fatal(LoopMatchMissingAssignment {
                                                                    span: body.span,
                                                                }),
                                                    },
                                                [single] if body.expr.is_none() =>
                                                    match single.kind {
                                                        hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) =>
                                                            expr,
                                                        _ =>
                                                            dcx.emit_fatal(LoopMatchMissingAssignment {
                                                                    span: body.span,
                                                                }),
                                                    },
                                                [first @ last] | [first, .., last] =>
                                                    dcx.emit_fatal(LoopMatchBadStatements {
                                                            span: first.span.to(last.span),
                                                        }),
                                            };
                                        let hir::ExprKind::Assign(state, rhs_expr, _) =
                                            loop_body_expr.kind else {
                                                dcx.emit_fatal(LoopMatchMissingAssignment {
                                                        span: loop_body_expr.span,
                                                    })
                                            };
                                        let hir::ExprKind::Block(block_body, _) =
                                            rhs_expr.kind else {
                                                dcx.emit_fatal(LoopMatchBadRhs { span: rhs_expr.span })
                                            };
                                        for stmt in block_body.stmts {
                                            if !#[allow(non_exhaustive_omitted_patterns)] match stmt.kind
                                                        {
                                                        rustc_hir::StmtKind::Item(_) => true,
                                                        _ => false,
                                                    } {
                                                dcx.emit_fatal(LoopMatchBadStatements { span: stmt.span })
                                            }
                                        }
                                        let Some(block_body_expr) =
                                            block_body.expr else {
                                                dcx.emit_fatal(LoopMatchBadRhs { span: block_body.span })
                                            };
                                        let hir::ExprKind::Match(scrutinee, arms, _match_source) =
                                            block_body_expr.kind else {
                                                dcx.emit_fatal(LoopMatchBadRhs {
                                                        span: block_body_expr.span,
                                                    })
                                            };
                                        fn local(cx: &mut ThirBuildCx<'_>,
                                            expr: &rustc_hir::Expr<'_>) -> Option<hir::HirId> {
                                            if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) =
                                                            expr.kind && let Res::Local(hir_id) = path.res &&
                                                    !cx.is_upvar(hir_id) {
                                                return Some(hir_id);
                                            }
                                            None
                                        }
                                        let Some(scrutinee_hir_id) =
                                            local(self,
                                                scrutinee) else {
                                                dcx.emit_fatal(LoopMatchInvalidMatch {
                                                        span: scrutinee.span,
                                                    })
                                            };
                                        if local(self, state) != Some(scrutinee_hir_id) {
                                            dcx.emit_fatal(LoopMatchInvalidUpdate {
                                                    scrutinee: scrutinee.span,
                                                    lhs: state.span,
                                                })
                                        }
                                        ExprKind::LoopMatch {
                                            state: self.mirror_expr(state),
                                            region_scope: region::Scope {
                                                local_id: block_body.hir_id.local_id,
                                                data: region::ScopeData::Node,
                                            },
                                            match_data: Box::new(LoopMatchMatchData {
                                                    scrutinee: self.mirror_expr(scrutinee),
                                                    arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
                                                    span: block_body_expr.span,
                                                }),
                                        }
                                    } else {
                                        let block_ty = self.typeck_results.node_type(body.hir_id);
                                        let block = self.mirror_block(body);
                                        let body =
                                            self.thir.exprs.push(Expr {
                                                    ty: block_ty,
                                                    temp_scope_id: body.hir_id.local_id,
                                                    span: self.thir[block].span,
                                                    kind: ExprKind::Block { block },
                                                });
                                        ExprKind::Loop { body }
                                    }
                                }
                                hir::ExprKind::Field(source, ..) =>
                                    ExprKind::Field {
                                        lhs: self.mirror_expr(source),
                                        variant_index: FIRST_VARIANT,
                                        name: self.typeck_results.field_index(expr.hir_id),
                                    },
                                hir::ExprKind::Cast(source, cast_ty) => {
                                    let user_provided_types =
                                        self.typeck_results.user_provided_types();
                                    let user_ty = user_provided_types.get(cast_ty.hir_id);
                                    {
                                        use ::tracing::__macro_support::Callsite as _;
                                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                            {
                                                static META: ::tracing::Metadata<'static> =
                                                    {
                                                        ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1130",
                                                            "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                                                            ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                                            ::tracing_core::__macro_support::Option::Some(1130u32),
                                                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                                            ::tracing_core::field::FieldSet::new(&["message"],
                                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                            ::tracing::metadata::Kind::EVENT)
                                                    };
                                                ::tracing::callsite::DefaultCallsite::new(&META)
                                            };
                                        let enabled =
                                            ::tracing::Level::DEBUG <=
                                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                                    ::tracing::Level::DEBUG <=
                                                        ::tracing::level_filters::LevelFilter::current() &&
                                                {
                                                    let interest = __CALLSITE.interest();
                                                    !interest.is_never() &&
                                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                            interest)
                                                };
                                        if enabled {
                                            (|value_set: ::tracing::field::ValueSet|
                                                        {
                                                            let meta = __CALLSITE.metadata();
                                                            ::tracing::Event::dispatch(meta, &value_set);
                                                            ;
                                                        })({
                                                    #[allow(unused_imports)]
                                                    use ::tracing::field::{debug, display, Value};
                                                    __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("cast({0:?}) has ty w/ hir_id {1:?} and user provided ty {2:?}",
                                                                                        expr, cast_ty.hir_id, user_ty) as
                                                                                &dyn ::tracing::field::Value))])
                                                });
                                        } else { ; }
                                    };
                                    let cast =
                                        self.mirror_expr_cast(source, expr.hir_id.local_id,
                                            expr.span);
                                    if let Some(user_ty) = user_ty {
                                        let cast_expr =
                                            self.thir.exprs.push(Expr {
                                                    temp_scope_id: expr.hir_id.local_id,
                                                    ty: expr_ty,
                                                    span: expr.span,
                                                    kind: cast,
                                                });
                                        {
                                            use ::tracing::__macro_support::Callsite as _;
                                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                                {
                                                    static META: ::tracing::Metadata<'static> =
                                                        {
                                                            ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1146",
                                                                "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                                                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                                                ::tracing_core::__macro_support::Option::Some(1146u32),
                                                                ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                                                ::tracing_core::field::FieldSet::new(&["message"],
                                                                    ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                                ::tracing::metadata::Kind::EVENT)
                                                        };
                                                    ::tracing::callsite::DefaultCallsite::new(&META)
                                                };
                                            let enabled =
                                                ::tracing::Level::DEBUG <=
                                                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                                        ::tracing::Level::DEBUG <=
                                                            ::tracing::level_filters::LevelFilter::current() &&
                                                    {
                                                        let interest = __CALLSITE.interest();
                                                        !interest.is_never() &&
                                                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                                interest)
                                                    };
                                            if enabled {
                                                (|value_set: ::tracing::field::ValueSet|
                                                            {
                                                                let meta = __CALLSITE.metadata();
                                                                ::tracing::Event::dispatch(meta, &value_set);
                                                                ;
                                                            })({
                                                        #[allow(unused_imports)]
                                                        use ::tracing::field::{debug, display, Value};
                                                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_mirror_unadjusted: (cast) user_ty={0:?}",
                                                                                            user_ty) as &dyn ::tracing::field::Value))])
                                                    });
                                            } else { ; }
                                        };
                                        ExprKind::ValueTypeAscription {
                                            source: cast_expr,
                                            user_ty: Some(Box::new(*user_ty)),
                                            user_ty_span: cast_ty.span,
                                        }
                                    } else { cast }
                                }
                                hir::ExprKind::Type(source, ty) => {
                                    let user_provided_types =
                                        self.typeck_results.user_provided_types();
                                    let user_ty =
                                        user_provided_types.get(ty.hir_id).copied().map(Box::new);
                                    {
                                        use ::tracing::__macro_support::Callsite as _;
                                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                            {
                                                static META: ::tracing::Metadata<'static> =
                                                    {
                                                        ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1160",
                                                            "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                                                            ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                                            ::tracing_core::__macro_support::Option::Some(1160u32),
                                                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                                            ::tracing_core::field::FieldSet::new(&["message"],
                                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                            ::tracing::metadata::Kind::EVENT)
                                                    };
                                                ::tracing::callsite::DefaultCallsite::new(&META)
                                            };
                                        let enabled =
                                            ::tracing::Level::DEBUG <=
                                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                                    ::tracing::Level::DEBUG <=
                                                        ::tracing::level_filters::LevelFilter::current() &&
                                                {
                                                    let interest = __CALLSITE.interest();
                                                    !interest.is_never() &&
                                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                            interest)
                                                };
                                        if enabled {
                                            (|value_set: ::tracing::field::ValueSet|
                                                        {
                                                            let meta = __CALLSITE.metadata();
                                                            ::tracing::Event::dispatch(meta, &value_set);
                                                            ;
                                                        })({
                                                    #[allow(unused_imports)]
                                                    use ::tracing::field::{debug, display, Value};
                                                    __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_mirror_unadjusted: (type) user_ty={0:?}",
                                                                                        user_ty) as &dyn ::tracing::field::Value))])
                                                });
                                        } else { ; }
                                    };
                                    let mirrored = self.mirror_expr(source);
                                    if source.is_syntactic_place_expr() {
                                        ExprKind::PlaceTypeAscription {
                                            source: mirrored,
                                            user_ty,
                                            user_ty_span: ty.span,
                                        }
                                    } else {
                                        ExprKind::ValueTypeAscription {
                                            source: mirrored,
                                            user_ty,
                                            user_ty_span: ty.span,
                                        }
                                    }
                                }
                                hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Unwrap,
                                    source, _ty) => {
                                    let mirrored = self.mirror_expr(source);
                                    if source.is_syntactic_place_expr() {
                                        ExprKind::PlaceUnwrapUnsafeBinder { source: mirrored }
                                    } else {
                                        ExprKind::ValueUnwrapUnsafeBinder { source: mirrored }
                                    }
                                }
                                hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Wrap,
                                    source, _ty) => {
                                    let mirrored = self.mirror_expr(source);
                                    ExprKind::WrapUnsafeBinder { source: mirrored }
                                }
                                hir::ExprKind::DropTemps(source) => {
                                    ExprKind::ValueExpr { source: self.mirror_expr(source) }
                                }
                                hir::ExprKind::Array(fields) =>
                                    ExprKind::Array { fields: self.mirror_exprs(fields) },
                                hir::ExprKind::Tup(fields) =>
                                    ExprKind::Tuple { fields: self.mirror_exprs(fields) },
                                hir::ExprKind::Yield(v, _) =>
                                    ExprKind::Yield { value: self.mirror_expr(v) },
                                hir::ExprKind::Err(_) => {
                                    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
                                            format_args!("cannot lower a `hir::ExprKind::Err` to THIR")));
                                }
                            };
                        mk_expr(kind, expr_ty)
                    }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:393",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(393u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[instrument(level = "debug", skip(self), ret)]
394    fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
395        let tcx = self.tcx;
396        let expr_ty = self.typeck_results.expr_ty(expr);
397        let mk_expr =
398            |kind, ty| Expr { temp_scope_id: expr.hir_id.local_id, span: expr.span, ty, kind };
399
400        let kind = match expr.kind {
401            // Here comes the interesting stuff:
402            hir::ExprKind::MethodCall(segment, receiver, args, fn_span) => {
403                if self.typeck_results.is_splatted_call(expr) {
404                    // The callee has a splatted tuple argument.
405                    // rewrite `receiver.f(a, u, v)` into `receiver.f(a, #[rustc_splat] (u, v))`
406                    self.convert_splatted_callee(
407                        expr,
408                        fn_span,
409                        args,
410                        SplattedFunc::FnDefReceiver(receiver),
411                    )
412                } else {
413                    // Rewrite a.b(c) into UFCS form like Trait::b(a, c)
414                    let expr = self.method_callee(expr, segment.ident.span, None);
415                    info!("Using method span: {:?}", expr.span);
416
417                    let args = std::iter::once(receiver)
418                        .chain(args.iter())
419                        .map(|expr| self.mirror_expr(expr))
420                        .collect();
421                    ExprKind::Call {
422                        ty: expr.ty,
423                        fun: self.thir.exprs.push(expr),
424                        args,
425                        from_hir_call: true,
426                        fn_span,
427                    }
428                }
429            }
430
431            hir::ExprKind::Call(fun, ref args) => {
432                if self.typeck_results.is_method_call(expr) {
433                    // The callee is something implementing Fn, FnMut, or FnOnce.
434                    // Find the actual method implementation being called and
435                    // build the appropriate UFCS call expression with the
436                    // callee-object as expr parameter.
437
438                    // rewrite f(u, v) into FnOnce::call_once(f, (u, v))
439
440                    let method = self.method_callee(expr, fun.span, None);
441
442                    let arg_tys = args.iter().map(|e| self.typeck_results.expr_ty_adjusted(e));
443                    let tupled_args = Expr {
444                        ty: Ty::new_tup_from_iter(tcx, arg_tys),
445                        temp_scope_id: expr.hir_id.local_id,
446                        span: expr.span,
447                        kind: ExprKind::Tuple { fields: self.mirror_exprs(args) },
448                    };
449                    let tupled_args = self.thir.exprs.push(tupled_args);
450
451                    ExprKind::Call {
452                        ty: method.ty,
453                        fun: self.thir.exprs.push(method),
454                        args: Box::new([self.mirror_expr(fun), tupled_args]),
455                        from_hir_call: true,
456                        fn_span: expr.span,
457                    }
458                } else if self.typeck_results.is_splatted_call(expr) {
459                    // The callee has a splatted tuple argument.
460                    // rewrite `f(a, u, v)` into `f(a, #[rustc_splat] (u, v))`
461                    self.convert_splatted_callee(
462                        expr,
463                        fun.span,
464                        args,
465                        SplattedFunc::FnExpression(fun),
466                    )
467                } else {
468                    // Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
469                    let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
470                        && let Some(adt_def) = expr_ty.ty_adt_def()
471                    {
472                        match qpath {
473                            hir::QPath::Resolved(_, path) => match path.res {
474                                Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
475                                    Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
476                                }
477                                Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
478                                _ => None,
479                            },
480                            hir::QPath::TypeRelative(_ty, _) => {
481                                if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
482                                    self.typeck_results.type_dependent_def(fun.hir_id)
483                                {
484                                    Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
485                                } else {
486                                    None
487                                }
488                            }
489                        }
490                    } else {
491                        None
492                    };
493                    if let Some((adt_def, index)) = adt_data {
494                        let node_args = self.typeck_results.node_args(fun.hir_id);
495                        let user_provided_types = self.typeck_results.user_provided_types();
496                        let user_ty =
497                            user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
498                                if let ty::UserTypeKind::TypeOf(did, _) = &mut u_ty.value.kind {
499                                    *did = adt_def.did();
500                                }
501                                Box::new(u_ty)
502                            });
503                        debug!("make_mirror_unadjusted: (call) user_ty={:?}", user_ty);
504
505                        let field_refs = args
506                            .iter()
507                            .enumerate()
508                            .map(|(idx, e)| FieldExpr {
509                                name: FieldIdx::new(idx),
510                                expr: self.mirror_expr(e),
511                            })
512                            .collect();
513                        ExprKind::Adt(Box::new(AdtExpr {
514                            adt_def,
515                            args: node_args,
516                            variant_index: index,
517                            fields: field_refs,
518                            user_ty,
519                            base: AdtExprBase::None,
520                        }))
521                    } else {
522                        ExprKind::Call {
523                            ty: self.typeck_results.node_type(fun.hir_id),
524                            fun: self.mirror_expr(fun),
525                            args: self.mirror_exprs(args),
526                            from_hir_call: true,
527                            fn_span: expr.span,
528                        }
529                    }
530                }
531            }
532
533            hir::ExprKind::Use(expr, span) => {
534                ExprKind::ByUse { expr: self.mirror_expr(expr), span }
535            }
536
537            hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, arg) => {
538                ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg: self.mirror_expr(arg) }
539            }
540
541            hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutability, arg) => {
542                ExprKind::RawBorrow { mutability, arg: self.mirror_expr(arg) }
543            }
544
545            // Make `&pin mut $expr` and `&pin const $expr` into
546            // `Pin { __pointer: &mut { $expr } }` and `Pin { __pointer: &$expr }`.
547            hir::ExprKind::AddrOf(hir::BorrowKind::Pin, mutbl, arg_expr) => match expr_ty.kind() {
548                &ty::Adt(adt_def, args) if tcx.is_lang_item(adt_def.did(), LangItem::Pin) => {
549                    let ty = args.type_at(0);
550                    let arg_ty = self.typeck_results.expr_ty(arg_expr);
551                    let mut arg = self.mirror_expr(arg_expr);
552                    // For `&pin mut $place` where `$place` is not `Unpin`, move the place
553                    // `$place` to ensure it will not be used afterwards.
554                    if mutbl.is_mut() && !arg_ty.is_unpin(self.tcx, self.typing_env) {
555                        let block = self.thir.blocks.push(Block {
556                            targeted_by_break: false,
557                            region_scope: region::Scope {
558                                local_id: arg_expr.hir_id.local_id,
559                                data: region::ScopeData::Node,
560                            },
561                            span: arg_expr.span,
562                            stmts: Box::new([]),
563                            expr: Some(arg),
564                            safety_mode: BlockSafety::Safe,
565                        });
566                        arg = self.thir.exprs.push(Expr {
567                            temp_scope_id: arg_expr.hir_id.local_id,
568                            ty: arg_ty,
569                            span: arg_expr.span,
570                            kind: ExprKind::Block { block },
571                        });
572                    }
573                    let expr = self.thir.exprs.push(Expr {
574                        temp_scope_id: expr.hir_id.local_id,
575                        ty,
576                        span: expr.span,
577                        kind: ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg },
578                    });
579                    ExprKind::Adt(Box::new(AdtExpr {
580                        adt_def,
581                        variant_index: FIRST_VARIANT,
582                        args,
583                        fields: Box::new([FieldExpr { name: FieldIdx::from(0u32), expr }]),
584                        user_ty: None,
585                        base: AdtExprBase::None,
586                    }))
587                }
588                _ => span_bug!(expr.span, "unexpected type for pinned borrow: {:?}", expr_ty),
589            },
590
591            hir::ExprKind::Block(blk, _) => ExprKind::Block { block: self.mirror_block(blk) },
592
593            hir::ExprKind::Assign(lhs, rhs, _) => {
594                ExprKind::Assign { lhs: self.mirror_expr(lhs), rhs: self.mirror_expr(rhs) }
595            }
596
597            hir::ExprKind::AssignOp(op, lhs, rhs) => {
598                if self.typeck_results.is_method_call(expr) {
599                    let lhs = self.mirror_expr(lhs);
600                    let rhs = self.mirror_expr(rhs);
601                    self.overloaded_operator(expr, Box::new([lhs, rhs]))
602                } else {
603                    ExprKind::AssignOp {
604                        op: assign_op(op.node),
605                        lhs: self.mirror_expr(lhs),
606                        rhs: self.mirror_expr(rhs),
607                    }
608                }
609            }
610
611            hir::ExprKind::Lit(lit) => ExprKind::Literal { lit, neg: false },
612
613            hir::ExprKind::Binary(op, lhs, rhs) => {
614                if self.typeck_results.is_method_call(expr) {
615                    let lhs = self.mirror_expr(lhs);
616                    let rhs = self.mirror_expr(rhs);
617                    self.overloaded_operator(expr, Box::new([lhs, rhs]))
618                } else {
619                    match op.node {
620                        hir::BinOpKind::And => ExprKind::LogicalOp {
621                            op: LogicalOp::And,
622                            lhs: self.mirror_expr(lhs),
623                            rhs: self.mirror_expr(rhs),
624                        },
625                        hir::BinOpKind::Or => ExprKind::LogicalOp {
626                            op: LogicalOp::Or,
627                            lhs: self.mirror_expr(lhs),
628                            rhs: self.mirror_expr(rhs),
629                        },
630                        _ => {
631                            let op = bin_op(op.node);
632                            ExprKind::Binary {
633                                op,
634                                lhs: self.mirror_expr(lhs),
635                                rhs: self.mirror_expr(rhs),
636                            }
637                        }
638                    }
639                }
640            }
641
642            hir::ExprKind::Index(lhs, index, brackets_span) => {
643                if self.typeck_results.is_method_call(expr) {
644                    let lhs = self.mirror_expr(lhs);
645                    let index = self.mirror_expr(index);
646                    self.overloaded_place(
647                        expr,
648                        expr_ty,
649                        None,
650                        Box::new([lhs, index]),
651                        brackets_span,
652                    )
653                } else {
654                    ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) }
655                }
656            }
657
658            hir::ExprKind::Unary(hir::UnOp::Deref, arg) => {
659                if self.typeck_results.is_method_call(expr) {
660                    let arg = self.mirror_expr(arg);
661                    self.overloaded_place(expr, expr_ty, None, Box::new([arg]), expr.span)
662                } else {
663                    ExprKind::Deref { arg: self.mirror_expr(arg) }
664                }
665            }
666
667            hir::ExprKind::Unary(hir::UnOp::Not, arg) => {
668                if self.typeck_results.is_method_call(expr) {
669                    let arg = self.mirror_expr(arg);
670                    self.overloaded_operator(expr, Box::new([arg]))
671                } else {
672                    ExprKind::Unary { op: UnOp::Not, arg: self.mirror_expr(arg) }
673                }
674            }
675
676            hir::ExprKind::Unary(hir::UnOp::Neg, arg) => {
677                if self.typeck_results.is_method_call(expr) {
678                    let arg = self.mirror_expr(arg);
679                    self.overloaded_operator(expr, Box::new([arg]))
680                } else if let hir::ExprKind::Lit(lit) = arg.kind {
681                    ExprKind::Literal { lit, neg: true }
682                } else {
683                    ExprKind::Unary { op: UnOp::Neg, arg: self.mirror_expr(arg) }
684                }
685            }
686
687            hir::ExprKind::Struct(qpath, fields, ref base) => match expr_ty.kind() {
688                ty::Adt(adt, args) => match adt.adt_kind() {
689                    AdtKind::Struct | AdtKind::Union => {
690                        let user_provided_types = self.typeck_results.user_provided_types();
691                        let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
692                        debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
693                        ExprKind::Adt(Box::new(AdtExpr {
694                            adt_def: *adt,
695                            variant_index: FIRST_VARIANT,
696                            args,
697                            user_ty,
698                            fields: self.field_refs(fields),
699                            base: match base {
700                                hir::StructTailExpr::Base(base) => AdtExprBase::Base(FruInfo {
701                                    base: self.mirror_expr(base),
702                                    field_types: self.typeck_results.fru_field_types()[expr.hir_id]
703                                        .iter()
704                                        .copied()
705                                        .collect(),
706                                }),
707                                hir::StructTailExpr::DefaultFields(_) => {
708                                    AdtExprBase::DefaultFields(
709                                        self.typeck_results.fru_field_types()[expr.hir_id]
710                                            .iter()
711                                            .copied()
712                                            .collect(),
713                                    )
714                                }
715                                hir::StructTailExpr::None
716                                | hir::StructTailExpr::NoneWithError(_) => AdtExprBase::None,
717                            },
718                        }))
719                    }
720                    AdtKind::Enum => {
721                        let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
722                        match res {
723                            Res::Def(DefKind::Variant, variant_id) => {
724                                assert!(matches!(
725                                    base,
726                                    hir::StructTailExpr::None
727                                        | hir::StructTailExpr::DefaultFields(_)
728                                        | hir::StructTailExpr::NoneWithError(_)
729                                ));
730
731                                let index = adt.variant_index_with_id(variant_id);
732                                let user_provided_types = self.typeck_results.user_provided_types();
733                                let user_ty =
734                                    user_provided_types.get(expr.hir_id).copied().map(Box::new);
735                                debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
736                                ExprKind::Adt(Box::new(AdtExpr {
737                                    adt_def: *adt,
738                                    variant_index: index,
739                                    args,
740                                    user_ty,
741                                    fields: self.field_refs(fields),
742                                    base: match base {
743                                        hir::StructTailExpr::DefaultFields(_) => {
744                                            AdtExprBase::DefaultFields(
745                                                self.typeck_results.fru_field_types()[expr.hir_id]
746                                                    .iter()
747                                                    .copied()
748                                                    .collect(),
749                                            )
750                                        }
751                                        hir::StructTailExpr::Base(base) => {
752                                            span_bug!(base.span, "unexpected res: {:?}", res);
753                                        }
754                                        hir::StructTailExpr::None
755                                        | hir::StructTailExpr::NoneWithError(_) => {
756                                            AdtExprBase::None
757                                        }
758                                    },
759                                }))
760                            }
761                            _ => {
762                                span_bug!(expr.span, "unexpected res: {:?}", res);
763                            }
764                        }
765                    }
766                },
767                _ => {
768                    span_bug!(expr.span, "unexpected type for struct literal: {:?}", expr_ty);
769                }
770            },
771
772            hir::ExprKind::Closure(hir::Closure { .. }) => {
773                let closure_ty = self.typeck_results.expr_ty(expr);
774                let (def_id, args, movability) = match *closure_ty.kind() {
775                    ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args), None),
776                    ty::Coroutine(def_id, args) => {
777                        (def_id, UpvarArgs::Coroutine(args), Some(tcx.coroutine_movability(def_id)))
778                    }
779                    ty::CoroutineClosure(def_id, args) => {
780                        (def_id, UpvarArgs::CoroutineClosure(args), None)
781                    }
782                    _ => {
783                        span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty);
784                    }
785                };
786                let def_id = def_id.expect_local();
787
788                let upvars = self
789                    .tcx
790                    .closure_captures(def_id)
791                    .iter()
792                    .zip_eq(args.upvar_tys())
793                    .map(|(captured_place, ty)| {
794                        let upvars = self.capture_upvar(expr, captured_place, ty);
795                        self.thir.exprs.push(upvars)
796                    })
797                    .collect();
798
799                // Convert the closure fake reads, if any, from hir `Place` to ExprRef
800                let fake_reads = match self.typeck_results.closure_fake_reads.get(&def_id) {
801                    Some(fake_reads) => fake_reads
802                        .iter()
803                        .map(|(place, cause, hir_id)| {
804                            let expr = self.convert_captured_hir_place(expr, place.clone());
805                            (self.thir.exprs.push(expr), *cause, *hir_id)
806                        })
807                        .collect(),
808                    None => Vec::new(),
809                };
810
811                ExprKind::Closure(Box::new(ClosureExpr {
812                    closure_id: def_id,
813                    args,
814                    upvars,
815                    movability,
816                    fake_reads,
817                }))
818            }
819
820            hir::ExprKind::Path(ref qpath) => {
821                let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
822                self.convert_path_expr(expr, res)
823            }
824
825            hir::ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
826                asm_macro: asm.asm_macro,
827                template: asm.template,
828                operands: asm
829                    .operands
830                    .iter()
831                    .map(|(op, _op_sp)| match *op {
832                        hir::InlineAsmOperand::In { reg, expr } => InlineAsmOperand::In {
833                            reg: reg.as_target(),
834                            expr: self.mirror_expr(expr),
835                        },
836                        hir::InlineAsmOperand::Out { reg, late, ref expr } => {
837                            InlineAsmOperand::Out {
838                                reg: reg.as_target(),
839                                late,
840                                expr: expr.map(|expr| self.mirror_expr(expr)),
841                            }
842                        }
843                        hir::InlineAsmOperand::InOut { reg, late, expr } => {
844                            InlineAsmOperand::InOut {
845                                reg: reg.as_target(),
846                                late,
847                                expr: self.mirror_expr(expr),
848                            }
849                        }
850                        hir::InlineAsmOperand::SplitInOut { reg, late, in_expr, ref out_expr } => {
851                            InlineAsmOperand::SplitInOut {
852                                reg: reg.as_target(),
853                                late,
854                                in_expr: self.mirror_expr(in_expr),
855                                out_expr: out_expr.map(|expr| self.mirror_expr(expr)),
856                            }
857                        }
858                        hir::InlineAsmOperand::Const { ref anon_const } => {
859                            let ty = self.typeck_results.node_type(anon_const.hir_id);
860                            let did = anon_const.def_id;
861                            let typeck_root_def_id = tcx.typeck_root_def_id_local(did);
862                            let parent_args = tcx.erase_and_anonymize_regions(
863                                GenericArgs::identity_for_item(tcx, typeck_root_def_id),
864                            );
865                            let args =
866                                InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty })
867                                    .args;
868
869                            let uneval = mir::UnevaluatedConst::new(did.to_def_id(), args);
870                            let value = mir::Const::Unevaluated(uneval, ty);
871                            InlineAsmOperand::Const { value, span: tcx.def_span(did) }
872                        }
873                        hir::InlineAsmOperand::SymFn { expr } => {
874                            InlineAsmOperand::SymFn { value: self.mirror_expr(expr) }
875                        }
876                        hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
877                            InlineAsmOperand::SymStatic { def_id }
878                        }
879                        hir::InlineAsmOperand::Label { block } => {
880                            InlineAsmOperand::Label { block: self.mirror_block(block) }
881                        }
882                    })
883                    .collect(),
884                options: asm.options,
885                line_spans: asm.line_spans,
886            })),
887
888            hir::ExprKind::OffsetOf(_, _) => {
889                let offset_of_intrinsic = tcx.require_lang_item(LangItem::OffsetOf, expr.span);
890                let mk_u32_kind = |val: u32| ExprKind::NonHirLiteral {
891                    lit: ScalarInt::try_from_uint(val, Size::from_bits(32)).unwrap(),
892                    user_ty: None,
893                };
894                let mk_usize_kind = |val: u64| ExprKind::NonHirLiteral {
895                    lit: ScalarInt::try_from_target_usize(val, tcx).unwrap(),
896                    user_ty: None,
897                };
898                let mk_call =
899                    |thir: &mut Thir<'tcx>, ty: Ty<'tcx>, variant: VariantIdx, field: FieldIdx| {
900                        let fun_ty = tcx
901                            .type_of(offset_of_intrinsic)
902                            .instantiate(tcx, &[ty.into()])
903                            .skip_norm_wip();
904                        let fun = thir
905                            .exprs
906                            .push(mk_expr(ExprKind::ZstLiteral { user_ty: None }, fun_ty));
907                        let variant =
908                            thir.exprs.push(mk_expr(mk_u32_kind(variant.as_u32()), tcx.types.u32));
909                        let field =
910                            thir.exprs.push(mk_expr(mk_u32_kind(field.as_u32()), tcx.types.u32));
911                        let args = Box::new([variant, field]);
912                        ExprKind::Call {
913                            ty: fun_ty,
914                            fun,
915                            args,
916                            from_hir_call: false,
917                            fn_span: expr.span,
918                        }
919                    };
920
921                let indices = self.typeck_results.offset_of_data().get(expr.hir_id).unwrap();
922                let mut expr = None::<ExprKind<'_>>;
923
924                for &(container, variant, field) in indices.iter() {
925                    let next = mk_call(&mut self.thir, container, variant, field);
926                    expr = Some(match expr.take() {
927                        None => next,
928                        Some(last) => {
929                            let last = self.thir.exprs.push(mk_expr(last, tcx.types.usize));
930                            let next = self.thir.exprs.push(mk_expr(next, tcx.types.usize));
931                            ExprKind::Binary { op: BinOp::Add, lhs: last, rhs: next }
932                        }
933                    });
934                }
935
936                expr.unwrap_or_else(|| mk_usize_kind(0))
937            }
938
939            hir::ExprKind::ConstBlock(ref anon_const) => {
940                let ty = self.typeck_results.node_type(anon_const.hir_id);
941                let did = anon_const.def_id;
942                let typeck_root_def_id = tcx.typeck_root_def_id_local(did);
943                let parent_args = tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(
944                    tcx,
945                    typeck_root_def_id,
946                ));
947                let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }).args;
948
949                ExprKind::ConstBlock { did: did.to_def_id(), args }
950            }
951            // Now comes the rote stuff:
952            hir::ExprKind::Repeat(v, _) => {
953                let ty = self.typeck_results.expr_ty(expr);
954                let ty::Array(_, count) = ty.kind() else {
955                    span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty);
956                };
957
958                ExprKind::Repeat { value: self.mirror_expr(v), count: *count }
959            }
960            hir::ExprKind::Ret(v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
961            hir::ExprKind::Become(call) => ExprKind::Become { value: self.mirror_expr(call) },
962            hir::ExprKind::Break(dest, ref value) => {
963                if find_attr!(self.tcx, expr.hir_id, ConstContinue(_)) {
964                    match dest.target_id {
965                        Ok(target_id) => {
966                            let (Some(value), Some(_)) = (value, dest.label) else {
967                                let span = expr.span;
968                                self.tcx.dcx().emit_fatal(ConstContinueMissingLabelOrValue { span })
969                            };
970
971                            ExprKind::ConstContinue {
972                                label: region::Scope {
973                                    local_id: target_id.local_id,
974                                    data: region::ScopeData::Node,
975                                },
976                                value: self.mirror_expr(value),
977                            }
978                        }
979                        Err(err) => bug!("invalid loop id for break: {}", err),
980                    }
981                } else {
982                    match dest.target_id {
983                        Ok(target_id) => ExprKind::Break {
984                            label: region::Scope {
985                                local_id: target_id.local_id,
986                                data: region::ScopeData::Node,
987                            },
988                            value: value.map(|value| self.mirror_expr(value)),
989                        },
990                        Err(err) => bug!("invalid loop id for break: {}", err),
991                    }
992                }
993            }
994            hir::ExprKind::Continue(dest) => match dest.target_id {
995                Ok(loop_id) => ExprKind::Continue {
996                    label: region::Scope {
997                        local_id: loop_id.local_id,
998                        data: region::ScopeData::Node,
999                    },
1000                },
1001                Err(err) => bug!("invalid loop id for continue: {}", err),
1002            },
1003            hir::ExprKind::Let(let_expr) => ExprKind::Let {
1004                expr: self.mirror_expr(let_expr.init),
1005                pat: self.pattern_from_hir(let_expr.pat),
1006            },
1007            hir::ExprKind::If(cond, then, else_opt) => ExprKind::If {
1008                if_then_scope: region::Scope {
1009                    local_id: then.hir_id.local_id,
1010                    data: {
1011                        if expr.span.at_least_rust_2024() {
1012                            region::ScopeData::IfThenRescope
1013                        } else {
1014                            region::ScopeData::IfThen
1015                        }
1016                    },
1017                },
1018                cond: self.mirror_expr(cond),
1019                then: self.mirror_expr(then),
1020                else_opt: else_opt.map(|el| self.mirror_expr(el)),
1021            },
1022            hir::ExprKind::Match(discr, arms, match_source) => ExprKind::Match {
1023                scrutinee: self.mirror_expr(discr),
1024                arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
1025                match_source,
1026            },
1027            hir::ExprKind::Loop(body, ..) => {
1028                if find_attr!(self.tcx, expr.hir_id, LoopMatch(_)) {
1029                    let dcx = self.tcx.dcx();
1030
1031                    // Accept either `state = expr` or `state = expr;`.
1032                    let loop_body_expr = match body.stmts {
1033                        [] => match body.expr {
1034                            Some(expr) => expr,
1035                            None => dcx.emit_fatal(LoopMatchMissingAssignment { span: body.span }),
1036                        },
1037                        [single] if body.expr.is_none() => match single.kind {
1038                            hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) => expr,
1039                            _ => dcx.emit_fatal(LoopMatchMissingAssignment { span: body.span }),
1040                        },
1041                        [first @ last] | [first, .., last] => dcx
1042                            .emit_fatal(LoopMatchBadStatements { span: first.span.to(last.span) }),
1043                    };
1044
1045                    let hir::ExprKind::Assign(state, rhs_expr, _) = loop_body_expr.kind else {
1046                        dcx.emit_fatal(LoopMatchMissingAssignment { span: loop_body_expr.span })
1047                    };
1048
1049                    let hir::ExprKind::Block(block_body, _) = rhs_expr.kind else {
1050                        dcx.emit_fatal(LoopMatchBadRhs { span: rhs_expr.span })
1051                    };
1052
1053                    // The labeled block should contain one match expression, but defining items is
1054                    // allowed.
1055                    for stmt in block_body.stmts {
1056                        if !matches!(stmt.kind, rustc_hir::StmtKind::Item(_)) {
1057                            dcx.emit_fatal(LoopMatchBadStatements { span: stmt.span })
1058                        }
1059                    }
1060
1061                    let Some(block_body_expr) = block_body.expr else {
1062                        dcx.emit_fatal(LoopMatchBadRhs { span: block_body.span })
1063                    };
1064
1065                    let hir::ExprKind::Match(scrutinee, arms, _match_source) = block_body_expr.kind
1066                    else {
1067                        dcx.emit_fatal(LoopMatchBadRhs { span: block_body_expr.span })
1068                    };
1069
1070                    fn local(
1071                        cx: &mut ThirBuildCx<'_>,
1072                        expr: &rustc_hir::Expr<'_>,
1073                    ) -> Option<hir::HirId> {
1074                        if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
1075                            && let Res::Local(hir_id) = path.res
1076                            && !cx.is_upvar(hir_id)
1077                        {
1078                            return Some(hir_id);
1079                        }
1080
1081                        None
1082                    }
1083
1084                    let Some(scrutinee_hir_id) = local(self, scrutinee) else {
1085                        dcx.emit_fatal(LoopMatchInvalidMatch { span: scrutinee.span })
1086                    };
1087
1088                    if local(self, state) != Some(scrutinee_hir_id) {
1089                        dcx.emit_fatal(LoopMatchInvalidUpdate {
1090                            scrutinee: scrutinee.span,
1091                            lhs: state.span,
1092                        })
1093                    }
1094
1095                    ExprKind::LoopMatch {
1096                        state: self.mirror_expr(state),
1097                        region_scope: region::Scope {
1098                            local_id: block_body.hir_id.local_id,
1099                            data: region::ScopeData::Node,
1100                        },
1101
1102                        match_data: Box::new(LoopMatchMatchData {
1103                            scrutinee: self.mirror_expr(scrutinee),
1104                            arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
1105                            span: block_body_expr.span,
1106                        }),
1107                    }
1108                } else {
1109                    let block_ty = self.typeck_results.node_type(body.hir_id);
1110                    let block = self.mirror_block(body);
1111                    let body = self.thir.exprs.push(Expr {
1112                        ty: block_ty,
1113                        temp_scope_id: body.hir_id.local_id,
1114                        span: self.thir[block].span,
1115                        kind: ExprKind::Block { block },
1116                    });
1117                    ExprKind::Loop { body }
1118                }
1119            }
1120            hir::ExprKind::Field(source, ..) => ExprKind::Field {
1121                lhs: self.mirror_expr(source),
1122                variant_index: FIRST_VARIANT,
1123                name: self.typeck_results.field_index(expr.hir_id),
1124            },
1125            hir::ExprKind::Cast(source, cast_ty) => {
1126                // Check for a user-given type annotation on this `cast`
1127                let user_provided_types = self.typeck_results.user_provided_types();
1128                let user_ty = user_provided_types.get(cast_ty.hir_id);
1129
1130                debug!(
1131                    "cast({:?}) has ty w/ hir_id {:?} and user provided ty {:?}",
1132                    expr, cast_ty.hir_id, user_ty,
1133                );
1134
1135                let cast = self.mirror_expr_cast(source, expr.hir_id.local_id, expr.span);
1136
1137                if let Some(user_ty) = user_ty {
1138                    // NOTE: Creating a new Expr and wrapping a Cast inside of it may be
1139                    //       inefficient, revisit this when performance becomes an issue.
1140                    let cast_expr = self.thir.exprs.push(Expr {
1141                        temp_scope_id: expr.hir_id.local_id,
1142                        ty: expr_ty,
1143                        span: expr.span,
1144                        kind: cast,
1145                    });
1146                    debug!("make_mirror_unadjusted: (cast) user_ty={:?}", user_ty);
1147
1148                    ExprKind::ValueTypeAscription {
1149                        source: cast_expr,
1150                        user_ty: Some(Box::new(*user_ty)),
1151                        user_ty_span: cast_ty.span,
1152                    }
1153                } else {
1154                    cast
1155                }
1156            }
1157            hir::ExprKind::Type(source, ty) => {
1158                let user_provided_types = self.typeck_results.user_provided_types();
1159                let user_ty = user_provided_types.get(ty.hir_id).copied().map(Box::new);
1160                debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty);
1161                let mirrored = self.mirror_expr(source);
1162                if source.is_syntactic_place_expr() {
1163                    ExprKind::PlaceTypeAscription {
1164                        source: mirrored,
1165                        user_ty,
1166                        user_ty_span: ty.span,
1167                    }
1168                } else {
1169                    ExprKind::ValueTypeAscription {
1170                        source: mirrored,
1171                        user_ty,
1172                        user_ty_span: ty.span,
1173                    }
1174                }
1175            }
1176
1177            hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Unwrap, source, _ty) => {
1178                // FIXME(unsafe_binders): Take into account the ascribed type, too.
1179                let mirrored = self.mirror_expr(source);
1180                if source.is_syntactic_place_expr() {
1181                    ExprKind::PlaceUnwrapUnsafeBinder { source: mirrored }
1182                } else {
1183                    ExprKind::ValueUnwrapUnsafeBinder { source: mirrored }
1184                }
1185            }
1186            hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Wrap, source, _ty) => {
1187                // FIXME(unsafe_binders): Take into account the ascribed type, too.
1188                let mirrored = self.mirror_expr(source);
1189                ExprKind::WrapUnsafeBinder { source: mirrored }
1190            }
1191
1192            hir::ExprKind::DropTemps(source) => {
1193                ExprKind::ValueExpr { source: self.mirror_expr(source) }
1194            }
1195            hir::ExprKind::Array(fields) => ExprKind::Array { fields: self.mirror_exprs(fields) },
1196            hir::ExprKind::Tup(fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) },
1197
1198            hir::ExprKind::Yield(v, _) => ExprKind::Yield { value: self.mirror_expr(v) },
1199            hir::ExprKind::Err(_) => unreachable!("cannot lower a `hir::ExprKind::Err` to THIR"),
1200        };
1201
1202        mk_expr(kind, expr_ty)
1203    }
1204
1205    fn user_args_applied_to_res(
1206        &mut self,
1207        hir_id: hir::HirId,
1208        res: Res,
1209    ) -> Option<Box<ty::CanonicalUserType<'tcx>>> {
1210        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1210",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1210u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("user_args_applied_to_res: res={0:?}",
                                                    res) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("user_args_applied_to_res: res={:?}", res);
1211        let user_provided_type = match res {
1212            // A reference to something callable -- e.g., a fn, method, or
1213            // a tuple-struct or tuple-variant. This has the type of a
1214            // `Fn` but with the user-given generic parameters.
1215            Res::Def(DefKind::Fn, _)
1216            | Res::Def(DefKind::AssocFn, _)
1217            | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
1218            | Res::Def(DefKind::Const, _)
1219            | Res::Def(DefKind::AssocConst, _) => {
1220                self.typeck_results.user_provided_types().get(hir_id).copied().map(Box::new)
1221            }
1222
1223            // A unit struct/variant which is used as a value (e.g.,
1224            // `None`). This has the type of the enum/struct that defines
1225            // this variant -- but with the generic parameters given by the
1226            // user.
1227            Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => {
1228                self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new)
1229            }
1230
1231            // `Self` is used in expression as a tuple struct constructor or a unit struct constructor
1232            Res::SelfCtor(_) => self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new),
1233
1234            _ => ::rustc_span::macros::bug_impl(None,
    format_args!("user_args_applied_to_res: unexpected res {0:?} at {1:?}",
        res, hir_id), Location::caller())bug!("user_args_applied_to_res: unexpected res {:?} at {:?}", res, hir_id),
1235        };
1236        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1236",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1236u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("user_args_applied_to_res: user_provided_type={0:?}",
                                                    user_provided_type) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("user_args_applied_to_res: user_provided_type={:?}", user_provided_type);
1237        user_provided_type
1238    }
1239
1240    fn method_callee(
1241        &mut self,
1242        expr: &hir::Expr<'_>,
1243        span: Span,
1244        overloaded_callee: Option<Ty<'tcx>>,
1245    ) -> Expr<'tcx> {
1246        let (ty, user_ty) = match overloaded_callee {
1247            Some(fn_def) => (fn_def, None),
1248            None => {
1249                let (kind, def_id) =
1250                    self.typeck_results.type_dependent_def(expr.hir_id).unwrap_or_else(|| {
1251                        ::rustc_span::macros::bug_impl(Some(expr.span),
    format_args!("no type-dependent def for method callee"),
    Location::caller())span_bug!(expr.span, "no type-dependent def for method callee")
1252                    });
1253                let user_ty = self.user_args_applied_to_res(expr.hir_id, Res::Def(kind, def_id));
1254                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1254",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1254u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("method_callee: user_ty={0:?}",
                                                    user_ty) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("method_callee: user_ty={:?}", user_ty);
1255                (
1256                    self.tcx
1257                        .type_of(def_id)
1258                        .instantiate(self.tcx, self.typeck_results.node_args(expr.hir_id))
1259                        .skip_norm_wip(),
1260                    user_ty,
1261                )
1262            }
1263        };
1264        Expr {
1265            temp_scope_id: expr.hir_id.local_id,
1266            ty,
1267            span,
1268            kind: ExprKind::ZstLiteral { user_ty },
1269        }
1270    }
1271
1272    /// The callee has a splatted tuple argument.
1273    /// Rewrite a splatted call `receiver.f(a, u, v)` into `receiver.f(a, #[rustc_splat] (u, v))`.
1274    /// The receiver is optional.
1275    fn convert_splatted_callee(
1276        &mut self,
1277        call_expr: &'tcx hir::Expr<'_>,
1278        fn_span: Span,
1279        args: &'tcx [hir::Expr<'tcx>],
1280        receiver_or_func: SplattedFunc<'tcx>,
1281    ) -> ExprKind<'tcx> {
1282        let tcx = self.tcx;
1283
1284        // Look up the typeck results
1285        let splatted_def =
1286            self.typeck_results.splatted_def(call_expr.hir_id).unwrap_or_else(|| {
1287                ::rustc_span::macros::bug_impl(Some(call_expr.span),
    format_args!("no splatted def for function or method callee"),
    Location::caller())span_bug!(call_expr.span, "no splatted def for function or method callee")
1288            });
1289
1290        let tupled_arg_index = usize::from(splatted_def.arg_index());
1291        let tupled_args_count = usize::from(splatted_def.arg_count());
1292
1293        // Splatting an empty tuple is permitted: `a.f() -> Trait::f(a, #[rustc_splat] ())`.
1294        // In that case, the tupled arg index is one past the end of the args.
1295        if tupled_arg_index + tupled_args_count > args.len() {
1296            ::rustc_span::macros::bug_impl(Some(call_expr.span),
    format_args!("splatted arg index out of bounds of function args: {0:?} + {1:?} > {2:?} for function call: {3:?}, args {4:?}",
        tupled_arg_index, tupled_args_count, args.len(), receiver_or_func,
        args), Location::caller());span_bug!(
1297                call_expr.span,
1298                "splatted arg index out of bounds of function args: {:?} + {:?} > {:?} for function call: {:?}, args {:?}",
1299                tupled_arg_index,
1300                tupled_args_count,
1301                args.len(),
1302                receiver_or_func,
1303                args,
1304            );
1305        }
1306
1307        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1307",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1307u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("Using splatted function span: {0:?}",
                                                    fn_span) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("Using splatted function span: {:?}", fn_span);
1308
1309        // Split into non-tupled and tupled arguments
1310        let initial_non_tupled_args =
1311            args.iter().take(tupled_arg_index).map(|e| self.mirror_expr(e)).collect_vec();
1312        let tupled_args = if tupled_arg_index == args.len() || tupled_args_count == 0 {
1313            // Splatting an empty tuple, in the ABI this gets ignored
1314            Default::default()
1315        } else {
1316            &args[tupled_arg_index..(tupled_arg_index + tupled_args_count)]
1317        };
1318        let final_non_tupled_args = args
1319            .iter()
1320            .skip(tupled_arg_index + tupled_args_count)
1321            .map(|e| self.mirror_expr(e))
1322            .collect_vec();
1323
1324        let tupled_arg_tys = tupled_args.iter().map(|e| self.typeck_results.expr_ty_adjusted(e));
1325
1326        // We need the tupled arguments in HIR/MIR for type checking
1327        // FIXME(splat): de-tuple args in codegen for performance
1328        let tupled_args = Expr {
1329            ty: Ty::new_tup_from_iter(tcx, tupled_arg_tys),
1330            temp_scope_id: call_expr.hir_id.local_id,
1331            span: call_expr.span,
1332            kind: ExprKind::Tuple { fields: self.mirror_exprs(tupled_args) },
1333        };
1334
1335        let tupled_args = self.thir.exprs.push(tupled_args);
1336
1337        // Handle the receiver as the first arg, if present
1338        let mut args = Vec::with_capacity(
1339            usize::from(receiver_or_func.has_receiver())
1340                + initial_non_tupled_args.len()
1341                + 1
1342                + final_non_tupled_args.len(),
1343        );
1344        if let Some(receiver) = receiver_or_func.receiver() {
1345            args.push(self.mirror_expr(receiver));
1346        }
1347        args.extend(initial_non_tupled_args);
1348        args.push(tupled_args);
1349        args.extend(final_non_tupled_args);
1350
1351        let fn_span = if receiver_or_func.has_receiver() { fn_span } else { call_expr.span };
1352
1353        let (fn_ty, fun_expr) = match (splatted_def, receiver_or_func.fn_expression()) {
1354            // Create a FnDef shim for user-provided types
1355            (SplattedDef::FnDef { def_id, arg_index, arg_count }, _) => {
1356                // We're calling a function via a FnDef, and its possibly generic type
1357                // This is effectively `self.method_callee(call_expr, fn_span, None)`,
1358                // applied to `splatted_def` instead of `type_dependent_def`.
1359                let def_kind = self.tcx.def_kind(def_id);
1360                let user_ty =
1361                    self.user_args_applied_to_res(call_expr.hir_id, Res::Def(def_kind, def_id));
1362                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1362",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1362u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("splatted_callee FnDef: user_ty={0:?} def_kind={1:?} def_id={2:?} arg_index={3:?} arg_count={4:?}",
                                                    user_ty, def_kind, def_id, arg_index, arg_count) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
1363                    "splatted_callee FnDef: user_ty={:?} def_kind={:?} def_id={:?} arg_index={:?} arg_count={:?}",
1364                    user_ty, def_kind, def_id, arg_index, arg_count,
1365                );
1366
1367                // Create a new FnDef expression with user-provided type applied
1368                let callee_expr = Expr {
1369                    temp_scope_id: call_expr.hir_id.local_id,
1370                    ty: self
1371                        .tcx
1372                        .type_of(def_id)
1373                        .instantiate(self.tcx, self.typeck_results.node_args(call_expr.hir_id))
1374                        .skip_norm_wip(),
1375                    span: fn_span,
1376                    kind: ExprKind::ZstLiteral { user_ty },
1377                };
1378                (callee_expr.ty, self.thir.exprs.push(callee_expr))
1379            }
1380
1381            // We're calling a function via a FnPtr and its type
1382            // FIXME(splat): do we need to populate and apply user_provided_types() ?
1383            (SplattedDef::FnPtr { fn_ptr_type, arg_index, arg_count }, Some(fn_expression)) => {
1384                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1384",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1384u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("splatted_callee FnPtr: fn_ty={0:?} arg_index={1:?} arg_count={2:?}",
                                                    fn_ptr_type, arg_index, arg_count) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
1385                    "splatted_callee FnPtr: fn_ty={:?} arg_index={:?} arg_count={:?}",
1386                    fn_ptr_type, arg_index, arg_count,
1387                );
1388
1389                if !fn_ptr_type.is_fn() {
1390                    ::rustc_span::macros::bug_impl(Some(call_expr.span),
    format_args!("splatted FnPtr side-tables were not populated correctly, non-fn type received: {0:?}",
        fn_ptr_type), Location::caller())span_bug!(
1391                        call_expr.span,
1392                        "splatted FnPtr side-tables were not populated correctly, non-fn type received: {:?}",
1393                        fn_ptr_type
1394                    )
1395                }
1396
1397                // Pass through the FnPtr type and the mirrored function path
1398                (fn_ptr_type, self.mirror_expr(fn_expression))
1399            }
1400            // FnPtrs must have a function expression (and they never have method receivers)
1401            (SplattedDef::FnPtr { .. }, None) => {
1402                ::rustc_span::macros::bug_impl(Some(call_expr.span),
    format_args!("convert_splatted_callee: FnPtr without fn expression (or with receiver) is invalid: splatted_def={0:?}, receiver_or_func={1:?}",
        splatted_def, receiver_or_func), Location::caller());span_bug!(
1403                    call_expr.span,
1404                    "convert_splatted_callee: FnPtr without fn expression (or with receiver) is invalid: splatted_def={:?}, receiver_or_func={:?}",
1405                    splatted_def,
1406                    receiver_or_func,
1407                );
1408            }
1409        };
1410
1411        ExprKind::Call {
1412            ty: fn_ty,
1413            fun: fun_expr,
1414            args: args.into_boxed_slice(),
1415            from_hir_call: true,
1416            fn_span,
1417        }
1418    }
1419
1420    fn convert_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) -> ArmId {
1421        let arm = Arm {
1422            pattern: self.pattern_from_hir(&arm.pat),
1423            guard: arm.guard.as_ref().map(|g| self.mirror_expr(g)),
1424            body: self.mirror_expr(arm.body),
1425            hir_id: arm.hir_id,
1426            scope: region::Scope { local_id: arm.hir_id.local_id, data: region::ScopeData::Node },
1427            span: arm.span,
1428        };
1429        self.thir.arms.push(arm)
1430    }
1431
1432    fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKind<'tcx> {
1433        let args = self.typeck_results.node_args(expr.hir_id);
1434        match res {
1435            // A regular function, constructor function or a constant.
1436            Res::Def(DefKind::Fn, _)
1437            | Res::Def(DefKind::AssocFn, _)
1438            | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
1439            | Res::SelfCtor(_) => {
1440                let user_ty = self.user_args_applied_to_res(expr.hir_id, res);
1441                ExprKind::ZstLiteral { user_ty }
1442            }
1443
1444            Res::Def(DefKind::ConstParam, def_id) => {
1445                let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local());
1446                let generics = self.tcx.generics_of(hir_id.owner);
1447                let Some(&index) = generics.param_def_id_to_index.get(&def_id) else {
1448                    ::rustc_span::macros::bug_impl(Some(expr.span),
    format_args!("Should have already errored about late bound consts: {0:?}",
        def_id), Location::caller());span_bug!(
1449                        expr.span,
1450                        "Should have already errored about late bound consts: {def_id:?}"
1451                    );
1452                };
1453                let name = self.tcx.hir_name(hir_id);
1454                let param = ty::ParamConst::new(index, name);
1455
1456                ExprKind::ConstParam { param, def_id }
1457            }
1458
1459            Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
1460                let user_ty = self.user_args_applied_to_res(expr.hir_id, res);
1461                ExprKind::NamedConst { def_id, args, user_ty }
1462            }
1463
1464            Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
1465                let user_provided_types = self.typeck_results.user_provided_types();
1466                let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
1467                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1467",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1467u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("convert_path_expr: user_ty={0:?}",
                                                    user_ty) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("convert_path_expr: user_ty={:?}", user_ty);
1468                let ty = self.typeck_results.node_type(expr.hir_id);
1469                match ty.kind() {
1470                    // A unit struct/variant which is used as a value.
1471                    // We return a completely different ExprKind here to account for this special case.
1472                    ty::Adt(adt_def, args) => ExprKind::Adt(Box::new(AdtExpr {
1473                        adt_def: *adt_def,
1474                        variant_index: adt_def.variant_index_with_ctor_id(def_id),
1475                        args,
1476                        user_ty,
1477                        fields: Box::new([]),
1478                        base: AdtExprBase::None,
1479                    })),
1480                    _ => ::rustc_span::macros::bug_impl(None, format_args!("unexpected ty: {0:?}", ty),
    Location::caller())bug!("unexpected ty: {:?}", ty),
1481                }
1482            }
1483
1484            // A source Rust `path::to::STATIC` is a place expr like *&ident is.
1485            // In THIR, we make them exactly equivalent by inserting the implied *& or *&raw,
1486            // but distinguish between &STATIC and &THREAD_LOCAL as they have different semantics
1487            Res::Def(DefKind::Static { .. }, id) => {
1488                // this is &raw for extern static or static mut, and & for other statics
1489                let ty = self.tcx.static_ptr_ty(id, self.typing_env);
1490                let kind = if self.tcx.is_thread_local_static(id) {
1491                    ExprKind::ThreadLocalRef(id)
1492                } else {
1493                    let alloc_id = self.tcx.reserve_and_set_static_alloc(id);
1494                    ExprKind::StaticRef { alloc_id, ty, def_id: id }
1495                };
1496                ExprKind::Deref {
1497                    arg: self.thir.exprs.push(Expr {
1498                        ty,
1499                        temp_scope_id: expr.hir_id.local_id,
1500                        span: expr.span,
1501                        kind,
1502                    }),
1503                }
1504            }
1505
1506            Res::Local(var_hir_id) => self.convert_var(var_hir_id),
1507
1508            _ => ::rustc_span::macros::bug_impl(Some(expr.span),
    format_args!("res `{0:?}` not yet implemented", res), Location::caller())span_bug!(expr.span, "res `{:?}` not yet implemented", res),
1509        }
1510    }
1511
1512    fn convert_var(&mut self, var_hir_id: hir::HirId) -> ExprKind<'tcx> {
1513        // We want upvars here not captures.
1514        // Captures will be handled in MIR.
1515        let is_upvar = self.is_upvar(var_hir_id);
1516
1517        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs:1517",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/1d81eb4ad9cd207e3e638bd32b17ec4fce8412a6/compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1517u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("convert_var({0:?}): is_upvar={1}, body_owner={2:?}",
                                                    var_hir_id, is_upvar, self.body_owner) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
1518            "convert_var({:?}): is_upvar={}, body_owner={:?}",
1519            var_hir_id, is_upvar, self.body_owner
1520        );
1521
1522        if is_upvar {
1523            ExprKind::UpvarRef {
1524                closure_def_id: self.body_owner,
1525                var_hir_id: LocalVarId(var_hir_id),
1526            }
1527        } else {
1528            ExprKind::VarRef { id: LocalVarId(var_hir_id) }
1529        }
1530    }
1531
1532    fn overloaded_operator(
1533        &mut self,
1534        expr: &'tcx hir::Expr<'tcx>,
1535        args: Box<[ExprId]>,
1536    ) -> ExprKind<'tcx> {
1537        let fun = self.method_callee(expr, expr.span, None);
1538        let fun = self.thir.exprs.push(fun);
1539        ExprKind::Call {
1540            ty: self.thir[fun].ty,
1541            fun,
1542            args,
1543            from_hir_call: false,
1544            fn_span: expr.span,
1545        }
1546    }
1547
1548    fn overloaded_place(
1549        &mut self,
1550        expr: &'tcx hir::Expr<'tcx>,
1551        place_ty: Ty<'tcx>,
1552        overloaded_callee: Option<Ty<'tcx>>,
1553        args: Box<[ExprId]>,
1554        span: Span,
1555    ) -> ExprKind<'tcx> {
1556        // For an overloaded *x or x[y] expression of type T, the method
1557        // call returns an &T and we must add the deref so that the types
1558        // line up (this is because `*x` and `x[y]` represent places):
1559
1560        // Reconstruct the output assuming it's a reference with the
1561        // same region and mutability as the receiver. This holds for
1562        // `Deref(Mut)::deref(_mut)` and `Index(Mut)::index(_mut)`.
1563        let ty::Ref(region, _, mutbl) = *self.thir[args[0]].ty.kind() else {
1564            ::rustc_span::macros::bug_impl(Some(span),
    format_args!("overloaded_place: receiver is not a reference"),
    Location::caller());span_bug!(span, "overloaded_place: receiver is not a reference");
1565        };
1566        let ref_ty = Ty::new_ref(self.tcx, region, place_ty, mutbl);
1567
1568        // construct the complete expression `foo()` for the overloaded call,
1569        // which will yield the &T type
1570        let fun = self.method_callee(expr, span, overloaded_callee);
1571        let fun = self.thir.exprs.push(fun);
1572        let fun_ty = self.thir[fun].ty;
1573        let ref_expr = self.thir.exprs.push(Expr {
1574            temp_scope_id: expr.hir_id.local_id,
1575            ty: ref_ty,
1576            span,
1577            kind: ExprKind::Call { ty: fun_ty, fun, args, from_hir_call: false, fn_span: span },
1578        });
1579
1580        // construct and return a deref wrapper `*foo()`
1581        ExprKind::Deref { arg: ref_expr }
1582    }
1583
1584    fn convert_captured_hir_place(
1585        &mut self,
1586        closure_expr: &'tcx hir::Expr<'tcx>,
1587        place: HirPlace<'tcx>,
1588    ) -> Expr<'tcx> {
1589        let temp_scope_id = closure_expr.hir_id.local_id;
1590        let var_ty = place.base_ty;
1591
1592        // The result of capture analysis in `rustc_hir_typeck/src/upvar.rs` represents a captured path
1593        // as it's seen for use within the closure and not at the time of closure creation.
1594        //
1595        // That is we see expect to see it start from a captured upvar and not something that is local
1596        // to the closure's parent.
1597        let var_hir_id = match place.base {
1598            HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
1599            base => ::rustc_span::macros::bug_impl(None,
    format_args!("Expected an upvar, found {0:?}", base), Location::caller())bug!("Expected an upvar, found {:?}", base),
1600        };
1601
1602        let mut captured_place_expr = Expr {
1603            temp_scope_id,
1604            ty: var_ty,
1605            span: closure_expr.span,
1606            kind: self.convert_var(var_hir_id),
1607        };
1608
1609        for proj in place.projections.iter() {
1610            let kind = match proj.kind {
1611                HirProjectionKind::Deref => {
1612                    ExprKind::Deref { arg: self.thir.exprs.push(captured_place_expr) }
1613                }
1614                HirProjectionKind::Field(field, variant_index) => ExprKind::Field {
1615                    lhs: self.thir.exprs.push(captured_place_expr),
1616                    variant_index,
1617                    name: field,
1618                },
1619                HirProjectionKind::OpaqueCast => {
1620                    ExprKind::ValueExpr { source: self.thir.exprs.push(captured_place_expr) }
1621                }
1622                HirProjectionKind::UnwrapUnsafeBinder => ExprKind::PlaceUnwrapUnsafeBinder {
1623                    source: self.thir.exprs.push(captured_place_expr),
1624                },
1625                HirProjectionKind::Index | HirProjectionKind::Subslice => {
1626                    // We don't capture these projections, so we can ignore them here
1627                    continue;
1628                }
1629            };
1630
1631            captured_place_expr =
1632                Expr { temp_scope_id, ty: proj.ty, span: closure_expr.span, kind };
1633        }
1634
1635        captured_place_expr
1636    }
1637
1638    fn capture_upvar(
1639        &mut self,
1640        closure_expr: &'tcx hir::Expr<'tcx>,
1641        captured_place: &'tcx ty::CapturedPlace<'tcx>,
1642        upvar_ty: Ty<'tcx>,
1643    ) -> Expr<'tcx> {
1644        let upvar_capture = captured_place.info.capture_kind;
1645        let captured_place_expr =
1646            self.convert_captured_hir_place(closure_expr, captured_place.place.clone());
1647        let temp_scope_id = closure_expr.hir_id.local_id;
1648
1649        match upvar_capture {
1650            ty::UpvarCapture::ByValue => captured_place_expr,
1651            ty::UpvarCapture::ByUse => {
1652                let span = captured_place_expr.span;
1653                let expr_id = self.thir.exprs.push(captured_place_expr);
1654
1655                Expr {
1656                    temp_scope_id,
1657                    ty: upvar_ty,
1658                    span: closure_expr.span,
1659                    kind: ExprKind::ByUse { expr: expr_id, span },
1660                }
1661            }
1662            ty::UpvarCapture::ByRef(upvar_borrow) => {
1663                let borrow_kind = match upvar_borrow {
1664                    ty::BorrowKind::Immutable => BorrowKind::Shared,
1665                    ty::BorrowKind::UniqueImmutable => {
1666                        BorrowKind::Mut { kind: mir::MutBorrowKind::ClosureCapture }
1667                    }
1668                    ty::BorrowKind::Mutable => {
1669                        BorrowKind::Mut { kind: mir::MutBorrowKind::Default }
1670                    }
1671                };
1672                Expr {
1673                    temp_scope_id,
1674                    ty: upvar_ty,
1675                    span: closure_expr.span,
1676                    kind: ExprKind::Borrow {
1677                        borrow_kind,
1678                        arg: self.thir.exprs.push(captured_place_expr),
1679                    },
1680                }
1681            }
1682        }
1683    }
1684
1685    fn is_upvar(&mut self, var_hir_id: hir::HirId) -> bool {
1686        self.tcx
1687            .upvars_mentioned(self.body_owner)
1688            .is_some_and(|upvars| upvars.contains_key(&var_hir_id))
1689    }
1690
1691    /// Converts a list of named fields (i.e., for struct-like struct/enum ADTs) into FieldExpr.
1692    fn field_refs(&mut self, fields: &'tcx [hir::ExprField<'tcx>]) -> Box<[FieldExpr]> {
1693        fields
1694            .iter()
1695            .map(|field| FieldExpr {
1696                name: self.typeck_results.field_index(field.hir_id),
1697                expr: self.mirror_expr(field.expr),
1698            })
1699            .collect()
1700    }
1701}
1702
1703trait ToBorrowKind {
1704    fn to_borrow_kind(&self) -> BorrowKind;
1705}
1706
1707impl ToBorrowKind for AutoBorrowMutability {
1708    fn to_borrow_kind(&self) -> BorrowKind {
1709        use rustc_middle::ty::adjustment::AllowTwoPhase;
1710        match *self {
1711            AutoBorrowMutability::Mut { allow_two_phase_borrow } => BorrowKind::Mut {
1712                kind: match allow_two_phase_borrow {
1713                    AllowTwoPhase::Yes => mir::MutBorrowKind::TwoPhaseBorrow,
1714                    AllowTwoPhase::No => mir::MutBorrowKind::Default,
1715                },
1716            },
1717            AutoBorrowMutability::Not => BorrowKind::Shared,
1718        }
1719    }
1720}
1721
1722impl ToBorrowKind for hir::Mutability {
1723    fn to_borrow_kind(&self) -> BorrowKind {
1724        match *self {
1725            hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
1726            hir::Mutability::Not => BorrowKind::Shared,
1727        }
1728    }
1729}
1730
1731fn bin_op(op: hir::BinOpKind) -> BinOp {
1732    match op {
1733        hir::BinOpKind::Add => BinOp::Add,
1734        hir::BinOpKind::Sub => BinOp::Sub,
1735        hir::BinOpKind::Mul => BinOp::Mul,
1736        hir::BinOpKind::Div => BinOp::Div,
1737        hir::BinOpKind::Rem => BinOp::Rem,
1738        hir::BinOpKind::BitXor => BinOp::BitXor,
1739        hir::BinOpKind::BitAnd => BinOp::BitAnd,
1740        hir::BinOpKind::BitOr => BinOp::BitOr,
1741        hir::BinOpKind::Shl => BinOp::Shl,
1742        hir::BinOpKind::Shr => BinOp::Shr,
1743        hir::BinOpKind::Eq => BinOp::Eq,
1744        hir::BinOpKind::Lt => BinOp::Lt,
1745        hir::BinOpKind::Le => BinOp::Le,
1746        hir::BinOpKind::Ne => BinOp::Ne,
1747        hir::BinOpKind::Ge => BinOp::Ge,
1748        hir::BinOpKind::Gt => BinOp::Gt,
1749        _ => ::rustc_span::macros::bug_impl(None,
    format_args!("no equivalent for ast binop {0:?}", op), Location::caller())bug!("no equivalent for ast binop {:?}", op),
1750    }
1751}
1752
1753fn assign_op(op: hir::AssignOpKind) -> AssignOp {
1754    match op {
1755        hir::AssignOpKind::AddAssign => AssignOp::AddAssign,
1756        hir::AssignOpKind::SubAssign => AssignOp::SubAssign,
1757        hir::AssignOpKind::MulAssign => AssignOp::MulAssign,
1758        hir::AssignOpKind::DivAssign => AssignOp::DivAssign,
1759        hir::AssignOpKind::RemAssign => AssignOp::RemAssign,
1760        hir::AssignOpKind::BitXorAssign => AssignOp::BitXorAssign,
1761        hir::AssignOpKind::BitAndAssign => AssignOp::BitAndAssign,
1762        hir::AssignOpKind::BitOrAssign => AssignOp::BitOrAssign,
1763        hir::AssignOpKind::ShlAssign => AssignOp::ShlAssign,
1764        hir::AssignOpKind::ShrAssign => AssignOp::ShrAssign,
1765    }
1766}