Skip to main content

rustc_hir_typeck/
expr_use_visitor.rs

1//! A different sort of visitor for walking fn bodies. Unlike the
2//! normal visitor, which just walks the entire body in one shot, the
3//! `ExprUseVisitor` determines how expressions are being used.
4//!
5//! In the compiler, this is only used for upvar inference and diagnostics, but there
6//! are many uses within clippy.
7
8use std::cell::{Ref, RefCell};
9use std::ops::Deref;
10
11use hir::def::DefKind;
12use hir::pat_util::EnumerateAndAdjustIterator as _;
13use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
14use rustc_ast::UnsafeBinderCastKind;
15use rustc_data_structures::fx::FxIndexMap;
16use rustc_hir::def::{CtorOf, Res};
17use rustc_hir::def_id::LocalDefId;
18use rustc_hir::{self as hir, HirId, PatExpr, PatExprKind, PatKind};
19use rustc_lint::LateContext;
20use rustc_middle::hir::place::ProjectionKind;
21// Export these here so that Clippy can use them.
22pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection};
23use rustc_middle::mir::FakeReadCause;
24use rustc_middle::thir::DerefPatBorrowMode;
25use rustc_middle::ty::adjustment::DerefAdjustKind;
26use rustc_middle::ty::{
27    self, BorrowKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, adjustment,
28};
29use rustc_middle::{bug, span_bug};
30use rustc_span::{ErrorGuaranteed, Span};
31use rustc_trait_selection::infer::InferCtxtExt;
32use tracing::{debug, instrument, trace};
33
34use crate::fn_ctxt::FnCtxt;
35
36/// This trait defines the callbacks you can expect to receive when
37/// employing the ExprUseVisitor.
38pub trait Delegate<'tcx> {
39    /// The value found at `place` is moved, depending
40    /// on `mode`. Where `diag_expr_id` is the id used for diagnostics for `place`.
41    ///
42    /// If the value is `Copy`, [`copy`][Self::copy] is called instead, which
43    /// by default falls back to [`borrow`][Self::borrow].
44    ///
45    /// The parameter `diag_expr_id` indicates the HIR id that ought to be used for
46    /// diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic
47    /// id will be the id of the expression `expr` but the place itself will have
48    /// the id of the binding in the pattern `pat`.
49    fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId);
50
51    /// The value found at `place` is used, depending
52    /// on `mode`. Where `diag_expr_id` is the id used for diagnostics for `place`.
53    ///
54    /// Use of a `Copy` type in a ByUse context is considered a use
55    /// by `ImmBorrow` and `borrow` is called instead. This is because
56    /// a shared borrow is the "minimum access" that would be needed
57    /// to perform a copy.
58    ///
59    ///
60    /// The parameter `diag_expr_id` indicates the HIR id that ought to be used for
61    /// diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic
62    /// id will be the id of the expression `expr` but the place itself will have
63    /// the id of the binding in the pattern `pat`.
64    fn use_cloned(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId);
65
66    /// The value found at `place` is being borrowed with kind `bk`.
67    /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
68    fn borrow(
69        &mut self,
70        place_with_id: &PlaceWithHirId<'tcx>,
71        diag_expr_id: HirId,
72        bk: ty::BorrowKind,
73    );
74
75    /// The value found at `place` is being copied.
76    /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
77    ///
78    /// If an implementation is not provided, use of a `Copy` type in a ByValue context is instead
79    /// considered a use by `ImmBorrow` and `borrow` is called instead. This is because a shared
80    /// borrow is the "minimum access" that would be needed to perform a copy.
81    fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
82        // In most cases, copying data from `x` is equivalent to doing `*&x`, so by default
83        // we treat a copy of `x` as a borrow of `x`.
84        self.borrow(place_with_id, diag_expr_id, ty::BorrowKind::Immutable)
85    }
86
87    /// The path at `assignee_place` is being assigned to.
88    /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
89    fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId);
90
91    /// The path at `binding_place` is a binding that is being initialized.
92    ///
93    /// This covers cases such as `let x = 42;`
94    fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
95        // Bindings can normally be treated as a regular assignment, so by default we
96        // forward this to the mutate callback.
97        self.mutate(binding_place, diag_expr_id)
98    }
99
100    /// The `place` should be a fake read because of specified `cause`.
101    fn fake_read(
102        &mut self,
103        place_with_id: &PlaceWithHirId<'tcx>,
104        cause: FakeReadCause,
105        diag_expr_id: HirId,
106    );
107}
108
109impl<'tcx, D: Delegate<'tcx>> Delegate<'tcx> for &mut D {
110    fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
111        (**self).consume(place_with_id, diag_expr_id)
112    }
113
114    fn use_cloned(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
115        (**self).use_cloned(place_with_id, diag_expr_id)
116    }
117
118    fn borrow(
119        &mut self,
120        place_with_id: &PlaceWithHirId<'tcx>,
121        diag_expr_id: HirId,
122        bk: ty::BorrowKind,
123    ) {
124        (**self).borrow(place_with_id, diag_expr_id, bk)
125    }
126
127    fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
128        (**self).copy(place_with_id, diag_expr_id)
129    }
130
131    fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
132        (**self).mutate(assignee_place, diag_expr_id)
133    }
134
135    fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
136        (**self).bind(binding_place, diag_expr_id)
137    }
138
139    fn fake_read(
140        &mut self,
141        place_with_id: &PlaceWithHirId<'tcx>,
142        cause: FakeReadCause,
143        diag_expr_id: HirId,
144    ) {
145        (**self).fake_read(place_with_id, cause, diag_expr_id)
146    }
147}
148
149/// This trait makes `ExprUseVisitor` usable with both [`FnCtxt`]
150/// and [`LateContext`], depending on where in the compiler it is used.
151pub trait TypeInformationCtxt<'tcx> {
152    type TypeckResults<'a>: Deref<Target = ty::TypeckResults<'tcx>>
153    where
154        Self: 'a;
155
156    type Error;
157
158    fn typeck_results(&self) -> Self::TypeckResults<'_>;
159
160    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T;
161
162    fn structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
163
164    fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error;
165
166    fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error>;
167
168    fn tainted_by_errors(&self) -> Result<(), Self::Error>;
169
170    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool;
171
172    fn type_is_use_cloned_modulo_regions(&self, ty: Ty<'tcx>) -> bool;
173
174    fn body_owner_def_id(&self) -> LocalDefId;
175
176    fn tcx(&self) -> TyCtxt<'tcx>;
177}
178
179impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> {
180    type TypeckResults<'a>
181        = Ref<'a, ty::TypeckResults<'tcx>>
182    where
183        Self: 'a;
184
185    type Error = ErrorGuaranteed;
186
187    fn typeck_results(&self) -> Self::TypeckResults<'_> {
188        self.typeck_results.borrow()
189    }
190
191    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
192        self.infcx.resolve_vars_if_possible(t)
193    }
194
195    fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
196        (**self).structurally_resolve_type(sp, ty)
197    }
198
199    fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error {
200        self.dcx().span_delayed_bug(span, msg.to_string())
201    }
202
203    fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error> {
204        ty.error_reported()
205    }
206
207    fn tainted_by_errors(&self) -> Result<(), ErrorGuaranteed> {
208        if let Some(guar) = self.infcx.tainted_by_errors() { Err(guar) } else { Ok(()) }
209    }
210
211    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
212        self.infcx.type_is_copy_modulo_regions(self.param_env, ty)
213    }
214
215    fn type_is_use_cloned_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
216        self.infcx.type_is_use_cloned_modulo_regions(self.param_env, ty)
217    }
218
219    fn body_owner_def_id(&self) -> LocalDefId {
220        self.body_id
221    }
222
223    fn tcx(&self) -> TyCtxt<'tcx> {
224        self.tcx
225    }
226}
227
228impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
229    type TypeckResults<'a>
230        = &'tcx ty::TypeckResults<'tcx>
231    where
232        Self: 'a;
233
234    type Error = !;
235
236    fn typeck_results(&self) -> Self::TypeckResults<'_> {
237        self.0.maybe_typeck_results().expect("expected typeck results")
238    }
239
240    fn structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
241        // FIXME: Maybe need to normalize here.
242        ty
243    }
244
245    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
246        t
247    }
248
249    fn report_bug(&self, span: Span, msg: impl ToString) -> ! {
250        ::rustc_middle::util::bug::span_bug_fmt(span,
    format_args!("{0}", msg.to_string()))span_bug!(span, "{}", msg.to_string())
251    }
252
253    fn error_reported_in_ty(&self, _ty: Ty<'tcx>) -> Result<(), !> {
254        Ok(())
255    }
256
257    fn tainted_by_errors(&self) -> Result<(), !> {
258        Ok(())
259    }
260
261    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
262        self.0.type_is_copy_modulo_regions(ty)
263    }
264
265    fn type_is_use_cloned_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
266        self.0.type_is_use_cloned_modulo_regions(ty)
267    }
268
269    fn body_owner_def_id(&self) -> LocalDefId {
270        self.1
271    }
272
273    fn tcx(&self) -> TyCtxt<'tcx> {
274        self.0.tcx
275    }
276}
277
278/// A visitor that reports how each expression is being used.
279///
280/// See [module-level docs][self] and [`Delegate`] for details.
281pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> {
282    cx: Cx,
283    /// We use a `RefCell` here so that delegates can mutate themselves, but we can
284    /// still have calls to our own helper functions.
285    delegate: RefCell<D>,
286    upvars: Option<&'tcx FxIndexMap<HirId, hir::Upvar>>,
287}
288
289impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'tcx, (&'a LateContext<'tcx>, LocalDefId), D> {
290    pub fn for_clippy(cx: &'a LateContext<'tcx>, body_def_id: LocalDefId, delegate: D) -> Self {
291        Self::new((cx, body_def_id), delegate)
292    }
293}
294
295impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
296    /// Creates the ExprUseVisitor, configuring it with the various options provided:
297    ///
298    /// - `delegate` -- who receives the callbacks
299    /// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`)
300    /// - `typeck_results` --- typeck results for the code being analyzed
301    pub(crate) fn new(cx: Cx, delegate: D) -> Self {
302        ExprUseVisitor {
303            delegate: RefCell::new(delegate),
304            upvars: cx.tcx().upvars_mentioned(cx.body_owner_def_id()),
305            cx,
306        }
307    }
308
309    pub fn consume_body(&self, body: &hir::Body<'_>) -> Result<(), Cx::Error> {
310        for param in body.params {
311            let param_ty = self.pat_ty_adjusted(param.pat)?;
312            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:312",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(312u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("consume_body: param_ty = {0:?}",
                                                    param_ty) as &dyn Value))])
            });
    } else { ; }
};debug!("consume_body: param_ty = {:?}", param_ty);
313
314            let param_place = self.cat_rvalue(param.hir_id, param_ty);
315
316            self.fake_read_scrutinee(&param_place, false)?;
317            self.walk_pat(&param_place, param.pat, false)?;
318        }
319
320        self.consume_expr(body.value)?;
321
322        Ok(())
323    }
324
325    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("consume_or_copy",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(325u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["place_with_id",
                                                    "diag_expr_id"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place_with_id)
                                                            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(&diag_expr_id)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
                self.delegate.borrow_mut().copy(place_with_id, diag_expr_id);
            } else {
                self.delegate.borrow_mut().consume(place_with_id,
                    diag_expr_id);
            }
        }
    }
}#[instrument(skip(self), level = "debug")]
326    fn consume_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
327        if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
328            self.delegate.borrow_mut().copy(place_with_id, diag_expr_id);
329        } else {
330            self.delegate.borrow_mut().consume(place_with_id, diag_expr_id);
331        }
332    }
333
334    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("consume_clone_or_copy",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(334u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["place_with_id",
                                                    "diag_expr_id"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&place_with_id)
                                                            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(&diag_expr_id)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
                self.delegate.borrow_mut().copy(place_with_id, diag_expr_id);
            } else if self.cx.type_is_use_cloned_modulo_regions(place_with_id.place.ty())
                {
                self.delegate.borrow_mut().use_cloned(place_with_id,
                    diag_expr_id);
            } else {
                self.delegate.borrow_mut().consume(place_with_id,
                    diag_expr_id);
            }
        }
    }
}#[instrument(skip(self), level = "debug")]
335    pub fn consume_clone_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
336        // `x.use` will do one of the following
337        // * if it implements `Copy`, it will be a copy
338        // * if it implements `UseCloned`, it will be a call to `clone`
339        // * otherwise, it is a move
340        //
341        // we do a conservative approximation of this, treating it as a move unless we know that it implements copy or `UseCloned`
342        if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
343            self.delegate.borrow_mut().copy(place_with_id, diag_expr_id);
344        } else if self.cx.type_is_use_cloned_modulo_regions(place_with_id.place.ty()) {
345            self.delegate.borrow_mut().use_cloned(place_with_id, diag_expr_id);
346        } else {
347            self.delegate.borrow_mut().consume(place_with_id, diag_expr_id);
348        }
349    }
350
351    fn consume_exprs(&self, exprs: &[hir::Expr<'_>]) -> Result<(), Cx::Error> {
352        for expr in exprs {
353            self.consume_expr(expr)?;
354        }
355
356        Ok(())
357    }
358
359    // FIXME: It's suspicious that this is public; clippy should probably use `walk_expr`.
360    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("consume_expr",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(360u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["expr"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr)
                                                            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: Result<(), Cx::Error> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let place_with_id = self.cat_expr(expr)?;
            self.consume_or_copy(&place_with_id, place_with_id.hir_id);
            self.walk_expr(expr)?;
            Ok(())
        }
    }
}#[instrument(skip(self), level = "debug")]
361    pub fn consume_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
362        let place_with_id = self.cat_expr(expr)?;
363        self.consume_or_copy(&place_with_id, place_with_id.hir_id);
364        self.walk_expr(expr)?;
365        Ok(())
366    }
367
368    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("consume_or_clone_expr",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(368u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["expr"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr)
                                                            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: Result<(), Cx::Error> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let place_with_id = self.cat_expr(expr)?;
            self.consume_clone_or_copy(&place_with_id, place_with_id.hir_id);
            self.walk_expr(expr)?;
            Ok(())
        }
    }
}#[instrument(skip(self), level = "debug")]
369    pub fn consume_or_clone_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
370        let place_with_id = self.cat_expr(expr)?;
371        self.consume_clone_or_copy(&place_with_id, place_with_id.hir_id);
372        self.walk_expr(expr)?;
373        Ok(())
374    }
375
376    fn mutate_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
377        let place_with_id = self.cat_expr(expr)?;
378        self.delegate.borrow_mut().mutate(&place_with_id, place_with_id.hir_id);
379        self.walk_expr(expr)?;
380        Ok(())
381    }
382
383    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("borrow_expr",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(383u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["expr", "bk"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&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(&bk)
                                                            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: Result<(), Cx::Error> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let place_with_id = self.cat_expr(expr)?;
            self.delegate.borrow_mut().borrow(&place_with_id,
                place_with_id.hir_id, bk);
            self.walk_expr(expr)
        }
    }
}#[instrument(skip(self), level = "debug")]
384    fn borrow_expr(&self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) -> Result<(), Cx::Error> {
385        let place_with_id = self.cat_expr(expr)?;
386        self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
387        self.walk_expr(expr)
388    }
389
390    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("walk_expr",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(390u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["expr"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr)
                                                            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: Result<(), Cx::Error> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            self.walk_adjustment(expr)?;
            match expr.kind {
                hir::ExprKind::Path(_) => {}
                hir::ExprKind::Type(subexpr, _) => {
                    self.walk_expr(subexpr)?;
                }
                hir::ExprKind::UnsafeBinderCast(_, subexpr, _) => {
                    self.walk_expr(subexpr)?;
                }
                hir::ExprKind::Unary(hir::UnOp::Deref, base) => {
                    self.walk_expr(base)?;
                }
                hir::ExprKind::Field(base, _) => { self.walk_expr(base)?; }
                hir::ExprKind::Index(lhs, rhs, _) => {
                    self.walk_expr(lhs)?;
                    self.consume_expr(rhs)?;
                }
                hir::ExprKind::Call(callee, args) => {
                    self.consume_expr(callee)?;
                    self.consume_exprs(args)?;
                }
                hir::ExprKind::Use(expr, _) => {
                    self.consume_or_clone_expr(expr)?;
                }
                hir::ExprKind::MethodCall(.., receiver, args, _) => {
                    self.consume_expr(receiver)?;
                    self.consume_exprs(args)?;
                }
                hir::ExprKind::Struct(_, fields, ref opt_with) => {
                    self.walk_struct_expr(fields, opt_with)?;
                }
                hir::ExprKind::Tup(exprs) => { self.consume_exprs(exprs)?; }
                hir::ExprKind::If(cond_expr, then_expr, ref opt_else_expr) =>
                    {
                    self.consume_expr(cond_expr)?;
                    self.consume_expr(then_expr)?;
                    if let Some(else_expr) = *opt_else_expr {
                        self.consume_expr(else_expr)?;
                    }
                }
                hir::ExprKind::Let(hir::LetExpr { pat, init, .. }) => {
                    self.walk_local(init, pat, None,
                            || self.borrow_expr(init, BorrowKind::Immutable))?;
                }
                hir::ExprKind::Match(discr, arms, _) => {
                    let discr_place = self.cat_expr(discr)?;
                    self.fake_read_scrutinee(&discr_place, true)?;
                    self.walk_expr(discr)?;
                    for arm in arms { self.walk_arm(&discr_place, arm)?; }
                }
                hir::ExprKind::Array(exprs) => { self.consume_exprs(exprs)?; }
                hir::ExprKind::AddrOf(_, m, base) => {
                    let bk = ty::BorrowKind::from_mutbl(m);
                    self.borrow_expr(base, bk)?;
                }
                hir::ExprKind::InlineAsm(asm) => {
                    for (op, _op_sp) in asm.operands {
                        match op {
                            hir::InlineAsmOperand::In { expr, .. } => {
                                self.consume_expr(expr)?;
                            }
                            hir::InlineAsmOperand::Out { expr: Some(expr), .. } |
                                hir::InlineAsmOperand::InOut { expr, .. } => {
                                self.mutate_expr(expr)?;
                            }
                            hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. }
                                => {
                                self.consume_expr(in_expr)?;
                                if let Some(out_expr) = out_expr {
                                    self.mutate_expr(out_expr)?;
                                }
                            }
                            hir::InlineAsmOperand::Out { expr: None, .. } |
                                hir::InlineAsmOperand::Const { .. } |
                                hir::InlineAsmOperand::SymFn { .. } |
                                hir::InlineAsmOperand::SymStatic { .. } => {}
                            hir::InlineAsmOperand::Label { block } => {
                                self.walk_block(block)?;
                            }
                        }
                    }
                }
                hir::ExprKind::Continue(..) | hir::ExprKind::Lit(..) |
                    hir::ExprKind::ConstBlock(..) | hir::ExprKind::OffsetOf(..)
                    | hir::ExprKind::Err(_) => {}
                hir::ExprKind::Loop(blk, ..) => { self.walk_block(blk)?; }
                hir::ExprKind::Unary(_, lhs) => { self.consume_expr(lhs)?; }
                hir::ExprKind::Binary(_, lhs, rhs) => {
                    self.consume_expr(lhs)?;
                    self.consume_expr(rhs)?;
                }
                hir::ExprKind::Block(blk, _) => { self.walk_block(blk)?; }
                hir::ExprKind::Break(_, ref opt_expr) |
                    hir::ExprKind::Ret(ref opt_expr) => {
                    if let Some(expr) = *opt_expr { self.consume_expr(expr)?; }
                }
                hir::ExprKind::Become(call) => { self.consume_expr(call)?; }
                hir::ExprKind::Assign(lhs, rhs, _) => {
                    self.mutate_expr(lhs)?;
                    self.consume_expr(rhs)?;
                }
                hir::ExprKind::Cast(base, _) => { self.consume_expr(base)?; }
                hir::ExprKind::DropTemps(expr) => {
                    self.consume_expr(expr)?;
                }
                hir::ExprKind::AssignOp(_, lhs, rhs) => {
                    if self.cx.typeck_results().is_method_call(expr) {
                        self.consume_expr(lhs)?;
                    } else { self.mutate_expr(lhs)?; }
                    self.consume_expr(rhs)?;
                }
                hir::ExprKind::Repeat(base, _) => {
                    self.consume_expr(base)?;
                }
                hir::ExprKind::Closure(closure) => {
                    self.walk_captures(closure)?;
                }
                hir::ExprKind::Yield(value, _) => {
                    self.consume_expr(value)?;
                }
            }
            Ok(())
        }
    }
}#[instrument(skip(self), level = "debug")]
391    pub fn walk_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
392        self.walk_adjustment(expr)?;
393
394        match expr.kind {
395            hir::ExprKind::Path(_) => {}
396
397            hir::ExprKind::Type(subexpr, _) => {
398                self.walk_expr(subexpr)?;
399            }
400
401            hir::ExprKind::UnsafeBinderCast(_, subexpr, _) => {
402                self.walk_expr(subexpr)?;
403            }
404
405            hir::ExprKind::Unary(hir::UnOp::Deref, base) => {
406                // *base
407                self.walk_expr(base)?;
408            }
409
410            hir::ExprKind::Field(base, _) => {
411                // base.f
412                self.walk_expr(base)?;
413            }
414
415            hir::ExprKind::Index(lhs, rhs, _) => {
416                // lhs[rhs]
417                self.walk_expr(lhs)?;
418                self.consume_expr(rhs)?;
419            }
420
421            hir::ExprKind::Call(callee, args) => {
422                // callee(args)
423                self.consume_expr(callee)?;
424                self.consume_exprs(args)?;
425            }
426
427            hir::ExprKind::Use(expr, _) => {
428                self.consume_or_clone_expr(expr)?;
429            }
430
431            hir::ExprKind::MethodCall(.., receiver, args, _) => {
432                // callee.m(args)
433                self.consume_expr(receiver)?;
434                self.consume_exprs(args)?;
435            }
436
437            hir::ExprKind::Struct(_, fields, ref opt_with) => {
438                self.walk_struct_expr(fields, opt_with)?;
439            }
440
441            hir::ExprKind::Tup(exprs) => {
442                self.consume_exprs(exprs)?;
443            }
444
445            hir::ExprKind::If(cond_expr, then_expr, ref opt_else_expr) => {
446                self.consume_expr(cond_expr)?;
447                self.consume_expr(then_expr)?;
448                if let Some(else_expr) = *opt_else_expr {
449                    self.consume_expr(else_expr)?;
450                }
451            }
452
453            hir::ExprKind::Let(hir::LetExpr { pat, init, .. }) => {
454                self.walk_local(init, pat, None, || self.borrow_expr(init, BorrowKind::Immutable))?;
455            }
456
457            hir::ExprKind::Match(discr, arms, _) => {
458                let discr_place = self.cat_expr(discr)?;
459                self.fake_read_scrutinee(&discr_place, true)?;
460                self.walk_expr(discr)?;
461
462                for arm in arms {
463                    self.walk_arm(&discr_place, arm)?;
464                }
465            }
466
467            hir::ExprKind::Array(exprs) => {
468                self.consume_exprs(exprs)?;
469            }
470
471            hir::ExprKind::AddrOf(_, m, base) => {
472                // &base
473                // make sure that the thing we are pointing out stays valid
474                // for the lifetime `scope_r` of the resulting ptr:
475                let bk = ty::BorrowKind::from_mutbl(m);
476                self.borrow_expr(base, bk)?;
477            }
478
479            hir::ExprKind::InlineAsm(asm) => {
480                for (op, _op_sp) in asm.operands {
481                    match op {
482                        hir::InlineAsmOperand::In { expr, .. } => {
483                            self.consume_expr(expr)?;
484                        }
485                        hir::InlineAsmOperand::Out { expr: Some(expr), .. }
486                        | hir::InlineAsmOperand::InOut { expr, .. } => {
487                            self.mutate_expr(expr)?;
488                        }
489                        hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
490                            self.consume_expr(in_expr)?;
491                            if let Some(out_expr) = out_expr {
492                                self.mutate_expr(out_expr)?;
493                            }
494                        }
495                        hir::InlineAsmOperand::Out { expr: None, .. }
496                        | hir::InlineAsmOperand::Const { .. }
497                        | hir::InlineAsmOperand::SymFn { .. }
498                        | hir::InlineAsmOperand::SymStatic { .. } => {}
499                        hir::InlineAsmOperand::Label { block } => {
500                            self.walk_block(block)?;
501                        }
502                    }
503                }
504            }
505
506            hir::ExprKind::Continue(..)
507            | hir::ExprKind::Lit(..)
508            | hir::ExprKind::ConstBlock(..)
509            | hir::ExprKind::OffsetOf(..)
510            | hir::ExprKind::Err(_) => {}
511
512            hir::ExprKind::Loop(blk, ..) => {
513                self.walk_block(blk)?;
514            }
515
516            hir::ExprKind::Unary(_, lhs) => {
517                self.consume_expr(lhs)?;
518            }
519
520            hir::ExprKind::Binary(_, lhs, rhs) => {
521                self.consume_expr(lhs)?;
522                self.consume_expr(rhs)?;
523            }
524
525            hir::ExprKind::Block(blk, _) => {
526                self.walk_block(blk)?;
527            }
528
529            hir::ExprKind::Break(_, ref opt_expr) | hir::ExprKind::Ret(ref opt_expr) => {
530                if let Some(expr) = *opt_expr {
531                    self.consume_expr(expr)?;
532                }
533            }
534
535            hir::ExprKind::Become(call) => {
536                self.consume_expr(call)?;
537            }
538
539            hir::ExprKind::Assign(lhs, rhs, _) => {
540                self.mutate_expr(lhs)?;
541                self.consume_expr(rhs)?;
542            }
543
544            hir::ExprKind::Cast(base, _) => {
545                self.consume_expr(base)?;
546            }
547
548            hir::ExprKind::DropTemps(expr) => {
549                self.consume_expr(expr)?;
550            }
551
552            hir::ExprKind::AssignOp(_, lhs, rhs) => {
553                if self.cx.typeck_results().is_method_call(expr) {
554                    self.consume_expr(lhs)?;
555                } else {
556                    self.mutate_expr(lhs)?;
557                }
558                self.consume_expr(rhs)?;
559            }
560
561            hir::ExprKind::Repeat(base, _) => {
562                self.consume_expr(base)?;
563            }
564
565            hir::ExprKind::Closure(closure) => {
566                self.walk_captures(closure)?;
567            }
568
569            hir::ExprKind::Yield(value, _) => {
570                self.consume_expr(value)?;
571            }
572        }
573
574        Ok(())
575    }
576
577    fn walk_stmt(&self, stmt: &hir::Stmt<'_>) -> Result<(), Cx::Error> {
578        match stmt.kind {
579            hir::StmtKind::Let(hir::LetStmt { pat, init: Some(expr), els, .. }) => {
580                self.walk_local(expr, pat, *els, || Ok(()))?;
581            }
582
583            hir::StmtKind::Let(_) => {}
584
585            hir::StmtKind::Item(_) => {
586                // We don't visit nested items in this visitor,
587                // only the fn body we were given.
588            }
589
590            hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) => {
591                self.consume_expr(expr)?;
592            }
593        }
594
595        Ok(())
596    }
597
598    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("fake_read_scrutinee",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(598u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["discr_place",
                                                    "refutable"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&discr_place)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&refutable 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: Result<(), Cx::Error> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let closure_def_id =
                match discr_place.place.base {
                    PlaceBase::Upvar(upvar_id) =>
                        Some(upvar_id.closure_expr_id),
                    _ => None,
                };
            let cause =
                if refutable {
                    FakeReadCause::ForMatchedPlace(closure_def_id)
                } else { FakeReadCause::ForLet(closure_def_id) };
            self.delegate.borrow_mut().fake_read(discr_place, cause,
                discr_place.hir_id);
            Ok(())
        }
    }
}#[instrument(skip(self), level = "debug")]
599    fn fake_read_scrutinee(
600        &self,
601        discr_place: &PlaceWithHirId<'tcx>,
602        refutable: bool,
603    ) -> Result<(), Cx::Error> {
604        let closure_def_id = match discr_place.place.base {
605            PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id),
606            _ => None,
607        };
608
609        let cause = if refutable {
610            FakeReadCause::ForMatchedPlace(closure_def_id)
611        } else {
612            FakeReadCause::ForLet(closure_def_id)
613        };
614
615        self.delegate.borrow_mut().fake_read(discr_place, cause, discr_place.hir_id);
616
617        Ok(())
618    }
619
620    fn walk_local<F>(
621        &self,
622        expr: &hir::Expr<'_>,
623        pat: &hir::Pat<'_>,
624        els: Option<&hir::Block<'_>>,
625        mut f: F,
626    ) -> Result<(), Cx::Error>
627    where
628        F: FnMut() -> Result<(), Cx::Error>,
629    {
630        self.walk_expr(expr)?;
631        let expr_place = self.cat_expr(expr)?;
632        f()?;
633        self.fake_read_scrutinee(&expr_place, els.is_some())?;
634        self.walk_pat(&expr_place, pat, false)?;
635        if let Some(els) = els {
636            self.walk_block(els)?;
637        }
638        Ok(())
639    }
640
641    /// Indicates that the value of `blk` will be consumed, meaning either copied or moved
642    /// depending on its type.
643    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("walk_block",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(643u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["blk"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&blk)
                                                            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: Result<(), Cx::Error> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            for stmt in blk.stmts { self.walk_stmt(stmt)?; }
            if let Some(tail_expr) = blk.expr {
                self.consume_expr(tail_expr)?;
            }
            Ok(())
        }
    }
}#[instrument(skip(self), level = "debug")]
644    fn walk_block(&self, blk: &hir::Block<'_>) -> Result<(), Cx::Error> {
645        for stmt in blk.stmts {
646            self.walk_stmt(stmt)?;
647        }
648
649        if let Some(tail_expr) = blk.expr {
650            self.consume_expr(tail_expr)?;
651        }
652
653        Ok(())
654    }
655
656    fn walk_struct_expr<'hir>(
657        &self,
658        fields: &[hir::ExprField<'_>],
659        opt_with: &hir::StructTailExpr<'hir>,
660    ) -> Result<(), Cx::Error> {
661        // Consume the expressions supplying values for each field.
662        for field in fields {
663            self.consume_expr(field.expr)?;
664
665            // The struct path probably didn't resolve
666            if self.cx.typeck_results().opt_field_index(field.hir_id).is_none() {
667                self.cx
668                    .tcx()
669                    .dcx()
670                    .span_delayed_bug(field.span, "couldn't resolve index for field");
671            }
672        }
673
674        let with_expr = match *opt_with {
675            hir::StructTailExpr::Base(w) => &*w,
676            hir::StructTailExpr::DefaultFields(_)
677            | hir::StructTailExpr::None
678            | hir::StructTailExpr::NoneWithError(_) => {
679                return Ok(());
680            }
681        };
682
683        let with_place = self.cat_expr(with_expr)?;
684
685        // Select just those fields of the `with`
686        // expression that will actually be used
687        match self.cx.structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() {
688            ty::Adt(adt, args) if adt.is_struct() => {
689                // Consume those fields of the with expression that are needed.
690                for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() {
691                    let is_mentioned = fields.iter().any(|f| {
692                        self.cx.typeck_results().opt_field_index(f.hir_id) == Some(f_index)
693                    });
694                    if !is_mentioned {
695                        let field_place = self.cat_projection(
696                            with_expr.hir_id,
697                            with_place.clone(),
698                            with_field.ty(self.cx.tcx(), args).skip_norm_wip(),
699                            ProjectionKind::Field(f_index, FIRST_VARIANT),
700                        );
701                        self.consume_or_copy(&field_place, field_place.hir_id);
702                    }
703                }
704            }
705            _ => {
706                // the base expression should always evaluate to a
707                // struct; however, when EUV is run during typeck, it
708                // may not. This will generate an error earlier in typeck,
709                // so we can just ignore it.
710                if self.cx.tainted_by_errors().is_ok() {
711                    ::rustc_middle::util::bug::span_bug_fmt(with_expr.span,
    format_args!("with expression doesn\'t evaluate to a struct"));span_bug!(with_expr.span, "with expression doesn't evaluate to a struct");
712                }
713            }
714        }
715
716        // walk the with expression so that complex expressions
717        // are properly handled.
718        self.walk_expr(with_expr)?;
719
720        Ok(())
721    }
722
723    /// Invoke the appropriate delegate calls for anything that gets
724    /// consumed or borrowed as part of the automatic adjustment
725    /// process.
726    fn walk_adjustment(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
727        let typeck_results = self.cx.typeck_results();
728        let adjustments = typeck_results.expr_adjustments(expr);
729        let mut place_with_id = self.cat_expr_unadjusted(expr)?;
730        for adjustment in adjustments {
731            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:731",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(731u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("walk_adjustment expr={0:?} adj={1:?}",
                                                    expr, adjustment) as &dyn Value))])
            });
    } else { ; }
};debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment);
732            match adjustment.kind {
733                adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) => {
734                    // Creating a closure/fn-pointer or unsizing consumes
735                    // the input and stores it into the resulting rvalue.
736                    self.consume_or_copy(&place_with_id, place_with_id.hir_id);
737                }
738
739                adjustment::Adjust::Deref(DerefAdjustKind::Builtin | DerefAdjustKind::Pin) => {}
740
741                // Autoderefs for overloaded Deref calls in fact reference
742                // their receiver. That is, if we have `(*x)` where `x`
743                // is of type `Rc<T>`, then this in fact is equivalent to
744                // `x.deref()`. Since `deref()` is declared with `&self`,
745                // this is an autoref of `x`.
746                adjustment::Adjust::Deref(DerefAdjustKind::Overloaded(deref)) => {
747                    let bk = ty::BorrowKind::from_mutbl(deref.mutbl);
748                    self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
749                }
750
751                adjustment::Adjust::Borrow(ref autoref) => {
752                    self.walk_autoref(expr, &place_with_id, autoref);
753                }
754
755                adjustment::Adjust::GenericReborrow(_reborrow) => {
756                    // To build an expression as a place expression, it needs to be a field
757                    // projection or deref at the outmost layer. So it is field projection or deref
758                    // on an adjusted value. But this means that adjustment is applied on a
759                    // subexpression that is not the final operand/rvalue for function call or
760                    // assignment. This is a contradiction.
761                    {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("Reborrow trait usage during adjustment walk")));
};unreachable!("Reborrow trait usage during adjustment walk");
762                }
763            }
764            place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?;
765        }
766
767        Ok(())
768    }
769
770    /// Walks the autoref `autoref` applied to the autoderef'd
771    /// `expr`. `base_place` is `expr` represented as a place,
772    /// after all relevant autoderefs have occurred.
773    fn walk_autoref(
774        &self,
775        expr: &hir::Expr<'_>,
776        base_place: &PlaceWithHirId<'tcx>,
777        autoref: &adjustment::AutoBorrow,
778    ) {
779        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:779",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(779u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("walk_autoref(expr.hir_id={0} base_place={1:?} autoref={2:?})",
                                                    expr.hir_id, base_place, autoref) as &dyn Value))])
            });
    } else { ; }
};debug!(
780            "walk_autoref(expr.hir_id={} base_place={:?} autoref={:?})",
781            expr.hir_id, base_place, autoref
782        );
783
784        match *autoref {
785            adjustment::AutoBorrow::Ref(m) => {
786                self.delegate.borrow_mut().borrow(
787                    base_place,
788                    base_place.hir_id,
789                    ty::BorrowKind::from_mutbl(m.into()),
790                );
791            }
792
793            adjustment::AutoBorrow::RawPtr(m) | adjustment::AutoBorrow::Pin(m) => {
794                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:794",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(794u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("walk_autoref: expr.hir_id={0} base_place={1:?}",
                                                    expr.hir_id, base_place) as &dyn Value))])
            });
    } else { ; }
};debug!("walk_autoref: expr.hir_id={} base_place={:?}", expr.hir_id, base_place);
795
796                self.delegate.borrow_mut().borrow(
797                    base_place,
798                    base_place.hir_id,
799                    ty::BorrowKind::from_mutbl(m),
800                );
801            }
802        }
803    }
804
805    fn walk_arm(
806        &self,
807        discr_place: &PlaceWithHirId<'tcx>,
808        arm: &hir::Arm<'_>,
809    ) -> Result<(), Cx::Error> {
810        self.walk_pat(discr_place, arm.pat, arm.guard.is_some())?;
811
812        if let Some(ref e) = arm.guard {
813            self.consume_expr(e)?;
814        }
815
816        self.consume_expr(arm.body)?;
817        Ok(())
818    }
819
820    /// The core driver for walking a pattern
821    ///
822    /// This should mirror how pattern-matching gets lowered to MIR, as
823    /// otherwise said lowering will ICE when trying to resolve the upvars.
824    ///
825    /// However, it is okay to approximate it here by doing *more* accesses than
826    /// the actual MIR builder will, which is useful when some checks are too
827    /// cumbersome to perform here, because e.g. they require more typeck results
828    /// than available.
829    ///
830    /// Do note that discrepancies like these do still create obscure corners
831    /// in the semantics of the language, and should be avoided if possible.
832    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("walk_pat",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(832u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["discr_place", "pat",
                                                    "has_guard"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&discr_place)
                                                            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(&pat)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&has_guard 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: Result<(), Cx::Error> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let tcx = self.cx.tcx();
            self.cat_pattern(discr_place.clone(), pat,
                &mut |place, pat|
                        {
                            {
                                use ::tracing::__macro_support::Callsite as _;
                                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                    {
                                        static META: ::tracing::Metadata<'static> =
                                            {
                                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:841",
                                                    "rustc_hir_typeck::expr_use_visitor",
                                                    ::tracing::Level::DEBUG,
                                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                                    ::tracing_core::__macro_support::Option::Some(841u32),
                                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                                    ::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!("walk_pat: pat.kind={0:?}",
                                                                                pat.kind) as &dyn Value))])
                                        });
                                } else { ; }
                            };
                            let read_discriminant =
                                ||
                                    {
                                        self.delegate.borrow_mut().borrow(place, discr_place.hir_id,
                                            BorrowKind::Immutable);
                                    };
                            match pat.kind {
                                PatKind::Binding(_, canonical_id, ..) => {
                                    {
                                        use ::tracing::__macro_support::Callsite as _;
                                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                            {
                                                static META: ::tracing::Metadata<'static> =
                                                    {
                                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:848",
                                                            "rustc_hir_typeck::expr_use_visitor",
                                                            ::tracing::Level::DEBUG,
                                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                                            ::tracing_core::__macro_support::Option::Some(848u32),
                                                            ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                                            ::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!("walk_pat: binding place={0:?} pat={1:?}",
                                                                                        place, pat) as &dyn Value))])
                                                });
                                        } else { ; }
                                    };
                                    let bm =
                                        self.cx.typeck_results().extract_binding_mode(tcx.sess,
                                            pat.hir_id, pat.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_hir_typeck/src/expr_use_visitor.rs:853",
                                                            "rustc_hir_typeck::expr_use_visitor",
                                                            ::tracing::Level::DEBUG,
                                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                                            ::tracing_core::__macro_support::Option::Some(853u32),
                                                            ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                                            ::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!("walk_pat: pat.hir_id={0:?} bm={1:?}",
                                                                                        pat.hir_id, bm) as &dyn Value))])
                                                });
                                        } else { ; }
                                    };
                                    let pat_ty = self.node_ty(pat.hir_id)?;
                                    {
                                        use ::tracing::__macro_support::Callsite as _;
                                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                            {
                                                static META: ::tracing::Metadata<'static> =
                                                    {
                                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:857",
                                                            "rustc_hir_typeck::expr_use_visitor",
                                                            ::tracing::Level::DEBUG,
                                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                                            ::tracing_core::__macro_support::Option::Some(857u32),
                                                            ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                                            ::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!("walk_pat: pat_ty={0:?}",
                                                                                        pat_ty) as &dyn Value))])
                                                });
                                        } else { ; }
                                    };
                                    let def = Res::Local(canonical_id);
                                    if let Ok(ref binding_place) =
                                            self.cat_res(pat.hir_id, pat.span, pat_ty, def) {
                                        self.delegate.borrow_mut().bind(binding_place,
                                            binding_place.hir_id);
                                    }
                                    if has_guard { read_discriminant(); }
                                    match bm.0 {
                                        hir::ByRef::Yes(_, m) => {
                                            let bk = ty::BorrowKind::from_mutbl(m);
                                            self.delegate.borrow_mut().borrow(place, discr_place.hir_id,
                                                bk);
                                        }
                                        hir::ByRef::No => {
                                            {
                                                use ::tracing::__macro_support::Callsite as _;
                                                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                                    {
                                                        static META: ::tracing::Metadata<'static> =
                                                            {
                                                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:881",
                                                                    "rustc_hir_typeck::expr_use_visitor",
                                                                    ::tracing::Level::DEBUG,
                                                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                                                    ::tracing_core::__macro_support::Option::Some(881u32),
                                                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                                                    ::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!("walk_pat binding consuming pat")
                                                                                        as &dyn Value))])
                                                        });
                                                } else { ; }
                                            };
                                            self.consume_or_copy(place, discr_place.hir_id);
                                        }
                                    }
                                }
                                PatKind::Deref(subpattern) => {
                                    if let DerefPatBorrowMode::Borrow(mutability) =
                                            self.cx.typeck_results().deref_pat_borrow_mode(place.place.ty(),
                                                subpattern) {
                                        let bk = ty::BorrowKind::from_mutbl(mutability);
                                        self.delegate.borrow_mut().borrow(place, discr_place.hir_id,
                                            bk);
                                    }
                                }
                                PatKind::Never => { read_discriminant(); }
                                PatKind::Expr(PatExpr {
                                    kind: PatExprKind::Path(qpath), hir_id, span }) => {
                                    let res =
                                        self.cx.typeck_results().qpath_res(qpath, *hir_id);
                                    match res {
                                        Res::Def(DefKind::Const { .. }, _) |
                                            Res::Def(DefKind::AssocConst { .. }, _) => {
                                            read_discriminant();
                                        }
                                        _ => {
                                            if self.is_multivariant_adt(place.place.ty(), *span) {
                                                read_discriminant();
                                            }
                                        }
                                    }
                                }
                                PatKind::Expr(_) | PatKind::Range(..) => {
                                    read_discriminant();
                                }
                                PatKind::Struct(..) | PatKind::TupleStruct(..) => {
                                    if self.is_multivariant_adt(place.place.ty(), pat.span) {
                                        read_discriminant();
                                    }
                                }
                                PatKind::Slice(lhs, wild, rhs) => {
                                    if #[allow(non_exhaustive_omitted_patterns)] match (lhs,
                                                    wild, rhs) {
                                                (&[], Some(_), &[]) => true,
                                                _ => false,
                                            } || place.place.ty().peel_refs().is_array()
                                        {} else { read_discriminant(); }
                                }
                                PatKind::Or(_) | PatKind::Box(_) | PatKind::Ref(..) |
                                    PatKind::Guard(..) | PatKind::Tuple(..) | PatKind::Wild |
                                    PatKind::Missing | PatKind::Err(_) => {}
                            }
                            Ok(())
                        })
        }
    }
}#[instrument(skip(self), level = "debug")]
833    fn walk_pat(
834        &self,
835        discr_place: &PlaceWithHirId<'tcx>,
836        pat: &hir::Pat<'_>,
837        has_guard: bool,
838    ) -> Result<(), Cx::Error> {
839        let tcx = self.cx.tcx();
840        self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| {
841            debug!("walk_pat: pat.kind={:?}", pat.kind);
842            let read_discriminant = || {
843                self.delegate.borrow_mut().borrow(place, discr_place.hir_id, BorrowKind::Immutable);
844            };
845
846            match pat.kind {
847                PatKind::Binding(_, canonical_id, ..) => {
848                    debug!("walk_pat: binding place={:?} pat={:?}", place, pat);
849                    let bm = self
850                        .cx
851                        .typeck_results()
852                        .extract_binding_mode(tcx.sess, pat.hir_id, pat.span);
853                    debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
854
855                    // pat_ty: the type of the binding being produced.
856                    let pat_ty = self.node_ty(pat.hir_id)?;
857                    debug!("walk_pat: pat_ty={:?}", pat_ty);
858
859                    let def = Res::Local(canonical_id);
860                    if let Ok(ref binding_place) = self.cat_res(pat.hir_id, pat.span, pat_ty, def) {
861                        self.delegate.borrow_mut().bind(binding_place, binding_place.hir_id);
862                    }
863
864                    // Subtle: MIR desugaring introduces immutable borrows for each pattern
865                    // binding when lowering pattern guards to ensure that the guard does not
866                    // modify the scrutinee.
867                    if has_guard {
868                        read_discriminant();
869                    }
870
871                    // It is also a borrow or copy/move of the value being matched.
872                    // In a cases of pattern like `let pat = upvar`, don't use the span
873                    // of the pattern, as this just looks confusing, instead use the span
874                    // of the discriminant.
875                    match bm.0 {
876                        hir::ByRef::Yes(_, m) => {
877                            let bk = ty::BorrowKind::from_mutbl(m);
878                            self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk);
879                        }
880                        hir::ByRef::No => {
881                            debug!("walk_pat binding consuming pat");
882                            self.consume_or_copy(place, discr_place.hir_id);
883                        }
884                    }
885                }
886                PatKind::Deref(subpattern) => {
887                    // A deref pattern is a bit special: the binding mode of its inner bindings
888                    // determines whether to borrow *at the level of the deref pattern* rather than
889                    // borrowing the bound place (since that inner place is inside the temporary that
890                    // stores the result of calling `deref()`/`deref_mut()` so can't be captured).
891                    // Deref patterns on boxes don't borrow, so we ignore them here.
892                    // HACK: this could be a fake pattern corresponding to a deref inserted by match
893                    // ergonomics, in which case `pat.hir_id` will be the id of the subpattern.
894                    if let DerefPatBorrowMode::Borrow(mutability) =
895                        self.cx.typeck_results().deref_pat_borrow_mode(place.place.ty(), subpattern)
896                    {
897                        let bk = ty::BorrowKind::from_mutbl(mutability);
898                        self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk);
899                    }
900                }
901                PatKind::Never => {
902                    // A `!` pattern always counts as an immutable read of the discriminant,
903                    // even in an irrefutable pattern.
904                    read_discriminant();
905                }
906                PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
907                    // A `Path` pattern is just a name like `Foo`. This is either a
908                    // named constant or else it refers to an ADT variant
909
910                    let res = self.cx.typeck_results().qpath_res(qpath, *hir_id);
911                    match res {
912                        Res::Def(DefKind::Const { .. }, _)
913                        | Res::Def(DefKind::AssocConst { .. }, _) => {
914                            // Named constants have to be equated with the value
915                            // being matched, so that's a read of the value being matched.
916                            //
917                            // FIXME: Does the MIR code skip this read when matching on a ZST?
918                            // If so, we can also skip it here.
919                            read_discriminant();
920                        }
921                        _ => {
922                            // Otherwise, this is a struct/enum variant, and so it's
923                            // only a read if we need to read the discriminant.
924                            if self.is_multivariant_adt(place.place.ty(), *span) {
925                                read_discriminant();
926                            }
927                        }
928                    }
929                }
930                PatKind::Expr(_) | PatKind::Range(..) => {
931                    // When matching against a literal or range, we need to
932                    // borrow the place to compare it against the pattern.
933                    //
934                    // Note that we do this read even if the range matches all
935                    // possible values, such as 0..=u8::MAX. This is because
936                    // we don't want to depend on consteval here.
937                    //
938                    // FIXME: What if the type being matched only has one
939                    // possible value?
940                    read_discriminant();
941                }
942                PatKind::Struct(..) | PatKind::TupleStruct(..) => {
943                    if self.is_multivariant_adt(place.place.ty(), pat.span) {
944                        read_discriminant();
945                    }
946                }
947                PatKind::Slice(lhs, wild, rhs) => {
948                    // We don't need to test the length if the pattern is `[..]`
949                    if matches!((lhs, wild, rhs), (&[], Some(_), &[]))
950                        // Arrays have a statically known size, so
951                        // there is no need to read their length
952                        || place.place.ty().peel_refs().is_array()
953                    {
954                        // No read necessary
955                    } else {
956                        read_discriminant();
957                    }
958                }
959                PatKind::Or(_)
960                | PatKind::Box(_)
961                | PatKind::Ref(..)
962                | PatKind::Guard(..)
963                | PatKind::Tuple(..)
964                | PatKind::Wild
965                | PatKind::Missing
966                | PatKind::Err(_) => {
967                    // If the PatKind is Or, Box, Ref, Guard, or Tuple, the relevant accesses
968                    // are made later as these patterns contains subpatterns.
969                    // If the PatKind is Missing, Wild or Err, any relevant accesses are made when processing
970                    // the other patterns that are part of the match
971                }
972            }
973
974            Ok(())
975        })
976    }
977
978    /// Handle the case where the current body contains a closure.
979    ///
980    /// When the current body being handled is a closure, then we must make sure that
981    /// - The parent closure only captures Places from the nested closure that are not local to it.
982    ///
983    /// In the following example the closures `c` only captures `p.x` even though `incr`
984    /// is a capture of the nested closure
985    ///
986    /// ```
987    /// struct P { x: i32 }
988    /// let mut p = P { x: 4 };
989    /// let c = || {
990    ///    let incr = 10;
991    ///    let nested = || p.x += incr;
992    /// };
993    /// ```
994    ///
995    /// - When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing
996    /// closure as the DefId.
997    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("walk_captures",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(997u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["closure_expr"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&closure_expr)
                                                            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: Result<(), Cx::Error> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            fn upvar_is_local_variable(upvars:
                    Option<&FxIndexMap<HirId, hir::Upvar>>, upvar_id: HirId,
                body_owner_is_closure: bool) -> bool {
                upvars.map(|upvars|
                            !upvars.contains_key(&upvar_id)).unwrap_or(body_owner_is_closure)
            }
            let tcx = self.cx.tcx();
            let closure_def_id = closure_expr.def_id;
            let body_owner_is_closure =
                #[allow(non_exhaustive_omitted_patterns)] match tcx.hir_body_owner_kind(self.cx.body_owner_def_id())
                    {
                    hir::BodyOwnerKind::Closure => true,
                    _ => false,
                };
            if let Some(fake_reads) =
                    self.cx.typeck_results().closure_fake_reads.get(&closure_def_id)
                {
                for (fake_read, cause, hir_id) in fake_reads.iter() {
                    match fake_read.base {
                        PlaceBase::Upvar(upvar_id) => {
                            if upvar_is_local_variable(self.upvars,
                                    upvar_id.var_path.hir_id, body_owner_is_closure) {
                                continue;
                            }
                        }
                        _ => {
                            ::rustc_middle::util::bug::bug_fmt(format_args!("Do not know how to get HirId out of Rvalue and StaticItem {0:?}",
                                    fake_read.base));
                        }
                    };
                    self.delegate.borrow_mut().fake_read(&PlaceWithHirId {
                                place: fake_read.clone(),
                                hir_id: *hir_id,
                            }, *cause, *hir_id);
                }
            }
            if let Some(min_captures) =
                    self.cx.typeck_results().closure_min_captures.get(&closure_def_id)
                {
                for (var_hir_id, min_list) in min_captures.iter() {
                    if self.upvars.map_or(body_owner_is_closure,
                            |upvars| !upvars.contains_key(var_hir_id)) {
                        continue;
                    }
                    for captured_place in min_list {
                        let place = &captured_place.place;
                        let capture_info = captured_place.info;
                        let place_base =
                            if body_owner_is_closure {
                                PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id,
                                        self.cx.body_owner_def_id()))
                            } else { PlaceBase::Local(*var_hir_id) };
                        let closure_hir_id =
                            tcx.local_def_id_to_hir_id(closure_def_id);
                        let place_with_id =
                            PlaceWithHirId::new(capture_info.path_expr_id.unwrap_or(capture_info.capture_kind_expr_id.unwrap_or(closure_hir_id)),
                                place.base_ty, place_base, place.projections.clone());
                        match capture_info.capture_kind {
                            ty::UpvarCapture::ByValue => {
                                self.consume_or_copy(&place_with_id, place_with_id.hir_id);
                            }
                            ty::UpvarCapture::ByUse => {
                                self.consume_clone_or_copy(&place_with_id,
                                    place_with_id.hir_id);
                            }
                            ty::UpvarCapture::ByRef(upvar_borrow) => {
                                self.delegate.borrow_mut().borrow(&place_with_id,
                                    place_with_id.hir_id, upvar_borrow);
                            }
                        }
                    }
                }
            }
            Ok(())
        }
    }
}#[instrument(skip(self), level = "debug")]
998    fn walk_captures(&self, closure_expr: &hir::Closure<'_>) -> Result<(), Cx::Error> {
999        fn upvar_is_local_variable(
1000            upvars: Option<&FxIndexMap<HirId, hir::Upvar>>,
1001            upvar_id: HirId,
1002            body_owner_is_closure: bool,
1003        ) -> bool {
1004            upvars.map(|upvars| !upvars.contains_key(&upvar_id)).unwrap_or(body_owner_is_closure)
1005        }
1006
1007        let tcx = self.cx.tcx();
1008        let closure_def_id = closure_expr.def_id;
1009        // For purposes of this function, coroutine and closures are equivalent.
1010        let body_owner_is_closure = matches!(
1011            tcx.hir_body_owner_kind(self.cx.body_owner_def_id()),
1012            hir::BodyOwnerKind::Closure
1013        );
1014
1015        // If we have a nested closure, we want to include the fake reads present in the nested
1016        // closure.
1017        if let Some(fake_reads) = self.cx.typeck_results().closure_fake_reads.get(&closure_def_id) {
1018            for (fake_read, cause, hir_id) in fake_reads.iter() {
1019                match fake_read.base {
1020                    PlaceBase::Upvar(upvar_id) => {
1021                        if upvar_is_local_variable(
1022                            self.upvars,
1023                            upvar_id.var_path.hir_id,
1024                            body_owner_is_closure,
1025                        ) {
1026                            // The nested closure might be fake reading the current (enclosing) closure's local variables.
1027                            // The only places we want to fake read before creating the parent closure are the ones that
1028                            // are not local to it/ defined by it.
1029                            //
1030                            // ```rust,ignore(cannot-test-this-because-pseudo-code)
1031                            // let v1 = (0, 1);
1032                            // let c = || { // fake reads: v1
1033                            //    let v2 = (0, 1);
1034                            //    let e = || { // fake reads: v1, v2
1035                            //       let (_, t1) = v1;
1036                            //       let (_, t2) = v2;
1037                            //    }
1038                            // }
1039                            // ```
1040                            // This check is performed when visiting the body of the outermost closure (`c`) and ensures
1041                            // that we don't add a fake read of v2 in c.
1042                            continue;
1043                        }
1044                    }
1045                    _ => {
1046                        bug!(
1047                            "Do not know how to get HirId out of Rvalue and StaticItem {:?}",
1048                            fake_read.base
1049                        );
1050                    }
1051                };
1052                self.delegate.borrow_mut().fake_read(
1053                    &PlaceWithHirId { place: fake_read.clone(), hir_id: *hir_id },
1054                    *cause,
1055                    *hir_id,
1056                );
1057            }
1058        }
1059
1060        if let Some(min_captures) =
1061            self.cx.typeck_results().closure_min_captures.get(&closure_def_id)
1062        {
1063            for (var_hir_id, min_list) in min_captures.iter() {
1064                if self
1065                    .upvars
1066                    .map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id))
1067                {
1068                    // The nested closure might be capturing the current (enclosing) closure's local variables.
1069                    // We check if the root variable is ever mentioned within the enclosing closure, if not
1070                    // then for the current body (if it's a closure) these aren't captures, we will ignore them.
1071                    continue;
1072                }
1073                for captured_place in min_list {
1074                    let place = &captured_place.place;
1075                    let capture_info = captured_place.info;
1076
1077                    let place_base = if body_owner_is_closure {
1078                        // Mark the place to be captured by the enclosing closure
1079                        PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.cx.body_owner_def_id()))
1080                    } else {
1081                        // If the body owner isn't a closure then the variable must
1082                        // be a local variable
1083                        PlaceBase::Local(*var_hir_id)
1084                    };
1085                    let closure_hir_id = tcx.local_def_id_to_hir_id(closure_def_id);
1086                    let place_with_id = PlaceWithHirId::new(
1087                        capture_info
1088                            .path_expr_id
1089                            .unwrap_or(capture_info.capture_kind_expr_id.unwrap_or(closure_hir_id)),
1090                        place.base_ty,
1091                        place_base,
1092                        place.projections.clone(),
1093                    );
1094
1095                    match capture_info.capture_kind {
1096                        ty::UpvarCapture::ByValue => {
1097                            self.consume_or_copy(&place_with_id, place_with_id.hir_id);
1098                        }
1099                        ty::UpvarCapture::ByUse => {
1100                            self.consume_clone_or_copy(&place_with_id, place_with_id.hir_id);
1101                        }
1102                        ty::UpvarCapture::ByRef(upvar_borrow) => {
1103                            self.delegate.borrow_mut().borrow(
1104                                &place_with_id,
1105                                place_with_id.hir_id,
1106                                upvar_borrow,
1107                            );
1108                        }
1109                    }
1110                }
1111            }
1112        }
1113
1114        Ok(())
1115    }
1116}
1117
1118/// The job of the methods whose name starts with `cat_` is to analyze
1119/// expressions and construct the corresponding [`Place`]s. The `cat`
1120/// stands for "categorize", this is a leftover from long ago when
1121/// places were called "categorizations".
1122///
1123/// Note that a [`Place`] differs somewhat from the expression itself. For
1124/// example, auto-derefs are explicit. Also, an index `a[b]` is decomposed into
1125/// two operations: a dereference to reach the array data and then an index to
1126/// jump forward to the relevant item.
1127impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
1128    fn expect_and_resolve_type(
1129        &self,
1130        id: HirId,
1131        ty: Option<Ty<'tcx>>,
1132    ) -> Result<Ty<'tcx>, Cx::Error> {
1133        match ty {
1134            Some(ty) => {
1135                let ty = self.cx.resolve_vars_if_possible(ty);
1136                self.cx.error_reported_in_ty(ty)?;
1137                Ok(ty)
1138            }
1139            None => {
1140                // FIXME: We shouldn't be relying on the infcx being tainted.
1141                self.cx.tainted_by_errors()?;
1142                ::rustc_middle::util::bug::bug_fmt(format_args!("no type for node {0} in ExprUseVisitor",
        self.cx.tcx().hir_id_to_string(id)));bug!("no type for node {} in ExprUseVisitor", self.cx.tcx().hir_id_to_string(id));
1143            }
1144        }
1145    }
1146
1147    fn node_ty(&self, hir_id: HirId) -> Result<Ty<'tcx>, Cx::Error> {
1148        self.expect_and_resolve_type(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
1149    }
1150
1151    fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
1152        self.expect_and_resolve_type(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
1153    }
1154
1155    fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
1156        self.expect_and_resolve_type(
1157            expr.hir_id,
1158            self.cx.typeck_results().expr_ty_adjusted_opt(expr),
1159        )
1160    }
1161
1162    /// Returns the type of value that this pattern matches against.
1163    /// Some non-obvious cases:
1164    ///
1165    /// - a `ref x` binding matches against a value of type `T` and gives
1166    ///   `x` the type `&T`; we return `T`.
1167    /// - a pattern with implicit derefs (thanks to default binding
1168    ///   modes #42640) may look like `Some(x)` but in fact have
1169    ///   implicit deref patterns attached (e.g., it is really
1170    ///   `&Some(x)`). In that case, we return the "outermost" type
1171    ///   (e.g., `&Option<T>`).
1172    fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> Result<Ty<'tcx>, Cx::Error> {
1173        // Check for implicit `&` types wrapping the pattern; note
1174        // that these are never attached to binding patterns, so
1175        // actually this is somewhat "disjoint" from the code below
1176        // that aims to account for `ref x`.
1177        if let Some(vec) = self.cx.typeck_results().pat_adjustments().get(pat.hir_id) {
1178            if let Some(first_adjust) = vec.first() {
1179                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1179",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(1179u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("pat_ty(pat={0:?}) found adjustment `{1:?}`",
                                                    pat, first_adjust) as &dyn Value))])
            });
    } else { ; }
};debug!("pat_ty(pat={:?}) found adjustment `{:?}`", pat, first_adjust);
1180                return Ok(first_adjust.source);
1181            }
1182        } else if let PatKind::Ref(subpat, _, _) = pat.kind
1183            && self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id)
1184        {
1185            return self.pat_ty_adjusted(subpat);
1186        }
1187
1188        self.pat_ty_unadjusted(pat)
1189    }
1190
1191    /// Like [`Self::pat_ty_adjusted`], but ignores implicit `&` patterns.
1192    fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> Result<Ty<'tcx>, Cx::Error> {
1193        let base_ty = self.node_ty(pat.hir_id)?;
1194        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1194",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(1194u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::tracing_core::field::FieldSet::new(&["base_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(&base_ty) as
                                            &dyn Value))])
            });
    } else { ; }
};trace!(?base_ty);
1195
1196        // This code detects whether we are looking at a `ref x`,
1197        // and if so, figures out what the type *being borrowed* is.
1198        match pat.kind {
1199            PatKind::Binding(..) => {
1200                let bm = *self
1201                    .cx
1202                    .typeck_results()
1203                    .pat_binding_modes()
1204                    .get(pat.hir_id)
1205                    .expect("missing binding mode");
1206
1207                if let hir::ByRef::Yes(pinnedness, _) = bm.0 {
1208                    let base_ty = if pinnedness.is_pinned() {
1209                        base_ty.pinned_ty().ok_or_else(|| {
1210                            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1210",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(1210u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("By-pin-ref binding of non-`Pin` type: {0:?}",
                                                    base_ty) as &dyn Value))])
            });
    } else { ; }
};debug!("By-pin-ref binding of non-`Pin` type: {base_ty:?}");
1211                            self.cx.report_bug(pat.span, "by-pin-ref binding of non-`Pin` type")
1212                        })?
1213                    } else {
1214                        base_ty
1215                    };
1216                    // a bind-by-ref means that the base_ty will be the type of the ident itself,
1217                    // but what we want here is the type of the underlying value being borrowed.
1218                    // So peel off one-level, turning the &T into T.
1219                    match self.cx.structurally_resolve_type(pat.span, base_ty).builtin_deref(false)
1220                    {
1221                        Some(ty) => Ok(ty),
1222                        None => {
1223                            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1223",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(1223u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("By-ref binding of non-derefable type: {0:?}",
                                                    base_ty) as &dyn Value))])
            });
    } else { ; }
};debug!("By-ref binding of non-derefable type: {base_ty:?}");
1224                            Err(self
1225                                .cx
1226                                .report_bug(pat.span, "by-ref binding of non-derefable type"))
1227                        }
1228                    }
1229                } else {
1230                    Ok(base_ty)
1231                }
1232            }
1233            _ => Ok(base_ty),
1234        }
1235    }
1236
1237    fn cat_expr(&self, expr: &hir::Expr<'_>) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1238        self.cat_expr_(expr, self.cx.typeck_results().expr_adjustments(expr))
1239    }
1240
1241    /// This recursion helper avoids going through *too many*
1242    /// adjustments, since *only* non-overloaded deref recurses.
1243    fn cat_expr_(
1244        &self,
1245        expr: &hir::Expr<'_>,
1246        adjustments: &[adjustment::Adjustment<'tcx>],
1247    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1248        match adjustments.split_last() {
1249            None => self.cat_expr_unadjusted(expr),
1250            Some((adjustment, previous)) => {
1251                self.cat_expr_adjusted_with(expr, || self.cat_expr_(expr, previous), adjustment)
1252            }
1253        }
1254    }
1255
1256    fn cat_expr_adjusted(
1257        &self,
1258        expr: &hir::Expr<'_>,
1259        previous: PlaceWithHirId<'tcx>,
1260        adjustment: &adjustment::Adjustment<'tcx>,
1261    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1262        self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment)
1263    }
1264
1265    fn cat_expr_adjusted_with<F>(
1266        &self,
1267        expr: &hir::Expr<'_>,
1268        previous: F,
1269        adjustment: &adjustment::Adjustment<'tcx>,
1270    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>
1271    where
1272        F: FnOnce() -> Result<PlaceWithHirId<'tcx>, Cx::Error>,
1273    {
1274        let target = self.cx.resolve_vars_if_possible(adjustment.target);
1275        match adjustment.kind {
1276            adjustment::Adjust::Deref(deref_kind) => {
1277                // Equivalent to *expr or something similar.
1278                let base = if let DerefAdjustKind::Overloaded(deref) = deref_kind {
1279                    let ref_ty = Ty::new_ref(
1280                        self.cx.tcx(),
1281                        self.cx.tcx().lifetimes.re_erased,
1282                        target,
1283                        deref.mutbl,
1284                    );
1285                    self.cat_rvalue(expr.hir_id, ref_ty)
1286                } else {
1287                    previous()?
1288                };
1289                self.cat_deref(expr.hir_id, base)
1290            }
1291
1292            adjustment::Adjust::NeverToAny
1293            | adjustment::Adjust::Pointer(_)
1294            | adjustment::Adjust::Borrow(_)
1295            | adjustment::Adjust::GenericReborrow(..) => {
1296                // Result is an rvalue.
1297                Ok(self.cat_rvalue(expr.hir_id, target))
1298            }
1299        }
1300    }
1301
1302    fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1303        let expr_ty = self.expr_ty(expr)?;
1304        match expr.kind {
1305            hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => {
1306                if self.cx.typeck_results().is_method_call(expr) {
1307                    self.cat_overloaded_place(expr, e_base)
1308                } else {
1309                    let base = self.cat_expr(e_base)?;
1310                    self.cat_deref(expr.hir_id, base)
1311                }
1312            }
1313
1314            hir::ExprKind::Field(base, _) => {
1315                let base = self.cat_expr(base)?;
1316                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1316",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(1316u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::tracing_core::field::FieldSet::new(&["base"],
                            ::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(&base) as
                                            &dyn Value))])
            });
    } else { ; }
};debug!(?base);
1317
1318                let field_idx = self
1319                    .cx
1320                    .typeck_results()
1321                    .field_indices()
1322                    .get(expr.hir_id)
1323                    .cloned()
1324                    .expect("Field index not found");
1325
1326                Ok(self.cat_projection(
1327                    expr.hir_id,
1328                    base,
1329                    expr_ty,
1330                    ProjectionKind::Field(field_idx, FIRST_VARIANT),
1331                ))
1332            }
1333
1334            hir::ExprKind::Index(base, _, _) => {
1335                if self.cx.typeck_results().is_method_call(expr) {
1336                    // If this is an index implemented by a method call, then it
1337                    // will include an implicit deref of the result.
1338                    // The call to index() returns a `&T` value, which
1339                    // is an rvalue. That is what we will be
1340                    // dereferencing.
1341                    self.cat_overloaded_place(expr, base)
1342                } else {
1343                    let base = self.cat_expr(base)?;
1344                    Ok(self.cat_projection(expr.hir_id, base, expr_ty, ProjectionKind::Index))
1345                }
1346            }
1347
1348            hir::ExprKind::Path(ref qpath) => {
1349                let res = self.cx.typeck_results().qpath_res(qpath, expr.hir_id);
1350                self.cat_res(expr.hir_id, expr.span, expr_ty, res)
1351            }
1352
1353            // type ascription doesn't affect the place-ness of the subexpression.
1354            hir::ExprKind::Type(e, _) => self.cat_expr(e),
1355
1356            hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Unwrap, e, _) => {
1357                let base = self.cat_expr(e)?;
1358                Ok(self.cat_projection(
1359                    expr.hir_id,
1360                    base,
1361                    expr_ty,
1362                    ProjectionKind::UnwrapUnsafeBinder,
1363                ))
1364            }
1365
1366            hir::ExprKind::AddrOf(..)
1367            | hir::ExprKind::Call(..)
1368            | hir::ExprKind::Use(..)
1369            | hir::ExprKind::Assign(..)
1370            | hir::ExprKind::AssignOp(..)
1371            | hir::ExprKind::Closure { .. }
1372            | hir::ExprKind::Ret(..)
1373            | hir::ExprKind::Become(..)
1374            | hir::ExprKind::Unary(..)
1375            | hir::ExprKind::Yield(..)
1376            | hir::ExprKind::MethodCall(..)
1377            | hir::ExprKind::Cast(..)
1378            | hir::ExprKind::DropTemps(..)
1379            | hir::ExprKind::Array(..)
1380            | hir::ExprKind::If(..)
1381            | hir::ExprKind::Tup(..)
1382            | hir::ExprKind::Binary(..)
1383            | hir::ExprKind::Block(..)
1384            | hir::ExprKind::Let(..)
1385            | hir::ExprKind::Loop(..)
1386            | hir::ExprKind::Match(..)
1387            | hir::ExprKind::Lit(..)
1388            | hir::ExprKind::ConstBlock(..)
1389            | hir::ExprKind::Break(..)
1390            | hir::ExprKind::Continue(..)
1391            | hir::ExprKind::Struct(..)
1392            | hir::ExprKind::Repeat(..)
1393            | hir::ExprKind::InlineAsm(..)
1394            | hir::ExprKind::OffsetOf(..)
1395            | hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Wrap, ..)
1396            | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr_ty)),
1397        }
1398    }
1399
1400    fn cat_res(
1401        &self,
1402        hir_id: HirId,
1403        span: Span,
1404        expr_ty: Ty<'tcx>,
1405        res: Res,
1406    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1407        match res {
1408            Res::Def(
1409                DefKind::Ctor(..)
1410                | DefKind::Const { .. }
1411                | DefKind::ConstParam
1412                | DefKind::AssocConst { .. }
1413                | DefKind::Fn
1414                | DefKind::AssocFn,
1415                _,
1416            )
1417            | Res::SelfCtor(..) => Ok(self.cat_rvalue(hir_id, expr_ty)),
1418
1419            Res::Def(DefKind::Static { .. }, _) => {
1420                Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::StaticItem, Vec::new()))
1421            }
1422
1423            Res::Local(var_id) => {
1424                if self.upvars.is_some_and(|upvars| upvars.contains_key(&var_id)) {
1425                    self.cat_upvar(hir_id, var_id)
1426                } else {
1427                    Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Local(var_id), Vec::new()))
1428                }
1429            }
1430
1431            def => ::rustc_middle::util::bug::span_bug_fmt(span,
    format_args!("unexpected definition in ExprUseVisitor: {0:?}", def))span_bug!(span, "unexpected definition in ExprUseVisitor: {:?}", def),
