Skip to main content

rustc_borrowck/
borrowck_errors.rs

1use rustc_errors::codes::*;
2use rustc_errors::{Applicability, Diag, DiagCtxtHandle, struct_span_code_err};
3use rustc_hir as hir;
4use rustc_middle::span_bug;
5use rustc_middle::ty::{self, Ty, TyCtxt};
6use rustc_span::Span;
7
8impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
9    pub(crate) fn dcx(&self) -> DiagCtxtHandle<'infcx> {
10        self.infcx.dcx()
11    }
12
13    pub(crate) fn cannot_move_when_borrowed(
14        &self,
15        span: Span,
16        borrow_span: Span,
17        place: &str,
18        borrow_place: &str,
19        value_place: &str,
20    ) -> Diag<'infcx> {
21        self.dcx().create_err(crate::session_diagnostics::MoveBorrow {
22            place,
23            span,
24            borrow_place,
25            value_place,
26            borrow_span,
27        })
28    }
29
30    pub(crate) fn cannot_use_when_mutably_borrowed(
31        &self,
32        span: Span,
33        desc: &str,
34        borrow_span: Span,
35        borrow_desc: &str,
36    ) -> Diag<'infcx> {
37        {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot use {0} because it was mutably borrowed",
                            desc))
                })).with_code(E0503)
}struct_span_code_err!(
38            self.dcx(),
39            span,
40            E0503,
41            "cannot use {} because it was mutably borrowed",
42            desc,
43        )
44        .with_span_label(borrow_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} is borrowed here",
                borrow_desc))
    })format!("{borrow_desc} is borrowed here"))
45        .with_span_label(span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("use of borrowed {0}", borrow_desc))
    })format!("use of borrowed {borrow_desc}"))
46    }
47
48    pub(crate) fn cannot_mutably_borrow_multiply(
49        &self,
50        new_loan_span: Span,
51        desc: &str,
52        opt_via: &str,
53        old_loan_span: Span,
54        old_opt_via: &str,
55        old_load_end_span: Option<Span>,
56    ) -> Diag<'infcx> {
57        let via = |msg: &str| if msg.is_empty() { "".to_string() } else { ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" (via {0})", msg))
    })format!(" (via {msg})") };
58        let mut err = {
    self.dcx().struct_span_err(new_loan_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot borrow {0}{1} as mutable more than once at a time",
                            desc, via(opt_via)))
                })).with_code(E0499)
}struct_span_code_err!(
59            self.dcx(),
60            new_loan_span,
61            E0499,
62            "cannot borrow {}{} as mutable more than once at a time",
63            desc,
64            via(opt_via),
65        );
66        if old_loan_span == new_loan_span {
67            // Both borrows are happening in the same place
68            // Meaning the borrow is occurring in a loop
69            err.span_label(
70                new_loan_span,
71                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1} was mutably borrowed here in the previous iteration of the loop{2}",
                desc, via(opt_via), opt_via))
    })format!(
72                    "{}{} was mutably borrowed here in the previous iteration of the loop{}",
73                    desc,
74                    via(opt_via),
75                    opt_via,
76                ),
77            );
78            if let Some(old_load_end_span) = old_load_end_span {
79                err.span_label(old_load_end_span, "mutable borrow ends here");
80            }
81        } else {
82            err.span_label(
83                old_loan_span,
84                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("first mutable borrow occurs here{0}",
                via(old_opt_via)))
    })format!("first mutable borrow occurs here{}", via(old_opt_via)),
85            );
86            err.span_label(
87                new_loan_span,
88                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("second mutable borrow occurs here{0}",
                via(opt_via)))
    })format!("second mutable borrow occurs here{}", via(opt_via)),
