about summary refs log tree commit diff
path: root/tests/ui/impl-trait
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/impl-trait')
-rw-r--r--tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs36
-rw-r--r--tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr14
-rw-r--r--tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs13
-rw-r--r--tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr15
-rw-r--r--tests/ui/impl-trait/associated-type-undefine.rs1
-rw-r--r--tests/ui/impl-trait/associated-type-undefine.stderr17
-rw-r--r--tests/ui/impl-trait/async_scope_creep.rs2
-rw-r--r--tests/ui/impl-trait/auto-trait-coherence.rs1
-rw-r--r--tests/ui/impl-trait/auto-trait-coherence.stderr2
-rw-r--r--tests/ui/impl-trait/bound-normalization-pass.rs1
-rw-r--r--tests/ui/impl-trait/coherence-treats-tait-ambig.rs3
-rw-r--r--tests/ui/impl-trait/deduce-signature-from-supertrait.rs3
-rw-r--r--tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs11
-rw-r--r--tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr2
-rw-r--r--tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr2
-rw-r--r--tests/ui/impl-trait/hidden-type-is-opaque-2.rs1
-rw-r--r--tests/ui/impl-trait/hidden-type-is-opaque.rs1
-rw-r--r--tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr14
-rw-r--r--tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr18
-rw-r--r--tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs1
-rw-r--r--tests/ui/impl-trait/in-assoc-type-unconstrained.stderr5
-rw-r--r--tests/ui/impl-trait/in-assoc-type.stderr5
-rw-r--r--tests/ui/impl-trait/issue-108591.rs1
-rw-r--r--tests/ui/impl-trait/issue-108592.rs11
-rw-r--r--tests/ui/impl-trait/issue-99642-2.rs3
-rw-r--r--tests/ui/impl-trait/issues/issue-53457.rs1
-rw-r--r--tests/ui/impl-trait/issues/issue-70877.rs38
-rw-r--r--tests/ui/impl-trait/issues/issue-70877.stderr63
-rw-r--r--tests/ui/impl-trait/issues/issue-74282.rs3
-rw-r--r--tests/ui/impl-trait/issues/issue-74282.stderr10
-rw-r--r--tests/ui/impl-trait/issues/issue-77987.rs13
-rw-r--r--tests/ui/impl-trait/issues/issue-78722-2.rs1
-rw-r--r--tests/ui/impl-trait/issues/issue-78722-2.stderr8
-rw-r--r--tests/ui/impl-trait/issues/issue-78722.rs1
-rw-r--r--tests/ui/impl-trait/issues/issue-78722.stderr6
-rw-r--r--tests/ui/impl-trait/issues/issue-86201.rs7
-rw-r--r--tests/ui/impl-trait/issues/issue-86800.rs24
-rw-r--r--tests/ui/impl-trait/issues/issue-86800.stderr40
-rw-r--r--tests/ui/impl-trait/issues/issue-89312.rs24
-rw-r--r--tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs1
-rw-r--r--tests/ui/impl-trait/multiple-lifetimes/error-handling-2.rs1
-rw-r--r--tests/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr4
-rw-r--r--tests/ui/impl-trait/multiple-lifetimes/error-handling.rs1
-rw-r--r--tests/ui/impl-trait/multiple-lifetimes/error-handling.stderr2
-rw-r--r--tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs1
-rw-r--r--tests/ui/impl-trait/negative-reasoning.rs1
-rw-r--r--tests/ui/impl-trait/negative-reasoning.stderr2
-rw-r--r--tests/ui/impl-trait/nested-return-type2-tait.rs4
-rw-r--r--tests/ui/impl-trait/nested-return-type2-tait.stderr2
-rw-r--r--tests/ui/impl-trait/nested-return-type2-tait2.rs4
-rw-r--r--tests/ui/impl-trait/nested-return-type2-tait3.rs4
-rw-r--r--tests/ui/impl-trait/nested-return-type3-tait.rs4
-rw-r--r--tests/ui/impl-trait/nested-return-type3-tait.stderr2
-rw-r--r--tests/ui/impl-trait/nested-return-type3-tait2.rs4
-rw-r--r--tests/ui/impl-trait/nested-return-type3-tait3.rs4
-rw-r--r--tests/ui/impl-trait/normalize-tait-in-const.stderr32
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs10
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs1
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr20
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs1
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr2
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other.current.stderr2
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other.rs1
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr10
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr2
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other2.rs1
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other3.current.stderr2
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other3.rs1
-rw-r--r--tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs1
-rw-r--r--tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr6
-rw-r--r--tests/ui/impl-trait/where-allowed.rs1
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr58
72 files changed, 360 insertions, 254 deletions
diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs
index 65e90c1ca53..f703269a438 100644
--- a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs
+++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs
@@ -8,31 +8,29 @@ impl<T> Captures<'_> for T {}
 pub struct MyTy<'a, 'b>(Option<*mut &'a &'b ()>);
 unsafe impl Send for MyTy<'_, 'static> {}
 
-pub mod step1 {
-    use super::*;
-    pub type Step1<'a, 'b: 'a> = impl Sized + Captures<'b> + 'a;
-    pub fn step1<'a, 'b: 'a>() -> Step1<'a, 'b> {
-        MyTy::<'a, 'b>(None)
-    }
+pub type Step1<'a, 'b: 'a> = impl Sized + Captures<'b> + 'a;
+#[define_opaque(Step1)]
+pub fn step1<'a, 'b: 'a>() -> Step1<'a, 'b> {
+    MyTy::<'a, 'b>(None)
 }
 
