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, 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),
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            place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?;
756        }
757
758        Ok(())
759    }
760
761    /// Walks the autoref `autoref` applied to the autoderef'd
762    /// `expr`. `base_place` is `expr` represented as a place,
763    /// after all relevant autoderefs have occurred.
764    fn walk_autoref(
765        &self,
766        expr: &hir::Expr<'_>,
767        base_place: &PlaceWithHirId<'tcx>,
768        autoref: &adjustment::AutoBorrow,
769    ) {
770        {
    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:770",
                        "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(770u32),
                        ::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!(
771            "walk_autoref(expr.hir_id={} base_place={:?} autoref={:?})",
772            expr.hir_id, base_place, autoref
773        );
774
775        match *autoref {
776            adjustment::AutoBorrow::Ref(m) => {
777                self.delegate.borrow_mut().borrow(
778                    base_place,
779                    base_place.hir_id,
780                    ty::BorrowKind::from_mutbl(m.into()),
781                );
782            }
783
784            adjustment::AutoBorrow::RawPtr(m) | adjustment::AutoBorrow::Pin(m) => {
785                {
    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:785",
                        "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(785u32),
                        ::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);
786
787                self.delegate.borrow_mut().borrow(
788                    base_place,
789                    base_place.hir_id,
790                    ty::BorrowKind::from_mutbl(m),
791                );
792            }
793        }
794    }
795
796    fn walk_arm(
797        &self,
798        discr_place: &PlaceWithHirId<'tcx>,
799        arm: &hir::Arm<'_>,
800    ) -> Result<(), Cx::Error> {
801        self.walk_pat(discr_place, arm.pat, arm.guard.is_some())?;
802
803        if let Some(ref e) = arm.guard {
804            self.consume_expr(e)?;
805        }
806
807        self.consume_expr(arm.body)?;
808        Ok(())
809    }
810
811    /// The core driver for walking a pattern
812    ///
813    /// This should mirror how pattern-matching gets lowered to MIR, as
814    /// otherwise said lowering will ICE when trying to resolve the upvars.
815    ///
816    /// However, it is okay to approximate it here by doing *more* accesses than
817    /// the actual MIR builder will, which is useful when some checks are too
818    /// cumbersome to perform here, because e.g. they require more typeck results
819    /// than available.
820    ///
821    /// Do note that discrepancies like these do still create obscure corners
822    /// in the semantics of the language, and should be avoided if possible.
823    #[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(823u32),
                                    ::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:832",
                                                    "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(&["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:839",
                                                            "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(839u32),
                                                            ::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:844",
                                                            "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(844u32),
                                                            ::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: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: 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:872",
                                                                    "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(872u32),
                                                                    ::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")]
824    fn walk_pat(
825        &self,
826        discr_place: &PlaceWithHirId<'tcx>,
827        pat: &hir::Pat<'_>,
828        has_guard: bool,
829    ) -> Result<(), Cx::Error> {
830        let tcx = self.cx.tcx();
831        self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| {
832            debug!("walk_pat: pat.kind={:?}", pat.kind);
833            let read_discriminant = || {
834                self.delegate.borrow_mut().borrow(place, discr_place.hir_id, BorrowKind::Immutable);
835            };
836
837            match pat.kind {
838                PatKind::Binding(_, canonical_id, ..) => {
839                    debug!("walk_pat: binding place={:?} pat={:?}", place, pat);
840                    let bm = self
841                        .cx
842                        .typeck_results()
843                        .extract_binding_mode(tcx.sess, pat.hir_id, pat.span);
844                    debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
845
846                    // pat_ty: the type of the binding being produced.
847                    let pat_ty = self.node_ty(pat.hir_id)?;
848                    debug!("walk_pat: pat_ty={:?}", pat_ty);
849
850                    let def = Res::Local(canonical_id);
851                    if let Ok(ref binding_place) = self.cat_res(pat.hir_id, pat.span, pat_ty, def) {
852                        self.delegate.borrow_mut().bind(binding_place, binding_place.hir_id);
853                    }
854
855                    // Subtle: MIR desugaring introduces immutable borrows for each pattern
856                    // binding when lowering pattern guards to ensure that the guard does not
857                    // modify the scrutinee.
858                    if has_guard {
859                        read_discriminant();
860                    }
861
862                    // It is also a borrow or copy/move of the value being matched.
863                    // In a cases of pattern like `let pat = upvar`, don't use the span
864                    // of the pattern, as this just looks confusing, instead use the span
865                    // of the discriminant.
866                    match bm.0 {
867                        hir::ByRef::Yes(_, m) => {
868                            let bk = ty::BorrowKind::from_mutbl(m);
869                            self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk);
870                        }
871                        hir::ByRef::No => {
872                            debug!("walk_pat binding consuming pat");
873                            self.consume_or_copy(place, discr_place.hir_id);
874                        }
875                    }
876                }
877                PatKind::Deref(subpattern) => {
878                    // A deref pattern is a bit special: the binding mode of its inner bindings
879                    // determines whether to borrow *at the level of the deref pattern* rather than
880                    // borrowing the bound place (since that inner place is inside the temporary that
881                    // stores the result of calling `deref()`/`deref_mut()` so can't be captured).
882                    // Deref patterns on boxes don't borrow, so we ignore them here.
883                    // HACK: this could be a fake pattern corresponding to a deref inserted by match
884                    // ergonomics, in which case `pat.hir_id` will be the id of the subpattern.
885                    if let DerefPatBorrowMode::Borrow(mutability) =
886                        self.cx.typeck_results().deref_pat_borrow_mode(place.place.ty(), subpattern)
887                    {
888                        let bk = ty::BorrowKind::from_mutbl(mutability);
889                        self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk);
890                    }
891                }
892                PatKind::Never => {
893                    // A `!` pattern always counts as an immutable read of the discriminant,
894                    // even in an irrefutable pattern.
895                    read_discriminant();
896                }
897                PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
898                    // A `Path` pattern is just a name like `Foo`. This is either a
899                    // named constant or else it refers to an ADT variant
900
901                    let res = self.cx.typeck_results().qpath_res(qpath, *hir_id);
902                    match res {
903                        Res::Def(DefKind::Const { .. }, _)
904                        | Res::Def(DefKind::AssocConst { .. }, _) => {
905                            // Named constants have to be equated with the value
906                            // being matched, so that's a read of the value being matched.
907                            //
908                            // FIXME: Does the MIR code skip this read when matching on a ZST?
909                            // If so, we can also skip it here.
910                            read_discriminant();
911                        }
912                        _ => {
913                            // Otherwise, this is a struct/enum variant, and so it's
914                            // only a read if we need to read the discriminant.
915                            if self.is_multivariant_adt(place.place.ty(), *span) {
916                                read_discriminant();
917                            }
918                        }
919                    }
920                }
921                PatKind::Expr(_) | PatKind::Range(..) => {
922                    // When matching against a literal or range, we need to
923                    // borrow the place to compare it against the pattern.
924                    //
925                    // Note that we do this read even if the range matches all
926                    // possible values, such as 0..=u8::MAX. This is because
927                    // we don't want to depend on consteval here.
928                    //
929                    // FIXME: What if the type being matched only has one
930                    // possible value?
931                    read_discriminant();
932                }
933                PatKind::Struct(..) | PatKind::TupleStruct(..) => {
934                    if self.is_multivariant_adt(place.place.ty(), pat.span) {
935                        read_discriminant();
936                    }
937                }
938                PatKind::Slice(lhs, wild, rhs) => {
939                    // We don't need to test the length if the pattern is `[..]`
940                    if matches!((lhs, wild, rhs), (&[], Some(_), &[]))
941                        // Arrays have a statically known size, so
942                        // there is no need to read their length
943                        || place.place.ty().peel_refs().is_array()
944                    {
945                        // No read necessary
946                    } else {
947                        read_discriminant();
948                    }
949                }
950                PatKind::Or(_)
951                | PatKind::Box(_)
952                | PatKind::Ref(..)
953                | PatKind::Guard(..)
954                | PatKind::Tuple(..)
955                | PatKind::Wild
956                | PatKind::Missing
957                | PatKind::Err(_) => {
958                    // If the PatKind is Or, Box, Ref, Guard, or Tuple, the relevant accesses
959                    // are made later as these patterns contains subpatterns.
960                    // If the PatKind is Missing, Wild or Err, any relevant accesses are made when processing
961                    // the other patterns that are part of the match
962                }
963            }
964
965            Ok(())
966        })
967    }
968
969    /// Handle the case where the current body contains a closure.
970    ///
971    /// When the current body being handled is a closure, then we must make sure that
972    /// - The parent closure only captures Places from the nested closure that are not local to it.
973    ///
974    /// In the following example the closures `c` only captures `p.x` even though `incr`
975    /// is a capture of the nested closure
976    ///
977    /// ```
978    /// struct P { x: i32 }
979    /// let mut p = P { x: 4 };
980    /// let c = || {
981    ///    let incr = 10;
982    ///    let nested = || p.x += incr;
983    /// };
984    /// ```
985    ///
986    /// - When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing
987    /// closure as the DefId.
988    #[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(988u32),
                                    ::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")]