89            );
90            if let Some(old_load_end_span) = old_load_end_span {
91                err.span_label(old_load_end_span, "first borrow ends here");
92            }
93        }
94        err
95    }
96
97    pub(crate) fn cannot_uniquely_borrow_by_two_closures(
98        &self,
99        new_loan_span: Span,
100        desc: &str,
101        old_loan_span: Span,
102        old_load_end_span: Option<Span>,
103    ) -> Diag<'infcx> {
104        let mut err = {
    self.dcx().struct_span_err(new_loan_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("two closures require unique access to {0} at the same time",
                            desc))
                })).with_code(E0524)
}struct_span_code_err!(
105            self.dcx(),
106            new_loan_span,
107            E0524,
108            "two closures require unique access to {} at the same time",
109            desc,
110        );
111        if old_loan_span == new_loan_span {
112            err.span_label(
113                old_loan_span,
114                "closures are constructed here in different iterations of loop",
115            );
116        } else {
117            err.span_label(old_loan_span, "first closure is constructed here");
118            err.span_label(new_loan_span, "second closure is constructed here");
119        }
120        if let Some(old_load_end_span) = old_load_end_span {
121            err.span_label(old_load_end_span, "borrow from first closure ends here");
122        }
123        err
124    }
125
126    pub(crate) fn cannot_uniquely_borrow_by_one_closure(
127        &self,
128        new_loan_span: Span,
129        container_name: &str,
130        desc_new: &str,
131        opt_via: &str,
132        old_loan_span: Span,
133        noun_old: &str,
134        old_opt_via: &str,
135        previous_end_span: Option<Span>,
136    ) -> Diag<'infcx> {
137        let mut err = {
    self.dcx().struct_span_err(new_loan_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("closure requires unique access to {0} but {1} is already borrowed{2}",
                            desc_new, noun_old, old_opt_via))
                })).with_code(E0500)
}struct_span_code_err!(
138            self.dcx(),
139            new_loan_span,
140            E0500,
141            "closure requires unique access to {} but {} is already borrowed{}",
142            desc_new,
143            noun_old,
144            old_opt_via,
145        );
146        err.span_label(
147            new_loan_span,
148            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} construction occurs here{1}",
                container_name, opt_via))
    })format!("{container_name} construction occurs here{opt_via}"),
149        );
150        err.span_label(old_loan_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("borrow occurs here{0}",
                old_opt_via))
    })format!("borrow occurs here{old_opt_via}"));
151        if let Some(previous_end_span) = previous_end_span {
152            err.span_label(previous_end_span, "borrow ends here");
153        }
154        err
155    }
156
157    pub(crate) fn cannot_reborrow_already_uniquely_borrowed(
158        &self,
159        new_loan_span: Span,
160        container_name: &str,
161        desc_new: &str,
162        opt_via: &str,
163        kind_new: &str,
164        old_loan_span: Span,
165        old_opt_via: &str,
166        previous_end_span: Option<Span>,
167        second_borrow_desc: &str,
168    ) -> Diag<'infcx> {
169        let mut err = {
    self.dcx().struct_span_err(new_loan_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot borrow {0}{1} as {2} because previous closure requires unique access",
                            desc_new, opt_via, kind_new))
                })).with_code(E0501)
}struct_span_code_err!(
170            self.dcx(),
171            new_loan_span,
172            E0501,
173            "cannot borrow {}{} as {} because previous closure requires unique access",
174            desc_new,
175            opt_via,
176            kind_new,
177        );
178        err.span_label(new_loan_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}borrow occurs here{1}",
                second_borrow_desc, opt_via))
    })format!("{second_borrow_desc}borrow occurs here{opt_via}"));
179        err.span_label(
180            old_loan_span,
181            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} construction occurs here{1}",
                container_name, old_opt_via))
    })format!("{container_name} construction occurs here{old_opt_via}"),
182        );
183        if let Some(previous_end_span) = previous_end_span {
184            err.span_label(previous_end_span, "borrow from closure ends here");
185        }
186        err
187    }
188
189    pub(crate) fn cannot_reborrow_already_borrowed(
190        &self,
191        span: Span,
192        desc_new: &str,
193        msg_new: &str,
194        kind_new: &str,
195        old_span: Span,
196        noun_old: &str,
197        kind_old: &str,
198        msg_old: &str,
199        old_load_end_span: Option<Span>,
200    ) -> Diag<'infcx> {
201        let via = |msg: &str| if msg.is_empty() { "".to_string() } else { ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" (via {0})", msg))
    })format!(" (via {msg})") };
