Auto merge of #114616 - oli-obk:gotta_capture_'em_all, r=compiler-errors

Capture all lifetimes for TAITs and impl trait in associated types

This reverts commit cb9467515b, reversing changes made to 57781b24c5. (This is only true for the tests, the change itself was done from scratch, as the compiler has diverged sufficiently for a revert to not make sense anymore).

This implements the lang team decision from this meeting: https://hackmd.io/sFaSIMJOQcuwCdnUvCxtuQ?view

r? `@cjgillot` on the impl
This commit is contained in:
bors 2023-08-30 15:57:26 +00:00
commit ac02e40380
24 changed files with 207 additions and 80 deletions

View File

@ -129,7 +129,15 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
// By default, RPIT are invariant wrt type and const generics, but they are bivariant wrt
// lifetime generics.
let mut variances: Vec<_> = std::iter::repeat(ty::Invariant).take(generics.count()).collect();
let variances = std::iter::repeat(ty::Invariant).take(generics.count());
let mut variances: Vec<_> = match tcx.opaque_type_origin(item_def_id) {
rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {
variances.collect()
}
// But TAIT are invariant for all generics
rustc_hir::OpaqueTyOrigin::TyAlias { .. } => return tcx.arena.alloc_from_iter(variances),
};
// Mark all lifetimes from parent generics as unused (Bivariant).
// This will be overridden later if required.

View File

@ -13,7 +13,8 @@ impl MyTy<'_> {
}
}
type Opaque<'a> = impl Sized;
type Opaque2 = impl Sized;
type Opaque<'a> = Opaque2;
fn define<'a>() -> Opaque<'a> {}
fn test<'a>() {

View File

@ -11,7 +11,8 @@ fn test_closure() {
closure(&opaque());
}
type Opaque<'a> = impl Sized;
type Opaque2 = impl Sized;
type Opaque<'a> = Opaque2;
fn define<'a>() -> Opaque<'a> {}
fn test_tait(_: &Opaque<'_>) {

View File

@ -1,10 +1,6 @@
#![feature(type_alias_impl_trait)]
pub trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}
type X<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
type X<'a, 'b> = impl std::fmt::Debug;
fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
(a, a)

View File

@ -1,5 +1,5 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/issue-86465.rs:10:5
--> $DIR/issue-86465.rs:6:5
|
LL | (a, a)
| ^^^^^^

View File

@ -1,11 +1,7 @@
#![feature(type_alias_impl_trait)]
#![allow(dead_code)]
pub trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}
type OneLifetime<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
type OneLifetime<'a, 'b> = impl std::fmt::Debug;
fn foo<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> {
a

View File

@ -1,11 +1,11 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/different_lifetimes_defining_uses.rs:15:5
--> $DIR/different_lifetimes_defining_uses.rs:11:5
|
LL | b
| ^ expected `&'a u32`, got `&'b u32`
|
note: previous use here
--> $DIR/different_lifetimes_defining_uses.rs:11:5
--> $DIR/different_lifetimes_defining_uses.rs:7:5
|
LL | a
| ^

View File

@ -2,11 +2,7 @@
fn main() {}
pub trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}
type Two<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
type Two<'a, 'b> = impl std::fmt::Debug;
fn one<'a>(t: &'a ()) -> Two<'a, 'a> {
//~^ ERROR non-defining opaque type use

View File

@ -1,25 +1,25 @@
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_lifetime_param.rs:11:26
--> $DIR/generic_duplicate_lifetime_param.rs:7:26
|
LL | fn one<'a>(t: &'a ()) -> Two<'a, 'a> {
| ^^^^^^^^^^^ generic argument `'a` used twice
|
note: for this opaque type
--> $DIR/generic_duplicate_lifetime_param.rs:9:20
--> $DIR/generic_duplicate_lifetime_param.rs:5:20
|
LL | type Two<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | type Two<'a, 'b> = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_lifetime_param.rs:13:5
--> $DIR/generic_duplicate_lifetime_param.rs:9:5
|
LL | t
| ^
|
note: lifetime used multiple times
--> $DIR/generic_duplicate_lifetime_param.rs:9:10
--> $DIR/generic_duplicate_lifetime_param.rs:5:10
|
LL | type Two<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
LL | type Two<'a, 'b> = impl std::fmt::Debug;
| ^^ ^^
error: aborting due to 2 previous errors

View File

@ -14,11 +14,7 @@ fn main() {}
// test that unused generic parameters are ok
type TwoTys<T, U> = impl Debug;
pub trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}
type TwoLifetimes<'a, 'b> = impl Debug + Captures<'a> + Captures<'b>;
type TwoLifetimes<'a, 'b> = impl Debug;
type TwoConsts<const X: usize, const Y: usize> = impl Debug;