989    fn walk_captures(&self, closure_expr: &hir::Closure<'_>) -> Result<(), Cx::Error> {
990        fn upvar_is_local_variable(
991            upvars: Option<&FxIndexMap<HirId, hir::Upvar>>,
992            upvar_id: HirId,
993            body_owner_is_closure: bool,
994        ) -> bool {
995            upvars.map(|upvars| !upvars.contains_key(&upvar_id)).unwrap_or(body_owner_is_closure)
996        }
997
998        let tcx = self.cx.tcx();
999        let closure_def_id = closure_expr.def_id;
1000        // For purposes of this function, coroutine and closures are equivalent.
1001        let body_owner_is_closure = matches!(
1002            tcx.hir_body_owner_kind(self.cx.body_owner_def_id()),
1003            hir::BodyOwnerKind::Closure
1004        );
1005
1006        // If we have a nested closure, we want to include the fake reads present in the nested
1007        // closure.
1008        if let Some(fake_reads) = self.cx.typeck_results().closure_fake_reads.get(&closure_def_id) {
1009            for (fake_read, cause, hir_id) in fake_reads.iter() {
1010                match fake_read.base {
1011                    PlaceBase::Upvar(upvar_id) => {
1012                        if upvar_is_local_variable(
1013                            self.upvars,
1014                            upvar_id.var_path.hir_id,
1015                            body_owner_is_closure,
1016                        ) {
1017                            // The nested closure might be fake reading the current (enclosing) closure's local variables.
1018                            // The only places we want to fake read before creating the parent closure are the ones that
1019                            // are not local to it/ defined by it.
1020                            //
1021                            // ```rust,ignore(cannot-test-this-because-pseudo-code)
1022                            // let v1 = (0, 1);
1023                            // let c = || { // fake reads: v1
1024                            //    let v2 = (0, 1);
1025                            //    let e = || { // fake reads: v1, v2
1026                            //       let (_, t1) = v1;
1027                            //       let (_, t2) = v2;
1028                            //    }
1029                            // }
1030                            // ```
1031                            // This check is performed when visiting the body of the outermost closure (`c`) and ensures
1032                            // that we don't add a fake read of v2 in c.
1033                            continue;
1034                        }
1035                    }
1036                    _ => {
1037                        bug!(
1038                            "Do not know how to get HirId out of Rvalue and StaticItem {:?}",
1039                            fake_read.base
1040                        );
1041                    }
1042                };
1043                self.delegate.borrow_mut().fake_read(
1044                    &PlaceWithHirId { place: fake_read.clone(), hir_id: *hir_id },
1045                    *cause,
1046                    *hir_id,
1047                );
1048            }
1049        }
1050
1051        if let Some(min_captures) =
1052            self.cx.typeck_results().closure_min_captures.get(&closure_def_id)
1053        {
1054            for (var_hir_id, min_list) in min_captures.iter() {
1055                if self
1056                    .upvars
1057                    .map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id))
1058                {
1059                    // The nested closure might be capturing the current (enclosing) closure's local variables.
1060                    // We check if the root variable is ever mentioned within the enclosing closure, if not
1061                    // then for the current body (if it's a closure) these aren't captures, we will ignore them.
1062                    continue;
1063                }
1064                for captured_place in min_list {
1065                    let place = &captured_place.place;
1066                    let capture_info = captured_place.info;
1067
1068                    let place_base = if body_owner_is_closure {
1069                        // Mark the place to be captured by the enclosing closure
1070                        PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.cx.body_owner_def_id()))
1071                    } else {
1072                        // If the body owner isn't a closure then the variable must
1073                        // be a local variable
1074                        PlaceBase::Local(*var_hir_id)
1075                    };
1076                    let closure_hir_id = tcx.local_def_id_to_hir_id(closure_def_id);
1077                    let place_with_id = PlaceWithHirId::new(
1078                        capture_info
1079                            .path_expr_id
1080                            .unwrap_or(capture_info.capture_kind_expr_id.unwrap_or(closure_hir_id)),
1081                        place.base_ty,
1082                        place_base,
1083                        place.projections.clone(),
1084                    );
1085
1086                    match capture_info.capture_kind {
1087                        ty::UpvarCapture::ByValue => {
1088                            self.consume_or_copy(&place_with_id, place_with_id.hir_id);
1089                        }
1090                        ty::UpvarCapture::ByUse => {
1091                            self.consume_clone_or_copy(&place_with_id, place_with_id.hir_id);
1092                        }
1093                        ty::UpvarCapture::ByRef(upvar_borrow) => {
1094                            self.delegate.borrow_mut().borrow(
1095                                &place_with_id,
1096                                place_with_id.hir_id,
1097                                upvar_borrow,
1098                            );
1099                        }
1100                    }
1101                }
1102            }
1103        }
1104
1105        Ok(())
1106    }
1107}
1108
1109/// The job of the methods whose name starts with `cat_` is to analyze
1110/// expressions and construct the corresponding [`Place`]s. The `cat`
1111/// stands for "categorize", this is a leftover from long ago when
1112/// places were called "categorizations".
1113///
1114/// Note that a [`Place`] differs somewhat from the expression itself. For
1115/// example, auto-derefs are explicit. Also, an index `a[b]` is decomposed into
1116/// two operations: a dereference to reach the array data and then an index to
1117/// jump forward to the relevant item.
1118impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
1119    fn expect_and_resolve_type(
1120        &self,
1121        id: HirId,
1122        ty: Option<Ty<'tcx>>,
1123    ) -> Result<Ty<'tcx>, Cx::Error> {
1124        match ty {
1125            Some(ty) => {
1126                let ty = self.cx.resolve_vars_if_possible(ty);
1127                self.cx.error_reported_in_ty(ty)?;
1128                Ok(ty)
1129            }
1130            None => {
1131                // FIXME: We shouldn't be relying on the infcx being tainted.
1132                self.cx.tainted_by_errors()?;
1133                ::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));
1134            }
1135        }
1136    }
1137
1138    fn node_ty(&self, hir_id: HirId) -> Result<Ty<'tcx>, Cx::Error> {
1139        self.expect_and_resolve_type(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
1140    }
1141
1142    fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
1143        self.expect_and_resolve_type(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
1144    }
1145
1146    fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
1147        self.expect_and_resolve_type(
1148            expr.hir_id,
1149            self.cx.typeck_results().expr_ty_adjusted_opt(expr),
1150        )
1151    }
1152
1153    /// Returns the type of value that this pattern matches against.
1154    /// Some non-obvious cases:
1155    ///
1156    /// - a `ref x` binding matches against a value of type `T` and gives
1157    ///   `x` the type `&T`; we return `T`.
1158    /// - a pattern with implicit derefs (thanks to default binding
1159    ///   modes #42640) may look like `Some(x)` but in fact have
1160    ///   implicit deref patterns attached (e.g., it is really
1161    ///   `&Some(x)`). In that case, we return the "outermost" type
1162    ///   (e.g., `&Option<T>`).
1163    fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> Result<Ty<'tcx>, Cx::Error> {
1164        // Check for implicit `&` types wrapping the pattern; note
1165        // that these are never attached to binding patterns, so
1166        // actually this is somewhat "disjoint" from the code below
1167        // that aims to account for `ref x`.
1168        if let Some(vec) = self.cx.typeck_results().pat_adjustments().get(pat.hir_id) {
1169            if let Some(first_adjust) = vec.first() {
1170                {
    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:1170",
                        "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(1170u32),
                        ::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);
1171                return Ok(first_adjust.source);
1172            }
1173        } else if let PatKind::Ref(subpat, _, _) = pat.kind
1174            && self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id)
1175        {
1176            return self.pat_ty_adjusted(subpat);
1177        }
1178
1179        self.pat_ty_unadjusted(pat)
1180    }
1181
1182    /// Like [`Self::pat_ty_adjusted`], but ignores implicit `&` patterns.
1183    fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> Result<Ty<'tcx>, Cx::Error> {
1184        let base_ty = self.node_ty(pat.hir_id)?;
1185        {
    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:1185",
                        "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(1185u32),
                        ::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);
1186
1187        // This code detects whether we are looking at a `ref x`,
1188        // and if so, figures out what the type *being borrowed* is.
1189        match pat.kind {
1190            PatKind::Binding(..) => {
1191                let bm = *self
1192                    .cx
1193                    .typeck_results()
1194                    .pat_binding_modes()
1195                    .get(pat.hir_id)
1196                    .expect("missing binding mode");
1197
1198                if let hir::ByRef::Yes(pinnedness, _) = bm.0 {
1199                    let base_ty = if pinnedness.is_pinned() {
1200                        base_ty.pinned_ty().ok_or_else(|| {
1201                            {
    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:1201",
                        "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(1201u32),
                        ::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:?}");
1202                            self.cx.report_bug(pat.span, "by-pin-ref binding of non-`Pin` type")
1203                        })?
1204                    } else {
1205                        base_ty
1206                    };
1207                    // a bind-by-ref means that the base_ty will be the type of the ident itself,
1208                    // but what we want here is the type of the underlying value being borrowed.
1209                    // So peel off one-level, turning the &T into T.
1210                    match self.cx.structurally_resolve_type(pat.span, base_ty).builtin_deref(false)
1211                    {
1212                        Some(ty) => Ok(ty),
1213                        None => {
1214                            {
    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:1214",
                        "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(1214u32),
                        ::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:?}");
1215                            Err(self
1216                                .cx
1217                                .report_bug(pat.span, "by-ref binding of non-derefable type"))
1218                        }
1219                    }
1220                } else {
1221                    Ok(base_ty)
1222                }
1223            }
1224            _ => Ok(base_ty),
1225        }
1226    }
1227
1228    fn cat_expr(&self, expr: &hir::Expr<'_>) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1229        self.cat_expr_(expr, self.cx.typeck_results().expr_adjustments(expr))
1230    }
1231
1232    /// This recursion helper avoids going through *too many*
1233    /// adjustments, since *only* non-overloaded deref recurses.
1234    fn cat_expr_(
1235        &self,
1236        expr: &hir::Expr<'_>,
1237        adjustments: &[adjustment::Adjustment<'tcx>],
1238    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1239        match adjustments.split_last() {
1240            None => self.cat_expr_unadjusted(expr),
1241            Some((adjustment, previous)) => {
1242                self.cat_expr_adjusted_with(expr, || self.cat_expr_(expr, previous), adjustment)
1243            }
1244        }
1245    }
1246
1247    fn cat_expr_adjusted(
1248        &self,
1249        expr: &hir::Expr<'_>,
1250        previous: PlaceWithHirId<'tcx>,
1251        adjustment: &adjustment::Adjustment<'tcx>,
1252    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1253        self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment)
1254    }
1255
1256    fn cat_expr_adjusted_with<F>(
1257        &self,
1258        expr: &hir::Expr<'_>,
1259        previous: F,
1260        adjustment: &adjustment::Adjustment<'tcx>,
1261    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error>
1262    where
1263        F: FnOnce() -> Result<PlaceWithHirId<'tcx>, Cx::Error>,
1264    {
1265        let target = self.cx.resolve_vars_if_possible(adjustment.target);
1266        match adjustment.kind {
1267            adjustment::Adjust::Deref(deref_kind) => {
1268                // Equivalent to *expr or something similar.
1269                let base = if let DerefAdjustKind::Overloaded(deref) = deref_kind {
1270                    let ref_ty = Ty::new_ref(
1271                        self.cx.tcx(),
1272                        self.cx.tcx().lifetimes.re_erased,
1273                        target,
1274                        deref.mutbl,
1275                    );
1276                    self.cat_rvalue(expr.hir_id, ref_ty)
1277                } else {
1278                    previous()?
1279                };
1280                self.cat_deref(expr.hir_id, base)
1281            }
1282
1283            adjustment::Adjust::NeverToAny
1284            | adjustment::Adjust::Pointer(_)
1285            | adjustment::Adjust::Borrow(_) => {
1286                // Result is an rvalue.
1287                Ok(self.cat_rvalue(expr.hir_id, target))
1288            }
1289        }
1290    }
1291
1292    fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1293        let expr_ty = self.expr_ty(expr)?;
1294        match expr.kind {
1295            hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => {
1296                if self.cx.typeck_results().is_method_call(expr) {
1297                    self.cat_overloaded_place(expr, e_base)
1298                } else {
1299                    let base = self.cat_expr(e_base)?;
1300                    self.cat_deref(expr.hir_id, base)
1301                }
1302            }
1303
1304            hir::ExprKind::Field(base, _) => {
1305                let base = self.cat_expr(base)?;
1306                {
    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:1306",
                        "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(1306u32),
                        ::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);
1307
1308                let field_idx = self
1309                    .cx
1310                    .typeck_results()
1311                    .field_indices()
1312                    .get(expr.hir_id)
1313                    .cloned()
1314                    .expect("Field index not found");
1315
1316                Ok(self.cat_projection(
1317                    expr.hir_id,
1318                    base,
1319                    expr_ty,
1320                    ProjectionKind::Field(field_idx, FIRST_VARIANT),
1321                ))
1322            }
1323
1324            hir::ExprKind::Index(base, _, _) => {
1325                if self.cx.typeck_results().is_method_call(expr) {
1326                    // If this is an index implemented by a method call, then it
1327                    // will include an implicit deref of the result.
1328                    // The call to index() returns a `&T` value, which
1329                    // is an rvalue. That is what we will be
1330                    // dereferencing.
1331                    self.cat_overloaded_place(expr, base)
1332                } else {
1333                    let base = self.cat_expr(base)?;
1334                    Ok(self.cat_projection(expr.hir_id, base, expr_ty, ProjectionKind::Index))
1335                }
1336            }
1337
1338            hir::ExprKind::Path(ref qpath) => {
1339                let res = self.cx.typeck_results().qpath_res(qpath, expr.hir_id);
1340                self.cat_res(expr.hir_id, expr.span, expr_ty, res)
1341            }
1342
1343            // type ascription doesn't affect the place-ness of the subexpression.
1344            hir::ExprKind::Type(e, _) => self.cat_expr(e),
1345
1346            hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Unwrap, e, _) => {
1347                let base = self.cat_expr(e)?;
1348                Ok(self.cat_projection(
1349                    expr.hir_id,
1350                    base,
1351                    expr_ty,
1352                    ProjectionKind::UnwrapUnsafeBinder,
1353                ))
1354            }
1355
1356            hir::ExprKind::AddrOf(..)
1357            | hir::ExprKind::Call(..)
1358            | hir::ExprKind::Use(..)
1359            | hir::ExprKind::Assign(..)
1360            | hir::ExprKind::AssignOp(..)
1361            | hir::ExprKind::Closure { .. }
1362            | hir::ExprKind::Ret(..)
1363            | hir::ExprKind::Become(..)
1364            | hir::ExprKind::Unary(..)
1365            | hir::ExprKind::Yield(..)
1366            | hir::ExprKind::MethodCall(..)
1367            | hir::ExprKind::Cast(..)
1368            | hir::ExprKind::DropTemps(..)
1369            | hir::ExprKind::Array(..)
1370            | hir::ExprKind::If(..)
1371            | hir::ExprKind::Tup(..)
1372            | hir::ExprKind::Binary(..)
1373            | hir::ExprKind::Block(..)
1374            | hir::ExprKind::Let(..)
1375            | hir::ExprKind::Loop(..)
1376            | hir::ExprKind::Match(..)
1377            | hir::ExprKind::Lit(..)
1378            | hir::ExprKind::ConstBlock(..)
1379            | hir::ExprKind::Break(..)
1380            | hir::ExprKind::Continue(..)
1381            | hir::ExprKind::Struct(..)
1382            | hir::ExprKind::Repeat(..)
1383            | hir::ExprKind::InlineAsm(..)
1384            | hir::ExprKind::OffsetOf(..)
1385            | hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Wrap, ..)
1386            | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr_ty)),
1387        }
1388    }
1389
1390    fn cat_res(
1391        &self,
1392        hir_id: HirId,
1393        span: Span,
1394        expr_ty: Ty<'tcx>,
1395        res: Res,
1396    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1397        match res {
1398            Res::Def(
1399                DefKind::Ctor(..)
1400                | DefKind::Const { .. }
1401                | DefKind::ConstParam
1402                | DefKind::AssocConst { .. }
1403                | DefKind::Fn
1404                | DefKind::AssocFn,
1405                _,
1406            )
1407            | Res::SelfCtor(..) => Ok(self.cat_rvalue(hir_id, expr_ty)),
1408
1409            Res::Def(DefKind::Static { .. }, _) => {
1410                Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::StaticItem, Vec::new()))
1411            }
1412
1413            Res::Local(var_id) => {
1414                if self.upvars.is_some_and(|upvars| upvars.contains_key(&var_id)) {
1415                    self.cat_upvar(hir_id, var_id)
1416                } else {
1417                    Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Local(var_id), Vec::new()))
1418                }
1419            }
1420
1421            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),
1422        }
1423    }
1424
1425    /// Categorize an upvar.
1426    ///
1427    /// Note: the actual upvar access contains invisible derefs of closure
1428    /// environment and upvar reference as appropriate. Only regionck cares
1429    /// about these dereferences, so we let it compute them as needed.
1430    fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1431        let closure_expr_def_id = self.cx.body_owner_def_id();
1432
1433        let upvar_id = ty::UpvarId {
1434            var_path: ty::UpvarPath { hir_id: var_id },
1435            closure_expr_id: closure_expr_def_id,
1436        };
1437        let var_ty = self.node_ty(var_id)?;
1438
1439        Ok(PlaceWithHirId::new(hir_id, var_ty, PlaceBase::Upvar(upvar_id), Vec::new()))
1440    }
1441
1442    fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> {
1443        PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new())
1444    }
1445
1446    fn cat_projection(
1447        &self,
1448        node: HirId,
1449        base_place: PlaceWithHirId<'tcx>,
1450        ty: Ty<'tcx>,
1451        kind: ProjectionKind,
1452    ) -> PlaceWithHirId<'tcx> {
1453        let place_ty = base_place.place.ty();
1454        let mut projections = base_place.place.projections;
1455
1456        let node_ty = self.cx.typeck_results().node_type(node);
1457        if !self.cx.tcx().next_trait_solver_globally() {
1458            // Opaque types can't have field projections, but we can instead convert
1459            // the current place in-place (heh) to the hidden type, and then apply all
1460            // follow up projections on that.
1461            if node_ty != place_ty
1462                && self
1463                    .cx
1464                    .structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), place_ty)
1465                    .is_opaque()
1466            {
1467                projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
1468            }
1469        }
1470        projections.push(Projection { kind, ty });
1471        PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections)
1472    }
1473
1474    fn cat_overloaded_place(
1475        &self,
1476        expr: &hir::Expr<'_>,
1477        base: &hir::Expr<'_>,
1478    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1479        // Reconstruct the output assuming it's a reference with the
1480        // same region and mutability as the receiver. This holds for
1481        // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
1482        let place_ty = self.expr_ty(expr)?;
1483        let base_ty = self.expr_ty_adjusted(base)?;
1484
1485        let ty::Ref(region, _, mutbl) =
1486            *self.cx.structurally_resolve_type(base.span, base_ty).kind()
1487        else {
1488            ::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");
1489        };
1490        let ref_ty = Ty::new_ref(self.cx.tcx(), region, place_ty, mutbl);
1491
1492        let base = self.cat_rvalue(expr.hir_id, ref_ty);
1493        self.cat_deref(expr.hir_id, base)
1494    }
1495
1496    fn cat_deref(
1497        &self,
1498        node: HirId,
1499        base_place: PlaceWithHirId<'tcx>,
1500    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1501        let base_curr_ty = base_place.place.ty();
1502        let Some(deref_ty) = self
1503            .cx
1504            .structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty)
1505            .builtin_deref(true)
1506        else {
1507            {
    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:1507",
                        "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(1507u32),
                        ::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);
1508            return Err(self
1509                .cx
1510                .report_bug(self.cx.tcx().hir_span(node), "explicit deref of non-derefable type"));
1511        };
1512        let mut projections = base_place.place.projections;
1513        projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty });
1514
1515        Ok(PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections))
1516    }
1517
1518    /// Returns the variant index for an ADT used within a Struct or TupleStruct pattern
1519    /// Here `pat_hir_id` is the HirId of the pattern itself.
1520    fn variant_index_for_adt(
1521        &self,
1522        qpath: &hir::QPath<'_>,
1523        pat_hir_id: HirId,
1524        span: Span,
1525    ) -> Result<VariantIdx, Cx::Error> {
1526        let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id);
1527        let ty = self.cx.typeck_results().node_type(pat_hir_id);
1528        let ty::Adt(adt_def, _) = self.cx.structurally_resolve_type(span, ty).kind() else {
1529            return Err(self
1530                .cx
1531                .report_bug(span, "struct or tuple struct pattern not applied to an ADT"));
1532        };
1533
1534        match res {
1535            Res::Def(DefKind::Variant, variant_id) => Ok(adt_def.variant_index_with_id(variant_id)),
1536            Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
1537                Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id))
1538            }
1539            Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
1540            | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
1541            | Res::SelfCtor(..)
1542            | Res::SelfTyParam { .. }
1543            | Res::SelfTyAlias { .. } => {
1544                // Structs and Unions have only have one variant.
1545                Ok(FIRST_VARIANT)
1546            }
1547            _ => ::rustc_middle::util::bug::bug_fmt(format_args!("expected ADT path, found={0:?}",
        res))bug!("expected ADT path, found={:?}", res),
1548        }
1549    }
1550
1551    /// Returns the total number of fields in an ADT variant used within a pattern.
1552    /// Here `pat_hir_id` is the HirId of the pattern itself.
1553    fn total_fields_in_adt_variant(
1554        &self,
1555        pat_hir_id: HirId,
1556        variant_index: VariantIdx,
1557        span: Span,
1558    ) -> Result<usize, Cx::Error> {
1559        let ty = self.cx.typeck_results().node_type(pat_hir_id);
1560        match self.cx.structurally_resolve_type(span, ty).kind() {
1561            ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
1562            _ => {
1563                self.cx
1564                    .tcx()
1565                    .dcx()
1566                    .span_bug(span, "struct or tuple struct pattern not applied to an ADT");
1567            }
1568        }
1569    }
1570
1571    /// Returns the total number of fields in a tuple used within a Tuple pattern.
1572    /// Here `pat_hir_id` is the HirId of the pattern itself.
1573    fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> Result<usize, Cx::Error> {
1574        let ty = self.cx.typeck_results().node_type(pat_hir_id);
1575        match self.cx.structurally_resolve_type(span, ty).kind() {
1576            ty::Tuple(args) => Ok(args.len()),
1577            _ => Err(self.cx.report_bug(span, "tuple pattern not applied to a tuple")),
1578        }
1579    }
1580
1581    /// Here, `place` is the `PlaceWithHirId` being matched and pat is the pattern it
1582    /// is being matched against.
1583    ///
1584    /// In general, the way that this works is that we walk down the pattern,
1585    /// constructing a `PlaceWithHirId` that represents the path that will be taken
1586    /// to reach the value being matched.
1587    fn cat_pattern<F>(
1588        &self,
1589        mut place_with_id: PlaceWithHirId<'tcx>,
1590        pat: &hir::Pat<'_>,
1591        op: &mut F,
1592    ) -> Result<(), Cx::Error>
1593    where
1594        F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>) -> Result<(), Cx::Error>,
1595    {
1596        // If (pattern) adjustments are active for this pattern, adjust the `PlaceWithHirId` correspondingly.
1597        // `PlaceWithHirId`s are constructed differently from patterns. For example, in
1598        //
1599        // ```
1600        // match foo {
1601        //     &&Some(x, ) => { ... },
1602        //     _ => { ... },
1603        // }
1604        // ```
1605        //
1606        // the pattern `&&Some(x,)` is represented as `Ref { Ref { TupleStruct }}`. To build the
1607        // corresponding `PlaceWithHirId` we start with the `PlaceWithHirId` for `foo`, and then, by traversing the
1608        // pattern, try to answer the question: given the address of `foo`, how is `x` reached?
1609        //
1610        // `&&Some(x,)` `place_foo`
1611        //  `&Some(x,)` `deref { place_foo}`
1612        //   `Some(x,)` `deref { deref { place_foo }}`
1613        //       `(x,)` `field0 { deref { deref { place_foo }}}` <- resulting place
1614        //
1615        // The above example has no adjustments. If the code were instead the (after adjustments,
1616        // equivalent) version
1617        //
1618        // ```
1619        // match foo {
1620        //     Some(x, ) => { ... },
1621        //     _ => { ... },
1622        // }
1623        // ```
1624        //
1625        // Then we see that to get the same result, we must start with
1626        // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)`
1627        // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`.
1628        let typeck_results = self.cx.typeck_results();
1629        let adjustments: &[adjustment::PatAdjustment<'tcx>] =
1630            typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
1631        let mut adjusts = adjustments.iter().peekable();
1632        while let Some(adjust) = adjusts.next() {
1633            {
    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:1633",
                        "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(1633u32),
                        ::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);
1634            place_with_id = match adjust.kind {
1635                adjustment::PatAdjust::BuiltinDeref => self.cat_deref(pat.hir_id, place_with_id)?,
1636                adjustment::PatAdjust::OverloadedDeref => {
1637                    // This adjustment corresponds to an overloaded deref; unless it's on a box, it
1638                    // borrows the scrutinee to call `Deref::deref` or `DerefMut::deref_mut`. Invoke
1639                    // the callback before setting `place_with_id` to the temporary storing the
1640                    // result of the deref.
1641                    // HACK(dianne): giving the callback a fake deref pattern makes sure it behaves the
1642                    // same as it would if this were an explicit deref pattern (including for boxes).
1643                    op(&place_with_id, &hir::Pat { kind: PatKind::Deref(pat), ..*pat })?;
1644                    let target_ty = match adjusts.peek() {
1645                        Some(&&next_adjust) => next_adjust.source,
1646                        // At the end of the deref chain, we get `pat`'s scrutinee.
1647                        None => self.pat_ty_unadjusted(pat)?,
1648                    };
1649                    self.pat_deref_place(pat.hir_id, place_with_id, pat, target_ty)?
1650                }
1651                adjustment::PatAdjust::PinDeref => {
1652                    {
    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:1652",
                        "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(1652u32),
                        ::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);
1653                    let target_ty = adjust.source.pinned_ty().ok_or_else(|| {
1654                        self.cx.report_bug(
1655                            self.cx.tcx().hir_span(pat.hir_id),
1656                            "`PinDeref` of non-pinned-reference type",
1657                        )
1658                    })?;
1659                    let kind = ProjectionKind::Field(FieldIdx::ZERO, FIRST_VARIANT);
1660                    place_with_id = self.cat_projection(pat.hir_id, place_with_id, target_ty, kind);
1661                    self.cat_deref(pat.hir_id, place_with_id)?
1662                }
1663            };
1664        }
1665        drop(typeck_results); // explicitly release borrow of typeck results, just in case.
1666        let place_with_id = place_with_id; // lose mutability
1667        {
    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:1667",
                        "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(1667u32),
                        ::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);
1668
1669        // Invoke the callback, but only now, after the `place_with_id` has adjusted.
1670        //
1671        // To see that this makes sense, consider `match &Some(3) { Some(x) => { ... }}`. In that
1672        // case, the initial `place_with_id` will be that for `&Some(3)` and the pattern is `Some(x)`. We
1673        // don't want to call `op` with these incompatible values. As written, what happens instead
1674        // is that `op` is called with the adjusted place (that for `*&Some(3)`) and the pattern
1675        // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)`
1676        // result in the place `Downcast<Some>(*&Some(3)).0` associated to `x` and invoke `op` with
1677        // that (where the `ref` on `x` is implied).
1678        op(&place_with_id, pat)?;
1679
1680        match pat.kind {
1681            PatKind::Tuple(subpats, dots_pos) => {
1682                // (p1, ..., pN)
1683                let total_fields = self.total_fields_in_tuple(pat.hir_id, pat.span)?;
1684
1685                for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
1686                    let subpat_ty = self.pat_ty_adjusted(subpat)?;
1687                    let projection_kind =
1688                        ProjectionKind::Field(FieldIdx::from_usize(i), FIRST_VARIANT);
1689                    let sub_place = self.cat_projection(
1690                        pat.hir_id,
1691                        place_with_id.clone(),
1692                        subpat_ty,
1693                        projection_kind,
1694                    );
1695                    self.cat_pattern(sub_place, subpat, op)?;
1696                }
1697            }
1698
1699            PatKind::TupleStruct(ref qpath, subpats, dots_pos) => {
1700                // S(p1, ..., pN)
1701                let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?;
1702                let total_fields =
1703                    self.total_fields_in_adt_variant(pat.hir_id, variant_index, pat.span)?;
1704
1705                for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) {
1706                    let subpat_ty = self.pat_ty_adjusted(subpat)?;
1707                    let projection_kind =
1708                        ProjectionKind::Field(FieldIdx::from_usize(i), variant_index);
1709                    let sub_place = self.cat_projection(
1710                        pat.hir_id,
1711                        place_with_id.clone(),
1712                        subpat_ty,
1713                        projection_kind,
1714                    );
1715                    self.cat_pattern(sub_place, subpat, op)?;
1716                }
1717            }
1718
1719            PatKind::Struct(ref qpath, field_pats, _) => {
1720                // S { f1: p1, ..., fN: pN }
1721
1722                let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?;
1723
1724                for fp in field_pats {
1725                    let field_ty = self.pat_ty_adjusted(fp.pat)?;
1726                    let field_index = self
1727                        .cx
1728                        .typeck_results()
1729                        .field_indices()
1730                        .get(fp.hir_id)
1731                        .cloned()
1732                        .expect("no index for a field");
1733
1734                    let field_place = self.cat_projection(
1735                        pat.hir_id,
1736                        place_with_id.clone(),
1737                        field_ty,
1738                        ProjectionKind::Field(field_index, variant_index),
1739                    );
1740                    self.cat_pattern(field_place, fp.pat, op)?;
1741                }
1742            }
1743
1744            PatKind::Or(pats) => {
1745                for pat in pats {
1746                    self.cat_pattern(place_with_id.clone(), pat, op)?;
1747                }
1748            }
1749
1750            PatKind::Binding(.., Some(subpat)) | PatKind::Guard(subpat, _) => {
1751                self.cat_pattern(place_with_id, subpat, op)?;
1752            }
1753
1754            PatKind::Ref(subpat, _, _)
1755                if self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id) =>
1756            {
1757                self.cat_pattern(place_with_id, subpat, op)?;
1758            }
1759
1760            PatKind::Box(subpat) | PatKind::Ref(subpat, _, _) => {
1761                // box p1, &p1, &mut p1. we can ignore the mutability of
1762                // PatKind::Ref since that information is already contained
1763                // in the type.
1764                let subplace = self.cat_deref(pat.hir_id, place_with_id)?;
1765                self.cat_pattern(subplace, subpat, op)?;
1766            }
1767            PatKind::Deref(subpat) => {
1768                let ty = self.pat_ty_adjusted(subpat)?;
1769                let place = self.pat_deref_place(pat.hir_id, place_with_id, subpat, ty)?;
1770                self.cat_pattern(place, subpat, op)?;
1771            }
1772
1773            PatKind::Slice(before, ref slice, after) => {
1774                let Some(element_ty) = self
1775                    .cx
1776                    .structurally_resolve_type(pat.span, place_with_id.place.ty())
1777                    .builtin_index()
1778                else {
1779                    {
    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:1779",
                        "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(1779u32),
                        ::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);
1780                    return Err(self
1781                        .cx
1782                        .report_bug(pat.span, "explicit index of non-indexable type"));
1783                };
1784                let elt_place = self.cat_projection(
1785                    pat.hir_id,
1786                    place_with_id.clone(),
1787                    element_ty,
1788                    ProjectionKind::Index,
1789                );
1790                for before_pat in before {
1791                    self.cat_pattern(elt_place.clone(), before_pat, op)?;
1792                }
1793                if let Some(slice_pat) = *slice {
1794                    let slice_pat_ty = self.pat_ty_adjusted(slice_pat)?;
1795                    let slice_place = self.cat_projection(
1796                        pat.hir_id,
1797                        place_with_id,
1798                        slice_pat_ty,
1799                        ProjectionKind::Subslice,
1800                    );
1801                    self.cat_pattern(slice_place, slice_pat, op)?;
1802                }
1803                for after_pat in after {
1804                    self.cat_pattern(elt_place.clone(), after_pat, op)?;
1805                }
1806            }
1807
1808            PatKind::Binding(.., None)
1809            | PatKind::Expr(..)
1810            | PatKind::Range(..)
1811            | PatKind::Never
1812            | PatKind::Missing
1813            | PatKind::Wild
1814            | PatKind::Err(_) => {
1815                // always ok
1816            }
1817        }
1818
1819        Ok(())
1820    }
1821
1822    /// Represents the place matched on by a deref pattern's interior.
1823    fn pat_deref_place(
1824        &self,
1825        hir_id: HirId,
1826        base_place: PlaceWithHirId<'tcx>,
1827        inner: &hir::Pat<'_>,
1828        target_ty: Ty<'tcx>,
1829    ) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
1830        match self.cx.typeck_results().deref_pat_borrow_mode(base_place.place.ty(), inner) {
1831            // Deref patterns on boxes are lowered using a built-in deref.
1832            DerefPatBorrowMode::Box => self.cat_deref(hir_id, base_place),
1833            // For other types, we create a temporary to match on.
1834            DerefPatBorrowMode::Borrow(mutability) => {
1835                let re_erased = self.cx.tcx().lifetimes.re_erased;
1836                let ty = Ty::new_ref(self.cx.tcx(), re_erased, target_ty, mutability);
1837                // A deref pattern stores the result of `Deref::deref` or `DerefMut::deref_mut` ...
1838                let base = self.cat_rvalue(hir_id, ty);
1839                // ... and the inner pattern matches on the place behind that reference.
1840                self.cat_deref(hir_id, base)
1841            }
1842        }
1843    }
1844
1845    /// Checks whether a type has multiple variants, and therefore, whether a
1846    /// read of the discriminant might be necessary.
1847    #[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(1847u32),
                                    ::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")]
1848    fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool {
1849        if let ty::Adt(def, _) = self.cx.structurally_resolve_type(span, ty).kind() {
1850            // We treat non-exhaustive enums the same independent of the crate they are
1851            // defined in, to avoid differences in the operational semantics between crates.
1852            def.variants().len() > 1 || def.is_variant_list_non_exhaustive()
1853        } else {
1854            false
1855        }
1856    }
1857}