202        let mut err = {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot borrow {0}{1} as {2} because {3} is also borrowed as {4}{5}",
                            desc_new, via(msg_new), kind_new, noun_old, kind_old,
                            via(msg_old)))
                })).with_code(E0502)
}struct_span_code_err!(
203            self.dcx(),
204            span,
205            E0502,
206            "cannot borrow {}{} as {} because {} is also borrowed as {}{}",
207            desc_new,
208            via(msg_new),
209            kind_new,
210            noun_old,
211            kind_old,
212            via(msg_old),
213        );
214
215        if msg_new.is_empty() {
216            // If `msg_new` is empty, then this isn't a borrow of a union field.
217            err.span_label(span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} borrow occurs here", kind_new))
    })format!("{kind_new} borrow occurs here"));
218            err.span_label(old_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} borrow occurs here", kind_old))
    })format!("{kind_old} borrow occurs here"));
219        } else {
220            // If `msg_new` isn't empty, then this a borrow of a union field.
221            err.span_label(
222                span,
223                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} borrow of {1} -- which overlaps with {2} -- occurs here",
                kind_new, msg_new, msg_old))
    })format!(
224                    "{kind_new} borrow of {msg_new} -- which overlaps with {msg_old} -- occurs here",
225                ),
226            );
227            err.span_label(old_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} borrow occurs here{1}",
                kind_old, via(msg_old)))
    })format!("{} borrow occurs here{}", kind_old, via(msg_old)));
228        }
229
230        if let Some(old_load_end_span) = old_load_end_span {
231            err.span_label(old_load_end_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} borrow ends here", kind_old))
    })format!("{kind_old} borrow ends here"));
232        }
233        err
234    }
235
236    pub(crate) fn cannot_assign_to_borrowed(
237        &self,
238        span: Span,
239        borrow_span: Span,
240        desc: &str,
241    ) -> Diag<'infcx> {
242        {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot assign to {0} because it is borrowed",
                            desc))
                })).with_code(E0506)
}struct_span_code_err!(
243            self.dcx(),
244            span,
245            E0506,
246            "cannot assign to {} because it is borrowed",
247            desc,
248        )
249        .with_span_label(borrow_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} is borrowed here", desc))
    })format!("{desc} is borrowed here"))
250        .with_span_label(span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} is assigned to here but it was already borrowed",
                desc))
    })format!("{desc} is assigned to here but it was already borrowed"))
251    }
252
253    pub(crate) fn cannot_reassign_immutable(
254        &self,
255        span: Span,
256        desc: &str,
257        is_arg: bool,
258    ) -> Diag<'infcx> {
259        let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" };
260        {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot assign {0} {1}",
                            msg, desc))
                })).with_code(E0384)
}struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc)
261    }
262
263    pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'infcx> {
264        {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot assign to {0}",
                            desc))
                })).with_code(E0594)
}struct_span_code_err!(self.dcx(), span, E0594, "cannot assign to {}", desc)
265    }
266
267    pub(crate) fn cannot_move_out_of(
268        &self,
269        move_from_span: Span,
270        move_from_desc: &str,
271    ) -> Diag<'infcx> {
272        {
    self.dcx().struct_span_err(move_from_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot move out of {0}",
                            move_from_desc))
                })).with_code(E0507)
}struct_span_code_err!(
273            self.dcx(),
274            move_from_span,
275            E0507,
276            "cannot move out of {}",
277            move_from_desc
278        )
279    }
280
281    /// Signal an error due to an attempt to move out of the interior
282    /// of an array or slice. `is_index` is None when error origin
283    /// didn't capture whether there was an indexing operation or not.
284    pub(crate) fn cannot_move_out_of_interior_noncopy(
285        &self,
286        move_from_span: Span,
287        ty: Ty<'_>,
288        is_index: Option<bool>,
289    ) -> Diag<'infcx> {
290        let type_name = match (ty.kind(), is_index) {
291            (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
292            (&ty::Slice(_), _) => "slice",
293            _ => ::rustc_middle::util::bug::span_bug_fmt(move_from_span,
    format_args!("this path should not cause illegal move"))span_bug!(move_from_span, "this path should not cause illegal move"),
294        };
295        {
    self.dcx().struct_span_err(move_from_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot move out of type `{0}`, a non-copy {1}",
                            ty, type_name))
                })).with_code(E0508)
}struct_span_code_err!(
296            self.dcx(),
297            move_from_span,
298            E0508,
299            "cannot move out of type `{}`, a non-copy {}",
300            ty,
301            type_name,
302        )
303        .with_span_label(move_from_span, "cannot move out of here")
304    }
305
306    pub(crate) fn cannot_move_out_of_interior_of_drop(
307        &self,
308        move_from_span: Span,
309        container_ty: Ty<'_>,
310    ) -> Diag<'infcx> {
311        {
    self.dcx().struct_span_err(move_from_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot move out of type `{0}`, which implements the `Drop` trait",
                            container_ty))
                })).with_code(E0509)
}struct_span_code_err!(
312            self.dcx(),
313            move_from_span,
314            E0509,
315            "cannot move out of type `{}`, which implements the `Drop` trait",
316            container_ty,
317        )
318        .with_span_label(move_from_span, "cannot move out of here")
319    }
320
321    pub(crate) fn cannot_act_on_moved_value(
322        &self,
323        use_span: Span,
324        verb: &str,
325        optional_adverb_for_moved: &str,
326        moved_path: Option<String>,
327    ) -> Diag<'infcx> {
328        let moved_path = moved_path.map(|mp| ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(": `{0}`", mp))
    })format!(": `{mp}`")).unwrap_or_default();
