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_data_structures::stack::ensure_sufficient_stack;
5use rustc_hir as hir;
6use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
7use rustc_hir::{LangItem, find_attr};
8use rustc_index::Idx;
9use rustc_middle::hir::place::{
10    Place as HirPlace, PlaceBase as HirPlaceBase, ProjectionKind as HirProjectionKind,
11};
12use rustc_middle::middle::region;
13use rustc_middle::mir::{self, AssignOp, BinOp, BorrowKind, UnOp};
14use rustc_middle::thir::*;
15use rustc_middle::ty::adjustment::{
16    Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, DerefAdjustKind, PointerCoercion,
17};
18use rustc_middle::ty::{
19    self, AdtKind, GenericArgs, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs,
20};
21use rustc_middle::{bug, span_bug};
22use rustc_span::Span;
23use tracing::{debug, info, instrument, trace};
24
25use crate::errors::*;
26use crate::thir::cx::ThirBuildCx;
27
28impl<'tcx> ThirBuildCx<'tcx> {
29    /// Create a THIR expression for the given HIR expression. This expands all
30    /// adjustments and directly adds the type information from the
31    /// `typeck_results`. See the [dev-guide] for more details.
32    ///
33    /// (The term "mirror" in this case does not refer to "flipped" or
34    /// "reversed".)
35    ///
36    /// [dev-guide]: https://rustc-dev-guide.rust-lang.org/thir.html
37    pub(crate) fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> ExprId {
38        // `mirror_expr` is recursing very deep. Make sure the stack doesn't overflow.
39        ensure_sufficient_stack(|| self.mirror_expr_inner(expr))
40    }
41
42    pub(crate) fn mirror_exprs(&mut self, exprs: &'tcx [hir::Expr<'tcx>]) -> Box<[ExprId]> {
43        // `mirror_exprs` may also recurse deeply, so it needs protection from stack overflow.
44        // Note that we *could* forward to `mirror_expr` for that, but we can consolidate the
45        // overhead of stack growth by doing it outside the iteration.
46        ensure_sufficient_stack(|| exprs.iter().map(|expr| self.mirror_expr_inner(expr)).collect())
47    }
48
49    #[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_inner",
                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                    ::tracing_core::__macro_support::Option::Some(49u32),
                                    ::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(&[]) })
                } 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 compiler/rustc_mir_build/src/thir/cx/expr.rs:54",
                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                    ::tracing_core::__macro_support::Option::Some(54u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                    ::tracing_core::field::FieldSet::new(&["hir_expr.hir_id",
                                                    "hir_expr.span"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&hir_expr.hir_id)
                                                        as &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&hir_expr.span)
                                                        as &dyn 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 compiler/rustc_mir_build/src/thir/cx/expr.rs:58",
                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                    ::tracing_core::__macro_support::Option::Some(58u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                    ::tracing_core::field::FieldSet::new(&["expr.ty"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&expr.ty) as
                                                        &dyn Value))])
                        });
                } else { ; }
            };
            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 compiler/rustc_mir_build/src/thir/cx/expr.rs:63",
                                            "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                            ::tracing_core::__macro_support::Option::Some(63u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                            ::tracing_core::field::FieldSet::new(&["expr",
                                                            "adjustment"],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::EVENT)
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let enabled =
                            ::tracing::Level::TRACE <=
                                        ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                    ::tracing::Level::TRACE <=
                                        ::tracing::level_filters::LevelFilter::current() &&
                                {
                                    let interest = __CALLSITE.interest();
                                    !interest.is_never() &&
                                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                            interest)
                                };
                        if enabled {
                            (|value_set: ::tracing::field::ValueSet|
                                        {
                                            let meta = __CALLSITE.metadata();
                                            ::tracing::Event::dispatch(meta, &value_set);
                                            ;
                                        })({
                                    #[allow(unused_imports)]
                                    use ::tracing::field::{debug, display, Value};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&debug(&expr) as
                                                                &dyn Value)),
                                                    (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&debug(&adjustment)
                                                                as &dyn 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 compiler/rustc_mir_build/src/thir/cx/expr.rs:69",
                                    "rustc_mir_build::thir::cx::expr", ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                    ::tracing_core::__macro_support::Option::Some(69u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                    ::tracing_core::field::FieldSet::new(&["message",
                                                    "expr.ty"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&format_args!("after adjustments")
                                                        as &dyn Value)),
                                            (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&expr.ty) as
                                                        &dyn Value))])
                        });
                } else { ; }
            };
            expr =
                Expr {
                    temp_scope_id: expr_scope.local_id,
                    ty: expr.ty,
                    span: hir_expr.span,
                    kind: ExprKind::Scope {
                        region_scope: expr_scope,
                        value: self.thir.exprs.push(expr),
                        hir_id: hir_expr.hir_id,
                    },
                };
            self.thir.exprs.push(expr)
        }
    }
}#[instrument(level = "trace", skip(self, hir_expr))]
50    pub(super) fn mirror_expr_inner(&mut self, hir_expr: &'tcx hir::Expr<'tcx>) -> ExprId {
51        let expr_scope =
52            region::Scope { local_id: hir_expr.hir_id.local_id, data: region::ScopeData::Node };
53
54        trace!(?hir_expr.hir_id, ?hir_expr.span);
55
56        let mut expr = self.make_mirror_unadjusted(hir_expr);
57
58        trace!(?expr.ty);
59
60        // Now apply adjustments, if any.
61        if self.apply_adjustments {
62            for adjustment in self.typeck_results.expr_adjustments(hir_expr) {
63                trace!(?expr, ?adjustment);
64                let span = expr.span;
65                expr = self.apply_adjustment(hir_expr, expr, adjustment, span);
66            }
67        }
68
69        trace!(?expr.ty, "after adjustments");
70
71        // Finally, wrap this up in the expr's scope.
72        expr = Expr {
73            temp_scope_id: expr_scope.local_id,
74            ty: expr.ty,
75            span: hir_expr.span,
76            kind: ExprKind::Scope {
77                region_scope: expr_scope,
78                value: self.thir.exprs.push(expr),
79                hir_id: hir_expr.hir_id,
80            },
81        };
82
83        // OK, all done!
84        self.thir.exprs.push(expr)
85    }
86
87    #[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("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                    ::tracing_core::__macro_support::Option::Some(87u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                    ::tracing_core::field::FieldSet::new(&["hir_expr",
                                                    "adjustment"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hir_expr)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&adjustment)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: 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::Overloaded(deref)) => {
                        let call_def_id = deref.method_call(self.tcx);
                        let overloaded_callee =
                            Ty::new_fn_def(self.tcx, call_def_id,
                                self.tcx.mk_args(&[expr.ty.into()]));
                        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::ReborrowPin(mutbl) => {
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/thir/cx/expr.rs:181",
                                                "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                                ::tracing_core::__macro_support::Option::Some(181u32),
                                                ::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};
                                        let mut iter = __CALLSITE.metadata().fields().iter();
                                        __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&format_args!("apply ReborrowPin adjustment")
                                                                    as &dyn Value))])
                                    });
                            } else { ; }
                        };
                        let pin_ty_args =
                            match expr.ty.kind() {
                                ty::Adt(_, args) => args,
                                _ =>
                                    ::rustc_middle::util::bug::bug_fmt(format_args!("ReborrowPin with non-Pin type")),
                            };
                        let pin_ty = pin_ty_args.iter().next().unwrap().expect_ty();
                        let ptr_target_ty =
                            match pin_ty.kind() {
                                ty::Ref(_, ty, _) => *ty,
                                _ =>
                                    ::rustc_middle::util::bug::bug_fmt(format_args!("ReborrowPin with non-Ref type")),
                            };
                        let pointer_target =
                            ExprKind::Field {
                                lhs: self.thir.exprs.push(expr),
                                variant_index: FIRST_VARIANT,
                                name: FieldIdx::ZERO,
                            };
                        let arg =
                            Expr {
                                temp_scope_id,
                                ty: pin_ty,
                                span,
                                kind: pointer_target,
                            };
                        let arg = self.thir.exprs.push(arg);
                        let expr = ExprKind::Deref { arg };
                        let arg =
                            self.thir.exprs.push(Expr {
                                    temp_scope_id,
                                    ty: ptr_target_ty,
                                    span,
                                    kind: expr,
                                });
                        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,
                                ptr_target_ty, mutbl);
                        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(rustc_hir::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 compiler/rustc_mir_build/src/thir/cx/expr.rs:239",
                                                "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                                                ::tracing_core::__macro_support::Option::Some(239u32),
                                                ::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::cx::expr"),
                                                ::tracing_core::field::FieldSet::new(&["kind"],
                                                    ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                                ::tracing::metadata::Kind::EVENT)
                                        };
                                    ::tracing::callsite::DefaultCallsite::new(&META)
                                };
                            let enabled =
                                ::tracing::Level::DEBUG <=
                                            ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                        ::tracing::Level::DEBUG <=
                                            ::tracing::level_filters::LevelFilter::current() &&
                                    {
                                        let interest = __CALLSITE.interest();
                                        !interest.is_never() &&
                                            ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                                interest)
                                    };
                            if enabled {
                                (|value_set: ::tracing::field::ValueSet|
                                            {
                                                let meta = __CALLSITE.metadata();
                                                ::tracing::Event::dispatch(meta, &value_set);
                                                ;
                                            })({
                                        #[allow(unused_imports)]
                                        use ::tracing::field::{debug, display, Value};
                                        let mut iter = __CALLSITE.metadata().fields().iter();
                                        __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&debug(&kind) as
                                                                    &dyn Value))])
                                    });
                            } else { ; }
                        };
                        kind
                    }
                };
            Expr { temp_scope_id, ty: adjustment.target, span, kind }
        }
    }
}#[instrument(level = "trace", skip(self, expr, span))]
88    fn apply_adjustment(
89        &mut self,
90        hir_expr: &'tcx hir::Expr<'tcx>,
91        mut expr: Expr<'tcx>,
92        adjustment: &Adjustment<'tcx>,
93        mut span: Span,
94    ) -> Expr<'tcx> {
95        let Expr { temp_scope_id, .. } = expr;
96
97        // Adjust the span from the block, to the last expression of the
98        // block. This is a better span when returning a mutable reference
99        // with too short a lifetime. The error message will use the span
100        // from the assignment to the return place, which should only point
101        // at the returned value, not the entire function body.
102        //
103        // fn return_short_lived<'a>(x: &'a mut i32) -> &'static mut i32 {
104        //      x
105        //   // ^ error message points at this expression.
106        // }
107        let mut adjust_span = |expr: &mut Expr<'tcx>| {
108            if let ExprKind::Block { block } = expr.kind
109                && let Some(last_expr) = self.thir[block].expr
110            {
111                span = self.thir[last_expr].span;
112                expr.span = span;
113            }
114        };
115
116        let kind = match adjustment.kind {
117            Adjust::Pointer(cast) => {
118                if cast == PointerCoercion::Unsize {
119                    adjust_span(&mut expr);
120                }
121
122                let is_from_as_cast = if let hir::Node::Expr(hir::Expr {
123                    kind: hir::ExprKind::Cast(..),
124                    span: cast_span,
125                    ..
126                }) = self.tcx.parent_hir_node(hir_expr.hir_id)
127                {
128                    // Use the whole span of the `x as T` expression for the coercion.
129                    span = *cast_span;
130                    true
131                } else {
132                    false
133                };
134                ExprKind::PointerCoercion {
135                    cast,
136                    source: self.thir.exprs.push(expr),
137                    is_from_as_cast,
138                }
139            }
140            Adjust::NeverToAny if adjustment.target.is_never() => return expr,
141            Adjust::NeverToAny => ExprKind::NeverToAny { source: self.thir.exprs.push(expr) },
142            Adjust::Deref(DerefAdjustKind::Builtin) => {
143                adjust_span(&mut expr);
144                ExprKind::Deref { arg: self.thir.exprs.push(expr) }
145            }
146            Adjust::Deref(DerefAdjustKind::Overloaded(deref)) => {
147                // We don't need to do call adjust_span here since
148                // deref coercions always start with a built-in deref.
149                let call_def_id = deref.method_call(self.tcx);
150                let overloaded_callee =
151                    Ty::new_fn_def(self.tcx, call_def_id, self.tcx.mk_args(&[expr.ty.into()]));
152
153                expr = Expr {
154                    temp_scope_id,
155                    ty: Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, deref.mutbl),
156                    span,
157                    kind: ExprKind::Borrow {
158                        borrow_kind: deref.mutbl.to_borrow_kind(),
159                        arg: self.thir.exprs.push(expr),
160                    },
161                };
162
163                let expr = Box::new([self.thir.exprs.push(expr)]);
164
165                self.overloaded_place(
166                    hir_expr,
167                    adjustment.target,
168                    Some(overloaded_callee),
169                    expr,
170                    deref.span,
171                )
172            }
173            Adjust::Borrow(AutoBorrow::Ref(m)) => ExprKind::Borrow {
174                borrow_kind: m.to_borrow_kind(),
175                arg: self.thir.exprs.push(expr),
176            },
177            Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
178                ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
179            }
180            Adjust::ReborrowPin(mutbl) => {
181                debug!("apply ReborrowPin adjustment");
182                // Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }`
183
184                // We'll need these types later on
185                let pin_ty_args = match expr.ty.kind() {
186                    ty::Adt(_, args) => args,
187                    _ => bug!("ReborrowPin with non-Pin type"),
188                };
189                let pin_ty = pin_ty_args.iter().next().unwrap().expect_ty();
190                let ptr_target_ty = match pin_ty.kind() {
191                    ty::Ref(_, ty, _) => *ty,
192                    _ => bug!("ReborrowPin with non-Ref type"),
193                };
194
195                // pointer = ($expr).__pointer
196                let pointer_target = ExprKind::Field {
197                    lhs: self.thir.exprs.push(expr),
198                    variant_index: FIRST_VARIANT,
199                    name: FieldIdx::ZERO,
200                };
201                let arg = Expr { temp_scope_id, ty: pin_ty, span, kind: pointer_target };
202                let arg = self.thir.exprs.push(arg);
203
204                // arg = *pointer
205                let expr = ExprKind::Deref { arg };
206                let arg = self.thir.exprs.push(Expr {
207                    temp_scope_id,
208                    ty: ptr_target_ty,
209                    span,
210                    kind: expr,
211                });
212
213                // expr = &mut target
214                let borrow_kind = match mutbl {
215                    hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
216                    hir::Mutability::Not => BorrowKind::Shared,
217                };
218                let new_pin_target =
219                    Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, ptr_target_ty, mutbl);
220                let expr = self.thir.exprs.push(Expr {
221                    temp_scope_id,
222                    ty: new_pin_target,
223                    span,
224                    kind: ExprKind::Borrow { borrow_kind, arg },
225                });
226
227                // kind = Pin { __pointer: pointer }
228                let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, span);
229                let args = self.tcx.mk_args(&[new_pin_target.into()]);
230                let kind = ExprKind::Adt(Box::new(AdtExpr {
231                    adt_def: self.tcx.adt_def(pin_did),
232                    variant_index: FIRST_VARIANT,
233                    args,
234                    fields: Box::new([FieldExpr { name: FieldIdx::ZERO, expr }]),
235                    user_ty: None,
236                    base: AdtExprBase::None,
237                }));
238
239                debug!(?kind);
240                kind
241            }
242        };
243
244        Expr { temp_scope_id, ty: adjustment.target, span, kind }
245    }
246
247    /// Lowers a cast expression.
248    ///
249    /// Dealing with user type annotations is left to the caller.
250    fn mirror_expr_cast(
251        &mut self,
252        source: &'tcx hir::Expr<'tcx>,
253        temp_scope_id: hir::ItemLocalId,
254        span: Span,
255    ) -> ExprKind<'tcx> {
256        let tcx = self.tcx;
257
258        // Check to see if this cast is a "coercion cast", where the cast is actually done
259        // using a coercion (or is a no-op).
260        if self.typeck_results.is_coercion_cast(source.hir_id) {
261            // Convert the lexpr to a vexpr.
262            ExprKind::Use { source: self.mirror_expr(source) }
263        } else if self.typeck_results.expr_ty(source).is_ref() {
264            // Special cased so that we can type check that the element
265            // type of the source matches the pointed to type of the
266            // destination.
267            ExprKind::PointerCoercion {
268                source: self.mirror_expr(source),
269                cast: PointerCoercion::ArrayToPointer,
270                is_from_as_cast: true,
271            }
272        } else if let hir::ExprKind::Path(ref qpath) = source.kind
273            && let res = self.typeck_results.qpath_res(qpath, source.hir_id)
274            && let ty = self.typeck_results.node_type(source.hir_id)
275            && let ty::Adt(adt_def, args) = ty.kind()
276            && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
277        {
278            // Check whether this is casting an enum variant discriminant.
279            // To prevent cycles, we refer to the discriminant initializer,
280            // which is always an integer and thus doesn't need to know the
281            // enum's layout (or its tag type) to compute it during const eval.
282            // Example:
283            // enum Foo {
284            //     A,
285            //     B = A as isize + 4,
286            // }
287            // The correct solution would be to add symbolic computations to miri,
288            // so we wouldn't have to compute and store the actual value
289
290            let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
291            let (discr_did, discr_offset) = adt_def.discriminant_def_for_variant(idx);
292
293            use rustc_middle::ty::util::IntTypeExt;
294            let ty = adt_def.repr().discr_type();
295            let discr_ty = ty.to_ty(tcx);
296
297            let size = tcx
298                .layout_of(self.typing_env.as_query_input(discr_ty))
299                .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:?}"))
300                .size;
301
302            let (lit, overflowing) = ScalarInt::truncate_from_uint(discr_offset as u128, size);
303            if overflowing {
304                // An erroneous enum with too many variants for its repr will emit E0081 and E0370
305                self.tcx.dcx().span_delayed_bug(
306                    source.span,
307                    "overflowing enum wasn't rejected by hir analysis",
308                );
309            }
310            let kind = ExprKind::NonHirLiteral { lit, user_ty: None };
311            let offset = self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind });
312
313            let source = match discr_did {
314                // in case we are offsetting from a computed discriminant
315                // and not the beginning of discriminants (which is always `0`)
316                Some(did) => {
317                    let kind = ExprKind::NamedConst { def_id: did, args, user_ty: None };
318                    let lhs =
319                        self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind });
320                    let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset };
321                    self.thir.exprs.push(Expr { temp_scope_id, ty: discr_ty, span, kind: bin })
322                }
323                None => offset,
324            };
325
326            ExprKind::Cast { source }
327        } else {
328            // Default to `ExprKind::Cast` for all explicit casts.
329            // MIR building then picks the right MIR casts based on the types.
330            ExprKind::Cast { source: self.mirror_expr(source) }
331        }
332    }
333
334    x;#[instrument(level = "debug", skip(self), ret)]
335    fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
336        let tcx = self.tcx;
337        let expr_ty = self.typeck_results.expr_ty(expr);
338        let mk_expr =
339            |kind, ty| Expr { temp_scope_id: expr.hir_id.local_id, span: expr.span, ty, kind };
340
341        let kind = match expr.kind {
342            // Here comes the interesting stuff:
343            hir::ExprKind::MethodCall(segment, receiver, args, fn_span) => {
344                // Rewrite a.b(c) into UFCS form like Trait::b(a, c)
345                let expr = self.method_callee(expr, segment.ident.span, None);
346                info!("Using method span: {:?}", expr.span);
347                let args = std::iter::once(receiver)
348                    .chain(args.iter())
349                    .map(|expr| self.mirror_expr(expr))
350                    .collect();
351                ExprKind::Call {
352                    ty: expr.ty,
353                    fun: self.thir.exprs.push(expr),
354                    args,
355                    from_hir_call: true,
356                    fn_span,
357                }
358            }
359
360            hir::ExprKind::Call(fun, ref args) => {
361                if self.typeck_results.is_method_call(expr) {
362                    // The callee is something implementing Fn, FnMut, or FnOnce.
363                    // Find the actual method implementation being called and
364                    // build the appropriate UFCS call expression with the
365                    // callee-object as expr parameter.
366
367                    // rewrite f(u, v) into FnOnce::call_once(f, (u, v))
368
369                    let method = self.method_callee(expr, fun.span, None);
370
371                    let arg_tys = args.iter().map(|e| self.typeck_results.expr_ty_adjusted(e));
372                    let tupled_args = Expr {
373                        ty: Ty::new_tup_from_iter(tcx, arg_tys),
374                        temp_scope_id: expr.hir_id.local_id,
375                        span: expr.span,
376                        kind: ExprKind::Tuple { fields: self.mirror_exprs(args) },
377                    };
378                    let tupled_args = self.thir.exprs.push(tupled_args);
379
380                    ExprKind::Call {
381                        ty: method.ty,
382                        fun: self.thir.exprs.push(method),
383                        args: Box::new([self.mirror_expr(fun), tupled_args]),
384                        from_hir_call: true,
385                        fn_span: expr.span,
386                    }
387                } else {
388                    // Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
389                    let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
390                        && let Some(adt_def) = expr_ty.ty_adt_def()
391                    {
392                        match qpath {
393                            hir::QPath::Resolved(_, path) => match path.res {
394                                Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => {
395                                    Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
396                                }
397                                Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)),
398                                _ => None,
399                            },
400                            hir::QPath::TypeRelative(_ty, _) => {
401                                if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
402                                    self.typeck_results.type_dependent_def(fun.hir_id)
403                                {
404                                    Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
405                                } else {
406                                    None
407                                }
408                            }
409                        }
410                    } else {
411                        None
412                    };
413                    if let Some((adt_def, index)) = adt_data {
414                        let node_args = self.typeck_results.node_args(fun.hir_id);
415                        let user_provided_types = self.typeck_results.user_provided_types();
416                        let user_ty =
417                            user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
418                                if let ty::UserTypeKind::TypeOf(did, _) = &mut u_ty.value.kind {
419                                    *did = adt_def.did();
420                                }
421                                Box::new(u_ty)
422                            });
423                        debug!("make_mirror_unadjusted: (call) user_ty={:?}", user_ty);
424
425                        let field_refs = args
426                            .iter()
427                            .enumerate()
428                            .map(|(idx, e)| FieldExpr {
429                                name: FieldIdx::new(idx),
430                                expr: self.mirror_expr(e),
431                            })
432                            .collect();
433                        ExprKind::Adt(Box::new(AdtExpr {
434                            adt_def,
435                            args: node_args,
436                            variant_index: index,
437                            fields: field_refs,
438                            user_ty,
439                            base: AdtExprBase::None,
440                        }))
441                    } else {
442                        ExprKind::Call {
443                            ty: self.typeck_results.node_type(fun.hir_id),
444                            fun: self.mirror_expr(fun),
445                            args: self.mirror_exprs(args),
446                            from_hir_call: true,
447                            fn_span: expr.span,
448                        }
449                    }
450                }
451            }
452
453            hir::ExprKind::Use(expr, span) => {
454                ExprKind::ByUse { expr: self.mirror_expr(expr), span }
455            }
456
457            hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, arg) => {
458                ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg: self.mirror_expr(arg) }
459            }
460
461            hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutability, arg) => {
462                ExprKind::RawBorrow { mutability, arg: self.mirror_expr(arg) }
463            }
464
465            // Make `&pin mut $expr` and `&pin const $expr` into
466            // `Pin { __pointer: &mut { $expr } }` and `Pin { __pointer: &$expr }`.
467            hir::ExprKind::AddrOf(hir::BorrowKind::Pin, mutbl, arg_expr) => match expr_ty.kind() {
468                &ty::Adt(adt_def, args) if tcx.is_lang_item(adt_def.did(), hir::LangItem::Pin) => {
469                    let ty = args.type_at(0);
470                    let arg_ty = self.typeck_results.expr_ty(arg_expr);
471                    let mut arg = self.mirror_expr(arg_expr);
472                    // For `&pin mut $place` where `$place` is not `Unpin`, move the place
473                    // `$place` to ensure it will not be used afterwards.
474                    if mutbl.is_mut() && !arg_ty.is_unpin(self.tcx, self.typing_env) {
475                        let block = self.thir.blocks.push(Block {
476                            targeted_by_break: false,
477                            region_scope: region::Scope {
478                                local_id: arg_expr.hir_id.local_id,
479                                data: region::ScopeData::Node,
480                            },
481                            span: arg_expr.span,
482                            stmts: Box::new([]),
483                            expr: Some(arg),
484                            safety_mode: BlockSafety::Safe,
485                        });
486                        arg = self.thir.exprs.push(Expr {
487                            temp_scope_id: arg_expr.hir_id.local_id,
488                            ty: arg_ty,
489                            span: arg_expr.span,
490                            kind: ExprKind::Block { block },
491                        });
492                    }
493                    let expr = self.thir.exprs.push(Expr {
494                        temp_scope_id: expr.hir_id.local_id,
495                        ty,
496                        span: expr.span,
497                        kind: ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg },
498                    });
499                    ExprKind::Adt(Box::new(AdtExpr {
500                        adt_def,
501                        variant_index: FIRST_VARIANT,
502                        args,
503                        fields: Box::new([FieldExpr { name: FieldIdx::from(0u32), expr }]),
504                        user_ty: None,
505                        base: AdtExprBase::None,
506                    }))
507                }
508                _ => span_bug!(expr.span, "unexpected type for pinned borrow: {:?}", expr_ty),
509            },
510
511            hir::ExprKind::Block(blk, _) => ExprKind::Block { block: self.mirror_block(blk) },
512
513            hir::ExprKind::Assign(lhs, rhs, _) => {
514                ExprKind::Assign { lhs: self.mirror_expr(lhs), rhs: self.mirror_expr(rhs) }
515            }
516
517            hir::ExprKind::AssignOp(op, lhs, rhs) => {
518                if self.typeck_results.is_method_call(expr) {
519                    let lhs = self.mirror_expr(lhs);
520                    let rhs = self.mirror_expr(rhs);
521                    self.overloaded_operator(expr, Box::new([lhs, rhs]))
522                } else {
523                    ExprKind::AssignOp {
524                        op: assign_op(op.node),
525                        lhs: self.mirror_expr(lhs),
526                        rhs: self.mirror_expr(rhs),
527                    }
528                }
529            }
530
531            hir::ExprKind::Lit(lit) => ExprKind::Literal { lit, neg: false },
532
533            hir::ExprKind::Binary(op, lhs, rhs) => {
534                if self.typeck_results.is_method_call(expr) {
535                    let lhs = self.mirror_expr(lhs);
536                    let rhs = self.mirror_expr(rhs);
537                    self.overloaded_operator(expr, Box::new([lhs, rhs]))
538                } else {
539                    match op.node {
540                        hir::BinOpKind::And => ExprKind::LogicalOp {
541                            op: LogicalOp::And,
542                            lhs: self.mirror_expr(lhs),
543                            rhs: self.mirror_expr(rhs),
544                        },
545                        hir::BinOpKind::Or => ExprKind::LogicalOp {
546                            op: LogicalOp::Or,
547                            lhs: self.mirror_expr(lhs),
548                            rhs: self.mirror_expr(rhs),
549                        },
550                        _ => {
551                            let op = bin_op(op.node);
552                            ExprKind::Binary {
553                                op,
554                                lhs: self.mirror_expr(lhs),
555                                rhs: self.mirror_expr(rhs),
556                            }
557                        }
558                    }
559                }
560            }
561
562            hir::ExprKind::Index(lhs, index, brackets_span) => {
563                if self.typeck_results.is_method_call(expr) {
564                    let lhs = self.mirror_expr(lhs);
565                    let index = self.mirror_expr(index);
566                    self.overloaded_place(
567                        expr,
568                        expr_ty,
569                        None,
570                        Box::new([lhs, index]),
571                        brackets_span,
572                    )
573                } else {
574                    ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) }
575                }
576            }
577
578            hir::ExprKind::Unary(hir::UnOp::Deref, arg) => {
579                if self.typeck_results.is_method_call(expr) {
580                    let arg = self.mirror_expr(arg);
581                    self.overloaded_place(expr, expr_ty, None, Box::new([arg]), expr.span)
582                } else {
583                    ExprKind::Deref { arg: self.mirror_expr(arg) }
584                }
585            }
586
587            hir::ExprKind::Unary(hir::UnOp::Not, arg) => {
588                if self.typeck_results.is_method_call(expr) {
589                    let arg = self.mirror_expr(arg);
590                    self.overloaded_operator(expr, Box::new([arg]))
591                } else {
592                    ExprKind::Unary { op: UnOp::Not, arg: self.mirror_expr(arg) }
593                }
594            }
595
596            hir::ExprKind::Unary(hir::UnOp::Neg, arg) => {
597                if self.typeck_results.is_method_call(expr) {
598                    let arg = self.mirror_expr(arg);
599                    self.overloaded_operator(expr, Box::new([arg]))
600                } else if let hir::ExprKind::Lit(lit) = arg.kind {
601                    ExprKind::Literal { lit, neg: true }
602                } else {
603                    ExprKind::Unary { op: UnOp::Neg, arg: self.mirror_expr(arg) }
604                }
605            }
606
607            hir::ExprKind::Struct(qpath, fields, ref base) => match expr_ty.kind() {
608                ty::Adt(adt, args) => match adt.adt_kind() {
609                    AdtKind::Struct | AdtKind::Union => {
610                        let user_provided_types = self.typeck_results.user_provided_types();
611                        let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
612                        debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
613                        ExprKind::Adt(Box::new(AdtExpr {
614                            adt_def: *adt,
615                            variant_index: FIRST_VARIANT,
616                            args,
617                            user_ty,
618                            fields: self.field_refs(fields),
619                            base: match base {
620                                hir::StructTailExpr::Base(base) => AdtExprBase::Base(FruInfo {
621                                    base: self.mirror_expr(base),
622                                    field_types: self.typeck_results.fru_field_types()[expr.hir_id]
623                                        .iter()
624                                        .copied()
625                                        .collect(),
626                                }),
627                                hir::StructTailExpr::DefaultFields(_) => {
628                                    AdtExprBase::DefaultFields(
629                                        self.typeck_results.fru_field_types()[expr.hir_id]
630                                            .iter()
631                                            .copied()
632                                            .collect(),
633                                    )
634                                }
635                                hir::StructTailExpr::None => AdtExprBase::None,
636                            },
637                        }))
638                    }
639                    AdtKind::Enum => {
640                        let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
641                        match res {
642                            Res::Def(DefKind::Variant, variant_id) => {
643                                assert!(matches!(
644                                    base,
645                                    hir::StructTailExpr::None
646                                        | hir::StructTailExpr::DefaultFields(_)
647                                ));
648
649                                let index = adt.variant_index_with_id(variant_id);
650                                let user_provided_types = self.typeck_results.user_provided_types();
651                                let user_ty =
652                                    user_provided_types.get(expr.hir_id).copied().map(Box::new);
653                                debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
654                                ExprKind::Adt(Box::new(AdtExpr {
655                                    adt_def: *adt,
656                                    variant_index: index,
657                                    args,
658                                    user_ty,
659                                    fields: self.field_refs(fields),
660                                    base: match base {
661                                        hir::StructTailExpr::DefaultFields(_) => {
662                                            AdtExprBase::DefaultFields(
663                                                self.typeck_results.fru_field_types()[expr.hir_id]
664                                                    .iter()
665                                                    .copied()
666                                                    .collect(),
667                                            )
668                                        }
669                                        hir::StructTailExpr::Base(base) => {
670                                            span_bug!(base.span, "unexpected res: {:?}", res);
671                                        }
672                                        hir::StructTailExpr::None => AdtExprBase::None,
673                                    },
674                                }))
675                            }
676                            _ => {
677                                span_bug!(expr.span, "unexpected res: {:?}", res);
678                            }
679                        }
680                    }
681                },
682                _ => {
683                    span_bug!(expr.span, "unexpected type for struct literal: {:?}", expr_ty);
684                }
685            },
686
687            hir::ExprKind::Closure(hir::Closure { .. }) => {
688                let closure_ty = self.typeck_results.expr_ty(expr);
689                let (def_id, args, movability) = match *closure_ty.kind() {
690                    ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args), None),
691                    ty::Coroutine(def_id, args) => {
692                        (def_id, UpvarArgs::Coroutine(args), Some(tcx.coroutine_movability(def_id)))
693                    }
694                    ty::CoroutineClosure(def_id, args) => {
695                        (def_id, UpvarArgs::CoroutineClosure(args), None)
696                    }
697                    _ => {
698                        span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty);
699                    }
700                };
701                let def_id = def_id.expect_local();
702
703                let upvars = self
704                    .tcx
705                    .closure_captures(def_id)
706                    .iter()
707                    .zip_eq(args.upvar_tys())
708                    .map(|(captured_place, ty)| {
709                        let upvars = self.capture_upvar(expr, captured_place, ty);
710                        self.thir.exprs.push(upvars)
711                    })
712                    .collect();
713
714                // Convert the closure fake reads, if any, from hir `Place` to ExprRef
715                let fake_reads = match self.typeck_results.closure_fake_reads.get(&def_id) {
716                    Some(fake_reads) => fake_reads
717                        .iter()
718                        .map(|(place, cause, hir_id)| {
719                            let expr = self.convert_captured_hir_place(expr, place.clone());
720                            (self.thir.exprs.push(expr), *cause, *hir_id)
721                        })
722                        .collect(),
723                    None => Vec::new(),
724                };
725
726                ExprKind::Closure(Box::new(ClosureExpr {
727                    closure_id: def_id,
728                    args,
729                    upvars,
730                    movability,
731                    fake_reads,
732                }))
733            }
734
735            hir::ExprKind::Path(ref qpath) => {
736                let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
737                self.convert_path_expr(expr, res)
738            }
739
740            hir::ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
741                asm_macro: asm.asm_macro,
742                template: asm.template,
743                operands: asm
744                    .operands
745                    .iter()
746                    .map(|(op, _op_sp)| match *op {
747                        hir::InlineAsmOperand::In { reg, expr } => {
748                            InlineAsmOperand::In { reg, expr: self.mirror_expr(expr) }
749                        }
750                        hir::InlineAsmOperand::Out { reg, late, ref expr } => {
751                            InlineAsmOperand::Out {
752                                reg,
753                                late,
754                                expr: expr.map(|expr| self.mirror_expr(expr)),
755                            }
756                        }
757                        hir::InlineAsmOperand::InOut { reg, late, expr } => {
758                            InlineAsmOperand::InOut { reg, late, expr: self.mirror_expr(expr) }
759                        }
760                        hir::InlineAsmOperand::SplitInOut { reg, late, in_expr, ref out_expr } => {
761                            InlineAsmOperand::SplitInOut {
762                                reg,
763                                late,
764                                in_expr: self.mirror_expr(in_expr),
765                                out_expr: out_expr.map(|expr| self.mirror_expr(expr)),
766                            }
767                        }
768                        hir::InlineAsmOperand::Const { ref anon_const } => {
769                            let ty = self.typeck_results.node_type(anon_const.hir_id);
770                            let did = anon_const.def_id.to_def_id();
771                            let typeck_root_def_id = tcx.typeck_root_def_id(did);
772                            let parent_args = tcx.erase_and_anonymize_regions(
773                                GenericArgs::identity_for_item(tcx, typeck_root_def_id),
774                            );
775                            let args =
776                                InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty })
777                                    .args;
778
779                            let uneval = mir::UnevaluatedConst::new(did, args);
780                            let value = mir::Const::Unevaluated(uneval, ty);
781                            InlineAsmOperand::Const { value, span: tcx.def_span(did) }
782                        }
783                        hir::InlineAsmOperand::SymFn { expr } => {
784                            InlineAsmOperand::SymFn { value: self.mirror_expr(expr) }
785                        }
786                        hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
787                            InlineAsmOperand::SymStatic { def_id }
788                        }
789                        hir::InlineAsmOperand::Label { block } => {
790                            InlineAsmOperand::Label { block: self.mirror_block(block) }
791                        }
792                    })
793                    .collect(),
794                options: asm.options,
795                line_spans: asm.line_spans,
796            })),
797
798            hir::ExprKind::OffsetOf(_, _) => {
799                let offset_of_intrinsic = tcx.require_lang_item(LangItem::OffsetOf, expr.span);
800                let mk_u32_kind = |val: u32| ExprKind::NonHirLiteral {
801                    lit: ScalarInt::try_from_uint(val, Size::from_bits(32)).unwrap(),
802                    user_ty: None,
803                };
804                let mk_call =
805                    |thir: &mut Thir<'tcx>, ty: Ty<'tcx>, variant: VariantIdx, field: FieldIdx| {
806                        let fun_ty =
807                            Ty::new_fn_def(tcx, offset_of_intrinsic, [ty::GenericArg::from(ty)]);
808                        let fun = thir
809                            .exprs
810                            .push(mk_expr(ExprKind::ZstLiteral { user_ty: None }, fun_ty));
811                        let variant =
812                            thir.exprs.push(mk_expr(mk_u32_kind(variant.as_u32()), tcx.types.u32));
813                        let field =
814                            thir.exprs.push(mk_expr(mk_u32_kind(field.as_u32()), tcx.types.u32));
815                        let args = Box::new([variant, field]);
816                        ExprKind::Call {
817                            ty: fun_ty,
818                            fun,
819                            args,
820                            from_hir_call: false,
821                            fn_span: expr.span,
822                        }
823                    };
824
825                let indices = self.typeck_results.offset_of_data().get(expr.hir_id).unwrap();
826                let mut expr = None::<ExprKind<'tcx>>;
827
828                for &(container, variant, field) in indices.iter() {
829                    let next = mk_call(&mut self.thir, container, variant, field);
830                    expr = Some(match expr.take() {
831                        None => next,
832                        Some(last) => {
833                            let last = self.thir.exprs.push(mk_expr(last, tcx.types.usize));
834                            let next = self.thir.exprs.push(mk_expr(next, tcx.types.usize));
835                            ExprKind::Binary { op: BinOp::Add, lhs: last, rhs: next }
836                        }
837                    });
838                }
839
840                expr.unwrap_or(mk_u32_kind(0))
841            }
842
843            hir::ExprKind::ConstBlock(ref anon_const) => {
844                let ty = self.typeck_results.node_type(anon_const.hir_id);
845                let did = anon_const.def_id.to_def_id();
846                let typeck_root_def_id = tcx.typeck_root_def_id(did);
847                let parent_args = tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(
848                    tcx,
849                    typeck_root_def_id,
850                ));
851                let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }).args;
852
853                ExprKind::ConstBlock { did, args }
854            }
855            // Now comes the rote stuff:
856            hir::ExprKind::Repeat(v, _) => {
857                let ty = self.typeck_results.expr_ty(expr);
858                let ty::Array(_, count) = ty.kind() else {
859                    span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty);
860                };
861
862                ExprKind::Repeat { value: self.mirror_expr(v), count: *count }
863            }
864            hir::ExprKind::Ret(v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
865            hir::ExprKind::Become(call) => ExprKind::Become { value: self.mirror_expr(call) },
866            hir::ExprKind::Break(dest, ref value) => {
867                if find_attr!(self.tcx.hir_attrs(expr.hir_id), ConstContinue(_)) {
868                    match dest.target_id {
869                        Ok(target_id) => {
870                            let (Some(value), Some(_)) = (value, dest.label) else {
871                                let span = expr.span;
872                                self.tcx.dcx().emit_fatal(ConstContinueMissingLabelOrValue { span })
873                            };
874
875                            ExprKind::ConstContinue {
876                                label: region::Scope {
877                                    local_id: target_id.local_id,
878                                    data: region::ScopeData::Node,
879                                },
880                                value: self.mirror_expr(value),
881                            }
882                        }
883                        Err(err) => bug!("invalid loop id for break: {}", err),
884                    }
885                } else {
886                    match dest.target_id {
887                        Ok(target_id) => ExprKind::Break {
888                            label: region::Scope {
889                                local_id: target_id.local_id,
890                                data: region::ScopeData::Node,
891                            },
892                            value: value.map(|value| self.mirror_expr(value)),
893                        },
894                        Err(err) => bug!("invalid loop id for break: {}", err),
895                    }
896                }
897            }
898            hir::ExprKind::Continue(dest) => match dest.target_id {
899                Ok(loop_id) => ExprKind::Continue {
900                    label: region::Scope {
901                        local_id: loop_id.local_id,
902                        data: region::ScopeData::Node,
903                    },
904                },
905                Err(err) => bug!("invalid loop id for continue: {}", err),
906            },
907            hir::ExprKind::Let(let_expr) => ExprKind::Let {
908                expr: self.mirror_expr(let_expr.init),
909                pat: self.pattern_from_hir(let_expr.pat),
910            },
911            hir::ExprKind::If(cond, then, else_opt) => ExprKind::If {
912                if_then_scope: region::Scope {
913                    local_id: then.hir_id.local_id,
914                    data: {
915                        if expr.span.at_least_rust_2024() {
916                            region::ScopeData::IfThenRescope
917                        } else {
918                            region::ScopeData::IfThen
919                        }
920                    },
921                },
922                cond: self.mirror_expr(cond),
923                then: self.mirror_expr(then),
924                else_opt: else_opt.map(|el| self.mirror_expr(el)),
925            },
926            hir::ExprKind::Match(discr, arms, match_source) => ExprKind::Match {
927                scrutinee: self.mirror_expr(discr),
928                arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
929                match_source,
930            },
931            hir::ExprKind::Loop(body, ..) => {
932                if find_attr!(self.tcx.hir_attrs(expr.hir_id), LoopMatch(_)) {
933                    let dcx = self.tcx.dcx();
934
935                    // Accept either `state = expr` or `state = expr;`.
936                    let loop_body_expr = match body.stmts {
937                        [] => match body.expr {
938                            Some(expr) => expr,
939                            None => dcx.emit_fatal(LoopMatchMissingAssignment { span: body.span }),
940                        },
941                        [single] if body.expr.is_none() => match single.kind {
942                            hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) => expr,
943                            _ => dcx.emit_fatal(LoopMatchMissingAssignment { span: body.span }),
944                        },
945                        [first @ last] | [first, .., last] => dcx
946                            .emit_fatal(LoopMatchBadStatements { span: first.span.to(last.span) }),
947                    };
948
949                    let hir::ExprKind::Assign(state, rhs_expr, _) = loop_body_expr.kind else {
950                        dcx.emit_fatal(LoopMatchMissingAssignment { span: loop_body_expr.span })
951                    };
952
953                    let hir::ExprKind::Block(block_body, _) = rhs_expr.kind else {
954                        dcx.emit_fatal(LoopMatchBadRhs { span: rhs_expr.span })
955                    };
956
957                    // The labeled block should contain one match expression, but defining items is
958                    // allowed.
959                    for stmt in block_body.stmts {
960                        if !matches!(stmt.kind, rustc_hir::StmtKind::Item(_)) {
961                            dcx.emit_fatal(LoopMatchBadStatements { span: stmt.span })
962                        }
963                    }
964
965                    let Some(block_body_expr) = block_body.expr else {
966                        dcx.emit_fatal(LoopMatchBadRhs { span: block_body.span })
967                    };
968
969                    let hir::ExprKind::Match(scrutinee, arms, _match_source) = block_body_expr.kind
970                    else {
971                        dcx.emit_fatal(LoopMatchBadRhs { span: block_body_expr.span })
972                    };
973
974                    fn local(
975                        cx: &mut ThirBuildCx<'_>,
976                        expr: &rustc_hir::Expr<'_>,
977                    ) -> Option<hir::HirId> {
978                        if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
979                            && let Res::Local(hir_id) = path.res
980                            && !cx.is_upvar(hir_id)
981                        {
982                            return Some(hir_id);
983                        }
984
985                        None
986                    }
987
988                    let Some(scrutinee_hir_id) = local(self, scrutinee) else {
989                        dcx.emit_fatal(LoopMatchInvalidMatch { span: scrutinee.span })
990                    };
991
992                    if local(self, state) != Some(scrutinee_hir_id) {
993                        dcx.emit_fatal(LoopMatchInvalidUpdate {
994                            scrutinee: scrutinee.span,
995                            lhs: state.span,
996                        })
997                    }
998
999                    ExprKind::LoopMatch {
1000                        state: self.mirror_expr(state),
1001                        region_scope: region::Scope {
1002                            local_id: block_body.hir_id.local_id,
1003                            data: region::ScopeData::Node,
1004                        },
1005
1006                        match_data: Box::new(LoopMatchMatchData {
1007                            scrutinee: self.mirror_expr(scrutinee),
1008                            arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
1009                            span: block_body_expr.span,
1010                        }),
1011                    }
1012                } else {
1013                    let block_ty = self.typeck_results.node_type(body.hir_id);
1014                    let block = self.mirror_block(body);
1015                    let body = self.thir.exprs.push(Expr {
1016                        ty: block_ty,
1017                        temp_scope_id: body.hir_id.local_id,
1018                        span: self.thir[block].span,
1019                        kind: ExprKind::Block { block },
1020                    });
1021                    ExprKind::Loop { body }
1022                }
1023            }
1024            hir::ExprKind::Field(source, ..) => ExprKind::Field {
1025                lhs: self.mirror_expr(source),
1026                variant_index: FIRST_VARIANT,
1027                name: self.typeck_results.field_index(expr.hir_id),
1028            },
1029            hir::ExprKind::Cast(source, cast_ty) => {
1030                // Check for a user-given type annotation on this `cast`
1031                let user_provided_types = self.typeck_results.user_provided_types();
1032                let user_ty = user_provided_types.get(cast_ty.hir_id);
1033
1034                debug!(
1035                    "cast({:?}) has ty w/ hir_id {:?} and user provided ty {:?}",
1036                    expr, cast_ty.hir_id, user_ty,
1037                );
1038
1039                let cast = self.mirror_expr_cast(source, expr.hir_id.local_id, expr.span);
1040
1041                if let Some(user_ty) = user_ty {
1042                    // NOTE: Creating a new Expr and wrapping a Cast inside of it may be
1043                    //       inefficient, revisit this when performance becomes an issue.
1044                    let cast_expr = self.thir.exprs.push(Expr {
1045                        temp_scope_id: expr.hir_id.local_id,
1046                        ty: expr_ty,
1047                        span: expr.span,
1048                        kind: cast,
1049                    });
1050                    debug!("make_mirror_unadjusted: (cast) user_ty={:?}", user_ty);
1051
1052                    ExprKind::ValueTypeAscription {
1053                        source: cast_expr,
1054                        user_ty: Some(Box::new(*user_ty)),
1055                        user_ty_span: cast_ty.span,
1056                    }
1057                } else {
1058                    cast
1059                }
1060            }
1061            hir::ExprKind::Type(source, ty) => {
1062                let user_provided_types = self.typeck_results.user_provided_types();
1063                let user_ty = user_provided_types.get(ty.hir_id).copied().map(Box::new);
1064                debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty);
1065                let mirrored = self.mirror_expr(source);
1066                if source.is_syntactic_place_expr() {
1067                    ExprKind::PlaceTypeAscription {
1068                        source: mirrored,
1069                        user_ty,
1070                        user_ty_span: ty.span,
1071                    }
1072                } else {
1073                    ExprKind::ValueTypeAscription {
1074                        source: mirrored,
1075                        user_ty,
1076                        user_ty_span: ty.span,
1077                    }
1078                }
1079            }
1080
1081            hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Unwrap, source, _ty) => {
1082                // FIXME(unsafe_binders): Take into account the ascribed type, too.
1083                let mirrored = self.mirror_expr(source);
1084                if source.is_syntactic_place_expr() {
1085                    ExprKind::PlaceUnwrapUnsafeBinder { source: mirrored }
1086                } else {
1087                    ExprKind::ValueUnwrapUnsafeBinder { source: mirrored }
1088                }
1089            }
1090            hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Wrap, source, _ty) => {
1091                // FIXME(unsafe_binders): Take into account the ascribed type, too.
1092                let mirrored = self.mirror_expr(source);
1093                ExprKind::WrapUnsafeBinder { source: mirrored }
1094            }
1095
1096            hir::ExprKind::DropTemps(source) => ExprKind::Use { source: self.mirror_expr(source) },
1097            hir::ExprKind::Array(fields) => ExprKind::Array { fields: self.mirror_exprs(fields) },
1098            hir::ExprKind::Tup(fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) },
1099
1100            hir::ExprKind::Yield(v, _) => ExprKind::Yield { value: self.mirror_expr(v) },
1101            hir::ExprKind::Err(_) => unreachable!("cannot lower a `hir::ExprKind::Err` to THIR"),
1102        };
1103
1104        mk_expr(kind, expr_ty)
1105    }
1106
1107    fn user_args_applied_to_res(
1108        &mut self,
1109        hir_id: hir::HirId,
1110        res: Res,
1111    ) -> Option<Box<ty::CanonicalUserType<'tcx>>> {
1112        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/thir/cx/expr.rs:1112",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1112u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("user_args_applied_to_res: res={0:?}",
                                                    res) as &dyn Value))])
            });
    } else { ; }
};debug!("user_args_applied_to_res: res={:?}", res);
1113        let user_provided_type = match res {
1114            // A reference to something callable -- e.g., a fn, method, or
1115            // a tuple-struct or tuple-variant. This has the type of a
1116            // `Fn` but with the user-given generic parameters.
1117            Res::Def(DefKind::Fn, _)
1118            | Res::Def(DefKind::AssocFn, _)
1119            | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
1120            | Res::Def(DefKind::Const, _)
1121            | Res::Def(DefKind::AssocConst, _) => {
1122                self.typeck_results.user_provided_types().get(hir_id).copied().map(Box::new)
1123            }
1124
1125            // A unit struct/variant which is used as a value (e.g.,
1126            // `None`). This has the type of the enum/struct that defines
1127            // this variant -- but with the generic parameters given by the
1128            // user.
1129            Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => {
1130                self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new)
1131            }
1132
1133            // `Self` is used in expression as a tuple struct constructor or a unit struct constructor
1134            Res::SelfCtor(_) => self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new),
1135
1136            _ => ::rustc_middle::util::bug::bug_fmt(format_args!("user_args_applied_to_res: unexpected res {0:?} at {1:?}",
        res, hir_id))bug!("user_args_applied_to_res: unexpected res {:?} at {:?}", res, hir_id),