View File

@ -1,5 +1,5 @@
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:25:30
--> $DIR/generic_duplicate_param_use.rs:21:30
|
LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
| ^^^^^^^^^^^^ generic argument `T` used twice
@ -11,7 +11,7 @@ LL | type TwoTys<T, U> = impl Debug;
| ^^^^^^^^^^
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:27:5
--> $DIR/generic_duplicate_param_use.rs:23:5
|
LL | t
| ^
@ -23,49 +23,49 @@ LL | type TwoTys<T, U> = impl Debug;
| ^ ^
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:31:36
--> $DIR/generic_duplicate_param_use.rs:27:36
|
LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
| ^^^^^^^^^^^^^^^^^^^^ generic argument `'a` used twice
|
note: for this opaque type
--> $DIR/generic_duplicate_param_use.rs:21:29
--> $DIR/generic_duplicate_param_use.rs:17:29
|
LL | type TwoLifetimes<'a, 'b> = impl Debug + Captures<'a> + Captures<'b>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | type TwoLifetimes<'a, 'b> = impl Debug;
| ^^^^^^^^^^
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:33:5
--> $DIR/generic_duplicate_param_use.rs:29:5
|
LL | t
| ^
|
note: lifetime used multiple times
--> $DIR/generic_duplicate_param_use.rs:21:19
--> $DIR/generic_duplicate_param_use.rs:17:19
|
LL | type TwoLifetimes<'a, 'b> = impl Debug + Captures<'a> + Captures<'b>;
LL | type TwoLifetimes<'a, 'b> = impl Debug;
| ^^ ^^
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:37:50
--> $DIR/generic_duplicate_param_use.rs:33:50
|
LL | fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
| ^^^^^^^^^^^^^^^ generic argument `N` used twice
|
note: for this opaque type
--> $DIR/generic_duplicate_param_use.rs:23:50
--> $DIR/generic_duplicate_param_use.rs:19:50
|
LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
| ^^^^^^^^^^
error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:39:5
--> $DIR/generic_duplicate_param_use.rs:35:5
|
LL | t
| ^
|
note: constant used multiple times
--> $DIR/generic_duplicate_param_use.rs:23:16
--> $DIR/generic_duplicate_param_use.rs:19:16
|
LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
| ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^

View File

@ -1,11 +1,10 @@
// check-pass
// build-pass (FIXME(62277): could be check-pass?)
#![feature(type_alias_impl_trait)]
fn main() {}
type Region<'a> = impl std::fmt::Debug + 'a;
type Region<'a> = impl std::fmt::Debug;
fn region<'b>(a: &'b ()) -> Region<'b> {
a

View File

@ -1,7 +1,7 @@
#![feature(type_alias_impl_trait)]
mod test_lifetime_param {
type Ty<'a> = impl Sized + 'a;
type Ty<'a> = impl Sized;
fn defining(a: &str) -> Ty<'_> { a }
fn assert_static<'a: 'static>() {}
fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() }
@ -9,7 +9,7 @@ mod test_lifetime_param {
}
mod test_higher_kinded_lifetime_param {
type Ty<'a> = impl Sized + 'a;
type Ty<'a> = impl Sized;
fn defining(a: &str) -> Ty<'_> { a }
fn assert_static<'a: 'static>() {}
fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() }

View File