329
330        {
    self.dcx().struct_span_err(use_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("{0} of {1}moved value{2}",
                            verb, optional_adverb_for_moved, moved_path))
                })).with_code(E0382)
}struct_span_code_err!(
331            self.dcx(),
332            use_span,
333            E0382,
334            "{} of {}moved value{}",
335            verb,
336            optional_adverb_for_moved,
337            moved_path,
338        )
339    }
340
341    pub(crate) fn cannot_borrow_path_as_mutable_because(
342        &self,
343        span: Span,
344        path: &str,
345        reason: &str,
346    ) -> Diag<'infcx> {
347        {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot borrow {0} as mutable{1}",
                            path, reason))
                })).with_code(E0596)
}struct_span_code_err!(
348            self.dcx(),
349            span,
350            E0596,
351            "cannot borrow {} as mutable{}",
352            path,
353            reason
354        )
355    }
356
357    pub(crate) fn cannot_mutate_in_immutable_section(
358        &self,
359        mutate_span: Span,
360        immutable_span: Span,
361        immutable_place: &str,
362        immutable_section: &str,
363        action: &str,
364    ) -> Diag<'infcx> {
365        {
    self.dcx().struct_span_err(mutate_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot {0} {1} in {2}",
                            action, immutable_place, immutable_section))
                })).with_code(E0510)
}struct_span_code_err!(
366            self.dcx(),
367            mutate_span,
368            E0510,
369            "cannot {} {} in {}",
370            action,
371            immutable_place,
372            immutable_section,
373        )
374        .with_span_label(mutate_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("cannot {0}", action))
    })format!("cannot {action}"))
375        .with_span_label(immutable_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("value is immutable in {0}",
                immutable_section))
    })format!("value is immutable in {immutable_section}"))
376    }
377
378    pub(crate) fn cannot_borrow_across_coroutine_yield(
379        &self,
380        span: Span,
381        yield_span: Span,
382    ) -> Diag<'infcx> {
383        let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind;
384        let mut diag = {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("borrow may still be in use when {0:#} yields",
                            coroutine_kind))
                })).with_code(E0626)
}struct_span_code_err!(
385            self.dcx(),
386            span,
387            E0626,
388            "borrow may still be in use when {coroutine_kind:#} yields",
389        );
390        diag.span_label(
391            self.infcx.tcx.def_span(self.body.source.def_id()),
392            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("within this {0:#}",
                coroutine_kind))
    })format!("within this {coroutine_kind:#}"),
393        );
394        diag.span_label(yield_span, "possible yield occurs here");
395        if #[allow(non_exhaustive_omitted_patterns)] match coroutine_kind {
    hir::CoroutineKind::Coroutine(_) => true,
    _ => false,
}matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_)) {
396            let hir::Closure { capture_clause, fn_decl_span, .. } = self
397                .infcx
398                .tcx
399                .hir_node_by_def_id(self.body.source.def_id().expect_local())
400                .expect_closure();
401            let span = match capture_clause {
402                rustc_hir::CaptureBy::Value { move_kw } => move_kw.shrink_to_lo(),
403                rustc_hir::CaptureBy::Use { use_kw } => use_kw.shrink_to_lo(),
404                rustc_hir::CaptureBy::Ref => fn_decl_span.shrink_to_lo(),
405            };
406            diag.span_suggestion_verbose(
407                span,
408                "add `static` to mark this coroutine as unmovable",
409                "static ",
410                Applicability::MaybeIncorrect,
411            );
412        }
413        diag
414    }
415
416    pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'infcx> {
417        {
    self.dcx().struct_span_err(borrow_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("borrow may still be in use when destructor runs"))
                })).with_code(E0713)
}struct_span_code_err!(
418            self.dcx(),
419            borrow_span,
420            E0713,
421            "borrow may still be in use when destructor runs",
422        )
423    }
424
425    pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'infcx> {
426        {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("{0} does not live long enough",
                            path))
                })).with_code(E0597)
}struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path)
427    }
428
429    pub(crate) fn cannot_return_reference_to_local(
430        &self,
431        span: Span,
432        return_kind: &str,
433        reference_desc: &str,
434        path_desc: &str,
435    ) -> Diag<'infcx> {
436        {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("cannot {0} {1} {2}",
                            return_kind, reference_desc, path_desc))
                })).with_code(E0515)
}struct_span_code_err!(
437            self.dcx(),
438            span,
439            E0515,
440            "cannot {RETURN} {REFERENCE} {LOCAL}",
441            RETURN = return_kind,
442            REFERENCE = reference_desc,
443            LOCAL = path_desc,
444        )
445        .with_span_label(
446            span,
447            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}s a {1} data owned by the current function",
                return_kind, reference_desc))
    })format!("{return_kind}s a {reference_desc} data owned by the current function"),
448        )
449    }
450
451    pub(crate) fn cannot_capture_in_long_lived_closure(
452        &self,
453        closure_span: Span,
454        closure_kind: &str,
455        borrowed_path: &str,
456        capture_span: Span,
457        scope: &str,
458    ) -> Diag<'infcx> {
459        {
    self.dcx().struct_span_err(closure_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("{0} may outlive the current {1}, but it borrows {2}, which is owned by the current {1}",
                            closure_kind, scope, borrowed_path))
                })).with_code(E0373)
}struct_span_code_err!(
460            self.dcx(),
461            closure_span,
462            E0373,
463            "{closure_kind} may outlive the current {scope}, but it borrows {borrowed_path}, \
464             which is owned by the current {scope}",
465        )
466        .with_span_label(capture_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} is borrowed here",
                borrowed_path))
    })format!("{borrowed_path} is borrowed here"))
467        .with_span_label(closure_span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("may outlive borrowed value {0}",
                borrowed_path))
    })format!("may outlive borrowed value {borrowed_path}"))
468    }
469
470    pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'infcx> {
471        {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("thread-local variable borrowed past end of function"))
                })).with_code(E0712)
}struct_span_code_err!(
472            self.dcx(),
473            span,
474            E0712,
475            "thread-local variable borrowed past end of function",
476        )
477    }
478
479    pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'infcx> {
480        {
    self.dcx().struct_span_err(span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("temporary value dropped while borrowed"))
                })).with_code(E0716)
}struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed")
481    }
482}
483
484pub(crate) fn borrowed_data_escapes_closure<'tcx>(
485    tcx: TyCtxt<'tcx>,
486    escape_span: Span,
487    escapes_from: &str,
488) -> Diag<'tcx> {
489    {
    tcx.dcx().struct_span_err(escape_span,
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!("borrowed data escapes outside of {0}",
                            escapes_from))
                })).with_code(E0521)
}struct_span_code_err!(
490        tcx.dcx(),
491        escape_span,
492        E0521,
493        "borrowed data escapes outside of {}",
494        escapes_from,
495    )
496}