1 //! Error Reporting for Anonymous Region Lifetime Errors
2 //! where both the regions are anonymous.
4 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
5 use crate::infer::lexical_region_resolve::RegionResolutionError::SubSupConflict;
6 use crate::infer::SubregionOrigin;
7 use rustc_errors::ErrorReported;
8 use rustc_hir::{Expr, ExprKind::Closure, Node};
9 use rustc_middle::ty::RegionKind;
11 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
12 /// Print the error message for lifetime errors when binding escapes a closure.
14 /// Consider a case where we have
17 /// fn with_int<F>(f: F) where F: FnOnce(&isize) {
23 /// with_int(|y| x = Some(y));
27 /// the output will be
31 /// ----- borrowed data cannot be stored into here...
32 /// with_int(|y| x = Some(y));
33 /// --- ^ cannot be stored outside of its closure
35 /// ...because it cannot outlive this closure
37 pub(super) fn try_report_outlives_closure(&self) -> Option<ErrorReported> {
38 if let Some(SubSupConflict(_, origin, ref sub_origin, _, ref sup_origin, sup_region)) =
41 // #45983: when trying to assign the contents of an argument to a binding outside of a
42 // closure, provide a specific message pointing this out.
44 &SubregionOrigin::BindingTypeIsNotValidAtDecl(ref external_span),
45 &RegionKind::ReFree(ref free_region),
46 ) = (&sub_origin, sup_region)
48 let hir = &self.tcx().hir();
49 if let Some(def_id) = free_region.scope.as_local() {
50 let hir_id = hir.as_local_hir_id(def_id);
51 if let Node::Expr(Expr { kind: Closure(_, _, _, closure_span, None), .. }) =
54 let sup_sp = sup_origin.span();
55 let origin_sp = origin.span();
56 let mut err = self.tcx().sess.struct_span_err(
58 "borrowed data cannot be stored outside of its closure",
60 err.span_label(sup_sp, "cannot be stored outside of its closure");
61 if origin_sp == sup_sp || origin_sp.contains(sup_sp) {
62 // // sup_sp == origin.span():
65 // ----- borrowed data cannot be stored into here...
66 // with_int(|y| x = Some(y));
67 // --- ^ cannot be stored outside of its closure
69 // ...because it cannot outlive this closure
71 // // origin.contains(&sup_sp):
73 // let mut f: Option<&u32> = None;
74 // ----- borrowed data cannot be stored into here...
75 // closure_expecting_bound(|x: &'x u32| {
76 // ------------ ... because it cannot outlive this closure
78 // ^ cannot be stored outside of its closure
81 "borrowed data cannot be stored into here...",
85 "...because it cannot outlive this closure",
88 // FIXME: the wording for this case could be much improved
90 // let mut lines_to_use: Vec<&CrateId> = Vec::new();
91 // - cannot infer an appropriate lifetime...
92 // let push_id = |installed_id: &CrateId| {
93 // ------- ------------------------ borrowed data cannot outlive this closure
95 // ...so that variable is valid at time of its declaration
96 // lines_to_use.push(installed_id);
97 // ^^^^^^^^^^^^ cannot be stored outside of its closure
98 err.span_label(origin_sp, "cannot infer an appropriate lifetime...");
101 "...so that variable is valid at time of its \
106 "borrowed data cannot outlive this closure",
110 return Some(ErrorReported);