@ -1,16 +1,20 @@
// check-pass
#![feature(impl_trait_in_assoc_type)]
#![feature(impl_trait_in_assoc_type, type_alias_impl_trait)]
trait Callable {
type Output;
fn call() -> Self::Output;
}
mod foo {
pub trait Callable {
type Output;
fn call() -> Self::Output;
}
impl<'a> Callable for &'a () {
type Output = impl Sized;
fn call() -> Self::Output {}
pub type OutputHelper = impl Sized;
impl<'a> Callable for &'a () {
type Output = OutputHelper;
fn call() -> Self::Output {}
}
}
use foo::*;
fn test<'a>() -> impl Sized {
<&'a () as Callable>::call()

View File

@ -4,7 +4,7 @@
use std::future::Future;
type G<'a, T> = impl Future<Output = ()> + 'a;
type G<'a, T> = impl Future<Output = ()>;
trait Trait {
type F: Future<Output = ()>;

View File

@ -6,7 +6,7 @@ LL | async move { self.f().await }
|
help: consider restricting type parameter `T`
|
LL | type G<'a, T: Trait> = impl Future<Output = ()> + 'a;
LL | type G<'a, T: Trait> = impl Future<Output = ()>;
| +++++++
error: aborting due to previous error

View File

@ -1,7 +1,8 @@
#![feature(type_alias_impl_trait)]
type Opaque<'a, T> = impl Sized;
type Opaque2<T> = impl Sized;
type Opaque<'a, T> = Opaque2<T>;
fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
//~^ ERROR: hidden type for `Opaque<'a, T>` captures lifetime that does not appear in bounds
//~^ ERROR: hidden type for `Opaque2<T>` captures lifetime that does not appear in bounds
fn main() {}

View File

@ -1,8 +1,9 @@
error[E0700]: hidden type for `Opaque<'a, T>` captures lifetime that does not appear in bounds
--> $DIR/missing_lifetime_bound.rs:4:47
error[E0700]: hidden type for `Opaque2<T>` captures lifetime that does not appear in bounds
--> $DIR/missing_lifetime_bound.rs:5:47
|
LL | type Opaque<'a, T> = impl Sized;
| ---------- opaque type defined here
LL | type Opaque2<T> = impl Sized;
| ---------- opaque type defined here
LL | type Opaque<'a, T> = Opaque2<T>;
LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
| -- ^
| |

View File

@ -1,10 +1,6 @@
#![feature(type_alias_impl_trait)]
pub trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}
type Foo<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
type Foo<'a, 'b> = impl std::fmt::Debug;
fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) {
(i, i) //~ ERROR concrete type differs from previous

View File

@ -1,5 +1,5 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:10:5
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
LL | (i, i)
| ^^^^^^

View File

@ -7,11 +7,7 @@ fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>)
(a.clone(), a)
}
pub trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}
type Foo<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
type Foo<'a, 'b> = impl std::fmt::Debug;
fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) {
(i, j)

View File

@ -22,9 +22,9 @@ fn bar() {
}
// desugared
type FooX<'a> = impl Sized;
type FooX = impl Sized;
impl<'a> Foo<'a> {
fn foo(&self) -> FooX<'a> {}
fn foo(&self) -> FooX {}
}
// use site

View File

@ -0,0 +1,50 @@
#![feature(rustc_attrs, type_alias_impl_trait, impl_trait_in_assoc_type)]
#![allow(internal_features)]
#![rustc_variance_of_opaques]
trait Captures<'a> {}
impl<T> Captures<'_> for T {}
type NotCapturedEarly<'a> = impl Sized; //~ [o]
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o]
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o]
type CapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'b>>; //~ [o]
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a> + Captures<'b>>; //~ [o]
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o]
trait Foo<'i> {
type ImplicitCapturedEarly<'a>;
type ExplicitCaptureEarly<'a>;
type ImplicitCaptureLate<'a>;
type ExplicitCaptureLate<'a>;
}
impl<'i> Foo<'i> for &'i () {
type ImplicitCapturedEarly<'a> = impl Sized; //~ [o, o]
type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; //~ [o, o]
type ImplicitCaptureLate<'a> = impl Sized; //~ [o, o]
type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; //~ [o, o]
}
impl<'i> Foo<'i> for () {
type ImplicitCapturedEarly<'a> = impl Sized; //~ [o, o]
type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; //~ [o, o]
type ImplicitCaptureLate<'a> = impl Sized; //~ [o, o]
type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; //~ [o, o]
}
fn main() {}

View File

@ -0,0 +1,86 @@
error: [o]
--> $DIR/variance.rs:8:29
|
LL | type NotCapturedEarly<'a> = impl Sized;
| ^^^^^^^^^^
error: [o]
--> $DIR/variance.rs:10:26
|
LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o]
--> $DIR/variance.rs:12:56
|
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
| ^^^^^^^^^^
error: [o]
--> $DIR/variance.rs:14:53
|
LL | type CapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'b>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o]
--> $DIR/variance.rs:16:49
|
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a> + Captures<'b>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o, o]
--> $DIR/variance.rs:18:27
|
LL | type Bar<'a, 'b: 'b, T> = impl Sized;
| ^^^^^^^^^^
error: [o, o]
--> $DIR/variance.rs:31:38
|
LL | type ImplicitCapturedEarly<'a> = impl Sized;
| ^^^^^^^^^^
error: [o, o]
--> $DIR/variance.rs:33:37
|
LL | type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o]
--> $DIR/variance.rs:35:36
|
LL | type ImplicitCaptureLate<'a> = impl Sized;
| ^^^^^^^^^^
error: [o, o]
--> $DIR/variance.rs:37:36
|
LL | type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o]
--> $DIR/variance.rs:41:38
|
LL | type ImplicitCapturedEarly<'a> = impl Sized;
| ^^^^^^^^^^
error: [o, o]
--> $DIR/variance.rs:43:37
|
LL | type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o]
--> $DIR/variance.rs:45:36
|
LL | type ImplicitCaptureLate<'a> = impl Sized;
| ^^^^^^^^^^
error: [o, o]
--> $DIR/variance.rs:47:36
|
LL | type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 14 previous errors