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::{BlameConstraint, 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 {
                category: __self_0,
                from_closure: __self_1,
                span: __self_2,
                region_name: __self_3,
                opt_place_desc: __self_4,
                path: __self_5 } => {
                let names: &'static _ =
                    &["category", "from_closure", "span", "region_name",
                                "opt_place_desc", "path"];
                let values: &[&dyn ::core::fmt::Debug] =
                    &[__self_0, __self_1, __self_2, __self_3, __self_4,
                                &__self_5];
                ::core::fmt::Formatter::debug_struct_fields_finish(f,
                    "MustBeValidFor", names, values)
            }
            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        category: ConstraintCategory<'tcx>,
39        from_closure: bool,
40        span: Span,
41        region_name: RegionName,
42        opt_place_desc: Option<String>,
43        path: Vec<OutlivesConstraint<'tcx>>,
44    },
45    Unexplained,
46}
47
48#[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)]
49pub(crate) enum LaterUseKind {
50    TraitCapture,
51    ClosureCapture,
52    Call,
53    FakeLetRead,
54    Other,
55}
56
57impl<'tcx> BorrowExplanation<'tcx> {
58    pub(crate) fn is_explained(&self) -> bool {
59        !#[allow(non_exhaustive_omitted_patterns)] match self {
    BorrowExplanation::Unexplained => true,
    _ => false,
}matches!(self, BorrowExplanation::Unexplained)
60    }
61    pub(crate) fn add_explanation_to_diagnostic<G: EmissionGuarantee>(
62        &self,
63        cx: &MirBorrowckCtxt<'_, '_, 'tcx>,
64        err: &mut Diag<'_, G>,
65        borrow_desc: &str,
66        borrow_span: Option<Span>,
67        multiple_borrow_span: Option<(Span, Span)>,
68    ) {
69        let tcx = cx.infcx.tcx;
70        let body = cx.body;
71
72        if let Some(span) = borrow_span {
73            let def_id = body.source.def_id();
74            if let Some(node) = tcx.hir_get_if_local(def_id)
75                && let Some(body_id) = node.body_id()
76            {
77                let body = tcx.hir_body(body_id);
78                let mut expr_finder = FindExprBySpan::new(span, tcx);
79                expr_finder.visit_expr(body.value);
80                if let Some(mut expr) = expr_finder.result {
81                    while let hir::ExprKind::AddrOf(_, _, inner)
82                    | hir::ExprKind::Unary(hir::UnOp::Deref, inner)
83                    | hir::ExprKind::Field(inner, _)
84                    | hir::ExprKind::MethodCall(_, inner, _, _)
85                    | hir::ExprKind::Index(inner, _, _) = &expr.kind
86                    {
87                        expr = inner;
88                    }
89                    if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind
90                        && let [hir::PathSegment { ident, args: None, .. }] = p.segments
91                        && let hir::def::Res::Local(hir_id) = p.res
92                        && let hir::Node::Pat(pat) = tcx.hir_node(hir_id)
93                    {
94                        if !ident.span.in_external_macro(tcx.sess.source_map()) {
95                            err.span_label(pat.span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("binding `{0}` declared here",
                ident))
    })format!("binding `{ident}` declared here"));
96                        }
97                    }
98                }
99            }
100        }
101        match *self {
102            BorrowExplanation::UsedLater(
103                dropped_local,
104                later_use_kind,
105                var_or_use_span,
106                path_span,
107            ) => {
108                let message = match later_use_kind {
109                    LaterUseKind::TraitCapture => "captured here by trait object",
110                    LaterUseKind::ClosureCapture => "captured here by closure",
111                    LaterUseKind::Call => "used by call",
112                    LaterUseKind::FakeLetRead => "stored here",
113                    LaterUseKind::Other => "used here",
114                };
115                let local_decl = &body.local_decls[dropped_local];
116
117                if let &LocalInfo::IfThenRescopeTemp { if_then } = local_decl.local_info()
118                    && let Some((_, hir::Node::Expr(expr))) = tcx.hir_parent_iter(if_then).next()
119                    && let hir::ExprKind::If(cond, conseq, alt) = expr.kind
120                    && let hir::ExprKind::Let(&hir::LetExpr {
121                        span: _,
122                        pat,
123                        init,
124                        // FIXME(#101728): enable rewrite when type ascription is stabilized again
125                        ty: None,
126                        recovered: _,
127                    }) = cond.kind
128                    && pat.span.can_be_used_for_suggestions()
129                    && let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
130                {
131                    suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
132                } else if path_span.is_none_or(|path_span| path_span == var_or_use_span) {
133                    // We can use `var_or_use_span` if either `path_span` is not present, or both
134                    // spans are the same.
135                    if borrow_span.is_none_or(|sp| !sp.overlaps(var_or_use_span)) {
136                        err.span_label(
137                            var_or_use_span,
138                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}borrow later {1}", borrow_desc,
                message))
    })format!("{borrow_desc}borrow later {message}"),
