Skip to content

Commit 889e047

Browse files
committed
Auto merge of rust-lang#133858 - dianne:better-blame-constraints-for-static, r=<try>
`best_blame_constraint`: Blame better constraints when failing to outlive `'static` This fixes rust-lang#132749 by changing which constraint is blamed for region errors when failing to prove a region outlives `'static`. The comments give a better explanation, but very roughly, all the `'static: R` edges in the region graph made `best_blame_constraint` consider every constraint (other than those from ascriptions, returns, and yields) uninteresting to point to, so it chose semi-randomly based on an ordering of how interesting each variant of `ConstraintCategory` is expected to be. This PR (admittedly hackily) makes it ignore all those edges, so that the existing logic works the same as it would when failing to outlive any other region. Looking at UI test diffs, most of them that changed I think changed for the better. Unfortunately, since a lot of borrowck's diagnostics depend on exactly which constraint is blamed, some things broke. A list of what I'm not happy with: - For `CopyBound` constraints, e.g. [`tests/ui/nll/do-not-ignore-lifetime-bounds-in-copy.stderr`](https://github.com/rust-lang/rust/compare/master...dianne:rust:better-blame-constraints-for-static?expand=1#diff-e220f1e433c5e48d9afd431787f6ff27fc66b653762ee8a0283e370c2d88e7d0), I think it's helpful to surface that the `Copy` impl introduces the bound. If this is an issue, maybe it's worth prioritizing it or adding a variant of `ExtraConstraintInfo` for it. - Likewise for `UseAsConst` and `UseAsStatic`; I've already added a special case for those. Without a special case, this was blaming `CallArgument` in [`tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr`](https://github.com/dianne/rust/blob/189b2f892e6d0809a77fc92fe1108a07d8de9be0/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr#L38), which seemed pretty egregious. I'm assuming we want to blame `UseAsConst`/`UseAsStatic` when possible, rather than add something to `ExtraConstraintInfo`, since it's pretty unambiguously to-blame for "outlives `'static`" constraints. The special-casing admittedly also changes the output for [`tests/ui/inline-const/const-match-pat-lifetime-err.rs`](https://github.com/rust-lang/rust/compare/master...dianne:rust:better-blame-constraints-for-static?expand=1#diff-e4d2c147aa96dd8dd963ec3d98ead9a8096c9de809d19ab379be3c53951ca1ca), but I think the new output there is fine; it's more direct about how `'a` and `'static` are getting related. - The subdiagnostic [`BorrowExplanation::add_object_lifetime_default_note`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/diagnostics/explain_borrow/enum.BorrowExplanation.html#method.add_object_lifetime_default_note) depends on `Cast` being reported as the constraint category, so I've added a special case for it to keep it disappearing from [`tests/ui/traits/trait-object-lifetime-default-note.stderr`](https://github.com/dianne/rust/blob/better-blame-constraints-for-static/tests/ui/traits/trait-object-lifetime-default-note.stderr)[^1] . As I've outlined in a `FIXME` comment though, I think that subdiagnostic needs changing. There's multiple cases throughout `tests/ui` where it would be helpful, but doesn't fire, because a different constraint is picked. rust-lang#131008 would also benefit from that note, but there's not a coercion there at all. I tried making it fire in more cases, but fundamentally, since it doesn't *actually* check if an object lifetime default was used in the HIR, it produced some extraneous notes[^2]. I tried seeing if it'd be easy enough to fix that first, but it seems nontrivial[^3] enough to warrant a separate PR. A final note: this may have perf consequences, since `best_blame_constraint` gets called on happy code too. If it's an issue, I can try to make it faster, or only do the expensive stuff when an error's been hit, or something. If nothing else, this makes the fallback logic (still relevant for invariant lifetimes[^4]) a bit faster. [^1]: Incidentally, without the special-casing, this would pick `CallArgument`, which I think produces a nicer message, apart from the missing note. [^2]: There's even some in current UI test output: [`tests/ui/borrowck/two-phase-surprise-no-conflict.stderr`](https://github.com/rust-lang/rust/blob/733616f7236b4be140ce851a30b3bb06532b9364/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr#L68). The object lifetime is [explicitly provided](https://github.com/rust-lang/rust/blob/733616f7236b4be140ce851a30b3bb06532b9364/tests/ui/borrowck/two-phase-surprise-no-conflict.rs#L94), and despite the note, it's not `'static`. [^3]: In case anyone reading this has advice: ultimately I think there has to be a choice between extraneous notes and missing notes unless "this object type had a missing lifetime in the HIR" is in crate metadata for some reason, since rustdoc doesn't elaborate object lifetime defaults, and the note is potentially helpful for library-users who may be wondering where a `'static` lifetime came from. That said, it's a bit confusing to point out lifetime defaults when they're not relevant[^5], so it's at least worth a best effort to look at user annotations. However, the HIR missing an object lifetime could be anywhere: a cast, an ascription, in the return type, in an input, in the signature for a function that's called, in an ADT field, in a type alias... I've considered looking at the entire output of `RegionInferenceContext::find_constraint_path_between_regions` and doing a best-effort association between typeck results (ideally MIR typeck for the region information) and whatever HIR seems relevant. But that seems like a lot of work for that note. [^4]: Cycles in the region graph due to invariance also confuse `better_blame_constraint`'s attempt to pick a constraint where the regions aren't unified. I'm not sure if there's a better heuristic to use there, though; I played around a bit with it, but my experiments only made diagnostic output worse. [^5]: Unless maybe there's a way of rewording the note so that it always makes sense to output when object lifetimes are involved in region errors?
2 parents acabb52 + 189b2f8 commit 889e047

23 files changed

+147
-111
lines changed

compiler/rustc_borrowck/src/region_infer/mod.rs

+37-9
Original file line numberDiff line numberDiff line change
@@ -2027,7 +2027,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20272027
// most likely to be the point where the value escapes -- but
20282028
// we still want to screen for an "interesting" point to
20292029
// highlight (e.g., a call site or something).
2030-
let target_scc = self.constraint_sccs.scc(target_region);
2030+
// As a special case, if the target region is 'static, it will always outlive the source,
2031+
// so they'll be in the same SCC. To get better diagnostics, we pretend those `'static: R`
2032+
// edges don't exist and use the resulting graph's SCCs.
2033+
let target_is_static = target_region == self.universal_regions().fr_static;
2034+
let sccs_without_static = target_is_static
2035+
.then(|| self.constraints.compute_sccs(RegionVid::MAX, &self.definitions));
2036+
let constraint_sccs = sccs_without_static.as_ref().unwrap_or(&self.constraint_sccs);
2037+
let target_scc = constraint_sccs.scc(target_region);
20312038
let mut range = 0..path.len();
20322039

20332040
// As noted above, when reporting an error, there is typically a chain of constraints
@@ -2075,7 +2082,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20752082
let find_region = |i: &usize| {
20762083
let constraint = &path[*i];
20772084

2078-
let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup);
2085+
let constraint_sup_scc = constraint_sccs.scc(constraint.sup);
20792086

20802087
if blame_source {
20812088
match categorized_path[*i].category {
@@ -2133,17 +2140,38 @@ impl<'tcx> RegionInferenceContext<'tcx> {
21332140
}
21342141
}
21352142

2143+
// If an "outlives 'static" constraint was from use as a const or static, blame that.
2144+
if target_is_static
2145+
&& blame_source
2146+
&& let Some(old_best) = categorized_path.iter().min_by_key(|p| p.category)
2147+
&& matches!(
2148+
old_best.category,
2149+
ConstraintCategory::UseAsConst
2150+
| ConstraintCategory::UseAsStatic
2151+
| ConstraintCategory::Cast {
2152+
is_implicit_coercion: true,
2153+
unsize_to: Some(_)
2154+
}
2155+
)
2156+
{
2157+
// FIXME(dianne): `BorrowExplanation::add_object_lifetime_default_note` depends on a
2158+
// coercion being blamed, so revert to the old blaming logic to prioritize that.
2159+
// The note's logic should be reworked, though; it's flaky (#131008 doesn't have a
2160+
// coercion, and even with this hack, one isn't always blamed when present).
2161+
// Only checking for a coercion also makes the note appear where it shouldn't
2162+
// shouldn't (e.g. `tests/ui/borrowck/two-phase-surprise-no-conflict.stderr`).
2163+
return (old_best.clone(), extra_info);
2164+
}
2165+
21362166
return (categorized_path[i].clone(), extra_info);
21372167
}
21382168

2139-
// If that search fails, that is.. unusual. Maybe everything
2140-
// is in the same SCC or something. In that case, find what
2141-
// appears to be the most interesting point to report to the
2142-
// user via an even more ad-hoc guess.
2143-
categorized_path.sort_by_key(|p| p.category);
2144-
debug!("sorted_path={:#?}", categorized_path);
2169+
// If that search fails, everything may be in the same SCC. In particular, this will be the
2170+
// case when dealing with invariant lifetimes. Find what appears to be the most interesting
2171+
// point to report to the user via an even more ad-hoc guess.
2172+
let best_choice = categorized_path.into_iter().min_by_key(|p| p.category).unwrap();
21452173

