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`
This commit is contained in:
commit
888d157417
6 changed files with 68 additions and 36 deletions
|
@ -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,
|
||||
|
|
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
|
||||
|
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue