Skip to content

Commit

Permalink
Auto merge of #114616 - oli-obk:gotta_capture_'em_all, r=compiler-errors
Browse files Browse the repository at this point in the history
Capture all lifetimes for TAITs and impl trait in associated types

This reverts commit cb94675, reversing changes made to 57781b2. (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
  • Loading branch information
bors committed Aug 30, 2023
2 parents 26089ba + e82ccd5 commit ac02e40
Show file tree
Hide file tree
Showing 24 changed files with 207 additions and 80 deletions.
10 changes: 9 additions & 1 deletion compiler/rustc_hir_analysis/src/variance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion tests/ui/impl-trait/issue-108591.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>() {
Expand Down
3 changes: 2 additions & 1 deletion tests/ui/impl-trait/issue-108592.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<'_>) {
Expand Down
6 changes: 1 addition & 5 deletions tests/ui/impl-trait/issue-86465.rs
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/issue-86465.stderr
Original file line number Diff line number Diff line change
@@ -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)
| ^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
| ^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
26 changes: 13 additions & 13 deletions tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
| ^
Expand All @@ -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;
| ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
Expand Down
5 changes: 2 additions & 3 deletions tests/ui/type-alias-impl-trait/generic_lifetime_param.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#![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>() }
//~^ ERROR: lifetime may not live long enough
}

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>() }
Expand Down
20 changes: 12 additions & 8 deletions tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
Original file line number Diff line number Diff line change
@@ -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()
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/issue-89686.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ()>;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/issue-89686.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
Original file line number Diff line number Diff line change
@@ -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() {}
9 changes: 5 additions & 4 deletions tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
Original file line number Diff line number Diff line change
@@ -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 }
| -- ^
| |
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
| ^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/type-alias-impl-trait/self_implication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit ac02e40

Please sign in to comment.