1432        }
1433    }
1434
1435    /// Categorize an upvar.
1436    ///
1437    /// Note: the actual upvar access contains invisible derefs of closure
1438    /// environment and upvar reference as appropriate. Only regionck cares
1439    /// about these dereferences, so we let it compute them as needed.
1440    fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1441        let closure_expr_def_id = self.cx.body_owner_def_id();
1442
1443        let upvar_id = ty::UpvarId {
1444            var_path: ty::UpvarPath { hir_id: var_id },
1445            closure_expr_id: closure_expr_def_id,
1446        };
1447        let var_ty = self.node_ty(var_id)?;
1448
1449        Ok(PlaceWithHirId::new(hir_id, var_ty, PlaceBase::Upvar(upvar_id), Vec::new()))
1450    }
1451
1452    fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> {
1453        PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new())
1454    }
1455
1456    fn cat_projection(
1457        &self,
1458        node: HirId,
1459        base_place: PlaceWithHirId<'tcx>,
1460        ty: Ty<'tcx>,
1461        kind: ProjectionKind,
1462    ) -> PlaceWithHirId<'tcx> {
1463        let place_ty = base_place.place.ty();
1464        let mut projections = base_place.place.projections;
1465
1466        let node_ty = self.cx.typeck_results().node_type(node);
1467        if !self.cx.tcx().next_trait_solver_globally() {
1468            // Opaque types can't have field projections, but we can instead convert
1469            // the current place in-place (heh) to the hidden type, and then apply all
1470            // follow up projections on that.
1471            if node_ty != place_ty
1472                && self
1473                    .cx
1474                    .structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), place_ty)
1475                    .is_opaque()
1476            {
1477                projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
1478            }
1479        }
1480        projections.push(Projection { kind, ty });
1481        PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections)
1482    }
1483
1484    fn cat_overloaded_place(
1485        &self,
1486        expr: &hir::Expr<'_>,
1487        base: &hir::Expr<'_>,
1488    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1489        // Reconstruct the output assuming it's a reference with the
1490        // same region and mutability as the receiver. This holds for
1491        // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
1492        let place_ty = self.expr_ty(expr)?;
1493        let base_ty = self.expr_ty_adjusted(base)?;
1494
1495        let ty::Ref(region, _, mutbl) =
1496            *self.cx.structurally_resolve_type(base.span, base_ty).kind()
1497        else {
1498            ::rustc_middle::util::bug::span_bug_fmt(expr.span,
    format_args!("cat_overloaded_place: base is not a reference"));span_bug!(expr.span, "cat_overloaded_place: base is not a reference");
1499        };
1500        let ref_ty = Ty::new_ref(self.cx.tcx(), region, place_ty, mutbl);
1501
1502        let base = self.cat_rvalue(expr.hir_id, ref_ty);
1503        self.cat_deref(expr.hir_id, base)
1504    }
1505
1506    fn cat_deref(
1507        &self,
1508        node: HirId,
1509        base_place: PlaceWithHirId<'tcx>,
1510    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1511        let base_curr_ty = base_place.place.ty();
1512        let Some(deref_ty) = self
1513            .cx
1514            .structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty)
1515            .builtin_deref(true)
1516        else {
1517            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1517",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(1517u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("explicit deref of non-derefable type: {0:?}",
                                                    base_curr_ty) as &dyn Value))])
            });
    } else { ; }
};debug!("explicit deref of non-derefable type: {:?}", base_curr_ty);
1518            return Err(self
1519                .cx
1520                .report_bug(self.cx.tcx().hir_span(node), "explicit deref of non-derefable type"));
1521        };
1522        let mut projections = base_place.place.projections;
1523        projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty });
1524
1525        Ok(PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections))
1526    }
1527
1528    /// Returns the variant index for an ADT used within a Struct or TupleStruct pattern
1529    /// Here `pat_hir_id` is the HirId of the pattern itself.
1530    fn variant_index_for_adt(
1531        &self,
1532        qpath: &hir::QPath<'_>,
1533        pat_hir_id: HirId,
1534        span: Span,
1535    ) -> Result<VariantIdx, Cx::Error> {
1536        let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id);
1537        let ty = self.cx.typeck_results().node_type(pat_hir_id);
1538        let ty::Adt(adt_def, _) = self.cx.structurally_resolve_type(span, ty).kind() else {
1539            return Err(self
1540                .cx
1541                .report_bug(span, "struct or tuple struct pattern not applied to an ADT"));
1542        };
1543
1544        match res {
1545            Res::Def(DefKind::Variant, variant_id) => Ok(adt_def.variant_index_with_id(variant_id)),
1546            Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
1547                Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id))
1548            }
1549            Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
1550            | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
1551            | Res::SelfCtor(..)
1552            | Res::SelfTyParam { .. }
1553            | Res::SelfTyAlias { .. } => {
1554                // Structs and Unions have only have one variant.
1555                Ok(FIRST_VARIANT)
1556            }
1557            _ => ::rustc_middle::util::bug::bug_fmt(format_args!("expected ADT path, found={0:?}",
        res))bug!("expected ADT path, found={:?}", res),
