diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index a1112d5961eca..c89dc889b5e39 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -247,7 +247,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { match category { ConstraintCategory::AssignmentToUpvar | ConstraintCategory::CallArgumentToUpvar => - self.report_closure_error(mir, infcx, fr, outlived_fr, span), + self.report_closure_error(mir, infcx, mir_def_id, fr, outlived_fr, category, span), _ => self.report_general_error(mir, infcx, mir_def_id, fr, outlived_fr, category, span), } @@ -257,33 +257,44 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, mir: &Mir<'tcx>, infcx: &InferCtxt<'_, '_, 'tcx>, + mir_def_id: DefId, fr: RegionVid, outlived_fr: RegionVid, + category: &ConstraintCategory, span: &Span, ) { + let fr_name_and_span = self.get_var_name_and_span_for_region( + infcx.tcx, mir, fr); + let outlived_fr_name_and_span = self.get_var_name_and_span_for_region( + infcx.tcx, mir,outlived_fr); + + if fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none() { + return self.report_general_error(mir, infcx, mir_def_id, fr, outlived_fr, category, + span); + } + let diag = &mut infcx.tcx.sess.struct_span_err( *span, &format!("borrowed data escapes outside of closure"), ); - let (outlived_fr_name, outlived_fr_span) = self.get_var_name_and_span_for_region( - infcx.tcx, mir, outlived_fr); - - if let Some(name) = outlived_fr_name { - diag.span_label( - outlived_fr_span, - format!("`{}` is declared here, outside of the closure body", name), - ); + if let Some((outlived_fr_name, outlived_fr_span)) = outlived_fr_name_and_span { + if let Some(name) = outlived_fr_name { + diag.span_label( + outlived_fr_span, + format!("`{}` is declared here, outside of the closure body", name), + ); + } } - let (fr_name, fr_span) = self.get_var_name_and_span_for_region(infcx.tcx, mir, fr); + if let Some((fr_name, fr_span)) = fr_name_and_span { + if let Some(name) = fr_name { + diag.span_label( + fr_span, + format!("`{}` is a reference that is only valid in the closure body", name), + ); - if let Some(name) = fr_name { - diag.span_label( - fr_span, - format!("`{}` is a reference that is only valid in the closure body", name), - ); - - diag.span_label(*span, format!("`{}` escapes the closure body here", name)); + diag.span_label(*span, format!("`{}` escapes the closure body here", name)); + } } diag.emit(); diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs index ba572de0de7ef..f1c3a7489ee8f 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs @@ -22,7 +22,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { tcx: TyCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>, fr: RegionVid, - ) -> (Option, Span) { + ) -> Option<(Option, Span)> { debug!("get_var_name_and_span_for_region(fr={:?})", fr); assert!(self.universal_regions.is_universal_region(fr)); @@ -37,7 +37,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.get_argument_index_for_region(tcx, fr) .map(|index| self.get_argument_name_and_span_for_region(mir, index)) }) - .unwrap_or_else(|| span_bug!(mir.span, "can't find var name for free region {:?}", fr)) } /// Search the upvars (if any) to find one that references fr. Return its index. diff --git a/src/test/ui/borrowck/issue-7573.nll.stderr b/src/test/ui/borrowck/issue-7573.nll.stderr index 5904e98753694..b0fbcd3ad9f39 100644 --- a/src/test/ui/borrowck/issue-7573.nll.stderr +++ b/src/test/ui/borrowck/issue-7573.nll.stderr @@ -4,17 +4,17 @@ warning: not reporting region error due to nll LL | let mut lines_to_use: Vec<&CrateId> = Vec::new(); | ^ -error: unsatisfied lifetime constraints +error: borrowed data escapes outside of closure --> $DIR/issue-7573.rs:32:9 | LL | let mut lines_to_use: Vec<&CrateId> = Vec::new(); - | ---------------- lifetime `'2` appears in the type of `lines_to_use` + | ---------------- `lines_to_use` is declared here, outside of the closure body LL | //~^ NOTE cannot infer an appropriate lifetime LL | let push_id = |installed_id: &CrateId| { - | - let's call the lifetime of this reference `'1` + | ------------ `installed_id` is a reference that is only valid in the closure body ... LL | lines_to_use.push(installed_id); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `installed_id` escapes the closure body here error: aborting due to previous error diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr b/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr index 19e10ba6da8b9..e26b1956d5e81 100644 --- a/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr +++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr @@ -4,11 +4,13 @@ warning: not reporting region error due to nll LL | static_val(x); //~ ERROR cannot infer | ^ -error: unsatisfied lifetime constraints +error: borrowed data escapes outside of closure --> $DIR/dyn-trait.rs:32:5 | +LL | fn with_dyn_debug_static<'a>(x: Box) { + | - `x` is a reference that is only valid in the closure body LL | static_val(x); //~ ERROR cannot infer - | ^^^^^^^^^^^^^ argument requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^ `x` escapes the closure body here error: aborting due to previous error diff --git a/src/test/ui/issue-16683.nll.stderr b/src/test/ui/issue-16683.nll.stderr index d789f580b2738..f9dda27da0985 100644 --- a/src/test/ui/issue-16683.nll.stderr +++ b/src/test/ui/issue-16683.nll.stderr @@ -10,13 +10,13 @@ warning: not reporting region error due to nll LL | self.a(); //~ ERROR cannot infer | ^ -error: unsatisfied lifetime constraints +error: borrowed data escapes outside of closure --> $DIR/issue-16683.rs:14:9 | LL | fn b(&self) { - | - let's call the lifetime of this reference `'1` + | ----- `self` is a reference that is only valid in the closure body LL | self.a(); //~ ERROR cannot infer - | ^^^^^^^^ argument requires that `'1` must outlive `'a` + | ^^^^^^^^ `self` escapes the closure body here error: aborting due to previous error diff --git a/src/test/ui/issue-17758.nll.stderr b/src/test/ui/issue-17758.nll.stderr index 124fc6f0b3998..5775135aefc5f 100644 --- a/src/test/ui/issue-17758.nll.stderr +++ b/src/test/ui/issue-17758.nll.stderr @@ -10,13 +10,13 @@ warning: not reporting region error due to nll LL | self.foo(); | ^^^ -error: unsatisfied lifetime constraints +error: borrowed data escapes outside of closure --> $DIR/issue-17758.rs:17:9 | LL | fn bar(&self) { - | - let's call the lifetime of this reference `'1` + | ----- `self` is a reference that is only valid in the closure body LL | self.foo(); - | ^^^^^^^^^^ argument requires that `'1` must outlive `'a` + | ^^^^^^^^^^ `self` escapes the closure body here error: aborting due to previous error diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 8fd5e898c8d9b..d51ba8201aaa6 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -4,16 +4,16 @@ warning: not reporting region error due to nll LL | foo(cell, |cell_a, cell_x| { | ^^^ -error: unsatisfied lifetime constraints +error: borrowed data escapes outside of closure --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:20 | LL | foo(cell, |cell_a, cell_x| { - | ------ ------ lifetime `'1` appears in this argument + | ------ ------ `cell_x` is a reference that is only valid in the closure body | | - | lifetime `'2` appears in this argument + | `cell_a` is declared here, outside of the closure body LL | //~^ WARNING not reporting region error due to nll LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure - | ^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + | ^^^^^^^^^^^^ `cell_x` escapes the closure body here note: No external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:31:15 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index f65e7161ca8c5..3177cd7c28f64 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -23,16 +23,18 @@ LL | | }); = note: number of external vids: 2 = note: where '_#1r: '_#0r -error: unsatisfied lifetime constraints +error: borrowed data escapes outside of closure --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:5 | +LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | ------ `cell_a` is a reference that is only valid in the closure body LL | / establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { LL | | //~^ ERROR LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll LL | | }); - | |______^ argument requires that `'a` must outlive `'static` + | |______^ `cell_a` escapes the closure body here note: No external requirements --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:44:1 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index f1b2c9f198d69..089c88abcdd4a 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -23,16 +23,18 @@ LL | | }); = note: number of external vids: 3 = note: where '_#1r: '_#0r -error: unsatisfied lifetime constraints +error: borrowed data escapes outside of closure --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:5 | +LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + | ------ `cell_a` is a reference that is only valid in the closure body LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { LL | | //~^ ERROR LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) LL | | //~^ WARNING not reporting region error due to nll LL | | }); - | |______^ argument requires that `'a` must outlive `'static` + | |______^ `cell_a` escapes the closure body here note: No external requirements --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:47:1 diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr index 48862166f897f..8acf2ef51ecd2 100644 --- a/src/test/ui/nll/issue-50716.stderr +++ b/src/test/ui/nll/issue-50716.stderr @@ -1,8 +1,11 @@ -error: unsatisfied lifetime constraints +error: borrowed data escapes outside of closure --> $DIR/issue-50716.rs:25:14 | +LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) + | - `s` is a reference that is only valid in the closure body +... LL | let _x = *s; //~ ERROR - | ^^ assignment requires that `'a` must outlive `'static` + | ^^ `s` escapes the closure body here error: aborting due to previous error