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::{
26    self, BorrowKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, adjustment,
27};
28use rustc_middle::{bug, span_bug};
29use rustc_span::{ErrorGuaranteed, Span};
30use rustc_trait_selection::infer::InferCtxtExt;
31use tracing::{debug, instrument, trace};
32
33use crate::fn_ctxt::FnCtxt;
34
35/// This trait defines the callbacks you can expect to receive when
36/// employing the ExprUseVisitor.
37pub trait Delegate<'tcx> {
38    /// The value found at `place` is moved, depending
39    /// on `mode`. Where `diag_expr_id` is the id used for diagnostics for `place`.
40    ///
41    /// If the value is `Copy`, [`copy`][Self::copy] is called instead, which
42    /// by default falls back to [`borrow`][Self::borrow].
43    ///
44    /// The parameter `diag_expr_id` indicates the HIR id that ought to be used for
45    /// diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic
46    /// id will be the id of the expression `expr` but the place itself will have
47    /// the id of the binding in the pattern `pat`.
48    fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId);
49
50    /// The value found at `place` is used, depending
51    /// on `mode`. Where `diag_expr_id` is the id used for diagnostics for `place`.
52    ///
53    /// Use of a `Copy` type in a ByUse context is considered a use
54    /// by `ImmBorrow` and `borrow` is called instead. This is because
55    /// a shared borrow is the "minimum access" that would be needed
56    /// to perform a copy.
57    ///
58    ///
59    /// The parameter `diag_expr_id` indicates the HIR id that ought to be used for
60    /// diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic
61    /// id will be the id of the expression `expr` but the place itself will have
62    /// the id of the binding in the pattern `pat`.
63    fn use_cloned(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId);
64
65    /// The value found at `place` is being borrowed with kind `bk`.
66    /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
67    fn borrow(
68        &mut self,
69        place_with_id: &PlaceWithHirId<'tcx>,
70        diag_expr_id: HirId,
71        bk: ty::BorrowKind,
72    );
73
74    /// The value found at `place` is being copied.
75    /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
76    ///
77    /// If an implementation is not provided, use of a `Copy` type in a ByValue context is instead
78    /// considered a use by `ImmBorrow` and `borrow` is called instead. This is because a shared
79    /// borrow is the "minimum access" that would be needed to perform a copy.
80    fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
81        // In most cases, copying data from `x` is equivalent to doing `*&x`, so by default
82        // we treat a copy of `x` as a borrow of `x`.
83        self.borrow(place_with_id, diag_expr_id, ty::BorrowKind::Immutable)
84    }
85
86    /// The path at `assignee_place` is being assigned to.
87    /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
88    fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId);
89
90    /// The path at `binding_place` is a binding that is being initialized.
91    ///
92    /// This covers cases such as `let x = 42;`
93    fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
94        // Bindings can normally be treated as a regular assignment, so by default we
95        // forward this to the mutate callback.
96        self.mutate(binding_place, diag_expr_id)
97    }
98
99    /// The `place` should be a fake read because of specified `cause`.
100    fn fake_read(
101        &mut self,
102        place_with_id: &PlaceWithHirId<'tcx>,
103        cause: FakeReadCause,
104        diag_expr_id: HirId,
105    );
106}
107
108impl<'tcx, D: Delegate<'tcx>> Delegate<'tcx> for &mut D {
109    fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
110        (**self).consume(place_with_id, diag_expr_id)
111    }
112
113    fn use_cloned(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
114        (**self).use_cloned(place_with_id, diag_expr_id)
115    }
116
117    fn borrow(
118        &mut self,
119        place_with_id: &PlaceWithHirId<'tcx>,
120        diag_expr_id: HirId,
121        bk: ty::BorrowKind,
122    ) {
123        (**self).borrow(place_with_id, diag_expr_id, bk)
124    }
125
126    fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
127        (**self).copy(place_with_id, diag_expr_id)
128    }
129
130    fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
131        (**self).mutate(assignee_place, diag_expr_id)
132    }
133
134    fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
135        (**self).bind(binding_place, diag_expr_id)
136    }
137
138    fn fake_read(
139        &mut self,
140        place_with_id: &PlaceWithHirId<'tcx>,
141        cause: FakeReadCause,
142        diag_expr_id: HirId,
143    ) {
144        (**self).fake_read(place_with_id, cause, diag_expr_id)
145    }
146}
147
148/// This trait makes `ExprUseVisitor` usable with both [`FnCtxt`]
149/// and [`LateContext`], depending on where in the compiler it is used.
150pub trait TypeInformationCtxt<'tcx> {
151    type TypeckResults<'a>: Deref<Target = ty::TypeckResults<'tcx>>
152    where
153        Self: 'a;
154
155    type Error;
156
157    fn typeck_results(&self) -> Self::TypeckResults<'_>;
158
159    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T;
160
161    fn structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
162
163    fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error;
164
165    fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error>;
166
167    fn tainted_by_errors(&self) -> Result<(), Self::Error>;
168
169    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool;
170
171    fn type_is_use_cloned_modulo_regions(&self, ty: Ty<'tcx>) -> bool;
172
173    fn body_owner_def_id(&self) -> LocalDefId;
174
175    fn tcx(&self) -> TyCtxt<'tcx>;
176}
177
178impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> {
179    type TypeckResults<'a>
180        = Ref<'a, ty::TypeckResults<'tcx>>
181    where
182        Self: 'a;
183
184    type Error = ErrorGuaranteed;
185
186    fn typeck_results(&self) -> Self::TypeckResults<'_> {
187        self.typeck_results.borrow()
188    }
189
190    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
191        self.infcx.resolve_vars_if_possible(t)
192    }
193
194    fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
195        (**self).structurally_resolve_type(sp, ty)
196    }
197
198    fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error {
199        self.dcx().span_delayed_bug(span, msg.to_string())
200    }
201
202    fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error> {
203        ty.error_reported()
204    }
205
206    fn tainted_by_errors(&self) -> Result<(), ErrorGuaranteed> {
207        if let Some(guar) = self.infcx.tainted_by_errors() { Err(guar) } else { Ok(()) }
208    }
209
210    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
211        self.infcx.type_is_copy_modulo_regions(self.param_env, ty)
212    }
213
214    fn type_is_use_cloned_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
215        self.infcx.type_is_use_cloned_modulo_regions(self.param_env, ty)
216    }
217
218    fn body_owner_def_id(&self) -> LocalDefId {
219        self.body_id
220    }
221
222    fn tcx(&self) -> TyCtxt<'tcx> {
223        self.tcx
224    }
225}
226
227impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
228    type TypeckResults<'a>
229        = &'tcx ty::TypeckResults<'tcx>
230    where
231        Self: 'a;
232
233    type Error = !;
234
235    fn typeck_results(&self) -> Self::TypeckResults<'_> {
236        self.0.maybe_typeck_results().expect("expected typeck results")
237    }
238
239    fn structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
240        // FIXME: Maybe need to normalize here.
241        ty
242    }
243
244    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
245        t
246    }
247
248    fn report_bug(&self, span: Span, msg: impl ToString) -> ! {
249        ::rustc_middle::util::bug::span_bug_fmt(span,
    format_args!("{0}", msg.to_string()))span_bug!(span, "{}", msg.to_string())
250    }
251
252    fn error_reported_in_ty(&self, _ty: Ty<'tcx>) -> Result<(), !> {
253        Ok(())
254    }
255
256    fn tainted_by_errors(&self) -> Result<(), !> {
257        Ok(())
258    }
259
260    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
261        self.0.type_is_copy_modulo_regions(ty)
262    }
263
264    fn type_is_use_cloned_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
265        self.0.type_is_use_cloned_modulo_regions(ty)
266    }
267
268    fn body_owner_def_id(&self) -> LocalDefId {
269        self.1
270    }
271
272    fn tcx(&self) -> TyCtxt<'tcx> {
273        self.0.tcx
274    }
275}
276
277/// A visitor that reports how each expression is being used.
278///
279/// See [module-level docs][self] and [`Delegate`] for details.
280pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> {
281    cx: Cx,
282    /// We use a `RefCell` here so that delegates can mutate themselves, but we can
283    /// still have calls to our own helper functions.
284    delegate: RefCell<D>,
285    upvars: Option<&'tcx FxIndexMap<HirId, hir::Upvar>>,
286}
287
288impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'tcx, (&'a LateContext<'tcx>, LocalDefId), D> {
289    pub fn for_clippy(cx: &'a LateContext<'tcx>, body_def_id: LocalDefId, delegate: D) -> Self {
290        Self::new((cx, body_def_id), delegate)
291    }
292}
293
294impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
295    /// Creates the ExprUseVisitor, configuring it with the various options provided:
296    ///
297    /// - `delegate` -- who receives the callbacks
298    /// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`)
299    /// - `typeck_results` --- typeck results for the code being analyzed
300    pub(crate) fn new(cx: Cx, delegate: D) -> Self {
301        ExprUseVisitor {
302            delegate: RefCell::new(delegate),
303            upvars: cx.tcx().upvars_mentioned(cx.body_owner_def_id()),
304            cx,
305        }
306    }
307
308    pub fn consume_body(&self, body: &hir::Body<'_>) -> Result<(), Cx::Error> {
309        for param in body.params {
310            let param_ty = self.pat_ty_adjusted(param.pat)?;
311            {
    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:311",
                        "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(311u32),
                        ::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);
312
313            let param_place = self.cat_rvalue(param.hir_id, param_ty);
314
315            self.fake_read_scrutinee(&param_place, false)?;
316            self.walk_pat(&param_place, param.pat, false)?;
317        }
318
319        self.consume_expr(body.value)?;
320
321        Ok(())
322    }
323
324    #[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(324u32),
                                    ::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")]
325    fn consume_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
326        if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
327            self.delegate.borrow_mut().copy(place_with_id, diag_expr_id);
328        } else {
329            self.delegate.borrow_mut().consume(place_with_id, diag_expr_id);
330        }
331    }
332
333    #[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(333u32),
                                    ::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")]
334    pub fn consume_clone_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
335        // `x.use` will do one of the following
336        // * if it implements `Copy`, it will be a copy
337        // * if it implements `UseCloned`, it will be a call to `clone`
338        // * otherwise, it is a move
339        //
340        // we do a conservative approximation of this, treating it as a move unless we know that it implements copy or `UseCloned`
341        if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
342            self.delegate.borrow_mut().copy(place_with_id, diag_expr_id);
343        } else if self.cx.type_is_use_cloned_modulo_regions(place_with_id.place.ty()) {
344            self.delegate.borrow_mut().use_cloned(place_with_id, diag_expr_id);
345        } else {
346            self.delegate.borrow_mut().consume(place_with_id, diag_expr_id);
347        }
348    }
349
350    fn consume_exprs(&self, exprs: &[hir::Expr<'_>]) -> Result<(), Cx::Error> {
351        for expr in exprs {
352            self.consume_expr(expr)?;
353        }
354
355        Ok(())
356    }
357
358    // FIXME: It's suspicious that this is public; clippy should probably use `walk_expr`.
359    #[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(359u32),
                                    ::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")]
360    pub fn consume_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
361        let place_with_id = self.cat_expr(expr)?;
362        self.consume_or_copy(&place_with_id, place_with_id.hir_id);
363        self.walk_expr(expr)?;
364        Ok(())
365    }
366
367    #[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(367u32),
                                    ::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")]
