Skip to content

Commit 888d157

Browse files
Rollup merge of #128753 - compiler-errors:arbitrary-upper, r=spastorino
Don't arbitrarily choose one upper bound for hidden captured region error message You could argue that the error message is objectively worse, even though it's more accurate. I guess we could also add a note explaining like "cannot capture the intersection of two regions" or something, though I'm not sure if that is confusing due to being totally technical jargon. This addresses the fact that #128752 says "add `+ 'b`" even though it does nothing to fix the issue. It doesn't fix the issue's root cause, though. r? `@spastorino`
2 parents f739c00 + c656ce7 commit 888d157

File tree

6 files changed

+68
-36
lines changed

6 files changed

+68
-36
lines changed

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

+20-15
Original file line numberDiff line numberDiff line change
@@ -225,21 +225,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
225225

226226
// Find something that we can name
227227
let upper_bound = self.approx_universal_upper_bound(vid);
228-
let upper_bound = &self.definitions[upper_bound];
229-
match upper_bound.external_name {
230-
Some(reg) => reg,
231-
None => {
232-
// Nothing exact found, so we pick the first one that we find.
233-
let scc = self.constraint_sccs.scc(vid);
234-
for vid in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
235-
match self.definitions[vid].external_name {
236-
None => {}
237-
Some(region) if region.is_static() => {}
238-
Some(region) => return region,
239-
}
240-
}
241-
region
242-
}
228+
if let Some(universal_region) = self.definitions[upper_bound].external_name {
229+
return universal_region;
230+
}
231+
232+
// Nothing exact found, so we pick a named upper bound, if there's only one.
233+
// If there's >1 universal region, then we probably are dealing w/ an intersection
234+
// region which cannot be mapped back to a universal.
235+
// FIXME: We could probably compute the LUB if there is one.
236+
let scc = self.constraint_sccs.scc(vid);
237+
let upper_bounds: Vec<_> = self
238+
.rev_scc_graph
239+
.as_ref()
240+
.unwrap()
241+
.upper_bounds(scc)
242+
.filter_map(|vid| self.definitions[vid].external_name)
243+
.filter(|r| !r.is_static())
244+
.collect();
245+
match &upper_bounds[..] {
246+
[universal_region] => *universal_region,
247+
_ => region,
243248
}
244249
}
245250
_ => region,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#![feature(precise_capturing)]
2+
3+
use std::future::Future;
4+
use std::pin::Pin;
5+
6+
trait MyTrait {
7+
fn foo<'a, 'b>(&'a self, x: &'b i32) -> impl Future<Output = i32>;
8+
}
9+
10+
trait ErasedMyTrait {
11+
fn foo<'life0, 'life1, 'dynosaur>(&'life0 self, x: &'life1 i32)
12+
-> Pin<Box<dyn Future<Output = i32> + 'dynosaur>>
13+
where
14+
'life0: 'dynosaur,
15+
'life1: 'dynosaur;
16+
}
17+
18+
struct DynMyTrait<T: ErasedMyTrait> {
19+
ptr: T,
20+
}
21+
22+
impl<T: ErasedMyTrait> MyTrait for DynMyTrait<T> {
23+
fn foo<'a, 'b>(&'a self, x: &'b i32) -> impl Future<Output = i32> {
24+
self.ptr.foo(x)
25+
//~^ ERROR hidden type for `impl Future<Output = i32>` captures lifetime that does not appear in bounds
26+
}
27+
}
28+
29+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0700]: hidden type for `impl Future<Output = i32>` captures lifetime that does not appear in bounds
2+
--> $DIR/cannot-capture-intersection.rs:24:9
3+
|
4+
LL | fn foo<'a, 'b>(&'a self, x: &'b i32) -> impl Future<Output = i32> {
5+
| ------------------------- opaque type defined here
6+
LL | self.ptr.foo(x)
7+
| ^^^^^^^^^^^^^^^
8+
|
9+
= note: hidden type `Pin<Box<dyn Future<Output = i32>>>` captures lifetime `'_`
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0700`.

Diff for: tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr

+2-7
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,12 @@ error[E0700]: hidden type for `impl Trait<'d, 'e>` captures lifetime that does n
22
--> $DIR/ordinary-bounds-unrelated.rs:28:33
33
|
44
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
5-
| -- ------------------ opaque type defined here
6-
| |
7-
| hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
5+
| ------------------ opaque type defined here
86
...
97
LL | if condition() { a } else { b }
108
| ^
119
|
12-
help: to declare that `impl Trait<'d, 'e>` captures `'b`, you can add an explicit `'b` lifetime bound
13-
|
14-
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + 'b
15-
| ++++
10+
= note: hidden type `Ordinary<'_>` captures lifetime `'_`
1611

1712
error: aborting due to 1 previous error
1813

Diff for: tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr

+2-7
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,12 @@ error[E0700]: hidden type for `impl Trait<'a, 'b>` captures lifetime that does n
22
--> $DIR/ordinary-bounds-unsuited.rs:31:33
33
|
44
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
5-
| -- ------------------ opaque type defined here
6-
| |
7-
| hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
5+
| ------------------ opaque type defined here
86
...
97
LL | if condition() { a } else { b }
108
| ^
119
|
12-
help: to declare that `impl Trait<'a, 'b>` captures `'b`, you can add an explicit `'b` lifetime bound
13-
|
14-
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> + 'b
15-
| ++++
10+
= note: hidden type `Ordinary<'_>` captures lifetime `'_`
1611

1712
error: aborting due to 1 previous error
1813

Diff for: tests/ui/suggestions/lifetimes/explicit-lifetime-suggestion-in-proper-span-issue-121267.stderr

+2-7
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,13 @@ error[E0700]: hidden type for `impl Iterator<Item = i32>` captures lifetime that
22
--> $DIR/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs:7:5
33
|
44
LL | fn bar(src: &crate::Foo) -> impl Iterator<Item = i32> {
5-
| ---------- ------------------------- opaque type defined here
6-
| |
7-
| hidden type `FilterMap<std::slice::Iter<'static, i32>, {closure@$DIR/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs:9:21: 9:24}>` captures the anonymous lifetime defined here
5+
| ------------------------- opaque type defined here
86
LL | / [0].into_iter()
97
LL | |
108
LL | | .filter_map(|_| foo(src))
119
| |_________________________________^
1210
|
13-
help: to declare that `impl Iterator<Item = i32>` captures `'_`, you can introduce a named lifetime parameter `'a`
14-
|
15-
LL | fn bar<'a>(src: &'a crate::Foo<'a>) -> impl Iterator<Item = i32> + 'a {
16-
| ++++ ++ ++++ ++++
11+
= note: hidden type `FilterMap<std::slice::Iter<'static, i32>, {closure@$DIR/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs:9:21: 9:24}>` captures lifetime `'_`
1712

1813
error: aborting due to 1 previous error
1914

0 commit comments

Comments
 (0)