Skip to main content

rustc_borrowck/diagnostics/
explain_borrow.rs

1//! Print diagnostics to explain why values are borrowed.
2
3use std::assert_matches;
4
5use rustc_errors::{Applicability, Diag, EmissionGuarantee};
6use rustc_hir as hir;
7use rustc_hir::intravisit::Visitor;
8use rustc_infer::infer::NllRegionVariableOrigin;
9use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
10use rustc_middle::mir::{
11    Body, CallSource, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location,
12    Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind,
13};
14use rustc_middle::ty::adjustment::PointerCoercion;
15use rustc_middle::ty::{self, Ty, TyCtxt};
16use rustc_span::{DesugaringKind, Span, kw, sym};
17use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
18use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
19use tracing::{debug, instrument};
20
21use super::{RegionName, UseSpans, find_use};
22use crate::borrow_set::BorrowData;
23use crate::constraints::OutlivesConstraint;
24use crate::nll::ConstraintDescription;
25use crate::region_infer::{BestBlame, Cause};
26use crate::{MirBorrowckCtxt, WriteKind};
27
28#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for BorrowExplanation<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            BorrowExplanation::UsedLater(__self_0, __self_1, __self_2,
                __self_3) =>
                ::core::fmt::Formatter::debug_tuple_field4_finish(f,
                    "UsedLater", __self_0, __self_1, __self_2, &__self_3),
            BorrowExplanation::UsedLaterInLoop(__self_0, __self_1, __self_2)
                =>
                ::core::fmt::Formatter::debug_tuple_field3_finish(f,
                    "UsedLaterInLoop", __self_0, __self_1, &__self_2),
            BorrowExplanation::UsedLaterWhenDropped {
                drop_loc: __self_0,
                dropped_local: __self_1,
                should_note_order: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "UsedLaterWhenDropped", "drop_loc", __self_0,
                    "dropped_local", __self_1, "should_note_order", &__self_2),
            BorrowExplanation::MustBeValidFor {
                best_blame: __self_0,
                region_name: __self_1,
                opt_place_desc: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "MustBeValidFor", "best_blame", __self_0, "region_name",
                    __self_1, "opt_place_desc", &__self_2),
            BorrowExplanation::Unexplained =>
                ::core::fmt::Formatter::write_str(f, "Unexplained"),
        }
    }
}Debug)]
29pub(crate) enum BorrowExplanation<'tcx> {
30    UsedLater(Local, LaterUseKind, Span, Option<Span>),
31    UsedLaterInLoop(LaterUseKind, Span, Option<Span>),
32    UsedLaterWhenDropped {
33        drop_loc: Location,
34        dropped_local: Local,
35        should_note_order: bool,
36    },
37    MustBeValidFor {
38        best_blame: BestBlame<'tcx>,
39        region_name: RegionName,
40        opt_place_desc: Option<String>,
41    },
42    Unexplained,
43}
44
45#[derive(#[automatically_derived]
impl ::core::clone::Clone for LaterUseKind {
    #[inline]
    fn clone(&self) -> LaterUseKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for LaterUseKind { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for LaterUseKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                LaterUseKind::TraitCapture => "TraitCapture",
                LaterUseKind::ClosureCapture => "ClosureCapture",
                LaterUseKind::Call => "Call",
                LaterUseKind::FakeLetRead => "FakeLetRead",
                LaterUseKind::Other => "Other",
            })
    }
}Debug)]
46pub(crate) enum LaterUseKind {
47    TraitCapture,
48    ClosureCapture,
49    Call,
50    FakeLetRead,
51    Other,
52}
53
54impl<'tcx> BorrowExplanation<'tcx> {
55    pub(crate) fn is_explained(&self) -> bool {
56        !#[allow(non_exhaustive_omitted_patterns)] match self {
    BorrowExplanation::Unexplained => true,
    _ => false,
}matches!(self, BorrowExplanation::Unexplained)
57    }
58    pub(crate) fn add_explanation_to_diagnostic<G: EmissionGuarantee>(
59        &self,
60        cx: &MirBorrowckCtxt<'_, '_, 'tcx>,
61        err: &mut Diag<'_, G>,
62        borrow_desc: &str,
63        borrow_span: Option<Span>,
64        multiple_borrow_span: Option<(Span, Span)>,
65    ) {
66        let tcx = cx.infcx.tcx;
67        let body = cx.body;
68
69        if let Some(span) = borrow_span {
70            let def_id = body.source.def_id();
71            if let Some(node) = tcx.hir_get_if_local(def_id)
72                && let Some(body_id) = node.body_id()
73            {
74                let body = tcx.hir_body(body_id);
75                let mut expr_finder = FindExprBySpan::new(span, tcx);
76                expr_finder.visit_expr(body.value);
77                if let Some(mut expr) = expr_finder.result {
78                    while let hir::ExprKind::AddrOf(_, _, inner)
79                    | hir::ExprKind::Unary(hir::UnOp::Deref, inner)
80                    | hir::ExprKind::Field(inner, _)
81                    | hir::ExprKind::MethodCall(_, inner, _, _)
82                    | hir::ExprKind::Index(inner, _, _) = &expr.kind
83                    {
84                        expr = inner;
85                    }
86                    if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind
87                        && let [hir::PathSegment { ident, args: None, .. }] = p.segments
88                        && let hir::def::Res::Local(hir_id) = p.res
89                        && let hir::Node::Pat(pat) = tcx.hir_node(hir_id)
90                    {
91                        if !ident.span.in_external_macro(tcx.sess.source_map()) {
92                            err.span_label(pat.span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("binding `{0}` declared here",
                ident))
    })format!("binding `{ident}` declared here"));
93                        }
94                    }
95                }
96            }
97        }
98        match *self {
99            BorrowExplanation::UsedLater(
100                dropped_local,
101                later_use_kind,
102                var_or_use_span,
103                path_span,
104            ) => {
105                let message = match later_use_kind {
106                    LaterUseKind::TraitCapture => "captured here by trait object",
107                    LaterUseKind::ClosureCapture => "captured here by closure",
108                    LaterUseKind::Call => "used by call",
109                    LaterUseKind::FakeLetRead => "stored here",
110                    LaterUseKind::Other => "used here",
111                };
112                let local_decl = &body.local_decls[dropped_local];
113
114                if let &LocalInfo::IfThenRescopeTemp { if_then } = local_decl.local_info()
115                    && let Some((_, hir::Node::Expr(expr))) = tcx.hir_parent_iter(if_then).next()
116                    && let hir::ExprKind::If(cond, conseq, alt) = expr.kind
117                    && let hir::ExprKind::Let(&hir::LetExpr {
118                        span: _,
119                        pat,
120                        init,
121                        // FIXME(#101728): enable rewrite when type ascription is stabilized again
122                        ty: None,
123                        recovered: _,
124                    }) = cond.kind
125                    && pat.span.can_be_used_for_suggestions()
126                    && let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
127                {
128                    suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
129                } else if path_span.is_none_or(|path_span| path_span == var_or_use_span) {
130                    // We can use `var_or_use_span` if either `path_span` is not present, or both
131                    // spans are the same.
132                    if borrow_span.is_none_or(|sp| !sp.overlaps(var_or_use_span)) {
133                        err.span_label(
134                            var_or_use_span,
135                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}borrow later {1}", borrow_desc,
                message))
    })format!("{borrow_desc}borrow later {message}"),