368    pub fn consume_or_clone_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
369        let place_with_id = self.cat_expr(expr)?;
370        self.consume_clone_or_copy(&place_with_id, place_with_id.hir_id);
371        self.walk_expr(expr)?;
372        Ok(())
373    }
374
375    fn mutate_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
376        let place_with_id = self.cat_expr(expr)?;
377        self.delegate.borrow_mut().mutate(&place_with_id, place_with_id.hir_id);
378        self.walk_expr(expr)?;
379        Ok(())
380    }
381
382    #[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(382u32),
                                    ::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")]
383    fn borrow_expr(&self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) -> Result<(), Cx::Error> {
384        let place_with_id = self.cat_expr(expr)?;
385        self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
386        self.walk_expr(expr)
387    }
388
389    #[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(389u32),
                                    ::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")]
390    pub fn walk_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
391        self.walk_adjustment(expr)?;
392
393        match expr.kind {
394            hir::ExprKind::Path(_) => {}
395
396            hir::ExprKind::Type(subexpr, _) => {
397                self.walk_expr(subexpr)?;
398            }
399
400            hir::ExprKind::UnsafeBinderCast(_, subexpr, _) => {
401                self.walk_expr(subexpr)?;
402            }
403
404            hir::ExprKind::Unary(hir::UnOp::Deref, base) => {
405                // *base
406                self.walk_expr(base)?;
407            }
408
409            hir::ExprKind::Field(base, _) => {
410                // base.f
411                self.walk_expr(base)?;
412            }
413
414            hir::ExprKind::Index(lhs, rhs, _) => {
415                // lhs[rhs]
416                self.walk_expr(lhs)?;
417                self.consume_expr(rhs)?;
418            }
419
420            hir::ExprKind::Call(callee, args) => {
421                // callee(args)
422                self.consume_expr(callee)?;
423                self.consume_exprs(args)?;
424            }
425
426            hir::ExprKind::Use(expr, _) => {
427                self.consume_or_clone_expr(expr)?;
428            }
429
430            hir::ExprKind::MethodCall(.., receiver, args, _) => {
431                // callee.m(args)
432                self.consume_expr(receiver)?;
433                self.consume_exprs(args)?;
434            }
435
436            hir::ExprKind::Struct(_, fields, ref opt_with) => {
437                self.walk_struct_expr(fields, opt_with)?;
438            }
439
440            hir::ExprKind::Tup(exprs) => {
441                self.consume_exprs(exprs)?;
442            }
443
444            hir::ExprKind::If(cond_expr, then_expr, ref opt_else_expr) => {
445                self.consume_expr(cond_expr)?;
446                self.consume_expr(then_expr)?;
447                if let Some(else_expr) = *opt_else_expr {
448                    self.consume_expr(else_expr)?;
449                }
450            }
451
452            hir::ExprKind::Let(hir::LetExpr { pat, init, .. }) => {
453                self.walk_local(init, pat, None, || self.borrow_expr(init, BorrowKind::Immutable))?;
454            }
455
456            hir::ExprKind::Match(discr, arms, _) => {
457                let discr_place = self.cat_expr(discr)?;
458                self.fake_read_scrutinee(&discr_place, true)?;
459                self.walk_expr(discr)?;
460
461                for arm in arms {
462                    self.walk_arm(&discr_place, arm)?;
463                }
464            }
465
466            hir::ExprKind::Array(exprs) => {
467                self.consume_exprs(exprs)?;
468            }
469
470            hir::ExprKind::AddrOf(_, m, base) => {
471                // &base
472                // make sure that the thing we are pointing out stays valid
473                // for the lifetime `scope_r` of the resulting ptr:
474                let bk = ty::BorrowKind::from_mutbl(m);
475                self.borrow_expr(base, bk)?;
476            }
477
478            hir::ExprKind::InlineAsm(asm) => {
479                for (op, _op_sp) in asm.operands {
480                    match op {
481                        hir::InlineAsmOperand::In { expr, .. } => {
482                            self.consume_expr(expr)?;
483                        }
484                        hir::InlineAsmOperand::Out { expr: Some(expr), .. }
485                        | hir::InlineAsmOperand::InOut { expr, .. } => {
486                            self.mutate_expr(expr)?;
487                        }
488                        hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
489                            self.consume_expr(in_expr)?;
490                            if let Some(out_expr) = out_expr {
491                                self.mutate_expr(out_expr)?;
492                            }
493                        }
494                        hir::InlineAsmOperand::Out { expr: None, .. }
495                        | hir::InlineAsmOperand::Const { .. }
496                        | hir::InlineAsmOperand::SymFn { .. }
497                        | hir::InlineAsmOperand::SymStatic { .. } => {}
498                        hir::InlineAsmOperand::Label { block } => {
499                            self.walk_block(block)?;
500                        }
501                    }
502                }
503            }
504
505            hir::ExprKind::Continue(..)
506            | hir::ExprKind::Lit(..)
507            | hir::ExprKind::ConstBlock(..)
508            | hir::ExprKind::OffsetOf(..)
509            | hir::ExprKind::Err(_) => {}
510
511            hir::ExprKind::Loop(blk, ..) => {
512                self.walk_block(blk)?;
513            }
514
515            hir::ExprKind::Unary(_, lhs) => {
516                self.consume_expr(lhs)?;
517            }
518
519            hir::ExprKind::Binary(_, lhs, rhs) => {
520                self.consume_expr(lhs)?;
521                self.consume_expr(rhs)?;
522            }
523
524            hir::ExprKind::Block(blk, _) => {
525                self.walk_block(blk)?;
526            }
527
528            hir::ExprKind::Break(_, ref opt_expr) | hir::ExprKind::Ret(ref opt_expr) => {
529                if let Some(expr) = *opt_expr {
530                    self.consume_expr(expr)?;
531                }
532            }
533
534            hir::ExprKind::Become(call) => {
535                self.consume_expr(call)?;
536            }
537
538            hir::ExprKind::Assign(lhs, rhs, _) => {
539                self.mutate_expr(lhs)?;
540                self.consume_expr(rhs)?;
541            }
542
543            hir::ExprKind::Cast(base, _) => {
544                self.consume_expr(base)?;
545            }
546
547            hir::ExprKind::DropTemps(expr) => {
548                self.consume_expr(expr)?;
549            }
550
551            hir::ExprKind::AssignOp(_, lhs, rhs) => {
552                if self.cx.typeck_results().is_method_call(expr) {
553                    self.consume_expr(lhs)?;
554                } else {
555                    self.mutate_expr(lhs)?;
556                }
557                self.consume_expr(rhs)?;
558            }
559
560            hir::ExprKind::Repeat(base, _) => {
561                self.consume_expr(base)?;
562            }
563
564            hir::ExprKind::Closure(closure) => {
565                self.walk_captures(closure)?;
566            }
567
568            hir::ExprKind::Yield(value, _) => {
569                self.consume_expr(value)?;
570            }
571        }
572
573        Ok(())
574    }
575
576    fn walk_stmt(&self, stmt: &hir::Stmt<'_>) -> Result<(), Cx::Error> {
577        match stmt.kind {
578            hir::StmtKind::Let(hir::LetStmt { pat, init: Some(expr), els, .. }) => {
579                self.walk_local(expr, pat, *els, || Ok(()))?;
580            }
581
582            hir::StmtKind::Let(_) => {}
583
584            hir::StmtKind::Item(_) => {
585                // We don't visit nested items in this visitor,
586                // only the fn body we were given.
587            }
588
589            hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) => {
590                self.consume_expr(expr)?;
591            }
592        }
593
594        Ok(())
595    }
596
597    #[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(597u32),
                                    ::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")]
598    fn fake_read_scrutinee(
599        &self,
600        discr_place: &PlaceWithHirId<'tcx>,
601        refutable: bool,
602    ) -> Result<(), Cx::Error> {
603        let closure_def_id = match discr_place.place.base {
604            PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id),
605            _ => None,
606        };
607
608        let cause = if refutable {
609            FakeReadCause::ForMatchedPlace(closure_def_id)
610        } else {
611            FakeReadCause::ForLet(closure_def_id)
612        };
613
614        self.delegate.borrow_mut().fake_read(discr_place, cause, discr_place.hir_id);
615
616        Ok(())
617    }
618
619    fn walk_local<F>(
620        &self,
621        expr: &hir::Expr<'_>,
622        pat: &hir::Pat<'_>,
623        els: Option<&hir::Block<'_>>,
624        mut f: F,
625    ) -> Result<(), Cx::Error>
626    where
627        F: FnMut() -> Result<(), Cx::Error>,
628    {
629        self.walk_expr(expr)?;
630        let expr_place = self.cat_expr(expr)?;
631        f()?;
632        self.fake_read_scrutinee(&expr_place, els.is_some())?;
633        self.walk_pat(&expr_place, pat, false)?;
634        if let Some(els) = els {
635            self.walk_block(els)?;
636        }
637        Ok(())
638    }
639
640    /// Indicates that the value of `blk` will be consumed, meaning either copied or moved
641    /// depending on its type.
642    #[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(642u32),
                                    ::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")]