2146-
(categorized_path.remove(0), extra_info)
2174+
(best_choice, extra_info)
21472175
}
21482176

21492177
pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {

tests/ui/borrowck/fn-item-check-type-params.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ LL | extend_lt(val);
1212
| argument requires that `'a` must outlive `'static`
1313

1414
error: lifetime may not live long enough
15-
--> $DIR/fn-item-check-type-params.rs:39:12
15+
--> $DIR/fn-item-check-type-params.rs:39:31
1616
|
1717
LL | pub fn test_coercion<'a>() {
1818
| -- lifetime `'a` defined here
1919
LL | let _: fn(&'a str) -> _ = extend_lt;
20-
| ^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
20+
| ^^^^^^^^^ coercion requires that `'a` must outlive `'static`
2121

2222
error[E0716]: temporary value dropped while borrowed
2323
--> $DIR/fn-item-check-type-params.rs:48:11

tests/ui/coroutine/resume-arg-outlives-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ fn demo<'not_static>(s: &'not_static str) -> thread::JoinHandle<()> {
1818
// exploit:
1919
generator.as_mut().resume("");
2020
generator.as_mut().resume(s); // <- generator hoards it as `let ctx`.
21-
//~^ ERROR borrowed data escapes outside of function
2221
thread::spawn(move || {
22+
//~^ ERROR borrowed data escapes outside of function
2323
thread::sleep(time::Duration::from_millis(200));
2424
generator.as_mut().resume(""); // <- resumes from the last `yield`, running `dbg!(ctx)`.
2525
})

tests/ui/coroutine/resume-arg-outlives-2.stderr

+14-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
error[E0521]: borrowed data escapes outside of function
2-
--> $DIR/resume-arg-outlives-2.rs:20:5
2+
--> $DIR/resume-arg-outlives-2.rs:21:5
33
|
4-
LL | fn demo<'not_static>(s: &'not_static str) -> thread::JoinHandle<()> {
5-
| ----------- - `s` is a reference that is only valid in the function body
6-
| |
7-
| lifetime `'not_static` defined here
4+
LL | fn demo<'not_static>(s: &'not_static str) -> thread::JoinHandle<()> {
5+
| ----------- - `s` is a reference that is only valid in the function body
6+
| |
7+
| lifetime `'not_static` defined here
88
...
9-
LL | generator.as_mut().resume(s); // <- generator hoards it as `let ctx`.
10-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11-
| |
12-
| `s` escapes the function body here
13-
| argument requires that `'not_static` must outlive `'static`
9+
LL | / thread::spawn(move || {
10+
LL | |
11+
LL | | thread::sleep(time::Duration::from_millis(200));
12+
LL | | generator.as_mut().resume(""); // <- resumes from the last `yield`, running `dbg!(ctx)`.
13+
LL | | })
14+
| | ^
15+
| | |
16+
| |______`s` escapes the function body here
17+
| argument requires that `'not_static` must outlive `'static`
1418

1519
error: aborting due to 1 previous error
1620

tests/ui/impl-trait/precise-capturing/migration-note.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ fn needs_static() {
2929
let a = display_len(&x);
3030
//~^ ERROR `x` does not live long enough
3131
//~| NOTE this call may capture more lifetimes than intended
32-
//~| NOTE argument requires that `x` is borrowed for `'static`
3332
//~| NOTE borrowed value does not live long enoug
3433

3534
fn needs_static(_: impl Sized + 'static) {}
3635
needs_static(a);
36+
//~^ NOTE argument requires that `x` is borrowed for `'static`
3737
}
3838
//~^ NOTE `x` dropped here while still borrowed
3939

@@ -76,11 +76,11 @@ fn needs_static_mut() {
7676
let a = display_len_mut(&mut x);
7777
//~^ ERROR `x` does not live long enough
7878
//~| NOTE this call may capture more lifetimes than intended
79-
//~| NOTE argument requires that `x` is borrowed for `'static`
8079
//~| NOTE borrowed value does not live long enough
8180

8281
fn needs_static(_: impl Sized + 'static) {}
8382
needs_static(a);
83+
//~^ NOTE argument requires that `x` is borrowed for `'static`
8484
}
8585
//~^ NOTE `x` dropped here while still borrowed
8686

tests/ui/impl-trait/precise-capturing/migration-note.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ LL | let x = vec![1];
4242
| - binding `x` declared here
4343
LL |
4444
LL | let a = display_len(&x);
45-
| ------------^^-
46-
| | |
47-
| | borrowed value does not live long enough
48-
| argument requires that `x` is borrowed for `'static`
45+
| ^^ borrowed value does not live long enough
4946
...
47+
LL | needs_static(a);
48+
| --------------- argument requires that `x` is borrowed for `'static`
49+
LL |
5050
LL | }
5151
| - `x` dropped here while still borrowed
5252
|
@@ -118,11 +118,11 @@ LL | let mut x = vec![1];
118118
| ----- binding `x` declared here
119119
LL |
120120
LL | let a = display_len_mut(&mut x);
121-
| ----------------^^^^^^-
122-
| | |
123-
| | borrowed value does not live long enough
124-
| argument requires that `x` is borrowed for `'static`
121+
| ^^^^^^ borrowed value does not live long enough
125122
...
123+
LL | needs_static(a);
124+
| --------------- argument requires that `x` is borrowed for `'static`
125+
LL |
126126
LL | }
127127
| - `x` dropped here while still borrowed
128128
|

tests/ui/inline-const/const-match-pat-lifetime-err.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ fn match_covariant_ref<'a>() {
3535
// `y.0`), but using the associated const directly in the pattern also
3636
// errors.
3737
let y: (CovariantRef<'static, _>,) = (CovariantRef(&()),);
38-
//~^ ERROR lifetime may not live long enough
3938
match y.0 {
4039
const { CovariantRef::<'a>::NEW } => (),
40+
//~^ ERROR lifetime may not live long enough
4141
}
4242
}
4343

tests/ui/inline-const/const-match-pat-lifetime-err.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ LL | }
1515
| - `y` dropped here while still borrowed
1616

1717
error: lifetime may not live long enough
18-
--> $DIR/const-match-pat-lifetime-err.rs:37:12
18+
--> $DIR/const-match-pat-lifetime-err.rs:39:17
1919
|
2020
LL | fn match_covariant_ref<'a>() {
2121
| -- lifetime `'a` defined here
2222
...
23-
LL | let y: (CovariantRef<'static, _>,) = (CovariantRef(&()),);
24-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
23+
LL | const { CovariantRef::<'a>::NEW } => (),
24+
| ^^^^^^^^^^^^^^^^^^^^^^^ using this value as a constant requires that `'a` must outlive `'static`
2525

2626
error: aborting due to 2 previous errors
2727

tests/ui/kindck/kindck-impl-type-params.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,13 @@ LL | struct Foo; // does not impl Copy
112112
|
113113

114114
error: lifetime may not live long enough
115-
--> $DIR/kindck-impl-type-params.rs:30:19
115+
--> $DIR/kindck-impl-type-params.rs:30:13
116116
|
117117
LL | fn foo<'a>() {
118118
| -- lifetime `'a` defined here
119119
LL | let t: S<&'a isize> = S(marker::PhantomData);
120120
LL | let a = &t as &dyn Gettable<&'a isize>;
121-
| ^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
121+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static`
122122

123123
error: aborting due to 7 previous errors
124124

tests/ui/lifetimes/issue-90600-expected-return-static-indirect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ fn inner(mut foo: &[u8]) {
77
let refcell = RefCell::new(&mut foo);
88
//~^ ERROR `foo` does not live long enough
99
let read = &refcell as &RefCell<dyn Read>;
10-
//~^ ERROR lifetime may not live long enough
1110

1211
read_thing(read);
12+
//~^ ERROR lifetime may not live long enough
1313
}
1414

1515
fn read_thing(refcell: &RefCell<dyn Read>) {}

tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@ LL | fn inner(mut foo: &[u8]) {
55
| ------- binding `foo` declared here
66
LL | let refcell = RefCell::new(&mut foo);
77
| ^^^^^^^^ borrowed value does not live long enough
8-
LL |
9-
LL | let read = &refcell as &RefCell<dyn Read>;
10-
| ------------------------------ cast requires that `foo` is borrowed for `'static`
118
...
9+
LL | read_thing(read);
10+
| ---- coercion requires that `foo` is borrowed for `'static`
11+
LL |
1212
LL | }
1313
| - `foo` dropped here while still borrowed
1414

1515
error: lifetime may not live long enough
16-
--> $DIR/issue-90600-expected-return-static-indirect.rs:9:16
16+
--> $DIR/issue-90600-expected-return-static-indirect.rs:11:16
1717
|
1818
LL | fn inner(mut foo: &[u8]) {
1919
| - let's call the lifetime of this reference `'1`
2020
...
21-
LL | let read = &refcell as &RefCell<dyn Read>;
22-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
21+
LL | read_thing(read);
22+
| ^^^^ coercion requires that `'1` must outlive `'static`
2323

2424
error: aborting due to 2 previous errors
2525

tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ error[E0597]: `a` does not live long enough
5656
LL | let a = 0;
5757
| - binding `a` declared here
5858
LL | let cell = Cell::new(&a);
59-
| ----------^^-
60-
| | |
61-
| | borrowed value does not live long enough
62-
| argument requires that `a` is borrowed for `'static`
59+
| ^^ borrowed value does not live long enough
6360
...
61+
LL | cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static -> borrow error
62+
| ------------------------ argument requires that `a` is borrowed for `'static`
63+
LL | })
6464
LL | }
6565
| - `a` dropped here while still borrowed
6666

tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,9 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3
3030
#[rustc_regions]
3131
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
3232
establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
33-
//~^ ERROR borrowed data escapes outside of function
34-
3533
// Only works if 'x: 'y:
3634
demand_y(x, y, x.get())
35+
//~^ ERROR borrowed data escapes outside of function
3736
});
3837
}
3938

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

+11-19
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,18 @@ LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
2323
= note: defining type: supply
2424

2525
error[E0521]: borrowed data escapes outside of function
26-
--> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:32:5
26+
--> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:34:9
2727
|
28-
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
29-
| -- ------ `cell_a` is a reference that is only valid in the function body
30-
| |
31-
| lifetime `'a` defined here
32-
LL | / establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
33-
LL | |
34-
LL | |
35-
LL | | // Only works if 'x: 'y:
36-
LL | | demand_y(x, y, x.get())
37-
LL | | });
38-
| | ^
39-
| | |
40-
| |______`cell_a` escapes the function body here
41-
| argument requires that `'a` must outlive `'static`
42-
|
43-
= note: requirement occurs because of the type `Cell<&'?9 u32>`, which makes the generic argument `&'?9 u32` invariant
44-
= note: the struct `Cell<T>` is invariant over the parameter `T`
45-
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
28+
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
29+
| -- ------ `cell_a` is a reference that is only valid in the function body
30+
| |
31+
| lifetime `'a` defined here
32+
...
33+
LL | demand_y(x, y, x.get())
34+
| ^^^^^^^^^^^^^^^^^^^^^^^
35+
| |
36+
| `cell_a` escapes the function body here
37+
| argument requires that `'a` must outlive `'static`
4638

4739
error: aborting due to 1 previous error
4840

tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,9 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3
3333
#[rustc_regions]
3434
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
3535
establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
36-
//~^ ERROR borrowed data escapes outside of function
37-
3836
// Only works if 'x: 'y:
3937
demand_y(x, y, x.get())
38+
//~^ ERROR borrowed data escapes outside of function
4039
});
4140
}
4241

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

+11-19
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,18 @@ LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
2323
= note: defining type: supply
2424

2525
error[E0521]: borrowed data escapes outside of function
26-
--> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:35:5
26+
--> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:37:9
2727
|
28-
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
29-
| -- ------ `cell_a` is a reference that is only valid in the function body
30-
| |
31-
| lifetime `'a` defined here
32-
LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
33-
LL | |
34-
LL | |
35-
LL | | // Only works if 'x: 'y:
36-
LL | | demand_y(x, y, x.get())
37-
LL | | });
38-
| | ^
39-
| | |
40-
| |______`cell_a` escapes the function body here
41-
| argument requires that `'a` must outlive `'static`
42-
|
43-
= note: requirement occurs because of the type `Cell<&'?10 u32>`, which makes the generic argument `&'?10 u32` invariant
44-
= note: the struct `Cell<T>` is invariant over the parameter `T`
45-
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
28+
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
29+
| -- ------ `cell_a` is a reference that is only valid in the function body
30+
| |
31+
| lifetime `'a` defined here
32+
...
33+
LL | demand_y(x, y, x.get())
34+
| ^^^^^^^^^^^^^^^^^^^^^^^
35+
| |
36+
| `cell_a` escapes the function body here
37+
| argument requires that `'a` must outlive `'static`
4638

4739
error: aborting due to 1 previous error
4840

tests/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.stderr

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ error[E0597]: `s` does not live long enough
44
LL | let s = 2;
55
| - binding `s` declared here
66
LL | let a = (Foo(&s),);
7-
| ^^ borrowed value does not live long enough
8-
LL | drop(a.0);
9-
| --- copying this value requires that `s` is borrowed for `'static`
10-
LL | drop(a.0);
7+
| -----^^---
8+
| | |
9+
| | borrowed value does not live long enough
10+
| assignment requires that `s` is borrowed for `'static`
11+
...
1112
LL | }
1213
| - `s` dropped here while still borrowed
1314

0 commit comments

Comments
 (0)