Rollup merge of #60449 - matthewjasper:impl-trait-outlives, r=pnkfelix
Constrain all regions in the concrete type for an opaque type `push_outlives_components` skips some regions in a type, notably the signature of a closure is ignored. Most of the time this is OK, but for opaque types the concrete type is used when checking auto-trait bounds in other functions. cc @nikomatsakis @pnkfelix Closes #57464 Closes #60127
This commit is contained in:
commit
b4c620dc05
6 changed files with 129 additions and 72 deletions
19
src/test/ui/impl-trait/can-return-unconstrained-closure.rs
Normal file
19
src/test/ui/impl-trait/can-return-unconstrained-closure.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Test that we are special casing "outlives" for opaque types.
|
||||
//
|
||||
// The return type of a closure is not required to outlive the closure. As such
|
||||
// the following code would not compile if we used a standard outlives check
|
||||
// when checking the return type, because the return type of the closure would
|
||||
// be `&ReEmpty i32`, and we don't allow `ReEmpty` to occur in the concrete
|
||||
// type used for an opaque type.
|
||||
//
|
||||
// However, opaque types are special cased to include check all regions in the
|
||||
// concrete type against the bound, which forces the return type to be
|
||||
// `&'static i32` here.
|
||||
|
||||
// compile-pass
|
||||
|
||||
fn make_identity() -> impl Sized {
|
||||
|x: &'static i32| x
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
// This used to ICE because it creates an `impl Trait` that captures a
|
||||
// hidden empty region.
|
||||
|
||||
#![feature(conservative_impl_trait)]
|
||||
// compile-pass
|
||||
|
||||
fn server() -> impl FilterBase2 { //~ ERROR [E0700]
|
||||
fn server() -> impl FilterBase2 {
|
||||
segment2(|| { loop { } }).map2(|| "")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
--> $DIR/issue-55608-captures-empty-region.rs:6:16
|
||||
|
|
||||
LL | fn server() -> impl FilterBase2 {
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: hidden type `Map2<[closure@$DIR/issue-55608-captures-empty-region.rs:7:36: 7:41]>` captures an empty lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0700`.
|
||||
22
src/test/ui/impl-trait/issue-57464-unexpected-regions.rs
Normal file
22
src/test/ui/impl-trait/issue-57464-unexpected-regions.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Regression test for issue 57464.
|
||||
//
|
||||
// Closure are (surprisingly) allowed to outlive their signature. As such it
|
||||
// was possible to end up with `ReScope`s appearing in the concrete type of an
|
||||
// opaque type. As all regions are now required to outlive the bound in an
|
||||
// opaque type we avoid the issue here.
|
||||
|
||||
// compile-pass
|
||||
|
||||
struct A<F>(F);
|
||||
|
||||
unsafe impl <'a, 'b, F: Fn(&'a i32) -> &'b i32> Send for A<F> {}
|
||||
|
||||
fn wrapped_closure() -> impl Sized {
|
||||
let f = |x| x;
|
||||
f(&0);
|
||||
A(f)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: Box<dyn Send> = Box::new(wrapped_closure());
|
||||
}
|
||||
|
|
@ -2,10 +2,10 @@
|
|||
fn iter<'a>(data: &'a [usize]) -> impl Iterator<Item = usize> + 'a {
|
||||
data.iter()
|
||||
.map(
|
||||
|x| x // fn(&'a usize) -> &'(ReScope) usize
|
||||
|x| x // fn(&'a usize) -> &'a usize
|
||||
)
|
||||
.map(
|
||||
|x| *x // fn(&'(ReScope) usize) -> usize
|
||||
|x| *x // fn(&'a usize) -> usize
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue