Skip to content

Commit b015940

Browse files
authored
Rollup merge of #89501 - Aaron1011:escaping-name-regions, r=davidtwco
Note specific regions involved in 'borrowed data escapes' error Fixes #67007 Currently, a 'borrowed data escapes' error does not mention the specific lifetime involved (except indirectly through a suggestion about adding a lifetime bound). We now explain the specific lifetime relationship that failed to hold, which improves otherwise vague error messages.
2 parents b87a9a8 + 3c974ad commit b015940

18 files changed

+209
-39
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+21
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
498498
diag.span_label(*span, format!("`{}` escapes the {} body here", fr_name, escapes_from));
499499
}
500500

501+
// Only show an extra note if we can find an 'error region' for both of the region
502+
// variables. This avoids showing a noisy note that just mentions 'synthetic' regions
503+
// that don't help the user understand the error.
504+
if self.to_error_region(errci.fr).is_some()
505+
&& self.to_error_region(errci.outlived_fr).is_some()
506+
{
507+
let fr_region_name = self.give_region_a_name(errci.fr).unwrap();
508+
fr_region_name.highlight_region_name(&mut diag);
509+
let outlived_fr_region_name = self.give_region_a_name(errci.outlived_fr).unwrap();
510+
outlived_fr_region_name.highlight_region_name(&mut diag);
511+
512+
diag.span_label(
513+
*span,
514+
format!(
515+
"{}requires that `{}` must outlive `{}`",
516+
category.description(),
517+
fr_region_name,
518+
outlived_fr_region_name,
519+
),
520+
);
521+
}
501522
diag
502523
}
503524

src/test/ui/async-await/issues/issue-62097.nll.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ error[E0521]: borrowed data escapes outside of associated function
2020
--> $DIR/issue-62097.rs:13:9
2121
|
2222
LL | pub async fn run_dummy_fn(&self) {
23-
| ----- `self` is a reference that is only valid in the associated function body
23+
| -----
24+
| |
25+
| `self` is a reference that is only valid in the associated function body
26+
| let's call the lifetime of this reference `'1`
2427
LL | foo(|| self.bar()).await;
25-
| ^^^^^^^^^^^^^^^^^^ `self` escapes the associated function body here
28+
| ^^^^^^^^^^^^^^^^^^
29+
| |
30+
| `self` escapes the associated function body here
31+
| argument requires that `'1` must outlive `'static`
2632

2733
error: aborting due to 2 previous errors
2834

src/test/ui/impl-header-lifetime-elision/dyn-trait.nll.stderr

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ error[E0521]: borrowed data escapes outside of function
22
--> $DIR/dyn-trait.rs:20:5
33
|
44
LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
5-
| - `x` is a reference that is only valid in the function body
5+
| -- - `x` is a reference that is only valid in the function body
6+
| |
7+
| lifetime `'a` defined here
68
LL | static_val(x);
7-
| ^^^^^^^^^^^^^ `x` escapes the function body here
9+
| ^^^^^^^^^^^^^
10+
| |
11+
| `x` escapes the function body here
12+
| argument requires that `'a` must outlive `'static`
813

914
error: aborting due to previous error
1015

src/test/ui/issues/issue-16683.nll.stderr

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
error[E0521]: borrowed data escapes outside of associated function
22
--> $DIR/issue-16683.rs:4:9
33
|
4+
LL | trait T<'a> {
5+
| -- lifetime `'a` defined here
6+
LL | fn a(&'a self) -> &'a bool;
47
LL | fn b(&self) {
5-
| ----- `self` is a reference that is only valid in the associated function body
8+
| -----
9+
| |
10+
| `self` is a reference that is only valid in the associated function body
11+
| let's call the lifetime of this reference `'1`
612
LL | self.a();
7-
| ^^^^^^^^ `self` escapes the associated function body here
13+
| ^^^^^^^^
14+
| |
15+
| `self` escapes the associated function body here
16+
| argument requires that `'1` must outlive `'a`
817

918
error: aborting due to previous error
1019

src/test/ui/issues/issue-17758.nll.stderr

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
error[E0521]: borrowed data escapes outside of associated function
22
--> $DIR/issue-17758.rs:7:9
33
|
4+
LL | trait Foo<'a> {
5+
| -- lifetime `'a` defined here
6+
LL | fn foo(&'a self);
47
LL | fn bar(&self) {
5-
| ----- `self` is a reference that is only valid in the associated function body
8+
| -----
9+
| |
10+
| `self` is a reference that is only valid in the associated function body
11+
| let's call the lifetime of this reference `'1`
612
LL | self.foo();
7-
| ^^^^^^^^^^ `self` escapes the associated function body here
13+
| ^^^^^^^^^^
14+
| |
15+
| `self` escapes the associated function body here
16+
| argument requires that `'1` must outlive `'a`
817

918
error: aborting due to previous error
1019

src/test/ui/lifetimes/lifetime-bound-will-change-warning.nll.stderr

+14-4
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,29 @@ error[E0521]: borrowed data escapes outside of function
22
--> $DIR/lifetime-bound-will-change-warning.rs:34:5
33
|
44
LL | fn test2<'a>(x: &'a Box<dyn Fn() + 'a>) {
5-
| - `x` is a reference that is only valid in the function body
5+
| -- - `x` is a reference that is only valid in the function body
6+
| |
7+
| lifetime `'a` defined here
68
LL | // but ref_obj will not, so warn.
79
LL | ref_obj(x)
8-
| ^^^^^^^^^^ `x` escapes the function body here
10+
| ^^^^^^^^^^
11+
| |
12+
| `x` escapes the function body here
13+
| argument requires that `'a` must outlive `'static`
914

1015
error[E0521]: borrowed data escapes outside of function
1116
--> $DIR/lifetime-bound-will-change-warning.rs:39:5
1217
|
1318
LL | fn test2cc<'a>(x: &'a Box<dyn Fn() + 'a>) {
14-
| - `x` is a reference that is only valid in the function body
19+
| -- - `x` is a reference that is only valid in the function body
20+
| |
21+
| lifetime `'a` defined here
1522
LL | // same as test2, but cross crate
1623
LL | lib::ref_obj(x)
17-
| ^^^^^^^^^^^^^^^ `x` escapes the function body here
24+
| ^^^^^^^^^^^^^^^
25+
| |
26+
| `x` escapes the function body here
27+
| argument requires that `'a` must outlive `'static`
1828

1929
error: aborting due to 2 previous errors
2030

src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr

+7-2
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,19 @@ error[E0521]: borrowed data escapes outside of function
3838
--> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:32:5
3939
|
4040
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
41-
| ------ `cell_a` is a reference that is only valid in the function body
41+
| -- ------ `cell_a` is a reference that is only valid in the function body
42+
| |
43+
| lifetime `'a` defined here
4244
LL | / establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
4345
LL | |
4446
LL | |
4547
LL | | // Only works if 'x: 'y:
4648
LL | | demand_y(x, y, x.get())
4749
LL | | });
48-
| |______^ `cell_a` escapes the function body here
50+
| | ^
51+
| | |
52+
| |______`cell_a` escapes the function body here
53+
| argument requires that `'a` must outlive `'static`
4954

5055
error: aborting due to previous error
5156

src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr

+7-2
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,19 @@ error[E0521]: borrowed data escapes outside of function
3838
--> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:35:5
3939
|
4040
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
41-
| ------ `cell_a` is a reference that is only valid in the function body
41+
| -- ------ `cell_a` is a reference that is only valid in the function body
42+
| |
43+
| lifetime `'a` defined here
4244
LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
4345
LL | |
4446
LL | |
4547
LL | | // Only works if 'x: 'y:
4648
LL | | demand_y(x, y, x.get())
4749
LL | | });
48-
| |______^ `cell_a` escapes the function body here
50+
| | ^
51+
| | |
52+
| |______`cell_a` escapes the function body here
53+
| argument requires that `'a` must outlive `'static`
4954

5055
error: aborting due to previous error
5156

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Regression test for issue #67007
2+
// Ensures that we show information about the specific regions involved
3+
4+
#![feature(nll)]
5+
6+
// Covariant over 'a, invariant over 'tcx
7+
struct FnCtxt<'a, 'tcx: 'a>(&'a (), *mut &'tcx ());
8+
9+
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10+
fn use_it(&self, _: &'tcx ()) {}
11+
}
12+
13+
struct Consumer<'tcx>(&'tcx ());
14+
15+
impl<'tcx> Consumer<'tcx> {
16+
fn bad_method<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) {
17+
let other = self.use_fcx(fcx); //~ ERROR borrowed data
18+
fcx.use_it(other);
19+
}
20+
21+
fn use_fcx<'a>(&self, _: &FnCtxt<'a, 'tcx>) -> &'a () {
22+
&()
23+
}
24+
}
25+
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0521]: borrowed data escapes outside of associated function
2+
--> $DIR/issue-67007-escaping-data.rs:17:21
3+
|
4+
LL | impl<'tcx> Consumer<'tcx> {
5+
| ---- lifetime `'tcx` defined here
6+
LL | fn bad_method<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) {
7+
| -- ----- --- `fcx` is a reference that is only valid in the associated function body
8+
| | |
9+
| | `self` declared here, outside of the associated function body
10+
| lifetime `'a` defined here
11+
LL | let other = self.use_fcx(fcx);
12+
| ^^^^^^^^^^^^^^^^^
13+
| |
14+
| `fcx` escapes the associated function body here
15+
| argument requires that `'a` must outlive `'tcx`
16+
|
17+
= help: consider adding the following bound: `'a: 'tcx`
18+
19+
error: aborting due to previous error
20+
21+
For more information about this error, try `rustc --explain E0521`.

src/test/ui/nll/outlives-suggestion-simple.stderr

+8-1
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,20 @@ LL | self.x
9292
error[E0521]: borrowed data escapes outside of associated function
9393
--> $DIR/outlives-suggestion-simple.rs:73:9
9494
|
95+
LL | impl<'a> Foo2<'a> {
96+
| -- lifetime `'a` defined here
97+
LL | // should not produce outlives suggestions to name 'self
9598
LL | fn get_bar(&self) -> Bar2 {
9699
| -----
97100
| |
98101
| `self` declared here, outside of the associated function body
99102
| `self` is a reference that is only valid in the associated function body
103+
| let's call the lifetime of this reference `'1`
100104
LL | Bar2::new(&self)
101-
| ^^^^^^^^^^^^^^^^ `self` escapes the associated function body here
105+
| ^^^^^^^^^^^^^^^^
106+
| |
107+
| `self` escapes the associated function body here
108+
| argument requires that `'1` must outlive `'a`
102109

103110
error: aborting due to 9 previous errors
104111

src/test/ui/nll/user-annotations/closure-substs.stderr

+7-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,14 @@ error[E0521]: borrowed data escapes outside of closure
2828
--> $DIR/closure-substs.rs:29:9
2929
|
3030
LL | |x: &i32, b: fn(&'static i32)| {
31-
| - `x` is a reference that is only valid in the closure body
31+
| - - let's call the lifetime of this reference `'1`
32+
| |
33+
| `x` is a reference that is only valid in the closure body
3234
LL | b(x);
33-
| ^^^^ `x` escapes the closure body here
35+
| ^^^^
36+
| |
37+
| `x` escapes the closure body here
38+
| argument requires that `'1` must outlive `'static`
3439

3540
error: aborting due to 4 previous errors
3641

src/test/ui/object-lifetime/object-lifetime-default-mybox.nll.stderr

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@ error[E0521]: borrowed data escapes outside of function
1515
--> $DIR/object-lifetime-default-mybox.rs:31:5
1616
|
1717
LL | fn load2<'a>(ss: &MyBox<dyn SomeTrait + 'a>) -> MyBox<dyn SomeTrait + 'a> {
18-
| -- `ss` is a reference that is only valid in the function body
18+
| -- -- `ss` is a reference that is only valid in the function body
19+
| |
20+
| lifetime `'a` defined here
1921
LL | load0(ss)
20-
| ^^^^^^^^^ `ss` escapes the function body here
22+
| ^^^^^^^^^
23+
| |
24+
| `ss` escapes the function body here
25+
| argument requires that `'a` must outlive `'static`
2126

2227
error: aborting due to 2 previous errors
2328

src/test/ui/regions/issue-78262.nll.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ error[E0521]: borrowed data escapes outside of closure
22
--> $DIR/issue-78262.rs:14:26
33
|
44
LL | let f = |x: &dyn TT| x.func();
5-
| - ^^^^^^^^ `x` escapes the closure body here
6-
| |
5+
| - - ^^^^^^^^
6+
| | | |
7+
| | | `x` escapes the closure body here
8+
| | | argument requires that `'1` must outlive `'static`
9+
| | let's call the lifetime of this reference `'1`
710
| `x` is a reference that is only valid in the closure body
811

912
error: aborting due to previous error

src/test/ui/regions/issue-78262.polonius.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ error[E0521]: borrowed data escapes outside of closure
22
--> $DIR/issue-78262.rs:14:26
33
|
44
LL | let f = |x: &dyn TT| x.func();
5-
| - ^^^^^^^^ `x` escapes the closure body here
6-
| |
5+
| - - ^^^^^^^^
6+
| | | |
7+
| | | `x` escapes the closure body here
8+
| | | argument requires that `'1` must outlive `'static`
9+
| | let's call the lifetime of this reference `'1`
710
| `x` is a reference that is only valid in the closure body
811

912
error: aborting due to previous error

src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ error[E0521]: borrowed data escapes outside of function
22
--> $DIR/region-invariant-static-error-reporting.rs:15:9
33
|
44
LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {
5-
| - `x` is a reference that is only valid in the function body
5+
| -- - `x` is a reference that is only valid in the function body
6+
| |
7+
| lifetime `'a` defined here
68
LL | let bad = if x.is_some() {
79
LL | x.unwrap()
8-
| ^^^^^^^^^^ `x` escapes the function body here
10+
| ^^^^^^^^^^
11+
| |
12+
| `x` escapes the function body here
13+
| argument requires that `'a` must outlive `'static`
914

1015
error: aborting due to previous error
1116

src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr

+9-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@ error[E0521]: borrowed data escapes outside of function
22
--> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:20:5
33
|
44
LL | fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) {
5-
| - - `b` is a reference that is only valid in the function body
6-
| |
7-
| `a` declared here, outside of the function body
5+
| -- -- - - `b` is a reference that is only valid in the function body
6+
| | | |
7+
| | | `a` declared here, outside of the function body
8+
| | lifetime `'b` defined here
9+
| lifetime `'a` defined here
810
LL | // Here the value provided for 'y is 'b, and hence 'b:'a does not hold.
911
LL | f.method(b);
10-
| ^^^^^^^^^^^ `b` escapes the function body here
12+
| ^^^^^^^^^^^
13+
| |
14+
| `b` escapes the function body here
15+
| argument requires that `'b` must outlive `'a`
1116
|
1217
= help: consider adding the following bound: `'b: 'a`
1318

0 commit comments

Comments
 (0)