mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Don't arbitrarily choose one upper bound for hidden captured region
This commit is contained in:
parent
60d146580c
commit
c656ce7aeb
@ -225,21 +225,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||||||
|
|
||||||
// Find something that we can name
|
// Find something that we can name
|
||||||
let upper_bound = self.approx_universal_upper_bound(vid);
|
let upper_bound = self.approx_universal_upper_bound(vid);
|
||||||
let upper_bound = &self.definitions[upper_bound];
|
if let Some(universal_region) = self.definitions[upper_bound].external_name {
|
||||||
match upper_bound.external_name {
|
return universal_region;
|
||||||
Some(reg) => reg,
|
}
|
||||||
None => {
|
|
||||||
// Nothing exact found, so we pick the first one that we find.
|
// 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 scc = self.constraint_sccs.scc(vid);
|
||||||
for vid in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
|
let upper_bounds: Vec<_> = self
|
||||||
match self.definitions[vid].external_name {
|
.rev_scc_graph
|
||||||
None => {}
|
.as_ref()
|
||||||
Some(region) if region.is_static() => {}
|
.unwrap()
|
||||||
Some(region) => return region,
|
.upper_bounds(scc)
|
||||||
}
|
.filter_map(|vid| self.definitions[vid].external_name)
|
||||||
}
|
.filter(|r| !r.is_static())
|
||||||
region
|
.collect();
|
||||||
}
|
match &upper_bounds[..] {
|
||||||
|
[universal_region] => *universal_region,
|
||||||
|
_ => region,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => region,
|
_ => region,
|
||||||
|
29
tests/ui/impl-trait/in-trait/cannot-capture-intersection.rs
Normal file
29
tests/ui/impl-trait/in-trait/cannot-capture-intersection.rs
Normal file
@ -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() {}
|
@ -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`.
|
@ -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
|
--> $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>
|
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
|
||||||
| -- ------------------ opaque type defined here
|
| ------------------ opaque type defined here
|
||||||
| |
|
|
||||||
| hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
|
|
||||||
...
|
...
|
||||||
LL | if condition() { a } else { b }
|
LL | if condition() { a } else { b }
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
help: to declare that `impl Trait<'d, 'e>` captures `'b`, you can add an explicit `'b` lifetime bound
|
= note: hidden type `Ordinary<'_>` captures lifetime `'_`
|
||||||
|
|
|
||||||
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> + 'b
|
|
||||||
| ++++
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -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
|
--> $DIR/ordinary-bounds-unsuited.rs:31:33
|
||||||
|
|
|
|
||||||
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
|
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
|
||||||
| -- ------------------ opaque type defined here
|
| ------------------ opaque type defined here
|
||||||
| |
|
|
||||||
| hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
|
|
||||||
...
|
...
|
||||||
LL | if condition() { a } else { b }
|
LL | if condition() { a } else { b }
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
help: to declare that `impl Trait<'a, 'b>` captures `'b`, you can add an explicit `'b` lifetime bound
|
= note: hidden type `Ordinary<'_>` captures lifetime `'_`
|
||||||
|
|
|
||||||
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> + 'b
|
|
||||||
| ++++
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -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
|
--> $DIR/explicit-lifetime-suggestion-in-proper-span-issue-121267.rs:7:5
|
||||||
|
|
|
|
||||||
LL | fn bar(src: &crate::Foo) -> impl Iterator<Item = i32> {
|
LL | fn bar(src: &crate::Foo) -> impl Iterator<Item = i32> {
|
||||||
| ---------- ------------------------- opaque type defined here
|
| ------------------------- 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
|
|
||||||
LL | / [0].into_iter()
|
LL | / [0].into_iter()
|
||||||
LL | |
|
LL | |
|
||||||
LL | | .filter_map(|_| foo(src))
|
LL | | .filter_map(|_| foo(src))
|
||||||
| |_________________________________^
|
| |_________________________________^
|
||||||
|
|
|
|
||||||
help: to declare that `impl Iterator<Item = i32>` captures `'_`, you can introduce a named lifetime parameter `'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 `'_`
|
||||||
|
|
|
||||||
LL | fn bar<'a>(src: &'a crate::Foo<'a>) -> impl Iterator<Item = i32> + 'a {
|
|
||||||
| ++++ ++ ++++ ++++
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user