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