136                        );
137                    }
138                } else {
139                    // path_span must be `Some` as otherwise the if condition is true
140                    let path_span = path_span.unwrap();
141                    // path_span is only present in the case of closure capture
142                    {
    match later_use_kind {
        LaterUseKind::ClosureCapture => {}
        ref left_val => {
            ::core::panicking::assert_matches_failed(left_val,
                "LaterUseKind::ClosureCapture", ::core::option::Option::None);
        }
    }
};assert_matches!(later_use_kind, LaterUseKind::ClosureCapture);
143                    if !borrow_span.is_some_and(|sp| sp.overlaps(var_or_use_span)) {
144                        let path_label = "used here by closure";
145                        let capture_kind_label = message;
146                        err.span_label(
147                            var_or_use_span,
148                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}borrow later {1}", borrow_desc,
                capture_kind_label))
    })format!("{borrow_desc}borrow later {capture_kind_label}"),
149                        );
150                        err.span_label(path_span, path_label);
151                    }
152                }
153            }
154            BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span, path_span) => {
155                let message = match later_use_kind {
156                    LaterUseKind::TraitCapture => {
157                        "borrow captured here by trait object, in later iteration of loop"
158                    }
159                    LaterUseKind::ClosureCapture => {
160                        "borrow captured here by closure, in later iteration of loop"
161                    }
162                    LaterUseKind::Call => "borrow used by call, in later iteration of loop",
163                    LaterUseKind::FakeLetRead => "borrow later stored here",
164                    LaterUseKind::Other => "borrow used here, in later iteration of loop",
165                };
166                // We can use `var_or_use_span` if either `path_span` is not present, or both spans
167                // are the same.
168                if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) {
169                    err.span_label(var_or_use_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}", borrow_desc, message))
    })format!("{borrow_desc}{message}"));
170                } else {
171                    // path_span must be `Some` as otherwise the if condition is true
172                    let path_span = path_span.unwrap();
173                    // path_span is only present in the case of closure capture
174                    {
    match later_use_kind {
        LaterUseKind::ClosureCapture => {}
        ref left_val => {
            ::core::panicking::assert_matches_failed(left_val,
                "LaterUseKind::ClosureCapture", ::core::option::Option::None);
        }
    }
};assert_matches!(later_use_kind, LaterUseKind::ClosureCapture);
175                    if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) {
176                        let path_label = "used here by closure";
177                        let capture_kind_label = message;
178                        err.span_label(
179                            var_or_use_span,
180                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}borrow later {1}", borrow_desc,
                capture_kind_label))
    })format!("{borrow_desc}borrow later {capture_kind_label}"),
181                        );
182                        err.span_label(path_span, path_label);
183                    }
184                }
185            }
186            BorrowExplanation::UsedLaterWhenDropped {
187                drop_loc,
188                dropped_local,
189                should_note_order,
190            } => {
191                let local_decl = &body.local_decls[dropped_local];
192                let mut ty = local_decl.ty;
193                if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
194                    if let ty::Adt(adt, args) = local_decl.ty.kind() {
195                        if tcx.is_diagnostic_item(sym::Option, adt.did()) {
196                            // in for loop desugaring, only look at the `Some(..)` inner type
197                            ty = args.type_at(0);
198                        }
199                    }
200                }
201                let (dtor_desc, type_desc) = match ty.kind() {
202                    // If type is an ADT that implements Drop, then
203                    // simplify output by reporting just the ADT name.
204                    ty::Adt(adt, _args) if adt.has_dtor(tcx) && !adt.is_box() => {
205                        ("`Drop` code", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("type `{0}`",
                tcx.def_path_str(adt.did())))
    })format!("type `{}`", tcx.def_path_str(adt.did())))
206                    }
207
208                    // Otherwise, just report the whole type (and use
209                    // the intentionally fuzzy phrase "destructor")
210                    ty::Closure(..) => ("destructor", "closure".to_owned()),
211                    ty::Coroutine(..) => ("destructor", "coroutine".to_owned()),
212
213                    _ => ("destructor", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("type `{0}`", local_decl.ty))
    })format!("type `{}`", local_decl.ty)),
214                };
215
216                match cx.local_name(dropped_local) {
217                    Some(local_name) if !local_decl.from_compiler_desugaring() => {
218                        let message = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}borrow might be used here, when `{1}` is dropped and runs the {2} for {3}",
                borrow_desc, local_name, dtor_desc, type_desc))
    })format!(
219                            "{borrow_desc}borrow might be used here, when `{local_name}` is dropped \
220                             and runs the {dtor_desc} for {type_desc}",
221                        );
222                        err.span_label(body.source_info(drop_loc).span, message);
223
224                        if should_note_order {
225                            err.note(
226                                "values in a scope are dropped \
227                                 in the opposite order they are defined",
228                            );
229                        }
230                    }
231                    _ => {
232                        err.span_label(
233                            local_decl.source_info.span,
234                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("a temporary with access to the {0}borrow is created here ...",
                borrow_desc))
    })format!(
235                                "a temporary with access to the {borrow_desc}borrow \
236                                 is created here ...",
237                            ),
238                        );
239                        let message = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("... and the {0}borrow might be used here, when that temporary is dropped and runs the {1} for {2}",
                borrow_desc, dtor_desc, type_desc))
    })format!(
240                            "... and the {borrow_desc}borrow might be used here, \
241                             when that temporary is dropped \
242                             and runs the {dtor_desc} for {type_desc}",
243                        );
244                        err.span_label(body.source_info(drop_loc).span, message);
245
246                        struct FindLetExpr<'hir> {
247                            span: Span,
248                            result: Option<(Span, &'hir hir::Pat<'hir>, &'hir hir::Expr<'hir>)>,
249                            tcx: TyCtxt<'hir>,
250                        }
251
252                        impl<'hir> rustc_hir::intravisit::Visitor<'hir> for FindLetExpr<'hir> {
253                            type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;
254                            fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
255                                self.tcx
256                            }
257                            fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
258                                if let hir::ExprKind::If(cond, _conseq, _alt)
259                                | hir::ExprKind::Loop(
260                                    &hir::Block {
261                                        expr:
262                                            Some(&hir::Expr {
263                                                kind: hir::ExprKind::If(cond, _conseq, _alt),
264                                                ..
265                                            }),
266                                        ..
267                                    },
268                                    _,
269                                    hir::LoopSource::While,
270                                    _,
271                                ) = expr.kind
272                                    && let hir::ExprKind::Let(hir::LetExpr {
273                                        init: let_expr_init,
274                                        span: let_expr_span,
275                                        pat: let_expr_pat,
276                                        ..
277                                    }) = cond.kind
278                                    && let_expr_init.span.contains(self.span)
279                                {
280                                    self.result =
281                                        Some((*let_expr_span, let_expr_pat, let_expr_init))
282                                } else {
283                                    hir::intravisit::walk_expr(self, expr);
284                                }
285                            }
286                        }
287
288                        if let &LocalInfo::IfThenRescopeTemp { if_then } = local_decl.local_info()
289                            && let hir::Node::Expr(expr) = tcx.hir_node(if_then)
290                            && let hir::ExprKind::If(cond, conseq, alt) = expr.kind
291                            && let hir::ExprKind::Let(&hir::LetExpr {
292                                span: _,
293                                pat,
294                                init,
295                                // FIXME(#101728): enable rewrite when type ascription is
296                                // stabilized again.
297                                ty: None,
298                                recovered: _,
299                            }) = cond.kind
300                            && pat.span.can_be_used_for_suggestions()
301                            && let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
302                        {
303                            suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
304                        } else if let Some((old, new)) = multiple_borrow_span
305                            && let def_id = body.source.def_id()
306                            && let Some(node) = tcx.hir_get_if_local(def_id)
307                            && let Some(body_id) = node.body_id()
308                            && let hir_body = tcx.hir_body(body_id)
309                            && let mut expr_finder = (FindLetExpr { span: old, result: None, tcx })
310                            && let Some((let_expr_span, let_expr_pat, let_expr_init)) = {
311                                expr_finder.visit_expr(hir_body.value);
312                                expr_finder.result
313                            }
314                            && !let_expr_span.contains(new)
315                        {
316                            // #133941: The `old` expression is at the conditional part of an
317                            // if/while let expression. Adding a semicolon won't work.
318                            // Instead, try suggesting the `matches!` macro or a temporary.
319                            if let_expr_pat
320                                .walk_short(|pat| !#[allow(non_exhaustive_omitted_patterns)] match pat.kind {
    hir::PatKind::Binding(..) => true,
    _ => false,
}matches!(pat.kind, hir::PatKind::Binding(..)))
321                            {
322                                if let Ok(pat_snippet) =
323                                    tcx.sess.source_map().span_to_snippet(let_expr_pat.span)
324                                    && let Ok(init_snippet) =
325                                        tcx.sess.source_map().span_to_snippet(let_expr_init.span)
326                                {
327                                    err.span_suggestion_verbose(
328                                        let_expr_span,
329                                        "consider using the `matches!` macro",
330                                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("matches!({0}, {1})", init_snippet,
                pat_snippet))
    })format!("matches!({init_snippet}, {pat_snippet})"),
331                                        Applicability::MaybeIncorrect,
332                                    );
333                                } else {
334                                    err.note("consider using the `matches!` macro");
335                                }
336                            }
337                        } else if let LocalInfo::BlockTailTemp(info) = local_decl.local_info() {
338                            let sp = info.span.find_ancestor_not_from_macro().unwrap_or(info.span);
339                            if info.tail_result_is_ignored {
340                                // #85581: If the first mutable borrow's scope contains
341                                // the second borrow, this suggestion isn't helpful.
342                                if !multiple_borrow_span.is_some_and(|(old, new)| {
343                                    old.to(info.span.shrink_to_hi()).contains(new)
344                                }) {
345                                    err.span_suggestion_verbose(
346                                        sp.shrink_to_hi(),
347                                        "consider adding semicolon after the expression so its \
348                                        temporaries are dropped sooner, before the local variables \
349                                        declared by the block are dropped",
350                                        ";",
351                                        Applicability::MaybeIncorrect,
352                                    );
353                                }
354                            } else {
355                                err.note(
356                                    "the temporary is part of an expression at the end of a \
357                                     block;\nconsider forcing this temporary to be dropped sooner, \
358                                     before the block's local variables are dropped",
359                                );
360                                err.multipart_suggestion(
361                                    "for example, you could save the expression's value in a new \
362                                     local variable `x` and then make `x` be the expression at the \
363                                     end of the block",
364                                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(sp.shrink_to_lo(), "let x = ".to_string()),
                (sp.shrink_to_hi(), "; x".to_string())]))vec![
365                                        (sp.shrink_to_lo(), "let x = ".to_string()),
366                                        (sp.shrink_to_hi(), "; x".to_string()),
367                                    ],
368                                    Applicability::MaybeIncorrect,
369                                );
370                            };
371                        }
372                    }
373                }
374            }
375            BorrowExplanation::MustBeValidFor {
376                ref best_blame,
377                ref region_name,
378                ref opt_place_desc,
379            } => {
380                let OutlivesConstraint { category, span, .. } = *best_blame.constraint();
381                let path = best_blame.path();
382
383                region_name.highlight_region_name(err);
384
385                if let Some(desc) = opt_place_desc {
386                    err.span_label(
387                        span,
388                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}requires that `{1}` is borrowed for `{2}`",
                category.description(), desc, region_name))
    })format!(
389                            "{}requires that `{desc}` is borrowed for `{region_name}`",
390                            category.description(),
391                        ),
392                    );
393                } else {
394                    err.span_label(
395                        span,
396                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}requires that {1}borrow lasts for `{2}`",
                category.description(), borrow_desc, region_name))
    })format!(
397                            "{}requires that {borrow_desc}borrow lasts for `{region_name}`",
398                            category.description(),
399                        ),
400                    );
401                };
402
403                cx.add_placeholder_from_predicate_note(err, path);
404                cx.add_sized_or_copy_bound_info(err, category, path);
405
406                if let ConstraintCategory::Cast {
407                    is_raw_ptr_dyn_type_cast: _,
408                    is_implicit_coercion: true,
409                    unsize_to: Some(unsize_ty),
410                } = category
411                {
412                    self.add_object_lifetime_default_note(tcx, err, unsize_ty);
413                }
414
415                let mut preds = path
416                    .iter()
417                    .filter_map(|constraint| match constraint.category {
418                        ConstraintCategory::Predicate(pred) if !pred.is_dummy() => Some(pred),
419                        _ => None,
420                    })
421                    .collect::<Vec<Span>>();
422                preds.sort();
423                preds.dedup();
424                if !preds.is_empty() {
425                    let s = if preds.len() == 1 { "" } else { "s" };
426                    err.span_note(
427                        preds,
428                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("requirement{0} that the value outlives `{1}` introduced here",
                s, region_name))
    })format!(
429                            "requirement{s} that the value outlives `{region_name}` introduced here"
430                        ),
431                    );
432                }
433
434                self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name);
435            }
436            _ => {}
437        }
438    }
439
440    fn add_object_lifetime_default_note<G: EmissionGuarantee>(
441        &self,
442        tcx: TyCtxt<'tcx>,
443        err: &mut Diag<'_, G>,
444        unsize_ty: Ty<'tcx>,
445    ) {
446        if let ty::Adt(def, args) = unsize_ty.kind() {
447            // We try to elaborate the object lifetime defaults and present those to the user. This
448            // should make it clear where the region constraint is coming from.
449            let generics = tcx.generics_of(def.did());
450
451            let mut has_dyn = false;
452            let mut failed = false;
453
454            let elaborated_args =
455                std::iter::zip(*args, &generics.own_params).map(|(arg, param)| {
456                    if let Some(ty::Dynamic(obj, _)) = arg.as_type().map(Ty::kind) {
457                        let default = tcx.object_lifetime_default(param.def_id);
458
459                        let re_static = tcx.lifetimes.re_static;
460
461                        let implied_region = match default {
462                            // This is not entirely precise.
463                            ObjectLifetimeDefault::Empty => re_static,
464                            ObjectLifetimeDefault::Ambiguous => {
465                                failed = true;
466                                re_static
467                            }
468                            ObjectLifetimeDefault::Param(param_def_id) => {
469                                let index = generics.param_def_id_to_index[&param_def_id] as usize;
470                                args.get(index).and_then(|arg| arg.as_region()).unwrap_or_else(
471                                    || {
472                                        failed = true;
473                                        re_static
474                                    },
475                                )
476                            }
477                            ObjectLifetimeDefault::Static => re_static,
478                        };
479
480                        has_dyn = true;
481
482                        Ty::new_dynamic(tcx, obj, implied_region).into()
483                    } else {
484                        arg
485                    }
486                });
487            let elaborated_ty = Ty::new_adt(tcx, *def, tcx.mk_args_from_iter(elaborated_args));
488
489            if has_dyn && !failed {
490                err.note(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("due to object lifetime defaults, `{0}` actually means `{1}`",
                unsize_ty, elaborated_ty))
    })format!(
491                    "due to object lifetime defaults, `{unsize_ty}` actually means `{elaborated_ty}`"
492                ));
493            }
494        }
495    }
496
497    fn add_lifetime_bound_suggestion_to_diagnostic<G: EmissionGuarantee>(
498        &self,
499        err: &mut Diag<'_, G>,
500        category: &ConstraintCategory<'tcx>,
501        span: Span,
502        region_name: &RegionName,
503    ) {
504        if !span.is_desugaring(DesugaringKind::OpaqueTy) {
505            return;
506        }
507        if let ConstraintCategory::OpaqueType = category {
508            let suggestable_name =
509                if region_name.was_named() { region_name.name } else { kw::UnderscoreLifetime };
510
511            let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("you can add a bound to the {0}to make it last less than `\'static` and match `{1}`",
                category.description(), region_name))
    })format!(
512                "you can add a bound to the {}to make it last less than `'static` and match `{region_name}`",
513                category.description(),
514            );
515
516            err.span_suggestion_verbose(
517                span.shrink_to_hi(),
518                msg,
519                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" + {0}", suggestable_name))
    })format!(" + {suggestable_name}"),
520                Applicability::Unspecified,
521            );
522        }
523    }
524}
525
526fn suggest_rewrite_if_let<G: EmissionGuarantee>(
527    tcx: TyCtxt<'_>,
528    expr: &hir::Expr<'_>,
529    pat: &str,
530    init: &hir::Expr<'_>,
531    conseq: &hir::Expr<'_>,
532    alt: Option<&hir::Expr<'_>>,
533    err: &mut Diag<'_, G>,
534) {
535    let source_map = tcx.sess.source_map();
536    err.span_note(
537        source_map.end_point(conseq.span),
538        "lifetimes for temporaries generated in `if let`s have been shortened in Edition 2024 so that they are dropped here instead",
539    );
540    if expr.span.can_be_used_for_suggestions() && conseq.span.can_be_used_for_suggestions() {
541        let needs_block = if let Some(hir::Node::Expr(expr)) =
542            alt.and_then(|alt| tcx.hir_parent_iter(alt.hir_id).next()).map(|(_, node)| node)
543        {
544            #[allow(non_exhaustive_omitted_patterns)] match expr.kind {
    hir::ExprKind::If(..) => true,
    _ => false,
}matches!(expr.kind, hir::ExprKind::If(..))
545        } else {
546            false
547        };
548        let mut sugg = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(expr.span.shrink_to_lo().between(init.span),
                    if needs_block {
                        "{ match ".into()
                    } else { "match ".into() }),
                (conseq.span.shrink_to_lo(),
                    ::alloc::__export::must_use({
                            ::alloc::fmt::format(format_args!(" {{ {0} => ", pat))
                        }))]))vec![
549            (
550                expr.span.shrink_to_lo().between(init.span),
551                if needs_block { "{ match ".into() } else { "match ".into() },
552            ),
553            (conseq.span.shrink_to_lo(), format!(" {{ {pat} => ")),
554        ];
555        let expr_end = expr.span.shrink_to_hi();
556        let mut expr_end_code;
557        if let Some(alt) = alt {
558            sugg.push((conseq.span.between(alt.span), " _ => ".into()));
559            expr_end_code = "}".to_string();
560        } else {
561            expr_end_code = " _ => {} }".into();
562        }
563        expr_end_code.push('}');
564        sugg.push((expr_end, expr_end_code));
565        err.multipart_suggestion(
566            "consider rewriting the `if` into `match` which preserves the extended lifetime",
567            sugg,
568            Applicability::MaybeIncorrect,
569        );
570    }
571}
572
573impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
574    /// Returns structured explanation for *why* the borrow contains the
575    /// point from `location`. This is key for the "3-point errors"
576    /// [described in the NLL RFC][d].
577    ///
578    /// # Parameters
579    ///
580    /// - `borrow`: the borrow in question
581    /// - `location`: where the borrow occurs
582    /// - `kind_place`: if Some, this describes the statement that triggered the error.
583    ///   - first half is the kind of write, if any, being performed
584    ///   - second half is the place being accessed
585    ///
586    /// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
587    #[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("explain_why_borrow_contains_point",
                                    "rustc_borrowck::diagnostics::explain_borrow",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                                    ::tracing_core::__macro_support::Option::Some(587u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("location")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("location");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("borrow")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("borrow");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("kind_place")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("kind_place");
                                                        NAME.as_str()
                                                    }], ::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};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&location)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&borrow)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&kind_place)
                                                            as &dyn ::tracing::field::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: BorrowExplanation<'tcx> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let regioncx = &self.regioncx;
            let body: &Body<'_> = self.body;
            let tcx = self.infcx.tcx;
            let borrow_region_vid = borrow.region;
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:599",
                                    "rustc_borrowck::diagnostics::explain_borrow",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                                    ::tracing_core::__macro_support::Option::Some(599u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("borrow_region_vid")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("borrow_region_vid");
                                                        NAME.as_str()
                                                    }], ::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};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&borrow_region_vid)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let mut region_sub =
                self.regioncx.find_sub_region_live_at(borrow_region_vid,
                    location);
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:602",
                                    "rustc_borrowck::diagnostics::explain_borrow",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                                    ::tracing_core::__macro_support::Option::Some(602u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("region_sub")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("region_sub");
                                                        NAME.as_str()
                                                    }], ::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};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&region_sub)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let mut use_location = location;
            let mut use_in_later_iteration_of_loop = false;
            if region_sub == borrow_region_vid {
                if let Some(loop_terminator_location) =
                        regioncx.find_loop_terminator_location(borrow.region, body)
                    {
                    region_sub =
                        self.regioncx.find_sub_region_live_at(borrow_region_vid,
                            loop_terminator_location);
                    {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:618",
                                            "rustc_borrowck::diagnostics::explain_borrow",
                                            ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                                            ::tracing_core::__macro_support::Option::Some(618u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                                            ::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};
                                    __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("explain_why_borrow_contains_point: region_sub in loop={0:?}",
                                                                        region_sub) as &dyn ::tracing::field::Value))])
                                });
                        } else { ; }
                    };
                    use_location = loop_terminator_location;
                    use_in_later_iteration_of_loop = true;
                }
            }
            let is_local_boring =
                |local|
                    {
                        if let Some(polonius_context) = self.polonius_context {
                            polonius_context.boring_nll_locals.contains(&local)
                        } else {
                            if !!tcx.sess.opts.unstable_opts.polonius.is_next_enabled()
                                {
                                ::core::panicking::panic("assertion failed: !tcx.sess.opts.unstable_opts.polonius.is_next_enabled()")
                            };
                            false
                        }
                    };
            match find_use::find(body, regioncx, tcx, region_sub,
                    use_location) {
                Some(Cause::LiveVar(local, location)) if
                    !is_local_boring(local) => {
                    let span = body.source_info(location).span;
                    let spans =
                        self.move_spans(Place::from(local).as_ref(),
                                location).or_else(|| self.borrow_spans(span, location));
                    if use_in_later_iteration_of_loop {
                        let (later_use_kind, var_or_use_span, path_span) =
                            self.later_use_kind(borrow, spans, use_location);
                        BorrowExplanation::UsedLaterInLoop(later_use_kind,
                            var_or_use_span, path_span)
                    } else {
                        let (later_use_kind, var_or_use_span, path_span) =
                            self.later_use_kind(borrow, spans, location);
                        BorrowExplanation::UsedLater(borrow.borrowed_place.local,
                            later_use_kind, var_or_use_span, path_span)
                    }
                }
                Some(Cause::DropVar(local, location)) if
                    !is_local_boring(local) => {
                    let mut should_note_order = false;
                    if self.local_name(local).is_some() &&
                                        let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place
                                    && let Some(borrowed_local) = place.as_local() &&
                                self.local_name(borrowed_local).is_some() &&
                            local != borrowed_local {
                        should_note_order = true;
                    }
                    BorrowExplanation::UsedLaterWhenDropped {
                        drop_loc: location,
                        dropped_local: local,
                        should_note_order,
                    }
                }
                Some(Cause::LiveVar(..) | Cause::DropVar(..)) | None => {
                    if let Some(region) =
                            self.regioncx.to_error_region_vid(borrow_region_vid) {
                        let best_blame =
                            self.regioncx.best_blame_constraint(borrow_region_vid,
                                NllRegionVariableOrigin::FreeRegion, region);
                        if let Some(region_name) = self.give_region_a_name(region) {
                            let opt_place_desc =
                                self.describe_place(borrow.borrowed_place.as_ref());
                            BorrowExplanation::MustBeValidFor {
                                best_blame,
                                region_name,
                                opt_place_desc,
                            }
                        } else {
                            {
                                use ::tracing::__macro_support::Callsite as _;
                                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                    {
                                        static META: ::tracing::Metadata<'static> =
                                            {
                                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:703",
                                                    "rustc_borrowck::diagnostics::explain_borrow",
                                                    ::tracing::Level::DEBUG,
                                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                                                    ::tracing_core::__macro_support::Option::Some(703u32),
                                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                                                    ::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};
                                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("Could not generate a region name")
                                                                        as &dyn ::tracing::field::Value))])
                                        });
                                } else { ; }
                            };
                            BorrowExplanation::Unexplained
                        }
                    } else {
                        {
                            use ::tracing::__macro_support::Callsite as _;
                            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                {
                                    static META: ::tracing::Metadata<'static> =
                                        {
                                            ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:707",
                                                "rustc_borrowck::diagnostics::explain_borrow",
                                                ::tracing::Level::DEBUG,
                                                ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                                                ::tracing_core::__macro_support::Option::Some(707u32),
                                                ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                                                ::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};
                                        __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("Could not generate an error region vid")
                                                                    as &dyn ::tracing::field::Value))])
                                    });
                            } else { ; }
                        };
                        BorrowExplanation::Unexplained
                    }
                }
            }
        }
    }
}#[instrument(level = "debug", skip(self))]
588    pub(crate) fn explain_why_borrow_contains_point(
589        &self,
590        location: Location,
591        borrow: &BorrowData<'tcx>,
592        kind_place: Option<(WriteKind, Place<'tcx>)>,
593    ) -> BorrowExplanation<'tcx> {
594        let regioncx = &self.regioncx;
595        let body: &Body<'_> = self.body;
596        let tcx = self.infcx.tcx;
597
598        let borrow_region_vid = borrow.region;
599        debug!(?borrow_region_vid);
600
601        let mut region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location);
602        debug!(?region_sub);
603
604        let mut use_location = location;
605        let mut use_in_later_iteration_of_loop = false;
606
607        if region_sub == borrow_region_vid {
608            // When `region_sub` is the same as `borrow_region_vid` (the location where the borrow
609            // is issued is the same location that invalidates the reference), this is likely a
610            // loop iteration. In this case, try using the loop terminator location in
611            // `find_sub_region_live_at`.
612            if let Some(loop_terminator_location) =
613                regioncx.find_loop_terminator_location(borrow.region, body)
614            {
615                region_sub = self
616                    .regioncx
617                    .find_sub_region_live_at(borrow_region_vid, loop_terminator_location);
618                debug!("explain_why_borrow_contains_point: region_sub in loop={:?}", region_sub);
619                use_location = loop_terminator_location;
620                use_in_later_iteration_of_loop = true;
621            }
622        }
623
624        // NLL doesn't consider boring locals for liveness, and wouldn't encounter a
625        // `Cause::LiveVar` for such a local. Polonius can't avoid computing liveness for boring
626        // locals yet, and will encounter them when trying to explain why a borrow contains a given
627        // point.
628        //
629        // We want to focus on relevant live locals in diagnostics, so when polonius is enabled, we
630        // ensure that we don't emit live boring locals as explanations.
631        let is_local_boring = |local| {
632            if let Some(polonius_context) = self.polonius_context {
633                polonius_context.boring_nll_locals.contains(&local)
634            } else {
635                assert!(!tcx.sess.opts.unstable_opts.polonius.is_next_enabled());
636
637                // Boring locals are never the cause of a borrow explanation in NLLs.
638                false
639            }
640        };
641        match find_use::find(body, regioncx, tcx, region_sub, use_location) {
642            Some(Cause::LiveVar(local, location)) if !is_local_boring(local) => {
643                let span = body.source_info(location).span;
644                let spans = self
645                    .move_spans(Place::from(local).as_ref(), location)
646                    .or_else(|| self.borrow_spans(span, location));
647
648                if use_in_later_iteration_of_loop {
649                    let (later_use_kind, var_or_use_span, path_span) =
650                        self.later_use_kind(borrow, spans, use_location);
651                    BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span, path_span)
652                } else {
653                    // Check if the location represents a `FakeRead`, and adapt the error
654                    // message to the `FakeReadCause` it is from: in particular,
655                    // the ones inserted in optimized `let var = <expr>` patterns.
656                    let (later_use_kind, var_or_use_span, path_span) =
657                        self.later_use_kind(borrow, spans, location);
658                    BorrowExplanation::UsedLater(
659                        borrow.borrowed_place.local,
660                        later_use_kind,
661                        var_or_use_span,
662                        path_span,
663                    )
664                }
665            }
666
667            Some(Cause::DropVar(local, location)) if !is_local_boring(local) => {
668                let mut should_note_order = false;
669                if self.local_name(local).is_some()
670                    && let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place
671                    && let Some(borrowed_local) = place.as_local()
672                    && self.local_name(borrowed_local).is_some()
673                    && local != borrowed_local
674                {
675                    should_note_order = true;
676                }
677
678                BorrowExplanation::UsedLaterWhenDropped {
679                    drop_loc: location,
680                    dropped_local: local,
681                    should_note_order,
682                }
683            }
684
685            Some(Cause::LiveVar(..) | Cause::DropVar(..)) | None => {
686                // Here, under NLL: no cause was found. Under polonius: no cause was found, or a
687                // boring local was found, which we ignore like NLLs do to match its diagnostics.
688                if let Some(region) = self.regioncx.to_error_region_vid(borrow_region_vid) {
689                    let best_blame = self.regioncx.best_blame_constraint(
690                        borrow_region_vid,
691                        NllRegionVariableOrigin::FreeRegion,
692                        region,
693                    );
694
695                    if let Some(region_name) = self.give_region_a_name(region) {
696                        let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref());
697                        BorrowExplanation::MustBeValidFor {
698                            best_blame,
699                            region_name,
700                            opt_place_desc,
701                        }
702                    } else {
703                        debug!("Could not generate a region name");
704                        BorrowExplanation::Unexplained
705                    }
706                } else {
707                    debug!("Could not generate an error region vid");
708                    BorrowExplanation::Unexplained
709                }
710            }
711        }
712    }
713
714    /// Determine how the borrow was later used.
715    /// First span returned points to the location of the conflicting use
716    /// Second span if `Some` is returned in the case of closures and points
717    /// to the use of the path
718    #[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("later_use_kind",
                                    "rustc_borrowck::diagnostics::explain_borrow",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                                    ::tracing_core::__macro_support::Option::Some(718u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("borrow")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("borrow");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("use_spans")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("use_spans");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("location")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("location");
                                                        NAME.as_str()
                                                    }], ::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};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&borrow)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&use_spans)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&location)
                                                            as &dyn ::tracing::field::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:
                    (LaterUseKind, Span, Option<Span>) = loop {};
            return __tracing_attr_fake_return;
        }
        {
            match use_spans {
                UseSpans::ClosureUse { capture_kind_span, path_span, .. } => {
                    (LaterUseKind::ClosureCapture, capture_kind_span,
                        Some(path_span))
                }
                UseSpans::FnSelfUse {
                    var_span: span,
                    kind: CallKind::Normal { desugaring: None, .. }, .. } if
                    span.overlaps(self.body.local_decls[borrow.assigned_place.local].source_info.span)
                    => {
                    if let TerminatorKind::Call {
                            func, call_source: CallSource::Normal, .. } =
                            &self.body.basic_blocks[location.block].terminator().kind {
                        let function_span =
                            match func {
                                Operand::RuntimeChecks(_) => span,
                                Operand::Constant(c) => c.span,
                                Operand::Copy(place) | Operand::Move(place) => {
                                    if let Some(l) = place.as_local() {
                                        let local_decl = &self.body.local_decls[l];
                                        if self.local_name(l).is_none() {
                                            local_decl.source_info.span
                                        } else { span }
                                    } else { span }
                                }
                            };
                        (LaterUseKind::Call, function_span, None)
                    } else { (LaterUseKind::Other, span, None) }
                }
                UseSpans::PatUse(span) | UseSpans::OtherUse(span) |
                    UseSpans::FnSelfUse { var_span: span, .. } => {
                    let block = &self.body.basic_blocks[location.block];
                    let kind =
                        if let Some(&Statement {
                                kind: StatementKind::FakeRead((FakeReadCause::ForLet(_),
                                    place)), .. }) =
                                block.statements.get(location.statement_index) {
                            if let Some(l) = place.as_local() &&
                                        let local_decl = &self.body.local_decls[l] &&
                                    local_decl.ty.is_closure() {
                                LaterUseKind::ClosureCapture
                            } else { LaterUseKind::FakeLetRead }
                        } else if self.was_captured_by_trait_object(borrow) {
                            LaterUseKind::TraitCapture
                        } else if location.statement_index == block.statements.len()
                            {
                            if let TerminatorKind::Call {
                                    func, call_source: CallSource::Normal, .. } =
                                    &block.terminator().kind {
                                let function_span =
                                    match func {
                                        Operand::RuntimeChecks(_) => span,
                                        Operand::Constant(c) => c.span,
                                        Operand::Copy(place) | Operand::Move(place) => {
                                            if let Some(l) = place.as_local() {
                                                let local_decl = &self.body.local_decls[l];
                                                if self.local_name(l).is_none() {
                                                    local_decl.source_info.span
                                                } else { span }
                                            } else { span }
                                        }
                                    };
                                return (LaterUseKind::Call, function_span, None);
                            } else { LaterUseKind::Other }
                        } else { LaterUseKind::Other };
                    (kind, span, None)
                }
            }
        }
    }
}#[instrument(level = "debug", skip(self))]
719    fn later_use_kind(
720        &self,
721        borrow: &BorrowData<'tcx>,
722        use_spans: UseSpans<'tcx>,
723        location: Location,
724    ) -> (LaterUseKind, Span, Option<Span>) {
725        match use_spans {
726            UseSpans::ClosureUse { capture_kind_span, path_span, .. } => {
727                // Used in a closure.
728                (LaterUseKind::ClosureCapture, capture_kind_span, Some(path_span))
729            }
730            // In the case that the borrowed value (probably a temporary)
731            // overlaps with the method's receiver, then point at the method.
732            UseSpans::FnSelfUse {
733                var_span: span,
734                kind: CallKind::Normal { desugaring: None, .. },
735                ..
736            } if span
737                .overlaps(self.body.local_decls[borrow.assigned_place.local].source_info.span) =>
738            {
739                if let TerminatorKind::Call { func, call_source: CallSource::Normal, .. } =
740                    &self.body.basic_blocks[location.block].terminator().kind
741                {
742                    // Just point to the function, to reduce the chance of overlapping spans.
743                    let function_span = match func {
744                        Operand::RuntimeChecks(_) => span,
745                        Operand::Constant(c) => c.span,
746                        Operand::Copy(place) | Operand::Move(place) => {
747                            if let Some(l) = place.as_local() {
748                                let local_decl = &self.body.local_decls[l];
749                                if self.local_name(l).is_none() {
750                                    local_decl.source_info.span
751                                } else {
752                                    span
753                                }
754                            } else {
755                                span
756                            }
757                        }
758                    };
759                    (LaterUseKind::Call, function_span, None)
760                } else {
761                    (LaterUseKind::Other, span, None)
762                }
763            }
764            UseSpans::PatUse(span)
765            | UseSpans::OtherUse(span)
766            | UseSpans::FnSelfUse { var_span: span, .. } => {
767                let block = &self.body.basic_blocks[location.block];
768
769                let kind = if let Some(&Statement {
770                    kind: StatementKind::FakeRead((FakeReadCause::ForLet(_), place)),
771                    ..
772                }) = block.statements.get(location.statement_index)
773                {
774                    if let Some(l) = place.as_local()
775                        && let local_decl = &self.body.local_decls[l]
776                        && local_decl.ty.is_closure()
777                    {
778                        LaterUseKind::ClosureCapture
779                    } else {
780                        LaterUseKind::FakeLetRead
781                    }
782                } else if self.was_captured_by_trait_object(borrow) {
783                    LaterUseKind::TraitCapture
784                } else if location.statement_index == block.statements.len() {
785                    if let TerminatorKind::Call { func, call_source: CallSource::Normal, .. } =
786                        &block.terminator().kind
787                    {
788                        // Just point to the function, to reduce the chance of overlapping spans.
789                        let function_span = match func {
790                            Operand::RuntimeChecks(_) => span,
791                            Operand::Constant(c) => c.span,
792                            Operand::Copy(place) | Operand::Move(place) => {
793                                if let Some(l) = place.as_local() {
794                                    let local_decl = &self.body.local_decls[l];
795                                    if self.local_name(l).is_none() {
796                                        local_decl.source_info.span
797                                    } else {
798                                        span
799                                    }
800                                } else {
801                                    span
802                                }
803                            }
804                        };
805                        return (LaterUseKind::Call, function_span, None);
806                    } else {
807                        LaterUseKind::Other
808                    }
809                } else {
810                    LaterUseKind::Other
811                };
812
813                (kind, span, None)
814            }
815        }
816    }
817
818    /// Checks if a borrowed value was captured by a trait object. We do this by
819    /// looking forward in the MIR from the reserve location and checking if we see
820    /// an unsized cast to a trait object on our data.
821    fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool {
822        // Start at the reserve location, find the place that we want to see cast to a trait object.
823        let location = borrow.reserve_location;
824        let block = &self.body[location.block];
825        let stmt = block.statements.get(location.statement_index);
826        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:826",
                        "rustc_borrowck::diagnostics::explain_borrow",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                        ::tracing_core::__macro_support::Option::Some(826u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait_object: location={0:?} stmt={1:?}",
                                                    location, stmt) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait_object: location={:?} stmt={:?}", location, stmt);
827
828        // We make a `queue` vector that has the locations we want to visit. As of writing, this
829        // will only ever have one item at any given time, but by using a vector, we can pop from
830        // it which simplifies the termination logic.
831        let mut queue = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [location]))vec![location];
832        let Some(Statement { kind: StatementKind::Assign((place, _)), .. }) = stmt else {
833            return false;
834        };
835        let Some(mut target) = place.as_local() else { return false };
836
837        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:837",
                        "rustc_borrowck::diagnostics::explain_borrow",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                        ::tracing_core::__macro_support::Option::Some(837u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait: target={0:?} queue={1:?}",
                                                    target, queue) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait: target={:?} queue={:?}", target, queue);