-pub mod step2 {
-    pub type Step2<'a> = impl Send + 'a;
-
-    // Although `Step2` is WF at the definition site, it's not WF in its
-    // declaration site (above). We check this in `check_opaque_meets_bounds`,
-    // which must remain sound.
-    pub fn step2<'a, 'b: 'a>() -> Step2<'a>
-        where crate::step1::Step1<'a, 'b>: Send
-    {
-        crate::step1::step1::<'a, 'b>()
-        //~^ ERROR hidden type for `Step2<'a>` captures lifetime that does not appear in bounds
-    }
+pub type Step2<'a> = impl Send + 'a;
+
+// Although `Step2` is WF at the definition site, it's not WF in its
+// declaration site (above). We check this in `check_opaque_meets_bounds`,
+// which must remain sound.
+#[define_opaque(Step2)]
+pub fn step2<'a, 'b: 'a>() -> Step2<'a>
+where
+    Step1<'a, 'b>: Send,
+{
+    step1::<'a, 'b>()
+    //~^ ERROR hidden type for `Step2<'a>` captures lifetime that does not appear in bounds
 }
 
 fn step3<'a, 'b>() {
     fn is_send<T: Send>() {}
-    is_send::<crate::step2::Step2::<'a>>();
+    is_send::<Step2<'a>>();
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr
index 58d7f9959d3..ce797ccf40c 100644
--- a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr
+++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr
@@ -1,14 +1,14 @@
 error[E0700]: hidden type for `Step2<'a>` captures lifetime that does not appear in bounds
-  --> $DIR/tait-hidden-erased-unsoundness-2.rs:28:9
+  --> $DIR/tait-hidden-erased-unsoundness-2.rs:27:5
    |
-LL |     pub type Step2<'a> = impl Send + 'a;
-   |                          -------------- opaque type defined here
+LL | pub type Step2<'a> = impl Send + 'a;
+   |                      -------------- opaque type defined here
 ...
-LL |     pub fn step2<'a, 'b: 'a>() -> Step2<'a>
-   |                      -- hidden type `Step1<'a, 'b>` captures the lifetime `'b` as defined here
+LL | pub fn step2<'a, 'b: 'a>() -> Step2<'a>
+   |                  -- hidden type `Step1<'a, 'b>` captures the lifetime `'b` as defined here
 ...
-LL |         crate::step1::step1::<'a, 'b>()
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     step1::<'a, 'b>()
+   |     ^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs
index 40efd941e33..ba22f16003c 100644
--- a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs
+++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.rs
@@ -12,16 +12,15 @@ fn step1<'a, 'b: 'a>() -> impl Sized + Captures<'b> + 'a {
     MyTy::<'a, 'b>(None)
 }
 
-mod tait {
-    type Tait<'a> = impl Sized + 'a;
-    pub(super) fn step2<'a, 'b: 'a>() -> Tait<'a> {
-        super::step1::<'a, 'b>()
-        //~^ ERROR hidden type for `Tait<'a>` captures lifetime that does not appear in bounds
-    }
+type Tait<'a> = impl Sized + 'a;
+#[define_opaque(Tait)]
+fn step2<'a, 'b: 'a>() -> Tait<'a> {
+    step1::<'a, 'b>()
+    //~^ ERROR hidden type for `Tait<'a>` captures lifetime that does not appear in bounds
 }
 
 fn step3<'a, 'b: 'a>() -> impl Send + 'a {
-    tait::step2::<'a, 'b>()
+    step2::<'a, 'b>()
     // This should not be Send unless `'b: 'static`
 }
 
diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr
index 6c9b8cf2427..ed1afd64507 100644
--- a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr
+++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness.stderr
@@ -1,12 +1,13 @@
 error[E0700]: hidden type for `Tait<'a>` captures lifetime that does not appear in bounds
-  --> $DIR/tait-hidden-erased-unsoundness.rs:18:9
+  --> $DIR/tait-hidden-erased-unsoundness.rs:18:5
    |
-LL |     type Tait<'a> = impl Sized + 'a;
-   |                     --------------- opaque type defined here
-LL |     pub(super) fn step2<'a, 'b: 'a>() -> Tait<'a> {
-   |                             -- hidden type `impl Captures<'b> + 'a` captures the lifetime `'b` as defined here
-LL |         super::step1::<'a, 'b>()
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+LL | type Tait<'a> = impl Sized + 'a;
+   |                 --------------- opaque type defined here
+LL | #[define_opaque(Tait)]
+LL | fn step2<'a, 'b: 'a>() -> Tait<'a> {
+   |              -- hidden type `impl Captures<'b> + 'a` captures the lifetime `'b` as defined here
+LL |     step1::<'a, 'b>()
+   |     ^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/associated-type-undefine.rs b/tests/ui/impl-trait/associated-type-undefine.rs
index c8f07021fbf..895525960fc 100644
--- a/tests/ui/impl-trait/associated-type-undefine.rs
+++ b/tests/ui/impl-trait/associated-type-undefine.rs
@@ -16,6 +16,7 @@ impl Foo for u32 {
 
 impl Foo for () {
     type Bar = impl Sized;
+    //~^ ERROR: unconstrained opaque type
     type Gat<T: Foo> = <T as Foo>::Bar;
     // Because we encounter `Gat<u32>` first, we never walk into another `Gat`
     // again, thus missing the opaque type that we could be defining.
diff --git a/tests/ui/impl-trait/associated-type-undefine.stderr b/tests/ui/impl-trait/associated-type-undefine.stderr
index 5d9d525eb93..e567f1bcdf6 100644
--- a/tests/ui/impl-trait/associated-type-undefine.stderr
+++ b/tests/ui/impl-trait/associated-type-undefine.stderr
@@ -1,5 +1,13 @@
+error: unconstrained opaque type
+  --> $DIR/associated-type-undefine.rs:18:16
+   |
+LL |     type Bar = impl Sized;
+   |                ^^^^^^^^^^
+   |
+   = note: `Bar` must be used in combination with a concrete type within the same impl
+
 error[E0308]: mismatched types
-  --> $DIR/associated-type-undefine.rs:23:14
+  --> $DIR/associated-type-undefine.rs:24:14
    |
 LL |     type Bar = impl Sized;
    |                ---------- the expected opaque type
@@ -9,12 +17,7 @@ LL |         ((), ())
    |
    = note: expected opaque type `<() as Foo>::Bar`
                 found unit type `()`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/associated-type-undefine.rs:22:8
-   |
-LL |     fn foo(self) -> (<Self as Foo>::Gat<u32>, <Self as Foo>::Gat<Self>) {
-   |        ^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/async_scope_creep.rs b/tests/ui/impl-trait/async_scope_creep.rs
index 0fb355c5233..449f090a2e4 100644
--- a/tests/ui/impl-trait/async_scope_creep.rs
+++ b/tests/ui/impl-trait/async_scope_creep.rs
@@ -22,11 +22,13 @@ impl Pending {
     }
 
     #[cfg(tait)]
+    #[define_opaque(OpeningReadFuture)]
     fn read_fut(&mut self) -> OpeningReadFuture<'_> {
         self.read()
     }
 
     #[cfg(rpit)]
+    #[define_opaque(PendingReader)]
     fn read_fut(
         &mut self,
     ) -> impl std::future::Future<Output = Result<PendingReader<'_>, CantOpen>> {
diff --git a/tests/ui/impl-trait/auto-trait-coherence.rs b/tests/ui/impl-trait/auto-trait-coherence.rs
index 0d7fef21cc9..fdb981ea406 100644
--- a/tests/ui/impl-trait/auto-trait-coherence.rs
+++ b/tests/ui/impl-trait/auto-trait-coherence.rs
@@ -5,6 +5,7 @@
 trait OpaqueTrait {}
 impl<T> OpaqueTrait for T {}
 type OpaqueType = impl OpaqueTrait;
+#[define_opaque(OpaqueType)]
 fn mk_opaque() -> OpaqueType {
     ()
 }
diff --git a/tests/ui/impl-trait/auto-trait-coherence.stderr b/tests/ui/impl-trait/auto-trait-coherence.stderr
index e0f4c857717..cfeccc3d766 100644
--- a/tests/ui/impl-trait/auto-trait-coherence.stderr
+++ b/tests/ui/impl-trait/auto-trait-coherence.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>`
-  --> $DIR/auto-trait-coherence.rs:21:1
+  --> $DIR/auto-trait-coherence.rs:22:1
    |
 LL | impl<T: Send> AnotherTrait for T {}
    | -------------------------------- first implementation here
diff --git a/tests/ui/impl-trait/bound-normalization-pass.rs b/tests/ui/impl-trait/bound-normalization-pass.rs
index 801187b6f5e..77bc0206830 100644
--- a/tests/ui/impl-trait/bound-normalization-pass.rs
+++ b/tests/ui/impl-trait/bound-normalization-pass.rs
@@ -77,6 +77,7 @@ mod opaque_types {
 
     type Ex = impl Trait<Out = <() as Implemented>::Assoc>;
 
+    #[define_opaque(Ex)]
     fn define() -> Ex {
         ()
     }
diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs
index e8c1fcdd213..54d68afc31f 100644
--- a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs
+++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs
@@ -5,7 +5,8 @@ type T = impl Sized;
 struct Foo;
 
 impl Into<T> for Foo {
-//~^ ERROR conflicting implementations of trait `Into<_>` for type `Foo`
+    //~^ ERROR conflicting implementations of trait `Into<_>` for type `Foo`
+    #[define_opaque(T)]
     fn into(self) -> T {
         Foo
     }
diff --git a/tests/ui/impl-trait/deduce-signature-from-supertrait.rs b/tests/ui/impl-trait/deduce-signature-from-supertrait.rs
index 4e452994f72..28b6697f4bc 100644
--- a/tests/ui/impl-trait/deduce-signature-from-supertrait.rs
+++ b/tests/ui/impl-trait/deduce-signature-from-supertrait.rs
@@ -8,7 +8,8 @@ impl<T: Fn(i32)> SuperExpectation for T {}
 
 type Foo = impl SuperExpectation;
 
-fn bop(_: Foo) {
+#[define_opaque(Foo)]
+fn bop() {
     let _: Foo = |x| {
         let _ = x.to_string();
     };
diff --git a/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs b/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs
index af623dc7cd9..e8be2082d7c 100644
--- a/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs
+++ b/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs
@@ -7,15 +7,12 @@
 
 use std::future::Future;
 
-mod foo {
-    use std::future::Future;
-    pub type Fut<'a> = impl Future<Output = ()> + 'a;
+pub type Fut<'a> = impl Future<Output = ()> + 'a;
 
-    fn foo<'a>(_: &()) -> Fut<'_> {
-        async {}
-    }
+#[define_opaque(Fut)]
+fn foo<'a>(_: &()) -> Fut<'_> {
+    async {}
 }
-use foo::*;
 
 trait Test {
     fn hello();
diff --git a/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr b/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr
index 01c5a553dc5..dca0a7b0a1a 100644
--- a/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr
+++ b/tests/ui/impl-trait/hidden-type-is-opaque-2.default.stderr
@@ -13,7 +13,7 @@ LL |     Thunk::new(|mut cont: /* Type */| {
    |                         ++++++++++++
 
 error[E0282]: type annotations needed
-  --> $DIR/hidden-type-is-opaque-2.rs:20:17
+  --> $DIR/hidden-type-is-opaque-2.rs:21:17
    |
 LL |     Thunk::new(|mut cont| {
    |                 ^^^^^^^^
diff --git a/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr b/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr
index 01c5a553dc5..dca0a7b0a1a 100644
--- a/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr
+++ b/tests/ui/impl-trait/hidden-type-is-opaque-2.next.stderr
@@ -13,7 +13,7 @@ LL |     Thunk::new(|mut cont: /* Type */| {
    |                         ++++++++++++
 
 error[E0282]: type annotations needed
-  --> $DIR/hidden-type-is-opaque-2.rs:20:17
+  --> $DIR/hidden-type-is-opaque-2.rs:21:17
    |
 LL |     Thunk::new(|mut cont| {
    |                 ^^^^^^^^
diff --git a/tests/ui/impl-trait/hidden-type-is-opaque-2.rs b/tests/ui/impl-trait/hidden-type-is-opaque-2.rs
index 78ac8363ba9..7725a04c358 100644
--- a/tests/ui/impl-trait/hidden-type-is-opaque-2.rs
+++ b/tests/ui/impl-trait/hidden-type-is-opaque-2.rs
@@ -16,6 +16,7 @@ fn reify_as() -> Thunk<impl FnOnce(Continuation) -> Continuation> {
 
 type Tait = impl FnOnce(Continuation) -> Continuation;
 
+#[define_opaque(Tait)]
 fn reify_as_tait() -> Thunk<Tait> {
     Thunk::new(|mut cont| {
         //~^ ERROR type annotations needed
diff --git a/tests/ui/impl-trait/hidden-type-is-opaque.rs b/tests/ui/impl-trait/hidden-type-is-opaque.rs
index 3111a21e209..aa9ea2a8a26 100644
--- a/tests/ui/impl-trait/hidden-type-is-opaque.rs
+++ b/tests/ui/impl-trait/hidden-type-is-opaque.rs
@@ -10,6 +10,7 @@ fn reify_as() -> Thunk<impl ContFn> {
 
 type Tait = impl ContFn;
 
+#[define_opaque(Tait)]
 fn reify_as_tait() -> Thunk<Tait> {
     Thunk::new(|mut cont| {
         cont.reify_as();
diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr
index 146a3d21068..c76415d8114 100644
--- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr
+++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.current.stderr
@@ -1,5 +1,5 @@
 error[E0407]: method `line_stream` is not a member of trait `X`
-  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:5
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:5
    |
 LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `X`
@@ -17,15 +17,23 @@ LL |     type LineStream<'c, 'd> = impl Stream;
    |                     |
    |                     found 0 type parameters
 
+error: unconstrained opaque type
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:31
+   |
+LL |     type LineStream<'c, 'd> = impl Stream;
+   |                               ^^^^^^^^^^^
+   |
+   = note: `LineStream` must be used in combination with a concrete type within the same impl
+
 error[E0277]: `()` is not a future
-  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:43
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:43
    |
 LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future
    |
    = help: the trait `Future` is not implemented for `()`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0049, E0277, E0407.
 For more information about an error, try `rustc --explain E0049`.
diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr
index ce64a022214..4d72490ff95 100644
--- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr
+++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.next.stderr
@@ -1,5 +1,5 @@
 error[E0407]: method `line_stream` is not a member of trait `X`
-  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:5
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:5
    |
 LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `X`
@@ -17,25 +17,33 @@ LL |     type LineStream<'c, 'd> = impl Stream;
    |                     |
    |                     found 0 type parameters
 
+error: unconstrained opaque type
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:25:31
+   |
+LL |     type LineStream<'c, 'd> = impl Stream;
+   |                               ^^^^^^^^^^^
+   |
+   = note: `LineStream` must be used in combination with a concrete type within the same impl
+
 error[E0271]: type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> == ()`
-  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:43
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:43
    |
 LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
 
 error[E0271]: type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
-  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:73
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:73
    |
 LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
    |                                                                         ^^ types differ
 
 error[E0271]: type mismatch resolving `<Y as X>::LineStreamFut<'a, Repr> normalizes-to _`
-  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:28:5
+  --> $DIR/ice-unexpected-param-type-whensubstituting-in-region-112823.rs:29:5
    |
 LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0049, E0271, E0407.
 For more information about an error, try `rustc --explain E0049`.
diff --git a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs
index cb32723b22d..a5a37dbb210 100644
--- a/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs
+++ b/tests/ui/impl-trait/ice-unexpected-param-type-whensubstituting-in-region-112823.rs
@@ -24,6 +24,7 @@ struct Y;
 impl X for Y {
     type LineStream<'c, 'd> = impl Stream;
     //~^ ERROR type `LineStream` has 0 type parameters but its trait declaration has 1 type parameter
+    //~| ERROR: unconstrained opaque type
     type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>>;
     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {}
     //~^ method `line_stream` is not a member of trait `X`
diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
index 8351175099c..c9e657b87d5 100644
--- a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
+++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
@@ -36,11 +36,6 @@ LL |         fn method() -> Self::Ty;
    |                        ^^^^^^^^
    = note: expected signature `fn() -> <() as compare_method::Trait>::Ty`
               found signature `fn() -> ()`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/in-assoc-type-unconstrained.rs:22:12
-   |
-LL |         fn method() -> () {}
-   |            ^^^^^^
 help: change the output type to match the trait
    |
 LL -         fn method() -> () {}
diff --git a/tests/ui/impl-trait/in-assoc-type.stderr b/tests/ui/impl-trait/in-assoc-type.stderr
index d5b543ea953..5a8cc40d027 100644
--- a/tests/ui/impl-trait/in-assoc-type.stderr
+++ b/tests/ui/impl-trait/in-assoc-type.stderr
@@ -11,11 +11,6 @@ LL |     fn foo(&self) -> <Self as Foo<()>>::Bar {}
    |
    = note: expected opaque type `<() as Foo<()>>::Bar`
                 found unit type `()`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/in-assoc-type.rs:20:8
-   |
-LL |     fn foo(&self) -> <Self as Foo<()>>::Bar {}
-   |        ^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/issue-108591.rs b/tests/ui/impl-trait/issue-108591.rs
index caf08024568..db1c73831ee 100644
--- a/tests/ui/impl-trait/issue-108591.rs
+++ b/tests/ui/impl-trait/issue-108591.rs
@@ -15,6 +15,7 @@ impl MyTy<'_> {
 
 type Opaque2 = impl Sized;
 type Opaque<'a> = Opaque2;
+#[define_opaque(Opaque)]
 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 7db2e31549c..facb8be9d23 100644
--- a/tests/ui/impl-trait/issue-108592.rs
+++ b/tests/ui/impl-trait/issue-108592.rs
@@ -11,13 +11,10 @@ fn test_closure() {
     closure(&opaque());
 }
 
-mod helper {
-    pub type Opaque2 = impl Sized;
-    pub type Opaque<'a> = Opaque2;
-    fn define<'a>() -> Opaque<'a> {}
-}
-
-use helper::*;
+pub type Opaque2 = impl Sized;
+pub type Opaque<'a> = Opaque2;
+#[define_opaque(Opaque)]
+fn define<'a>() -> Opaque<'a> {}
 
 fn test_tait(_: &Opaque<'_>) {
     None::<&'static Opaque<'_>>;
diff --git a/tests/ui/impl-trait/issue-99642-2.rs b/tests/ui/impl-trait/issue-99642-2.rs
index acbf3e3e2a0..d8d367a5d35 100644
--- a/tests/ui/impl-trait/issue-99642-2.rs
+++ b/tests/ui/impl-trait/issue-99642-2.rs
@@ -2,7 +2,8 @@
 
 #![feature(type_alias_impl_trait)]
 type Opq = impl Sized;
+#[define_opaque(Opq)]
 fn test() -> impl Iterator<Item = Opq> {
     Box::new(0..) as Box<dyn Iterator<Item = _>>
 }
-fn main(){}
+fn main() {}
diff --git a/tests/ui/impl-trait/issues/issue-53457.rs b/tests/ui/impl-trait/issues/issue-53457.rs
index bb248ef7177..a47c7655058 100644
--- a/tests/ui/impl-trait/issues/issue-53457.rs
+++ b/tests/ui/impl-trait/issues/issue-53457.rs
@@ -7,6 +7,7 @@ fn bar<F: Fn(&i32) + Clone>(f: F) -> F {
     f
 }
 
+#[define_opaque(X)]
 fn foo() -> X {
     bar(|_| ())
 }
diff --git a/tests/ui/impl-trait/issues/issue-70877.rs b/tests/ui/impl-trait/issues/issue-70877.rs
index 6ced0bbba8b..0f0a1b5187d 100644
--- a/tests/ui/impl-trait/issues/issue-70877.rs
+++ b/tests/ui/impl-trait/issues/issue-70877.rs
@@ -15,27 +15,27 @@ impl Iterator for Bar {
     }
 }
 
-mod ret {
-    pub type FooRet = impl std::fmt::Debug;
-    pub fn quux(st: super::FooArg) -> FooRet {
-        Some(st.to_string())
-    }
+pub type FooRet = impl std::fmt::Debug;
+#[define_opaque(FooRet)]
+pub fn quux(st: FooArg) -> FooRet {
+    Some(st.to_string())
 }
-use ret::*;
-mod foo {
-    pub type Foo = impl Iterator<Item = super::FooItem>;
-    pub fn ham() -> Foo {
-        super::Bar(1)
-    }
-    pub fn oof(_: Foo) -> impl std::fmt::Debug {
-        //~^ ERROR: item does not constrain `Foo::{opaque#0}`, but has it in its signature
-        let mut bar = ham();
-        let func = bar.next().unwrap();
-        return func(&"oof");
-    }
+pub type Foo = impl Iterator<Item = FooItem>;
+#[define_opaque(Foo)]
+pub fn ham() -> Foo {
+    //~^ ERROR: item does not constrain `FooRet::{opaque#0}`
+    Bar(1)
+}
+#[define_opaque(Foo)]
+pub fn oof() -> impl std::fmt::Debug {
+    //~^ ERROR: item does not constrain `FooRet::{opaque#0}`
+    //~| ERROR: item does not constrain `Foo::{opaque#0}`
+    let mut bar = ham();
+    let func = bar.next().unwrap();
+    return func(&"oof");
+    //~^ ERROR: opaque type's hidden type cannot be another opaque type
 }
-use foo::*;
 
 fn main() {
-    let _ = oof(ham());
+    let _ = oof();
 }
diff --git a/tests/ui/impl-trait/issues/issue-70877.stderr b/tests/ui/impl-trait/issues/issue-70877.stderr
index 4b23a02aaee..b2f37c8af9e 100644
--- a/tests/ui/impl-trait/issues/issue-70877.stderr
+++ b/tests/ui/impl-trait/issues/issue-70877.stderr
@@ -1,15 +1,58 @@
-error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-70877.rs:30:12
+error: item does not constrain `FooRet::{opaque#0}`
+  --> $DIR/issue-70877.rs:25:8
    |
-LL |     pub fn oof(_: Foo) -> impl std::fmt::Debug {
-   |            ^^^
+LL | pub fn ham() -> Foo {
+   |        ^^^
    |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
-  --> $DIR/issue-70877.rs:26:20
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/issue-70877.rs:18:19
    |
-LL |     pub type Foo = impl Iterator<Item = super::FooItem>;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | pub type FooRet = impl std::fmt::Debug;
+   |                   ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: item does not constrain `FooRet::{opaque#0}`
+  --> $DIR/issue-70877.rs:30:8
+   |
+LL | pub fn oof() -> impl std::fmt::Debug {
+   |        ^^^
+   |
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/issue-70877.rs:18:19
+   |
+LL | pub type FooRet = impl std::fmt::Debug;
+   |                   ^^^^^^^^^^^^^^^^^^^^
+
+error: item does not constrain `Foo::{opaque#0}`
+  --> $DIR/issue-70877.rs:30:8
+   |
+LL | pub fn oof() -> impl std::fmt::Debug {
+   |        ^^^
+   |
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/issue-70877.rs:23:16
+   |
+LL | pub type Foo = impl Iterator<Item = FooItem>;
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: opaque type's hidden type cannot be another opaque type from the same scope
+  --> $DIR/issue-70877.rs:35:12
+   |
+LL |     return func(&"oof");
+   |            ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
+   |
+note: opaque type whose hidden type is being assigned
+  --> $DIR/issue-70877.rs:30:17
+   |
+LL | pub fn oof() -> impl std::fmt::Debug {
+   |                 ^^^^^^^^^^^^^^^^^^^^
+note: opaque type being used as hidden type
+  --> $DIR/issue-70877.rs:18:19
+   |
+LL | pub type FooRet = impl std::fmt::Debug;
+   |                   ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/impl-trait/issues/issue-74282.rs b/tests/ui/impl-trait/issues/issue-74282.rs
index 51bd5f67ed5..eb14a76a069 100644
--- a/tests/ui/impl-trait/issues/issue-74282.rs
+++ b/tests/ui/impl-trait/issues/issue-74282.rs
@@ -3,7 +3,8 @@
 type Closure = impl Fn() -> u64;
 struct Anonymous(Closure);
 
-fn bop(_: Closure) {
+#[define_opaque(Closure)]
+fn bop() {
     let y = || -> Closure { || 3 };
     Anonymous(|| {
         //~^ ERROR mismatched types
diff --git a/tests/ui/impl-trait/issues/issue-74282.stderr b/tests/ui/impl-trait/issues/issue-74282.stderr
index f8e85f7ae00..7a49041cace 100644
--- a/tests/ui/impl-trait/issues/issue-74282.stderr
+++ b/tests/ui/impl-trait/issues/issue-74282.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-74282.rs:8:15
+  --> $DIR/issue-74282.rs:9:15
    |
 LL |   type Closure = impl Fn() -> u64;
    |                  ---------------- the expected opaque type
@@ -14,7 +14,7 @@ LL | |     })
    | |_____^ expected opaque type, found closure
    |
    = note: expected opaque type `Closure`
-                  found closure `{closure@$DIR/issue-74282.rs:8:15: 8:17}`
+                  found closure `{closure@$DIR/issue-74282.rs:9:15: 9:17}`
    = note: no two closures, even if identical, have the same type
    = help: consider boxing your closure and/or using it as a trait object
 note: tuple struct defined here
@@ -24,7 +24,7 @@ LL | struct Anonymous(Closure);
    |        ^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/issue-74282.rs:8:5
+  --> $DIR/issue-74282.rs:9:5
    |
 LL | /     Anonymous(|| {
 LL | |
@@ -38,8 +38,8 @@ LL |     });
    |       +
 help: try adding a return type
    |
-LL | fn bop(_: Closure) -> Anonymous {
-   |                    ++++++++++++
+LL | fn bop() -> Anonymous {
+   |          ++++++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/impl-trait/issues/issue-77987.rs b/tests/ui/impl-trait/issues/issue-77987.rs
index a7e7b067d5f..f134224071f 100644
--- a/tests/ui/impl-trait/issues/issue-77987.rs
+++ b/tests/ui/impl-trait/issues/issue-77987.rs
@@ -5,17 +5,16 @@
 pub trait Foo<T> {}
 impl<T, U> Foo<T> for U {}
 
-mod scope {
-    pub type Scope = impl super::Foo<()>;
+pub type Scope = impl Foo<()>;
 
-    #[allow(unused)]
-    fn infer_scope() -> Scope {
-        ()
-    }
+#[allow(unused)]
+#[define_opaque(Scope)]
+fn infer_scope() -> Scope {
+    ()
 }
 
 #[allow(unused)]
-fn ice() -> impl Foo<scope::Scope> {
+fn ice() -> impl Foo<Scope> {
     loop {}
 }
 
diff --git a/tests/ui/impl-trait/issues/issue-78722-2.rs b/tests/ui/impl-trait/issues/issue-78722-2.rs
index e811620c03b..ef4d26b6975 100644
--- a/tests/ui/impl-trait/issues/issue-78722-2.rs
+++ b/tests/ui/impl-trait/issues/issue-78722-2.rs
@@ -8,6 +8,7 @@ type F = impl core::future::Future<Output = u8>;
 
 struct Bug {
     V1: [(); {
+        #[define_opaque(F)]
         fn concrete_use() -> F {
             //~^ ERROR future that resolves to `u8`, but it resolves to `()`
             async {}
diff --git a/tests/ui/impl-trait/issues/issue-78722-2.stderr b/tests/ui/impl-trait/issues/issue-78722-2.stderr
index 27b4b712830..ede830bf72c 100644
--- a/tests/ui/impl-trait/issues/issue-78722-2.stderr
+++ b/tests/ui/impl-trait/issues/issue-78722-2.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-78722-2.rs:16:20
+  --> $DIR/issue-78722-2.rs:17:20
    |
 LL | type F = impl core::future::Future<Output = u8>;
    |          -------------------------------------- the expected future
@@ -10,10 +10,10 @@ LL |         let f: F = async { 1 };
    |                expected due to this
    |
    = note: expected opaque type `F`
-            found `async` block `{async block@$DIR/issue-78722-2.rs:16:20: 16:25}`
+            found `async` block `{async block@$DIR/issue-78722-2.rs:17:20: 17:25}`
 
-error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:13:13: 13:18}` to be a future that resolves to `u8`, but it resolves to `()`
-  --> $DIR/issue-78722-2.rs:11:30
+error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:14:13: 14:18}` to be a future that resolves to `u8`, but it resolves to `()`
+  --> $DIR/issue-78722-2.rs:12:30
    |
 LL |         fn concrete_use() -> F {
    |                              ^ expected `u8`, found `()`
diff --git a/tests/ui/impl-trait/issues/issue-78722.rs b/tests/ui/impl-trait/issues/issue-78722.rs
index 5518c2cf12a..374cd564b8e 100644
--- a/tests/ui/impl-trait/issues/issue-78722.rs
+++ b/tests/ui/impl-trait/issues/issue-78722.rs
@@ -5,6 +5,7 @@
 struct Bug {
     V1: [(); {
         type F = impl core::future::Future<Output = u8>;
+        #[define_opaque(F)]
         fn concrete_use() -> F {
             //~^ ERROR to be a future that resolves to `u8`, but it resolves to `()`
             async {}
diff --git a/tests/ui/impl-trait/issues/issue-78722.stderr b/tests/ui/impl-trait/issues/issue-78722.stderr
index 109bda0c5cd..84c7dfb0338 100644
--- a/tests/ui/impl-trait/issues/issue-78722.stderr
+++ b/tests/ui/impl-trait/issues/issue-78722.stderr
@@ -1,5 +1,5 @@
 error[E0658]: `async` blocks are not allowed in constants
-  --> $DIR/issue-78722.rs:12:20
+  --> $DIR/issue-78722.rs:13:20
    |
 LL |         let f: F = async { 1 };
    |                    ^^^^^^^^^^^
@@ -8,8 +8,8 @@ LL |         let f: F = async { 1 };
    = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0271]: expected `{async block@$DIR/issue-78722.rs:10:13: 10:18}` to be a future that resolves to `u8`, but it resolves to `()`
-  --> $DIR/issue-78722.rs:8:30
+error[E0271]: expected `{async block@$DIR/issue-78722.rs:11:13: 11:18}` to be a future that resolves to `u8`, but it resolves to `()`
+  --> $DIR/issue-78722.rs:9:30
    |
 LL |         fn concrete_use() -> F {
    |                              ^ expected `u8`, found `()`
diff --git a/tests/ui/impl-trait/issues/issue-86201.rs b/tests/ui/impl-trait/issues/issue-86201.rs
index cde0b861160..19c68f7697b 100644
--- a/tests/ui/impl-trait/issues/issue-86201.rs
+++ b/tests/ui/impl-trait/issues/issue-86201.rs
@@ -4,10 +4,13 @@
 //@ check-pass
 
 type FunType = impl Fn<()>;
-static STATIC_FN: FunType = some_fn;
+#[define_opaque(FunType)]
+fn foo() -> FunType {
+    some_fn
+}
 
 fn some_fn() {}
 
 fn main() {
-    let _: <FunType as FnOnce<()>>::Output = STATIC_FN();
+    let _: <FunType as FnOnce<()>>::Output = foo()();
 }
diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs
index ff1d273ae48..c1176255f24 100644
--- a/tests/ui/impl-trait/issues/issue-86800.rs
+++ b/tests/ui/impl-trait/issues/issue-86800.rs
@@ -4,43 +4,41 @@
 
 use std::future::Future;
 
-struct Connection {
-}
+struct Connection {}
 
-trait Transaction {
-}
+trait Transaction {}
 
 struct TestTransaction<'conn> {
-    conn: &'conn Connection
+    conn: &'conn Connection,
 }
 
-impl<'conn> Transaction for TestTransaction<'conn> {
-}
+impl<'conn> Transaction for TestTransaction<'conn> {}
 
-struct Context {
-}
+struct Context {}
 
 type TransactionResult<O> = Result<O, ()>;
 
 type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
 
+#[define_opaque(TransactionFuture)]
 fn execute_transaction_fut<'f, F, O>(
     //~^ ERROR: item does not constrain
     f: F,
 ) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>
 where
-    F: FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + 'f
+    F: FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + 'f,
 {
     f
     //~^ ERROR expected generic lifetime parameter, found `'_`
 }
 
 impl Context {
+    #[define_opaque(TransactionFuture)]
     async fn do_transaction<O>(
         //~^ ERROR: item does not constrain
-        &self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>
-    ) -> TransactionResult<O>
-    {
+        &self,
+        f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>,
+    ) -> TransactionResult<O> {
         //~^ ERROR expected generic lifetime parameter, found `'_`
         //~| ERROR: item does not constrain
         let mut conn = Connection {};
diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr
index fd9b8e7ac99..11e23d97d72 100644
--- a/tests/ui/impl-trait/issues/issue-86800.stderr
+++ b/tests/ui/impl-trait/issues/issue-86800.stderr
@@ -1,33 +1,34 @@
-error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-86800.rs:27:4
+error: item does not constrain `TransactionFuture::{opaque#0}`
+  --> $DIR/issue-86800.rs:24:4
    |
 LL | fn execute_transaction_fut<'f, F, O>(
    |    ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
-  --> $DIR/issue-86800.rs:25:34
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/issue-86800.rs:21:34
    |
 LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-86800.rs:39:14
+error: item does not constrain `TransactionFuture::{opaque#0}`
+  --> $DIR/issue-86800.rs:37:14
    |
 LL |     async fn do_transaction<O>(
    |              ^^^^^^^^^^^^^^
    |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
-  --> $DIR/issue-86800.rs:25:34
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/issue-86800.rs:21:34
    |
 LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-86800.rs:43:5
+error: item does not constrain `TransactionFuture::{opaque#0}`
+  --> $DIR/issue-86800.rs:41:31
    |
-LL | /     {
+LL |       ) -> TransactionResult<O> {
+   |  _______________________________^
 LL | |
 LL | |
 LL | |         let mut conn = Connection {};
@@ -36,15 +37,15 @@ LL | |         f(&mut transaction).await
 LL | |     }
    | |_____^
    |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
-  --> $DIR/issue-86800.rs:25:34
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/issue-86800.rs:21:34
    |
 LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/issue-86800.rs:34:5
+  --> $DIR/issue-86800.rs:31:5
    |
 LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
    |                        --- this generic parameter must be used with a generic lifetime parameter
@@ -53,12 +54,13 @@ LL |     f
    |     ^
 
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/issue-86800.rs:43:5
+  --> $DIR/issue-86800.rs:41:31
    |
 LL |   type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
    |                          --- this generic parameter must be used with a generic lifetime parameter
 ...
-LL | /     {
+LL |       ) -> TransactionResult<O> {
+   |  _______________________________^
 LL | |
 LL | |
 LL | |         let mut conn = Connection {};
diff --git a/tests/ui/impl-trait/issues/issue-89312.rs b/tests/ui/impl-trait/issues/issue-89312.rs
index 3b0e976780b..35cba41dd4b 100644
--- a/tests/ui/impl-trait/issues/issue-89312.rs
+++ b/tests/ui/impl-trait/issues/issue-89312.rs
@@ -2,23 +2,21 @@
 
 //@ check-pass
 
-mod helper {
-    pub trait T {
-        type Item;
-    }
+pub trait T {
+    type Item;
+}
 
-    pub type Alias<'a> = impl T<Item = &'a ()>;
+pub type Alias<'a> = impl T<Item = &'a ()>;
 
-    struct S;
-    impl<'a> T for &'a S {
-        type Item = &'a ();
-    }
+struct S;
+impl<'a> T for &'a S {
+    type Item = &'a ();
+}
 
-    pub fn filter_positive<'a>() -> Alias<'a> {
-        &S
-    }
+#[define_opaque(Alias)]
+pub fn filter_positive<'a>() -> Alias<'a> {
+    &S
 }
-use helper::*;
 
 fn with_positive(fun: impl Fn(Alias<'_>)) {
     fun(filter_positive());
diff --git a/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs b/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs
index b05579f2166..e19230b44b4 100644
--- a/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs
+++ b/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs
@@ -21,6 +21,7 @@ trait Bar {
     type Other;
 }
 
+#[define_opaque(Tait)]
 fn tait() -> Tait {}
 
 fn main() {}
diff --git a/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.rs b/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.rs
index 2a2be6b7429..21ca558153d 100644
--- a/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.rs
+++ b/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.rs
@@ -7,6 +7,7 @@ impl<T: Copy> Copy for CopyIfEq<T, T> {}
 
 type E<'a, 'b> = impl Sized;
 
+#[define_opaque(E)]
 fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
     let v = CopyIfEq::<*mut _, *mut _>(&mut { x }, &mut y);
 
diff --git a/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr b/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr
index b968592beff..712cbbecd74 100644
--- a/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr
+++ b/tests/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr
@@ -1,9 +1,9 @@
 error[E0700]: hidden type for `E<'b, 'c>` captures lifetime that does not appear in bounds
-  --> $DIR/error-handling-2.rs:22:5
+  --> $DIR/error-handling-2.rs:23:5
    |
 LL | type E<'a, 'b> = impl Sized;
    |                  ---------- opaque type defined here
-LL |
+...
 LL | fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
    |        -- hidden type `*mut &'a i32` captures the lifetime `'a` as defined here
 ...
diff --git a/tests/ui/impl-trait/multiple-lifetimes/error-handling.rs b/tests/ui/impl-trait/multiple-lifetimes/error-handling.rs
index 367e7f4e6ea..0f3b7506318 100644
--- a/tests/ui/impl-trait/multiple-lifetimes/error-handling.rs
+++ b/tests/ui/impl-trait/multiple-lifetimes/error-handling.rs
@@ -7,6 +7,7 @@ impl<T: Copy> Copy for CopyIfEq<T, T> {}
 
 type E<'a, 'b> = impl Sized;
 
+#[define_opaque(E)]
 fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
     let v = CopyIfEq::<*mut _, *mut _>(&mut { x }, &mut y);
 
diff --git a/tests/ui/impl-trait/multiple-lifetimes/error-handling.stderr b/tests/ui/impl-trait/multiple-lifetimes/error-handling.stderr
index 945fb0fc618..3732307ca35 100644
--- a/tests/ui/impl-trait/multiple-lifetimes/error-handling.stderr
+++ b/tests/ui/impl-trait/multiple-lifetimes/error-handling.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/error-handling.rs:20:16
+  --> $DIR/error-handling.rs:21:16
    |
 LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
    |        --  -- lifetime `'b` defined here
diff --git a/tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs b/tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs
index 6f90160866b..6a1cb61b8ba 100644
--- a/tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs
+++ b/tests/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs
@@ -10,6 +10,7 @@ impl<T> Trait<'_, '_> for T {}
 
 type Foo<'a, 'b> = impl Trait<'a, 'b>;
 
+#[define_opaque(Foo)]
 fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> {
     // In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like
     //
diff --git a/tests/ui/impl-trait/negative-reasoning.rs b/tests/ui/impl-trait/negative-reasoning.rs
index 0474dc0beda..0d4a1ba75d8 100644
--- a/tests/ui/impl-trait/negative-reasoning.rs
+++ b/tests/ui/impl-trait/negative-reasoning.rs
@@ -5,6 +5,7 @@
 trait OpaqueTrait {}
 impl<T> OpaqueTrait for T {}
 type OpaqueType = impl OpaqueTrait;
+#[define_opaque(OpaqueType)]
 fn mk_opaque() -> OpaqueType {
     ()
 }
diff --git a/tests/ui/impl-trait/negative-reasoning.stderr b/tests/ui/impl-trait/negative-reasoning.stderr
index 631784c817b..2918be5135c 100644
--- a/tests/ui/impl-trait/negative-reasoning.stderr
+++ b/tests/ui/impl-trait/negative-reasoning.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>`
-  --> $DIR/negative-reasoning.rs:19:1
+  --> $DIR/negative-reasoning.rs:20:1
    |
 LL | impl<T: std::fmt::Debug> AnotherTrait for T {}
    | ------------------------------------------- first implementation here
diff --git a/tests/ui/impl-trait/nested-return-type2-tait.rs b/tests/ui/impl-trait/nested-return-type2-tait.rs
index 7cb98cfe060..aa871df9d9c 100644
--- a/tests/ui/impl-trait/nested-return-type2-tait.rs
+++ b/tests/ui/impl-trait/nested-return-type2-tait.rs
@@ -25,10 +25,10 @@ type Sendable = impl Send;
 // the hidden type. We already have obligations registered on the inference
 // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
 // type does not implement `Duh`, but if its hidden type does.
+#[define_opaque(Sendable)]
 fn foo() -> impl Trait<Assoc = Sendable> {
     //~^ WARN opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds
     || 42
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/impl-trait/nested-return-type2-tait.stderr b/tests/ui/impl-trait/nested-return-type2-tait.stderr
index 4383e8ab3a0..8105990eac4 100644
--- a/tests/ui/impl-trait/nested-return-type2-tait.stderr
+++ b/tests/ui/impl-trait/nested-return-type2-tait.stderr
@@ -1,5 +1,5 @@
 warning: opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds
-  --> $DIR/nested-return-type2-tait.rs:28:24
+  --> $DIR/nested-return-type2-tait.rs:29:24
    |
 LL |     type Assoc: Duh;
    |                 --- this associated type bound is unsatisfied for `Sendable`
diff --git a/tests/ui/impl-trait/nested-return-type2-tait2.rs b/tests/ui/impl-trait/nested-return-type2-tait2.rs
index 574602079d4..bd89dad7dfd 100644
--- a/tests/ui/impl-trait/nested-return-type2-tait2.rs
+++ b/tests/ui/impl-trait/nested-return-type2-tait2.rs
@@ -26,9 +26,9 @@ type Traitable = impl Trait<Assoc = Sendable>;
 // the hidden type. We already have obligations registered on the inference
 // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
 // type does not implement `Duh`, even if its hidden type does. So we error out.
+#[define_opaque(Traitable)]
 fn foo() -> Traitable {
     || 42
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/impl-trait/nested-return-type2-tait3.rs b/tests/ui/impl-trait/nested-return-type2-tait3.rs
index e3429731782..83bf441181a 100644
--- a/tests/ui/impl-trait/nested-return-type2-tait3.rs
+++ b/tests/ui/impl-trait/nested-return-type2-tait3.rs
@@ -25,9 +25,9 @@ type Traitable = impl Trait<Assoc = impl Send>;
 // the hidden type. We already have obligations registered on the inference
 // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
 // type does not implement `Duh`, even if its hidden type does. So we error out.
+#[define_opaque(Traitable)]
 fn foo() -> Traitable {
     || 42
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/impl-trait/nested-return-type3-tait.rs b/tests/ui/impl-trait/nested-return-type3-tait.rs
index 05759fb2697..fb2e4d87543 100644
--- a/tests/ui/impl-trait/nested-return-type3-tait.rs
+++ b/tests/ui/impl-trait/nested-return-type3-tait.rs
@@ -16,10 +16,10 @@ impl<F: Duh> Trait for F {
 
 type Sendable = impl Send;
 
+#[define_opaque(Sendable)]
 fn foo() -> impl Trait<Assoc = Sendable> {
     //~^ WARN opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds
     42
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/impl-trait/nested-return-type3-tait.stderr b/tests/ui/impl-trait/nested-return-type3-tait.stderr
index d32944a0d72..bb1f524b992 100644
--- a/tests/ui/impl-trait/nested-return-type3-tait.stderr
+++ b/tests/ui/impl-trait/nested-return-type3-tait.stderr
@@ -1,5 +1,5 @@
 warning: opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds
-  --> $DIR/nested-return-type3-tait.rs:19:24
+  --> $DIR/nested-return-type3-tait.rs:20:24
    |
 LL |     type Assoc: Duh;
    |                 --- this associated type bound is unsatisfied for `Sendable`
diff --git a/tests/ui/impl-trait/nested-return-type3-tait2.rs b/tests/ui/impl-trait/nested-return-type3-tait2.rs
index 927fa8d596b..f3fda61e920 100644
--- a/tests/ui/impl-trait/nested-return-type3-tait2.rs
+++ b/tests/ui/impl-trait/nested-return-type3-tait2.rs
@@ -18,9 +18,9 @@ type Sendable = impl Send;
 type Traitable = impl Trait<Assoc = Sendable>;
 //~^ WARN opaque type `Traitable` does not satisfy its associated type bounds
 
+#[define_opaque(Traitable)]
 fn foo() -> Traitable {
     42
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/impl-trait/nested-return-type3-tait3.rs b/tests/ui/impl-trait/nested-return-type3-tait3.rs
index 5b3b2d2e198..d2acee9cafd 100644
--- a/tests/ui/impl-trait/nested-return-type3-tait3.rs
+++ b/tests/ui/impl-trait/nested-return-type3-tait3.rs
@@ -17,9 +17,9 @@ impl<F: Duh> Trait for F {
 type Traitable = impl Trait<Assoc = impl Send>;
 //~^ WARN opaque type `Traitable` does not satisfy its associated type bounds
 
+#[define_opaque(Traitable)]
 fn foo() -> Traitable {
     42
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr
index c6cd1b139c5..d4ba9a31170 100644
--- a/tests/ui/impl-trait/normalize-tait-in-const.stderr
+++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr
@@ -17,6 +17,14 @@ note: `Fn` can't be used with `~const` because it isn't annotated with `#[const_
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
+error: unconstrained opaque type
+  --> $DIR/normalize-tait-in-const.rs:14:26
+   |
+LL |     pub type Alias<'a> = impl T<Item = &'a ()>;
+   |                          ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Alias` must be used in combination with a concrete type within the same crate
+
 error[E0015]: cannot call non-const closure in constant functions
   --> $DIR/normalize-tait-in-const.rs:28:5
    |
@@ -25,6 +33,26 @@ LL |     fun(filter_positive());
    |
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
-error: aborting due to 3 previous errors
+error[E0308]: mismatched types
+  --> $DIR/normalize-tait-in-const.rs:22:9
+   |
+LL |     pub type Alias<'a> = impl T<Item = &'a ()>;
+   |                          --------------------- the expected opaque type
+...
+LL |     pub const fn filter_positive<'a>() -> &'a Alias<'a> {
+   |                                           ------------- expected `&'a foo::Alias<'a>` because of return type
+LL |         &&S
+   |         ^^^ expected `&Alias<'_>`, found `&&S`
+   |
+   = note: expected reference `&'a foo::Alias<'a>`
+              found reference `&&S`
+note: this item must have a `#[define_opaque(foo::Alias)]` attribute to be able to define hidden types
+  --> $DIR/normalize-tait-in-const.rs:21:18
+   |
+LL |     pub const fn filter_positive<'a>() -> &'a Alias<'a> {
+   |                  ^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0015`.
+Some errors have detailed explanations: E0015, E0308.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
index 0b29af5df5b..662c7ee2ecf 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
@@ -2,14 +2,12 @@
 
 //@ check-pass
 
-mod foo {
-    pub type Foo = impl PartialEq<(Foo, i32)>;
+pub type Foo = impl PartialEq<(Foo, i32)>;
 
-    fn foo() -> Foo {
-        super::Bar
-    }
+#[define_opaque(Foo)]
+fn foo() -> Foo {
+    Bar
 }
-use foo::Foo;
 
 struct Bar;
 
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
index 3f41c5984b4..5b9c40ecede 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
@@ -6,6 +6,7 @@ mod a {
     struct Bar;
 
     impl PartialEq<(Bar, i32)> for Bar {
+        #[define_opaque(Foo)]
         fn eq(&self, _other: &(Foo, i32)) -> bool {
             //~^ ERROR: `eq` has an incompatible type for trait
             //~| ERROR: item does not constrain `a::Foo::{opaque#0}`
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index 767bd312407..7f642fa1bed 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -1,5 +1,5 @@
 error[E0053]: method `eq` has an incompatible type for trait
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:9:30
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:30
    |
 LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                -------------------------- the found opaque type
@@ -15,21 +15,21 @@ LL -         fn eq(&self, _other: &(Foo, i32)) -> bool {
 LL +         fn eq(&self, _other: &(a::Bar, i32)) -> bool {
    |
 
-error: item does not constrain `a::Foo::{opaque#0}`, but has it in its signature
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:9:12
+error: item does not constrain `a::Foo::{opaque#0}`
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
    |
 LL |         fn eq(&self, _other: &(Foo, i32)) -> bool {
    |            ^^
    |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
   --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
    |
 LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0053]: method `eq` has an incompatible type for trait
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:30
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:30
    |
 LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                -------------------------- the expected opaque type
@@ -39,8 +39,8 @@ LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
    |
    = note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _`
               found signature `fn(&b::Bar, &(b::Bar, _)) -> _`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:12
+note: this item must have a `#[define_opaque(b::Foo)]` attribute to be able to define hidden types
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:12
    |
 LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
    |            ^^
@@ -51,12 +51,12 @@ LL +         fn eq(&self, _other: &(b::Foo, i32)) -> bool {
    |
 
 error: unconstrained opaque type
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
    |
 LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `Foo` must be used in combination with a concrete type within the same module
+   = note: `Foo` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs
index aab10be2de2..372a095192b 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs
@@ -10,6 +10,7 @@ impl PartialEq<(Bar, i32)> for Bar {
     }
 }
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     //~^ ERROR can't compare `Bar` with `(Foo, i32)`
     Bar
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr
index bc810c0f88f..a9a5483caa9 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Bar` with `(Foo, i32)`
-  --> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13
+  --> $DIR/recursive-type-alias-impl-trait-declaration.rs:14:13
    |
 LL | fn foo() -> Foo {
    |             ^^^ no implementation for `Bar == (Foo, i32)`
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other.current.stderr
index bf194f997b4..8845b3ff2c8 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other.current.stderr
+++ b/tests/ui/impl-trait/two_tait_defining_each_other.current.stderr
@@ -1,5 +1,5 @@
 error: opaque type's hidden type cannot be another opaque type from the same scope
-  --> $DIR/two_tait_defining_each_other.rs:17:5
+  --> $DIR/two_tait_defining_each_other.rs:18:5
    |
 LL |     x // A's hidden type is `Bar`, because all the hidden types of `B` are compared with each other
    |     ^ one of the two opaque types used here has to be outside its defining scope
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other.rs b/tests/ui/impl-trait/two_tait_defining_each_other.rs
index ebfe7f674be..d3038688eee 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other.rs
+++ b/tests/ui/impl-trait/two_tait_defining_each_other.rs
@@ -10,6 +10,7 @@ type B = impl Foo;
 
 trait Foo {}
 
+#[define_opaque(A, B)]
 fn muh(x: A) -> B {
     if false {
         return Bar; // B's hidden type is Bar
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr
index 7d02a0606fc..0711af1cad4 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr
+++ b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr
@@ -1,18 +1,18 @@
-error: item does not constrain `A::{opaque#0}`, but has it in its signature
-  --> $DIR/two_tait_defining_each_other2.rs:11:4
+error: item does not constrain `A::{opaque#0}`
+  --> $DIR/two_tait_defining_each_other2.rs:12:4
    |
 LL | fn muh(x: A) -> B {
    |    ^^^
    |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
   --> $DIR/two_tait_defining_each_other2.rs:6:10
    |
 LL | type A = impl Foo;
    |          ^^^^^^^^
 
 error: opaque type's hidden type cannot be another opaque type from the same scope
-  --> $DIR/two_tait_defining_each_other2.rs:14:5
+  --> $DIR/two_tait_defining_each_other2.rs:15:5
    |
 LL |     x // B's hidden type is A (opaquely)
    |     ^ one of the two opaque types used here has to be outside its defining scope
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr
index 5316160125b..1a4c0f5f7ee 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr
+++ b/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr
@@ -1,5 +1,5 @@
 error[E0284]: type annotations needed: cannot satisfy `_ == A`
-  --> $DIR/two_tait_defining_each_other2.rs:11:8
+  --> $DIR/two_tait_defining_each_other2.rs:12:8
    |
 LL | fn muh(x: A) -> B {
    |        ^ cannot satisfy `_ == A`
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.rs b/tests/ui/impl-trait/two_tait_defining_each_other2.rs
index 1681b019418..a3223b07a7e 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs
+++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs
@@ -8,6 +8,7 @@ type B = impl Foo;
 
 trait Foo {}
 
+#[define_opaque(A, B)]
 fn muh(x: A) -> B {
     //[current]~^ ERROR: item does not constrain `A::{opaque#0}`
     //[next]~^^ ERROR: cannot satisfy `_ == A`
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other3.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other3.current.stderr
index fa353a77536..7b0003ff59b 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other3.current.stderr
+++ b/tests/ui/impl-trait/two_tait_defining_each_other3.current.stderr
@@ -1,5 +1,5 @@
 error: opaque type's hidden type cannot be another opaque type from the same scope
-  --> $DIR/two_tait_defining_each_other3.rs:14:16
+  --> $DIR/two_tait_defining_each_other3.rs:15:16
    |
 LL |         return x;  // B's hidden type is A (opaquely)
    |                ^ one of the two opaque types used here has to be outside its defining scope
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other3.rs b/tests/ui/impl-trait/two_tait_defining_each_other3.rs
index 33695d8ed80..ec3cd58a3a5 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other3.rs
+++ b/tests/ui/impl-trait/two_tait_defining_each_other3.rs
@@ -9,6 +9,7 @@ type B = impl Foo;
 
 trait Foo {}
 
+#[define_opaque(A, B)]
 fn muh(x: A) -> B {
     if false {
         return x;  // B's hidden type is A (opaquely)
diff --git a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs
index 4879d2db40b..77b2407e304 100644
--- a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs
+++ b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs
@@ -9,6 +9,7 @@ fn main() {
     //~^ ERROR: item does not constrain
     type Existential = impl Debug;
 
+    #[define_opaque(Existential)]
     fn f() -> Existential {}
     println!("{:?}", f());
 }
diff --git a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr
index 7744fa2f2ae..0877b4b71be 100644
--- a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr
+++ b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr
@@ -1,11 +1,11 @@
-error: item does not constrain `Existential::{opaque#0}`, but has it in its signature
+error: item does not constrain `Existential::{opaque#0}`
   --> $DIR/type-alias-impl-trait-in-fn-body.rs:8:4
    |
 LL | fn main() {
    |    ^^^^
    |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
   --> $DIR/type-alias-impl-trait-in-fn-body.rs:10:24
    |
 LL |     type Existential = impl Debug;
diff --git a/tests/ui/impl-trait/where-allowed.rs b/tests/ui/impl-trait/where-allowed.rs
index 3f435f0f443..1c3c66c537f 100644
--- a/tests/ui/impl-trait/where-allowed.rs
+++ b/tests/ui/impl-trait/where-allowed.rs
@@ -157,6 +157,7 @@ extern "C" fn in_extern_fn_return() -> impl Debug {
 
 type InTypeAlias<R> = impl Debug;
 //~^ ERROR `impl Trait` in type aliases is unstable
+//~| ERROR unconstrained opaque type
 
 type InReturnInTypeAlias<R> = fn() -> impl Debug;
 //~^ ERROR `impl Trait` is not allowed in `fn` pointer
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index ebce9b7e445..052ae5a9931 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -37,7 +37,7 @@ LL | type InTypeAlias<R> = impl Debug;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:161:39
+  --> $DIR/where-allowed.rs:162:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
@@ -199,7 +199,7 @@ LL |     fn in_foreign_return() -> impl Debug;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in `fn` pointer return types
-  --> $DIR/where-allowed.rs:161:39
+  --> $DIR/where-allowed.rs:162:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
@@ -207,7 +207,7 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in traits
-  --> $DIR/where-allowed.rs:166:16
+  --> $DIR/where-allowed.rs:167:16
    |
 LL | impl PartialEq<impl Debug> for () {
    |                ^^^^^^^^^^
@@ -215,7 +215,7 @@ LL | impl PartialEq<impl Debug> for () {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in impl headers
-  --> $DIR/where-allowed.rs:171:24
+  --> $DIR/where-allowed.rs:172:24
    |
 LL | impl PartialEq<()> for impl Debug {
    |                        ^^^^^^^^^^
@@ -223,7 +223,7 @@ LL | impl PartialEq<()> for impl Debug {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in impl headers
-  --> $DIR/where-allowed.rs:176:6
+  --> $DIR/where-allowed.rs:177:6
    |
 LL | impl impl Debug {
    |      ^^^^^^^^^^
@@ -231,7 +231,7 @@ LL | impl impl Debug {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in impl headers
-  --> $DIR/where-allowed.rs:182:24
+  --> $DIR/where-allowed.rs:183:24
    |
 LL | impl InInherentImplAdt<impl Debug> {
    |                        ^^^^^^^^^^
@@ -239,7 +239,7 @@ LL | impl InInherentImplAdt<impl Debug> {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in bounds
-  --> $DIR/where-allowed.rs:188:11
+  --> $DIR/where-allowed.rs:189:11
    |
 LL |     where impl Debug: Debug
    |           ^^^^^^^^^^
@@ -247,7 +247,7 @@ LL |     where impl Debug: Debug
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in bounds
-  --> $DIR/where-allowed.rs:195:15
+  --> $DIR/where-allowed.rs:196:15
    |
 LL |     where Vec<impl Debug>: Debug
    |               ^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     where Vec<impl Debug>: Debug
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in bounds
-  --> $DIR/where-allowed.rs:202:24
+  --> $DIR/where-allowed.rs:203:24
    |
 LL |     where T: PartialEq<impl Debug>
    |                        ^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     where T: PartialEq<impl Debug>
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the parameters of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:209:17
+  --> $DIR/where-allowed.rs:210:17
    |
 LL |     where T: Fn(impl Debug)
    |                 ^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |     where T: Fn(impl Debug)
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the return type of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:216:22
+  --> $DIR/where-allowed.rs:217:22
    |
 LL |     where T: Fn() -> impl Debug
    |                      ^^^^^^^^^^
@@ -279,7 +279,7 @@ LL |     where T: Fn() -> impl Debug
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:222:40
+  --> $DIR/where-allowed.rs:223:40
    |
 LL | struct InStructGenericParamDefault<T = impl Debug>(T);
    |                                        ^^^^^^^^^^
@@ -287,7 +287,7 @@ LL | struct InStructGenericParamDefault<T = impl Debug>(T);
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:226:36
+  --> $DIR/where-allowed.rs:227:36
    |
 LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
    |                                    ^^^^^^^^^^
@@ -295,7 +295,7 @@ LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:230:38
+  --> $DIR/where-allowed.rs:231:38
    |
 LL | trait InTraitGenericParamDefault<T = impl Debug> {}
    |                                      ^^^^^^^^^^
@@ -303,7 +303,7 @@ LL | trait InTraitGenericParamDefault<T = impl Debug> {}
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:234:41
+  --> $DIR/where-allowed.rs:235:41
    |
 LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
    |                                         ^^^^^^^^^^
@@ -311,7 +311,7 @@ LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:238:11
+  --> $DIR/where-allowed.rs:239:11
    |
 LL | impl <T = impl Debug> T {}
    |           ^^^^^^^^^^
@@ -319,7 +319,7 @@ LL | impl <T = impl Debug> T {}
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:245:40
+  --> $DIR/where-allowed.rs:246:40
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                        ^^^^^^^^^^
@@ -327,7 +327,7 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the type of variable bindings
-  --> $DIR/where-allowed.rs:251:29
+  --> $DIR/where-allowed.rs:252:29
    |
 LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
@@ -338,7 +338,7 @@ LL |     let _in_local_variable: impl Fn() = || {};
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0562]: `impl Trait` is not allowed in closure return types
-  --> $DIR/where-allowed.rs:253:46
+  --> $DIR/where-allowed.rs:254:46
    |
 LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
    |                                              ^^^^^^^^^
@@ -369,7 +369,7 @@ LL +     fn in_trait_impl_return() -> <() as DummyTrait>::Out { () }
    |
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:245:36
+  --> $DIR/where-allowed.rs:246:36
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                    ^^^^^^^^^^^^^^
@@ -379,7 +379,7 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    = note: `#[deny(invalid_type_param_default)]` on by default
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:238:7
+  --> $DIR/where-allowed.rs:239:7
    |
 LL | impl <T = impl Debug> T {}
    |       ^^^^^^^^^^^^^^
@@ -408,7 +408,7 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani
              where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
 
 error[E0118]: no nominal type found for inherent implementation
-  --> $DIR/where-allowed.rs:238:1
+  --> $DIR/where-allowed.rs:239:1
    |
 LL | impl <T = impl Debug> T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
@@ -423,13 +423,21 @@ LL |     type Out = impl Debug;
    |
    = note: `Out` must be used in combination with a concrete type within the same impl
 
-error: aborting due to 49 previous errors
+error: unconstrained opaque type
+  --> $DIR/where-allowed.rs:158:23
+   |
+LL | type InTypeAlias<R> = impl Debug;
+   |                       ^^^^^^^^^^
+   |
+   = note: `InTypeAlias` must be used in combination with a concrete type within the same crate
+
+error: aborting due to 50 previous errors
 
 Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666.
 For more information about an error, try `rustc --explain E0053`.
 Future incompatibility report: Future breakage diagnostic:
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:245:36
+  --> $DIR/where-allowed.rs:246:36
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                    ^^^^^^^^^^^^^^
@@ -440,7 +448,7 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
 
 Future breakage diagnostic:
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:238:7
+  --> $DIR/where-allowed.rs:239:7
    |
 LL | impl <T = impl Debug> T {}
    |       ^^^^^^^^^^^^^^