139                        );
140                    }
141                } else {
142                    // path_span must be `Some` as otherwise the if condition is true
143                    let path_span = path_span.unwrap();
144                    // path_span is only present in the case of closure capture
145                    {
    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);
146                    if !borrow_span.is_some_and(|sp| sp.overlaps(var_or_use_span)) {
147                        let path_label = "used here by closure";
148                        let capture_kind_label = message;
149                        err.span_label(
150                            var_or_use_span,
151                            ::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}"),
152                        );
153                        err.span_label(path_span, path_label);
154                    }
155                }
156            }
157            BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span, path_span) => {
158                let message = match later_use_kind {
159                    LaterUseKind::TraitCapture => {
160                        "borrow captured here by trait object, in later iteration of loop"
161                    }
162                    LaterUseKind::ClosureCapture => {
163                        "borrow captured here by closure, in later iteration of loop"
164                    }
165                    LaterUseKind::Call => "borrow used by call, in later iteration of loop",
166                    LaterUseKind::FakeLetRead => "borrow later stored here",
167                    LaterUseKind::Other => "borrow used here, in later iteration of loop",
168                };
169                // We can use `var_or_use_span` if either `path_span` is not present, or both spans
170                // are the same.
171                if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) {
172                    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}"));
173                } else {
174                    // path_span must be `Some` as otherwise the if condition is true
175                    let path_span = path_span.unwrap();
176                    // path_span is only present in the case of closure capture
177                    {
    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);
178                    if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) {
179                        let path_label = "used here by closure";
180                        let capture_kind_label = message;
181                        err.span_label(
182                            var_or_use_span,
183                            ::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}"),
184                        );
185                        err.span_label(path_span, path_label);
186                    }
187                }
188            }
189            BorrowExplanation::UsedLaterWhenDropped {
190                drop_loc,
191                dropped_local,
192                should_note_order,
193            } => {
194                let local_decl = &body.local_decls[dropped_local];
195                let mut ty = local_decl.ty;
196                if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
197                    if let ty::Adt(adt, args) = local_decl.ty.kind() {
198                        if tcx.is_diagnostic_item(sym::Option, adt.did()) {
199                            // in for loop desugaring, only look at the `Some(..)` inner type
200                            ty = args.type_at(0);
201                        }
202                    }
203                }
204                let (dtor_desc, type_desc) = match ty.kind() {
205                    // If type is an ADT that implements Drop, then
206                    // simplify output by reporting just the ADT name.
207                    ty::Adt(adt, _args) if adt.has_dtor(tcx) && !adt.is_box() => {
208                        ("`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())))
209                    }
210
211                    // Otherwise, just report the whole type (and use
212                    // the intentionally fuzzy phrase "destructor")
213                    ty::Closure(..) => ("destructor", "closure".to_owned()),
214                    ty::Coroutine(..) => ("destructor", "coroutine".to_owned()),
215
216                    _ => ("destructor", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("type `{0}`", local_decl.ty))
    })format!("type `{}`", local_decl.ty)),
