Skip to main content

rustc_borrowck/diagnostics/
explain_borrow.rs

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