Skip to content

Commit 364ca7f

Browse files
committed
best_blame_constraint: add a special case to recover object lifetime default notes
1 parent 7dfa04d commit 364ca7f

6 files changed

+51
-38
lines changed

Diff for: compiler/rustc_borrowck/src/region_infer/mod.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -1940,7 +1940,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
19401940
target_test: impl Fn(RegionVid) -> bool,
19411941
) -> (BlameConstraint<'tcx>, Vec<OutlivesConstraint<'tcx>>) {
19421942
// Find all paths
1943-
let (path, _) =
1943+
let (path, target_region) =
19441944
self.find_constraint_paths_between_regions(from_region, target_test).unwrap();
19451945
debug!(
19461946
"path={:#?}",
@@ -2060,6 +2060,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20602060
}
20612061
}
20622062

2063+
Some(_)
2064+
if target_region == self.universal_regions().fr_static
2065+
&& let Some(old_best) = path.iter().min_by_key(|p| p.category)
2066+
&& matches!(old_best.category, ConstraintCategory::Cast {
2067+
is_implicit_coercion: true,
2068+
unsize_to: Some(_)
2069+
}) =>
2070+
{
2071+
// FIXME(dianne): This is a hack in order to emit the subdiagnostic
2072+
// `BorrowExplanation::add_object_lifetime_default_note` more often, e.g. on
2073+
// `tests/ui/traits/trait-object-lifetime-default-note.rs`. The subdiagnostic
2074+
// depends on a coercion being blamed, so we fall back to an earlier version of this
2075+
// function's blaming logic to keep the test result the same. A proper fix will
2076+
// require rewriting the subdiagnostic not to rely on a coercion being blamed.
2077+
// For examples of where notes are missing, see #131008 and
2078+
// `tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs`.
2079+
// As part of fixing those, this case should be removed.
2080+
*old_best
2081+
}
2082+
20632083
Some(i) => path[i],
20642084

20652085
None => {

Diff for: tests/ui/dropck/dropck_trait_cycle_checked.stderr

+19-23
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,83 @@ error[E0597]: `o2` does not live long enough
22
--> $DIR/dropck_trait_cycle_checked.rs:111:13
33
|
44
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
5-
| -- binding `o2` declared here
5+
| -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static`
66
LL | o1.set0(&o2);
77
| ^^^ borrowed value does not live long enough
88
...
9-
LL | o3.set0(&o1);
10-
| ------------ argument requires that `o2` is borrowed for `'static`
11-
LL | o3.set1(&o2);
129
LL | }
1310
| - `o2` dropped here while still borrowed
11+
|
12+
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
1413

1514
error[E0597]: `o3` does not live long enough
1615
--> $DIR/dropck_trait_cycle_checked.rs:112:13
1716
|
1817
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
19-
| -- binding `o3` declared here
18+
| -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static`
2019
LL | o1.set0(&o2);
2120
LL | o1.set1(&o3);
2221
| ^^^ borrowed value does not live long enough
2322
...
24-
LL | o3.set0(&o1);
25-
| ------------ argument requires that `o3` is borrowed for `'static`
26-
LL | o3.set1(&o2);
2723
LL | }
2824
| - `o3` dropped here while still borrowed
25+
|
26+
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
2927

3028
error[E0597]: `o2` does not live long enough
3129
--> $DIR/dropck_trait_cycle_checked.rs:113:13
3230
|
3331
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
34-
| -- binding `o2` declared here
35-
LL | o1.set0(&o2);
36-
| ------------ argument requires that `o2` is borrowed for `'static`
37-
LL | o1.set1(&o3);
32+
| -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static`
33+
...
3834
LL | o2.set0(&o2);
3935
| ^^^ borrowed value does not live long enough
4036
...
4137
LL | }
4238
| - `o2` dropped here while still borrowed
39+
|
40+
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
4341

4442
error[E0597]: `o3` does not live long enough
4543
--> $DIR/dropck_trait_cycle_checked.rs:114:13
4644
|
4745
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
48-
| -- binding `o3` declared here
49-
LL | o1.set0(&o2);
50-
| ------------ argument requires that `o3` is borrowed for `'static`
46+
| -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static`
5147
...
5248
LL | o2.set1(&o3);
5349
| ^^^ borrowed value does not live long enough
5450
...
5551
LL | }
5652
| - `o3` dropped here while still borrowed
53+
|
54+
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
5755

5856
error[E0597]: `o1` does not live long enough
5957
--> $DIR/dropck_trait_cycle_checked.rs:115:13
6058
|
6159
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
62-
| -- binding `o1` declared here
63-
LL | o1.set0(&o2);
64-
LL | o1.set1(&o3);
65-
| ------------ argument requires that `o1` is borrowed for `'static`
60+
| -- binding `o1` declared here -------- coercion requires that `o1` is borrowed for `'static`
6661
...
6762
LL | o3.set0(&o1);
6863
| ^^^ borrowed value does not live long enough
6964
LL | o3.set1(&o2);
7065
LL | }
7166
| - `o1` dropped here while still borrowed
67+
|
68+
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
7269