1137        };
1138        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/thir/cx/expr.rs:1138",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1138u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("user_args_applied_to_res: user_provided_type={0:?}",
                                                    user_provided_type) as &dyn Value))])
            });
    } else { ; }
};debug!("user_args_applied_to_res: user_provided_type={:?}", user_provided_type);
1139        user_provided_type
1140    }
1141
1142    fn method_callee(
1143        &mut self,
1144        expr: &hir::Expr<'_>,
1145        span: Span,
1146        overloaded_callee: Option<Ty<'tcx>>,
1147    ) -> Expr<'tcx> {
1148        let (ty, user_ty) = match overloaded_callee {
1149            Some(fn_def) => (fn_def, None),
1150            None => {
1151                let (kind, def_id) =
1152                    self.typeck_results.type_dependent_def(expr.hir_id).unwrap_or_else(|| {
1153                        ::rustc_middle::util::bug::span_bug_fmt(expr.span,
    format_args!("no type-dependent def for method callee"))span_bug!(expr.span, "no type-dependent def for method callee")
1154                    });
1155                let user_ty = self.user_args_applied_to_res(expr.hir_id, Res::Def(kind, def_id));
1156                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/thir/cx/expr.rs:1156",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1156u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("method_callee: user_ty={0:?}",
                                                    user_ty) as &dyn Value))])
            });
    } else { ; }
};debug!("method_callee: user_ty={:?}", user_ty);
1157                (
1158                    Ty::new_fn_def(self.tcx, def_id, self.typeck_results.node_args(expr.hir_id)),
1159                    user_ty,
1160                )
1161            }
1162        };
1163        Expr {
1164            temp_scope_id: expr.hir_id.local_id,
1165            ty,
1166            span,
1167            kind: ExprKind::ZstLiteral { user_ty },
1168        }
1169    }
1170
1171    fn convert_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) -> ArmId {
1172        let arm = Arm {
1173            pattern: self.pattern_from_hir(&arm.pat),
1174            guard: arm.guard.as_ref().map(|g| self.mirror_expr(g)),
1175            body: self.mirror_expr(arm.body),
1176            hir_id: arm.hir_id,
1177            scope: region::Scope { local_id: arm.hir_id.local_id, data: region::ScopeData::Node },
1178            span: arm.span,
1179        };
1180        self.thir.arms.push(arm)
1181    }
1182
1183    fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKind<'tcx> {
1184        let args = self.typeck_results.node_args(expr.hir_id);
1185        match res {
1186            // A regular function, constructor function or a constant.
1187            Res::Def(DefKind::Fn, _)
1188            | Res::Def(DefKind::AssocFn, _)
1189            | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
1190            | Res::SelfCtor(_) => {
1191                let user_ty = self.user_args_applied_to_res(expr.hir_id, res);
1192                ExprKind::ZstLiteral { user_ty }
1193            }
1194
1195            Res::Def(DefKind::ConstParam, def_id) => {
1196                let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local());
1197                let generics = self.tcx.generics_of(hir_id.owner);
1198                let Some(&index) = generics.param_def_id_to_index.get(&def_id) else {
1199                    ::rustc_middle::util::bug::span_bug_fmt(expr.span,
    format_args!("Should have already errored about late bound consts: {0:?}",
        def_id));span_bug!(
1200                        expr.span,
1201                        "Should have already errored about late bound consts: {def_id:?}"
1202                    );
1203                };
1204                let name = self.tcx.hir_name(hir_id);
1205                let param = ty::ParamConst::new(index, name);
1206
1207                ExprKind::ConstParam { param, def_id }
1208            }
1209
1210            Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
1211                let user_ty = self.user_args_applied_to_res(expr.hir_id, res);
1212                ExprKind::NamedConst { def_id, args, user_ty }
1213            }
1214
1215            Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
1216                let user_provided_types = self.typeck_results.user_provided_types();
1217                let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
1218                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/thir/cx/expr.rs:1218",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1218u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("convert_path_expr: user_ty={0:?}",
                                                    user_ty) as &dyn Value))])
            });
    } else { ; }
};debug!("convert_path_expr: user_ty={:?}", user_ty);
1219                let ty = self.typeck_results.node_type(expr.hir_id);
1220                match ty.kind() {
1221                    // A unit struct/variant which is used as a value.
1222                    // We return a completely different ExprKind here to account for this special case.
1223                    ty::Adt(adt_def, args) => ExprKind::Adt(Box::new(AdtExpr {
1224                        adt_def: *adt_def,
1225                        variant_index: adt_def.variant_index_with_ctor_id(def_id),
1226                        args,
1227                        user_ty,
1228                        fields: Box::new([]),
1229                        base: AdtExprBase::None,
1230                    })),
1231                    _ => ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected ty: {0:?}", ty))bug!("unexpected ty: {:?}", ty),
1232                }
1233            }
1234
1235            // A source Rust `path::to::STATIC` is a place expr like *&ident is.
1236            // In THIR, we make them exactly equivalent by inserting the implied *& or *&raw,
1237            // but distinguish between &STATIC and &THREAD_LOCAL as they have different semantics
1238            Res::Def(DefKind::Static { .. }, id) => {
1239                // this is &raw for extern static or static mut, and & for other statics
1240                let ty = self.tcx.static_ptr_ty(id, self.typing_env);
1241                let kind = if self.tcx.is_thread_local_static(id) {
1242                    ExprKind::ThreadLocalRef(id)
1243                } else {
1244                    let alloc_id = self.tcx.reserve_and_set_static_alloc(id);
1245                    ExprKind::StaticRef { alloc_id, ty, def_id: id }
1246                };
1247                ExprKind::Deref {
1248                    arg: self.thir.exprs.push(Expr {
1249                        ty,
1250                        temp_scope_id: expr.hir_id.local_id,
1251                        span: expr.span,
1252                        kind,
1253                    }),
1254                }
1255            }
1256
1257            Res::Local(var_hir_id) => self.convert_var(var_hir_id),
1258
1259            _ => ::rustc_middle::util::bug::span_bug_fmt(expr.span,
    format_args!("res `{0:?}` not yet implemented", res))span_bug!(expr.span, "res `{:?}` not yet implemented", res),