217                };
218
219                match cx.local_name(dropped_local) {
220                    Some(local_name) if !local_decl.from_compiler_desugaring() => {
221                        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!(
222                            "{borrow_desc}borrow might be used here, when `{local_name}` is dropped \
223                             and runs the {dtor_desc} for {type_desc}",
224                        );
225                        err.span_label(body.source_info(drop_loc).span, message);
226
227                        if should_note_order {
228                            err.note(
229                                "values in a scope are dropped \
230                                 in the opposite order they are defined",
231                            );
232                        }
233                    }
234                    _ => {
235                        err.span_label(
236                            local_decl.source_info.span,
237                            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("a temporary with access to the {0}borrow is created here ...",
                borrow_desc))
    })format!(
238                                "a temporary with access to the {borrow_desc}borrow \
239                                 is created here ...",
240                            ),
241                        );
242                        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!(
243                            "... and the {borrow_desc}borrow might be used here, \
244                             when that temporary is dropped \
245                             and runs the {dtor_desc} for {type_desc}",
246                        );
247                        err.span_label(body.source_info(drop_loc).span, message);
248
249                        struct FindLetExpr<'hir> {
250                            span: Span,
251                            result: Option<(Span, &'hir hir::Pat<'hir>, &'hir hir::Expr<'hir>)>,
252                            tcx: TyCtxt<'hir>,
253                        }
254
255                        impl<'hir> rustc_hir::intravisit::Visitor<'hir> for FindLetExpr<'hir> {
256                            type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;
257                            fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
258                                self.tcx
259                            }
260                            fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
261                                if let hir::ExprKind::If(cond, _conseq, _alt)
262                                | hir::ExprKind::Loop(
263                                    &hir::Block {
264                                        expr:
265                                            Some(&hir::Expr {
266                                                kind: hir::ExprKind::If(cond, _conseq, _alt),
267                                                ..
268                                            }),
269                                        ..
270                                    },
271                                    _,
272                                    hir::LoopSource::While,
273                                    _,
274                                ) = expr.kind
275                                    && let hir::ExprKind::Let(hir::LetExpr {
276                                        init: let_expr_init,
277                                        span: let_expr_span,
278                                        pat: let_expr_pat,
279                                        ..
280                                    }) = cond.kind
281                                    && let_expr_init.span.contains(self.span)
282                                {
283                                    self.result =
284                                        Some((*let_expr_span, let_expr_pat, let_expr_init))
285                                } else {
286                                    hir::intravisit::walk_expr(self, expr);
287                                }
288                            }
289                        }
290
291                        if let &LocalInfo::IfThenRescopeTemp { if_then } = local_decl.local_info()
292                            && let hir::Node::Expr(expr) = tcx.hir_node(if_then)
293                            && let hir::ExprKind::If(cond, conseq, alt) = expr.kind
294                            && let hir::ExprKind::Let(&hir::LetExpr {
295                                span: _,
296                                pat,
297                                init,
298                                // FIXME(#101728): enable rewrite when type ascription is
299                                // stabilized again.
300                                ty: None,
301                                recovered: _,
302                            }) = cond.kind
303                            && pat.span.can_be_used_for_suggestions()
304                            && let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
305                        {
306                            suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
307                        } else if let Some((old, new)) = multiple_borrow_span
308                            && let def_id = body.source.def_id()
309                            && let Some(node) = tcx.hir_get_if_local(def_id)
310                            && let Some(body_id) = node.body_id()
311                            && let hir_body = tcx.hir_body(body_id)
312                            && let mut expr_finder = (FindLetExpr { span: old, result: None, tcx })
313                            && let Some((let_expr_span, let_expr_pat, let_expr_init)) = {
314                                expr_finder.visit_expr(hir_body.value);
315                                expr_finder.result
316                            }
317                            && !let_expr_span.contains(new)
318                        {
319                            // #133941: The `old` expression is at the conditional part of an
320                            // if/while let expression. Adding a semicolon won't work.
321                            // Instead, try suggesting the `matches!` macro or a temporary.
322                            if let_expr_pat
323                                .walk_short(|pat| !#[allow(non_exhaustive_omitted_patterns)] match pat.kind {
    hir::PatKind::Binding(..) => true,
    _ => false,
}matches!(pat.kind, hir::PatKind::Binding(..)))
324                            {
325                                if let Ok(pat_snippet) =
326                                    tcx.sess.source_map().span_to_snippet(let_expr_pat.span)
327                                    && let Ok(init_snippet) =
328                                        tcx.sess.source_map().span_to_snippet(let_expr_init.span)
329                                {
330                                    err.span_suggestion_verbose(
331                                        let_expr_span,
332                                        "consider using the `matches!` macro",
333                                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("matches!({0}, {1})", init_snippet,
                pat_snippet))
    })format!("matches!({init_snippet}, {pat_snippet})"),
334                                        Applicability::MaybeIncorrect,
335                                    );
336                                } else {
337                                    err.note("consider using the `matches!` macro");
338                                }
339                            }
340                        } else if let LocalInfo::BlockTailTemp(info) = local_decl.local_info() {
341                            let sp = info.span.find_ancestor_not_from_macro().unwrap_or(info.span);
342                            if info.tail_result_is_ignored {
343                                // #85581: If the first mutable borrow's scope contains
344                                // the second borrow, this suggestion isn't helpful.
345                                if !multiple_borrow_span.is_some_and(|(old, new)| {
346                                    old.to(info.span.shrink_to_hi()).contains(new)
347                                }) {
348                                    err.span_suggestion_verbose(
349                                        sp.shrink_to_hi(),
350                                        "consider adding semicolon after the expression so its \
351                                        temporaries are dropped sooner, before the local variables \
352                                        declared by the block are dropped",
353                                        ";",
354                                        Applicability::MaybeIncorrect,
355                                    );
356                                }
357                            } else {
358                                err.note(
359                                    "the temporary is part of an expression at the end of a \
360                                     block;\nconsider forcing this temporary to be dropped sooner, \
361                                     before the block's local variables are dropped",
362                                );
363                                err.multipart_suggestion(
364                                    "for example, you could save the expression's value in a new \
365                                     local variable `x` and then make `x` be the expression at the \
366                                     end of the block",
367                                    ::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![
368                                        (sp.shrink_to_lo(), "let x = ".to_string()),
369                                        (sp.shrink_to_hi(), "; x".to_string()),
370                                    ],
371                                    Applicability::MaybeIncorrect,
372                                );
373                            };
374                        }
375                    }
376                }
377            }
378            BorrowExplanation::MustBeValidFor {
379                category,
380                span,
381                ref region_name,
382                ref opt_place_desc,
383                from_closure: _,
384                ref path,
385            } => {
386                region_name.highlight_region_name(err);
387
388                if let Some(desc) = opt_place_desc {
389                    err.span_label(
390                        span,
391                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}requires that `{1}` is borrowed for `{2}`",
                category.description(), desc, region_name))
    })format!(
392                            "{}requires that `{desc}` is borrowed for `{region_name}`",
393                            category.description(),
394                        ),
395                    );
396                } else {
397                    err.span_label(
398                        span,
399                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}requires that {1}borrow lasts for `{2}`",
                category.description(), borrow_desc, region_name))
    })format!(
400                            "{}requires that {borrow_desc}borrow lasts for `{region_name}`",
401                            category.description(),
402                        ),
403                    );
404                };
405
406                cx.add_placeholder_from_predicate_note(err, &path);
407                cx.add_sized_or_copy_bound_info(err, category, &path);
408
409                if let ConstraintCategory::Cast {
410                    is_raw_ptr_dyn_type_cast: _,
411                    is_implicit_coercion: true,
412                    unsize_to: Some(unsize_ty),
413                } = category
414                {
415                    self.add_object_lifetime_default_note(tcx, err, unsize_ty);
416                }
417
418                let mut preds = path
419                    .iter()
420                    .filter_map(|constraint| match constraint.category {
421                        ConstraintCategory::Predicate(pred) if !pred.is_dummy() => Some(pred),
422                        _ => None,
423                    })
424                    .collect::<Vec<Span>>();
425                preds.sort();
426                preds.dedup();
427                if !preds.is_empty() {
428                    let s = if preds.len() == 1 { "" } else { "s" };
429                    err.span_note(
430                        preds,
431                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("requirement{0} that the value outlives `{1}` introduced here",
                s, region_name))
    })format!(
432                            "requirement{s} that the value outlives `{region_name}` introduced here"
433                        ),
434                    );
435                }
436
437                self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name);
438            }
439            _ => {}
440        }
441    }
442
443    fn add_object_lifetime_default_note<G: EmissionGuarantee>(
444        &self,
445        tcx: TyCtxt<'tcx>,
446        err: &mut Diag<'_, G>,
447        unsize_ty: Ty<'tcx>,
448    ) {
449        if let ty::Adt(def, args) = unsize_ty.kind() {
450            // We try to elaborate the object lifetime defaults and present those to the user. This
451            // should make it clear where the region constraint is coming from.
452            let generics = tcx.generics_of(def.did());
453
454            let mut has_dyn = false;
455            let mut failed = false;
456
457            let elaborated_args =
458                std::iter::zip(*args, &generics.own_params).map(|(arg, param)| {
459                    if let Some(ty::Dynamic(obj, _)) = arg.as_type().map(Ty::kind) {
460                        let default = tcx.object_lifetime_default(param.def_id);
461
462                        let re_static = tcx.lifetimes.re_static;
463
464                        let implied_region = match default {
465                            // This is not entirely precise.
466                            ObjectLifetimeDefault::Empty => re_static,
467                            ObjectLifetimeDefault::Ambiguous => {
468                                failed = true;
469                                re_static
470                            }
471                            ObjectLifetimeDefault::Param(param_def_id) => {
472                                let index = generics.param_def_id_to_index[&param_def_id] as usize;
473                                args.get(index).and_then(|arg| arg.as_region()).unwrap_or_else(
474                                    || {
475                                        failed = true;
476                                        re_static
477                                    },
478                                )
479                            }
480                            ObjectLifetimeDefault::Static => re_static,
481                        };
482
483                        has_dyn = true;
484
485                        Ty::new_dynamic(tcx, obj, implied_region).into()
486                    } else {
487                        arg
488                    }
489                });
490            let elaborated_ty = Ty::new_adt(tcx, *def, tcx.mk_args_from_iter(elaborated_args));
491
492            if has_dyn && !failed {
493                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!(
494                    "due to object lifetime defaults, `{unsize_ty}` actually means `{elaborated_ty}`"
495                ));
496            }
497        }
498    }
499
500    fn add_lifetime_bound_suggestion_to_diagnostic<G: EmissionGuarantee>(
501        &self,
502        err: &mut Diag<'_, G>,
503        category: &ConstraintCategory<'tcx>,
504        span: Span,
505        region_name: &RegionName,
506    ) {
507        if !span.is_desugaring(DesugaringKind::OpaqueTy) {
508            return;
509        }
510        if let ConstraintCategory::OpaqueType = category {
511            let suggestable_name =
512                if region_name.was_named() { region_name.name } else { kw::UnderscoreLifetime };
513
514            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!(
515                "you can add a bound to the {}to make it last less than `'static` and match `{region_name}`",
516                category.description(),
517            );
518
519            err.span_suggestion_verbose(
520                span.shrink_to_hi(),
521                msg,
522                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" + {0}", suggestable_name))
    })format!(" + {suggestable_name}"),
523                Applicability::Unspecified,
524            );
525        }
526    }
527}
528
529fn suggest_rewrite_if_let<G: EmissionGuarantee>(
530    tcx: TyCtxt<'_>,
531    expr: &hir::Expr<'_>,
532    pat: &str,
533    init: &hir::Expr<'_>,
534    conseq: &hir::Expr<'_>,
535    alt: Option<&hir::Expr<'_>>,
536    err: &mut Diag<'_, G>,
537) {
538    let source_map = tcx.sess.source_map();
539    err.span_note(
540        source_map.end_point(conseq.span),
541        "lifetimes for temporaries generated in `if let`s have been shortened in Edition 2024 so that they are dropped here instead",
542    );
543    if expr.span.can_be_used_for_suggestions() && conseq.span.can_be_used_for_suggestions() {
544        let needs_block = if let Some(hir::Node::Expr(expr)) =
545            alt.and_then(|alt| tcx.hir_parent_iter(alt.hir_id).next()).map(|(_, node)| node)
546        {
547            #[allow(non_exhaustive_omitted_patterns)] match expr.kind {
    hir::ExprKind::If(..) => true,
    _ => false,
}matches!(expr.kind, hir::ExprKind::If(..))
548        } else {
549            false
550        };
551        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![
552            (
553                expr.span.shrink_to_lo().between(init.span),
554                if needs_block { "{ match ".into() } else { "match ".into() },
555            ),
556            (conseq.span.shrink_to_lo(), format!(" {{ {pat} => ")),
557        ];
558        let expr_end = expr.span.shrink_to_hi();
559        let mut expr_end_code;
560        if let Some(alt) = alt {
561            sugg.push((conseq.span.between(alt.span), " _ => ".into()));
562            expr_end_code = "}".to_string();
563        } else {
564            expr_end_code = " _ => {} }".into();
565        }
566        expr_end_code.push('}');
567        sugg.push((expr_end, expr_end_code));
568        err.multipart_suggestion(
569            "consider rewriting the `if` into `match` which preserves the extended lifetime",
570            sugg,
571            Applicability::MaybeIncorrect,
572        );
573    }
574}
575
576impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
577    /// Returns structured explanation for *why* the borrow contains the
578    /// point from `location`. This is key for the "3-point errors"
579    /// [described in the NLL RFC][d].
580    ///
581    /// # Parameters
582    ///
583    /// - `borrow`: the borrow in question
584    /// - `location`: where the borrow occurs
585    /// - `kind_place`: if Some, this describes the statement that triggered the error.
586    ///   - first half is the kind of write, if any, being performed
587    ///   - second half is the place being accessed
588    ///
589    /// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
590    #[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(590u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                                    ::tracing_core::field::FieldSet::new(&["location", "borrow",
                                                    "kind_place"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&location)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&borrow)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&kind_place)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: 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: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(&["borrow_region_vid"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&borrow_region_vid)
                                                        as &dyn 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:605",
                                    "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(605u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                                    ::tracing_core::field::FieldSet::new(&["region_sub"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&region_sub)
                                                        as &dyn 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:621",
                                            "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(621u32),
                                            ::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};
                                    let mut iter = __CALLSITE.metadata().fields().iter();
                                    __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                        ::tracing::__macro_support::Option::Some(&format_args!("explain_why_borrow_contains_point: region_sub in loop={0:?}",
                                                                        region_sub) as &dyn 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 (blame_constraint, path) =
                            self.regioncx.best_blame_constraint(borrow_region_vid,
                                NllRegionVariableOrigin::FreeRegion, region);
                        let BlameConstraint { category, from_closure, span, .. } =
                            blame_constraint;
                        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 {
                                category,
                                from_closure,
                                span,
                                region_name,
                                opt_place_desc,
                                path,
                            }
                        } 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:710",
                                                    "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(710u32),
                                                    ::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};
                                            let mut iter = __CALLSITE.metadata().fields().iter();
                                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                                ::tracing::__macro_support::Option::Some(&format_args!("Could not generate a region name")
                                                                        as &dyn 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:714",
                                                "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(714u32),
                                                ::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};
                                        let mut iter = __CALLSITE.metadata().fields().iter();
                                        __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                            ::tracing::__macro_support::Option::Some(&format_args!("Could not generate an error region vid")
                                                                    as &dyn Value))])
                                    });
                            } else { ; }
                        };
                        BorrowExplanation::Unexplained
                    }
                }
            }
        }
    }
}#[instrument(level = "debug", skip(self))]
591    pub(crate) fn explain_why_borrow_contains_point(
592        &self,
593        location: Location,
594        borrow: &BorrowData<'tcx>,
595        kind_place: Option<(WriteKind, Place<'tcx>)>,
596    ) -> BorrowExplanation<'tcx> {
597        let regioncx = &self.regioncx;
598        let body: &Body<'_> = self.body;
599        let tcx = self.infcx.tcx;
600
601        let borrow_region_vid = borrow.region;
602        debug!(?borrow_region_vid);
603
604        let mut region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location);
605        debug!(?region_sub);
606
607        let mut use_location = location;
608        let mut use_in_later_iteration_of_loop = false;
609
610        if region_sub == borrow_region_vid {
611            // When `region_sub` is the same as `borrow_region_vid` (the location where the borrow
612            // is issued is the same location that invalidates the reference), this is likely a
613            // loop iteration. In this case, try using the loop terminator location in
614            // `find_sub_region_live_at`.
615            if let Some(loop_terminator_location) =
616                regioncx.find_loop_terminator_location(borrow.region, body)
617            {
618                region_sub = self
619                    .regioncx
620                    .find_sub_region_live_at(borrow_region_vid, loop_terminator_location);
621                debug!("explain_why_borrow_contains_point: region_sub in loop={:?}", region_sub);
622                use_location = loop_terminator_location;
623                use_in_later_iteration_of_loop = true;
624            }
625        }
626
627        // NLL doesn't consider boring locals for liveness, and wouldn't encounter a
628        // `Cause::LiveVar` for such a local. Polonius can't avoid computing liveness for boring
629        // locals yet, and will encounter them when trying to explain why a borrow contains a given
630        // point.
631        //
632        // We want to focus on relevant live locals in diagnostics, so when polonius is enabled, we
633        // ensure that we don't emit live boring locals as explanations.
634        let is_local_boring = |local| {
635            if let Some(polonius_context) = self.polonius_context {
636                polonius_context.boring_nll_locals.contains(&local)
637            } else {
638                assert!(!tcx.sess.opts.unstable_opts.polonius.is_next_enabled());
639
640                // Boring locals are never the cause of a borrow explanation in NLLs.
641                false
642            }
643        };
644        match find_use::find(body, regioncx, tcx, region_sub, use_location) {
645            Some(Cause::LiveVar(local, location)) if !is_local_boring(local) => {
646                let span = body.source_info(location).span;
647                let spans = self
648                    .move_spans(Place::from(local).as_ref(), location)
649                    .or_else(|| self.borrow_spans(span, location));
650
651                if use_in_later_iteration_of_loop {
652                    let (later_use_kind, var_or_use_span, path_span) =
653                        self.later_use_kind(borrow, spans, use_location);
654                    BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span, path_span)
655                } else {
656                    // Check if the location represents a `FakeRead`, and adapt the error
657                    // message to the `FakeReadCause` it is from: in particular,
658                    // the ones inserted in optimized `let var = <expr>` patterns.
659                    let (later_use_kind, var_or_use_span, path_span) =
660                        self.later_use_kind(borrow, spans, location);
661                    BorrowExplanation::UsedLater(
662                        borrow.borrowed_place.local,
663                        later_use_kind,
664                        var_or_use_span,
665                        path_span,
666                    )
667                }
668            }
669
670            Some(Cause::DropVar(local, location)) if !is_local_boring(local) => {
671                let mut should_note_order = false;
672                if self.local_name(local).is_some()
673                    && let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place
674                    && let Some(borrowed_local) = place.as_local()
675                    && self.local_name(borrowed_local).is_some()
676                    && local != borrowed_local
677                {
678                    should_note_order = true;
679                }
680
681                BorrowExplanation::UsedLaterWhenDropped {
682                    drop_loc: location,
683                    dropped_local: local,
684                    should_note_order,
685                }
686            }
687
688            Some(Cause::LiveVar(..) | Cause::DropVar(..)) | None => {
689                // Here, under NLL: no cause was found. Under polonius: no cause was found, or a
690                // boring local was found, which we ignore like NLLs do to match its diagnostics.
691                if let Some(region) = self.regioncx.to_error_region_vid(borrow_region_vid) {
692                    let (blame_constraint, path) = self.regioncx.best_blame_constraint(
693                        borrow_region_vid,
694                        NllRegionVariableOrigin::FreeRegion,
695                        region,
696                    );
697                    let BlameConstraint { category, from_closure, span, .. } = blame_constraint;
698
699                    if let Some(region_name) = self.give_region_a_name(region) {
700                        let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref());
701                        BorrowExplanation::MustBeValidFor {
702                            category,
703                            from_closure,
704                            span,
705                            region_name,
706                            opt_place_desc,
707                            path,
708                        }
709                    } else {
710                        debug!("Could not generate a region name");
711                        BorrowExplanation::Unexplained
712                    }
713                } else {
714                    debug!("Could not generate an error region vid");
715                    BorrowExplanation::Unexplained
716                }
717            }
718        }
719    }
720
721    /// Determine how the borrow was later used.
722    /// First span returned points to the location of the conflicting use
723    /// Second span if `Some` is returned in the case of closures and points
724    /// to the use of the path
725    #[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(725u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::explain_borrow"),
                                    ::tracing_core::field::FieldSet::new(&["borrow",
                                                    "use_spans", "location"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&borrow)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&use_spans)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&location)
                                                            as &dyn Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return:
                    (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))]
726    fn later_use_kind(
727        &self,
728        borrow: &BorrowData<'tcx>,
729        use_spans: UseSpans<'tcx>,
730        location: Location,
731    ) -> (LaterUseKind, Span, Option<Span>) {
732        match use_spans {
733            UseSpans::ClosureUse { capture_kind_span, path_span, .. } => {
734                // Used in a closure.
735                (LaterUseKind::ClosureCapture, capture_kind_span, Some(path_span))
736            }
737            // In the case that the borrowed value (probably a temporary)
738            // overlaps with the method's receiver, then point at the method.
739            UseSpans::FnSelfUse {
740                var_span: span,
741                kind: CallKind::Normal { desugaring: None, .. },
742                ..
743            } if span
744                .overlaps(self.body.local_decls[borrow.assigned_place.local].source_info.span) =>
745            {
746                if let TerminatorKind::Call { func, call_source: CallSource::Normal, .. } =
747                    &self.body.basic_blocks[location.block].terminator().kind
748                {
749                    // Just point to the function, to reduce the chance of overlapping spans.
750                    let function_span = match func {
751                        Operand::RuntimeChecks(_) => span,
752                        Operand::Constant(c) => c.span,
753                        Operand::Copy(place) | Operand::Move(place) => {
754                            if let Some(l) = place.as_local() {
755                                let local_decl = &self.body.local_decls[l];
756                                if self.local_name(l).is_none() {
757                                    local_decl.source_info.span
758                                } else {
759                                    span
760                                }
761                            } else {
762                                span
763                            }
764                        }
765                    };
766                    (LaterUseKind::Call, function_span, None)
767                } else {
768                    (LaterUseKind::Other, span, None)
769                }
770            }
771            UseSpans::PatUse(span)
772            | UseSpans::OtherUse(span)
773            | UseSpans::FnSelfUse { var_span: span, .. } => {
774                let block = &self.body.basic_blocks[location.block];
775
776                let kind = if let Some(&Statement {
777                    kind: StatementKind::FakeRead((FakeReadCause::ForLet(_), place)),
778                    ..
779                }) = block.statements.get(location.statement_index)
780                {
781                    if let Some(l) = place.as_local()
782                        && let local_decl = &self.body.local_decls[l]
783                        && local_decl.ty.is_closure()
784                    {
785                        LaterUseKind::ClosureCapture
786                    } else {
787                        LaterUseKind::FakeLetRead
788                    }
789                } else if self.was_captured_by_trait_object(borrow) {
790                    LaterUseKind::TraitCapture
791                } else if location.statement_index == block.statements.len() {
792                    if let TerminatorKind::Call { func, call_source: CallSource::Normal, .. } =
793                        &block.terminator().kind
794                    {
795                        // Just point to the function, to reduce the chance of overlapping spans.
796                        let function_span = match func {
797                            Operand::RuntimeChecks(_) => span,
798                            Operand::Constant(c) => c.span,
799                            Operand::Copy(place) | Operand::Move(place) => {
800                                if let Some(l) = place.as_local() {
801                                    let local_decl = &self.body.local_decls[l];
802                                    if self.local_name(l).is_none() {
803                                        local_decl.source_info.span
804                                    } else {
805                                        span
806                                    }
807                                } else {
808                                    span
809                                }
810                            }
811                        };
812                        return (LaterUseKind::Call, function_span, None);
813                    } else {
814                        LaterUseKind::Other
815                    }
816                } else {
817                    LaterUseKind::Other
818                };
819
820                (kind, span, None)
821            }
822        }
823    }
824
825    /// Checks if a borrowed value was captured by a trait object. We do this by
826    /// looking forward in the MIR from the reserve location and checking if we see
827    /// an unsized cast to a trait object on our data.
828    fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool {
829        // Start at the reserve location, find the place that we want to see cast to a trait object.
830        let location = borrow.reserve_location;
831        let block = &self.body[location.block];
832        let stmt = block.statements.get(location.statement_index);
833        {
    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:833",
                        "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(833u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait_object: location={0:?} stmt={1:?}",
                                                    location, stmt) as &dyn Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait_object: location={:?} stmt={:?}", location, stmt);
834
835        // We make a `queue` vector that has the locations we want to visit. As of writing, this
836        // will only ever have one item at any given time, but by using a vector, we can pop from
837        // it which simplifies the termination logic.
838        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];
839        let Some(Statement { kind: StatementKind::Assign((place, _)), .. }) = stmt else {
840            return false;
841        };
842        let Some(mut target) = place.as_local() else { return false };
843
844        {
    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:844",
                        "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(844u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait: target={0:?} queue={1:?}",
                                                    target, queue) as &dyn Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait: target={:?} queue={:?}", target, queue);
845        while let Some(current_location) = queue.pop() {
846            {
    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:846",
                        "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(846u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait: target={0:?}",
                                                    target) as &dyn Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait: target={:?}", target);
847            let block = &self.body[current_location.block];
848            // We need to check the current location to find out if it is a terminator.
849            let is_terminator = current_location.statement_index == block.statements.len();
850            if !is_terminator {
851                let stmt = &block.statements[current_location.statement_index];
852                {
    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:852",
                        "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(852u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait_object: stmt={0:?}",
                                                    stmt) as &dyn Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait_object: stmt={:?}", stmt);
853
854                // The only kind of statement that we care about is assignments...
855                if let StatementKind::Assign((place, rvalue)) = &stmt.kind {
856                    let Some(into) = place.local_or_deref_local() else {
857                        // Continue at the next location.
858                        queue.push(current_location.successor_within_block());
859                        continue;
860                    };
861
862                    match rvalue {
863                        // If we see a use, we should check whether it is our data, and if so
864                        // update the place that we're looking for to that new place.
865                        Rvalue::Use(operand, _) => match operand {
866                            Operand::Copy(place) | Operand::Move(place) => {
867                                if let Some(from) = place.as_local() {
868                                    if from == target {
869                                        target = into;
870                                    }
871                                }
872                            }
873                            _ => {}
874                        },
875                        // If we see an unsized cast, then if it is our data we should check
876                        // whether it is being cast to a trait object.
877                        Rvalue::Cast(
878                            CastKind::PointerCoercion(PointerCoercion::Unsize, _),
879                            operand,
880                            ty,
881                        ) => {
882                            match operand {
883                                Operand::Copy(place) | Operand::Move(place) => {
884                                    if let Some(from) = place.as_local() {
885                                        if from == target {
886                                            {
    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:886",
                        "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(886u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait_object: ty={0:?}",
                                                    ty) as &dyn Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait_object: ty={:?}", ty);
887                                            // Check the type for a trait object.
888                                            return match ty.kind() {
889                                                // `&dyn Trait`
890                                                ty::Ref(_, ty, _) if ty.is_trait() => true,
891                                                // `Box<dyn Trait>`
892                                                _ if ty.boxed_ty().is_some_and(Ty::is_trait) => {
893                                                    true
894                                                }
895
896                                                // `dyn Trait`
897                                                _ if ty.is_trait() => true,
898                                                // Anything else.
899                                                _ => false,
900                                            };
901                                        }
902                                    }
903                                    return false;
904                                }
905                                _ => return false,
906                            }
907                        }
908                        _ => {}
909                    }
910                }
911
912                // Continue at the next location.
913                queue.push(current_location.successor_within_block());
914            } else {
915                // The only thing we need to do for terminators is progress to the next block.
916                let terminator = block.terminator();
917                {
    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:917",
                        "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(917u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait_object: terminator={0:?}",
                                                    terminator) as &dyn Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait_object: terminator={:?}", terminator);
918
919                if let TerminatorKind::Call { destination, target: Some(block), args, .. } =
920                    &terminator.kind
921                    && let Some(dest) = destination.as_local()
922                {
923                    {
    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:923",
                        "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(923u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait_object: target={0:?} dest={1:?} args={2:?}",
                                                    target, dest, args) as &dyn Value))])
            });
    } else { ; }
};debug!(
924                        "was_captured_by_trait_object: target={:?} dest={:?} args={:?}",
925                        target, dest, args
926                    );
927                    // Check if one of the arguments to this function is the target place.
928                    let found_target = args.iter().any(|arg| {
929                        if let Operand::Move(place) = arg.node {
930                            if let Some(potential) = place.as_local() {
931                                potential == target
932                            } else {
933                                false
934                            }
935                        } else {
936                            false
937                        }
938                    });
939
940                    // If it is, follow this to the next block and update the target.
941                    if found_target {
942                        target = dest;
943                        queue.push(block.start_location());
944                    }
945                }
946            }
947
948            {
    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:948",
                        "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(948u32),
                        ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("was_captured_by_trait: queue={0:?}",
                                                    queue) as &dyn Value))])
            });
    } else { ; }
};debug!("was_captured_by_trait: queue={:?}", queue);
949        }
950
951        // We didn't find anything and ran out of locations to check.
952        false
953    }
954}