Skip to content

Commit

Permalink
Rollup merge of rust-lang#128753 - compiler-errors:arbitrary-upper, r…
Browse files Browse the repository at this point in the history
…=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 rust-lang#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`
  • Loading branch information
GuillaumeGomez committed Aug 7, 2024
2 parents f739c00 + c656ce7 commit 888d157
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 36 deletions.
35 changes: 20 additions & 15 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,21 +225,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {

// Find something that we can name
let upper_bound = self.approx_universal_upper_bound(vid);
let upper_bound = &self.definitions[upper_bound];
match upper_bound.external_name {
Some(reg) => reg,
None => {
// Nothing exact found, so we pick the first one that we find.
let scc = self.constraint_sccs.scc(vid);
for vid in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
match self.definitions[vid].external_name {
None => {}
Some(region) if region.is_static() => {}
Some(region) => return region,
}
}
region
}
if let Some(universal_region) = self.definitions[upper_bound].external_name {
return universal_region;
}

// Nothing exact found, so we pick a named upper bound, if there's only one.
// If there's >1 universal region, then we probably are dealing w/ an intersection
// region which cannot be mapped back to a universal.
// FIXME: We could probably compute the LUB if there is one.
let scc = self.constraint_sccs.scc(vid);
let upper_bounds: Vec<_> = self
.rev_scc_graph
.as_ref()
.unwrap()
.upper_bounds(scc)
.filter_map(|vid| self.definitions[vid].external_name)
.filter(|r| !r.is_static())
.collect();
match &upper_bounds[..] {
[universal_region] => *universal_region,
_ => region,
}
}
_ => region,
Expand Down
29 changes: 29 additions & 0 deletions tests/ui/impl-trait/in-trait/cannot-capture-intersection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#![feature(precise_capturing)]

use std::future::Future;
use std::pin::Pin;

trait MyTrait {
fn foo<'a, 'b>(&'a self, x: &'b i32) -> impl Future<Output = i32>;
}

trait ErasedMyTrait {
fn foo<'life0, 'life1, 'dynosaur>(&'life0 self, x: &'life1 i32)
-> Pin<Box<dyn Future<Output = i32> + 'dynosaur>>
where
'life0: 'dynosaur,
'life1: 'dynosaur;
}

struct DynMyTrait<T: ErasedMyTrait> {
ptr: T,
}

impl<T: ErasedMyTrait> MyTrait for DynMyTrait<T> {
fn foo<'a, 'b>(&'a self, x: &'b i32) -> impl Future<Output = i32> {
self.ptr.foo(x)
//~^ ERROR hidden type for `impl Future<Output = i32>` captures lifetime that does not appear in bounds
}
}

fn main() {}
13 changes: 13 additions & 0 deletions tests/ui/impl-trait/in-trait/cannot-capture-intersection.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error[E0700]: hidden type for `impl Future<Output = i32>` captures lifetime that does not appear in bounds
--> $DIR/cannot-capture-intersection.rs:24:9
|
LL | fn foo<'a, 'b>(&'a self, x: &'b i32) -> impl Future<Output = i32> {
| ------------------------- opaque type defined here
LL | self.ptr.foo(x)
| ^^^^^^^^^^^^^^^
|
= note: hidden type `Pin<Box<dyn Future<Output = i32>>>` captures lifetime `'_`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0700`.
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@ error[E0700]: hidden type for `impl Trait<'d, 'e>` captures lifetime that does n
--> $DIR/ordinary-bounds-unrelated.rs:28:33
|
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
| -- ------------------ opaque type defined here
| |
| hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
| ------------------ opaque type defined here
...
LL | if condition() { a } else { b }
| ^
|
help: to declare that `impl Trait<'d, 'e>` captures `'b`, you can add an explicit `'b` lifetime bound
|
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + 'b
| ++++
= note: hidden type `Ordinary<'_>` captures lifetime `'_`

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@ error[E0700]: hidden type for `impl Trait<'a, 'b>` captures lifetime that does n
--> $DIR/ordinary-bounds-unsuited.rs:31:33
|
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
| -- ------------------ opaque type defined here
| |
| hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
| ------------------ opaque type defined here
...
LL | if condition() { a } else { b }
| ^
|
help: to declare that `impl Trait<'a, 'b>` captures `'b`, you can add an explicit `'b` lifetime bound
|
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> + 'b
| ++++
= note: hidden type `Ordinary<'_>` captures lifetime `'_`

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@ error[E0700]: hidden type for `impl Iterator<Item = i32>` captures lifetime that
--> $DIR/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs:7:5
|
LL | fn bar(src: &crate::Foo) -> impl Iterator<Item = i32> {
| ---------- ------------------------- opaque type defined here
| |
| 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
| ------------------------- opaque type defined here
LL | / [0].into_iter()
LL | |
LL | | .filter_map(|_| foo(src))
| |_________________________________^
|
help: to declare that `impl Iterator<Item = i32>` captures `'_`, you can introduce a named lifetime parameter `'a`
|
LL | fn bar<'a>(src: &'a crate::Foo<'a>) -> impl Iterator<Item = i32> + 'a {
| ++++ ++ ++++ ++++
= 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 `'_`

error: aborting due to 1 previous error

Expand Down

0 comments on commit 888d157

Please sign in to comment.