1260        }
1261    }
1262
1263    fn convert_var(&mut self, var_hir_id: hir::HirId) -> ExprKind<'tcx> {
1264        // We want upvars here not captures.
1265        // Captures will be handled in MIR.
1266        let is_upvar = self.is_upvar(var_hir_id);
1267
1268        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_build/src/thir/cx/expr.rs:1268",
                        "rustc_mir_build::thir::cx::expr", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_build/src/thir/cx/expr.rs"),
                        ::tracing_core::__macro_support::Option::Some(1268u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("convert_var({0:?}): is_upvar={1}, body_owner={2:?}",
                                                    var_hir_id, is_upvar, self.body_owner) as &dyn Value))])
            });
    } else { ; }
};debug!(
1269            "convert_var({:?}): is_upvar={}, body_owner={:?}",
1270            var_hir_id, is_upvar, self.body_owner
1271        );
1272
1273        if is_upvar {
1274            ExprKind::UpvarRef {
1275                closure_def_id: self.body_owner,
1276                var_hir_id: LocalVarId(var_hir_id),
1277            }
1278        } else {
1279            ExprKind::VarRef { id: LocalVarId(var_hir_id) }
1280        }
1281    }
1282
1283    fn overloaded_operator(
1284        &mut self,
1285        expr: &'tcx hir::Expr<'tcx>,
1286        args: Box<[ExprId]>,
1287    ) -> ExprKind<'tcx> {
1288        let fun = self.method_callee(expr, expr.span, None);
1289        let fun = self.thir.exprs.push(fun);
1290        ExprKind::Call {
1291            ty: self.thir[fun].ty,
1292            fun,
1293            args,
1294            from_hir_call: false,
1295            fn_span: expr.span,
1296        }
1297    }
1298
1299    fn overloaded_place(
1300        &mut self,
1301        expr: &'tcx hir::Expr<'tcx>,
1302        place_ty: Ty<'tcx>,
1303        overloaded_callee: Option<Ty<'tcx>>,
1304        args: Box<[ExprId]>,
1305        span: Span,
1306    ) -> ExprKind<'tcx> {
1307        // For an overloaded *x or x[y] expression of type T, the method
1308        // call returns an &T and we must add the deref so that the types
1309        // line up (this is because `*x` and `x[y]` represent places):
1310
1311        // Reconstruct the output assuming it's a reference with the
1312        // same region and mutability as the receiver. This holds for
1313        // `Deref(Mut)::deref(_mut)` and `Index(Mut)::index(_mut)`.
1314        let ty::Ref(region, _, mutbl) = *self.thir[args[0]].ty.kind() else {
1315            ::rustc_middle::util::bug::span_bug_fmt(span,
    format_args!("overloaded_place: receiver is not a reference"));span_bug!(span, "overloaded_place: receiver is not a reference");
1316        };
1317        let ref_ty = Ty::new_ref(self.tcx, region, place_ty, mutbl);
1318
1319        // construct the complete expression `foo()` for the overloaded call,
1320        // which will yield the &T type
1321        let fun = self.method_callee(expr, span, overloaded_callee);
1322        let fun = self.thir.exprs.push(fun);
1323        let fun_ty = self.thir[fun].ty;
1324        let ref_expr = self.thir.exprs.push(Expr {
1325            temp_scope_id: expr.hir_id.local_id,
1326            ty: ref_ty,
1327            span,
1328            kind: ExprKind::Call { ty: fun_ty, fun, args, from_hir_call: false, fn_span: span },
1329        });
1330
1331        // construct and return a deref wrapper `*foo()`
1332        ExprKind::Deref { arg: ref_expr }
1333    }
1334
1335    fn convert_captured_hir_place(
1336        &mut self,
1337        closure_expr: &'tcx hir::Expr<'tcx>,
1338        place: HirPlace<'tcx>,
1339    ) -> Expr<'tcx> {
1340        let temp_scope_id = closure_expr.hir_id.local_id;
1341        let var_ty = place.base_ty;
1342
1343        // The result of capture analysis in `rustc_hir_typeck/src/upvar.rs` represents a captured path
1344        // as it's seen for use within the closure and not at the time of closure creation.
1345        //
1346        // That is we see expect to see it start from a captured upvar and not something that is local
1347        // to the closure's parent.
1348        let var_hir_id = match place.base {
1349            HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
1350            base => ::rustc_middle::util::bug::bug_fmt(format_args!("Expected an upvar, found {0:?}",
        base))bug!("Expected an upvar, found {:?}", base),
1351        };
1352
1353        let mut captured_place_expr = Expr {
1354            temp_scope_id,
1355            ty: var_ty,
1356            span: closure_expr.span,
1357            kind: self.convert_var(var_hir_id),
1358        };
1359
1360        for proj in place.projections.iter() {
1361            let kind = match proj.kind {
1362                HirProjectionKind::Deref => {
1363                    ExprKind::Deref { arg: self.thir.exprs.push(captured_place_expr) }
1364                }
1365                HirProjectionKind::Field(field, variant_index) => ExprKind::Field {
1366                    lhs: self.thir.exprs.push(captured_place_expr),
1367                    variant_index,
1368                    name: field,
1369                },
1370                HirProjectionKind::OpaqueCast => {
1371                    ExprKind::Use { source: self.thir.exprs.push(captured_place_expr) }
1372                }
1373                HirProjectionKind::UnwrapUnsafeBinder => ExprKind::PlaceUnwrapUnsafeBinder {
1374                    source: self.thir.exprs.push(captured_place_expr),
1375                },
1376                HirProjectionKind::Index | HirProjectionKind::Subslice => {
1377                    // We don't capture these projections, so we can ignore them here
1378                    continue;
1379                }
1380            };
1381
1382            captured_place_expr =
1383                Expr { temp_scope_id, ty: proj.ty, span: closure_expr.span, kind };
1384        }
1385
1386        captured_place_expr
1387    }
1388
1389    fn capture_upvar(
1390        &mut self,
1391        closure_expr: &'tcx hir::Expr<'tcx>,
1392        captured_place: &'tcx ty::CapturedPlace<'tcx>,
1393        upvar_ty: Ty<'tcx>,
1394    ) -> Expr<'tcx> {
1395        let upvar_capture = captured_place.info.capture_kind;
1396        let captured_place_expr =
1397            self.convert_captured_hir_place(closure_expr, captured_place.place.clone());
1398        let temp_scope_id = closure_expr.hir_id.local_id;
1399
1400        match upvar_capture {
1401            ty::UpvarCapture::ByValue => captured_place_expr,
1402            ty::UpvarCapture::ByUse => {
1403                let span = captured_place_expr.span;
1404                let expr_id = self.thir.exprs.push(captured_place_expr);
1405
1406                Expr {
1407                    temp_scope_id,
1408                    ty: upvar_ty,
1409                    span: closure_expr.span,
1410                    kind: ExprKind::ByUse { expr: expr_id, span },
1411                }
1412            }
1413            ty::UpvarCapture::ByRef(upvar_borrow) => {
1414                let borrow_kind = match upvar_borrow {
1415                    ty::BorrowKind::Immutable => BorrowKind::Shared,
1416                    ty::BorrowKind::UniqueImmutable => {
1417                        BorrowKind::Mut { kind: mir::MutBorrowKind::ClosureCapture }
1418                    }
1419                    ty::BorrowKind::Mutable => {
1420                        BorrowKind::Mut { kind: mir::MutBorrowKind::Default }
1421                    }
1422                };
1423                Expr {
1424                    temp_scope_id,
1425                    ty: upvar_ty,
1426                    span: closure_expr.span,
1427                    kind: ExprKind::Borrow {
1428                        borrow_kind,
1429                        arg: self.thir.exprs.push(captured_place_expr),
1430                    },
1431                }
1432            }
1433        }
1434    }
1435
1436    fn is_upvar(&mut self, var_hir_id: hir::HirId) -> bool {
1437        self.tcx
1438            .upvars_mentioned(self.body_owner)
1439            .is_some_and(|upvars| upvars.contains_key(&var_hir_id))
1440    }
1441
1442    /// Converts a list of named fields (i.e., for struct-like struct/enum ADTs) into FieldExpr.
1443    fn field_refs(&mut self, fields: &'tcx [hir::ExprField<'tcx>]) -> Box<[FieldExpr]> {
1444        fields
1445            .iter()
1446            .map(|field| FieldExpr {
1447                name: self.typeck_results.field_index(field.hir_id),
1448                expr: self.mirror_expr(field.expr),
1449            })
1450            .collect()
1451    }
1452}
1453
1454trait ToBorrowKind {
1455    fn to_borrow_kind(&self) -> BorrowKind;
1456}
1457
1458impl ToBorrowKind for AutoBorrowMutability {
1459    fn to_borrow_kind(&self) -> BorrowKind {
1460        use rustc_middle::ty::adjustment::AllowTwoPhase;
1461        match *self {
1462            AutoBorrowMutability::Mut { allow_two_phase_borrow } => BorrowKind::Mut {
1463                kind: match allow_two_phase_borrow {
1464                    AllowTwoPhase::Yes => mir::MutBorrowKind::TwoPhaseBorrow,
1465                    AllowTwoPhase::No => mir::MutBorrowKind::Default,
1466                },
1467            },
1468            AutoBorrowMutability::Not => BorrowKind::Shared,
1469        }
1470    }
1471}
1472
1473impl ToBorrowKind for hir::Mutability {
1474    fn to_borrow_kind(&self) -> BorrowKind {
1475        match *self {
1476            hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
1477            hir::Mutability::Not => BorrowKind::Shared,
1478        }
1479    }
1480}
1481
1482fn bin_op(op: hir::BinOpKind) -> BinOp {
1483    match op {
1484        hir::BinOpKind::Add => BinOp::Add,
1485        hir::BinOpKind::Sub => BinOp::Sub,
1486        hir::BinOpKind::Mul => BinOp::Mul,
1487        hir::BinOpKind::Div => BinOp::Div,
1488        hir::BinOpKind::Rem => BinOp::Rem,
1489        hir::BinOpKind::BitXor => BinOp::BitXor,
1490        hir::BinOpKind::BitAnd => BinOp::BitAnd,
1491        hir::BinOpKind::BitOr => BinOp::BitOr,
1492        hir::BinOpKind::Shl => BinOp::Shl,
1493        hir::BinOpKind::Shr => BinOp::Shr,
1494        hir::BinOpKind::Eq => BinOp::Eq,
1495        hir::BinOpKind::Lt => BinOp::Lt,
1496        hir::BinOpKind::Le => BinOp::Le,
1497        hir::BinOpKind::Ne => BinOp::Ne,
1498        hir::BinOpKind::Ge => BinOp::Ge,
1499        hir::BinOpKind::Gt => BinOp::Gt,
1500        _ => ::rustc_middle::util::bug::bug_fmt(format_args!("no equivalent for ast binop {0:?}",
        op))bug!("no equivalent for ast binop {:?}", op),
1501    }
1502}
1503
1504fn assign_op(op: hir::AssignOpKind) -> AssignOp {
1505    match op {
1506        hir::AssignOpKind::AddAssign => AssignOp::AddAssign,
1507        hir::AssignOpKind::SubAssign => AssignOp::SubAssign,
1508        hir::AssignOpKind::MulAssign => AssignOp::MulAssign,
1509        hir::AssignOpKind::DivAssign => AssignOp::DivAssign,
1510        hir::AssignOpKind::RemAssign => AssignOp::RemAssign,
1511        hir::AssignOpKind::BitXorAssign => AssignOp::BitXorAssign,
1512        hir::AssignOpKind::BitAndAssign => AssignOp::BitAndAssign,
1513        hir::AssignOpKind::BitOrAssign => AssignOp::BitOrAssign,
1514        hir::AssignOpKind::ShlAssign => AssignOp::ShlAssign,
1515        hir::AssignOpKind::ShrAssign => AssignOp::ShrAssign,
1516    }
1517}