643    fn walk_block(&self, blk: &hir::Block<'_>) -> Result<(), Cx::Error> {
644        for stmt in blk.stmts {
645            self.walk_stmt(stmt)?;
646        }
647
648        if let Some(tail_expr) = blk.expr {
649            self.consume_expr(tail_expr)?;
650        }
651
652        Ok(())
653    }
654
655    fn walk_struct_expr<'hir>(
656        &self,
657        fields: &[hir::ExprField<'_>],
658        opt_with: &hir::StructTailExpr<'hir>,
659    ) -> Result<(), Cx::Error> {
660        // Consume the expressions supplying values for each field.
661        for field in fields {
662            self.consume_expr(field.expr)?;
663
664            // The struct path probably didn't resolve
665            if self.cx.typeck_results().opt_field_index(field.hir_id).is_none() {
666                self.cx
667                    .tcx()
668                    .dcx()
669                    .span_delayed_bug(field.span, "couldn't resolve index for field");
670            }
671        }
672
673        let with_expr = match *opt_with {
674            hir::StructTailExpr::Base(w) => &*w,
675            hir::StructTailExpr::DefaultFields(_) | hir::StructTailExpr::None => {
676                return Ok(());
677            }
678        };
679
680        let with_place = self.cat_expr(with_expr)?;
681
682        // Select just those fields of the `with`
683        // expression that will actually be used
684        match self.cx.structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() {
685            ty::Adt(adt, args) if adt.is_struct() => {
686                // Consume those fields of the with expression that are needed.
687                for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() {
688                    let is_mentioned = fields.iter().any(|f| {
689                        self.cx.typeck_results().opt_field_index(f.hir_id) == Some(f_index)
690                    });
691                    if !is_mentioned {
692                        let field_place = self.cat_projection(
693                            with_expr.hir_id,
694                            with_place.clone(),
695                            with_field.ty(self.cx.tcx(), args),
696                            ProjectionKind::Field(f_index, FIRST_VARIANT),
697                        );
698                        self.consume_or_copy(&field_place, field_place.hir_id);
699                    }
700                }
701            }
702            _ => {
703                // the base expression should always evaluate to a
704                // struct; however, when EUV is run during typeck, it
705                // may not. This will generate an error earlier in typeck,
706                // so we can just ignore it.
707                if self.cx.tainted_by_errors().is_ok() {
708                    ::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");
709                }
710            }
711        }
712
713        // walk the with expression so that complex expressions
714        // are properly handled.
715        self.walk_expr(with_expr)?;
716
717        Ok(())
718    }
719
720    /// Invoke the appropriate delegate calls for anything that gets
721    /// consumed or borrowed as part of the automatic adjustment
722    /// process.
723    fn walk_adjustment(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> {
724        let typeck_results = self.cx.typeck_results();
725        let adjustments = typeck_results.expr_adjustments(expr);
726        let mut place_with_id = self.cat_expr_unadjusted(expr)?;
727        for adjustment in adjustments {
728            {
    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:728",
                        "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(728u32),
                        ::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);
729            match adjustment.kind {
730                adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) => {
731                    // Creating a closure/fn-pointer or unsizing consumes
732                    // the input and stores it into the resulting rvalue.
733                    self.consume_or_copy(&place_with_id, place_with_id.hir_id);
734                }
735
736                adjustment::Adjust::Deref(None) => {}
737
738                // Autoderefs for overloaded Deref calls in fact reference
739                // their receiver. That is, if we have `(*x)` where `x`
740                // is of type `Rc<T>`, then this in fact is equivalent to
741                // `x.deref()`. Since `deref()` is declared with `&self`,
742                // this is an autoref of `x`.
743                adjustment::Adjust::Deref(Some(ref deref)) => {
744                    let bk = ty::BorrowKind::from_mutbl(deref.mutbl);
745                    self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
746                }
747
748                adjustment::Adjust::Borrow(ref autoref) => {
749                    self.walk_autoref(expr, &place_with_id, autoref);
750                }
751
752                adjustment::Adjust::ReborrowPin(mutbl) => {
753                    // Reborrowing a Pin is like a combinations of a deref and a borrow, so we do
754                    // both.
755                    let bk = match mutbl {
756                        ty::Mutability::Not => ty::BorrowKind::Immutable,
757                        ty::Mutability::Mut => ty::BorrowKind::Mutable,
758                    };
759                    self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
760                }
761            }
762            place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?;
763        }
764
765        Ok(())
766    }
767
768    /// Walks the autoref `autoref` applied to the autoderef'd
769    /// `expr`. `base_place` is `expr` represented as a place,
770    /// after all relevant autoderefs have occurred.
771    fn walk_autoref(
772        &self,
773        expr: &hir::Expr<'_>,
774        base_place: &PlaceWithHirId<'tcx>,
775        autoref: &adjustment::AutoBorrow,
776    ) {
777        {
    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:777",
                        "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(777u32),
                        ::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!(
778            "walk_autoref(expr.hir_id={} base_place={:?} autoref={:?})",
779            expr.hir_id, base_place, autoref
780        );
781
782        match *autoref {
783            adjustment::AutoBorrow::Ref(m) => {
784                self.delegate.borrow_mut().borrow(
785                    base_place,
786                    base_place.hir_id,
787                    ty::BorrowKind::from_mutbl(m.into()),
788                );
789            }
790
791            adjustment::AutoBorrow::RawPtr(m) => {
792                {
    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:792",
                        "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(792u32),
                        ::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);
793
794                self.delegate.borrow_mut().borrow(
795                    base_place,
796                    base_place.hir_id,
797                    ty::BorrowKind::from_mutbl(m),
798                );
799            }
800        }
801    }
802
803    fn walk_arm(
804        &self,
805        discr_place: &PlaceWithHirId<'tcx>,
806        arm: &hir::Arm<'_>,
807    ) -> Result<(), Cx::Error> {
808        self.walk_pat(discr_place, arm.pat, arm.guard.is_some())?;
809
810        if let Some(ref e) = arm.guard {
811            self.consume_expr(e)?;
812        }
813
814        self.consume_expr(arm.body)?;
815        Ok(())
816    }
817
818    /// The core driver for walking a pattern
819    ///
820    /// This should mirror how pattern-matching gets lowered to MIR, as
821    /// otherwise lowering will ICE when trying to resolve the upvars.
822    ///
823    /// However, it is okay to approximate it here by doing *more* accesses than
824    /// the actual MIR builder will, which is useful when some checks are too
825    /// cumbersome to perform here. For example, if after typeck it becomes
826    /// clear that only one variant of an enum is inhabited, and therefore a
827    /// read of the discriminant is not necessary, `walk_pat` will have
828    /// over-approximated the necessary upvar capture granularity.
829    ///
830    /// Do note that discrepancies like these do still create obscure corners
831    /// in the semantics of the language, and should be avoided if possible.
832    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("walk_pat",
                                    "rustc_hir_typeck::expr_use_visitor",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/expr_use_visitor.rs"),
                                    ::tracing_core::__macro_support::Option::Some(832u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::expr_use_visitor"),
                                    ::tracing_core::field::FieldSet::new(&["discr_place", "pat",
                                                    "has_guard"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&discr_place)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&pat)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&has_guard as
                                                            &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

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