838        while let Some(current_location) = queue.pop() {
839            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:839",
                        "rustc_borrowck::diagnostics::explain_borrow",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                        ::tracing_core::__macro_support::Option::Some(839u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait: target={0:?}",
                                                    target) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait: target={:?}", target);
840            let block = &self.body[current_location.block];
841            // We need to check the current location to find out if it is a terminator.
842            let is_terminator = current_location.statement_index == block.statements.len();
843            if !is_terminator {
844                let stmt = &block.statements[current_location.statement_index];
845                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:845",
                        "rustc_borrowck::diagnostics::explain_borrow",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                        ::tracing_core::__macro_support::Option::Some(845u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait_object: stmt={0:?}",
                                                    stmt) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait_object: stmt={:?}", stmt);
846
847                // The only kind of statement that we care about is assignments...
848                if let StatementKind::Assign((place, rvalue)) = &stmt.kind {
849                    let Some(into) = place.local_or_deref_local() else {
850                        // Continue at the next location.
851                        queue.push(current_location.successor_within_block());
852                        continue;
853                    };
854
855                    match rvalue {
856                        // If we see a use, we should check whether it is our data, and if so
857                        // update the place that we're looking for to that new place.
858                        Rvalue::Use(operand, _) => match operand {
859                            Operand::Copy(place) | Operand::Move(place) => {
860                                if let Some(from) = place.as_local() {
861                                    if from == target {
862                                        target = into;
863                                    }
864                                }
865                            }
866                            _ => {}
867                        },
868                        // If we see an unsized cast, then if it is our data we should check
869                        // whether it is being cast to a trait object.
870                        Rvalue::Cast(
871                            CastKind::PointerCoercion(PointerCoercion::Unsize, _),
872                            operand,
873                            ty,
874                        ) => {
875                            match operand {
876                                Operand::Copy(place) | Operand::Move(place) => {
877                                    if let Some(from) = place.as_local() {
878                                        if from == target {
879                                            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:879",
                        "rustc_borrowck::diagnostics::explain_borrow",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                        ::tracing_core::__macro_support::Option::Some(879u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait_object: ty={0:?}",
                                                    ty) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait_object: ty={:?}", ty);
880                                            // Check the type for a trait object.
881                                            return match ty.kind() {
882                                                // `&dyn Trait`
883                                                ty::Ref(_, ty, _) if ty.is_trait() => true,
884                                                // `Box<dyn Trait>`
885                                                _ if ty.boxed_ty().is_some_and(Ty::is_trait) => {
886                                                    true
887                                                }
888
889                                                // `dyn Trait`
890                                                _ if ty.is_trait() => true,
891                                                // Anything else.
892                                                _ => false,
893                                            };
894                                        }
895                                    }
896                                    return false;
897                                }
898                                _ => return false,
899                            }
900                        }
901                        _ => {}
902                    }
903                }
904
905                // Continue at the next location.
906                queue.push(current_location.successor_within_block());
907            } else {
908                // The only thing we need to do for terminators is progress to the next block.
909                let terminator = block.terminator();
910                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:910",
                        "rustc_borrowck::diagnostics::explain_borrow",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                        ::tracing_core::__macro_support::Option::Some(910u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait_object: terminator={0:?}",
                                                    terminator) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait_object: terminator={:?}", terminator);
911
912                if let TerminatorKind::Call { destination, target: Some(block), args, .. } =
913                    &terminator.kind
914                    && let Some(dest) = destination.as_local()
915                {
916                    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:916",
                        "rustc_borrowck::diagnostics::explain_borrow",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                        ::tracing_core::__macro_support::Option::Some(916u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait_object: target={0:?} dest={1:?} args={2:?}",
                                                    target, dest, args) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
917                        "was_captured_by_trait_object: target={:?} dest={:?} args={:?}",
918                        target, dest, args
919                    );
920                    // Check if one of the arguments to this function is the target place.
921                    let found_target = args.iter().any(|arg| {
922                        if let Operand::Move(place) = arg.node {
923                            if let Some(potential) = place.as_local() {
924                                potential == target
925                            } else {
926                                false
927                            }
928                        } else {
929                            false
930                        }
931                    });
932
933                    // If it is, follow this to the next block and update the target.
934                    if found_target {
935                        target = dest;
936                        queue.push(block.start_location());
937                    }
938                }
939            }
940
941            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs:941",
                        "rustc_borrowck::diagnostics::explain_borrow",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs"),
                        ::tracing_core::__macro_support::Option::Some(941u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                        ::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};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait: queue={0:?}",
                                                    queue) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait: queue={:?}", queue);
942        }
943
944        // We didn't find anything and ran out of locations to check.
945        false
946    }
947}