7370
error[E0597]: `o2` does not live long enough
7471
--> $DIR/dropck_trait_cycle_checked.rs:116:13
7572
|
7673
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
77-
| -- binding `o2` declared here
78-
LL | o1.set0(&o2);
79-
LL | o1.set1(&o3);
80-
| ------------ argument requires that `o2` is borrowed for `'static`
74+
| -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static`
8175
...
8276
LL | o3.set1(&o2);
8377
| ^^^ borrowed value does not live long enough
8478
LL | }
8579
| - `o2` dropped here while still borrowed
80+
|
81+
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
8682

8783
error: aborting due to 6 previous errors
8884

Diff for: tests/ui/nll/issue-54779-anon-static-lifetime.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl DebugWith<dyn DebugContext> for Foo {
2929
fmt: &mut std::fmt::Formatter<'_>,
3030
) -> std::fmt::Result {
3131
let Foo { bar } = self;
32-
bar.debug_with(cx); //~ ERROR borrowed data escapes outside of method [E0521]
32+
bar.debug_with(cx); //~ lifetime may not live long enough
3333
Ok(())
3434
}
3535
}

Diff for: tests/ui/nll/issue-54779-anon-static-lifetime.stderr

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
error[E0521]: borrowed data escapes outside of method
2-
--> $DIR/issue-54779-anon-static-lifetime.rs:32:9
1+
error: lifetime may not live long enough
2+
--> $DIR/issue-54779-anon-static-lifetime.rs:32:24
33
|
44
LL | cx: &dyn DebugContext,
5-
| -- - let's call the lifetime of this reference `'1`
6-
| |
7-
| `cx` is a reference that is only valid in the method body
5+
| - let's call the lifetime of this reference `'1`
86
...
97
LL | bar.debug_with(cx);
10-
| ^^^^^^^^^^^^^^^^^^
11-
| |
12-
| `cx` escapes the method body here
13-
| argument requires that `'1` must outlive `'static`
8+
| ^^ coercion requires that `'1` must outlive `'static`
149

1510
error: aborting due to 1 previous error
1611

17-
For more information about this error, try `rustc --explain E0521`.

Diff for: tests/ui/traits/trait-object-lifetime-default-note.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ fn main() {
66
let local = 0; //~ NOTE binding `local` declared here
77
let r = &local; //~ ERROR `local` does not live long enough
88
//~| NOTE borrowed value does not live long enough
9+
//~| NOTE due to object lifetime defaults, `Box<dyn A>` actually means `Box<(dyn A + 'static)>`
910
require_box(Box::new(r));
10-
//~^ NOTE argument requires that `local` is borrowed for `'static`
11+
//~^ NOTE coercion requires that `local` is borrowed for `'static`
1112

1213
let _ = 0;
1314
} //~ NOTE `local` dropped here while still borrowed

Diff for: tests/ui/traits/trait-object-lifetime-default-note.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ LL | let local = 0;
55
| ----- binding `local` declared here
66
LL | let r = &local;
77
| ^^^^^^ borrowed value does not live long enough
8-
LL |
8+
...
99
LL | require_box(Box::new(r));
10-
| ------------------------ argument requires that `local` is borrowed for `'static`
10+
| ----------- coercion requires that `local` is borrowed for `'static`
1111
...
1212
LL | }
1313
| - `local` dropped here while still borrowed
14+
|
15+
= note: due to object lifetime defaults, `Box<dyn A>` actually means `Box<(dyn A + 'static)>`
1416

1517
error: aborting due to 1 previous error
1618

0 commit comments

Comments
 (0)