1558        }
1559    }
1560
1561    /// Returns the total number of fields in an ADT variant used within a pattern.
1562    /// Here `pat_hir_id` is the HirId of the pattern itself.
1563    fn total_fields_in_adt_variant(
1564        &self,
1565        pat_hir_id: HirId,
1566        variant_index: VariantIdx,
1567        span: Span,
1568    ) -> Result<usize, Cx::Error> {
1569        let ty = self.cx.typeck_results().node_type(pat_hir_id);
1570        match self.cx.structurally_resolve_type(span, ty).kind() {
1571            ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
1572            _ => {
1573                self.cx
1574                    .tcx()
1575                    .dcx()
1576                    .span_bug(span, "struct or tuple struct pattern not applied to an ADT");
1577            }
1578        }
1579    }
1580
1581    /// Returns the total number of fields in a tuple used within a Tuple pattern.
1582    /// Here `pat_hir_id` is the HirId of the pattern itself.
1583    fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> Result<usize, Cx::Error> {
1584        let ty = self.cx.typeck_results().node_type(pat_hir_id);
1585        match self.cx.structurally_resolve_type(span, ty).kind() {
1586            ty::Tuple(args) => Ok(args.len()),
1587            _ => Err(self.cx.report_bug(span, "tuple pattern not applied to a tuple")),
1588        }
1589    }
1590
1591    /// Here, `place` is the `PlaceWithHirId` being matched and pat is the pattern it
1592    /// is being matched against.
1593    ///
1594    /// In general, the way that this works is that we walk down the pattern,
1595    /// constructing a `PlaceWithHirId` that represents the path that will be taken
1596    /// to reach the value being matched.
1597    fn cat_pattern<F>(
1598        &self,
1599        mut place_with_id: PlaceWithHirId<'tcx>,
1600        pat: &hir::Pat<'_>,
1601        op: &mut F,
1602    ) -> Result<(), Cx::Error>
1603    where
1604        F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>) -> Result<(), Cx::Error>,
1605    {
1606        // If (pattern) adjustments are active for this pattern, adjust the `PlaceWithHirId` correspondingly.
1607        // `PlaceWithHirId`s are constructed differently from patterns. For example, in
1608        //
1609        // ```
1610        // match foo {
1611        //     &&Some(x, ) => { ... },
1612        //     _ => { ... },
1613        // }
1614        // ```
1615        //
1616        // the pattern `&&Some(x,)` is represented as `Ref { Ref { TupleStruct }}`. To build the
1617        // corresponding `PlaceWithHirId` we start with the `PlaceWithHirId` for `foo`, and then, by traversing the
1618        // pattern, try to answer the question: given the address of `foo`, how is `x` reached?
1619        //
1620        // `&&Some(x,)` `place_foo`
1621        //  `&Some(x,)` `deref { place_foo}`
1622        //   `Some(x,)` `deref { deref { place_foo }}`
1623        //       `(x,)` `field0 { deref { deref { place_foo }}}` <- resulting place
1624        //
1625        // The above example has no adjustments. If the code were instead the (after adjustments,
1626        // equivalent) version
1627        //
1628        // ```
1629        // match foo {
1630        //     Some(x, ) => { ... },
1631        //     _ => { ... },
1632        // }
1633        // ```
1634        //
1635        // Then we see that to get the same result, we must start with
1636        // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)`
1637        // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`.
1638        let typeck_results = self.cx.typeck_results();
1639        let adjustments: &[adjustment::PatAdjustment<'tcx>] =
1640            typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
1641        let mut adjusts = adjustments.iter().peekable();
1642        while let Some(adjust) = adjusts.next() {
1643            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1643",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(1643u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("applying adjustment to place_with_id={0:?}",
                                                    place_with_id) as &dyn Value))])
            });
    } else { ; }
};debug!("applying adjustment to place_with_id={:?}", place_with_id);
1644            place_with_id = match adjust.kind {
1645                adjustment::PatAdjust::BuiltinDeref => self.cat_deref(pat.hir_id, place_with_id)?,
1646                adjustment::PatAdjust::OverloadedDeref => {
1647                    // This adjustment corresponds to an overloaded deref; unless it's on a box, it
1648                    // borrows the scrutinee to call `Deref::deref` or `DerefMut::deref_mut`. Invoke
1649                    // the callback before setting `place_with_id` to the temporary storing the
1650                    // result of the deref.
1651                    // HACK(dianne): giving the callback a fake deref pattern makes sure it behaves the
1652                    // same as it would if this were an explicit deref pattern (including for boxes).
1653                    op(&place_with_id, &hir::Pat { kind: PatKind::Deref(pat), ..*pat })?;
1654                    let target_ty = match adjusts.peek() {
1655                        Some(&&next_adjust) => next_adjust.source,
1656                        // At the end of the deref chain, we get `pat`'s scrutinee.
1657                        None => self.pat_ty_unadjusted(pat)?,
1658                    };
1659                    self.pat_deref_place(pat.hir_id, place_with_id, pat, target_ty)?
1660                }
1661                adjustment::PatAdjust::PinDeref => {
1662                    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1662",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(1662u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("`PinDeref` of non-pinned-reference type: {0:?}",
                                                    adjust.source) as &dyn Value))])
            });
    } else { ; }
};debug!("`PinDeref` of non-pinned-reference type: {:?}", adjust.source);
1663                    let target_ty = adjust.source.pinned_ty().ok_or_else(|| {
1664                        self.cx.report_bug(
1665                            self.cx.tcx().hir_span(pat.hir_id),
1666                            "`PinDeref` of non-pinned-reference type",
1667                        )
1668                    })?;
1669                    let kind = ProjectionKind::Field(FieldIdx::ZERO, FIRST_VARIANT);
1670                    place_with_id = self.cat_projection(pat.hir_id, place_with_id, target_ty, kind);
1671                    self.cat_deref(pat.hir_id, place_with_id)?
1672                }
1673            };
1674        }
1675        drop(typeck_results); // explicitly release borrow of typeck results, just in case.
1676        let place_with_id = place_with_id; // lose mutability
1677        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1677",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(1677u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("applied adjustment derefs to get place_with_id={0:?}",
                                                    place_with_id) as &dyn Value))])
            });
    } else { ; }
};debug!("applied adjustment derefs to get place_with_id={:?}", place_with_id);
1678
1679        // Invoke the callback, but only now, after the `place_with_id` has adjusted.
1680        //
1681        // To see that this makes sense, consider `match &Some(3) { Some(x) => { ... }}`. In that
1682        // case, the initial `place_with_id` will be that for `&Some(3)` and the pattern is `Some(x)`. We
1683        // don't want to call `op` with these incompatible values. As written, what happens instead
1684        // is that `op` is called with the adjusted place (that for `*&Some(3)`) and the pattern
1685        // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)`
1686        // result in the place `Downcast<Some>(*&Some(3)).0` associated to `x` and invoke `op` with
1687        // that (where the `ref` on `x` is implied).
1688        op(&place_with_id, pat)?;
1689
1690        match pat.kind {
1691            PatKind::Tuple(subpats, dots_pos) => {
1692                // (p1, ..., pN)
1693                let total_fields = self.total_fields_in_tuple(pat.hir_id, pat.span)?;
1694
1695                for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
1696                    let subpat_ty = self.pat_ty_adjusted(subpat)?;
1697                    let projection_kind =
1698                        ProjectionKind::Field(FieldIdx::from_usize(i), FIRST_VARIANT);
1699                    let sub_place = self.cat_projection(
1700                        pat.hir_id,
1701                        place_with_id.clone(),
1702                        subpat_ty,
1703                        projection_kind,
1704                    );
1705                    self.cat_pattern(sub_place, subpat, op)?;
1706                }
1707            }
1708
1709            PatKind::TupleStruct(ref qpath, subpats, dots_pos) => {
1710                // S(p1, ..., pN)
1711                let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?;
1712                let total_fields =
1713                    self.total_fields_in_adt_variant(pat.hir_id, variant_index, pat.span)?;
1714
1715                for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
1716                    let subpat_ty = self.pat_ty_adjusted(subpat)?;
1717                    let projection_kind =
1718                        ProjectionKind::Field(FieldIdx::from_usize(i), variant_index);
1719                    let sub_place = self.cat_projection(
1720                        pat.hir_id,
1721                        place_with_id.clone(),
1722                        subpat_ty,
1723                        projection_kind,
1724                    );
1725                    self.cat_pattern(sub_place, subpat, op)?;
1726                }
1727            }
1728
1729            PatKind::Struct(ref qpath, field_pats, _) => {
1730                // S { f1: p1, ..., fN: pN }
1731
1732                let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?;
1733
1734                for fp in field_pats {
1735                    let field_ty = self.pat_ty_adjusted(fp.pat)?;
1736                    let field_index = self
1737                        .cx
1738                        .typeck_results()
1739                        .field_indices()
1740                        .get(fp.hir_id)
1741                        .cloned()
1742                        .expect("no index for a field");
1743
1744                    let field_place = self.cat_projection(
1745                        pat.hir_id,
1746                        place_with_id.clone(),
1747                        field_ty,
1748                        ProjectionKind::Field(field_index, variant_index),
1749                    );
1750                    self.cat_pattern(field_place, fp.pat, op)?;
1751                }
1752            }
1753
1754            PatKind::Or(pats) => {
1755                for pat in pats {
1756                    self.cat_pattern(place_with_id.clone(), pat, op)?;
1757                }
1758            }
1759
1760            PatKind::Binding(.., Some(subpat)) | PatKind::Guard(subpat, _) => {
1761                self.cat_pattern(place_with_id, subpat, op)?;
1762            }
1763
1764            PatKind::Ref(subpat, _, _)
1765                if self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id) =>
1766            {
1767                self.cat_pattern(place_with_id, subpat, op)?;
1768            }
1769
1770            PatKind::Box(subpat) | PatKind::Ref(subpat, _, _) => {
1771                // box p1, &p1, &mut p1. we can ignore the mutability of
1772                // PatKind::Ref since that information is already contained
1773                // in the type.
1774                let subplace = self.cat_deref(pat.hir_id, place_with_id)?;
1775                self.cat_pattern(subplace, subpat, op)?;
1776            }
1777            PatKind::Deref(subpat) => {
1778                let ty = self.pat_ty_adjusted(subpat)?;
1779                let place = self.pat_deref_place(pat.hir_id, place_with_id, subpat, ty)?;
1780                self.cat_pattern(place, subpat, op)?;
1781            }
1782
1783            PatKind::Slice(before, ref slice, after) => {
1784                let Some(element_ty) = self
1785                    .cx
1786                    .structurally_resolve_type(pat.span, place_with_id.place.ty())
1787                    .builtin_index()
1788                else {
1789                    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1789",
                        "rustc_hir_typeck::expr_use_visitor",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                        ::tracing_core::__macro_support::Option::Some(1789u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                        ::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!("explicit index of non-indexable type {0:?}",
                                                    place_with_id) as &dyn Value))])
            });
    } else { ; }
};debug!("explicit index of non-indexable type {:?}", place_with_id);
1790                    return Err(self
1791                        .cx
1792                        .report_bug(pat.span, "explicit index of non-indexable type"));
1793                };
1794                let elt_place = self.cat_projection(
1795                    pat.hir_id,
1796                    place_with_id.clone(),
1797                    element_ty,
1798                    ProjectionKind::Index,
1799                );
1800                for before_pat in before {
1801                    self.cat_pattern(elt_place.clone(), before_pat, op)?;
1802                }
1803                if let Some(slice_pat) = *slice {
1804                    let slice_pat_ty = self.pat_ty_adjusted(slice_pat)?;
1805                    let slice_place = self.cat_projection(
1806                        pat.hir_id,
1807                        place_with_id,
1808                        slice_pat_ty,
1809                        ProjectionKind::Subslice,
1810                    );
1811                    self.cat_pattern(slice_place, slice_pat, op)?;
1812                }
1813                for after_pat in after {
1814                    self.cat_pattern(elt_place.clone(), after_pat, op)?;
1815                }
1816            }
1817
1818            PatKind::Binding(.., None)
1819            | PatKind::Expr(..)
1820            | PatKind::Range(..)
1821            | PatKind::Never
1822            | PatKind::Missing
1823            | PatKind::Wild
1824            | PatKind::Err(_) => {
1825                // always ok
1826            }
1827        }
1828
1829        Ok(())
1830    }
1831
1832    /// Represents the place matched on by a deref pattern's interior.
1833    fn pat_deref_place(
1834        &self,
1835        hir_id: HirId,
1836        base_place: PlaceWithHirId<'tcx>,
1837        inner: &hir::Pat<'_>,
1838        target_ty: Ty<'tcx>,
1839    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1840        match self.cx.typeck_results().deref_pat_borrow_mode(base_place.place.ty(), inner) {
1841            // Deref patterns on boxes are lowered using a built-in deref.
1842            DerefPatBorrowMode::Box => self.cat_deref(hir_id, base_place),
1843            // For other types, we create a temporary to match on.
1844            DerefPatBorrowMode::Borrow(mutability) => {
1845                let re_erased = self.cx.tcx().lifetimes.re_erased;
1846                let ty = Ty::new_ref(self.cx.tcx(), re_erased, target_ty, mutability);
1847                // A deref pattern stores the result of `Deref::deref` or `DerefMut::deref_mut` ...
1848                let base = self.cat_rvalue(hir_id, ty);
1849                // ... and the inner pattern matches on the place behind that reference.
1850                self.cat_deref(hir_id, base)
1851            }
1852        }
1853    }
1854
1855    /// Checks whether a type has multiple variants, and therefore, whether a
1856    /// read of the discriminant might be necessary.
1857    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("is_multivariant_adt",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1857u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["ty"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: bool = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if let ty::Adt(def, _) =
                    self.cx.structurally_resolve_type(span, ty).kind() {
                def.variants().len() > 1 ||
                    def.is_variant_list_non_exhaustive()
            } else { false }
        }
    }
}#[instrument(skip(self, span), level = "debug")]
1858    fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool {
1859        if let ty::Adt(def, _) = self.cx.structurally_resolve_type(span, ty).kind() {
1860            // We treat non-exhaustive enums the same independent of the crate they are
1861            // defined in, to avoid differences in the operational semantics between crates.
1862            def.variants().len() > 1 || def.is_variant_list_non_exhaustive()
1863        } else {
1864            false
1865        }
1866    }
1867}
1868
1869struct ExprPlaceDelegate;
1870
1871impl<'tcx> Delegate<'tcx> for ExprPlaceDelegate {
1872    fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
1873
1874    fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
1875
1876    fn borrow(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {}
1877
1878    fn mutate(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
1879
1880    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
1881}
1882
1883/// Categorizes `expr` as a place for diagnostic suggestions.
1884///
1885/// This should be used for diagnostics purpose only.
1886pub(crate) fn expr_place<'tcx>(
1887    fcx: &FnCtxt<'_, 'tcx>,
1888    expr: &hir::Expr<'_>,
1889) -> Result<PlaceWithHirId<'tcx>, ErrorGuaranteed> {
1890    ExprUseVisitor::new(fcx, ExprPlaceDelegate).cat_expr(expr)
1891}