about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-30 15:57:26 +0000
committerbors <bors@rust-lang.org>2023-08-30 15:57:26 +0000
commitac02e403803e10b45ee8ec0faeb3b4468740f3e6 (patch)
tree5169a30590869d9fbe07a0c1c864f848c0fe3670
parent26089ba0a2d9dab8381ccb0d7b99e704bc5cb3ed (diff)
parente82ccd52db55ac166da02efbc07b9c8ae9e4421b (diff)
downloadrust-ac02e403803e10b45ee8ec0faeb3b4468740f3e6.tar.gz
rust-ac02e403803e10b45ee8ec0faeb3b4468740f3e6.zip
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 cb9467515b5a9b15aaa905683c6b4dd9e851056c, reversing changes made to 57781b24c54f9548722927ba88c343ff28da94ce. (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
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs10
-rw-r--r--tests/ui/impl-trait/issue-108591.rs3
-rw-r--r--tests/ui/impl-trait/issue-108592.rs3
-rw-r--r--tests/ui/impl-trait/issue-86465.rs6
-rw-r--r--tests/ui/impl-trait/issue-86465.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr26
-rw-r--r--tests/ui/type-alias-impl-trait/generic_lifetime_param.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/issue-89686.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-89686.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/self_implication.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/variance.rs50
-rw-r--r--tests/ui/type-alias-impl-trait/variance.stderr86
24 files changed, 207 insertions, 80 deletions
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index d91d9fcbc8e..d69d7ff904a 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -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.
diff --git a/tests/ui/impl-trait/issue-108591.rs b/tests/ui/impl-trait/issue-108591.rs
index 6b9d14941f2..91ea2e9fb85 100644
--- a/tests/ui/impl-trait/issue-108591.rs
+++ b/tests/ui/impl-trait/issue-108591.rs
@@ -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>() {
diff --git a/tests/ui/impl-trait/issue-108592.rs b/tests/ui/impl-trait/issue-108592.rs
index 58a0ed9bf1a..953fffc4898 100644
--- a/tests/ui/impl-trait/issue-108592.rs
+++ b/tests/ui/impl-trait/issue-108592.rs
@@ -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<'_>) {
diff --git a/tests/ui/impl-trait/issue-86465.rs b/tests/ui/impl-trait/issue-86465.rs
index 8c7b41d73b7..a79bb6474d8 100644
--- a/tests/ui/impl-trait/issue-86465.rs
+++ b/tests/ui/impl-trait/issue-86465.rs
@@ -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)
diff --git a/tests/ui/impl-trait/issue-86465.stderr b/tests/ui/impl-trait/issue-86465.stderr
index b949b2b4245..90d6904ed61 100644
--- a/tests/ui/impl-trait/issue-86465.stderr
+++ b/tests/ui/impl-trait/issue-86465.stderr
@@ -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)
    |     ^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs
index 5f75fdc716e..4f424b8c665 100644
--- a/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs
+++ b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs
@@ -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
diff --git a/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr
index 546598e8a5c..0c50a84e894 100644
--- a/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr
+++ b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr
@@ -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
    |     ^
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs
index 14ced341854..169d4f8d509 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs
@@ -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
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr
index 4da69a705c0..b03bf2466e6 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr
@@ -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
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
index 1e391b55a4f..e3c6f4d874b 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
@@ -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;
 
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
index d8330771d30..495308a6cac 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
@@ -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;
    |                ^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs b/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs
index 106efefbaf2..e109c38c986 100644
--- a/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs
+++ b/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs
@@ -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
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs
index 6f9434255a8..469a493b0b3 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs
@@ -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>() }
diff --git a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
index 4f99236f4ea..06c119287d7 100644
--- a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
+++ b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
@@ -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()
diff --git a/tests/ui/type-alias-impl-trait/issue-89686.rs b/tests/ui/type-alias-impl-trait/issue-89686.rs
index 058417bdb80..de070fc9deb 100644
--- a/tests/ui/type-alias-impl-trait/issue-89686.rs
+++ b/tests/ui/type-alias-impl-trait/issue-89686.rs
@@ -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 = ()>;
diff --git a/tests/ui/type-alias-impl-trait/issue-89686.stderr b/tests/ui/type-alias-impl-trait/issue-89686.stderr
index 3b95a575ac2..b636ada8b75 100644
--- a/tests/ui/type-alias-impl-trait/issue-89686.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-89686.stderr
@@ -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
diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
index 01d1f5db132..c584a58cb32 100644
--- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
@@ -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() {}
diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
index d666e668d36..6bcae6e5316 100644
--- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
@@ -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 }
    |             --                                ^
    |             |
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs
index 65eb2952e0f..3f122f10609 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs
@@ -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
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr
index d7676b8e9b1..81e603e2355 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr
@@ -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)
    |     ^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs
index 21fca047a3c..83fd9a1da45 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs
@@ -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)
diff --git a/tests/ui/type-alias-impl-trait/self_implication.rs b/tests/ui/type-alias-impl-trait/self_implication.rs
index 4e805ee308f..65659a0f3b1 100644
--- a/tests/ui/type-alias-impl-trait/self_implication.rs
+++ b/tests/ui/type-alias-impl-trait/self_implication.rs
@@ -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
diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs
new file mode 100644
index 00000000000..eba4816003b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/variance.rs
@@ -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() {}
diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr
new file mode 100644
index 00000000000..f73cf617a4c
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/variance.stderr
@@ -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
+