Skip to content

Commit

Permalink
Don't arbitrarily choose one upper bound for hidden captured region
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Aug 6, 2024
1 parent 60d1465 commit c656ce7
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 c656ce7

Please sign in to comment.