about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-07-26 10:04:02 +0000
committerOli Scherer <github333195615777966@oli-obk.de>2025-03-11 12:05:02 +0000
commitcb4751d4b87e1c8ebdeb381abe3785486a59968e (patch)
tree7e40c81d8bbec10bd16102231ac20828f7b0f4f6
parent2c6a12ec44d0426c8939123c2f2cf27d2217de13 (diff)
downloadrust-cb4751d4b87e1c8ebdeb381abe3785486a59968e.tar.gz
rust-cb4751d4b87e1c8ebdeb381abe3785486a59968e.zip
Implement `#[define_opaque]` attribute for functions.
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_ast/src/ast.rs3
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs14
-rw-r--r--compiler/rustc_ast/src/visit.rs14
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs51
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs9
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs5
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs11
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs13
-rw-r--r--compiler/rustc_borrowck/src/type_check/opaque_types.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/alloc_error_handler.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/autodiff.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/define_opaque.rs54
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/example/issue-72793.rs24
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/mod.rs1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0792.md4
-rw-r--r--compiler/rustc_error_messages/src/lib.rs1
-rw-r--r--compiler/rustc_hir/src/hir.rs9
-rw-r--r--compiler/rustc_hir/src/stable_hash_impls.rs2
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl9
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs80
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs10
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs1
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs3
-rw-r--r--compiler/rustc_middle/src/query/erase.rs2
-rw-r--r--compiler/rustc_parse/src/parser/item.rs9
-rw-r--r--compiler/rustc_resolve/src/late.rs67
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs27
-rw-r--r--compiler/rustc_ty_utils/Cargo.toml1
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs129
-rw-r--r--library/core/src/macros/mod.rs15
-rw-r--r--library/core/src/prelude/v1.rs8
-rw-r--r--library/std/src/backtrace.rs1
-rw-r--r--library/std/src/prelude/v1.rs9
-rw-r--r--src/librustdoc/html/render/span_map.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils/mod.rs6
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-10972-tait.rs10
-rw-r--r--src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed1
-rw-r--r--src/tools/clippy/tests/ui/implied_bounds_in_impls.rs1
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs1
-rw-r--r--src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs1
-rw-r--r--src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr2
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs24
-rw-r--r--tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs22
-rw-r--r--tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs88
-rw-r--r--tests/crashes/120016.rs1
-rw-r--r--tests/crashes/122904-2.rs2
-rw-r--r--tests/crashes/122904.rs1
-rw-r--r--tests/crashes/125185.rs14
-rw-r--r--tests/crashes/126680.rs22
-rw-r--r--tests/crashes/131298.rs12
-rw-r--r--tests/crashes/131886.rs5
-rw-r--r--tests/crashes/135528.rs2
-rw-r--r--tests/crashes/137049.rs1
-rw-r--r--tests/ui/associated-inherent-types/constrain_opaque_types_during_projection.rs3
-rw-r--r--tests/ui/associated-inherent-types/issue-109299-1.stderr2
-rw-r--r--tests/ui/associated-type-bounds/dont-imply-atb-in-closure-inference.rs6
-rw-r--r--tests/ui/associated-type-bounds/duplicate.rs6
-rw-r--r--tests/ui/associated-type-bounds/duplicate.stderr126
-rw-r--r--tests/ui/associated-type-bounds/trait-alias-impl-trait.rs4
-rw-r--r--tests/ui/async-await/async-fn/impl-trait.rs5
-rw-r--r--tests/ui/async-await/issues/issue-60655-latebound-regions.rs4
-rw-r--r--tests/ui/async-await/normalize-output-in-signature-deduction.rs1
-rw-r--r--tests/ui/attributes/collapse-debuginfo-invalid.rs19
-rw-r--r--tests/ui/attributes/collapse-debuginfo-invalid.stderr6
-rw-r--r--tests/ui/borrowck/overwrite-anon-late-param-regions.rs1
-rw-r--r--tests/ui/borrowck/overwrite-anon-late-param-regions.stderr4
-rw-r--r--tests/ui/coherence/coherence-with-closure.rs1
-rw-r--r--tests/ui/coherence/coherence-with-closure.stderr2
-rw-r--r--tests/ui/coherence/coherence-with-coroutine.rs1
-rw-r--r--tests/ui/coherence/coherence-with-coroutine.stock.stderr2
-rw-r--r--tests/ui/coherence/issue-99663-2.rs1
-rw-r--r--tests/ui/coherence/issue-99663.rs1
-rw-r--r--tests/ui/coherence/occurs-check/opaques.current.stderr6
-rw-r--r--tests/ui/coherence/occurs-check/opaques.next.stderr12
-rw-r--r--tests/ui/coherence/occurs-check/opaques.rs17
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.rs2
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/opaque_type.rs4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/opaque_type.stderr4
-rw-r--r--tests/ui/const-generics/opaque_types.rs3
-rw-r--r--tests/ui/const-generics/opaque_types.stderr116
-rw-r--r--tests/ui/const-generics/opaque_types2.rs13
-rw-r--r--tests/ui/const-generics/opaque_types2.stderr6
-rw-r--r--tests/ui/consts/const-eval/ice-unhandled-type-122191.rs14
-rw-r--r--tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr33
-rw-r--r--tests/ui/consts/const-promoted-opaque.atomic.stderr8
-rw-r--r--tests/ui/consts/const-promoted-opaque.rs30
-rw-r--r--tests/ui/consts/const-promoted-opaque.string.stderr6
-rw-r--r--tests/ui/consts/const-promoted-opaque.unit.stderr24
-rw-r--r--tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs1
-rw-r--r--tests/ui/coroutine/layout-error.rs24
-rw-r--r--tests/ui/coroutine/layout-error.stderr6
-rw-r--r--tests/ui/coroutine/metadata-sufficient-for-layout.rs1
-rw-r--r--tests/ui/drop/drop_elaboration_with_errors.rs1
-rw-r--r--tests/ui/drop/drop_elaboration_with_errors.stderr2
-rw-r--r--tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs6
-rw-r--r--tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs9
-rw-r--r--tests/ui/fn/fn_def_opaque_coercion.rs5
-rw-r--r--tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs3
-rw-r--r--tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr4
-rw-r--r--tests/ui/generic-associated-types/issue-87258_b.rs1
-rw-r--r--tests/ui/generic-associated-types/issue-87258_b.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-88287.rs1
-rw-r--r--tests/ui/generic-associated-types/issue-88287.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-90014-tait.stderr15
-rw-r--r--tests/ui/generic-associated-types/issue-90014-tait2.rs1
-rw-r--r--tests/ui/generic-associated-types/issue-90014-tait2.stderr2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr10
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs1
-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
-rw-r--r--tests/ui/implied-bounds/dyn-erasure-tait.rs1
-rw-r--r--tests/ui/layout/debug.rs1
-rw-r--r--tests/ui/layout/debug.stderr30
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/branches.rs8
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/branches.stderr2
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/branches2.rs13
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/branches3.rs3
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/branches3.stderr8
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/recursion.rs5
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/recursion2.rs3
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/recursion3.rs5
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/recursion3.stderr4
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/recursion4.rs1
-rw-r--r--tests/ui/lazy-type-alias-impl-trait/recursion4.stderr4
-rw-r--r--tests/ui/lint/issue-99387.rs1
-rw-r--r--tests/ui/lint/issue-99387.stderr6
-rw-r--r--tests/ui/lint/let_underscore/issue-119697-extra-let.rs2
-rw-r--r--tests/ui/lint/let_underscore/issue-119697-extra-let.stderr4
-rw-r--r--tests/ui/lint/lint-ctypes-73249-2.rs1
-rw-r--r--tests/ui/lint/lint-ctypes-73249-2.stderr2
-rw-r--r--tests/ui/lint/lint-ctypes-73249-3.rs1
-rw-r--r--tests/ui/lint/lint-ctypes-73249-3.stderr2
-rw-r--r--tests/ui/lint/lint-ctypes-73249-5.rs1
-rw-r--r--tests/ui/lint/lint-ctypes-73249-5.stderr2
-rw-r--r--tests/ui/lint/lint-ctypes-73251-1.rs1
-rw-r--r--tests/ui/lint/lint-ctypes-73251-1.stderr2
-rw-r--r--tests/ui/lint/lint-ctypes-73251-2.rs2
-rw-r--r--tests/ui/lint/lint-ctypes-73251-2.stderr2
-rw-r--r--tests/ui/lint/lint-ctypes-73251.rs1
-rw-r--r--tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs2
-rw-r--r--tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr2
-rw-r--r--tests/ui/lint/opaque-ty-ffi-unsafe.rs1
-rw-r--r--tests/ui/lint/opaque-ty-ffi-unsafe.stderr2
-rw-r--r--tests/ui/methods/opaque_param_in_ufc.rs2
-rw-r--r--tests/ui/mir/issue-75053.rs12
-rw-r--r--tests/ui/mir/issue-75053.stderr2
-rw-r--r--tests/ui/never_type/impl_trait_fallback2.rs2
-rw-r--r--tests/ui/never_type/impl_trait_fallback2.stderr2
-rw-r--r--tests/ui/never_type/impl_trait_fallback3.rs1
-rw-r--r--tests/ui/never_type/impl_trait_fallback3.stderr2
-rw-r--r--tests/ui/never_type/impl_trait_fallback4.rs1
-rw-r--r--tests/ui/pattern/usefulness/impl-trait.rs6
-rw-r--r--tests/ui/pattern/usefulness/impl-trait.stderr80
-rw-r--r--tests/ui/privacy/private-in-public-type-alias-impl-trait.rs1
-rw-r--r--tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs13
-rw-r--r--tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr53
-rw-r--r--tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs7
-rw-r--r--tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr6
-rw-r--r--tests/ui/self/arbitrary-self-opaque.rs1
-rw-r--r--tests/ui/self/arbitrary-self-opaque.stderr10
-rw-r--r--tests/ui/specialization/min_specialization/impl-on-opaque.rs1
-rw-r--r--tests/ui/specialization/min_specialization/impl-on-opaque2.rs1
-rw-r--r--tests/ui/traits/alias/issue-83613.rs1
-rw-r--r--tests/ui/traits/alias/issue-83613.stderr2
-rw-r--r--tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs3
-rw-r--r--tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs3
-rw-r--r--tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs3
-rw-r--r--tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr2
-rw-r--r--tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr2
-rw-r--r--tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs4
-rw-r--r--tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr14
-rw-r--r--tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs4
-rw-r--r--tests/ui/traits/pointee-tail-is-generic-errors.rs1
-rw-r--r--tests/ui/traits/pointee-tail-is-generic-errors.stderr8
-rw-r--r--tests/ui/traits/pointee-tail-is-generic.rs11
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs1
-rw-r--r--tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs1
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/argument-types.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/assoc-projection-ice.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr18
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/bound_reduction.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/bound_reduction2.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/bound_reduction2.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked3.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/bounds.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/closure_args.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/closure_args2.rs34
-rw-r--r--tests/ui/type-alias-impl-trait/closure_infer.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/closure_parent_substs.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/closure_wf_outlives.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/closures_in_branches.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/closures_in_branches.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.classic.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.next.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_cross_crate.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_generalization.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr28
-rw-r--r--tests/ui/type-alias-impl-trait/const_generic_type.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_in_projection.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_in_projection2.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_inputs.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_inputs.stderr30
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/defining-use-submodule.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/different_args_considered_equal.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs36
-rw-r--r--tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr25
-rw-r--r--tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/escaping-bound-var.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr36
-rw-r--r--tests/ui/type-alias-impl-trait/fallback.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/fallback.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/field-types.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/future.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/future.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs2
-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.stderr38
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_lifetime_param.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/generic_nondefining_use.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr38
-rw-r--r--tests/ui/type-alias-impl-trait/generic_not_used.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/generic_not_used.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained2.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr17
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_type_mismatch.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/higher_kinded_params.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/higher_kinded_params2.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr20
-rw-r--r--tests/ui/type-alias-impl-trait/higher_kinded_params3.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden3.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden4.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr42
-rw-r--r--tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs7
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds2.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr24
-rw-r--r--tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/in-where-clause.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/in-where-clause.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/incomplete-inference.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/incomplete-inference.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/inference-cycle.rs28
-rw-r--r--tests/ui/type-alias-impl-trait/inference-cycle.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/issue-101750.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/issue-104817.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-104817.stock.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-109054.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-109054.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-52843.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-52843.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092-2.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092-2.stderr77
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53096.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53096.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-57961.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-58662-simplified.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/issue-58951-2.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/issue-58951.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60407.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60407.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60564.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60564.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63279.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63279.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63355.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63355.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/issue-65384.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/issue-65918.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr18
-rw-r--r--tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr18
-rw-r--r--tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-69323.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-70121.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-70121.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/issue-72793.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74244.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74280.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74280.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs29
-rw-r--r--tests/ui/type-alias-impl-trait/issue-77179.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/issue-77179.stderr40
-rw-r--r--tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/issue-89686.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-89686.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-93411.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr5
-rw-r--r--tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/lifetime_mismatch.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution.current.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution.next.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution2.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution3.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution4.current.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution4.next.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution4.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution5.rs8
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr7
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference3.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/nested.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/nested.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/nested_inference_failure.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr36
-rw-r--r--tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr18
-rw-r--r--tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr26
-rw-r--r--tests/ui/type-alias-impl-trait/normalize-alias-type.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/normalize-hidden-types.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr17
-rw-r--r--tests/ui/type-alias-impl-trait/not_a_defining_use.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/not_a_defining_use.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/not_well_formed.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/obligation_ice.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/outlives-bound-var.rs8
-rw-r--r--tests/ui/type-alias-impl-trait/param_mismatch.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/param_mismatch.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/param_mismatch2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/param_mismatch2.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/param_mismatch3.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/param_mismatch3.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/param_mismatch4.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/param_mismatch4.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/path_resolution_taint.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/path_resolution_taint.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/privacy.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/privacy.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-fn-tait.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/reveal_local.rs7
-rw-r--r--tests/ui/type-alias-impl-trait/reveal_local.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-2.current.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-3.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-3.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-4.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-4.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/self_implication.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/static-const-types.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/structural-match-no-leak.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/structural-match.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/structural-match.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/taint.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/taint.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr57
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs105
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/type_of_a_let.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/under-binder.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/under-binder.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/underconstrained_generic.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/underconstrained_generic.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/unnameable_type.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/unnameable_type.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/unused_generic_param.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/variance.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/variance.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/weird-return-types.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/wf-check-definition-site.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/wf-check-fn-def.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/wf-nested.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/wf-nested.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/wf_check_closures.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/wf_check_closures.stderr8
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.rs1
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.stderr42
653 files changed, 2798 insertions, 2467 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ecd26d6199c..a6471b195b9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4529,6 +4529,7 @@ version = "0.0.0"
 dependencies = [
  "itertools",
  "rustc_abi",
+ "rustc_attr_parsing",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_fluent_macro",
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 002435b2d03..1b831c454e6 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -3466,6 +3466,7 @@ pub struct Fn {
     pub generics: Generics,
     pub sig: FnSig,
     pub contract: Option<P<FnContract>>,
+    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
     pub body: Option<P<Block>>,
 }
 
@@ -3763,7 +3764,7 @@ mod size_asserts {
     static_assert_size!(Block, 32);
     static_assert_size!(Expr, 72);
     static_assert_size!(ExprKind, 40);
-    static_assert_size!(Fn, 168);
+    static_assert_size!(Fn, 176);
     static_assert_size!(ForeignItem, 88);
     static_assert_size!(ForeignItemKind, 16);
     static_assert_size!(GenericArg, 24);
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index ee894db7b96..e4396a50a15 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -973,7 +973,14 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
             _ctxt,
             _ident,
             _vis,
-            Fn { defaultness, generics, contract, body, sig: FnSig { header, decl, span } },
+            Fn {
+                defaultness,
+                generics,
+                contract,
+                body,
+                sig: FnSig { header, decl, span },
+                define_opaque,
+            },
         ) => {
             // Identifier and visibility are visited as a part of the item.
             visit_defaultness(vis, defaultness);
@@ -987,6 +994,11 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
                 vis.visit_block(body);
             }
             vis.visit_span(span);
+
+            for (id, path) in define_opaque.iter_mut().flatten() {
+                vis.visit_id(id);
+                vis.visit_path(path)
+            }
         }
         FnKind::Closure(binder, coroutine_kind, decl, body) => {
             vis.visit_closure_binder(binder);
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 43ffbe9b071..cfcb0e23cb5 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -892,7 +892,14 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
             _ctxt,
             _ident,
             _vis,
-            Fn { defaultness: _, sig: FnSig { header, decl, span: _ }, generics, contract, body },
+            Fn {
+                defaultness: _,
+                sig: FnSig { header, decl, span: _ },
+                generics,
+                contract,
+                body,
+                define_opaque,
+            },
         ) => {
             // Identifier and visibility are visited as a part of the item.
             try_visit!(visitor.visit_fn_header(header));
@@ -900,6 +907,9 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
             try_visit!(visitor.visit_fn_decl(decl));
             visit_opt!(visitor, visit_contract, contract);
             visit_opt!(visitor, visit_block, body);
+            for (id, path) in define_opaque.iter().flatten() {
+                try_visit!(visitor.visit_path(path, *id))
+            }
         }
         FnKind::Closure(binder, coroutine_kind, decl, body) => {
             try_visit!(visitor.visit_closure_binder(binder));
@@ -1203,7 +1213,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
                 FnKind::Closure(binder, coroutine_kind, fn_decl, body),
                 *span,
                 *id
-            ))
+            ));
         }
         ExprKind::Block(block, opt_label) => {
             visit_opt!(visitor, visit_label, opt_label);
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 5e89321e6ec..0aa42a0c4e7 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -3,10 +3,9 @@ use rustc_ast::ptr::P;
 use rustc_ast::visit::AssocCtxt;
 use rustc_ast::*;
 use rustc_errors::ErrorGuaranteed;
-use rustc_hir as hir;
-use rustc_hir::PredicateOrigin;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
+use rustc_hir::{self as hir, HirId, PredicateOrigin};
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::span_bug;
 use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
@@ -209,6 +208,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 generics,
                 body,
                 contract,
+                define_opaque,
                 ..
             }) => {
                 self.with_new_scopes(*fn_sig_span, |this| {
@@ -237,6 +237,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         header: this.lower_fn_header(*header, hir::Safety::Safe, attrs),
                         span: this.lower_span(*fn_sig_span),
                     };
+                    this.lower_define_opaque(hir_id, &define_opaque);
                     hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() }
                 })
             }
@@ -779,7 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 );
                 (generics, kind, expr.is_some())
             }
-            AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => {
+            AssocItemKind::Fn(box Fn { sig, generics, body: None, define_opaque, .. }) => {
                 // FIXME(contracts): Deny contract here since it won't apply to
                 // any impl method or callees.
                 let names = self.lower_fn_params_to_names(&sig.decl);
@@ -791,9 +792,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     sig.header.coroutine_kind,
                     attrs,
                 );
+                if define_opaque.is_some() {
+                    self.dcx().span_err(
+                        i.span,
+                        "only trait methods with default bodies can define opaque types",
+                    );
+                }
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
             }
-            AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), contract, .. }) => {
+            AssocItemKind::Fn(box Fn {
+                sig,
+                generics,
+                body: Some(body),
+                contract,
+                define_opaque,
+                ..
+            }) => {
                 let body_id = self.lower_maybe_coroutine_body(
                     sig.span,
                     i.span,
@@ -812,6 +826,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     sig.header.coroutine_kind,
                     attrs,
                 );
+                self.lower_define_opaque(hir_id, &define_opaque);
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
             }
             AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => {
@@ -911,7 +926,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     hir::ImplItemKind::Const(ty, body)
                 },
             ),
-            AssocItemKind::Fn(box Fn { sig, generics, body, contract, .. }) => {
+            AssocItemKind::Fn(box Fn { sig, generics, body, contract, define_opaque, .. }) => {
                 let body_id = self.lower_maybe_coroutine_body(
                     sig.span,
                     i.span,
@@ -930,6 +945,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     sig.header.coroutine_kind,
                     attrs,
                 );
+                self.lower_define_opaque(hir_id, &define_opaque);
 
                 (generics, hir::ImplItemKind::Fn(sig, body_id))
             }
@@ -1657,6 +1673,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
         (lowered_generics, res)
     }
 
+    pub(super) fn lower_define_opaque(
+        &mut self,
+        hir_id: HirId,
+        define_opaque: &Option<ThinVec<(NodeId, Path)>>,
+    ) {
+        assert_eq!(self.define_opaque, None);
+        assert!(hir_id.is_owner());
+        let Some(define_opaque) = define_opaque.as_ref() else {
+            return;
+        };
+        let define_opaque = define_opaque
+            .iter()
+            // TODO: error reporting for non-local items being mentioned and tests that go through these code paths
+            .map(|(id, _path)| {
+                self.resolver
+                    .get_partial_res(*id)
+                    .unwrap()
+                    .expect_full_res()
+                    .def_id()
+                    .expect_local()
+            });
+        let define_opaque = self.arena.alloc_from_iter(define_opaque);
+        self.define_opaque = Some(define_opaque);
+    }
+
     pub(super) fn lower_generic_bound_predicate(
         &mut self,
         ident: Ident,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 4cecc56909e..e42a4b460fe 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -35,6 +35,7 @@
 #![doc(rust_logo)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
+#![feature(exact_size_is_empty)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
@@ -97,6 +98,8 @@ struct LoweringContext<'a, 'hir> {
 
     /// Bodies inside the owner being lowered.
     bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
+    /// `#[define_opaque]` attributes
+    define_opaque: Option<&'hir [LocalDefId]>,
     /// Attributes inside the owner being lowered.
     attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,
     /// Collect items that were created by lowering the current owner.
@@ -154,6 +157,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
             // HirId handling.
             bodies: Vec::new(),
+            define_opaque: None,
             attrs: SortedMap::default(),
             children: Vec::default(),
             contract_ensures: None,
@@ -546,6 +550,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         let current_attrs = std::mem::take(&mut self.attrs);
         let current_bodies = std::mem::take(&mut self.bodies);
+        let current_define_opaque = std::mem::take(&mut self.define_opaque);
         let current_ident_and_label_to_local_id =
             std::mem::take(&mut self.ident_and_label_to_local_id);
 
@@ -579,6 +584,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         self.attrs = current_attrs;
         self.bodies = current_bodies;
+        self.define_opaque = current_define_opaque;
         self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;
 
         #[cfg(debug_assertions)]
@@ -598,6 +604,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {
         let attrs = std::mem::take(&mut self.attrs);
         let mut bodies = std::mem::take(&mut self.bodies);
+        let define_opaque = std::mem::take(&mut self.define_opaque);
         let trait_map = std::mem::take(&mut self.trait_map);
 
         #[cfg(debug_assertions)]
@@ -617,7 +624,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let num_nodes = self.item_local_id_counter.as_usize();
         let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
         let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
-        let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
+        let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };
 
         self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
     }
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index f9f4035cb22..232d60be4eb 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -917,7 +917,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 walk_list!(self, visit_attribute, &item.attrs);
                 return; // Avoid visiting again.
             }
-            ItemKind::Fn(func @ box Fn { defaultness, generics: _, sig, contract: _, body }) => {
+            ItemKind::Fn(
+                func
+                @ box Fn { defaultness, generics: _, sig, contract: _, body, define_opaque: _ },
+            ) => {
                 self.check_defaultness(item.span, *defaultness);
 
                 let is_intrinsic =
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 01fc272a458..a8eaff7346b 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -24,7 +24,6 @@ use rustc_span::edition::Edition;
 use rustc_span::source_map::{SourceMap, Spanned};
 use rustc_span::symbol::IdentPrinter;
 use rustc_span::{BytePos, CharPos, DUMMY_SP, FileName, Ident, Pos, Span, Symbol, kw, sym};
-use thin_vec::ThinVec;
 
 use crate::pp::Breaks::{Consistent, Inconsistent};
 use crate::pp::{self, Breaks};
@@ -1978,15 +1977,7 @@ impl<'a> State<'a> {
     ) {
         self.ibox(INDENT_UNIT);
         self.print_formal_generic_params(generic_params);
-        let generics = ast::Generics {
-            params: ThinVec::new(),
-            where_clause: ast::WhereClause {
-                has_where_token: false,
-                predicates: ThinVec::new(),
-                span: DUMMY_SP,
-            },
-            span: DUMMY_SP,
-        };
+        let generics = ast::Generics::default();
         let header = ast::FnHeader { safety, ext, ..ast::FnHeader::default() };
         self.print_fn(decl, header, name, &generics);
         self.end();
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index ced0cbd2fef..6236f8ecfb5 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -650,7 +650,16 @@ impl<'a> State<'a> {
         attrs: &[ast::Attribute],
         func: &ast::Fn,
     ) {
-        let ast::Fn { defaultness, generics, sig, contract, body } = func;
+        let ast::Fn { defaultness, generics, sig, contract, body, define_opaque } = func;
+
+        if let Some(define_opaque) = define_opaque {
+            for (_, path) in define_opaque {
+                self.word("define opaques from ");
+                self.print_path(path, false, 0);
+                self.word(",");
+            }
+        }
+
         if body.is_some() {
             self.head("");
         }
@@ -698,7 +707,7 @@ impl<'a> State<'a> {
         }
         self.print_generic_params(&generics.params);
         self.print_fn_params_and_ret(decl, false);
-        self.print_where_clause(&generics.where_clause)
+        self.print_where_clause(&generics.where_clause);
     }
 
     pub(crate) fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl, is_closure: bool) {
diff --git a/compiler/rustc_borrowck/src/type_check/opaque_types.rs b/compiler/rustc_borrowck/src/type_check/opaque_types.rs
index 17482cc0cbd..94b3d0c2bbf 100644
--- a/compiler/rustc_borrowck/src/type_check/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/type_check/opaque_types.rs
@@ -180,6 +180,7 @@ pub(super) fn take_opaques_and_register_member_constraints<'tcx>(
 /// // Equivalent to:
 /// # mod dummy { use super::*;
 /// type FooReturn<'a, T> = impl Foo<'a>;
+/// #[define_opaque(FooReturn)]
 /// fn foo<'a, T>(x: &'a u32, y: T) -> FooReturn<'a, T> {
 ///   (x, y)
 /// }
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index 78bf2195975..1c1b2c88f76 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -88,6 +88,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
         generics: Generics::default(),
         contract: None,
         body,
+        define_opaque: None,
     }));
 
     let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index 7b5c4a159b0..bb17efa02e0 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -247,6 +247,7 @@ mod llvm_enzyme {
             generics: Generics::default(),
             contract: None,
             body: Some(d_body),
+            define_opaque: None,
         });
         let mut rustc_ad_attr =
             P(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff)));
diff --git a/compiler/rustc_builtin_macros/src/define_opaque.rs b/compiler/rustc_builtin_macros/src/define_opaque.rs
new file mode 100644
index 00000000000..9777e772cf2
--- /dev/null
+++ b/compiler/rustc_builtin_macros/src/define_opaque.rs
@@ -0,0 +1,54 @@
+use rustc_ast::{DUMMY_NODE_ID, ast};
+use rustc_expand::base::{Annotatable, ExtCtxt};
+use rustc_span::Span;
+
+pub(crate) fn expand(
+    ecx: &mut ExtCtxt<'_>,
+    _expand_span: Span,
+    meta_item: &ast::MetaItem,
+    mut item: Annotatable,
+) -> Vec<Annotatable> {
+    let define_opaque = match &mut item {
+        Annotatable::Item(p) => match &mut p.kind {
+            ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
+            _ => None,
+        },
+        Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind {
+            ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque),
+            _ => None,
+        },
+        Annotatable::Stmt(s) => match &mut s.kind {
+            ast::StmtKind::Item(p) => match &mut p.kind {
+                ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
+                _ => None,
+            },
+            _ => None,
+        },
+        _ => None,
+    };
+
+    let Some(list) = meta_item.meta_item_list() else {
+        ecx.dcx().span_err(meta_item.span, "expected list of type aliases");
+        return vec![item];
+    };
+
+    if let Some(define_opaque) = define_opaque {
+        *define_opaque = Some(
+            list.iter()
+                .filter_map(|entry| match entry {
+                    ast::MetaItemInner::MetaItem(meta_item) if meta_item.is_word() => {
+                        Some((DUMMY_NODE_ID, meta_item.path.clone()))
+                    }
+                    _ => {
+                        ecx.dcx().span_err(entry.span(), "expected path to type alias");
+                        None
+                    }
+                })
+                .collect(),
+        );
+    } else {
+        ecx.dcx().span_err(meta_item.span, "only functions and methods can define opaque types");
+    }
+
+    vec![item]
+}
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 5402b5a1ae9..03ee59de70e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -1040,6 +1040,7 @@ impl<'a> MethodDef<'a> {
                 generics: fn_generics,
                 contract: None,
                 body: Some(body_block),
+                define_opaque: None,
             })),
             tokens: None,
         })
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 8fdbbf8e704..90d79235820 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -83,6 +83,7 @@ impl AllocFnFactory<'_, '_> {
             generics: Generics::default(),
             contract: None,
             body,
+            define_opaque: None,
         }));
         let item = self.cx.item(
             self.span,
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index c23ce1e5e4a..1defd3867a0 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -38,6 +38,7 @@ mod compile_error;
 mod concat;
 mod concat_bytes;
 mod concat_idents;
+mod define_opaque;
 mod derive;
 mod deriving;
 mod edition_panic;
@@ -113,6 +114,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         bench: test::expand_bench,
         cfg_accessible: cfg_accessible::Expander,
         cfg_eval: cfg_eval::expand,
+        define_opaque: define_opaque::expand,
         derive: derive::Expander { is_const: false },
         derive_const: derive::Expander { is_const: true },
         global_allocator: global_allocator::expand,
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 472e16e62d5..768b459ec5e 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -346,6 +346,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
         generics: ast::Generics::default(),
         contract: None,
         body: Some(main_body),
+        define_opaque: None,
     }));
 
     // Honor the reexport_test_harness_main attribute
diff --git a/compiler/rustc_codegen_cranelift/example/issue-72793.rs b/compiler/rustc_codegen_cranelift/example/issue-72793.rs
index 2e08fbca8ef..95d58b90e79 100644
--- a/compiler/rustc_codegen_cranelift/example/issue-72793.rs
+++ b/compiler/rustc_codegen_cranelift/example/issue-72793.rs
@@ -2,23 +2,21 @@
 
 #![feature(type_alias_impl_trait)]
 
-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/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index 8d19fc5f9cc..f63b201742d 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -315,6 +315,7 @@ mod helper {
     use super::*;
     pub(super) type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
     impl<O: ForestObligation> ObligationForest<O> {
+        #[cfg_attr(not(bootstrap), define_opaque(ObligationTreeIdGenerator))]
         pub fn new() -> ObligationForest<O> {
             ObligationForest {
                 nodes: vec![],
diff --git a/compiler/rustc_error_codes/src/error_codes/E0792.md b/compiler/rustc_error_codes/src/error_codes/E0792.md
index 5e3dcc4aa72..033e1c65192 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0792.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0792.md
@@ -7,6 +7,7 @@ This means
 
 type Foo<T> = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo() -> Foo<u32> {
     5u32
 }
@@ -19,6 +20,7 @@ is not accepted. If it were accepted, one could create unsound situations like
 
 type Foo<T> = impl Default;
 
+#[define_opaque(Foo)]
 fn foo() -> Foo<u32> {
     5u32
 }
@@ -36,6 +38,7 @@ Instead you need to make the function generic:
 
 type Foo<T> = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo<U>() -> Foo<U> {
     5u32
 }
@@ -56,6 +59,7 @@ use std::fmt::Debug;
 
 type Foo<T: Debug> = impl Debug;
 
+#[define_opaque(Foo)]
 fn foo<U: Debug>() -> Foo<U> {
     Vec::<U>::new()
 }
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index a6fbbb29ccd..066546ecf74 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -208,6 +208,7 @@ pub type LazyFallbackBundle = Arc<LazyLock<FluentBundle, impl FnOnce() -> Fluent
 
 /// Return the default `FluentBundle` with standard "en-US" diagnostic messages.
 #[instrument(level = "trace", skip(resources))]
+#[cfg_attr(not(bootstrap), define_opaque(LazyFallbackBundle))]
 pub fn fallback_fluent_bundle(
     resources: Vec<&'static str>,
     with_directionality_markers: bool,
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 928455ace85..1c54b99b12f 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1307,13 +1307,18 @@ impl Attribute {
 #[derive(Debug)]
 pub struct AttributeMap<'tcx> {
     pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
+    /// Preprocessed `#[define_opaque]` attribute.
+    pub define_opaque: Option<&'tcx [LocalDefId]>,
     // Only present when the crate hash is needed.
     pub opt_hash: Option<Fingerprint>,
 }
 
 impl<'tcx> AttributeMap<'tcx> {
-    pub const EMPTY: &'static AttributeMap<'static> =
-        &AttributeMap { map: SortedMap::new(), opt_hash: Some(Fingerprint::ZERO) };
+    pub const EMPTY: &'static AttributeMap<'static> = &AttributeMap {
+        map: SortedMap::new(),
+        opt_hash: Some(Fingerprint::ZERO),
+        define_opaque: None,
+    };
 
     #[inline]
     pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index 2709a826549..91ea88cae47 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -106,7 +106,7 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for AttributeMap
     fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
         // We ignore the `map` since it refers to information included in `opt_hash` which is
         // hashed in the collector and used for the crate hash.
-        let AttributeMap { opt_hash, map: _ } = *self;
+        let AttributeMap { opt_hash, define_opaque: _, map: _ } = *self;
         opt_hash.unwrap().hash_stable(hcx, hasher);
     }
 }
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 935f4de6c58..194f2cd04e4 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -504,12 +504,9 @@ hir_analysis_supertrait_item_shadowee = item from `{$supertrait}` is shadowed by
 
 hir_analysis_supertrait_item_shadowing = trait item `{$item}` from `{$subtrait}` shadows identically named item from supertrait
 
-hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
-    .note = this item must mention the opaque type in its signature in order to be able to register hidden types
-
-hir_analysis_tait_forward_compat2 = item does not constrain `{$opaque_type}`, but has it in its signature
-    .note = consider moving the opaque type's declaration and defining uses into a separate module
-    .opaque = this opaque type is in the signature
+hir_analysis_tait_forward_compat2 = item does not constrain `{$opaque_type}`
+    .note = consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+    .opaque = this opaque type is supposed to be constrained
 
 hir_analysis_target_feature_on_main = `main` function is not allowed to have `#[target_feature]`
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 8f9997cb62c..8dc5d361750 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -392,6 +392,12 @@ fn best_definition_site_of_opaque<'tcx>(
                 return ControlFlow::Continue(());
             }
 
+            let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
+            // Don't try to check items that cannot possibly constrain the type.
+            if !opaque_types_defined_by.contains(&self.opaque_def_id) {
+                return ControlFlow::Continue(());
+            }
+
             if let Some(hidden_ty) =
                 self.tcx.mir_borrowck(item_def_id).concrete_opaque_types.get(&self.opaque_def_id)
             {
@@ -451,19 +457,7 @@ fn best_definition_site_of_opaque<'tcx>(
             None
         }
         hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
-            let scope = tcx.hir_get_defining_scope(tcx.local_def_id_to_hir_id(opaque_def_id));
-            let found = if scope == hir::CRATE_HIR_ID {
-                tcx.hir_walk_toplevel_module(&mut locator)
-            } else {
-                match tcx.hir_node(scope) {
-                    Node::Item(it) => locator.visit_item(it),
-                    Node::ImplItem(it) => locator.visit_impl_item(it),
-                    Node::TraitItem(it) => locator.visit_trait_item(it),
-                    Node::ForeignItem(it) => locator.visit_foreign_item(it),
-                    other => bug!("{:?} is not a valid scope for an opaque type item", other),
-                }
-            };
-            found.break_value()
+            tcx.hir_walk_toplevel_module(&mut locator).break_value()
         }
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index 399c4fbe55a..142078900f0 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -1,14 +1,13 @@
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
-use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def};
+use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def, intravisit};
 use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::DUMMY_SP;
 use tracing::{debug, instrument, trace};
 
-use crate::errors::{TaitForwardCompat, TaitForwardCompat2, UnconstrainedOpaqueType};
+use crate::errors::{TaitForwardCompat2, UnconstrainedOpaqueType};
 
 /// Checks "defining uses" of opaque `impl Trait` in associated types.
 /// These can only be defined by associated items of the same trait.
@@ -82,38 +81,9 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
 /// ```
 #[instrument(skip(tcx), level = "debug")]
 pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
-    let hir_id = tcx.local_def_id_to_hir_id(def_id);
-    let scope = tcx.hir_get_defining_scope(hir_id);
     let mut locator = TaitConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] };
 
-    debug!(?scope);
-
-    if scope == hir::CRATE_HIR_ID {
-        tcx.hir_walk_toplevel_module(&mut locator);
-    } else {
-        trace!("scope={:#?}", tcx.hir_node(scope));
-        match tcx.hir_node(scope) {
-            // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
-            // This allows our visitor to process the defining item itself, causing
-            // it to pick up any 'sibling' defining uses.
-            //
-            // For example, this code:
-            // ```
-            // fn foo() {
-            //     type Blah = impl Debug;
-            //     let my_closure = || -> Blah { true };
-            // }
-            // ```
-            //
-            // requires us to explicitly process `foo()` in order
-            // to notice the defining usage of `Blah`.
-            Node::Item(it) => locator.visit_item(it),
-            Node::ImplItem(it) => locator.visit_impl_item(it),
-            Node::TraitItem(it) => locator.visit_trait_item(it),
-            Node::ForeignItem(it) => locator.visit_foreign_item(it),
-            other => bug!("{:?} is not a valid scope for an opaque type item", other),
-        }
-    }
+    tcx.hir_walk_toplevel_module(&mut locator);
 
     if let Some(hidden) = locator.found {
         // Only check against typeck if we didn't already error
@@ -137,12 +107,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
         let reported = tcx.dcx().emit_err(UnconstrainedOpaqueType {
             span: tcx.def_span(def_id),
             name: tcx.item_ident(parent_def_id.to_def_id()),
-            what: match tcx.hir_node(scope) {
-                _ if scope == hir::CRATE_HIR_ID => "module",
-                Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module",
-                Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl",
-                _ => "item",
-            },
+            what: "crate",
         });
         Ty::new_error(tcx, reported)
     }
@@ -176,6 +141,13 @@ impl TaitConstraintLocator<'_> {
             return;
         }
 
+        let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
+        // Don't try to check items that cannot possibly constrain the type.
+        if !opaque_types_defined_by.contains(&self.def_id) {
+            debug!("no constraint: no opaque types defined");
+            return;
+        }
+
         // Function items with `_` in their return type already emit an error, skip any
         // "non-defining use" errors for them.
         // Note that we use `Node::fn_sig` instead of `Node::fn_decl` here, because the former
@@ -215,8 +187,6 @@ impl TaitConstraintLocator<'_> {
             return;
         }
 
-        let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
-
         let mut constrained = false;
         for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
             if opaque_type_key.def_id != self.def_id {
@@ -224,20 +194,6 @@ impl TaitConstraintLocator<'_> {
             }
             constrained = true;
 
-            if !opaque_types_defined_by.contains(&self.def_id) {
-                let guar = self.tcx.dcx().emit_err(TaitForwardCompat {
-                    span: hidden_type.span,
-                    item_span: self
-                        .tcx
-                        .def_ident_span(item_def_id)
-                        .unwrap_or_else(|| self.tcx.def_span(item_def_id)),
-                });
-                // Avoid "opaque type not constrained" errors on the opaque itself.
-                self.found = Some(ty::OpaqueHiddenType {
-                    span: DUMMY_SP,
-                    ty: Ty::new_error(self.tcx, guar),
-                });
-            }
             let concrete_type =
                 self.tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params(
                     opaque_type_key,
@@ -309,19 +265,13 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
     }
     fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
         trace!(?it.owner_id);
-        // The opaque type itself or its children are not within its reveal scope.
-        if it.owner_id.def_id != self.def_id {
-            self.check(it.owner_id.def_id);
-            intravisit::walk_item(self, it);
-        }
+        self.check(it.owner_id.def_id);
+        intravisit::walk_item(self, it);
     }
     fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) {
         trace!(?it.owner_id);
-        // The opaque type itself or its children are not within its reveal scope.
-        if it.owner_id.def_id != self.def_id {
-            self.check(it.owner_id.def_id);
-            intravisit::walk_impl_item(self, it);
-        }
+        self.check(it.owner_id.def_id);
+        intravisit::walk_impl_item(self, it);
     }
     fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
         trace!(?it.owner_id);
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 4c6c2504126..f2560f22874 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -425,16 +425,6 @@ pub(crate) struct UnconstrainedOpaqueType {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_tait_forward_compat)]
-#[note]
-pub(crate) struct TaitForwardCompat {
-    #[primary_span]
-    pub span: Span,
-    #[note]
-    pub item_span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(hir_analysis_tait_forward_compat2)]
 #[note]
 pub(crate) struct TaitForwardCompat2 {
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index 7eaf83f5acf..659f6d98f03 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -43,6 +43,7 @@ declare_lint! {
     ///
     /// type Tait = impl Sized;
     ///
+    /// #[define_opaque(Tait)]
     /// fn test() -> impl Trait<Assoc = Tait> {
     ///     42
     /// }
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index bc77f22af67..b2c51ad8864 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -454,6 +454,7 @@ mod helper {
         /// Like [`SwitchTargets::target_for_value`], but returning the same type as
         /// [`Terminator::successors`].
         #[inline]
+        #[cfg_attr(not(bootstrap), define_opaque(Successors))]
         pub fn successors_for_value(&self, value: u128) -> Successors<'_> {
             let target = self.target_for_value(value);
             (&[]).into_iter().copied().chain(Some(target))
@@ -462,6 +463,7 @@ mod helper {
 
     impl<'tcx> TerminatorKind<'tcx> {
         #[inline]
+        #[cfg_attr(not(bootstrap), define_opaque(Successors))]
         pub fn successors(&self) -> Successors<'_> {
             use self::TerminatorKind::*;
             match *self {
@@ -500,6 +502,7 @@ mod helper {
         }
 
         #[inline]
+        #[cfg_attr(not(bootstrap), define_opaque(SuccessorsMut))]
         pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
             use self::TerminatorKind::*;
             match *self {
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 907618e428f..7bbaa0496d5 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -24,6 +24,7 @@ pub trait EraseType: Copy {
 pub type Erase<T: EraseType> = Erased<impl Copy>;
 
 #[inline(always)]
+#[cfg_attr(not(bootstrap), define_opaque(Erase))]
 pub fn erase<T: EraseType>(src: T) -> Erase<T> {
     // Ensure the sizes match
     const {
@@ -47,6 +48,7 @@ pub fn erase<T: EraseType>(src: T) -> Erase<T> {
 
 /// Restores an erased value.
 #[inline(always)]
+#[cfg_attr(not(bootstrap), define_opaque(Erase))]
 pub fn restore<T: EraseType>(value: Erase<T>) -> T {
     let value: Erased<<T as EraseType>::Result> = value;
     // See comment in `erase` for why we use `transmute_unchecked`.
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 0b9350c7199..e309f144b4f 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -217,7 +217,14 @@ impl<'a> Parser<'a> {
                 self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;
             (
                 ident,
-                ItemKind::Fn(Box::new(Fn { defaultness: def_(), sig, generics, contract, body })),
+                ItemKind::Fn(Box::new(Fn {
+                    defaultness: def_(),
+                    sig,
+                    generics,
+                    contract,
+                    body,
+                    define_opaque: None,
+                })),
             )
         } else if self.eat_keyword(exp!(Extern)) {
             if self.eat_keyword(exp!(Crate)) {
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 79479986d07..2c3e4bb505c 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -397,32 +397,37 @@ pub(crate) enum AliasPossibility {
 
 #[derive(Copy, Clone, Debug)]
 pub(crate) enum PathSource<'a> {
-    // Type paths `Path`.
+    /// Type paths `Path`.
     Type,
-    // Trait paths in bounds or impls.
+    /// Trait paths in bounds or impls.
     Trait(AliasPossibility),
-    // Expression paths `path`, with optional parent context.
+    /// Expression paths `path`, with optional parent context.
     Expr(Option<&'a Expr>),
-    // Paths in path patterns `Path`.
+    /// Paths in path patterns `Path`.
     Pat,
-    // Paths in struct expressions and patterns `Path { .. }`.
+    /// Paths in struct expressions and patterns `Path { .. }`.
     Struct,
-    // Paths in tuple struct patterns `Path(..)`.
+    /// Paths in tuple struct patterns `Path(..)`.
     TupleStruct(Span, &'a [Span]),
-    // `m::A::B` in `<T as m::A>::B::C`.
+    /// `m::A::B` in `<T as m::A>::B::C`.
     TraitItem(Namespace),
-    // Paths in delegation item
+    /// Paths in delegation item
     Delegation,
     /// An arg in a `use<'a, N>` precise-capturing bound.
     PreciseCapturingArg(Namespace),
-    // Paths that end with `(..)`, for return type notation.
+    /// Paths that end with `(..)`, for return type notation.
     ReturnTypeNotation,
+    /// Paths from `#[define_opaque]` attributes
+    DefineOpaques,
 }
 
 impl<'a> PathSource<'a> {
     fn namespace(self) -> Namespace {
         match self {
-            PathSource::Type | PathSource::Trait(_) | PathSource::Struct => TypeNS,
+            PathSource::Type
+            | PathSource::Trait(_)
+            | PathSource::Struct
+            | PathSource::DefineOpaques => TypeNS,
             PathSource::Expr(..)
             | PathSource::Pat
             | PathSource::TupleStruct(..)
@@ -443,6 +448,7 @@ impl<'a> PathSource<'a> {
             | PathSource::ReturnTypeNotation => true,
             PathSource::Trait(_)
             | PathSource::TraitItem(..)
+            | PathSource::DefineOpaques
             | PathSource::Delegation
             | PathSource::PreciseCapturingArg(..) => false,
         }
@@ -450,6 +456,7 @@ impl<'a> PathSource<'a> {
 
     fn descr_expected(self) -> &'static str {
         match &self {
+            PathSource::DefineOpaques => "type alias or associated type with opaqaue types",
             PathSource::Type => "type",
             PathSource::Trait(_) => "trait",
             PathSource::Pat => "unit struct, unit variant or constant",
@@ -493,6 +500,19 @@ impl<'a> PathSource<'a> {
 
     pub(crate) fn is_expected(self, res: Res) -> bool {
         match self {
+            PathSource::DefineOpaques => {
+                matches!(
+                    res,
+                    Res::Def(
+                        DefKind::Struct
+                            | DefKind::Union
+                            | DefKind::Enum
+                            | DefKind::TyAlias
+                            | DefKind::AssocTy,
+                        _
+                    ) | Res::SelfTyAlias { .. }
+                )
+            }
             PathSource::Type => matches!(
                 res,
                 Res::Def(
@@ -572,16 +592,16 @@ impl<'a> PathSource<'a> {
         match (self, has_unexpected_resolution) {
             (PathSource::Trait(_), true) => E0404,
             (PathSource::Trait(_), false) => E0405,
-            (PathSource::Type, true) => E0573,
-            (PathSource::Type, false) => E0412,
+            (PathSource::Type | PathSource::DefineOpaques, true) => E0573,
+            (PathSource::Type | PathSource::DefineOpaques, false) => E0412,
             (PathSource::Struct, true) => E0574,
             (PathSource::Struct, false) => E0422,
             (PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423,
             (PathSource::Expr(..), false) | (PathSource::Delegation, false) => E0425,
             (PathSource::Pat | PathSource::TupleStruct(..), true) => E0532,
             (PathSource::Pat | PathSource::TupleStruct(..), false) => E0531,
-            (PathSource::TraitItem(..), true) | (PathSource::ReturnTypeNotation, true) => E0575,
-            (PathSource::TraitItem(..), false) | (PathSource::ReturnTypeNotation, false) => E0576,
+            (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, true) => E0575,
+            (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, false) => E0576,
             (PathSource::PreciseCapturingArg(..), true) => E0799,
             (PathSource::PreciseCapturingArg(..), false) => E0800,
         }
@@ -2006,6 +2026,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 | PathSource::Pat
                 | PathSource::Struct
                 | PathSource::TupleStruct(..)
+                | PathSource::DefineOpaques
                 | PathSource::Delegation => true,
             };
             if inferred {
@@ -2619,7 +2640,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 );
             }
 
-            ItemKind::Fn(box Fn { ref generics, .. }) => {
+            ItemKind::Fn(box Fn { ref generics, ref define_opaque, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
                     RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
@@ -2630,6 +2651,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                     },
                     |this| visit::walk_item(this, item),
                 );
+
+                for (id, path) in define_opaque.iter().flatten() {
+                    self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
+                }
             }
 
             ItemKind::Enum(_, ref generics)
@@ -3100,8 +3125,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         },
                     );
                 }
-                AssocItemKind::Fn(box Fn { generics, .. }) => {
+                AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => {
                     walk_assoc_item(self, generics, LifetimeBinderKind::Function, item);
+
+                    for (id, path) in define_opaque.iter().flatten() {
+                        self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
+                    }
                 }
                 AssocItemKind::Delegation(delegation) => {
                     self.with_generic_param_rib(
@@ -3311,7 +3340,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                     },
                 );
             }
-            AssocItemKind::Fn(box Fn { generics, .. }) => {
+            AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => {
                 debug!("resolve_implementation AssocItemKind::Fn");
                 // We also need a new scope for the impl item type parameters.
                 self.with_generic_param_rib(
@@ -3338,6 +3367,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         visit::walk_assoc_item(this, item, AssocCtxt::Impl)
                     },
                 );
+
+                for (id, path) in define_opaque.iter().flatten() {
+                    self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
+                }
             }
             AssocItemKind::Type(box TyAlias { generics, .. }) => {
                 self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty());
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9e7f5047eb3..4360109b633 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -779,6 +779,7 @@ symbols! {
         default_method_body_is_const,
         default_type_parameter_fallback,
         default_type_params,
+        define_opaque,
         delayed_bug_from_inside_query,
         deny,
         deprecated,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
index 514615735a5..51b2a0b36bb 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
@@ -395,11 +395,28 @@ impl<T> Trait<T> for X {
                             let sp = tcx
                                 .def_ident_span(body_owner_def_id)
                                 .unwrap_or_else(|| tcx.def_span(body_owner_def_id));
-                            diag.span_note(
-                                sp,
-                                "this item must have the opaque type in its signature in order to \
-                                 be able to register hidden types",
-                            );
+                            let mut alias_def_id = opaque_ty.def_id;
+                            while let DefKind::OpaqueTy = tcx.def_kind(alias_def_id) {
+                                alias_def_id = tcx.parent(alias_def_id);
+                            }
+                            let opaque_path = tcx.def_path_str(alias_def_id);
+                            // FIXME(type_alias_impl_trait): make this a structured suggestion
+                            match tcx.opaque_ty_origin(opaque_ty.def_id) {
+                                rustc_hir::OpaqueTyOrigin::FnReturn { .. } => {}
+                                rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {}
+                                rustc_hir::OpaqueTyOrigin::TyAlias {
+                                    in_assoc_ty: false, ..
+                                } => {
+                                    diag.span_note(
+                                        sp,
+                                        format!("this item must have a `#[define_opaque({opaque_path})]` \
+                                        attribute to be able to define hidden types"),
+                                    );
+                                }
+                                rustc_hir::OpaqueTyOrigin::TyAlias {
+                                    in_assoc_ty: true, ..
+                                } => {}
+                            }
                         }
                         // If two if arms can be coerced to a trait object, provide a structured
                         // suggestion.
diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml
index 61acc12d0eb..7213a150d2b 100644
--- a/compiler/rustc_ty_utils/Cargo.toml
+++ b/compiler/rustc_ty_utils/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2024"
 # tidy-alphabetical-start
 itertools = "0.12"
 rustc_abi = { path = "../rustc_abi" }
+rustc_attr_parsing = { path = "../rustc_attr_parsing" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 98881905bcf..2d590dfdd14 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -1,8 +1,8 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
+use rustc_hir::intravisit;
 use rustc_hir::intravisit::Visitor;
-use rustc_hir::{CRATE_HIR_ID, intravisit};
 use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::util::{CheckRegions, NotUniqueParam};
@@ -30,14 +30,21 @@ enum CollectionMode {
     /// For impl trait in assoc types we only permit collecting them from
     /// associated types of the same impl block.
     ImplTraitInAssocTypes,
-    TypeAliasImplTraitTransition,
+    /// When collecting for an explicit `#[define_opaque]` attribute, find all TAITs
+    Taits,
+    /// The default case, only collect RPITs and AsyncFn return types, as these are
+    /// always defined by the current item.
+    RpitAndAsyncFnOnly,
 }
 
 impl<'tcx> OpaqueTypeCollector<'tcx> {
     fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
-        let mode = match tcx.def_kind(tcx.local_parent(item)) {
-            DefKind::Impl { of_trait: true } => CollectionMode::ImplTraitInAssocTypes,
-            _ => CollectionMode::TypeAliasImplTraitTransition,
+        let mode = match tcx.def_kind(item) {
+            DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy => {
+                CollectionMode::ImplTraitInAssocTypes
+            }
+            DefKind::TyAlias => CollectionMode::Taits,
+            _ => CollectionMode::RpitAndAsyncFnOnly,
         };
         Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None, mode }
     }
@@ -73,40 +80,6 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
         }
     }
 
-    /// Returns `true` if `opaque_hir_id` is a sibling or a child of a sibling of `self.item`.
-    ///
-    /// Example:
-    /// ```ignore UNSOLVED (is this a bug?)
-    /// # #![feature(type_alias_impl_trait)]
-    /// pub mod foo {
-    ///     pub mod bar {
-    ///         pub trait Bar { /* ... */ }
-    ///         pub type Baz = impl Bar;
-    ///
-    ///         # impl Bar for () {}
-    ///         fn f1() -> Baz { /* ... */ }
-    ///     }
-    ///     fn f2() -> bar::Baz { /* ... */ }
-    /// }
-    /// ```
-    ///
-    /// and `opaque_def_id` is the `DefId` of the definition of the opaque type `Baz`.
-    /// For the above example, this function returns `true` for `f1` and `false` for `f2`.
-    #[instrument(level = "trace", skip(self), ret)]
-    fn check_tait_defining_scope(&self, opaque_def_id: LocalDefId) -> bool {
-        let mut hir_id = self.tcx.local_def_id_to_hir_id(self.item);
-        let opaque_hir_id = self.tcx.local_def_id_to_hir_id(opaque_def_id);
-
-        // Named opaque types can be defined by any siblings or children of siblings.
-        let scope = self.tcx.hir_get_defining_scope(opaque_hir_id);
-        // We walk up the node tree until we hit the root or the scope of the opaque type.
-        while hir_id != scope && hir_id != CRATE_HIR_ID {
-            hir_id = self.tcx.hir_get_parent_item(hir_id).into();
-        }
-        // Syntactically, we are allowed to define the concrete type if:
-        hir_id == scope
-    }
-
     #[instrument(level = "trace", skip(self))]
     fn collect_taits_declared_in_body(&mut self) {
         let body = self.tcx.hir_body_owned_by(self.item).value;
@@ -139,18 +112,31 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
         }
 
         // TAITs outside their defining scopes are ignored.
-        let origin = self.tcx.local_opaque_ty_origin(alias_ty.def_id.expect_local());
-        trace!(?origin);
-        match origin {
+        match self.tcx.local_opaque_ty_origin(alias_ty.def_id.expect_local()) {
             rustc_hir::OpaqueTyOrigin::FnReturn { .. }
             | rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {}
-            rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
-                if !in_assoc_ty && !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
-                    return;
+            rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => match self.mode {
+                // If we are collecting opaques in an assoc method, we are only looking at assoc types
+                // mentioned in the assoc method and only at opaques defined in there. We do not
+                // want to collect TAITs
+                CollectionMode::ImplTraitInAssocTypes => {
+                    if !in_assoc_ty {
+                        return;
+                    }
                 }
-            }
+                // If we are collecting opaques referenced from a `define_opaque` attribute, we
+                // do not want to look at opaques defined in associated types. Those can only be
+                // defined by methods on the same impl.
+                CollectionMode::Taits => {
+                    if in_assoc_ty {
+                        return;
+                    }
+                }
+                CollectionMode::RpitAndAsyncFnOnly => return,
+            },
         }
 
+        trace!(?alias_ty, "adding");
         self.opaques.push(alias_ty.def_id.expect_local());
 
         let parent_count = self.tcx.generics_of(alias_ty.def_id).parent_count;
@@ -192,6 +178,29 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
             }
         }
     }
+
+    /// Checks the `#[define_opaque]` attributes on items and collectes opaques to define
+    /// from the referenced types.
+    #[instrument(level = "trace", skip(self))]
+    fn collect_taits_from_defines_attr(&mut self) {
+        let hir_id = self.tcx.local_def_id_to_hir_id(self.item);
+        if !hir_id.is_owner() {
+            return;
+        }
+        let Some(defines) = self.tcx.hir_attrs(hir_id.owner).define_opaque else {
+            return;
+        };
+        for &define in defines {
+            trace!(?define);
+            let mode = std::mem::replace(&mut self.mode, CollectionMode::Taits);
+            // TODO: check that opaque types were introduced and error otherwise (also add tests)
+            super::sig_types::walk_types(self.tcx, define, self);
+            self.mode = mode;
+        }
+        // Allow using `#[define_opaque]` on assoc methods and type aliases to override the default collection mode in
+        // case it was capturing too much.
+        self.mode = CollectionMode::RpitAndAsyncFnOnly;
+    }
 }
 
 impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
@@ -210,6 +219,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
                 self.visit_opaque_ty(alias_ty);
             }
             // Skips type aliases, as they are meant to be transparent.
+            // FIXME(type_alias_impl_trait): can we require mentioning nested type aliases explicitly?
             ty::Alias(ty::Weak, alias_ty) if alias_ty.def_id.is_local() => {
                 self.tcx
                     .type_of(alias_ty.def_id)
@@ -283,28 +293,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
                     self.visit_opaque_ty(alias_ty);
                 }
             }
-            ty::Adt(def, _) if def.did().is_local() => {
-                if let CollectionMode::ImplTraitInAssocTypes = self.mode {
-                    return;
-                }
-                if !self.seen.insert(def.did().expect_local()) {
-                    return;
-                }
-                for variant in def.variants().iter() {
-                    for field in variant.fields.iter() {
-                        // Don't use the `ty::Adt` args, we either
-                        // * found the opaque in the args
-                        // * will find the opaque in the uninstantiated fields
-                        // The only other situation that can occur is that after instantiating,
-                        // some projection resolves to an opaque that we would have otherwise
-                        // not found. While we could instantiate and walk those, that would mean we
-                        // would have to walk all generic parameters of an Adt, which can quickly
-                        // degenerate into looking at an exponential number of types.
-                        let ty = self.tcx.type_of(field.did).instantiate_identity();
-                        self.visit_spanned(self.tcx.def_span(field.did), ty);
-                    }
-                }
-            }
             _ => trace!(kind=?t.kind()),
         }
     }
@@ -317,7 +305,9 @@ fn opaque_types_defined_by<'tcx>(
     let kind = tcx.def_kind(item);
     trace!(?kind);
     let mut collector = OpaqueTypeCollector::new(tcx, item);
+    collector.collect_taits_from_defines_attr();
     super::sig_types::walk_types(tcx, item, &mut collector);
+
     match kind {
         DefKind::AssocFn
         | DefKind::Fn
@@ -350,8 +340,7 @@ fn opaque_types_defined_by<'tcx>(
         | DefKind::GlobalAsm
         | DefKind::Impl { .. }
         | DefKind::SyntheticCoroutineBody => {}
-        // Closures and coroutines are type checked with their parent, so we need to allow all
-        // opaques from the closure signature *and* from the parent body.
+        // Closures and coroutines are type checked with their parent
         DefKind::Closure | DefKind::InlineConst => {
             collector.opaques.extend(tcx.opaque_types_defined_by(tcx.local_parent(item)));
         }
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 16200184422..a527a2ea5aa 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1743,6 +1743,21 @@ pub(crate) mod builtin {
         /* compiler built-in */
     }
 
+    /// Provide a list of type aliases and other opaque-type-containing type definitions.
+    /// This list will be used in the body of the item it is applied to to define opaque
+    /// types' hidden types.
+    /// Can only be applied to things that have bodies.
+    #[unstable(
+        feature = "type_alias_impl_trait",
+        issue = "63063",
+        reason = "`type_alias_impl_trait` has open design concerns"
+    )]
+    #[rustc_builtin_macro]
+    #[cfg(not(bootstrap))]
+    pub macro define_opaque($($tt:tt)*) {
+        /* compiler built-in */
+    }
+
     /// Unstable placeholder for type ascription.
     #[allow_internal_unstable(builtin_syntax)]
     #[unstable(
diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs
index 50fd67e8395..c5975c03050 100644
--- a/library/core/src/prelude/v1.rs
+++ b/library/core/src/prelude/v1.rs
@@ -111,3 +111,11 @@ pub use crate::macros::builtin::type_ascribe;
     reason = "placeholder syntax for deref patterns"
 )]
 pub use crate::macros::builtin::deref;
+
+#[unstable(
+    feature = "type_alias_impl_trait",
+    issue = "63063",
+    reason = "`type_alias_impl_trait` has open design concerns"
+)]
+#[cfg(not(bootstrap))]
+pub use crate::macros::builtin::define_opaque;
diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs
index fc333d7ff3f..3e641ac5d90 100644
--- a/library/std/src/backtrace.rs
+++ b/library/std/src/backtrace.rs
@@ -432,6 +432,7 @@ mod helper {
     use super::*;
     pub(super) type LazyResolve = impl (FnOnce() -> Capture) + Send + Sync + UnwindSafe;
 
+    #[cfg_attr(not(bootstrap), define_opaque(LazyResolve))]
     pub(super) fn lazy_resolve(mut capture: Capture) -> LazyResolve {
         move || {
             // Use the global backtrace lock to synchronize this as it's a
diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs
index 5b324b2e916..4217f658640 100644
--- a/library/std/src/prelude/v1.rs
+++ b/library/std/src/prelude/v1.rs
@@ -103,6 +103,15 @@ pub use core::prelude::v1::type_ascribe;
 )]
 pub use core::prelude::v1::deref;
 
+// Do not `doc(no_inline)` either.
+#[unstable(
+    feature = "type_alias_impl_trait",
+    issue = "63063",
+    reason = "`type_alias_impl_trait` has open design concerns"
+)]
+#[cfg(not(bootstrap))]
+pub use core::prelude::v1::define_opaque;
+
 // The file so far is equivalent to core/src/prelude/v1.rs. It is duplicated
 // rather than glob imported because we want docs to show these re-exports as
 // pointing to within `std`.
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 4610e092cdf..3228f71df07 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -272,7 +272,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
 
     fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
         match item.kind {
-            ItemKind::Static(_, _, _)
+            ItemKind::Static(..)
             | ItemKind::Const(_, _, _)
             | ItemKind::Fn { .. }
             | ItemKind::Macro(_, _)
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index 4f024ecaf29..707312a97f3 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -364,6 +364,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 generics: lg,
                 contract: lc,
                 body: lb,
+                define_opaque: _,
             }),
             Fn(box ast::Fn {
                 defaultness: rd,
@@ -371,6 +372,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 generics: rg,
                 contract: rc,
                 body: rb,
+                define_opaque: _,
             }),
         ) => {
             eq_defaultness(*ld, *rd)
@@ -502,6 +504,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
                 generics: lg,
                 contract: lc,
                 body: lb,
+                define_opaque: _,
             }),
             Fn(box ast::Fn {
                 defaultness: rd,
@@ -509,6 +512,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
                 generics: rg,
                 contract: rc,
                 body: rb,
+                define_opaque: _,
             }),
         ) => {
             eq_defaultness(*ld, *rd)
@@ -567,6 +571,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
                 generics: lg,
                 contract: lc,
                 body: lb,
+                define_opaque: _,
             }),
             Fn(box ast::Fn {
                 defaultness: rd,
@@ -574,6 +579,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
                 generics: rg,
                 contract: rc,
                 body: rb,
+                define_opaque: _,
             }),
         ) => {
             eq_defaultness(*ld, *rd)
diff --git a/src/tools/clippy/tests/ui/crashes/ice-10972-tait.rs b/src/tools/clippy/tests/ui/crashes/ice-10972-tait.rs
deleted file mode 100644
index 11ddbfc3a04..00000000000
--- a/src/tools/clippy/tests/ui/crashes/ice-10972-tait.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ check-pass
-// ICE: #10972
-// asked to assemble constituent types of unexpected type: Binder(Foo, [])
-#![feature(type_alias_impl_trait)]
-
-use std::fmt::Debug;
-type Foo = impl Debug;
-const FOO2: Foo = 22_u32;
-
-pub fn main() {}
diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed b/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed
index bac7af59491..4fe3fa4eab5 100644
--- a/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed
+++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed
@@ -192,6 +192,7 @@ impl Atpit for () {
 
 type Tait = impl DerefMut;
 //~^ implied_bounds_in_impls
+#[define_opaque(Tait)]
 fn define() -> Tait {
     &mut [] as &mut [()]
 }
diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs b/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs
index 2014cd46ada..6cc824db110 100644
--- a/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs
@@ -192,6 +192,7 @@ impl Atpit for () {
 
 type Tait = impl Deref + DerefMut;
 //~^ implied_bounds_in_impls
+#[define_opaque(Tait)]
 fn define() -> Tait {
     &mut [] as &mut [()]
 }
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
index aef5eb5b890..bd6339b7870 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
@@ -207,6 +207,7 @@ mod msrv {
 mod with_ty_alias {
     type Foo = impl std::fmt::Debug;
 
+    #[define_opaque(Foo)]
     fn foo(_: Foo) {
         let _: Foo = 1;
     }
diff --git a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs
index 8a85c566227..f317674bc1a 100644
--- a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs
+++ b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.rs
@@ -17,6 +17,7 @@ mod issue10041 {
     struct Bomb2;
 
     impl Bomb2 {
+        #[define_opaque(X)]
         pub fn new() -> X {
             //~^ ERROR: overflow evaluating the requirement
             0i32
diff --git a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr
index 77c1b64ebc8..8ecd0437e7d 100644
--- a/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr
+++ b/src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr
@@ -1,5 +1,5 @@
 error[E0275]: overflow evaluating the requirement `<i32 as std::ops::Add>::Output == issue10041::X`
-  --> tests/ui/new_ret_no_self_overflow.rs:20:25
+  --> tests/ui/new_ret_no_self_overflow.rs:21:25
    |
 LL |         pub fn new() -> X {
    |                         ^
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 253e13375c7..2b9ae195478 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -4058,7 +4058,6 @@ ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs
 ui/type-alias-impl-trait/issue-101750.rs
 ui/type-alias-impl-trait/issue-104817.rs
 ui/type-alias-impl-trait/issue-109054.rs
-ui/type-alias-impl-trait/issue-52843-closure-constrain.rs
 ui/type-alias-impl-trait/issue-52843.rs
 ui/type-alias-impl-trait/issue-53092-2.rs
 ui/type-alias-impl-trait/issue-53092.rs
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs
index 3edc68e1347..9048c6a1f18 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs
@@ -9,18 +9,16 @@
 
 extern crate core;
 
-mod defining_module {
-    pub type Type1 = impl Send;
+pub type Type1 = impl Send;
 
-    pub fn foo()
-    where
-        Type1: 'static,
-    {
-        pub struct Foo<T, const N: usize>([T; N]);
-        let _: Type1 = Foo([0; 32]);
-    }
+#[define_opaque(Type1)]
+pub fn foo()
+where
+    Type1: 'static,
+{
+    pub struct Foo<T, const N: usize>([T; N]);
+    let _: Type1 = Foo([0; 32]);
 }
-use defining_module::*;
 
 pub fn foo1(_: Type1) {}
 // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
@@ -29,6 +27,6 @@ pub fn foo2(_: Type1, _: Type1) {}
 pub fn foo3(_: Type1, _: Type1, _: Type1) {}
 // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
 
-// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EEE"}
-// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EES2_E"}
-// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EES2_S2_E"}
+// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EEE"}
+// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EES2_E"}
+// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EES2_S2_E"}
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs
index 09cfd2e10d6..36d2e8c9f25 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs
@@ -9,22 +9,18 @@
 
 extern crate core;
 
-mod defining_module {
+pub type Type1 = impl Send;
 
-    pub type Type1 = impl Send;
-
-    pub fn foo<'a>()
-    where
-        Type1: 'static,
-    {
-        pub struct Foo<'a>(&'a i32);
-        pub struct Bar<'a, 'b>(&'a i32, &'b Foo<'b>);
-        let _: Type1 = Bar;
-    }
+#[define_opaque(Type1)]
+pub fn foo<'a>()
+where
+    Type1: 'static,
+{
+    pub struct Foo<'a>(&'a i32);
+    pub struct Bar<'a, 'b>(&'a i32, &'b Foo<'b>);
+    let _: Type1 = Bar;
 }
 
-use defining_module::*;
-
 pub fn foo1(_: Type1) {}
 // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
 pub fn foo2(_: Type1, _: Type1) {}
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs
index ffbfe021ba3..a8ba8db1be3 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs
@@ -9,47 +9,41 @@
 
 extern crate core;
 
-mod defining_module {
-    pub type Type1 = impl Send;
-    pub type Type2 = impl Send;
-    pub type Type3 = impl Send;
-    pub type Type4 = impl Send;
+pub type Type1 = impl Send;
+pub type Type2 = impl Send;
+pub type Type3 = impl Send;
+pub type Type4 = impl Send;
 
-    pub fn foo()
-    where
-        Type1: 'static,
-        Type2: 'static,
-        Type4: 'static,
-    {
-        // Type in extern path
-        extern "C" {
-            fn bar();
-        }
-        let _: Type1 = bar;
-
-        // Type in closure path
-        || {
-            pub struct Foo;
-            let _: Type2 = Foo;
-        };
+#[define_opaque(Type1, Type2, Type4)]
+pub fn foo() {
+    // Type in extern path
+    extern "C" {
+        fn bar();
+    }
+    let _: Type1 = bar;
 
-        // Type in const path
-        const {
-            pub struct Foo;
-            fn bar() -> Type3 {
-                Foo
-            }
-        };
+    // Type in closure path
+    || {
+        pub struct Foo;
+        let _: Type2 = Foo;
+    };
 
-        // Type in impl path
-        struct Foo;
-        impl Foo {
-            fn bar(&self) {}
+    // Type in const path
+    const {
+        pub struct Foo;
+        #[define_opaque(Type3)]
+        fn bar() -> Type3 {
+            Foo
         }
-        let _: Type4 = <Foo>::bar;
+    };
+
+    // Type in impl path
+    struct Foo;
+    impl Foo {
+        fn bar(&self) {}
     }
+    let _: Type4 = <Foo>::bar;
 }
-use defining_module::*;
 
 // Force arguments to be passed by using a reference. Otherwise, they may end up PassMode::Ignore
 
@@ -78,15 +72,15 @@ pub fn foo11(_: &Type4, _: &Type4) {}
 pub fn foo12(_: &Type4, _: &Type4, _: &Type4) {}
 // CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
 
-// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barEE"}
-// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_E"}
-// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_S0_E"}
-// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"}
-// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"}
-// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"}
-// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"}
-// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"}
-// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"}
-// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"}
-// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"}
-// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"}
+// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barEE"}
+// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_E"}
+// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_S0_E"}
+// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"}
+// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"}
+// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"}
+// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"}
+// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"}
+// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"}
+// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"}
+// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"}
+// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"}
diff --git a/tests/crashes/120016.rs b/tests/crashes/120016.rs
index 09175689256..faba1af91b4 100644
--- a/tests/crashes/120016.rs
+++ b/tests/crashes/120016.rs
@@ -6,6 +6,7 @@
 struct Bug {
     V1: [(); {
         type F = impl std::future::Future<Output = impl Sized>;
+        #[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/crashes/122904-2.rs b/tests/crashes/122904-2.rs
index 85ed91c2fa4..db66b8625db 100644
--- a/tests/crashes/122904-2.rs
+++ b/tests/crashes/122904-2.rs
@@ -6,10 +6,12 @@ type Alias<'a> = impl T;
 struct S;
 impl<'a> T for &'a S {}
 
+#[define_opaque(Alias)]
 fn with_positive(fun: impl Fn(Alias<'_>)) {
     with_positive(|&n| ());
 }
 
+#[define_opaque(Alias)]
 fn main(Alias<'_>) {
     with_positive(|&a| ());
 }
diff --git a/tests/crashes/122904.rs b/tests/crashes/122904.rs
index 8b8bb35d56c..2068cd9d239 100644
--- a/tests/crashes/122904.rs
+++ b/tests/crashes/122904.rs
@@ -6,6 +6,7 @@ type Alias<'a> = impl T;
 struct S;
 impl<'a> T for &'a S {}
 
+#[define_opaque(Alias)]
 fn with_positive(fun: impl Fn(Alias<'_>)) {
     with_positive(|&n| ());
 }
diff --git a/tests/crashes/125185.rs b/tests/crashes/125185.rs
index 8693d6c7662..e77666ca73d 100644
--- a/tests/crashes/125185.rs
+++ b/tests/crashes/125185.rs
@@ -1,16 +1,26 @@
 //@ known-bug: rust-lang/rust#125185
 //@ compile-flags: -Zvalidate-mir
 
+#![feature(type_alias_impl_trait)]
+
 type Foo = impl Send;
 
 struct A;
 
-const VALUE: Foo = value();
+#[define_opaque(Foo)]
+const fn foo() -> Foo {
+    value()
+}
+
+const VALUE: Foo = foo();
 
-fn test(foo: Foo<'a>, f: impl for<'b> FnMut()) {
+#[define_opaque(Foo)]
+fn test(foo: Foo, f: impl for<'b> FnMut()) {
     match VALUE {
         0 | 0 => {}
 
         _ => (),
     }
 }
+
+fn main() {}
diff --git a/tests/crashes/126680.rs b/tests/crashes/126680.rs
index b1566d5e6be..dcb6ccad6b4 100644
--- a/tests/crashes/126680.rs
+++ b/tests/crashes/126680.rs
@@ -8,14 +8,18 @@ use std::path::Path;
 struct A {
     pub func: fn(check: Bar, b: Option<&Path>),
 }
-const MY_A: A = A {
-    func: |check, b| {
-        if check {
-            ()
-        } else if let Some(_) = b.and_then(|p| p.parent()) {
-            ()
-        }
-    },
-};
+
+#[define_opaque(Bar)]
+fn foo() -> A {
+    A {
+        func: |check, b| {
+            if check {
+                ()
+            } else if let Some(_) = b.and_then(|p| p.parent()) {
+                ()
+            }
+        },
+    }
+}
 
 fn main() {}
diff --git a/tests/crashes/131298.rs b/tests/crashes/131298.rs
deleted file mode 100644
index 833f1b04ffa..00000000000
--- a/tests/crashes/131298.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: #131298
-
-fn dyn_hoops<T>() -> *const dyn Iterator<Item = impl Captures> {
-    loop {}
-}
-
-mod typeck {
-    type Opaque = impl Sized;
-    fn define() -> Opaque {
-        let _: Opaque = super::dyn_hoops::<u8>();
-    }
-}
diff --git a/tests/crashes/131886.rs b/tests/crashes/131886.rs
index 2c692dfb777..16cb815f1c2 100644
--- a/tests/crashes/131886.rs
+++ b/tests/crashes/131886.rs
@@ -1,5 +1,5 @@
 //@ known-bug: #131886
-//@ compile-flags: -Zvalidate-mir --crate-type=lib
+//@ compile-flags: -Zvalidate-mir
 #![feature(type_alias_impl_trait)]
 
 type Tait = impl Sized;
@@ -7,6 +7,9 @@ type Tait = impl Sized;
 trait Foo<'a>: Bar<'a, 'a, Tait> {}
 trait Bar<'a, 'b, T> {}
 
+#[define_opaque(Tait)]
 fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) {
     let _ = x as &dyn Bar<'_, '_, ()>;
 }
+
+fn main() {}
diff --git a/tests/crashes/135528.rs b/tests/crashes/135528.rs
index a1418f40be6..171550e209e 100644
--- a/tests/crashes/135528.rs
+++ b/tests/crashes/135528.rs
@@ -7,10 +7,12 @@ fn set(x: &isize) -> isize {
     *x
 }
 
+#[define_opaque(Tait)]
 fn d(x: Tait) {
     set(x);
 }
 
+#[define_opaque(Tait)]
 fn other_define() -> Tait {
     ()
 }
diff --git a/tests/crashes/137049.rs b/tests/crashes/137049.rs
index a7132e4fa17..3dbbf280733 100644
--- a/tests/crashes/137049.rs
+++ b/tests/crashes/137049.rs
@@ -22,6 +22,7 @@ impl<T: Project1<Assoc1 = ()>> Project2 for PhantomData<T> {
 
 type Alias<T> = impl Project2;
 
+#[define_opaque(Alias)]
 fn constrain<T>() -> Alias<T> {
     PhantomData::<T>
 }
diff --git a/tests/ui/associated-inherent-types/constrain_opaque_types_during_projection.rs b/tests/ui/associated-inherent-types/constrain_opaque_types_during_projection.rs
index 292733cd492..929fa354cd0 100644
--- a/tests/ui/associated-inherent-types/constrain_opaque_types_during_projection.rs
+++ b/tests/ui/associated-inherent-types/constrain_opaque_types_during_projection.rs
@@ -11,7 +11,8 @@ impl Foo<i32> {
 
 type Tait = impl Sized;
 
-fn bar(_: Tait) {
+#[define_opaque(Tait)]
+fn bar() {
     let x: Foo<Tait>::Assoc = 42;
 }
 
diff --git a/tests/ui/associated-inherent-types/issue-109299-1.stderr b/tests/ui/associated-inherent-types/issue-109299-1.stderr
index 77a78da852f..940ccd7e400 100644
--- a/tests/ui/associated-inherent-types/issue-109299-1.stderr
+++ b/tests/ui/associated-inherent-types/issue-109299-1.stderr
@@ -29,7 +29,7 @@ error: unconstrained opaque type
 LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor;
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `X` must be used in combination with a concrete type within the same module
+   = note: `X` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/associated-type-bounds/dont-imply-atb-in-closure-inference.rs b/tests/ui/associated-type-bounds/dont-imply-atb-in-closure-inference.rs
index fecb3b15338..1cfbefb9daa 100644
--- a/tests/ui/associated-type-bounds/dont-imply-atb-in-closure-inference.rs
+++ b/tests/ui/associated-type-bounds/dont-imply-atb-in-closure-inference.rs
@@ -11,10 +11,8 @@ impl<T> IsPtr for T {
 
 type Tait = impl IsPtr<Assoc: Fn(i32)> + Fn(u32);
 
-fn hello()
-where
-    Tait:,
-{
+#[define_opaque(Tait)]
+fn hello() {
     let _: Tait = |x| {};
 }
 
diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs
index 2b4a01376d7..e9d94787e98 100644
--- a/tests/ui/associated-type-bounds/duplicate.rs
+++ b/tests/ui/associated-type-bounds/duplicate.rs
@@ -179,19 +179,25 @@ where
 
 type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
 //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
+//~| ERROR unconstrained opaque type
 type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
 //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
+//~| ERROR unconstrained opaque type
 type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
 //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
+//~| ERROR unconstrained opaque type
 type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
 //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
 //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
+//~| ERROR unconstrained opaque type
 type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
 //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
 //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
+//~| ERROR unconstrained opaque type
 type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
 //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
 //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
+//~| ERROR unconstrained opaque type
 
 trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
 //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr
index 0dabcbdce1b..1ce212a9ff3 100644
--- a/tests/ui/associated-type-bounds/duplicate.stderr
+++ b/tests/ui/associated-type-bounds/duplicate.stderr
@@ -325,7 +325,7 @@ LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:182:36
+  --> $DIR/duplicate.rs:183:36
    |
 LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -333,7 +333,7 @@ LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:184:39
+  --> $DIR/duplicate.rs:186:39
    |
 LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -341,7 +341,7 @@ LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:186:40
+  --> $DIR/duplicate.rs:189:40
    |
 LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -349,7 +349,7 @@ LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:186:40
+  --> $DIR/duplicate.rs:189:40
    |
 LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -359,7 +359,7 @@ LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:189:40
+  --> $DIR/duplicate.rs:193:40
    |
 LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -367,7 +367,7 @@ LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:189:40
+  --> $DIR/duplicate.rs:193:40
    |
 LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -377,7 +377,7 @@ LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:192:43
+  --> $DIR/duplicate.rs:197:43
    |
 LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -385,7 +385,7 @@ LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:192:43
+  --> $DIR/duplicate.rs:197:43
    |
 LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -395,7 +395,7 @@ LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:196:36
+  --> $DIR/duplicate.rs:202:36
    |
 LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -403,7 +403,7 @@ LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:198:36
+  --> $DIR/duplicate.rs:204:36
    |
 LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
    |                        ----------  ^^^^^^^^^^ re-bound here
@@ -411,7 +411,7 @@ LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:200:39
+  --> $DIR/duplicate.rs:206:39
    |
 LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
    |                        -------------  ^^^^^^^^^^^^^ re-bound here
@@ -419,7 +419,7 @@ LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:202:34
+  --> $DIR/duplicate.rs:208:34
    |
 LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -427,7 +427,7 @@ LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:202:34
+  --> $DIR/duplicate.rs:208:34
    |
 LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -437,7 +437,7 @@ LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:202:34
+  --> $DIR/duplicate.rs:208:34
    |
 LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -447,7 +447,7 @@ LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:206:34
+  --> $DIR/duplicate.rs:212:34
    |
 LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -455,7 +455,7 @@ LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:206:34
+  --> $DIR/duplicate.rs:212:34
    |
 LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -465,7 +465,7 @@ LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:206:34
+  --> $DIR/duplicate.rs:212:34
    |
 LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -475,7 +475,7 @@ LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:210:37
+  --> $DIR/duplicate.rs:216:37
    |
 LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -483,7 +483,7 @@ LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:210:37
+  --> $DIR/duplicate.rs:216:37
    |
 LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -493,7 +493,7 @@ LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:210:37
+  --> $DIR/duplicate.rs:216:37
    |
 LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -503,7 +503,7 @@ LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:216:29
+  --> $DIR/duplicate.rs:222:29
    |
 LL |     T: Iterator<Item: Copy, Item: Send>,
    |                 ----------  ^^^^^^^^^^ re-bound here
@@ -511,7 +511,7 @@ LL |     T: Iterator<Item: Copy, Item: Send>,
    |                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:222:29
+  --> $DIR/duplicate.rs:228:29
    |
 LL |     T: Iterator<Item: Copy, Item: Copy>,
    |                 ----------  ^^^^^^^^^^ re-bound here
@@ -519,7 +519,7 @@ LL |     T: Iterator<Item: Copy, Item: Copy>,
    |                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:228:32
+  --> $DIR/duplicate.rs:234:32
    |
 LL |     T: Iterator<Item: 'static, Item: 'static>,
    |                 -------------  ^^^^^^^^^^^^^ re-bound here
@@ -527,7 +527,7 @@ LL |     T: Iterator<Item: 'static, Item: 'static>,
    |                 `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:234:32
+  --> $DIR/duplicate.rs:240:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Send>,
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -535,7 +535,7 @@ LL |     Self: Iterator<Item: Copy, Item: Send>,
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:234:32
+  --> $DIR/duplicate.rs:240:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Send>,
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -545,7 +545,7 @@ LL |     Self: Iterator<Item: Copy, Item: Send>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:234:32
+  --> $DIR/duplicate.rs:240:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Send>,
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -555,7 +555,7 @@ LL |     Self: Iterator<Item: Copy, Item: Send>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:242:32
+  --> $DIR/duplicate.rs:248:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Copy>,
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -563,7 +563,7 @@ LL |     Self: Iterator<Item: Copy, Item: Copy>,
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:242:32
+  --> $DIR/duplicate.rs:248:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Copy>,
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -573,7 +573,7 @@ LL |     Self: Iterator<Item: Copy, Item: Copy>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:242:32
+  --> $DIR/duplicate.rs:248:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Copy>,
    |                    ----------  ^^^^^^^^^^ re-bound here
@@ -583,7 +583,7 @@ LL |     Self: Iterator<Item: Copy, Item: Copy>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:250:35
+  --> $DIR/duplicate.rs:256:35
    |
 LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |                    -------------  ^^^^^^^^^^^^^ re-bound here
@@ -591,7 +591,7 @@ LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |                    `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:250:35
+  --> $DIR/duplicate.rs:256:35
    |
 LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |                    -------------  ^^^^^^^^^^^^^ re-bound here
@@ -601,7 +601,7 @@ LL |     Self: Iterator<Item: 'static, Item: 'static>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:250:35
+  --> $DIR/duplicate.rs:256:35
    |
 LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |                    -------------  ^^^^^^^^^^^^^ re-bound here
@@ -611,7 +611,7 @@ LL |     Self: Iterator<Item: 'static, Item: 'static>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:257:34
+  --> $DIR/duplicate.rs:263:34
    |
 LL |     type A: Iterator<Item: Copy, Item: Send>;
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -619,7 +619,7 @@ LL |     type A: Iterator<Item: Copy, Item: Send>;
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:257:34
+  --> $DIR/duplicate.rs:263:34
    |
 LL |     type A: Iterator<Item: Copy, Item: Send>;
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -629,7 +629,7 @@ LL |     type A: Iterator<Item: Copy, Item: Send>;
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:262:34
+  --> $DIR/duplicate.rs:268:34
    |
 LL |     type A: Iterator<Item: Copy, Item: Copy>;
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -637,7 +637,7 @@ LL |     type A: Iterator<Item: Copy, Item: Copy>;
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:262:34
+  --> $DIR/duplicate.rs:268:34
    |
 LL |     type A: Iterator<Item: Copy, Item: Copy>;
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -647,7 +647,7 @@ LL |     type A: Iterator<Item: Copy, Item: Copy>;
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:267:37
+  --> $DIR/duplicate.rs:273:37
    |
 LL |     type A: Iterator<Item: 'static, Item: 'static>;
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -655,7 +655,7 @@ LL |     type A: Iterator<Item: 'static, Item: 'static>;
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:267:37
+  --> $DIR/duplicate.rs:273:37
    |
 LL |     type A: Iterator<Item: 'static, Item: 'static>;
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -697,7 +697,55 @@ help: consider specifying the generic argument
 LL |     iter::empty::<T>()
    |                +++++
 
-error: aborting due to 81 previous errors
+error: unconstrained opaque type
+  --> $DIR/duplicate.rs:180:51
+   |
+LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
+   |                                                   ^^^^^^^^^
+   |
+   = note: `ETAI1` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+  --> $DIR/duplicate.rs:183:51
+   |
+LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
+   |                                                   ^^^^^^^^^
+   |
+   = note: `ETAI2` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+  --> $DIR/duplicate.rs:186:57
+   |
+LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
+   |                                                         ^^^^^^^^^
+   |
+   = note: `ETAI3` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+  --> $DIR/duplicate.rs:189:14
+   |
+LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `ETAI4` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+  --> $DIR/duplicate.rs:193:14
+   |
+LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `ETAI5` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+  --> $DIR/duplicate.rs:197:14
+   |
+LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `ETAI6` must be used in combination with a concrete type within the same crate
+
+error: aborting due to 87 previous errors
 
 Some errors have detailed explanations: E0282, E0719.
 For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs b/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs
index fb6a4fcbe97..540c083e309 100644
--- a/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs
+++ b/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs
@@ -31,6 +31,7 @@ impl Tr1 for S1 {
 }
 
 type Et1 = impl Tr1<As1: Copy>;
+#[define_opaque(Et1)]
 fn def_et1() -> Et1 {
     S1
 }
@@ -39,6 +40,7 @@ pub fn use_et1() {
 }
 
 type Et2 = impl Tr1<As1: 'static>;
+#[define_opaque(Et2)]
 fn def_et2() -> Et2 {
     S1
 }
@@ -47,6 +49,7 @@ pub fn use_et2() {
 }
 
 type Et3 = impl Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>>;
+#[define_opaque(Et3)]
 fn def_et3() -> Et3 {
     struct A;
     impl Tr1 for A {
@@ -68,6 +71,7 @@ pub fn use_et3() {
 }
 
 type Et4 = impl Tr1<As1: for<'a> Tr2<'a>>;
+#[define_opaque(Et4)]
 fn def_et4() -> Et4 {
     #[derive(Copy, Clone)]
     struct A;
diff --git a/tests/ui/async-await/async-fn/impl-trait.rs b/tests/ui/async-await/async-fn/impl-trait.rs
index f284de8981a..89c41ceb2da 100644
--- a/tests/ui/async-await/async-fn/impl-trait.rs
+++ b/tests/ui/async-await/async-fn/impl-trait.rs
@@ -4,11 +4,14 @@
 #![feature(type_alias_impl_trait)]
 
 type Tait = impl AsyncFn();
+#[define_opaque(Tait)]
 fn tait() -> Tait {
     || async {}
 }
 
-fn foo(x: impl AsyncFn()) -> impl AsyncFn() { x }
+fn foo(x: impl AsyncFn()) -> impl AsyncFn() {
+    x
+}
 
 fn param<T: AsyncFn()>() {}
 
diff --git a/tests/ui/async-await/issues/issue-60655-latebound-regions.rs b/tests/ui/async-await/issues/issue-60655-latebound-regions.rs
index 4a8b5af5769..f9eeb361b13 100644
--- a/tests/ui/async-await/issues/issue-60655-latebound-regions.rs
+++ b/tests/ui/async-await/issues/issue-60655-latebound-regions.rs
@@ -11,15 +11,17 @@ pub type Func = impl Sized;
 
 // Late bound region should be allowed to escape the function, since it's bound
 // in the type.
+#[define_opaque(Func)]
 fn null_function_ptr() -> Func {
     None::<for<'a> fn(&'a ())>
 }
 
 async fn async_nop(_: &u8) {}
 
-pub type ServeFut = impl Future<Output=()>;
+pub type ServeFut = impl Future<Output = ()>;
 
 // Late bound regions occur in the coroutine witness type here.
+#[define_opaque(ServeFut)]
 fn serve() -> ServeFut {
     async move {
         let x = 5;
diff --git a/tests/ui/async-await/normalize-output-in-signature-deduction.rs b/tests/ui/async-await/normalize-output-in-signature-deduction.rs
index 19d70c2c6ee..e2238d85093 100644
--- a/tests/ui/async-await/normalize-output-in-signature-deduction.rs
+++ b/tests/ui/async-await/normalize-output-in-signature-deduction.rs
@@ -13,6 +13,7 @@ pub trait Trait {}
 
 pub type TAIT<T> = impl Trait;
 
+#[define_opaque(TAIT)]
 async fn foo<T>() -> TAIT<T> {
     Foo
 }
diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.rs b/tests/ui/attributes/collapse-debuginfo-invalid.rs
index d6b3554a5a8..ccf11df2eb0 100644
--- a/tests/ui/attributes/collapse-debuginfo-invalid.rs
+++ b/tests/ui/attributes/collapse-debuginfo-invalid.rs
@@ -24,15 +24,15 @@ const BAR: u32 = 3;
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 fn foo() {
     let _ = #[collapse_debuginfo(yes)] || { };
-//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     #[collapse_debuginfo(yes)]
-//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     let _ = 3;
     let _ = #[collapse_debuginfo(yes)] 3;
-//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     match (3, 4) {
         #[collapse_debuginfo(yes)]
-//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+        //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
         _ => (),
     }
 }
@@ -50,7 +50,7 @@ type Map = HashMap<u32, u32>;
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 enum Foo {
     #[collapse_debuginfo(yes)]
-//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     Variant,
 }
 
@@ -58,7 +58,7 @@ enum Foo {
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 struct Bar {
     #[collapse_debuginfo(yes)]
-//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     field: u32,
 }
 
@@ -73,7 +73,7 @@ union Qux {
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 trait Foobar {
     #[collapse_debuginfo(yes)]
-//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     type Bar;
 }
 
@@ -85,6 +85,7 @@ impl Foobar for Bar {
     type Bar = u32;
 }
 
+#[define_opaque(AFoobar)]
 fn constraining() -> AFoobar {
     Bar { field: 3 }
 }
@@ -93,11 +94,11 @@ fn constraining() -> AFoobar {
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 impl Bar {
     #[collapse_debuginfo(yes)]
-//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     const FOO: u32 = 3;
 
     #[collapse_debuginfo(yes)]
-//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     fn bar(&self) {}
 }
 
diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.stderr b/tests/ui/attributes/collapse-debuginfo-invalid.stderr
index 70376f985cb..081e4445a86 100644
--- a/tests/ui/attributes/collapse-debuginfo-invalid.stderr
+++ b/tests/ui/attributes/collapse-debuginfo-invalid.stderr
@@ -176,7 +176,7 @@ LL | type AFoobar = impl Foobar;
    | --------------------------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:92:1
+  --> $DIR/collapse-debuginfo-invalid.rs:93:1
    |
 LL |   #[collapse_debuginfo(yes)]
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -200,7 +200,7 @@ LL |     type Bar;
    |     --------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:95:5
+  --> $DIR/collapse-debuginfo-invalid.rs:96:5
    |
 LL |     #[collapse_debuginfo(yes)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +209,7 @@ LL |     const FOO: u32 = 3;
    |     ------------------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:99:5
+  --> $DIR/collapse-debuginfo-invalid.rs:100:5
    |
 LL |     #[collapse_debuginfo(yes)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/borrowck/overwrite-anon-late-param-regions.rs b/tests/ui/borrowck/overwrite-anon-late-param-regions.rs
index 7b0f784068f..8e0e005cd78 100644
--- a/tests/ui/borrowck/overwrite-anon-late-param-regions.rs
+++ b/tests/ui/borrowck/overwrite-anon-late-param-regions.rs
@@ -6,6 +6,7 @@
 #![feature(type_alias_impl_trait)]
 type Opaque2<'a> = impl Sized + 'a;
 
+#[define_opaque(Opaque2)]
 fn test2() -> impl for<'a, 'b> Fn((&'a str, &'b str)) -> (Opaque2<'a>, Opaque2<'a>) {
     |x| x
     //~^ ERROR lifetime may not live long enough
diff --git a/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr b/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr
index c5b7284271e..96b3ebf1eb4 100644
--- a/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr
+++ b/tests/ui/borrowck/overwrite-anon-late-param-regions.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/overwrite-anon-late-param-regions.rs:10:9
+  --> $DIR/overwrite-anon-late-param-regions.rs:11:9
    |
 LL |     |x| x
    |      -  ^ closure was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
@@ -8,7 +8,7 @@ LL |     |x| x
    |      has type `(&'2 str, &str)`
 
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/overwrite-anon-late-param-regions.rs:10:5
+  --> $DIR/overwrite-anon-late-param-regions.rs:11:5
    |
 LL | type Opaque2<'a> = impl Sized + 'a;
    |              -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/coherence/coherence-with-closure.rs b/tests/ui/coherence/coherence-with-closure.rs
index 5b6a62b24d4..ac2c5584392 100644
--- a/tests/ui/coherence/coherence-with-closure.rs
+++ b/tests/ui/coherence/coherence-with-closure.rs
@@ -1,6 +1,7 @@
 // Test that encountering closures during coherence does not cause issues.
 #![feature(type_alias_impl_trait)]
 type OpaqueClosure = impl Sized;
+#[define_opaque(OpaqueClosure)]
 fn defining_use() -> OpaqueClosure {
     || ()
 }
diff --git a/tests/ui/coherence/coherence-with-closure.stderr b/tests/ui/coherence/coherence-with-closure.stderr
index 501279ffe6a..37f393ceeb7 100644
--- a/tests/ui/coherence/coherence-with-closure.stderr
+++ b/tests/ui/coherence/coherence-with-closure.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
-  --> $DIR/coherence-with-closure.rs:11:1
+  --> $DIR/coherence-with-closure.rs:12:1
    |
 LL | impl Trait for Wrapper<OpaqueClosure> {}
    | ------------------------------------- first implementation here
diff --git a/tests/ui/coherence/coherence-with-coroutine.rs b/tests/ui/coherence/coherence-with-coroutine.rs
index 6b0617e950b..0e65a6c1da0 100644
--- a/tests/ui/coherence/coherence-with-coroutine.rs
+++ b/tests/ui/coherence/coherence-with-coroutine.rs
@@ -7,6 +7,7 @@
 //@ [specialized]check-pass
 
 type OpaqueCoroutine = impl Sized;
+#[define_opaque(OpaqueCoroutine)]
 fn defining_use() -> OpaqueCoroutine {
     #[coroutine]
     || {
diff --git a/tests/ui/coherence/coherence-with-coroutine.stock.stderr b/tests/ui/coherence/coherence-with-coroutine.stock.stderr
index 5f58b3088f1..c7af384df6d 100644
--- a/tests/ui/coherence/coherence-with-coroutine.stock.stderr
+++ b/tests/ui/coherence/coherence-with-coroutine.stock.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueCoroutine>`
-  --> $DIR/coherence-with-coroutine.rs:22:1
+  --> $DIR/coherence-with-coroutine.rs:23:1
    |
 LL | impl Trait for Wrapper<OpaqueCoroutine> {}
    | --------------------------------------- first implementation here
diff --git a/tests/ui/coherence/issue-99663-2.rs b/tests/ui/coherence/issue-99663-2.rs
index 675e9fdfdba..9827df1d5e7 100644
--- a/tests/ui/coherence/issue-99663-2.rs
+++ b/tests/ui/coherence/issue-99663-2.rs
@@ -8,6 +8,7 @@ struct Outer<T: ?Sized> {
 
 type InnerSend<T: ?Sized> = impl Send;
 
+#[define_opaque(InnerSend)]
 fn constrain<T: ?Sized>() -> InnerSend<T> {
     ()
 }
diff --git a/tests/ui/coherence/issue-99663.rs b/tests/ui/coherence/issue-99663.rs
index 00d15977d8f..49156952990 100644
--- a/tests/ui/coherence/issue-99663.rs
+++ b/tests/ui/coherence/issue-99663.rs
@@ -8,6 +8,7 @@ struct Send<T> {
 
 type InnerSend<T> = impl Sized;
 
+#[define_opaque(InnerSend)]
 fn constrain<T>() -> InnerSend<T> {
     ()
 }
diff --git a/tests/ui/coherence/occurs-check/opaques.current.stderr b/tests/ui/coherence/occurs-check/opaques.current.stderr
index f3fc22027c2..d3850df5218 100644
--- a/tests/ui/coherence/occurs-check/opaques.current.stderr
+++ b/tests/ui/coherence/occurs-check/opaques.current.stderr
@@ -1,11 +1,11 @@
 error[E0119]: conflicting implementations of trait `Trait<_>`
-  --> $DIR/opaques.rs:28:1
+  --> $DIR/opaques.rs:27:1
    |
 LL | impl<T> Trait<T> for T {
    | ---------------------- first implementation here
 ...
-LL | impl<T> Trait<T> for defining_scope::Alias<T> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+LL | impl<T> Trait<T> for Alias<T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr
index 04fd139f901..508e6f40234 100644
--- a/tests/ui/coherence/occurs-check/opaques.next.stderr
+++ b/tests/ui/coherence/occurs-check/opaques.next.stderr
@@ -1,17 +1,17 @@
 error[E0119]: conflicting implementations of trait `Trait<_>`
-  --> $DIR/opaques.rs:28:1
+  --> $DIR/opaques.rs:27:1
    |
 LL | impl<T> Trait<T> for T {
    | ---------------------- first implementation here
 ...
-LL | impl<T> Trait<T> for defining_scope::Alias<T> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+LL | impl<T> Trait<T> for Alias<T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error[E0282]: type annotations needed
-  --> $DIR/opaques.rs:11:23
+  --> $DIR/opaques.rs:11:19
    |
-LL |     pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
-   |                       ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
+LL | pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
+   |                   ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/coherence/occurs-check/opaques.rs b/tests/ui/coherence/occurs-check/opaques.rs
index e197256c78c..5ea654189a9 100644
--- a/tests/ui/coherence/occurs-check/opaques.rs
+++ b/tests/ui/coherence/occurs-check/opaques.rs
@@ -4,14 +4,13 @@
 
 // A regression test for #105787
 #![feature(type_alias_impl_trait)]
-mod defining_scope {
-    use super::*;
-    pub type Alias<T> = impl Sized;
 
-    pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
-        //[next]~^ ERROR type annotations needed
-        x
-    }
+pub type Alias<T> = impl Sized;
+
+#[define_opaque(Alias)]
+pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
+    //[next]~^ ERROR type annotations needed
+    x
 }
 
 struct Container<T: Trait<U>, U> {
@@ -25,12 +24,12 @@ trait Trait<T> {
 impl<T> Trait<T> for T {
     type Assoc = Box<u32>;
 }
-impl<T> Trait<T> for defining_scope::Alias<T> {
+impl<T> Trait<T> for Alias<T> {
     //~^ ERROR conflicting implementations of trait
     type Assoc = usize;
 }
 
 fn main() {
-    let x: Box<u32> = defining_scope::cast::<()>(Container { x: 0 }).x;
+    let x: Box<u32> = cast::<()>(Container { x: 0 }).x;
     println!("{}", *x);
 }
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs
index 02e9eb65570..ea91933e694 100644
--- a/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs
+++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs
@@ -7,6 +7,7 @@
 
 type Identity<T> = impl Sized;
 
+#[define_opaque(Identity)]
 fn define_identity<T>(x: T) -> Identity<T> {
     x
 }
@@ -16,6 +17,7 @@ impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
 
 type Opaque<T> = impl Sized;
 
+#[define_opaque(Opaque)]
 fn define_local<T>() -> Opaque<T> {
     Local
 }
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr b/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr
index 57f5bbd2278..6203742b47c 100644
--- a/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr
+++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-  --> $DIR/orphan-check-opaque-types-not-covering.rs:14:6
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:15:6
    |
 LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
    |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
@@ -8,7 +8,7 @@ LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
    = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
 
 error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-  --> $DIR/orphan-check-opaque-types-not-covering.rs:23:6
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:25:6
    |
 LL | impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
    |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
index 56b8acbf88c..446112cc617 100644
--- a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
+++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
@@ -3,14 +3,14 @@
 
 type Foo = impl Sized;
 
-fn with_bound<const N: usize>() -> Foo
+#[define_opaque(Foo)]
+fn with_bound<const N: usize>()
 where
     [u8; (N / 2) as usize]: Sized,
 {
     let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
     //~^ ERROR mismatched types
     //~| ERROR non-primitive cast: `usize` as `Foo`
-    todo!()
 }
 
 fn main() {
diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
index e9fb8c0f403..9f48a8563c8 100644
--- a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/opaque_type.rs:10:17
+  --> $DIR/opaque_type.rs:11:17
    |
 LL | type Foo = impl Sized;
    |            ---------- the found opaque type
@@ -11,7 +11,7 @@ LL |     let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
            found opaque type `Foo`
 
 error[E0605]: non-primitive cast: `usize` as `Foo`
-  --> $DIR/opaque_type.rs:10:17
+  --> $DIR/opaque_type.rs:11:17
    |
 LL |     let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
    |                 ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
diff --git a/tests/ui/const-generics/opaque_types.rs b/tests/ui/const-generics/opaque_types.rs
index 2c7170c889f..788d7951999 100644
--- a/tests/ui/const-generics/opaque_types.rs
+++ b/tests/ui/const-generics/opaque_types.rs
@@ -1,9 +1,8 @@
 #![feature(type_alias_impl_trait)]
 
 type Foo = impl Sized;
-//~^ ERROR: cycle
-//~| ERROR: cycle
 
+#[define_opaque(Foo)]
 fn foo<const C: Foo>() {}
 //~^ ERROR: `Foo` is forbidden as the type of a const generic parameter
 //~| ERROR: item does not constrain
diff --git a/tests/ui/const-generics/opaque_types.stderr b/tests/ui/const-generics/opaque_types.stderr
index a060488b328..f67e1c8ce69 100644
--- a/tests/ui/const-generics/opaque_types.stderr
+++ b/tests/ui/const-generics/opaque_types.stderr
@@ -1,26 +1,26 @@
 error: `Foo` is forbidden as the type of a const generic parameter
-  --> $DIR/opaque_types.rs:7:17
+  --> $DIR/opaque_types.rs:6:17
    |
 LL | fn foo<const C: Foo>() {}
    |                 ^^^
    |
    = note: the only supported types are integers, `bool`, and `char`
 
-error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
-  --> $DIR/opaque_types.rs:7:4
+error: item does not constrain `Foo::{opaque#0}`
+  --> $DIR/opaque_types.rs:6:4
    |
 LL | fn foo<const C: Foo>() {}
    |    ^^^
    |
-   = 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/opaque_types.rs:3:12
    |
 LL | type Foo = impl Sized;
    |            ^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/opaque_types.rs:12:11
+  --> $DIR/opaque_types.rs:11:11
    |
 LL | type Foo = impl Sized;
    |            ---------- the expected opaque type
@@ -31,106 +31,6 @@ LL |     foo::<42>();
    = note: expected opaque type `Foo`
                      found type `{integer}`
 
-error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
-  --> $DIR/opaque_types.rs:3:12
-   |
-LL | type Foo = impl Sized;
-   |            ^^^^^^^^^^
-   |
-note: ...which requires computing type of opaque `Foo::{opaque#0}`...
-  --> $DIR/opaque_types.rs:3:12
-   |
-LL | type Foo = impl Sized;
-   |            ^^^^^^^^^^
-note: ...which requires type-checking `main`...
-  --> $DIR/opaque_types.rs:11:1
-   |
-LL | fn main() {
-   | ^^^^^^^^^
-note: ...which requires evaluating type-level constant...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-note: ...which requires const-evaluating + checking `main::{constant#0}`...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-note: ...which requires caching mir of `main::{constant#0}` for CTFE...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-note: ...which requires elaborating drops for `main::{constant#0}`...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-   = note: ...which requires normalizing `Foo`...
-   = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
-note: cycle used when checking that `Foo::{opaque#0}` is well-formed
-  --> $DIR/opaque_types.rs:3:12
-   |
-LL | type Foo = impl Sized;
-   |            ^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}`
-  --> $DIR/opaque_types.rs:3:12
-   |
-LL | type Foo = impl Sized;
-   |            ^^^^^^^^^^
-   |
-note: ...which requires type-checking `main`...
-  --> $DIR/opaque_types.rs:11:1
-   |
-LL | fn main() {
-   | ^^^^^^^^^
-note: ...which requires evaluating type-level constant...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-note: ...which requires const-evaluating + checking `main::{constant#0}`...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-note: ...which requires caching mir of `main::{constant#0}` for CTFE...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-note: ...which requires elaborating drops for `main::{constant#0}`...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-note: ...which requires borrow-checking `main::{constant#0}`...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-note: ...which requires promoting constants in MIR for `main::{constant#0}`...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-note: ...which requires const checking `main::{constant#0}`...
-  --> $DIR/opaque_types.rs:12:11
-   |
-LL |     foo::<42>();
-   |           ^^
-   = note: ...which again requires computing type of opaque `Foo::{opaque#0}`, completing the cycle
-note: cycle used when computing type of `Foo::{opaque#0}`
-  --> $DIR/opaque_types.rs:3:12
-   |
-LL | type Foo = impl Sized;
-   |            ^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0308, E0391.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/opaque_types2.rs b/tests/ui/const-generics/opaque_types2.rs
index fd57438bb61..69f813cf84a 100644
--- a/tests/ui/const-generics/opaque_types2.rs
+++ b/tests/ui/const-generics/opaque_types2.rs
@@ -4,13 +4,14 @@ type Foo = impl Sized;
 
 fn foo<const C: u32>() {}
 
-const C: Foo = 42;
+#[define_opaque(Foo)]
+const fn baz() -> Foo {
+    42
+}
 
-fn bar()
-where
-    Foo:,
-{
-    foo::<C>();
+#[define_opaque(Foo)]
+fn bar() {
+    foo::<{ baz() }>();
     //~^ ERROR: mismatched types
 }
 
diff --git a/tests/ui/const-generics/opaque_types2.stderr b/tests/ui/const-generics/opaque_types2.stderr
index 2fb1669b7bf..98d96c3ccee 100644
--- a/tests/ui/const-generics/opaque_types2.stderr
+++ b/tests/ui/const-generics/opaque_types2.stderr
@@ -1,11 +1,11 @@
 error[E0308]: mismatched types
-  --> $DIR/opaque_types2.rs:13:11
+  --> $DIR/opaque_types2.rs:14:13
    |
 LL | type Foo = impl Sized;
    |            ---------- the found opaque type
 ...
-LL |     foo::<C>();
-   |           ^ expected `u32`, found opaque type
+LL |     foo::<{ baz() }>();
+   |             ^^^^^ expected `u32`, found opaque type
    |
    = note:     expected type `u32`
            found opaque type `Foo`
diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs b/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs
index a92b99976e2..75bd6f7a123 100644
--- a/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs
+++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs
@@ -3,14 +3,20 @@ type Foo = impl Send;
 
 struct A;
 
-const VALUE: Foo = value();
-//~^ ERROR cannot find function `value` in this scope
+#[define_opaque(Foo)]
+//~^ ERROR unstable library feature
+const fn foo() -> Foo {
+    value()
+    //~^ ERROR cannot find function `value` in this scope
+}
+
+const VALUE: Foo = foo();
 
 fn test() {
     match VALUE {
         0 | 0 => {}
-//~^ ERROR mismatched types
-//~| ERROR mismatched types
+        //~^ ERROR mismatched types
+        //~| ERROR mismatched types
         _ => (),
     }
 }
diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr
index daf0ccaa776..bcb6a80a8f2 100644
--- a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr
+++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr
@@ -1,3 +1,13 @@
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/ice-unhandled-type-122191.rs:6:3
+   |
+LL | #[define_opaque(Foo)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` 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[E0658]: `impl Trait` in type aliases is unstable
   --> $DIR/ice-unhandled-type-122191.rs:1:12
    |
@@ -9,13 +19,16 @@ LL | type Foo = impl Send;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0425]: cannot find function `value` in this scope
-  --> $DIR/ice-unhandled-type-122191.rs:6:20
+  --> $DIR/ice-unhandled-type-122191.rs:9:5
    |
-LL | const VALUE: Foo = value();
-   |                    ^^^^^ not found in this scope
+LL |     value()
+   |     ^^^^^ help: a constant with a similar name exists: `VALUE`
+...
+LL | const VALUE: Foo = foo();
+   | ------------------------- similarly named constant `VALUE` defined here
 
 error[E0308]: mismatched types
-  --> $DIR/ice-unhandled-type-122191.rs:11:9
+  --> $DIR/ice-unhandled-type-122191.rs:17:9
    |
 LL | type Foo = impl Send;
    |            --------- the expected opaque type
@@ -27,14 +40,14 @@ LL |         0 | 0 => {}
    |
    = note: expected opaque type `Foo`
                      found type `{integer}`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/ice-unhandled-type-122191.rs:9:4
+note: this item must have a `#[define_opaque(Foo)]` attribute to be able to define hidden types
+  --> $DIR/ice-unhandled-type-122191.rs:15:4
    |
 LL | fn test() {
    |    ^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/ice-unhandled-type-122191.rs:11:13
+  --> $DIR/ice-unhandled-type-122191.rs:17:13
    |
 LL | type Foo = impl Send;
    |            --------- the expected opaque type
@@ -46,13 +59,13 @@ LL |         0 | 0 => {}
    |
    = note: expected opaque type `Foo`
                      found type `{integer}`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/ice-unhandled-type-122191.rs:9:4
+note: this item must have a `#[define_opaque(Foo)]` attribute to be able to define hidden types
+  --> $DIR/ice-unhandled-type-122191.rs:15:4
    |
 LL | fn test() {
    |    ^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0308, E0425, E0658.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/const-promoted-opaque.atomic.stderr b/tests/ui/consts/const-promoted-opaque.atomic.stderr
index b9d5cbf801a..9c0c969d586 100644
--- a/tests/ui/consts/const-promoted-opaque.atomic.stderr
+++ b/tests/ui/consts/const-promoted-opaque.atomic.stderr
@@ -1,5 +1,5 @@
-error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time
-  --> $DIR/const-promoted-opaque.rs:28:26
+error[E0493]: destructor of `Foo` cannot be evaluated at compile-time
+  --> $DIR/const-promoted-opaque.rs:32:26
    |
 LL |     let _: &'static _ = &FOO;
    |                          ^^^ the destructor for this type cannot be evaluated in constants
@@ -8,13 +8,13 @@ LL | };
    | - value is dropped here
 
 error[E0492]: constants cannot refer to interior mutable data
-  --> $DIR/const-promoted-opaque.rs:32:19
+  --> $DIR/const-promoted-opaque.rs:36:19
    |
 LL | const BAZ: &Foo = &FOO;
    |                   ^^^^ this borrow of an interior mutable value may end up in the final value
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/const-promoted-opaque.rs:36:26
+  --> $DIR/const-promoted-opaque.rs:40:26
    |
 LL |     let _: &'static _ = &FOO;
    |            ----------    ^^^ creates a temporary value which is freed while still in use
diff --git a/tests/ui/consts/const-promoted-opaque.rs b/tests/ui/consts/const-promoted-opaque.rs
index bb33e92778a..188dacd1003 100644
--- a/tests/ui/consts/const-promoted-opaque.rs
+++ b/tests/ui/consts/const-promoted-opaque.rs
@@ -8,25 +8,29 @@
 //! hidden type of the opaque type. Thus we ended up relying on the
 //! result of our analysis to compute the result of our analysis.
 
-//@[unit] check-pass
+pub type Foo = impl Sized;
 
-mod helper {
-    pub type Foo = impl Sized;
+#[cfg(string)]
+#[define_opaque(Foo)]
+const fn foo() -> Foo {
+    String::new()
+}
 
-    #[cfg(string)]
-    pub const FOO: Foo = String::new();
+#[cfg(atomic)]
+#[define_opaque(Foo)]
+const fn foo() -> Foo {
+    std::sync::atomic::AtomicU8::new(42)
+}
 
-    #[cfg(atomic)]
-    pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42);
+#[cfg(unit)]
+#[define_opaque(Foo)]
+const fn foo() -> Foo {}
 
-    #[cfg(unit)]
-    pub const FOO: Foo = ();
-}
-use helper::*;
+const FOO: Foo = foo();
 
 const BAR: () = {
     let _: &'static _ = &FOO;
-    //[string,atomic]~^ ERROR: destructor of `helper::Foo` cannot be evaluated at compile-time
+    //[string,atomic,unit]~^ ERROR: destructor of `Foo` cannot be evaluated at compile-time
 };
 
 const BAZ: &Foo = &FOO;
@@ -34,5 +38,5 @@ const BAZ: &Foo = &FOO;
 
 fn main() {
     let _: &'static _ = &FOO;
-    //[string,atomic]~^ ERROR: temporary value dropped while borrowed
+    //[string,atomic,unit]~^ ERROR: temporary value dropped while borrowed
 }
diff --git a/tests/ui/consts/const-promoted-opaque.string.stderr b/tests/ui/consts/const-promoted-opaque.string.stderr
index 33e5f426448..847a466f21c 100644
--- a/tests/ui/consts/const-promoted-opaque.string.stderr
+++ b/tests/ui/consts/const-promoted-opaque.string.stderr
@@ -1,5 +1,5 @@
-error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time
-  --> $DIR/const-promoted-opaque.rs:28:26
+error[E0493]: destructor of `Foo` cannot be evaluated at compile-time
+  --> $DIR/const-promoted-opaque.rs:32:26
    |
 LL |     let _: &'static _ = &FOO;
    |                          ^^^ the destructor for this type cannot be evaluated in constants
@@ -8,7 +8,7 @@ LL | };
    | - value is dropped here
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/const-promoted-opaque.rs:36:26
+  --> $DIR/const-promoted-opaque.rs:40:26
    |
 LL |     let _: &'static _ = &FOO;
    |            ----------    ^^^ creates a temporary value which is freed while still in use
diff --git a/tests/ui/consts/const-promoted-opaque.unit.stderr b/tests/ui/consts/const-promoted-opaque.unit.stderr
new file mode 100644
index 00000000000..847a466f21c
--- /dev/null
+++ b/tests/ui/consts/const-promoted-opaque.unit.stderr
@@ -0,0 +1,24 @@
+error[E0493]: destructor of `Foo` cannot be evaluated at compile-time
+  --> $DIR/const-promoted-opaque.rs:32:26
+   |
+LL |     let _: &'static _ = &FOO;
+   |                          ^^^ the destructor for this type cannot be evaluated in constants
+LL |
+LL | };
+   | - value is dropped here
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/const-promoted-opaque.rs:40:26
+   |
+LL |     let _: &'static _ = &FOO;
+   |            ----------    ^^^ creates a temporary value which is freed while still in use
+   |            |
+   |            type annotation requires that borrow lasts for `'static`
+LL |
+LL | }
+   | - temporary value is freed at the end of this statement
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0493, E0716.
+For more information about an error, try `rustc --explain E0493`.
diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs
index 795e021ceb0..f333f3462c7 100644
--- a/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs
+++ b/tests/ui/consts/required-consts/collect-in-dead-fn-behind-opaque-type.rs
@@ -20,6 +20,7 @@ mod m {
         }
     }
 
+    #[define_opaque(NotCalledFn)]
     fn mk_not_called() -> NotCalledFn {
         not_called::<i32>
     }
diff --git a/tests/ui/coroutine/layout-error.rs b/tests/ui/coroutine/layout-error.rs
index 3e26cf17d29..6cf32134025 100644
--- a/tests/ui/coroutine/layout-error.rs
+++ b/tests/ui/coroutine/layout-error.rs
@@ -16,22 +16,20 @@ impl<F: Future> Task<F> {
     }
 }
 
-mod helper {
-    use super::*;
-    pub type F = impl Future;
-    fn foo()
-    where
-        F:,
-    {
-        async fn cb() {
-            let a = Foo; //~ ERROR cannot find value `Foo` in this scope
-        }
-
-        Task::spawn(&POOL, || cb());
+pub type F = impl Future;
+#[define_opaque(F)]
+fn foo()
+where
+    F:,
+{
+    async fn cb() {
+        let a = Foo; //~ ERROR cannot find value `Foo` in this scope
     }
+
+    Task::spawn(&POOL, || cb());
 }
 
 // Check that statics are inhabited computes they layout.
-static POOL: Task<helper::F> = Task::new();
+static POOL: Task<F> = Task::new();
 
 fn main() {}
diff --git a/tests/ui/coroutine/layout-error.stderr b/tests/ui/coroutine/layout-error.stderr
index ceadb62c999..91e35216435 100644
--- a/tests/ui/coroutine/layout-error.stderr
+++ b/tests/ui/coroutine/layout-error.stderr
@@ -1,8 +1,8 @@
 error[E0425]: cannot find value `Foo` in this scope
-  --> $DIR/layout-error.rs:27:21
+  --> $DIR/layout-error.rs:26:17
    |
-LL |             let a = Foo;
-   |                     ^^^ not found in this scope
+LL |         let a = Foo;
+   |                 ^^^ not found in this scope
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coroutine/metadata-sufficient-for-layout.rs b/tests/ui/coroutine/metadata-sufficient-for-layout.rs
index 9c3a7e4378e..b7d8575c761 100644
--- a/tests/ui/coroutine/metadata-sufficient-for-layout.rs
+++ b/tests/ui/coroutine/metadata-sufficient-for-layout.rs
@@ -15,6 +15,7 @@ mod helper {
     use std::ops::Coroutine;
     pub type F = impl Coroutine<(), Yield = (), Return = ()>;
 
+    #[define_opaque(F)]
     fn f() -> F {
         metadata_sufficient_for_layout::g()
     }
diff --git a/tests/ui/drop/drop_elaboration_with_errors.rs b/tests/ui/drop/drop_elaboration_with_errors.rs
index 35d05e6cf64..6b686e49d45 100644
--- a/tests/ui/drop/drop_elaboration_with_errors.rs
+++ b/tests/ui/drop/drop_elaboration_with_errors.rs
@@ -10,6 +10,7 @@ struct Foo {
 
 type Tait = impl Sized;
 
+#[define_opaque(Tait)]
 fn ice_cold(beverage: Tait) {
     let Foo { field } = beverage;
     _ = field;
diff --git a/tests/ui/drop/drop_elaboration_with_errors.stderr b/tests/ui/drop/drop_elaboration_with_errors.stderr
index bec229631e1..ea2c9b949e4 100644
--- a/tests/ui/drop/drop_elaboration_with_errors.stderr
+++ b/tests/ui/drop/drop_elaboration_with_errors.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/drop_elaboration_with_errors.rs:19:5
+  --> $DIR/drop_elaboration_with_errors.rs:20:5
    |
 LL | fn main() {
    |          - expected `()` because of default return type
diff --git a/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs b/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs
index d0be240e07b..4e6be341ef0 100644
--- a/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs
+++ b/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.rs
@@ -4,7 +4,11 @@ pub mod foo {
     type MainFn = impl Fn();
 
     fn bar() {}
-    pub const BAR: MainFn = bar;
+    #[define_opaque(MainFn)]
+    const fn def() -> MainFn {
+        bar
+    }
+    pub const BAR: MainFn = def();
 }
 
 use foo::BAR as main; //~ ERROR `main` function not found in crate
diff --git a/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr b/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr
index 50e4cd7d39f..375b3a53030 100644
--- a/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr
+++ b/tests/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr
@@ -1,5 +1,5 @@
 error[E0601]: `main` function not found in crate `imported_main_const_fn_item_type_forbidden`
-  --> $DIR/imported_main_const_fn_item_type_forbidden.rs:10:22
+  --> $DIR/imported_main_const_fn_item_type_forbidden.rs:14:22
    |
 LL | use foo::BAR as main;
    |     ---------------- ^ consider adding a `main` function to `$DIR/imported_main_const_fn_item_type_forbidden.rs`
diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
index 6d17f5e837d..ec70a20844a 100644
--- a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
+++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
@@ -5,27 +5,32 @@ use std::fmt::Debug;
 type Foo = impl Debug;
 
 struct Bar(Foo);
+#[define_opaque(Foo)]
 fn define() -> Bar {
     Bar(42)
 }
 
 type Foo2 = impl Debug;
 
-fn define2(_: Foo2) {
+#[define_opaque(Foo2)]
+fn define2() {
     let x = || -> Foo2 { 42 };
 }
 
 type Foo3 = impl Debug;
 
+#[define_opaque(Foo3)]
 fn define3(x: Foo3) {
     let y: i32 = x;
 }
-fn define3_1(_: Foo3) {
+#[define_opaque(Foo3)]
+fn define3_1() {
     define3(42)
 }
 
 type Foo4 = impl Debug;
 
+#[define_opaque(Foo4)]
 fn define4(_: Foo4) {
     let y: Foo4 = 42;
 }
diff --git a/tests/ui/fn/fn_def_opaque_coercion.rs b/tests/ui/fn/fn_def_opaque_coercion.rs
index 0a8810cf4f8..8235878c59d 100644
--- a/tests/ui/fn/fn_def_opaque_coercion.rs
+++ b/tests/ui/fn/fn_def_opaque_coercion.rs
@@ -11,6 +11,7 @@ fn foo<T>(t: T) -> T {
 
 type F = impl Sized;
 
+#[define_opaque(F)]
 fn f(a: F) {
     let mut x = foo::<F>;
     x = foo::<()>;
@@ -20,6 +21,7 @@ fn f(a: F) {
 
 type G = impl Sized;
 
+#[define_opaque(G)]
 fn g(a: G) {
     let x = foo::<()>;
     let _: () = x(a);
@@ -27,6 +29,7 @@ fn g(a: G) {
 
 type H = impl Sized;
 
+#[define_opaque(H)]
 fn h(a: H) {
     let x = foo::<H>;
     let _: H = x(());
@@ -34,6 +37,7 @@ fn h(a: H) {
 
 type I = impl Sized;
 
+#[define_opaque(I)]
 fn i(a: I) {
     let mut x = foo::<()>;
     x = foo::<I>;
@@ -43,6 +47,7 @@ fn i(a: I) {
 
 type J = impl Sized;
 
+#[define_opaque(J)]
 fn j(a: J) {
     let x = match true {
         true => foo::<J>,
diff --git a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs
index 5250e3a3d93..e090b7039b8 100644
--- a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs
+++ b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.rs
@@ -13,6 +13,7 @@ fn bar<T>(t: T) -> T {
 
 type F = impl Sized;
 
+#[define_opaque(F)]
 fn f(a: F) {
     let mut x = bar::<F>;
     x = foo::<()>; //~ ERROR: mismatched types
@@ -22,6 +23,7 @@ fn f(a: F) {
 
 type I = impl Sized;
 
+#[define_opaque(I)]
 fn i(a: I) {
     let mut x = bar::<()>;
     x = foo::<I>; //~ ERROR: mismatched types
@@ -31,6 +33,7 @@ fn i(a: I) {
 
 type J = impl Sized;
 
+#[define_opaque(J)]
 fn j(a: J) {
     let x = match true {
         true => bar::<J>,
diff --git a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr
index 5000601e90f..4a0991d0eb3 100644
--- a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr
+++ b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:18:9
+  --> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:19:9
    |
 LL | type F = impl Sized;
    |          ---------- the expected opaque type
@@ -13,7 +13,7 @@ LL |     x = foo::<()>;
               found fn item `fn(()) -> () {foo::<()>}`
 
 error[E0308]: mismatched types
-  --> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:27:9
+  --> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:29:9
    |
 LL | fn foo<T>(t: T) -> T {
    | -------------------- function `foo` defined here
diff --git a/tests/ui/generic-associated-types/issue-87258_b.rs b/tests/ui/generic-associated-types/issue-87258_b.rs
index 7b7610b21c7..84c7182cdcb 100644
--- a/tests/ui/generic-associated-types/issue-87258_b.rs
+++ b/tests/ui/generic-associated-types/issue-87258_b.rs
@@ -18,6 +18,7 @@ type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1;
 
 impl<'c, S: Trait2> Trait2 for &'c mut S {
     type FooFuture<'a> = Helper<'c, 'a, S>;
+    #[define_opaque(Helper)]
     fn foo<'a>() -> Self::FooFuture<'a> {
         Struct(unimplemented!())
     }
diff --git a/tests/ui/generic-associated-types/issue-87258_b.stderr b/tests/ui/generic-associated-types/issue-87258_b.stderr
index 73f984dcfb8..906ce1f50da 100644
--- a/tests/ui/generic-associated-types/issue-87258_b.stderr
+++ b/tests/ui/generic-associated-types/issue-87258_b.stderr
@@ -4,7 +4,7 @@ error: unconstrained opaque type
 LL | type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1;
    |                                                 ^^^^^^^^^^^
    |
-   = note: `Helper` must be used in combination with a concrete type within the same module
+   = note: `Helper` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/generic-associated-types/issue-88287.rs b/tests/ui/generic-associated-types/issue-88287.rs
index 5d64ad8eeae..ce0b9827d11 100644
--- a/tests/ui/generic-associated-types/issue-88287.rs
+++ b/tests/ui/generic-associated-types/issue-88287.rs
@@ -30,6 +30,7 @@ where
         A: SearchableResource<B> + ?Sized + 'f,
         Self: 'f;
 
+    #[define_opaque(SearchFutureTy)]
     fn search<'c>(&'c self, _client: &'c ()) -> Self::Future<'c, Self, Criteria> {
         async move { todo!() }
         //~^ ERROR: the size for values of type `A` cannot be known at compilation time
diff --git a/tests/ui/generic-associated-types/issue-88287.stderr b/tests/ui/generic-associated-types/issue-88287.stderr
index 54ecc5cfcd8..71cd6677e63 100644
--- a/tests/ui/generic-associated-types/issue-88287.stderr
+++ b/tests/ui/generic-associated-types/issue-88287.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the size for values of type `A` cannot be known at compilation time
-  --> $DIR/issue-88287.rs:34:9
+  --> $DIR/issue-88287.rs:35:9
    |
 LL | type SearchFutureTy<'f, A, B: 'f>
    |                         - this type parameter needs to be `Sized`
diff --git a/tests/ui/generic-associated-types/issue-90014-tait.stderr b/tests/ui/generic-associated-types/issue-90014-tait.stderr
index 09c2903ab02..fffe5b93e5a 100644
--- a/tests/ui/generic-associated-types/issue-90014-tait.stderr
+++ b/tests/ui/generic-associated-types/issue-90014-tait.stderr
@@ -1,3 +1,11 @@
+error: unconstrained opaque type
+  --> $DIR/issue-90014-tait.rs:15:20
+   |
+LL |     type Fut<'a> = impl Future<Output = ()>;
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Fut` must be used in combination with a concrete type within the same impl
+
 error[E0308]: mismatched types
   --> $DIR/issue-90014-tait.rs:18:9
    |
@@ -11,12 +19,7 @@ LL |         async { () }
    |
    = note: expected opaque type `Foo<'_>::Fut<'a>`
             found `async` block `{async block@$DIR/issue-90014-tait.rs:18:9: 18:14}`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/issue-90014-tait.rs:17:8
-   |
-LL |     fn make_fut<'a>(&'a self) -> Self::Fut<'a> {
-   |        ^^^^^^^^
 
-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/generic-associated-types/issue-90014-tait2.rs b/tests/ui/generic-associated-types/issue-90014-tait2.rs
index 3f7a9ff63c3..472a0d500c8 100644
--- a/tests/ui/generic-associated-types/issue-90014-tait2.rs
+++ b/tests/ui/generic-associated-types/issue-90014-tait2.rs
@@ -20,6 +20,7 @@ impl<'x, T: 'x> Trait<'x> for (T,) {
 }
 
 impl Foo<'_> {
+    #[define_opaque(Fut)]
     fn make_fut(&self) -> Box<dyn for<'a> Trait<'a, Thing = Fut<'a>>> {
         Box::new((async { () },))
         //~^ ERROR expected generic lifetime parameter, found `'a`
diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.stderr b/tests/ui/generic-associated-types/issue-90014-tait2.stderr
index aa427d42649..bf944aac797 100644
--- a/tests/ui/generic-associated-types/issue-90014-tait2.stderr
+++ b/tests/ui/generic-associated-types/issue-90014-tait2.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/issue-90014-tait2.rs:24:9
+  --> $DIR/issue-90014-tait2.rs:25:9
    |
 LL | type Fut<'a> = impl Future<Output = ()>;
    |          -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr
index 57cbe169118..34617448a69 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr
@@ -1,18 +1,18 @@
-error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
-  --> $DIR/norm-before-method-resolution-opaque-type.rs:16:4
+error: item does not constrain `Foo::{opaque#0}`
+  --> $DIR/norm-before-method-resolution-opaque-type.rs:17:4
    |
 LL | fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X
    |    ^^^^^^^^^^^
    |
-   = 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/norm-before-method-resolution-opaque-type.rs:14:12
    |
 LL | type Foo = impl Sized;
    |            ^^^^^^^^^^
 
 error[E0507]: cannot move out of `*x` which is behind a shared reference
-  --> $DIR/norm-before-method-resolution-opaque-type.rs:22:13
+  --> $DIR/norm-before-method-resolution-opaque-type.rs:23:13
    |
 LL |     let x = *x;
    |             ^^ move occurs because `*x` has type `<X as Trait<'_>>::Out<Foo>`, which does not implement the `Copy` trait
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs
index 43207d89276..bb663c82abb 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs
@@ -13,6 +13,7 @@ impl<'a, T> Trait<'a> for T {
 
 type Foo = impl Sized;
 
+#[define_opaque(Foo)]
 fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X
 //[old]~^ ERROR: item does not constrain
 where
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 {}
    |       ^^^^^^^^^^^^^^
diff --git a/tests/ui/implied-bounds/dyn-erasure-tait.rs b/tests/ui/implied-bounds/dyn-erasure-tait.rs
index 4766d221d67..1744e529393 100644
--- a/tests/ui/implied-bounds/dyn-erasure-tait.rs
+++ b/tests/ui/implied-bounds/dyn-erasure-tait.rs
@@ -14,6 +14,7 @@ type T<'lt> = &'lt str;
 
 type F<'a, 'b> = impl 'static + Fn(T<'a>) -> T<'b>;
 
+#[define_opaque(F)]
 fn helper<'a, 'b>(_: [&'b &'a (); 0]) -> F<'a, 'b> {
     |x: T<'a>| -> T<'b> { x } // this should *not* be `: 'static`
 }
diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs
index b87a1d2031d..90e3c58dad7 100644
--- a/tests/ui/layout/debug.rs
+++ b/tests/ui/layout/debug.rs
@@ -18,6 +18,7 @@ type Test = Result<i32, i32>; //~ ERROR: layout_of
 
 #[rustc_layout(debug)]
 type T = impl std::fmt::Debug; //~ ERROR: layout_of
+#[define_opaque(T)]
 fn f() -> T {
     0i32
 }
diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr
index 80b35ff6ad4..abaa16cdefa 100644
--- a/tests/ui/layout/debug.stderr
+++ b/tests/ui/layout/debug.stderr
@@ -1,5 +1,5 @@
 error: unions cannot have zero fields
-  --> $DIR/debug.rs:83:1
+  --> $DIR/debug.rs:84:1
    |
 LL | union EmptyUnion {}
    | ^^^^^^^^^^^^^^^^^^^
@@ -372,7 +372,7 @@ error: layout_of(V) = Layout {
            unadjusted_abi_align: Align(2 bytes),
            randomization_seed: $SEED,
        }
-  --> $DIR/debug.rs:26:1
+  --> $DIR/debug.rs:27:1
    |
 LL | pub union V {
    | ^^^^^^^^^^^
@@ -398,7 +398,7 @@ error: layout_of(W) = Layout {
            unadjusted_abi_align: Align(2 bytes),
            randomization_seed: $SEED,
        }
-  --> $DIR/debug.rs:32:1
+  --> $DIR/debug.rs:33:1
    |
 LL | pub union W {
    | ^^^^^^^^^^^
@@ -424,7 +424,7 @@ error: layout_of(Y) = Layout {
            unadjusted_abi_align: Align(2 bytes),
            randomization_seed: $SEED,
        }
-  --> $DIR/debug.rs:38:1
+  --> $DIR/debug.rs:39:1
    |
 LL | pub union Y {
    | ^^^^^^^^^^^
@@ -450,7 +450,7 @@ error: layout_of(P1) = Layout {
            unadjusted_abi_align: Align(1 bytes),
            randomization_seed: $SEED,
        }
-  --> $DIR/debug.rs:45:1
+  --> $DIR/debug.rs:46:1
    |
 LL | union P1 { x: u32 }
    | ^^^^^^^^
@@ -476,7 +476,7 @@ error: layout_of(P2) = Layout {
            unadjusted_abi_align: Align(1 bytes),
            randomization_seed: $SEED,
        }
-  --> $DIR/debug.rs:49:1
+  --> $DIR/debug.rs:50:1
    |
 LL | union P2 { x: (u32, u32) }
    | ^^^^^^^^
@@ -502,7 +502,7 @@ error: layout_of(P3) = Layout {
            unadjusted_abi_align: Align(1 bytes),
            randomization_seed: $SEED,
        }
-  --> $DIR/debug.rs:57:1
+  --> $DIR/debug.rs:58:1
    |
 LL | union P3 { x: F32x4 }
    | ^^^^^^^^
@@ -528,7 +528,7 @@ error: layout_of(P4) = Layout {
            unadjusted_abi_align: Align(1 bytes),
            randomization_seed: $SEED,
        }
-  --> $DIR/debug.rs:61:1
+  --> $DIR/debug.rs:62:1
    |
 LL | union P4 { x: E }
    | ^^^^^^^^
@@ -559,7 +559,7 @@ error: layout_of(P5) = Layout {
            unadjusted_abi_align: Align(1 bytes),
            randomization_seed: $SEED,
        }
-  --> $DIR/debug.rs:65:1
+  --> $DIR/debug.rs:66:1
    |
 LL | union P5 { zst: [u16; 0], byte: u8 }
    | ^^^^^^^^
@@ -590,19 +590,19 @@ error: layout_of(MaybeUninit<u8>) = Layout {
            unadjusted_abi_align: Align(1 bytes),
            randomization_seed: $SEED,
        }
-  --> $DIR/debug.rs:68:1
+  --> $DIR/debug.rs:69:1
    |
 LL | type X = std::mem::MaybeUninit<u8>;
    | ^^^^^^
 
 error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases
-  --> $DIR/debug.rs:71:1
+  --> $DIR/debug.rs:72:1
    |
 LL | const C: () = ();
    | ^^^^^^^^^^^
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/debug.rs:79:19
+  --> $DIR/debug.rs:80:19
    |
 LL | type Impossible = (str, str);
    |                   ^^^^^^^^^^ doesn't have a size known at compile-time
@@ -611,19 +611,19 @@ LL | type Impossible = (str, str);
    = note: only the last element of a tuple may have a dynamically sized type
 
 error: the type has an unknown layout
-  --> $DIR/debug.rs:83:1
+  --> $DIR/debug.rs:84:1
    |
 LL | union EmptyUnion {}
    | ^^^^^^^^^^^^^^^^
 
 error: the type `T` does not have a fixed layout
-  --> $DIR/debug.rs:89:1
+  --> $DIR/debug.rs:90:1
    |
 LL | type TooGeneric<T> = T;
    | ^^^^^^^^^^^^^^^^^^
 
 error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases
-  --> $DIR/debug.rs:75:5
+  --> $DIR/debug.rs:76:5
    |
 LL |     const C: () = ();
    |     ^^^^^^^^^^^
diff --git a/tests/ui/lazy-type-alias-impl-trait/branches.rs b/tests/ui/lazy-type-alias-impl-trait/branches.rs
index 95239e2e341..30f9c08a27f 100644
--- a/tests/ui/lazy-type-alias-impl-trait/branches.rs
+++ b/tests/ui/lazy-type-alias-impl-trait/branches.rs
@@ -2,16 +2,14 @@
 
 type Foo = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo(b: bool) -> Foo {
-    if b {
-        vec![42_i32]
-    } else {
-        std::iter::empty().collect()
-    }
+    if b { vec![42_i32] } else { std::iter::empty().collect() }
 }
 
 type Bar = impl std::fmt::Debug;
 
+#[define_opaque(Bar)]
 fn bar(b: bool) -> Bar {
     let x: Bar = if b {
         vec![42_i32]
diff --git a/tests/ui/lazy-type-alias-impl-trait/branches.stderr b/tests/ui/lazy-type-alias-impl-trait/branches.stderr
index 9e937622775..0cc727bc3de 100644
--- a/tests/ui/lazy-type-alias-impl-trait/branches.stderr
+++ b/tests/ui/lazy-type-alias-impl-trait/branches.stderr
@@ -1,5 +1,5 @@
 error[E0277]: a value of type `Bar` cannot be built from an iterator over elements of type `_`
-  --> $DIR/branches.rs:19:28
+  --> $DIR/branches.rs:17:28
    |
 LL |         std::iter::empty().collect()
    |                            ^^^^^^^ value of type `Bar` cannot be built from `std::iter::Iterator<Item=_>`
diff --git a/tests/ui/lazy-type-alias-impl-trait/branches2.rs b/tests/ui/lazy-type-alias-impl-trait/branches2.rs
index 467400f1c24..35b76845c85 100644
--- a/tests/ui/lazy-type-alias-impl-trait/branches2.rs
+++ b/tests/ui/lazy-type-alias-impl-trait/branches2.rs
@@ -4,20 +4,13 @@
 
 type Foo = impl std::iter::FromIterator<i32> + PartialEq<Vec<i32>> + std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo(b: bool) -> Foo {
-    if b {
-        vec![42_i32]
-    } else {
-        std::iter::empty().collect()
-    }
+    if b { vec![42_i32] } else { std::iter::empty().collect() }
 }
 
 fn bar(b: bool) -> impl PartialEq<Vec<i32>> + std::fmt::Debug {
-    if b {
-        vec![42_i32]
-    } else {
-        std::iter::empty().collect()
-    }
+    if b { vec![42_i32] } else { std::iter::empty().collect() }
 }
 
 fn main() {
diff --git a/tests/ui/lazy-type-alias-impl-trait/branches3.rs b/tests/ui/lazy-type-alias-impl-trait/branches3.rs
index 30c0af8a5dc..cff7a0b437f 100644
--- a/tests/ui/lazy-type-alias-impl-trait/branches3.rs
+++ b/tests/ui/lazy-type-alias-impl-trait/branches3.rs
@@ -3,6 +3,7 @@
 type Foo = impl for<'a> FnOnce(&'a str) -> usize;
 type Bar = impl FnOnce(&'static str) -> usize;
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     if true {
         |s| s.len() //~ ERROR type annotations needed
@@ -10,6 +11,8 @@ fn foo() -> Foo {
         panic!()
     }
 }
+
+#[define_opaque(Bar)]
 fn bar() -> Bar {
     if true {
         |s| s.len() //~ ERROR type annotations needed
diff --git a/tests/ui/lazy-type-alias-impl-trait/branches3.stderr b/tests/ui/lazy-type-alias-impl-trait/branches3.stderr
index fe2631f9474..117d189867b 100644
--- a/tests/ui/lazy-type-alias-impl-trait/branches3.stderr
+++ b/tests/ui/lazy-type-alias-impl-trait/branches3.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/branches3.rs:8:10
+  --> $DIR/branches3.rs:9:10
    |
 LL |         |s| s.len()
    |          ^  - type must be known at this point
@@ -10,7 +10,7 @@ LL |         |s: /* Type */| s.len()
    |           ++++++++++++
 
 error[E0282]: type annotations needed
-  --> $DIR/branches3.rs:15:10
+  --> $DIR/branches3.rs:18:10
    |
 LL |         |s| s.len()
    |          ^  - type must be known at this point
@@ -21,7 +21,7 @@ LL |         |s: /* Type */| s.len()
    |           ++++++++++++
 
 error[E0282]: type annotations needed
-  --> $DIR/branches3.rs:23:10
+  --> $DIR/branches3.rs:26:10
    |
 LL |         |s| s.len()
    |          ^  - type must be known at this point
@@ -32,7 +32,7 @@ LL |         |s: /* Type */| s.len()
    |           ++++++++++++
 
 error[E0282]: type annotations needed
-  --> $DIR/branches3.rs:30:10
+  --> $DIR/branches3.rs:33:10
    |
 LL |         |s| s.len()
    |          ^  - type must be known at this point
diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion.rs b/tests/ui/lazy-type-alias-impl-trait/recursion.rs
index 51933560599..33dbf8d0280 100644
--- a/tests/ui/lazy-type-alias-impl-trait/recursion.rs
+++ b/tests/ui/lazy-type-alias-impl-trait/recursion.rs
@@ -4,9 +4,10 @@
 
 type Foo = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo(b: bool) -> Foo {
     if b {
-        return 42
+        return 42;
     }
     let x: u32 = foo(false);
     99
@@ -14,7 +15,7 @@ fn foo(b: bool) -> Foo {
 
 fn bar(b: bool) -> impl std::fmt::Debug {
     if b {
-        return 42
+        return 42;
     }
     let x: u32 = bar(false);
     99
diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion2.rs b/tests/ui/lazy-type-alias-impl-trait/recursion2.rs
index e14da32e116..b28a95c53f4 100644
--- a/tests/ui/lazy-type-alias-impl-trait/recursion2.rs
+++ b/tests/ui/lazy-type-alias-impl-trait/recursion2.rs
@@ -4,6 +4,7 @@
 
 type Foo = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo(b: bool) -> Foo {
     if b {
         return vec![];
@@ -14,7 +15,7 @@ fn foo(b: bool) -> Foo {
 
 fn bar(b: bool) -> impl std::fmt::Debug {
     if b {
-        return vec![]
+        return vec![];
     }
     let x: Vec<i32> = bar(false);
     std::iter::empty().collect()
diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion3.rs b/tests/ui/lazy-type-alias-impl-trait/recursion3.rs
index 7f1cedae068..0b15484f7ef 100644
--- a/tests/ui/lazy-type-alias-impl-trait/recursion3.rs
+++ b/tests/ui/lazy-type-alias-impl-trait/recursion3.rs
@@ -2,9 +2,10 @@
 
 type Foo = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo(b: bool) -> Foo {
     if b {
-        return 42
+        return 42;
     }
     let x: u32 = foo(false) + 42; //~ ERROR cannot add
     99
@@ -12,7 +13,7 @@ fn foo(b: bool) -> Foo {
 
 fn bar(b: bool) -> impl std::fmt::Debug {
     if b {
-        return 42
+        return 42;
     }
     let x: u32 = bar(false) + 42; //~ ERROR cannot add
     99
diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion3.stderr b/tests/ui/lazy-type-alias-impl-trait/recursion3.stderr
index e1d5cafedc8..0cbedfb69f8 100644
--- a/tests/ui/lazy-type-alias-impl-trait/recursion3.stderr
+++ b/tests/ui/lazy-type-alias-impl-trait/recursion3.stderr
@@ -1,5 +1,5 @@
 error[E0369]: cannot add `{integer}` to `Foo`
-  --> $DIR/recursion3.rs:9:29
+  --> $DIR/recursion3.rs:10:29
    |
 LL |     let x: u32 = foo(false) + 42;
    |                  ---------- ^ -- {integer}
@@ -7,7 +7,7 @@ LL |     let x: u32 = foo(false) + 42;
    |                  Foo
 
 error[E0369]: cannot add `{integer}` to `impl Debug`
-  --> $DIR/recursion3.rs:17:29
+  --> $DIR/recursion3.rs:18:29
    |
 LL |     let x: u32 = bar(false) + 42;
    |                  ---------- ^ -- {integer}
diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion4.rs b/tests/ui/lazy-type-alias-impl-trait/recursion4.rs
index 57dd7fb067c..892e72e2335 100644
--- a/tests/ui/lazy-type-alias-impl-trait/recursion4.rs
+++ b/tests/ui/lazy-type-alias-impl-trait/recursion4.rs
@@ -2,6 +2,7 @@
 
 type Foo = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo(b: bool) -> Foo {
     if b {
         return vec![];
diff --git a/tests/ui/lazy-type-alias-impl-trait/recursion4.stderr b/tests/ui/lazy-type-alias-impl-trait/recursion4.stderr
index d8ac39a4f27..b04bf6b9987 100644
--- a/tests/ui/lazy-type-alias-impl-trait/recursion4.stderr
+++ b/tests/ui/lazy-type-alias-impl-trait/recursion4.stderr
@@ -1,5 +1,5 @@
 error[E0277]: a value of type `Foo` cannot be built from an iterator over elements of type `_`
-  --> $DIR/recursion4.rs:10:28
+  --> $DIR/recursion4.rs:11:28
    |
 LL |     x = std::iter::empty().collect();
    |                            ^^^^^^^ value of type `Foo` cannot be built from `std::iter::Iterator<Item=_>`
@@ -9,7 +9,7 @@ note: required by a bound in `collect`
   --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
 
 error[E0277]: a value of type `impl Debug` cannot be built from an iterator over elements of type `_`
-  --> $DIR/recursion4.rs:19:28
+  --> $DIR/recursion4.rs:20:28
    |
 LL |     x = std::iter::empty().collect();
    |                            ^^^^^^^ value of type `impl Debug` cannot be built from `std::iter::Iterator<Item=_>`
diff --git a/tests/ui/lint/issue-99387.rs b/tests/ui/lint/issue-99387.rs
index 6f082239456..b40d31384be 100644
--- a/tests/ui/lint/issue-99387.rs
+++ b/tests/ui/lint/issue-99387.rs
@@ -6,6 +6,7 @@
 
 pub type Successors<'a> = impl Iterator<Item = &'a ()>;
 
+#[define_opaque(Successors)]
 pub fn f<'a>() -> Successors<'a> {
     None.into_iter()
 }
diff --git a/tests/ui/lint/issue-99387.stderr b/tests/ui/lint/issue-99387.stderr
index 4eee4f36392..0d9ded23c78 100644
--- a/tests/ui/lint/issue-99387.stderr
+++ b/tests/ui/lint/issue-99387.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-99387.rs:22:5
+  --> $DIR/issue-99387.rs:23:5
    |
 LL | pub type Successors<'a> = impl Iterator<Item = &'a ()>;
    |                           ---------------------------- the expected opaque type
@@ -11,8 +11,8 @@ LL |     None.into_iter()
    |
    = note: expected opaque type `Successors<'a>`
                    found struct `std::option::IntoIter<_>`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/issue-99387.rs:21:8
+note: this item must have a `#[define_opaque(Successors)]` attribute to be able to define hidden types
+  --> $DIR/issue-99387.rs:22:8
    |
 LL | pub fn ohno<'a>() -> <&'a () as Tr>::Item {
    |        ^^^^
diff --git a/tests/ui/lint/let_underscore/issue-119697-extra-let.rs b/tests/ui/lint/let_underscore/issue-119697-extra-let.rs
index 84abb933911..9782b3191fd 100644
--- a/tests/ui/lint/let_underscore/issue-119697-extra-let.rs
+++ b/tests/ui/lint/let_underscore/issue-119697-extra-let.rs
@@ -8,6 +8,7 @@ pub struct Foo {
 
 pub type Tait = impl Sized;
 
+#[define_opaque(Tait)]
 pub fn ice_cold(beverage: Tait) {
     // Must destructure at least one field of `Foo`
     let Foo { field } = beverage;
@@ -17,5 +18,4 @@ pub fn ice_cold(beverage: Tait) {
     let _ = field; //~ ERROR non-binding let on a type that has a destructor
 }
 
-
 pub fn main() {}
diff --git a/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr b/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
index 3ff57ab441d..8d5deadd46e 100644
--- a/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
+++ b/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
@@ -1,5 +1,5 @@
 error: non-binding let on a type that has a destructor
-  --> $DIR/issue-119697-extra-let.rs:15:5
+  --> $DIR/issue-119697-extra-let.rs:16:5
    |
 LL |     _ = field;
    |     ^^^^^^^^^
@@ -21,7 +21,7 @@ LL +     drop(field);
    |
 
 error: non-binding let on a type that has a destructor
-  --> $DIR/issue-119697-extra-let.rs:17:5
+  --> $DIR/issue-119697-extra-let.rs:18:5
    |
 LL |     let _ = field;
    |     ^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/lint-ctypes-73249-2.rs b/tests/ui/lint/lint-ctypes-73249-2.rs
index f30377d6c16..31af0e3d381 100644
--- a/tests/ui/lint/lint-ctypes-73249-2.rs
+++ b/tests/ui/lint/lint-ctypes-73249-2.rs
@@ -7,6 +7,7 @@ impl Baz for () {}
 
 type Qux = impl Baz;
 
+#[define_opaque(Qux)]
 fn assign() -> Qux {}
 
 trait Foo {
diff --git a/tests/ui/lint/lint-ctypes-73249-2.stderr b/tests/ui/lint/lint-ctypes-73249-2.stderr
index ef30a406969..2d0dfe94f09 100644
--- a/tests/ui/lint/lint-ctypes-73249-2.stderr
+++ b/tests/ui/lint/lint-ctypes-73249-2.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `Qux`, which is not FFI-safe
-  --> $DIR/lint-ctypes-73249-2.rs:26:21
+  --> $DIR/lint-ctypes-73249-2.rs:27:21
    |
 LL |     fn lint_me() -> A<()>;
    |                     ^^^^^ not FFI-safe
diff --git a/tests/ui/lint/lint-ctypes-73249-3.rs b/tests/ui/lint/lint-ctypes-73249-3.rs
index ef8ab7e03d2..8bdf536bf77 100644
--- a/tests/ui/lint/lint-ctypes-73249-3.rs
+++ b/tests/ui/lint/lint-ctypes-73249-3.rs
@@ -7,6 +7,7 @@ impl Baz for u32 {}
 
 type Qux = impl Baz;
 
+#[define_opaque(Qux)]
 fn assign() -> Qux {
     3
 }
diff --git a/tests/ui/lint/lint-ctypes-73249-3.stderr b/tests/ui/lint/lint-ctypes-73249-3.stderr
index e5607ba72e9..e1a313a2906 100644
--- a/tests/ui/lint/lint-ctypes-73249-3.stderr
+++ b/tests/ui/lint/lint-ctypes-73249-3.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `Qux`, which is not FFI-safe
-  --> $DIR/lint-ctypes-73249-3.rs:20:25
+  --> $DIR/lint-ctypes-73249-3.rs:21:25
    |
 LL |     pub fn lint_me() -> A;
    |                         ^ not FFI-safe
diff --git a/tests/ui/lint/lint-ctypes-73249-5.rs b/tests/ui/lint/lint-ctypes-73249-5.rs
index 083fb6c5fb1..cc6da59950d 100644
--- a/tests/ui/lint/lint-ctypes-73249-5.rs
+++ b/tests/ui/lint/lint-ctypes-73249-5.rs
@@ -7,6 +7,7 @@ impl Baz for u32 {}
 
 type Qux = impl Baz;
 
+#[define_opaque(Qux)]
 fn assign() -> Qux {
     3
 }
diff --git a/tests/ui/lint/lint-ctypes-73249-5.stderr b/tests/ui/lint/lint-ctypes-73249-5.stderr
index fcb106c485d..c4fa955de05 100644
--- a/tests/ui/lint/lint-ctypes-73249-5.stderr
+++ b/tests/ui/lint/lint-ctypes-73249-5.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `Qux`, which is not FFI-safe
-  --> $DIR/lint-ctypes-73249-5.rs:20:25
+  --> $DIR/lint-ctypes-73249-5.rs:21:25
    |
 LL |     pub fn lint_me() -> A;
    |                         ^ not FFI-safe
diff --git a/tests/ui/lint/lint-ctypes-73251-1.rs b/tests/ui/lint/lint-ctypes-73251-1.rs
index fc11f23a104..07ae05be69f 100644
--- a/tests/ui/lint/lint-ctypes-73251-1.rs
+++ b/tests/ui/lint/lint-ctypes-73251-1.rs
@@ -15,6 +15,7 @@ impl Foo for u32 {
     type Assoc = Qux;
 }
 
+#[define_opaque(Qux)]
 fn assign() -> Qux {
     1
 }
diff --git a/tests/ui/lint/lint-ctypes-73251-1.stderr b/tests/ui/lint/lint-ctypes-73251-1.stderr
index a3b3ebaac30..675a9de51cd 100644
--- a/tests/ui/lint/lint-ctypes-73251-1.stderr
+++ b/tests/ui/lint/lint-ctypes-73251-1.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `Qux`, which is not FFI-safe
-  --> $DIR/lint-ctypes-73251-1.rs:23:21
+  --> $DIR/lint-ctypes-73251-1.rs:24:21
    |
 LL |     fn lint_me() -> <u32 as Foo>::Assoc;
    |                     ^^^^^^^^^^^^^^^^^^^ not FFI-safe
diff --git a/tests/ui/lint/lint-ctypes-73251-2.rs b/tests/ui/lint/lint-ctypes-73251-2.rs
index fbe0a58f3b5..c47118672e0 100644
--- a/tests/ui/lint/lint-ctypes-73251-2.rs
+++ b/tests/ui/lint/lint-ctypes-73251-2.rs
@@ -24,10 +24,12 @@ type AliasA = impl TraitA<Assoc = u32>;
 
 type AliasB = impl TraitB<Assoc = AliasA>;
 
+#[define_opaque(AliasA)]
 fn use_of_a() -> AliasA {
     3
 }
 
+#[define_opaque(AliasB)]
 fn use_of_b() -> AliasB {
     3
 }
diff --git a/tests/ui/lint/lint-ctypes-73251-2.stderr b/tests/ui/lint/lint-ctypes-73251-2.stderr
index 40a9cd00c50..634950b29ed 100644
--- a/tests/ui/lint/lint-ctypes-73251-2.stderr
+++ b/tests/ui/lint/lint-ctypes-73251-2.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `AliasA`, which is not FFI-safe
-  --> $DIR/lint-ctypes-73251-2.rs:36:21
+  --> $DIR/lint-ctypes-73251-2.rs:38:21
    |
 LL |     fn lint_me() -> <AliasB as TraitB>::Assoc;
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
diff --git a/tests/ui/lint/lint-ctypes-73251.rs b/tests/ui/lint/lint-ctypes-73251.rs
index 68eeb67deea..15c1dfcaabf 100644
--- a/tests/ui/lint/lint-ctypes-73251.rs
+++ b/tests/ui/lint/lint-ctypes-73251.rs
@@ -13,6 +13,7 @@ impl Foo for () {
 
 type Bar = impl Foo<Assoc = u32>;
 
+#[define_opaque(Bar)]
 fn assign() -> Bar {}
 
 extern "C" {
diff --git a/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs
index c83bca4a4c5..dee77cf4873 100644
--- a/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs
+++ b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.rs
@@ -25,10 +25,12 @@ type AliasA = impl TraitA<Assoc = u32>;
 
 type AliasB = impl TraitB;
 
+#[define_opaque(AliasA)]
 fn use_of_a() -> AliasA {
     3
 }
 
+#[define_opaque(AliasB)]
 fn use_of_b() -> AliasB {
     3
 }
diff --git a/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr
index 9efc187833f..020eac4febb 100644
--- a/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr
+++ b/tests/ui/lint/opaque-ty-ffi-normalization-cycle.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `AliasB`, which is not FFI-safe
-  --> $DIR/opaque-ty-ffi-normalization-cycle.rs:37:21
+  --> $DIR/opaque-ty-ffi-normalization-cycle.rs:39:21
    |
 LL |     fn lint_me() -> <AliasB as TraitB>::Assoc;
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
diff --git a/tests/ui/lint/opaque-ty-ffi-unsafe.rs b/tests/ui/lint/opaque-ty-ffi-unsafe.rs
index 5faeac9ed4c..97016267fa8 100644
--- a/tests/ui/lint/opaque-ty-ffi-unsafe.rs
+++ b/tests/ui/lint/opaque-ty-ffi-unsafe.rs
@@ -3,6 +3,7 @@
 
 type A = impl Fn();
 
+#[define_opaque(A)]
 pub(crate) fn ret_closure() -> A {
     || {}
 }
diff --git a/tests/ui/lint/opaque-ty-ffi-unsafe.stderr b/tests/ui/lint/opaque-ty-ffi-unsafe.stderr
index 7f5d1792bf1..5c52f702671 100644
--- a/tests/ui/lint/opaque-ty-ffi-unsafe.stderr
+++ b/tests/ui/lint/opaque-ty-ffi-unsafe.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `A`, which is not FFI-safe
-  --> $DIR/opaque-ty-ffi-unsafe.rs:11:24
+  --> $DIR/opaque-ty-ffi-unsafe.rs:12:24
    |
 LL |     pub(crate) fn a(_: A);
    |                        ^ not FFI-safe
diff --git a/tests/ui/methods/opaque_param_in_ufc.rs b/tests/ui/methods/opaque_param_in_ufc.rs
index b170e6805f6..3b0c8b778ff 100644
--- a/tests/ui/methods/opaque_param_in_ufc.rs
+++ b/tests/ui/methods/opaque_param_in_ufc.rs
@@ -11,11 +11,13 @@ impl Foo<u32> {
 
 type Bar = impl Sized;
 
+#[define_opaque(Bar)]
 fn bar() -> Bar {
     42_u32
 }
 
 impl Foo<Bar> {
+    #[define_opaque(Bar)]
     fn foo() -> Bar {
         Self::method();
         Foo::<Bar>::method();
diff --git a/tests/ui/mir/issue-75053.rs b/tests/ui/mir/issue-75053.rs
index 38684f3548f..9b247fa5434 100644
--- a/tests/ui/mir/issue-75053.rs
+++ b/tests/ui/mir/issue-75053.rs
@@ -13,13 +13,11 @@ trait MyFrom<T>: Sized {
     fn my_from(value: T) -> Result<Self, Self::Error>;
 }
 
-mod f {
-    pub trait F {}
-    impl F for () {}
-    pub type DummyT<T> = impl F;
-    fn _dummy_t<T>() -> DummyT<T> {}
-}
-use f::*;
+pub trait F {}
+impl F for () {}
+pub type DummyT<T> = impl F;
+#[define_opaque(DummyT)]
+fn _dummy_t<T>() -> DummyT<T> {}
 
 struct Phantom1<T>(PhantomData<T>);
 struct Phantom2<T>(PhantomData<T>);
diff --git a/tests/ui/mir/issue-75053.stderr b/tests/ui/mir/issue-75053.stderr
index a464d3266f4..91032bc3797 100644
--- a/tests/ui/mir/issue-75053.stderr
+++ b/tests/ui/mir/issue-75053.stderr
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/issue-75053.rs:49:1
+  --> $DIR/issue-75053.rs:47:1
    |
 LL | fn main() {
    | ^^^^^^^^^
diff --git a/tests/ui/never_type/impl_trait_fallback2.rs b/tests/ui/never_type/impl_trait_fallback2.rs
index 12c187b9e82..399bd72561b 100644
--- a/tests/ui/never_type/impl_trait_fallback2.rs
+++ b/tests/ui/never_type/impl_trait_fallback2.rs
@@ -12,11 +12,13 @@ fn should_ret_unit() -> impl T {
 
 type Foo = impl T;
 
+#[define_opaque(Foo)]
 fn a() -> Foo {
     //~^ ERROR `(): T` is not satisfied
     panic!()
 }
 
+#[define_opaque(Foo)]
 fn b() -> Foo {
     42
 }
diff --git a/tests/ui/never_type/impl_trait_fallback2.stderr b/tests/ui/never_type/impl_trait_fallback2.stderr
index 4c32dce465b..0f197aa5cc6 100644
--- a/tests/ui/never_type/impl_trait_fallback2.stderr
+++ b/tests/ui/never_type/impl_trait_fallback2.stderr
@@ -10,7 +10,7 @@ LL |     panic!()
    = help: the trait `T` is implemented for `i32`
 
 error[E0277]: the trait bound `(): T` is not satisfied
-  --> $DIR/impl_trait_fallback2.rs:15:11
+  --> $DIR/impl_trait_fallback2.rs:16:11
    |
 LL | fn a() -> Foo {
    |           ^^^ the trait `T` is not implemented for `()`
diff --git a/tests/ui/never_type/impl_trait_fallback3.rs b/tests/ui/never_type/impl_trait_fallback3.rs
index ed645b82394..3740aad73f0 100644
--- a/tests/ui/never_type/impl_trait_fallback3.rs
+++ b/tests/ui/never_type/impl_trait_fallback3.rs
@@ -8,6 +8,7 @@ trait T {
 
 type Foo = impl T;
 
+#[define_opaque(Foo)]
 fn a() -> Foo {
     //~^ ERROR the trait bound `(): T` is not satisfied
     // This is not a defining use, it doesn't actually constrain the opaque type.
diff --git a/tests/ui/never_type/impl_trait_fallback3.stderr b/tests/ui/never_type/impl_trait_fallback3.stderr
index fde8d0896dd..11425a74953 100644
--- a/tests/ui/never_type/impl_trait_fallback3.stderr
+++ b/tests/ui/never_type/impl_trait_fallback3.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(): T` is not satisfied
-  --> $DIR/impl_trait_fallback3.rs:11:11
+  --> $DIR/impl_trait_fallback3.rs:12:11
    |
 LL | fn a() -> Foo {
    |           ^^^ the trait `T` is not implemented for `()`
diff --git a/tests/ui/never_type/impl_trait_fallback4.rs b/tests/ui/never_type/impl_trait_fallback4.rs
index fe62773fa02..2fa3d0028be 100644
--- a/tests/ui/never_type/impl_trait_fallback4.rs
+++ b/tests/ui/never_type/impl_trait_fallback4.rs
@@ -15,6 +15,7 @@ fn foo() -> impl T {
     panic!()
 }
 
+#[define_opaque(Foo)]
 fn a() -> Foo {
     foo()
 }
diff --git a/tests/ui/pattern/usefulness/impl-trait.rs b/tests/ui/pattern/usefulness/impl-trait.rs
index 16560a09267..47cee17b579 100644
--- a/tests/ui/pattern/usefulness/impl-trait.rs
+++ b/tests/ui/pattern/usefulness/impl-trait.rs
@@ -25,6 +25,7 @@ fn friend_of_return_never_rpit(x: Void) {
 }
 
 type T = impl Copy;
+#[define_opaque(T)]
 fn return_never_tait(x: Void) -> T {
     if false {
         match return_never_tait(x) {
@@ -88,6 +89,7 @@ fn inner_tuple() {
 }
 
 type U = impl Copy;
+#[define_opaque(U)]
 fn unify_never(x: Void, u: U) -> U {
     if false {
         match u {
@@ -98,6 +100,7 @@ fn unify_never(x: Void, u: U) -> U {
 }
 
 type V = impl Copy;
+#[define_opaque(V)]
 fn infer_in_match(x: Option<V>) {
     match x {
         None => {}
@@ -116,6 +119,7 @@ struct Rec<'a> {
     n: u32,
     w: Option<&'a W>,
 }
+#[define_opaque(W)]
 fn recursive_opaque() -> W {
     if false {
         match recursive_opaque() {
@@ -130,6 +134,7 @@ fn recursive_opaque() -> W {
 
 type X = impl Copy;
 struct SecretelyVoid(X);
+#[define_opaque(X)]
 fn nested_empty_opaque(x: Void) -> X {
     if false {
         let opaque_void = nested_empty_opaque(x);
@@ -143,6 +148,7 @@ fn nested_empty_opaque(x: Void) -> X {
 
 type Y = (impl Copy, impl Copy);
 struct SecretelyDoubleVoid(Y);
+#[define_opaque(Y)]
 fn super_nested_empty_opaque(x: Void) -> Y {
     if false {
         let opaque_void = super_nested_empty_opaque(x);
diff --git a/tests/ui/pattern/usefulness/impl-trait.stderr b/tests/ui/pattern/usefulness/impl-trait.stderr
index c3e1c267b61..62045151968 100644
--- a/tests/ui/pattern/usefulness/impl-trait.stderr
+++ b/tests/ui/pattern/usefulness/impl-trait.stderr
@@ -15,7 +15,7 @@ LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:31:13
+  --> $DIR/impl-trait.rs:32:13
    |
 LL |             _ => {}
    |             ^------
@@ -25,22 +25,8 @@ LL |             _ => {}
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
-error[E0004]: non-exhaustive patterns: type `impl Copy` is non-empty
-  --> $DIR/impl-trait.rs:23:11
-   |
-LL |     match return_never_rpit(x) {}
-   |           ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: the matched value is of type `impl Copy`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
-   |
-LL ~     match return_never_rpit(x) {
-LL +         _ => todo!(),
-LL ~     }
-   |
-
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:45:13
+  --> $DIR/impl-trait.rs:46:13
    |
 LL |             Some(_) => {}
    |             ^^^^^^^------
@@ -51,7 +37,7 @@ LL |             Some(_) => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:49:13
+  --> $DIR/impl-trait.rs:50:13
    |
 LL |             None => {}
    |             ---- matches all the relevant values
@@ -59,7 +45,7 @@ LL |             _ => {}
    |             ^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:59:13
+  --> $DIR/impl-trait.rs:60:13
    |
 LL |             Some(_) => {}
    |             ^^^^^^^------
@@ -70,7 +56,7 @@ LL |             Some(_) => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:63:13
+  --> $DIR/impl-trait.rs:64:13
    |
 LL |             None => {}
    |             ---- matches all the relevant values
@@ -78,7 +64,7 @@ LL |             _ => {}
    |             ^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:76:9
+  --> $DIR/impl-trait.rs:77:9
    |
 LL |         _ => {}
    |         ^------
@@ -89,7 +75,7 @@ LL |         _ => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:86:9
+  --> $DIR/impl-trait.rs:87:9
    |
 LL |         _ => {}
    |         - matches any value
@@ -97,7 +83,7 @@ LL |         Some((a, b)) => {}
    |         ^^^^^^^^^^^^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:94:13
+  --> $DIR/impl-trait.rs:96:13
    |
 LL |             _ => {}
    |             ^------
@@ -107,22 +93,8 @@ LL |             _ => {}
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
-error[E0004]: non-exhaustive patterns: type `T` is non-empty
-  --> $DIR/impl-trait.rs:37:11
-   |
-LL |     match return_never_tait(x) {}
-   |           ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: the matched value is of type `T`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
-   |
-LL ~     match return_never_tait(x) {
-LL +         _ => todo!(),
-LL ~     }
-   |
-
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:105:9
+  --> $DIR/impl-trait.rs:108:9
    |
 LL |         Some((a, b)) => {}
    |         ------------ matches all the relevant values
@@ -130,7 +102,7 @@ LL |         Some((mut x, mut y)) => {
    |         ^^^^^^^^^^^^^^^^^^^^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:124:13
+  --> $DIR/impl-trait.rs:128:13
    |
 LL |             _ => {}
    |             - matches any value
@@ -138,7 +110,7 @@ LL |             Rec { n: 0, w: Some(Rec { n: 0, w: _ }) } => {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no value can reach this
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:138:13
+  --> $DIR/impl-trait.rs:143:13
    |
 LL |             _ => {}
    |             ^------
@@ -149,7 +121,7 @@ LL |             _ => {}
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
 error: unreachable pattern
-  --> $DIR/impl-trait.rs:151:13
+  --> $DIR/impl-trait.rs:157:13
    |
 LL |             _ => {}
    |             ^------
@@ -159,6 +131,34 @@ LL |             _ => {}
    |
    = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
 
+error[E0004]: non-exhaustive patterns: type `impl Copy` is non-empty
+  --> $DIR/impl-trait.rs:23:11
+   |
+LL |     match return_never_rpit(x) {}
+   |           ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the matched value is of type `impl Copy`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match return_never_rpit(x) {
+LL +         _ => todo!(),
+LL ~     }
+   |
+
+error[E0004]: non-exhaustive patterns: type `T` is non-empty
+  --> $DIR/impl-trait.rs:38:11
+   |
+LL |     match return_never_tait(x) {}
+   |           ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the matched value is of type `T`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match return_never_tait(x) {
+LL +         _ => todo!(),
+LL ~     }
+   |
+
 error: aborting due to 15 previous errors
 
 For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs b/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs
index fd0e07fb9b4..743ca650fdd 100644
--- a/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs
+++ b/tests/ui/privacy/private-in-public-type-alias-impl-trait.rs
@@ -8,6 +8,7 @@ pub type Pub = impl Default;
 #[derive(Default)]
 struct Priv;
 
+#[define_opaque(Pub)]
 fn check() -> Pub {
     Priv
 }
diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs
index 34b94f2e1c7..4cf2d1ac4a6 100644
--- a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs
+++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs
@@ -12,6 +12,7 @@ impl<'a, T> Trait<'a> for T {
 mod basic_pass {
     use super::*;
     type Opq<'a> = impl Sized + 'a;
+    #[define_opaque(Opq)]
     fn test() -> impl for<'a> Trait<'a, Ty = Opq<'a>> {}
     //~^ ERROR: expected generic lifetime parameter, found `'a`
 }
@@ -27,6 +28,7 @@ mod capture_tait {
     type Opq0 = impl Sized;
     type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0>;
     type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
+    #[define_opaque(Opq2)]
     fn test() -> Opq2 {}
     //~^ ERROR hidden type for `capture_tait::Opq0` captures lifetime that does not appear in bounds
 }
@@ -36,6 +38,7 @@ mod capture_tait_complex_pass {
     type Opq0<'a> = impl Sized;
     type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b
     type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
+    #[define_opaque(Opq2)]
     fn test() -> Opq2 {}
     //~^ ERROR: expected generic lifetime parameter, found `'a`
 }
@@ -46,6 +49,7 @@ mod capture_tait_complex_fail {
     type Opq0<'a> = impl Sized;
     type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a>>; // <- Note 'a
     type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
+    #[define_opaque(Opq2)]
     fn test() -> Opq2 {}
     //~^ ERROR hidden type for `capture_tait_complex_fail::Opq0<'a>` captures lifetime that does not appear in bounds
 }
@@ -54,18 +58,18 @@ mod capture_tait_complex_fail {
 mod constrain_fail0 {
     use super::*;
     type Opq0<'a, 'b> = impl Sized;
+    #[define_opaque(Opq0)]
     fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {}
-    //~^ ERROR non-defining opaque type use in defining scope
-    //~| ERROR: expected generic lifetime parameter, found `'a`
+    //~^ ERROR: expected generic lifetime parameter, found `'a`
 }
 
 // non-defining use because generic lifetime is used multiple times.
 mod constrain_fail {
     use super::*;
     type Opq0<'a, 'b> = impl Sized;
+    #[define_opaque(Opq0)]
     fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {}
-    //~^ ERROR non-defining opaque type use in defining scope
-    //~| ERROR: expected generic lifetime parameter, found `'a`
+    //~^ ERROR: expected generic lifetime parameter, found `'a`
 }
 
 mod constrain_pass {
@@ -73,6 +77,7 @@ mod constrain_pass {
     type Opq0<'a, 'b> = impl Sized;
     type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>;
     type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
+    #[define_opaque(Opq2)]
     fn test() -> Opq2 {}
     //~^ ERROR: expected generic lifetime parameter, found `'a`
 }
diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr
index fb1e4cca3f4..3614fc8f45c 100644
--- a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr
+++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr
@@ -1,13 +1,14 @@
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/higher-ranked-regions-basic.rs:15:55
+  --> $DIR/higher-ranked-regions-basic.rs:16:55
    |
 LL |     type Opq<'a> = impl Sized + 'a;
    |              -- this generic parameter must be used with a generic lifetime parameter
+LL |     #[define_opaque(Opq)]
 LL |     fn test() -> impl for<'a> Trait<'a, Ty = Opq<'a>> {}
    |                                                       ^^
 
 error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
-  --> $DIR/higher-ranked-regions-basic.rs:21:58
+  --> $DIR/higher-ranked-regions-basic.rs:22:58
    |
 LL |     fn test() -> impl for<'a> Trait<'a, Ty = impl Sized> {}
    |                           --                 ----------  ^^
@@ -16,86 +17,64 @@ LL |     fn test() -> impl for<'a> Trait<'a, Ty = impl Sized> {}
    |                           hidden type `&'a ()` captures the lifetime `'a` as defined here
 
 error[E0700]: hidden type for `capture_tait::Opq0` captures lifetime that does not appear in bounds
-  --> $DIR/higher-ranked-regions-basic.rs:30:23
+  --> $DIR/higher-ranked-regions-basic.rs:32:23
    |
 LL |     type Opq0 = impl Sized;
    |                 ---------- opaque type defined here
 LL |     type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0>;
    |                              -- hidden type `&'b ()` captures the lifetime `'b` as defined here
-LL |     type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
+...
 LL |     fn test() -> Opq2 {}
    |                       ^^
 
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/higher-ranked-regions-basic.rs:39:23
+  --> $DIR/higher-ranked-regions-basic.rs:42:23
    |
 LL |     type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b
    |               -- this generic parameter must be used with a generic lifetime parameter
-LL |     type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
+...
 LL |     fn test() -> Opq2 {}
    |                       ^^
 
 error[E0700]: hidden type for `capture_tait_complex_fail::Opq0<'a>` captures lifetime that does not appear in bounds
-  --> $DIR/higher-ranked-regions-basic.rs:49:23
+  --> $DIR/higher-ranked-regions-basic.rs:53:23
    |
 LL |     type Opq0<'a> = impl Sized;
    |                     ---------- opaque type defined here
 LL |     type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a>>; // <- Note 'a
    |                              -- hidden type `&'b ()` captures the lifetime `'b` as defined here
-LL |     type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
+...
 LL |     fn test() -> Opq2 {}
    |                       ^^
 
-error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/higher-ranked-regions-basic.rs:57:41
-   |
-LL |     fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {}
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^ argument `'static` is not a generic parameter
-   |
-note: for this opaque type
-  --> $DIR/higher-ranked-regions-basic.rs:56:25
-   |
-LL |     type Opq0<'a, 'b> = impl Sized;
-   |                         ^^^^^^^^^^
-
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/higher-ranked-regions-basic.rs:57:65
+  --> $DIR/higher-ranked-regions-basic.rs:62:65
    |
 LL |     type Opq0<'a, 'b> = impl Sized;
    |               -- this generic parameter must be used with a generic lifetime parameter
+LL |     #[define_opaque(Opq0)]
 LL |     fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {}
    |                                                                 ^^
 
-error: non-defining opaque type use in defining scope
-  --> $DIR/higher-ranked-regions-basic.rs:66:41
-   |
-LL |     fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {}
-   |                                         ^^^^^^^^^^^^^^^^^ generic argument `'a` used twice
-   |
-note: for this opaque type
-  --> $DIR/higher-ranked-regions-basic.rs:65:25
-   |
-LL |     type Opq0<'a, 'b> = impl Sized;
-   |                         ^^^^^^^^^^
-
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/higher-ranked-regions-basic.rs:66:60
+  --> $DIR/higher-ranked-regions-basic.rs:71:60
    |
 LL |     type Opq0<'a, 'b> = impl Sized;
    |               -- this generic parameter must be used with a generic lifetime parameter
+LL |     #[define_opaque(Opq0)]
 LL |     fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {}
    |                                                            ^^
 
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/higher-ranked-regions-basic.rs:76:23
+  --> $DIR/higher-ranked-regions-basic.rs:81:23
    |
 LL |     type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>;
    |               -- this generic parameter must be used with a generic lifetime parameter
-LL |     type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>;
+...
 LL |     fn test() -> Opq2 {}
    |                       ^^
 
-error: aborting due to 10 previous errors
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0700, E0792.
 For more information about an error, try `rustc --explain E0700`.
diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs
index db5e5e05e54..e0b7909c240 100644
--- a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs
+++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs
@@ -14,7 +14,10 @@ impl Trait for Struct {
     type Assoc<'a> = &'a u32;
 }
 
-const FOO: Foo = Struct;
-//~^ ERROR: expected generic lifetime parameter, found `'a`
+#[define_opaque(Foo)]
+fn foo() -> Foo {
+    Struct
+    //~^ ERROR: expected generic lifetime parameter, found `'a`
+}
 
 fn main() {}
diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr
index 9b361445f1e..b3edc942732 100644
--- a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr
+++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr
@@ -1,11 +1,11 @@
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/higher-ranked-regions-gat.rs:17:18
+  --> $DIR/higher-ranked-regions-gat.rs:19:5
    |
 LL | pub type FooAssoc<'a> = impl Sized;
    |                   -- this generic parameter must be used with a generic lifetime parameter
 ...
-LL | const FOO: Foo = Struct;
-   |                  ^^^^^^
+LL |     Struct
+   |     ^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/self/arbitrary-self-opaque.rs b/tests/ui/self/arbitrary-self-opaque.rs
index c26ef658b69..b176a982e5f 100644
--- a/tests/ui/self/arbitrary-self-opaque.rs
+++ b/tests/ui/self/arbitrary-self-opaque.rs
@@ -4,6 +4,7 @@ struct Foo;
 type Bar = impl Sized;
 
 impl Foo {
+    #[define_opaque(Bar)]
     fn foo(self: Bar) {}
     //~^ ERROR: invalid `self` parameter type: `Bar`
     //~| ERROR: item does not constrain
diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr
index c75165d9f8e..36ae3d6fd02 100644
--- a/tests/ui/self/arbitrary-self-opaque.stderr
+++ b/tests/ui/self/arbitrary-self-opaque.stderr
@@ -1,5 +1,5 @@
 error[E0307]: invalid `self` parameter type: `Bar`
-  --> $DIR/arbitrary-self-opaque.rs:7:18
+  --> $DIR/arbitrary-self-opaque.rs:8:18
    |
 LL |     fn foo(self: Bar) {}
    |                  ^^^
@@ -7,14 +7,14 @@ LL |     fn foo(self: Bar) {}
    = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
-  --> $DIR/arbitrary-self-opaque.rs:7:8
+error: item does not constrain `Bar::{opaque#0}`
+  --> $DIR/arbitrary-self-opaque.rs:8:8
    |
 LL |     fn foo(self: Bar) {}
    |        ^^^
    |
-   = 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/arbitrary-self-opaque.rs:4:12
    |
 LL | type Bar = impl Sized;
diff --git a/tests/ui/specialization/min_specialization/impl-on-opaque.rs b/tests/ui/specialization/min_specialization/impl-on-opaque.rs
index 7531dcaccf2..131ad8b9d65 100644
--- a/tests/ui/specialization/min_specialization/impl-on-opaque.rs
+++ b/tests/ui/specialization/min_specialization/impl-on-opaque.rs
@@ -26,6 +26,7 @@ impl SpecTrait<u32> for () {
     fn f() {}
 }
 
+#[define_opaque(Opaque)]
 fn foo() -> Opaque {}
 
 fn main() {}
diff --git a/tests/ui/specialization/min_specialization/impl-on-opaque2.rs b/tests/ui/specialization/min_specialization/impl-on-opaque2.rs
index 0cd8be84ed3..bcdb54c2b4f 100644
--- a/tests/ui/specialization/min_specialization/impl-on-opaque2.rs
+++ b/tests/ui/specialization/min_specialization/impl-on-opaque2.rs
@@ -23,6 +23,7 @@ impl SpecTrait<(), Opaque> for () {
     fn f() {}
 }
 
+#[define_opaque(Opaque)]
 fn foo() -> Opaque {}
 
 fn main() {}
diff --git a/tests/ui/traits/alias/issue-83613.rs b/tests/ui/traits/alias/issue-83613.rs
index 6f0012bf089..752c4b84546 100644
--- a/tests/ui/traits/alias/issue-83613.rs
+++ b/tests/ui/traits/alias/issue-83613.rs
@@ -2,6 +2,7 @@
 trait OpaqueTrait {}
 impl<T> OpaqueTrait for T {}
 type OpaqueType = impl OpaqueTrait;
+#[define_opaque(OpaqueType)]
 fn mk_opaque() -> OpaqueType {
     || 0
 }
diff --git a/tests/ui/traits/alias/issue-83613.stderr b/tests/ui/traits/alias/issue-83613.stderr
index 47181c3f33e..7d2bdd7e186 100644
--- a/tests/ui/traits/alias/issue-83613.stderr
+++ b/tests/ui/traits/alias/issue-83613.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `AnotherTrait`
-  --> $DIR/issue-83613.rs:10:1
+  --> $DIR/issue-83613.rs:11:1
    |
 LL | impl<T: Send> AnotherTrait for T {}
    | -------------------------------- first implementation here
diff --git a/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs
index cb9fe176ac9..92a0913dee2 100644
--- a/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs
+++ b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs
@@ -12,7 +12,8 @@ fn mk<T>() -> T {
     todo!()
 }
 
-fn a(_: Tait) {
+#[define_opaque(Tait)]
+fn a() {
     let x: Tait = mk();
     let mut array = mk();
     let mut z = IntoIterator::into_iter(array);
diff --git a/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs
index 8d92c88ae72..0e99ef87c89 100644
--- a/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs
+++ b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs
@@ -28,7 +28,8 @@ goals together. Essentially:
 
 */
 
-fn a(_: Tait) {
+#[define_opaque(Tait)]
+fn a() {
     let _: Tait = IntoIterator::into_iter([0i32; 32]);
 }
 
diff --git a/tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs b/tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs
index 904bc179495..38fcc561b32 100644
--- a/tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs
+++ b/tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs
@@ -12,7 +12,8 @@ type Foo<T: Send, U> = impl NeedsSend<T>;
 trait NeedsSend<T> {}
 impl<T: Send> NeedsSend<T> for T {}
 
-fn define<A, B: Send>(a: A, b: B, _: Foo<B, A>) {
+#[define_opaque(Foo)]
+fn define<A, B: Send>(a: A, b: B) {
     let y: Option<Foo<B, A>> = Some(b);
 }
 
diff --git a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr
index 158fefd1538..736c8c10da9 100644
--- a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr
+++ b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.is_send.stderr
@@ -1,5 +1,5 @@
 error[E0284]: type annotations needed: cannot satisfy `Foo == _`
-  --> $DIR/dont-type_of-tait-in-defining-scope.rs:15:18
+  --> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18
    |
 LL |     needs_send::<Foo>();
    |                  ^^^ cannot satisfy `Foo == _`
diff --git a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr
index 158fefd1538..736c8c10da9 100644
--- a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr
+++ b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.not_send.stderr
@@ -1,5 +1,5 @@
 error[E0284]: type annotations needed: cannot satisfy `Foo == _`
-  --> $DIR/dont-type_of-tait-in-defining-scope.rs:15:18
+  --> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18
    |
 LL |     needs_send::<Foo>();
    |                  ^^^ cannot satisfy `Foo == _`
diff --git a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs
index 10b746cc989..2a08a3b2b94 100644
--- a/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs
+++ b/tests/ui/traits/next-solver/opaques/dont-type_of-tait-in-defining-scope.rs
@@ -11,12 +11,14 @@ type Foo = impl Sized;
 
 fn needs_send<T: Send>() {}
 
+#[define_opaque(Foo)]
 fn test(_: Foo) {
     needs_send::<Foo>();
     //~^ ERROR type annotations needed: cannot satisfy `Foo == _`
 }
 
-fn defines(_: Foo) {
+#[define_opaque(Foo)]
+fn defines() {
     let _: Foo = ();
 }
 
diff --git a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr
index 9a28dc093c1..5625cb24d42 100644
--- a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr
+++ b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.current.stderr
@@ -4,31 +4,31 @@ error: unconstrained opaque type
 LL |     type Tait1 = impl Sized;
    |                  ^^^^^^^^^^
    |
-   = note: `Tait1` must be used in combination with a concrete type within the same module
+   = note: `Tait1` must be used in combination with a concrete type within the same crate
 
 error: unconstrained opaque type
-  --> $DIR/no-define-in-wf-check.rs:27:18
+  --> $DIR/no-define-in-wf-check.rs:28:18
    |
 LL |     type Tait1 = impl Sized;
    |                  ^^^^^^^^^^
    |
-   = note: `Tait1` must be used in combination with a concrete type within the same module
+   = note: `Tait1` must be used in combination with a concrete type within the same crate
 
 error: unconstrained opaque type
-  --> $DIR/no-define-in-wf-check.rs:36:18
+  --> $DIR/no-define-in-wf-check.rs:38:18
    |
 LL |     type Tait1 = impl Sized;
    |                  ^^^^^^^^^^
    |
-   = note: `Tait1` must be used in combination with a concrete type within the same module
+   = note: `Tait1` must be used in combination with a concrete type within the same crate
 
 error: unconstrained opaque type
-  --> $DIR/no-define-in-wf-check.rs:47:18
+  --> $DIR/no-define-in-wf-check.rs:50:18
    |
 LL |     type Tait1 = impl Sized;
    |                  ^^^^^^^^^^
    |
-   = note: `Tait1` must be used in combination with a concrete type within the same module
+   = note: `Tait1` 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/traits/next-solver/opaques/no-define-in-wf-check.rs b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs
index dd6df097da1..31d07d89d8d 100644
--- a/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs
+++ b/tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs
@@ -18,6 +18,7 @@ mod ex0 {
 mod ex1 {
     type Tait1 = impl Sized;
     //[current]~^ ERROR unconstrained opaque type
+    #[define_opaque(Tait1)]
     fn foo(x: Tait1) -> impl Sized {
         let () = x;
     }
@@ -27,6 +28,7 @@ mod ex2 {
     type Tait1 = impl Sized;
     //[current]~^ ERROR unconstrained opaque type
     type Tait2 = impl Sized;
+    #[define_opaque(Tait1, Tait2)]
     fn foo(x: Tait1) -> Tait2 {
         let () = x;
     }
@@ -38,6 +40,7 @@ mod ex3 {
     trait Something<T> {}
     impl<T, U> Something<U> for T {}
     type Tait2 = impl Something<Tait1>;
+    #[define_opaque(Tait1, Tait2)]
     fn foo(x: Tait1) -> Tait2 {
         let () = x;
     }
@@ -58,6 +61,7 @@ mod ex4 {
     //
     // ambiguity proving `(): Trait<Tait1>`.
     type Tait2 = impl Trait<(), Assoc = impl Trait<Tait1>>;
+    #[define_opaque(Tait1, Tait2)]
     fn foo(x: Tait1) -> Tait2 {
         let () = x;
     }
diff --git a/tests/ui/traits/pointee-tail-is-generic-errors.rs b/tests/ui/traits/pointee-tail-is-generic-errors.rs
index 92a83f40b18..8ddac5b2f39 100644
--- a/tests/ui/traits/pointee-tail-is-generic-errors.rs
+++ b/tests/ui/traits/pointee-tail-is-generic-errors.rs
@@ -5,6 +5,7 @@
 
 type Opaque = impl std::fmt::Debug + ?Sized;
 
+#[define_opaque(Opaque)]
 fn opaque() -> &'static Opaque {
     &[1] as &[i32]
 }
diff --git a/tests/ui/traits/pointee-tail-is-generic-errors.stderr b/tests/ui/traits/pointee-tail-is-generic-errors.stderr
index 0c3d7060dd7..907f07026a4 100644
--- a/tests/ui/traits/pointee-tail-is-generic-errors.stderr
+++ b/tests/ui/traits/pointee-tail-is-generic-errors.stderr
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `<T as Pointee>::Metadata == ()`
-  --> $DIR/pointee-tail-is-generic-errors.rs:13:15
+  --> $DIR/pointee-tail-is-generic-errors.rs:14:15
    |
 LL |     is_thin::<T>();
    |               ^ expected `()`, found associated type
@@ -9,13 +9,13 @@ LL |     is_thin::<T>();
    = help: consider constraining the associated type `<T as Pointee>::Metadata` to `()`
    = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 note: required by a bound in `is_thin`
-  --> $DIR/pointee-tail-is-generic-errors.rs:20:33
+  --> $DIR/pointee-tail-is-generic-errors.rs:21:33
    |
 LL | fn is_thin<T: std::ptr::Pointee<Metadata = ()> + ?Sized>() {}
    |                                 ^^^^^^^^^^^^^ required by this bound in `is_thin`
 
 error[E0271]: type mismatch resolving `<Opaque as Pointee>::Metadata == ()`
-  --> $DIR/pointee-tail-is-generic-errors.rs:16:15
+  --> $DIR/pointee-tail-is-generic-errors.rs:17:15
    |
 LL | type Opaque = impl std::fmt::Debug + ?Sized;
    |               ----------------------------- the found opaque type
@@ -26,7 +26,7 @@ LL |     is_thin::<Opaque>();
    = note:    expected unit type `()`
            found associated type `<Opaque as Pointee>::Metadata`
 note: required by a bound in `is_thin`
-  --> $DIR/pointee-tail-is-generic-errors.rs:20:33
+  --> $DIR/pointee-tail-is-generic-errors.rs:21:33
    |
 LL | fn is_thin<T: std::ptr::Pointee<Metadata = ()> + ?Sized>() {}
    |                                 ^^^^^^^^^^^^^ required by this bound in `is_thin`
diff --git a/tests/ui/traits/pointee-tail-is-generic.rs b/tests/ui/traits/pointee-tail-is-generic.rs
index 14bdf0880c7..b41fb61e4a4 100644
--- a/tests/ui/traits/pointee-tail-is-generic.rs
+++ b/tests/ui/traits/pointee-tail-is-generic.rs
@@ -4,12 +4,11 @@
 #![feature(ptr_metadata)]
 #![feature(type_alias_impl_trait)]
 
-mod opaque {
-    pub type Opaque = impl std::future::Future;
+pub type Opaque = impl std::future::Future;
 
-    fn opaque() -> Opaque {
-        async {}
-    }
+#[define_opaque(Opaque)]
+fn opaque() -> Opaque {
+    async {}
 }
 
 fn a<T>() {
@@ -18,7 +17,7 @@ fn a<T>() {
     // tail of ADT (which is a type param) is known to be sized
     is_thin::<std::cell::Cell<T>>();
     // opaque type is known to be sized
-    is_thin::<opaque::Opaque>();
+    is_thin::<Opaque>();
 }
 
 fn a2<T: Iterator>() {
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs
index ab3817da28b..ed852ef986a 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs
@@ -15,6 +15,7 @@ fn test_correct2<'a>(x: &dyn Foo<'a>) {
     let _ = x as &dyn Bar<'_, '_, Tait>;
 }
 
+#[define_opaque(Tait)]
 fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) {
     let _ = x as &dyn Bar<'_, '_, ()>;
 }
diff --git a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs
index 0548eda0468..3e36ce0dc72 100644
--- a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs
+++ b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs
@@ -17,6 +17,7 @@ impl<T: ?Sized> Super for T {
 
 type Foo = impl Sized;
 
+#[define_opaque(Foo)]
 fn upcast(x: &dyn Sub<Assoc = Foo>) -> &dyn Super<Assoc = i32> {
     x
 }
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr
index cdf9deecd51..7f51d1519db 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr
+++ b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr
@@ -19,7 +19,7 @@ error: unconstrained opaque type
 LL | type OpaqueType = impl OpaqueTrait;
    |                   ^^^^^^^^^^^^^^^^
    |
-   = note: `OpaqueType` must be used in combination with a concrete type within the same module
+   = note: `OpaqueType` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/argument-types.rs b/tests/ui/type-alias-impl-trait/argument-types.rs
index 7382d4c78c7..ea87bcb3e45 100644
--- a/tests/ui/type-alias-impl-trait/argument-types.rs
+++ b/tests/ui/type-alias-impl-trait/argument-types.rs
@@ -2,20 +2,19 @@
 #![allow(dead_code)]
 //@ check-pass
 
-mod foo {
-    use std::fmt::Debug;
+use std::fmt::Debug;
 
-    pub type Foo = impl Debug;
+pub type Foo = impl Debug;
 
-    fn foo1(mut x: Foo) {
-        x = 22_u32;
-    }
+#[define_opaque(Foo)]
+fn foo1(mut x: Foo) {
+    x = 22_u32;
+}
 
-    pub fn foo_value() -> Foo {
-        11_u32
-    }
+#[define_opaque(Foo)]
+pub fn foo_value() -> Foo {
+    11_u32
 }
-use foo::*;
 
 fn foo2(mut x: Foo) {
     // no constraint on x
diff --git a/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs b/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
index 9dcbc75db3f..97c1c1b64cc 100644
--- a/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
+++ b/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
@@ -2,23 +2,21 @@
 
 //@ build-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/type-alias-impl-trait/associated-type-alias-impl-trait.rs b/tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs
index a1185cd5ba8..6761835be89 100644
--- a/tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs
+++ b/tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs
@@ -15,9 +15,11 @@ type Helper = impl Bar;
 
 impl Foo for i32 {
     type Assoc = Helper;
+    #[define_opaque(Helper)]
     fn foo() -> Helper {
         Dummy
     }
+    #[define_opaque(Helper)]
     fn bar() -> Helper {
         Dummy
     }
diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs
index a03a146d041..cf385223ce4 100644
--- a/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs
+++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs
@@ -3,16 +3,15 @@
 #![feature(type_alias_impl_trait)]
 #![allow(dead_code)]
 
-mod m {
-    pub(crate) type Foo = impl std::fmt::Debug;
+pub(crate) type Foo = impl std::fmt::Debug;
 
-    pub(crate) fn foo() -> Foo {
-        22_u32
-    }
+#[define_opaque(Foo)]
+pub(crate) fn foo() -> Foo {
+    22_u32
 }
 
 fn is_send<T: Send>(_: T) {}
 
 fn main() {
-    is_send(m::foo());
+    is_send(foo());
 }
diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs
index fc89b0e870e..6132eef0db5 100644
--- a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs
+++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs
@@ -1,16 +1,15 @@
 #![feature(type_alias_impl_trait)]
 #![allow(dead_code)]
 
-mod m {
-    use std::rc::Rc;
+use std::rc::Rc;
 
-    type Foo = impl std::fmt::Debug; //~ NOTE appears within the type
-    //~^ within this `Foo`
-    //~| expansion of desugaring
+type Foo = impl std::fmt::Debug; //~ NOTE appears within the type
+//~^ within this `Foo`
+//~| expansion of desugaring
 
-    pub fn foo() -> Foo {
-        Rc::new(22_u32)
-    }
+#[define_opaque(Foo)]
+pub fn foo() -> Foo {
+    Rc::new(22_u32)
 }
 
 fn is_send<T: Send>(_: T) {}
@@ -18,7 +17,7 @@ fn is_send<T: Send>(_: T) {}
 //~| required by a bound
 
 fn main() {
-    is_send(m::foo());
+    is_send(foo());
     //~^ ERROR: `Rc<u32>` cannot be sent between threads safely [E0277]
     //~| NOTE cannot be sent
     //~| NOTE required by a bound
diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
index 2ed918eca17..d2db468b519 100644
--- a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
+++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
@@ -1,22 +1,22 @@
 error[E0277]: `Rc<u32>` cannot be sent between threads safely
-  --> $DIR/auto-trait-leakage2.rs:21:13
+  --> $DIR/auto-trait-leakage2.rs:20:13
    |
-LL |     type Foo = impl std::fmt::Debug;
-   |                -------------------- within this `Foo`
+LL | type Foo = impl std::fmt::Debug;
+   |            -------------------- within this `Foo`
 ...
-LL |     is_send(m::foo());
-   |     ------- ^^^^^^^^ `Rc<u32>` cannot be sent between threads safely
+LL |     is_send(foo());
+   |     ------- ^^^^^ `Rc<u32>` cannot be sent between threads safely
    |     |
    |     required by a bound introduced by this call
    |
    = help: within `Foo`, the trait `Send` is not implemented for `Rc<u32>`
 note: required because it appears within the type `Foo`
-  --> $DIR/auto-trait-leakage2.rs:7:16
+  --> $DIR/auto-trait-leakage2.rs:6:12
    |
-LL |     type Foo = impl std::fmt::Debug;
-   |                ^^^^^^^^^^^^^^^^^^^^
+LL | type Foo = impl std::fmt::Debug;
+   |            ^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `is_send`
-  --> $DIR/auto-trait-leakage2.rs:16:15
+  --> $DIR/auto-trait-leakage2.rs:15:15
    |
 LL | fn is_send<T: Send>(_: T) {}
    |               ^^^^ required by this bound in `is_send`
diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs
index cad75cffe05..3e0bd3b6521 100644
--- a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs
+++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs
@@ -1,17 +1,17 @@
 #![feature(type_alias_impl_trait)]
 #![allow(dead_code)]
 
-// FIXME This should compile, but it currently doesn't
+//@ check-pass
 
 mod m {
     pub type Foo = impl std::fmt::Debug;
+    #[define_opaque(Foo)]
     pub fn foo() -> Foo {
         22_u32
     }
 
     pub fn bar() {
         is_send(foo());
-        //~^ ERROR: cannot check whether the hidden type of `auto_trait_leakage3[211d]::m::Foo::{opaque#0}
     }
 
     fn is_send<T: Send>(_: T) {}
diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr
deleted file mode 100644
index 6bdc76aab45..00000000000
--- a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error: cannot check whether the hidden type of `auto_trait_leakage3[211d]::m::Foo::{opaque#0}` satisfies auto traits
-  --> $DIR/auto-trait-leakage3.rs:13:17
-   |
-LL |         is_send(foo());
-   |         ------- ^^^^^
-   |         |
-   |         required by a bound introduced by this call
-   |
-   = note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
-note: opaque type is declared here
-  --> $DIR/auto-trait-leakage3.rs:7:20
-   |
-LL |     pub type Foo = impl std::fmt::Debug;
-   |                    ^^^^^^^^^^^^^^^^^^^^
-note: required by a bound in `is_send`
-  --> $DIR/auto-trait-leakage3.rs:17:19
-   |
-LL |     fn is_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `is_send`
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs b/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs
index e7bca2231de..c60fd0b6798 100644
--- a/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs
+++ b/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs
@@ -5,6 +5,7 @@
 
 pub type Foo = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 pub fn foo() -> Foo {
     5
 }
diff --git a/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs b/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs
index 54a22510066..3c823d3e5d2 100644
--- a/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs
+++ b/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs
@@ -3,6 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 type Tait = impl Sized;
+#[define_opaque(Tait)]
 fn _constrain() -> Tait {}
 
 struct WrapperWithDrop<T>(T);
diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs
index 4b2ee344aa3..b6870b16450 100644
--- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs
+++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs
@@ -8,9 +8,9 @@ pub enum UninhabitedVariants {
     Tuple(Alias),
     //~^ ERROR missing lifetime specifier
     //~| ERROR missing generics
-    //~| ERROR non-defining opaque type use in defining scope
 }
 
+#[define_opaque(Alias)]
 fn uwu(x: UninhabitedVariants) {
     //~^ ERROR item does not constrain
     match x {}
diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr
index 38fbff9d59d..59909197e7b 100644
--- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr
+++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr
@@ -26,26 +26,14 @@ help: add missing generic argument
 LL |     Tuple(Alias<U>),
    |                +++
 
-error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/bad-tait-no-substs.rs:8:11
-   |
-LL |     Tuple(Alias),
-   |           ^^^^^ argument `'_` is not a generic parameter
-   |
-note: for this opaque type
-  --> $DIR/bad-tait-no-substs.rs:5:21
-   |
-LL | type Alias<'a, U> = impl Trait<U>;
-   |                     ^^^^^^^^^^^^^
-
-error: item does not constrain `Alias::{opaque#0}`, but has it in its signature
+error: item does not constrain `Alias::{opaque#0}`
   --> $DIR/bad-tait-no-substs.rs:14:4
    |
 LL | fn uwu(x: UninhabitedVariants) {
    |    ^^^
    |
-   = 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/bad-tait-no-substs.rs:5:21
    |
 LL | type Alias<'a, U> = impl Trait<U>;
@@ -72,7 +60,7 @@ LL +         UninhabitedVariants::Tuple(_) => todo!(),
 LL ~     }
    |
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0004, E0106, E0107, E0792.
+Some errors have detailed explanations: E0004, E0106, E0107.
 For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs b/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs
index 3b83b2e544b..4dba8d7b230 100644
--- a/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs
+++ b/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs
@@ -11,6 +11,7 @@
 
 type Opaque<'a> = impl Sized + 'a;
 
+#[define_opaque(Opaque)]
 fn test<'a>() -> Opaque<'a> {
     let _: () = test::<'a>();
 }
diff --git a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs
index df589473a84..e714aca812b 100644
--- a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs
+++ b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.rs
@@ -9,7 +9,7 @@ fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
 }
 
 pub fn main() {
-    //~^ ERROR item does not constrain `Opaque::{opaque#0}`, but has it in its signature
+    //~^ ERROR item does not constrain `Opaque::{opaque#0}`
     type Opaque = impl Sized;
     fn define() -> Opaque {
         let x: Opaque = dyn_hoops::<()>();
diff --git a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr
index 59d9ff86c6e..7219fda4772 100644
--- a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr
+++ b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr
@@ -10,14 +10,14 @@ note: lifetime declared here
 LL | fn dyn_hoops<T: Sized>() -> dyn for<'a> Iterator<Item = impl Captures<'a>> {
    |                                     ^^
 
-error: item does not constrain `Opaque::{opaque#0}`, but has it in its signature
+error: item does not constrain `Opaque::{opaque#0}`
   --> $DIR/bound-lifetime-through-dyn-trait.rs:11:8
    |
 LL | pub 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/bound-lifetime-through-dyn-trait.rs:13:19
    |
 LL |     type Opaque = impl Sized;
diff --git a/tests/ui/type-alias-impl-trait/bound_reduction.rs b/tests/ui/type-alias-impl-trait/bound_reduction.rs
index 74012e34e92..5966b5cc815 100644
--- a/tests/ui/type-alias-impl-trait/bound_reduction.rs
+++ b/tests/ui/type-alias-impl-trait/bound_reduction.rs
@@ -10,6 +10,7 @@ type Foo<V> = impl std::fmt::Debug;
 
 trait Trait<U> {}
 
+#[define_opaque(Foo)]
 fn foo_desugared<T: Trait<[u32; {
     #[no_mangle]
     static FOO: usize = 42;
diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.rs b/tests/ui/type-alias-impl-trait/bound_reduction2.rs
index 4e9f65d88a1..78288caffef 100644
--- a/tests/ui/type-alias-impl-trait/bound_reduction2.rs
+++ b/tests/ui/type-alias-impl-trait/bound_reduction2.rs
@@ -12,8 +12,8 @@ trait Trait<U> {}
 
 impl<W> Trait<W> for () {}
 
+#[define_opaque(Foo)]
 fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-    //~^ ERROR non-defining opaque type use
     ()
     //~^ ERROR expected generic type parameter, found `<T as TraitWithAssoc>::Assoc`
 }
diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr
index 14f9dbbdb4e..289826cc1d0 100644
--- a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr
+++ b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr
@@ -1,15 +1,3 @@
-error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/bound_reduction2.rs:15:46
-   |
-LL | fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-   |                                              ^^^^^^^^^^^^^ argument `<T as TraitWithAssoc>::Assoc` is not a generic parameter
-   |
-note: for this opaque type
-  --> $DIR/bound_reduction2.rs:9:15
-   |
-LL | type Foo<V> = impl Trait<V>;
-   |               ^^^^^^^^^^^^^
-
 error[E0792]: expected generic type parameter, found `<T as TraitWithAssoc>::Assoc`
   --> $DIR/bound_reduction2.rs:17:5
    |
@@ -19,6 +7,6 @@ LL | type Foo<V> = impl Trait<V>;
 LL |     ()
    |     ^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs
index 45f54266014..4151a6a5f12 100644
--- a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs
+++ b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs
@@ -3,15 +3,13 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod foo {
-    pub type X<T> = impl Clone;
+pub type X<T> = impl Clone;
 
-    fn f<T: Clone>(t: T) -> X<T> {
-        t
-        //~^ ERROR the trait bound `T: Clone` is not satisfied
-    }
+#[define_opaque(X)]
+fn f<T: Clone>(t: T) -> X<T> {
+    t
+    //~^ ERROR the trait bound `T: Clone` is not satisfied
 }
-use foo::X;
 
 fn g<T>(o: Option<X<T>>) -> Option<X<T>> {
     o.clone()
diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr
index bbb32b2d604..21166631c3e 100644
--- a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr
+++ b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr
@@ -1,23 +1,23 @@
 error[E0277]: the trait bound `T: Clone` is not satisfied
-  --> $DIR/bounds-are-checked-2.rs:10:9
+  --> $DIR/bounds-are-checked-2.rs:10:5
    |
-LL |         t
-   |         ^ the trait `Clone` is not implemented for `T`
+LL |     t
+   |     ^ the trait `Clone` is not implemented for `T`
    |
 note: required by a bound in an opaque type
-  --> $DIR/bounds-are-checked-2.rs:7:26
+  --> $DIR/bounds-are-checked-2.rs:6:22
    |
-LL |     pub type X<T> = impl Clone;
-   |                          ^^^^^
+LL | pub type X<T> = impl Clone;
+   |                      ^^^^^
 note: this definition site has more where clauses than the opaque type
-  --> $DIR/bounds-are-checked-2.rs:9:5
+  --> $DIR/bounds-are-checked-2.rs:9:1
    |
-LL |     fn f<T: Clone>(t: T) -> X<T> {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn f<T: Clone>(t: T) -> X<T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider restricting type parameter `T` with trait `Clone`
    |
-LL |     pub type X<T: std::clone::Clone> = impl Clone;
-   |                 +++++++++++++++++++
+LL | pub type X<T: std::clone::Clone> = impl Clone;
+   |             +++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked.rs
index 7c3a3a84406..3d295358728 100644
--- a/tests/ui/type-alias-impl-trait/bounds-are-checked.rs
+++ b/tests/ui/type-alias-impl-trait/bounds-are-checked.rs
@@ -5,6 +5,7 @@
 
 type X<'a> = impl Into<&'static str> + From<&'a str>;
 
+#[define_opaque(X)]
 fn f<'a: 'static>(t: &'a str) -> X<'a> {
     t
     //~^ ERROR expected generic lifetime parameter, found `'static`
diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr b/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr
index ad1b9f19d8e..7617268dd8e 100644
--- a/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr
+++ b/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'static`
-  --> $DIR/bounds-are-checked.rs:9:5
+  --> $DIR/bounds-are-checked.rs:10:5
    |
 LL | type X<'a> = impl Into<&'static str> + From<&'a str>;
    |        -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs
index 5a9e87c0919..a8524770a85 100644
--- a/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs
+++ b/tests/ui/type-alias-impl-trait/bounds-are-checked3.rs
@@ -9,6 +9,7 @@ struct Struct<V: Display>(Option<V>);
 type Foo<T: Debug> = (impl Debug, Struct<T>);
 //~^ ERROR: `T` doesn't implement `std::fmt::Display`
 
+#[define_opaque(Foo)]
 fn foo<U: Debug + Display>() -> Foo<U> {
     (Vec::<U>::new(), Struct(None))
 }
diff --git a/tests/ui/type-alias-impl-trait/bounds.rs b/tests/ui/type-alias-impl-trait/bounds.rs
index 8e24a937d1d..c131d52a4ba 100644
--- a/tests/ui/type-alias-impl-trait/bounds.rs
+++ b/tests/ui/type-alias-impl-trait/bounds.rs
@@ -9,6 +9,7 @@ use std::fmt::Debug;
 // type alias bounds.
 type Foo<T: Debug> = (impl Debug, usize);
 
+#[define_opaque(Foo)]
 fn foo<U: Debug>() -> Foo<U> {
     (Vec::<U>::new(), 1234)
 }
diff --git a/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs b/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs
index 0dfa1f40ae6..7fd8fa6f9db 100644
--- a/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs
+++ b/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs
@@ -6,14 +6,12 @@
 
 use std::marker::PhantomData;
 
-mod foo {
-    pub type WithEmplacableForFn<'a> = impl super::EmplacableFn + 'a;
+type WithEmplacableForFn<'a> = impl EmplacableFn + 'a;
 
-    fn _constrain(_: &mut ()) -> WithEmplacableForFn<'_> {
-        ()
-    }
+#[define_opaque(WithEmplacableForFn)]
+fn _constrain(_: &mut ()) -> WithEmplacableForFn<'_> {
+    ()
 }
-use foo::*;
 
 fn with_emplacable_for<'a, F, R>(mut f: F) -> R
 where
diff --git a/tests/ui/type-alias-impl-trait/closure_args.rs b/tests/ui/type-alias-impl-trait/closure_args.rs
index 0141a01aad0..8a518c19dba 100644
--- a/tests/ui/type-alias-impl-trait/closure_args.rs
+++ b/tests/ui/type-alias-impl-trait/closure_args.rs
@@ -4,21 +4,19 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod foo {
-    pub trait Anything {}
-    impl<T> Anything for T {}
-    pub type Input = impl Anything;
+pub trait Anything {}
+impl<T> Anything for T {}
+pub type Input = impl Anything;
 
-    fn bop(_: Input) {
-        super::run(
-            |x: u32| {
-                println!("{x}");
-            },
-            0,
-        );
-    }
+#[define_opaque(Input)]
+fn bop(_: Input) {
+    run(
+        |x: u32| {
+            println!("{x}");
+        },
+        0,
+    );
 }
-use foo::Input;
 
 fn run<F: FnOnce(Input) -> ()>(f: F, i: Input) {
     f(i);
diff --git a/tests/ui/type-alias-impl-trait/closure_args2.rs b/tests/ui/type-alias-impl-trait/closure_args2.rs
index 13ac3d31d83..257c5f86633 100644
--- a/tests/ui/type-alias-impl-trait/closure_args2.rs
+++ b/tests/ui/type-alias-impl-trait/closure_args2.rs
@@ -2,27 +2,25 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod foo {
-    pub trait Foo {
-        // This was reachable in https://github.com/rust-lang/rust/issues/100800
-        fn foo(&self) {
-            unreachable!()
-        }
+pub trait Foo {
+    // This was reachable in https://github.com/rust-lang/rust/issues/100800
+    fn foo(&self) {
+        unreachable!()
     }
-    impl<T> Foo for T {}
+}
+impl<T> Foo for T {}
 
-    pub struct B;
-    impl B {
-        fn foo(&self) {}
-    }
-    pub type Input = impl Foo;
-    fn bop() -> Input {
-        super::run1(|x: B| x.foo(), B);
-        super::run2(|x: B| x.foo(), B);
-        panic!()
-    }
+pub struct B;
+impl B {
+    fn foo(&self) {}
+}
+pub type Input = impl Foo;
+#[define_opaque(Input)]
+fn bop() -> Input {
+    run1(|x: B| x.foo(), B);
+    run2(|x: B| x.foo(), B);
+    panic!()
 }
-use foo::*;
 
 fn run1<F: FnOnce(Input)>(f: F, i: Input) {
     f(i)
diff --git a/tests/ui/type-alias-impl-trait/closure_infer.rs b/tests/ui/type-alias-impl-trait/closure_infer.rs
index fa0514c34a0..2aa19913ad6 100644
--- a/tests/ui/type-alias-impl-trait/closure_infer.rs
+++ b/tests/ui/type-alias-impl-trait/closure_infer.rs
@@ -22,12 +22,14 @@ impl StreamConsumer for DispatchExecutor {
 
 // Functions that constrain TAITs can contain closures with an `_` in the return type.
 type Foo = impl Sized;
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     || -> _ {}
 }
 
 // The `_` in the closure return type can also be the TAIT itself.
 type Bar = impl Sized;
+#[define_opaque(Bar)]
 fn bar() -> impl FnOnce() -> Bar {
     || -> _ {}
 }
diff --git a/tests/ui/type-alias-impl-trait/closure_parent_substs.rs b/tests/ui/type-alias-impl-trait/closure_parent_substs.rs
index e78c7c16c8e..4c99778b66e 100644
--- a/tests/ui/type-alias-impl-trait/closure_parent_substs.rs
+++ b/tests/ui/type-alias-impl-trait/closure_parent_substs.rs
@@ -15,6 +15,7 @@ mod test1 {
     // Hidden type = Closure['?0]
     type Opaque = impl Sized;
 
+    #[define_opaque(Opaque)]
     fn define<'a: 'a>() -> Opaque {
         || {}
     }
@@ -31,6 +32,7 @@ mod test2 {
         &'a (): Trait,
     = impl Sized + 'a;
 
+    #[define_opaque(Opaque)]
     fn define<'a, 'x, 'y>() -> Opaque<'a>
     where
         &'a (): Trait,
@@ -52,6 +54,7 @@ mod test3 {
         (&'a (), &'b ()): Trait,
     = impl Sized + 'a + 'b;
 
+    #[define_opaque(Opaque)]
     fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
     where
         (&'a (), &'b ()): Trait,
diff --git a/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs b/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs
index caa9b6d979a..5316a47bbd4 100644
--- a/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs
+++ b/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs
@@ -13,6 +13,7 @@
 mod test1 {
     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
 
+    #[define_opaque(Opaque)]
     fn define<'a, 'b>() -> Opaque<'a, 'b>
     where
         'a: 'b,
@@ -26,6 +27,7 @@ mod test1 {
 mod test2 {
     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
 
+    #[define_opaque(Opaque)]
     fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
     where
         'a: 'x,
@@ -40,6 +42,7 @@ mod test2 {
 mod test2_fixed {
     type Opaque<'a: 'b, 'b> = impl Sized + 'a + 'b;
 
+    #[define_opaque(Opaque)]
     fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
     where
         'a: 'x,
@@ -53,6 +56,7 @@ mod test2_fixed {
 mod test3 {
     type Opaque<T> = impl Sized;
 
+    #[define_opaque(Opaque)]
     fn define<T>() -> Opaque<T>
     where
         T: 'static,
diff --git a/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr b/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr
index ae00d3fc667..ccba2d37fd0 100644
--- a/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr
+++ b/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr
@@ -1,5 +1,5 @@
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/closure_wf_outlives.rs:20:9
+  --> $DIR/closure_wf_outlives.rs:21:9
    |
 LL |         || {}
    |         ^^^^^
@@ -16,34 +16,34 @@ LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
    |                     ^^
 
 error[E0803]: cannot infer an appropriate lifetime due to conflicting requirements
-  --> $DIR/closure_wf_outlives.rs:34:9
+  --> $DIR/closure_wf_outlives.rs:36:9
    |
 LL |         || {}
    |         ^^^^^
    |
 note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
-  --> $DIR/closure_wf_outlives.rs:27:17
+  --> $DIR/closure_wf_outlives.rs:28:17
    |
 LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
    |                 ^^
 note: ...so that the declared lifetime parameter bounds are satisfied
-  --> $DIR/closure_wf_outlives.rs:34:9
+  --> $DIR/closure_wf_outlives.rs:36:9
    |
 LL |         || {}
    |         ^^^^^
 note: but, the lifetime must be valid for the lifetime `'b` as defined here...
-  --> $DIR/closure_wf_outlives.rs:27:21
+  --> $DIR/closure_wf_outlives.rs:28:21
    |
 LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
    |                     ^^
 note: ...so that the declared lifetime parameter bounds are satisfied
-  --> $DIR/closure_wf_outlives.rs:34:9
+  --> $DIR/closure_wf_outlives.rs:36:9
    |
 LL |         || {}
    |         ^^^^^
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/closure_wf_outlives.rs:60:9
+  --> $DIR/closure_wf_outlives.rs:64:9
    |
 LL |         || {}
    |         ^^^^^
@@ -52,7 +52,7 @@ LL |         || {}
    |         ...so that the type `T` will meet its required lifetime bounds...
    |
 note: ...that is required by this bound
-  --> $DIR/closure_wf_outlives.rs:58:12
+  --> $DIR/closure_wf_outlives.rs:62:12
    |
 LL |         T: 'static,
    |            ^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/closures_in_branches.rs b/tests/ui/type-alias-impl-trait/closures_in_branches.rs
index 7bb490bbec8..d83bf36a444 100644
--- a/tests/ui/type-alias-impl-trait/closures_in_branches.rs
+++ b/tests/ui/type-alias-impl-trait/closures_in_branches.rs
@@ -2,6 +2,7 @@
 
 type Foo = impl std::ops::FnOnce(String) -> usize;
 
+#[define_opaque(Foo)]
 fn foo(b: bool) -> Foo {
     if b {
         |x| x.len() //~ ERROR type annotations needed
@@ -10,8 +11,8 @@ fn foo(b: bool) -> Foo {
     }
 }
 
-
 type Foo1 = impl std::ops::FnOnce(String) -> usize;
+#[define_opaque(Foo1)]
 fn foo1(b: bool) -> Foo1 {
     |x| x.len()
 }
diff --git a/tests/ui/type-alias-impl-trait/closures_in_branches.stderr b/tests/ui/type-alias-impl-trait/closures_in_branches.stderr
index 9cc15f14a99..849ffd214f0 100644
--- a/tests/ui/type-alias-impl-trait/closures_in_branches.stderr
+++ b/tests/ui/type-alias-impl-trait/closures_in_branches.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/closures_in_branches.rs:7:10
+  --> $DIR/closures_in_branches.rs:8:10
    |
 LL |         |x| x.len()
    |          ^  - type must be known at this point
@@ -10,7 +10,7 @@ LL |         |x: /* Type */| x.len()
    |           ++++++++++++
 
 error[E0282]: type annotations needed
-  --> $DIR/closures_in_branches.rs:21:10
+  --> $DIR/closures_in_branches.rs:22:10
    |
 LL |         |x| x.len()
    |          ^  - type must be known at this point
diff --git a/tests/ui/type-alias-impl-trait/coherence.classic.stderr b/tests/ui/type-alias-impl-trait/coherence.classic.stderr
index 98badeef382..e99d4636b13 100644
--- a/tests/ui/type-alias-impl-trait/coherence.classic.stderr
+++ b/tests/ui/type-alias-impl-trait/coherence.classic.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence.rs:16:1
+  --> $DIR/coherence.rs:17:1
    |
 LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------
diff --git a/tests/ui/type-alias-impl-trait/coherence.next.stderr b/tests/ui/type-alias-impl-trait/coherence.next.stderr
index 8d718383110..6d14594e33a 100644
--- a/tests/ui/type-alias-impl-trait/coherence.next.stderr
+++ b/tests/ui/type-alias-impl-trait/coherence.next.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence.rs:16:1
+  --> $DIR/coherence.rs:17:1
    |
 LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------
diff --git a/tests/ui/type-alias-impl-trait/coherence.rs b/tests/ui/type-alias-impl-trait/coherence.rs
index 760e5210c5b..eb27c270804 100644
--- a/tests/ui/type-alias-impl-trait/coherence.rs
+++ b/tests/ui/type-alias-impl-trait/coherence.rs
@@ -9,6 +9,7 @@ trait LocalTrait {}
 impl<T> LocalTrait for foreign_crate::ForeignType<T> {}
 
 type AliasOfForeignType<T> = impl LocalTrait;
+#[define_opaque(AliasOfForeignType)]
 fn use_alias<T>(val: T) -> AliasOfForeignType<T> {
     foreign_crate::ForeignType(val)
 }
diff --git a/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs b/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs
index c1958e4f246..73f13f22bee 100644
--- a/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs
+++ b/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs
@@ -13,6 +13,7 @@ trait OtherTrait {}
 
 type Alias = impl SomeTrait;
 
+#[define_opaque(Alias)]
 fn constrain() -> Alias {
     ()
 }
diff --git a/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr b/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr
index 893a27faced..6b251cfac73 100644
--- a/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr
+++ b/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `OtherTrait` for type `Alias`
-  --> $DIR/coherence_cross_crate.rs:21:1
+  --> $DIR/coherence_cross_crate.rs:22:1
    |
 LL | impl OtherTrait for Alias {}
    | ------------------------- first implementation here
diff --git a/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs b/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs
index 39b3d535ad4..a7e251b1ab9 100644
--- a/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs
+++ b/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs
@@ -20,6 +20,7 @@ impl Trait for (TAIT, TAIT) {}
 impl Trait for (u32, i32) {}
 //~^ ERROR conflicting implementations of trait `Trait` for type `(TAIT, TAIT)`
 
+#[define_opaque(TAIT)]
 fn define() -> TAIT {}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/coherence_generalization.rs b/tests/ui/type-alias-impl-trait/coherence_generalization.rs
index 2d7de1add49..46cde115b7f 100644
--- a/tests/ui/type-alias-impl-trait/coherence_generalization.rs
+++ b/tests/ui/type-alias-impl-trait/coherence_generalization.rs
@@ -6,6 +6,7 @@
 #![feature(type_alias_impl_trait)]
 trait Trait {}
 type Opaque<T> = impl Sized;
+#[define_opaque(Opaque)]
 fn foo<T>() -> Opaque<T> {
     ()
 }
diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr
index 5b77bb6c2bc..dc15d530fd7 100644
--- a/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr
+++ b/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr
@@ -1,8 +1,8 @@
 error: `Bar` is forbidden as the type of a const generic parameter
-  --> $DIR/const_generic_type.rs:7:24
+  --> $DIR/const_generic_type.rs:8:24
    |
-LL | async fn test<const N: crate::Bar>() {
-   |                        ^^^^^^^^^^
+LL | async fn test<const N: Bar>() {
+   |                        ^^^
    |
    = note: the only supported types are integers, `bool`, and `char`
 
diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
index c7c93eee63e..ba97bbf89f8 100644
--- a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
+++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
@@ -1,36 +1,36 @@
 error: `Bar` is forbidden as the type of a const generic parameter
-  --> $DIR/const_generic_type.rs:7:24
+  --> $DIR/const_generic_type.rs:8:24
    |
-LL | async fn test<const N: crate::Bar>() {
-   |                        ^^^^^^^^^^
+LL | async fn test<const N: Bar>() {
+   |                        ^^^
    |
    = note: the only supported types are integers, `bool`, and `char`
 
-error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
-  --> $DIR/const_generic_type.rs:7:10
+error: item does not constrain `Bar::{opaque#0}`
+  --> $DIR/const_generic_type.rs:8:10
    |
-LL | async fn test<const N: crate::Bar>() {
+LL | async fn test<const N: Bar>() {
    |          ^^^^
    |
-   = 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/const_generic_type.rs:5:12
    |
 LL | type Bar = impl std::fmt::Display;
    |            ^^^^^^^^^^^^^^^^^^^^^^
 
-error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
-  --> $DIR/const_generic_type.rs:7:38
+error: item does not constrain `Bar::{opaque#0}`
+  --> $DIR/const_generic_type.rs:8:31
    |
-LL |   async fn test<const N: crate::Bar>() {
-   |  ______________________________________^
+LL |   async fn test<const N: Bar>() {
+   |  _______________________________^
 ...  |
 LL | |     let x: u32 = N;
 LL | | }
    | |_^
    |
-   = 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/const_generic_type.rs:5:12
    |
 LL | type Bar = impl std::fmt::Display;
diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.rs b/tests/ui/type-alias-impl-trait/const_generic_type.rs
index 7149370048b..5b093be9231 100644
--- a/tests/ui/type-alias-impl-trait/const_generic_type.rs
+++ b/tests/ui/type-alias-impl-trait/const_generic_type.rs
@@ -4,7 +4,8 @@
 #![feature(type_alias_impl_trait)]
 type Bar = impl std::fmt::Display;
 
-async fn test<const N: crate::Bar>() {
+#[define_opaque(Bar)]
+async fn test<const N: Bar>() {
     //~^ ERROR: `Bar` is forbidden as the type of a const generic parameter
     //[no_infer]~^^ ERROR item does not constrain
     //[no_infer]~| ERROR item does not constrain
diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr
index 580258bbb28..c4c55d8e092 100644
--- a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr
+++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied
-  --> $DIR/constrain_in_projection.rs:24:14
+  --> $DIR/constrain_in_projection.rs:25:14
    |
 LL |     let x = <Foo as Trait<Bar>>::Assoc::default();
    |              ^^^ the trait `Trait<Bar>` is not implemented for `Foo`
@@ -8,7 +8,7 @@ LL |     let x = <Foo as Trait<Bar>>::Assoc::default();
            but trait `Trait<()>` is implemented for it
 
 error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied
-  --> $DIR/constrain_in_projection.rs:24:13
+  --> $DIR/constrain_in_projection.rs:25:13
    |
 LL |     let x = <Foo as Trait<Bar>>::Assoc::default();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<Bar>` is not implemented for `Foo`
diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs
index 355c0e1692b..64b9c583ca2 100644
--- a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs
+++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs
@@ -20,7 +20,8 @@ impl Trait<()> for Foo {
     type Assoc = u32;
 }
 
-fn bop(_: Bar) {
+#[define_opaque(Bar)]
+fn bop() {
     let x = <Foo as Trait<Bar>>::Assoc::default();
     //[current]~^ `Foo: Trait<Bar>` is not satisfied
     //[current]~| `Foo: Trait<Bar>` is not satisfied
diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr
index 777fe1e2788..d7fb6e67ad2 100644
--- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr
+++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied
-  --> $DIR/constrain_in_projection2.rs:27:14
+  --> $DIR/constrain_in_projection2.rs:28:14
    |
 LL |     let x = <Foo as Trait<Bar>>::Assoc::default();
    |              ^^^ the trait `Trait<Bar>` is not implemented for `Foo`
@@ -9,7 +9,7 @@ LL |     let x = <Foo as Trait<Bar>>::Assoc::default();
              `Foo` implements `Trait<u32>`
 
 error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied
-  --> $DIR/constrain_in_projection2.rs:27:13
+  --> $DIR/constrain_in_projection2.rs:28:13
    |
 LL |     let x = <Foo as Trait<Bar>>::Assoc::default();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<Bar>` is not implemented for `Foo`
diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr
index 0d6eac4216b..7c09ab6a91a 100644
--- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr
+++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr
@@ -1,5 +1,5 @@
 error[E0283]: type annotations needed: cannot satisfy `Foo: Trait<Bar>`
-  --> $DIR/constrain_in_projection2.rs:27:14
+  --> $DIR/constrain_in_projection2.rs:28:14
    |
 LL |     let x = <Foo as Trait<Bar>>::Assoc::default();
    |              ^^^ help: use the fully qualified path to an implementation: `<Type as Trait>::Assoc`
diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs
index 16b1329b52f..61773cf59d4 100644
--- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs
+++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs
@@ -23,7 +23,8 @@ impl Trait<u32> for Foo {
     type Assoc = u32;
 }
 
-fn bop(_: Bar) {
+#[define_opaque(Bar)]
+fn bop() {
     let x = <Foo as Trait<Bar>>::Assoc::default();
     //[next]~^ ERROR: cannot satisfy `Foo: Trait<Bar>`
     //[current]~^^ ERROR: `Foo: Trait<Bar>` is not satisfied
diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs.rs b/tests/ui/type-alias-impl-trait/constrain_inputs.rs
index 1391a2036b2..7f6698e641d 100644
--- a/tests/ui/type-alias-impl-trait/constrain_inputs.rs
+++ b/tests/ui/type-alias-impl-trait/constrain_inputs.rs
@@ -2,7 +2,9 @@
 
 mod lifetime_params {
     type Ty<'a> = impl Sized;
+    #[define_opaque(Ty)]
     fn defining(s: &str) -> Ty<'_> { s }
+    #[define_opaque(Ty)]
     fn execute(ty: Ty<'_>) -> &str { todo!() }
     //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
     //~| ERROR item does not constrain
@@ -15,7 +17,9 @@ mod lifetime_params {
 
 mod lifetime_params_2 {
     type Ty<'a> = impl FnOnce() -> &'a str;
+    #[define_opaque(Ty)]
     fn defining(s: &str) -> Ty<'_> { move || s }
+    #[define_opaque(Ty)]
     fn execute(ty: Ty<'_>) -> &str { ty() }
     //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
     //~| ERROR item does not constrain
@@ -24,6 +28,7 @@ mod lifetime_params_2 {
 // regression test for https://github.com/rust-lang/rust/issues/97104
 mod type_params {
     type Ty<T> = impl Sized;
+    #[define_opaque(Ty)]
     fn define<T>(s: T) -> Ty<T> { s }
 
     type BadFnSig = fn(Ty<&str>) -> &str;
diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs.stderr b/tests/ui/type-alias-impl-trait/constrain_inputs.stderr
index 436326e66c3..b016715b129 100644
--- a/tests/ui/type-alias-impl-trait/constrain_inputs.stderr
+++ b/tests/ui/type-alias-impl-trait/constrain_inputs.stderr
@@ -1,5 +1,5 @@
 error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
-  --> $DIR/constrain_inputs.rs:6:31
+  --> $DIR/constrain_inputs.rs:8:31
    |
 LL |     fn execute(ty: Ty<'_>) -> &str { todo!() }
    |                               ^^^^
@@ -8,7 +8,7 @@ LL |     fn execute(ty: Ty<'_>) -> &str { todo!() }
    = note: consider introducing a named lifetime parameter
 
 error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
-  --> $DIR/constrain_inputs.rs:10:35
+  --> $DIR/constrain_inputs.rs:12:35
    |
 LL |     type BadFnSig = fn(Ty<'_>) -> &str;
    |                                   ^^^^
@@ -17,7 +17,7 @@ LL |     type BadFnSig = fn(Ty<'_>) -> &str;
    = note: consider introducing a named lifetime parameter
 
 error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
-  --> $DIR/constrain_inputs.rs:12:42
+  --> $DIR/constrain_inputs.rs:14:42
    |
 LL |     type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
    |                                          ^^^^
@@ -25,21 +25,21 @@ LL |     type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
    = note: lifetimes appearing in an associated or opaque type are not considered constrained
    = note: consider introducing a named lifetime parameter
 
-error: item does not constrain `lifetime_params::Ty::{opaque#0}`, but has it in its signature
-  --> $DIR/constrain_inputs.rs:6:8
+error: item does not constrain `lifetime_params::Ty::{opaque#0}`
+  --> $DIR/constrain_inputs.rs:8:8
    |
 LL |     fn execute(ty: Ty<'_>) -> &str { todo!() }
    |        ^^^^^^^
    |
-   = 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/constrain_inputs.rs:4:19
    |
 LL |     type Ty<'a> = impl Sized;
    |                   ^^^^^^^^^^
 
 error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
-  --> $DIR/constrain_inputs.rs:19:31
+  --> $DIR/constrain_inputs.rs:23:31
    |
 LL |     fn execute(ty: Ty<'_>) -> &str { ty() }
    |                               ^^^^
@@ -47,21 +47,21 @@ LL |     fn execute(ty: Ty<'_>) -> &str { ty() }
    = note: lifetimes appearing in an associated or opaque type are not considered constrained
    = note: consider introducing a named lifetime parameter
 
-error: item does not constrain `lifetime_params_2::Ty::{opaque#0}`, but has it in its signature
-  --> $DIR/constrain_inputs.rs:19:8
+error: item does not constrain `lifetime_params_2::Ty::{opaque#0}`
+  --> $DIR/constrain_inputs.rs:23:8
    |
 LL |     fn execute(ty: Ty<'_>) -> &str { ty() }
    |        ^^^^^^^
    |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
-  --> $DIR/constrain_inputs.rs:17:19
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/constrain_inputs.rs:19:19
    |
 LL |     type Ty<'a> = impl FnOnce() -> &'a str;
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
-  --> $DIR/constrain_inputs.rs:29:37
+  --> $DIR/constrain_inputs.rs:34:37
    |
 LL |     type BadFnSig = fn(Ty<&str>) -> &str;
    |                                     ^^^^
@@ -70,7 +70,7 @@ LL |     type BadFnSig = fn(Ty<&str>) -> &str;
    = note: consider introducing a named lifetime parameter
 
 error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
-  --> $DIR/constrain_inputs.rs:31:44
+  --> $DIR/constrain_inputs.rs:36:44
    |
 LL |     type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
    |                                            ^^^^
diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs
index 3bae0f17309..dc38e9a8cdc 100644
--- a/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs
+++ b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs
@@ -4,9 +4,12 @@ trait Static: 'static {}
 impl Static for () {}
 
 type Gal<T> = impl Static;
+#[define_opaque(Gal)]
 fn _defining<T>() -> Gal<T> {}
 
-trait Callable<Arg> { type Output; }
+trait Callable<Arg> {
+    type Output;
+}
 
 /// We can infer `<C as Callable<Arg>>::Output: 'static`,
 /// because we know `C: 'static` and `Arg: 'static`,
diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr
index 948bd6deacd..0edb0a06884 100644
--- a/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr
+++ b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr
@@ -1,5 +1,5 @@
 error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
-  --> $DIR/constrain_inputs_unsound.rs:23:58
+  --> $DIR/constrain_inputs_unsound.rs:26:58
    |
 LL |     type MalformedTy = dyn for<'a> Callable<Gal<&'a ()>, Output = &'a str>;
    |                                                          ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs b/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs
index db9c2cc096a..6d9c05d9c68 100644
--- a/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs
+++ b/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs
@@ -3,12 +3,10 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod bar {
-    pub type Debuggable = impl core::fmt::Debug;
-    fn foo() -> Debuggable {
-        0u32
-    }
+pub type Debuggable = impl core::fmt::Debug;
+#[define_opaque(Debuggable)]
+fn foo() -> Debuggable {
+    0u32
 }
-use bar::Debuggable;
 
 static mut TEST: Option<Debuggable> = None;
diff --git a/tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr b/tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr
index 772f487d96a..c2c401da0e8 100644
--- a/tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr
+++ b/tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr
@@ -4,7 +4,7 @@ error: unconstrained opaque type
 LL | type Bar = impl std::fmt::Debug;
    |            ^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `Bar` must be used in combination with a concrete type within the same module
+   = note: `Bar` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr b/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr
index d60f1ffbccc..e97a69bd92c 100644
--- a/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr
+++ b/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr
@@ -4,7 +4,7 @@ error: unconstrained opaque type
 LL |     pub type Boo = impl ::std::fmt::Debug;
    |                    ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `Boo` must be used in combination with a concrete type within the same module
+   = note: `Boo` must be used in combination with a concrete type within the same crate
 
 error[E0308]: mismatched types
   --> $DIR/declared_but_not_defined_in_scope.rs:11:5
@@ -19,7 +19,7 @@ LL |     ""
    |
    = note: expected opaque type `Boo`
                 found reference `&'static str`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
+note: this item must have a `#[define_opaque(Boo)]` attribute to be able to define hidden types
   --> $DIR/declared_but_not_defined_in_scope.rs:10:4
    |
 LL | fn bomp() -> boo::Boo {
diff --git a/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs b/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs
index 75a4fbdb5d6..6a07ea05c1a 100644
--- a/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs
+++ b/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs
@@ -11,9 +11,11 @@ impl<A, B: Equate<Proj = A>> Indirect for (A, B) { type Ty = (); }
 mod basic {
     use super::*;
     type Opq = impl Sized;
+    #[define_opaque(Opq)]
     fn define_1(_: Opq) {
         let _ = None::<<(Opq, u8) as Indirect>::Ty>;
     }
+    #[define_opaque(Opq)]
     fn define_2() -> Opq {
         0u8
     }
@@ -23,6 +25,7 @@ mod basic {
 mod lifetime {
     use super::*;
     type Opq<'a> = impl Sized + 'a;
+    #[define_opaque(Opq)]
     fn define<'a: 'b, 'b: 'a>(_: Opq<'a>) {
         let _ = None::<<(Opq<'a>, &'b u8) as Indirect>::Ty>;
     }
diff --git a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs
index 9101e4385b3..bc3904eb4e5 100644
--- a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs
+++ b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs
@@ -2,6 +2,7 @@
 
 mod case1 {
     type Opaque<'x> = impl Sized + 'x;
+    #[define_opaque(Opaque)]
     fn foo<'s>() -> Opaque<'s> {
         let _ = || { let _: Opaque<'s> = (); };
         //~^ ERROR expected generic lifetime parameter, found `'_`
@@ -10,6 +11,7 @@ mod case1 {
 
 mod case2 {
     type Opaque<'x> = impl Sized + 'x;
+    #[define_opaque(Opaque)]
     fn foo<'s>() -> Opaque<'s> {
         let _ = || -> Opaque<'s> {};
         //~^ ERROR expected generic lifetime parameter, found `'_`
diff --git a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr
index a8fd1f691dd..2210291d37b 100644
--- a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr
+++ b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr
@@ -1,18 +1,18 @@
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/defined-in-closure-external-lifetime.rs:6:29
+  --> $DIR/defined-in-closure-external-lifetime.rs:7:29
    |
 LL |     type Opaque<'x> = impl Sized + 'x;
    |                 -- this generic parameter must be used with a generic lifetime parameter
-LL |     fn foo<'s>() -> Opaque<'s> {
+...
 LL |         let _ = || { let _: Opaque<'s> = (); };
    |                             ^^^^^^^^^^
 
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/defined-in-closure-external-lifetime.rs:14:34
+  --> $DIR/defined-in-closure-external-lifetime.rs:16:34
    |
 LL |     type Opaque<'x> = impl Sized + 'x;
    |                 -- this generic parameter must be used with a generic lifetime parameter
-LL |     fn foo<'s>() -> Opaque<'s> {
+...
 LL |         let _ = || -> Opaque<'s> {};
    |                                  ^^
 
diff --git a/tests/ui/type-alias-impl-trait/defining-use-submodule.rs b/tests/ui/type-alias-impl-trait/defining-use-submodule.rs
index 3e7bc32640f..b953cd646a0 100644
--- a/tests/ui/type-alias-impl-trait/defining-use-submodule.rs
+++ b/tests/ui/type-alias-impl-trait/defining-use-submodule.rs
@@ -11,13 +11,24 @@ type Foo = impl std::fmt::Display;
 type Bar = impl std::fmt::Display;
 
 mod foo {
+    #[define_opaque(super::Foo)]
     pub(crate) fn foo() -> super::Foo {
         "foo"
     }
 
     pub(crate) mod bar {
+        #[define_opaque(crate::Bar)]
         pub(crate) fn bar() -> crate::Bar {
             1
         }
     }
 }
+
+mod bar {
+    pub type Baz = impl std::fmt::Display;
+}
+
+#[define_opaque(bar::Baz)]
+fn baz() -> bar::Baz {
+    "boom"
+}
diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs
index eadf21c9138..a3b1aba7041 100644
--- a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs
+++ b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs
@@ -10,6 +10,7 @@ pub struct Foo {
 
 pub type Tait = impl Sized;
 
+#[define_opaque(Tait)]
 pub async fn ice_cold(beverage: Tait) {
     // Must destructure at least one field of `Foo`
     let Foo { field } = beverage;
diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs
index 8ce471e3956..e56f60a6693 100644
--- a/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs
+++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs
@@ -2,10 +2,12 @@
 
 pub type Opaque<'a> = impl Sized;
 
+#[define_opaque(Opaque)]
 fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> {
     a
 }
 
+#[define_opaque(Opaque)]
 fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> {
     //~^ ERROR:  item does not constrain
     None::<Opaque<'static>>
diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr b/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr
index f27f2234525..587328e2870 100644
--- a/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr
+++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr
@@ -1,11 +1,11 @@
-error: item does not constrain `Opaque::{opaque#0}`, but has it in its signature
-  --> $DIR/different_args_considered_equal.rs:9:4
+error: item does not constrain `Opaque::{opaque#0}`
+  --> $DIR/different_args_considered_equal.rs:11:4
    |
 LL | fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> {
    |    ^^^^^^^^
    |
-   = 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/different_args_considered_equal.rs:3:23
    |
 LL | pub type Opaque<'a> = impl Sized;
diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs
index 43dfea97e6d..902d6ca57e6 100644
--- a/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs
+++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs
@@ -2,6 +2,7 @@
 
 pub type Opaque<'a> = impl Sized;
 
+#[define_opaque(Opaque)]
 fn get_one<'a>(a: *mut &'a str) -> impl IntoIterator<Item = Opaque<'a>> {
     if a.is_null() {
         Some(a)
diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr
index 213272f5f34..562ab4168b5 100644
--- a/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr
+++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr
@@ -1,9 +1,9 @@
 error[E0700]: hidden type for `Opaque<'static>` captures lifetime that does not appear in bounds
-  --> $DIR/different_args_considered_equal2.rs:9:9
+  --> $DIR/different_args_considered_equal2.rs:10:9
    |
 LL | pub type Opaque<'a> = impl Sized;
    |                       ---------- opaque type defined here
-LL |
+...
 LL | fn get_one<'a>(a: *mut &'a str) -> impl IntoIterator<Item = Opaque<'a>> {
    |            -- hidden type `*mut &'a str` captures the lifetime `'a` as defined here
 ...
diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs
index ea69175ba31..85a7e371b07 100644
--- a/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs
+++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs
@@ -5,14 +5,12 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod defining_scope {
-    pub type Opaque<'a> = impl Sized;
+pub type Opaque<'a> = impl Sized;
 
-    fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> {
-        a
-    }
+#[define_opaque(Opaque)]
+fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> {
+    a
 }
-use defining_scope::Opaque;
 
 fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> {
     None::<Opaque<'static>>
diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr
index d8f70e3d778..06d6433c4b5 100644
--- a/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr
+++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/different_args_considered_equal3.rs:18:5
+  --> $DIR/different_args_considered_equal3.rs:16:5
    |
 LL | fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> {
    |             -- lifetime `'a` defined here
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses.rs b/tests/ui/type-alias-impl-trait/different_defining_uses.rs
index 4505c4d9524..246f255e8fc 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses.rs
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses.rs
@@ -5,10 +5,12 @@ fn main() {}
 // two definitions with different types
 type Foo = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     ""
 }
 
+#[define_opaque(Foo)]
 fn bar() -> Foo {
     42i32
     //~^ ERROR concrete type differs from previous
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses.stderr
index 9e6169b2af7..9a7f4b416f4 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses.stderr
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/different_defining_uses.rs:13:5
+  --> $DIR/different_defining_uses.rs:15:5
    |
 LL |     42i32
    |     ^^^^^ expected `&'static str`, got `i32`
    |
 note: previous use here
-  --> $DIR/different_defining_uses.rs:9:5
+  --> $DIR/different_defining_uses.rs:10:5
    |
 LL |     ""
    |     ^^
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs
index 4b5f455e381..e8c40e8bf92 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs
@@ -2,6 +2,7 @@
 
 type Tait<'a> = impl Sized + 'a;
 
+#[define_opaque(Tait)]
 fn foo<'a, 'b>() -> Tait<'a> {
     if false {
         if { return } {
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr
index 6f5be5467f7..d4bd3975924 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr
@@ -1,23 +1,23 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/different_defining_uses_never_type-2.rs:13:5
+  --> $DIR/different_defining_uses_never_type-2.rs:14:5
    |
 LL |     x
    |     ^ expected `i32`, got `()`
    |
 note: previous use here
-  --> $DIR/different_defining_uses_never_type-2.rs:8:31
+  --> $DIR/different_defining_uses_never_type-2.rs:9:31
    |
 LL |             let y: Tait<'b> = 1i32;
    |                               ^^^^
 
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/different_defining_uses_never_type-2.rs:8:31
+  --> $DIR/different_defining_uses_never_type-2.rs:9:31
    |
 LL |             let y: Tait<'b> = 1i32;
    |                               ^^^^ expected `()`, got `i32`
    |
 note: previous use here
-  --> $DIR/different_defining_uses_never_type-2.rs:7:14
+  --> $DIR/different_defining_uses_never_type-2.rs:8:14
    |
 LL |         if { return } {
    |              ^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs
index a4ac27378e1..b2713b9602c 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs
@@ -2,6 +2,7 @@
 
 type Tait<T> = impl Sized;
 
+#[define_opaque(Tait)]
 fn foo<T, U>() -> Tait<T> {
     if false {
         if { return } {
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr
index 0fdcb81f667..cb12fddd9a0 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/different_defining_uses_never_type-3.rs:8:30
+  --> $DIR/different_defining_uses_never_type-3.rs:9:30
    |
 LL |             let y: Tait<U> = 1i32;
    |                              ^^^^ expected `()`, got `i32`
    |
 note: previous use here
-  --> $DIR/different_defining_uses_never_type-3.rs:12:22
+  --> $DIR/different_defining_uses_never_type-3.rs:13:22
    |
 LL |     let x: Tait<T> = ();
    |                      ^^
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs
index 0b8157fe33d..38597ccaf42 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs
@@ -5,14 +5,17 @@ fn main() {}
 // two definitions with different types
 type Foo = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     ""
 }
 
+#[define_opaque(Foo)]
 fn bar() -> Foo { //~ ERROR: concrete type differs from previous defining opaque type use
     panic!()
 }
 
+#[define_opaque(Foo)]
 fn boo() -> Foo {
     loop {}
 }
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr
index 2a77eb4c4ac..38afa3cbcd0 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/different_defining_uses_never_type.rs:12:13
+  --> $DIR/different_defining_uses_never_type.rs:14:13
    |
 LL | fn bar() -> Foo {
    |             ^^^ expected `&'static str`, got `()`
    |
 note: previous use here
-  --> $DIR/different_defining_uses_never_type.rs:9:5
+  --> $DIR/different_defining_uses_never_type.rs:10:5
    |
 LL |     ""
    |     ^^
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs
index c39cc192dc7..03766da34cb 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs
@@ -7,10 +7,12 @@ fn main() {}
 // two definitions with different types
 type Foo = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     ""
 }
 
+#[define_opaque(Foo)]
 fn bar(arg: bool) -> Foo {
     if arg {
         panic!()
@@ -19,6 +21,7 @@ fn bar(arg: bool) -> Foo {
     }
 }
 
+#[define_opaque(Foo)]
 fn boo(arg: bool) -> Foo {
     if arg {
         loop {}
@@ -27,6 +30,7 @@ fn boo(arg: bool) -> Foo {
     }
 }
 
+#[define_opaque(Foo)]
 fn bar2(arg: bool) -> Foo {
     if arg {
         "bar2"
@@ -35,6 +39,7 @@ fn bar2(arg: bool) -> Foo {
     }
 }
 
+#[define_opaque(Foo)]
 fn boo2(arg: bool) -> Foo {
     if arg {
         "boo2"
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs
index bc827a8f211..b5c2bf504ac 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs
@@ -3,9 +3,11 @@
 type Tait = impl Sized;
 
 struct One;
+#[define_opaque(Tait)]
 fn one() -> Tait { One }
 
 struct Two<T>(T);
+#[define_opaque(Tait)]
 fn two() -> Tait { Two::<()>(todo!()) }
 //~^ ERROR concrete type differs from previous defining opaque type use
 
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr
index abf4a0d241b..21fab818063 100644
--- a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/different_defining_uses_never_type3.rs:9:13
+  --> $DIR/different_defining_uses_never_type3.rs:11:13
    |
 LL | fn two() -> Tait { Two::<()>(todo!()) }
    |             ^^^^ expected `One`, got `Two<()>`
    |
 note: previous use here
-  --> $DIR/different_defining_uses_never_type3.rs:6:20
+  --> $DIR/different_defining_uses_never_type3.rs:7:20
    |
 LL | fn one() -> Tait { One }
    |                    ^^^
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 4f424b8c665..ba3265343c6 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
@@ -3,10 +3,12 @@
 
 type OneLifetime<'a, 'b> = impl std::fmt::Debug;
 
+#[define_opaque(OneLifetime)]
 fn foo<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> {
     a
 }
 
+#[define_opaque(OneLifetime)]
 fn bar<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> {
     b
     //~^ ERROR: concrete type differs from previous defining opaque type use
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 07ba17ad27b..b87e884708a 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:11:5
+  --> $DIR/different_lifetimes_defining_uses.rs:13:5
    |
 LL |     b
    |     ^ expected `&'a u32`, got `&'b u32`
    |
 note: previous use here
-  --> $DIR/different_lifetimes_defining_uses.rs:7:5
+  --> $DIR/different_lifetimes_defining_uses.rs:8:5
    |
 LL |     a
    |     ^
diff --git a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs
index 4332f1264a8..987ac381289 100644
--- a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs
+++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs
@@ -2,29 +2,32 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod impl_trait_mod {
-    use super::*;
-    pub type OpaqueBlock = impl Trait;
-    //~^ ERROR unconstrained opaque type
-    pub type OpaqueIf = impl Trait;
+pub type OpaqueBlock = impl Trait;
+//~^ ERROR unconstrained opaque type
+pub type OpaqueIf = impl Trait;
 
-    pub struct BlockWrapper(OpaqueBlock);
-    pub struct IfWrapper(pub OpaqueIf);
+pub struct BlockWrapper(OpaqueBlock);
+pub struct IfWrapper(pub OpaqueIf);
 
-    pub fn if_impl() -> Parser<OpaqueIf> {
-        bind(option(block()), |_| block())
-    }
+#[define_opaque(OpaqueIf)]
+pub fn if_impl() -> Parser<OpaqueIf> {
+    bind(option(block()), |_| block())
 }
-use impl_trait_mod::*;
 
 pub trait Trait {
     type Assoc;
 }
 pub struct Parser<P>(P);
 pub struct Bind<P, F>(P, F);
-impl<P, F> Trait for Bind<P, F> { type Assoc = (); }
-impl Trait for BlockWrapper { type Assoc = (); }
-impl Trait for IfWrapper { type Assoc = (); }
+impl<P, F> Trait for Bind<P, F> {
+    type Assoc = ();
+}
+impl Trait for BlockWrapper {
+    type Assoc = ();
+}
+impl Trait for IfWrapper {
+    type Assoc = ();
+}
 
 pub fn block() -> Parser<BlockWrapper> {
     loop {}
@@ -32,8 +35,9 @@ pub fn block() -> Parser<BlockWrapper> {
 pub fn option<P: Trait>(arg: Parser<P>) -> Parser<impl Trait> {
     bind(arg, |_| block())
 }
-fn bind<P: Trait, P2, F: Fn(P::Assoc) -> Parser<P2>>(_: Parser<P>, _: F) -> Parser<Bind<P, F>>
-    { loop {} }
+fn bind<P: Trait, P2, F: Fn(P::Assoc) -> Parser<P2>>(_: Parser<P>, _: F) -> Parser<Bind<P, F>> {
+    loop {}
+}
 
 fn main() {
     if_impl().0;
diff --git a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr
index 8e5838d5ddf..db97954f698 100644
--- a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr
+++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr
@@ -1,10 +1,10 @@
 error: unconstrained opaque type
-  --> $DIR/drop-analysis-on-unconstrained-tait.rs:7:28
+  --> $DIR/drop-analysis-on-unconstrained-tait.rs:5:24
    |
-LL |     pub type OpaqueBlock = impl Trait;
-   |                            ^^^^^^^^^^
+LL | pub type OpaqueBlock = impl Trait;
+   |                        ^^^^^^^^^^
    |
-   = note: `OpaqueBlock` must be used in combination with a concrete type within the same module
+   = note: `OpaqueBlock` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs b/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs
index b1d5961067b..5dda2597c66 100644
--- a/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs
+++ b/tests/ui/type-alias-impl-trait/duplicate-lifetimes-from-rpit-containing-tait.rs
@@ -4,6 +4,7 @@
 
 type Opaque<'lt> = impl Sized + 'lt;
 
+#[define_opaque(Opaque)]
 fn test<'a>(
     arg: impl Iterator<Item = &'a u8>,
 ) -> impl Iterator<Item = Opaque<'a>> {
diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs
index b209b4bc89d..64f926fba9e 100644
--- a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs
+++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs
@@ -7,19 +7,21 @@ impl<T> Trait<'_, '_> for T {}
 
 mod mod1 {
     type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
+    #[define_opaque(Opaque)]
     fn test<'a>() -> Opaque<'a, 'a> {}
     //~^ ERROR non-defining opaque type use in defining scope
-    //~| ERROR non-defining opaque type use in defining scope
 }
 
 mod mod2 {
     type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
+    #[define_opaque(Opaque)]
     fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> {}
     //~^ ERROR non-defining opaque type use in defining scope
 }
 
 mod mod3 {
     type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
+    #[define_opaque(Opaque)]
     fn test<'a: 'b, 'b: 'a>(a: &'a str) -> Opaque<'a, 'b> { a }
     //~^ ERROR non-defining opaque type use in defining scope
 }
@@ -30,6 +32,7 @@ mod mod3 {
 // it is ambiguous whether `Opaque<'a> := &'a ()` or `Opaque<'a> := &'static ()`
 mod mod4 {
     type Opaque<'a> = impl super::Trait<'a, 'a>;
+    #[define_opaque(Opaque)]
     fn test<'a: 'static>() -> Opaque<'a> {}
     //~^ ERROR expected generic lifetime parameter, found `'static`
 }
diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr
index b08bc8b8268..34af7cb32c2 100644
--- a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr
+++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr
@@ -1,17 +1,5 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/equal-lifetime-params-not-ok.rs:10:22
-   |
-LL |     fn test<'a>() -> Opaque<'a, 'a> {}
-   |                      ^^^^^^^^^^^^^^ generic argument `'a` used twice
-   |
-note: for this opaque type
-  --> $DIR/equal-lifetime-params-not-ok.rs:9:27
-   |
-LL |     type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: non-defining opaque type use in defining scope
-  --> $DIR/equal-lifetime-params-not-ok.rs:10:37
+  --> $DIR/equal-lifetime-params-not-ok.rs:11:37
    |
 LL |     fn test<'a>() -> Opaque<'a, 'a> {}
    |                                     ^^
@@ -23,7 +11,7 @@ LL |     type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
    |                 ^^  ^^
 
 error: non-defining opaque type use in defining scope
-  --> $DIR/equal-lifetime-params-not-ok.rs:17:49
+  --> $DIR/equal-lifetime-params-not-ok.rs:18:49
    |
 LL |     fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> {}
    |                                                 ^^
@@ -35,25 +23,26 @@ LL |     type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
    |                 ^^  ^^
 
 error: non-defining opaque type use in defining scope
-  --> $DIR/equal-lifetime-params-not-ok.rs:23:61
+  --> $DIR/equal-lifetime-params-not-ok.rs:25:61
    |
 LL |     fn test<'a: 'b, 'b: 'a>(a: &'a str) -> Opaque<'a, 'b> { a }
    |                                                             ^
    |
 note: lifetime used multiple times
-  --> $DIR/equal-lifetime-params-not-ok.rs:22:17
+  --> $DIR/equal-lifetime-params-not-ok.rs:23:17
    |
 LL |     type Opaque<'a, 'b> = impl super::Trait<'a, 'b>;
    |                 ^^  ^^
 
 error[E0792]: expected generic lifetime parameter, found `'static`
-  --> $DIR/equal-lifetime-params-not-ok.rs:33:42
+  --> $DIR/equal-lifetime-params-not-ok.rs:36:42
    |
 LL |     type Opaque<'a> = impl super::Trait<'a, 'a>;
    |                 -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
+LL |     #[define_opaque(Opaque)]
 LL |     fn test<'a: 'static>() -> Opaque<'a> {}
    |                                          ^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs b/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs
index 0ce85a4d6cb..711aca662d1 100644
--- a/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs
+++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs
@@ -12,6 +12,7 @@ impl<T> Trait<'_, '_> for T {}
 
 mod equal_params {
     type Opaque<'a: 'b, 'b: 'a> = impl super::Trait<'a, 'b>;
+    #[define_opaque(Opaque)]
     fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> {
         let _ = None::<&'a &'b &'a ()>;
         0u8
@@ -20,6 +21,7 @@ mod equal_params {
 
 mod equal_static {
     type Opaque<'a: 'static> = impl Sized + 'a;
+    #[define_opaque(Opaque)]
     fn test<'a: 'static>() -> Opaque<'a> {
         let _ = None::<&'static &'a ()>;
         0u8
diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs
index 07206dd2491..31bdd0815ec 100644
--- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs
+++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs
@@ -16,6 +16,7 @@ impl Trait<'_> for () {
 
 impl Test<'_> for () {}
 
+#[define_opaque(Foo)]
 fn constrain() -> Foo {
     ()
 }
diff --git a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs
index 9ed010f2293..726820bbd5a 100644
--- a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs
+++ b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs
@@ -22,10 +22,12 @@ type StateWidget<'a> = impl Widget<&'a ()>;
 impl<F: for<'a> Fn(&'a ()) -> StateWidget<'a>> Widget<()> for StatefulWidget<F> {
     type State = ();
 
+    #[define_opaque(StateWidget)]
     fn make_state(&self) -> Self::State {}
     //~^ ERROR item does not constrain
 }
 
+#[define_opaque(StateWidget)]
 fn new_stateful_widget<F: for<'a> Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> {
     //~^ ERROR item does not constrain
     StatefulWidget(build)
diff --git a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr
index 9a3f4ae4c1c..4f5c65adab9 100644
--- a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr
+++ b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr
@@ -1,31 +1,40 @@
-error: item does not constrain `StateWidget::{opaque#0}`, but has it in its signature
-  --> $DIR/failed-to-normalize-ice-99945.rs:25:8
+error: item does not constrain `StateWidget::{opaque#0}`
+  --> $DIR/failed-to-normalize-ice-99945.rs:26:8
    |
 LL |     fn make_state(&self) -> Self::State {}
    |        ^^^^^^^^^^
    |
-   = 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/failed-to-normalize-ice-99945.rs:20:24
    |
 LL | type StateWidget<'a> = impl Widget<&'a ()>;
    |                        ^^^^^^^^^^^^^^^^^^^
 
-error: item does not constrain `StateWidget::{opaque#0}`, but has it in its signature
-  --> $DIR/failed-to-normalize-ice-99945.rs:29:4
+error: item does not constrain `StateWidget::{opaque#0}`
+  --> $DIR/failed-to-normalize-ice-99945.rs:31:4
    |
 LL | fn new_stateful_widget<F: for<'a> Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> {
    |    ^^^^^^^^^^^^^^^^^^^
    |
-   = 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/failed-to-normalize-ice-99945.rs:20:24
    |
 LL | type StateWidget<'a> = impl Widget<&'a ()>;
    |                        ^^^^^^^^^^^^^^^^^^^
 
+error[E0792]: expected generic lifetime parameter, found `'a`
+  --> $DIR/failed-to-normalize-ice-99945.rs:33:5
+   |
+LL | type StateWidget<'a> = impl Widget<&'a ()>;
+   |                  -- this generic parameter must be used with a generic lifetime parameter
+...
+LL |     StatefulWidget(build)
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
 error[E0308]: mismatched types
-  --> $DIR/failed-to-normalize-ice-99945.rs:36:29
+  --> $DIR/failed-to-normalize-ice-99945.rs:38:29
    |
 LL | type StateWidget<'a> = impl Widget<&'a ()>;
    |                        ------------------- the expected opaque type
@@ -36,15 +45,6 @@ LL |     new_stateful_widget(|_| ()).make_state();
    = note: expected opaque type `StateWidget<'_>`
                 found unit type `()`
 
-error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/failed-to-normalize-ice-99945.rs:31:5
-   |
-LL | type StateWidget<'a> = impl Widget<&'a ()>;
-   |                  -- this generic parameter must be used with a generic lifetime parameter
-...
-LL |     StatefulWidget(build)
-   |     ^^^^^^^^^^^^^^^^^^^^^
-
 error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0308, E0792.
diff --git a/tests/ui/type-alias-impl-trait/fallback.rs b/tests/ui/type-alias-impl-trait/fallback.rs
index d8cf7d71fef..a2f25acca0d 100644
--- a/tests/ui/type-alias-impl-trait/fallback.rs
+++ b/tests/ui/type-alias-impl-trait/fallback.rs
@@ -7,19 +7,20 @@ type Foo = impl Copy;
 
 enum Wrapper<T> {
     First(T),
-    Second
+    Second,
 }
 
 // This method constrains `Foo` to be `bool`
+#[define_opaque(Foo)]
 fn constrained_foo() -> Foo {
     true
 }
 
-
 // This method does not constrain `Foo`.
 // Per RFC 2071, function bodies may either
 // fully constrain an opaque type, or place no
 // constraints on it.
+#[define_opaque(Foo)]
 fn unconstrained_foo() -> Wrapper<Foo> {
     Wrapper::Second
     //~^ ERROR: type annotations needed
diff --git a/tests/ui/type-alias-impl-trait/fallback.stderr b/tests/ui/type-alias-impl-trait/fallback.stderr
index c909ab66f0e..1eb0afb13a8 100644
--- a/tests/ui/type-alias-impl-trait/fallback.stderr
+++ b/tests/ui/type-alias-impl-trait/fallback.stderr
@@ -1,5 +1,5 @@
 error[E0283]: type annotations needed
-  --> $DIR/fallback.rs:24:5
+  --> $DIR/fallback.rs:25:5
    |
 LL | fn unconstrained_foo() -> Wrapper<Foo> {
    |                           ------------ type must be known at this point
diff --git a/tests/ui/type-alias-impl-trait/field-types.rs b/tests/ui/type-alias-impl-trait/field-types.rs
index 24e430afac3..3ea73abb03f 100644
--- a/tests/ui/type-alias-impl-trait/field-types.rs
+++ b/tests/ui/type-alias-impl-trait/field-types.rs
@@ -1,3 +1,6 @@
+//! Show that `defines(StructName)` works for
+//! fields of that struct being an opaque type.
+
 #![feature(type_alias_impl_trait)]
 #![allow(dead_code)]
 
@@ -11,6 +14,7 @@ struct Bar {
     foo: Foo,
 }
 
+#[define_opaque(Bar)]
 fn bar() -> Bar {
     Bar { foo: "foo" }
 }
diff --git a/tests/ui/type-alias-impl-trait/future.rs b/tests/ui/type-alias-impl-trait/future.rs
index 36d1dcd00ad..e233554f6a1 100644
--- a/tests/ui/type-alias-impl-trait/future.rs
+++ b/tests/ui/type-alias-impl-trait/future.rs
@@ -11,6 +11,7 @@ trait Bar {
 
 type FooFuture<B> = impl Future<Output = ()>;
 
+#[define_opaque(FooFuture)]
 fn foo<B: Bar>(bar: B) -> FooFuture<B> {
     async move { bar.bar() }
     //~^ ERROR: the trait bound `B: Bar` is not satisfied
diff --git a/tests/ui/type-alias-impl-trait/future.stderr b/tests/ui/type-alias-impl-trait/future.stderr
index 047ad164239..8510ab27fb7 100644
--- a/tests/ui/type-alias-impl-trait/future.stderr
+++ b/tests/ui/type-alias-impl-trait/future.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `B: Bar` is not satisfied
-  --> $DIR/future.rs:15:5
+  --> $DIR/future.rs:16:5
    |
 LL |     async move { bar.bar() }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B`
    |
 note: required by a bound in `foo`
-  --> $DIR/future.rs:14:11
+  --> $DIR/future.rs:15:11
    |
 LL | fn foo<B: Bar>(bar: B) -> FooFuture<B> {
    |           ^^^ required by this bound in `foo`
diff --git a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr
index e5f86c8c193..43e887f36c5 100644
--- a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr
+++ b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/generic-not-strictly-equal.rs:33:5
+  --> $DIR/generic-not-strictly-equal.rs:34:5
    |
 LL | type Opaque<'a> = impl Copy + Captures<'a>;
    |             -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr
index 693af69d6fa..4a5360c9922 100644
--- a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr
+++ b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr
@@ -1,9 +1,9 @@
 error[E0700]: hidden type for `Opaque<'x>` captures lifetime that does not appear in bounds
-  --> $DIR/generic-not-strictly-equal.rs:33:5
+  --> $DIR/generic-not-strictly-equal.rs:34:5
    |
 LL | type Opaque<'a> = impl Copy + Captures<'a>;
    |                   ------------------------ opaque type defined here
-LL |
+...
 LL | fn test<'x>(_: Opaque<'x>) {
    |         -- hidden type `&'x u8` captures the lifetime `'x` as defined here
 ...
diff --git a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs
index a059fd3b822..c1059e3da33 100644
--- a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs
+++ b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs
@@ -20,6 +20,7 @@ fn relate<X>(_: X, _: X) {}
 
 type Opaque<'a> = impl Copy + Captures<'a>;
 
+#[define_opaque(Opaque)]
 fn test<'x>(_: Opaque<'x>) {
     let opaque = None::<Opaque<'_>>; // let's call this lifetime '?1
 
diff --git a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs
index 8b683ad2828..d55a9a376b9 100644
--- a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs
+++ b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs
@@ -4,10 +4,12 @@ fn main() {}
 
 type MyIter<T> = impl Iterator<Item = T>;
 
+#[define_opaque(MyIter)]
 fn my_iter<T>(t: T) -> MyIter<T> {
     std::iter::once(t)
 }
 
+#[define_opaque(MyIter)]
 fn my_iter2<T>(t: T) -> MyIter<T> {
     Some(t).into_iter()
     //~^ ERROR concrete type differs from previous
diff --git a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr
index 72271d158a1..6d3279144d8 100644
--- a/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_different_defining_uses.rs:12:5
+  --> $DIR/generic_different_defining_uses.rs:14:5
    |
 LL |     Some(t).into_iter()
    |     ^^^^^^^^^^^^^^^^^^^ expected `std::iter::Once<T>`, got `std::option::IntoIter<T>`
    |
 note: previous use here
-  --> $DIR/generic_different_defining_uses.rs:8:5
+  --> $DIR/generic_different_defining_uses.rs:9:5
    |
 LL |     std::iter::once(t)
    |     ^^^^^^^^^^^^^^^^^^
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 169d4f8d509..45da4145278 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
@@ -4,8 +4,8 @@ fn main() {}
 
 type Two<'a, 'b> = impl std::fmt::Debug;
 
+#[define_opaque(Two)]
 fn one<'a>(t: &'a ()) -> Two<'a, 'a> {
-    //~^ ERROR non-defining opaque type use
     t
     //~^ 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 b03bf2466e6..352e6fd3c5c 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,16 +1,4 @@
 error: non-defining opaque type use in defining scope
-  --> $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:5:20
-   |
-LL | type Two<'a, 'b> = impl std::fmt::Debug;
-   |                    ^^^^^^^^^^^^^^^^^^^^
-
-error: non-defining opaque type use in defining scope
   --> $DIR/generic_duplicate_lifetime_param.rs:9:5
    |
 LL |     t
@@ -22,5 +10,5 @@ note: lifetime used multiple times
 LL | type Two<'a, 'b> = impl std::fmt::Debug;
    |          ^^  ^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
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 e3c6f4d874b..e8ed38a24ce 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
@@ -18,20 +18,20 @@ type TwoLifetimes<'a, 'b> = impl Debug;
 
 type TwoConsts<const X: usize, const Y: usize> = impl Debug;
 
+#[define_opaque(TwoTys)]
 fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
-    //~^ ERROR non-defining opaque type use in defining scope
     t
     //~^ ERROR non-defining opaque type use in defining scope
 }
 
+#[define_opaque(TwoLifetimes)]
 fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
-    //~^ ERROR non-defining opaque type use in defining scope
     t
     //~^ ERROR non-defining opaque type use in defining scope
 }
 
+#[define_opaque(TwoConsts)]
 fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
-    //~^ ERROR non-defining opaque type use in defining scope
     t
     //~^ ERROR non-defining opaque type use in defining scope
 }
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 73570de5326..3e048c8138d 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,16 +1,4 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/generic_duplicate_param_use.rs:21:30
-   |
-LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
-   |                              ^^^^^^^^^^^^ generic argument `T` used twice
-   |
-note: for this opaque type
-  --> $DIR/generic_duplicate_param_use.rs:15:21
-   |
-LL | type TwoTys<T, U> = impl Debug;
-   |                     ^^^^^^^^^^
-
-error: non-defining opaque type use in defining scope
   --> $DIR/generic_duplicate_param_use.rs:23:5
    |
 LL |     t
@@ -23,30 +11,6 @@ LL | type TwoTys<T, U> = impl Debug;
    |             ^  ^
 
 error: non-defining opaque type use in defining scope
-  --> $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:17:29
-   |
-LL | type TwoLifetimes<'a, 'b> = impl Debug;
-   |                             ^^^^^^^^^^
-
-error: non-defining opaque type use in defining scope
-  --> $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: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:29:5
    |
 LL |     t
@@ -70,5 +34,5 @@ note: constant used multiple times
 LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
    |                ^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs
index 439214911eb..849d237b809 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs
@@ -7,6 +7,7 @@ fn main() {}
 
 type Two<T: Debug, U> = impl Debug;
 
+#[define_opaque(Two)]
 fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> {
     (t, 4u32)
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
index 201535efe15..073684b8add 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
@@ -7,6 +7,7 @@ fn main() {}
 // test that unused generic parameters are ok
 type Two<T, U> = impl Debug;
 
+#[define_opaque(Two)]
 fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
     t
     //~^ ERROR `T` doesn't implement `Debug`
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
index cd6e85764bd..ef0e73f1481 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `T` doesn't implement `Debug`
-  --> $DIR/generic_duplicate_param_use2.rs:11:5
+  --> $DIR/generic_duplicate_param_use2.rs:12:5
    |
 LL |     t
    |     ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
@@ -10,7 +10,7 @@ note: required by a bound in an opaque type
 LL | type Two<T, U> = impl Debug;
    |                       ^^^^^
 note: this definition site has more where clauses than the opaque type
-  --> $DIR/generic_duplicate_param_use2.rs:10:1
+  --> $DIR/generic_duplicate_param_use2.rs:11:1
    |
 LL | fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
index 2074f12750f..f732b233396 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
@@ -7,10 +7,12 @@ fn main() {}
 // test that unused generic parameters are ok
 type Two<T, U> = impl Debug;
 
+#[define_opaque(Two)]
 fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
     t
 }
 
+#[define_opaque(Two)]
 fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
     u
     //~^ ERROR concrete type differs
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
index 9a10a4980d8..b0a1bd77f85 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_duplicate_param_use3.rs:15:5
+  --> $DIR/generic_duplicate_param_use3.rs:17:5
    |
 LL |     u
    |     ^ expected `T`, got `U`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use3.rs:11:5
+  --> $DIR/generic_duplicate_param_use3.rs:12:5
    |
 LL |     t
    |     ^
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
index d1e5a0f0198..68a8f3da168 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
@@ -7,6 +7,7 @@ fn main() {}
 // test that unused generic parameters are ok
 type Two<T, U> = impl Debug;
 
+#[define_opaque(Two)]
 fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
     u
     //~^ ERROR `U` doesn't implement `Debug`
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
index bf3c4a0e04f..0932c72ff93 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `U` doesn't implement `Debug`
-  --> $DIR/generic_duplicate_param_use4.rs:11:5
+  --> $DIR/generic_duplicate_param_use4.rs:12:5
    |
 LL |     u
    |     ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
@@ -10,7 +10,7 @@ note: required by a bound in an opaque type
 LL | type Two<T, U> = impl Debug;
    |                       ^^^^^
 note: this definition site has more where clauses than the opaque type
-  --> $DIR/generic_duplicate_param_use4.rs:10:1
+  --> $DIR/generic_duplicate_param_use4.rs:11:1
    |
 LL | fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs
index b3d6beaf848..d450bef5758 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs
@@ -7,10 +7,12 @@ fn main() {}
 // test that unused generic parameters are ok
 type Two<T, U> = impl Debug;
 
+#[define_opaque(Two)]
 fn two<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
     (t, u)
 }
 
+#[define_opaque(Two)]
 fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
     (u, t)
     //~^ ERROR concrete type differs
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
index b0027f8fa57..b8a2a937416 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_duplicate_param_use5.rs:15:5
+  --> $DIR/generic_duplicate_param_use5.rs:17:5
    |
 LL |     (u, t)
    |     ^^^^^^ expected `(T, U)`, got `(U, T)`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use5.rs:11:5
+  --> $DIR/generic_duplicate_param_use5.rs:12:5
    |
 LL |     (t, u)
    |     ^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs
index fa8b2a290b9..24d03b9e60d 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs
@@ -7,10 +7,12 @@ fn main() {}
 // test that unused generic parameters are ok
 type Two<T, U> = impl Debug;
 
+#[define_opaque(Two)]
 fn two<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
     (t, t)
 }
 
+#[define_opaque(Two)]
 fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
     (u, t)
     //~^ ERROR concrete type differs
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
index 09c01932cef..983e58d3c70 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_duplicate_param_use6.rs:15:5
+  --> $DIR/generic_duplicate_param_use6.rs:17:5
    |
 LL |     (u, t)
    |     ^^^^^^ expected `(T, T)`, got `(U, T)`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use6.rs:11:5
+  --> $DIR/generic_duplicate_param_use6.rs:12:5
    |
 LL |     (t, t)
    |     ^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs
index adc912294fd..6f4a81ed760 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs
@@ -7,18 +7,22 @@ fn main() {}
 
 type Two<A: Debug, B> = impl Debug;
 
+#[define_opaque(Two)]
 fn two<T: Debug + Copy, U>(t: T, u: U) -> Two<T, U> {
     (t, t)
 }
 
+#[define_opaque(Two)]
 fn three<T: Debug, U>(t: T, t2: T, u: U) -> Two<T, U> {
     (t, t2)
 }
 
+#[define_opaque(Two)]
 fn four<T: Debug, U, V>(t: T, t2: T, u: U, v: V) -> Two<T, U> {
     (t, t2)
 }
 
+#[define_opaque(Two)]
 fn five<X, Y: Debug>(x: X, y: Y, y2: Y) -> Two<Y, X> {
     (y, y2)
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs
index 76c13bb027b..03057c84782 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs
@@ -6,10 +6,12 @@ fn main() {}
 
 type Two<T, U> = impl Debug;
 
+#[define_opaque(Two)]
 fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> {
     (t, 4u32)
 }
 
+#[define_opaque(Two)]
 fn three<T: Debug, U: Debug>(_: T, u: U) -> Two<T, U> {
     (u, 4u32)
     //~^ concrete type differs
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
index 09d2abe3663..48c98c1e2b1 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_duplicate_param_use8.rs:14:5
+  --> $DIR/generic_duplicate_param_use8.rs:16:5
    |
 LL |     (u, 4u32)
    |     ^^^^^^^^^ expected `(T, u32)`, got `(U, u32)`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use8.rs:10:5
+  --> $DIR/generic_duplicate_param_use8.rs:11:5
    |
 LL |     (t, 4u32)
    |     ^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
index 5da7aab0da7..74176550ab2 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
@@ -11,10 +11,12 @@ trait Foo {
     const BAR: Self::Bar;
 }
 
+#[define_opaque(Two)]
 fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> {
     (t, u, T::BAR)
 }
 
+#[define_opaque(Two)]
 fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
     (t, u, 42)
     //~^ ERROR concrete type differs
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
index 6e1bb3dfa17..542324c949f 100644
--- a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/generic_duplicate_param_use9.rs:19:5
+  --> $DIR/generic_duplicate_param_use9.rs:21:5
    |
 LL |     (t, u, 42)
    |     ^^^^^^^^^^ expected `(A, B, <A as Foo>::Bar)`, got `(A, B, i32)`
    |
 note: previous use here
-  --> $DIR/generic_duplicate_param_use9.rs:15:5
+  --> $DIR/generic_duplicate_param_use9.rs:16:5
    |
 LL |     (t, u, T::BAR)
    |     ^^^^^^^^^^^^^^
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 b9b34f55e7e..d5fb1b461ec 100644
--- a/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs
+++ b/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs
@@ -6,6 +6,7 @@ fn main() {}
 
 type Region<'a> = impl std::fmt::Debug;
 
+#[define_opaque(Region)]
 fn region<'b>(a: &'b ()) -> Region<'b> {
     a
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
index 68f4c6923ae..7791410294c 100644
--- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
+++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
@@ -12,20 +12,20 @@ type OneConst<const X: usize> = impl Debug;
 
 // Not defining uses, because they doesn't define *all* possible generics.
 
+#[define_opaque(OneTy)]
 fn concrete_ty() -> OneTy<u32> {
-    //~^ ERROR: non-defining opaque type use in defining scope
     5u32
     //~^ ERROR: expected generic type parameter, found `u32`
 }
 
+#[define_opaque(OneLifetime)]
 fn concrete_lifetime() -> OneLifetime<'static> {
-    //~^ ERROR: non-defining opaque type use in defining scope
     6u32
     //~^ ERROR: expected generic lifetime parameter, found `'static`
 }
 
+#[define_opaque(OneConst)]
 fn concrete_const() -> OneConst<{ 123 }> {
-    //~^ ERROR: non-defining opaque type use in defining scope
     7u32
     //~^ ERROR: expected generic constant parameter, found `123`
 }
diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr
index bd68b4e3ea4..1b0ce7cc619 100644
--- a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr
@@ -1,15 +1,3 @@
-error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/generic_nondefining_use.rs:15:21
-   |
-LL | fn concrete_ty() -> OneTy<u32> {
-   |                     ^^^^^^^^^^ argument `u32` is not a generic parameter
-   |
-note: for this opaque type
-  --> $DIR/generic_nondefining_use.rs:7:17
-   |
-LL | type OneTy<T> = impl Debug;
-   |                 ^^^^^^^^^^
-
 error[E0792]: expected generic type parameter, found `u32`
   --> $DIR/generic_nondefining_use.rs:17:5
    |
@@ -19,30 +7,6 @@ LL | type OneTy<T> = impl Debug;
 LL |     5u32
    |     ^^^^
 
-error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/generic_nondefining_use.rs:21:27
-   |
-LL | fn concrete_lifetime() -> OneLifetime<'static> {
-   |                           ^^^^^^^^^^^^^^^^^^^^ argument `'static` is not a generic parameter
-   |
-note: for this opaque type
-  --> $DIR/generic_nondefining_use.rs:9:24
-   |
-LL | type OneLifetime<'a> = impl Debug;
-   |                        ^^^^^^^^^^
-
-error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/generic_nondefining_use.rs:27:24
-   |
-LL | fn concrete_const() -> OneConst<{ 123 }> {
-   |                        ^^^^^^^^^^^^^^^^^ argument `123` is not a generic parameter
-   |
-note: for this opaque type
-  --> $DIR/generic_nondefining_use.rs:11:33
-   |
-LL | type OneConst<const X: usize> = impl Debug;
-   |                                 ^^^^^^^^^^
-
 error[E0792]: expected generic lifetime parameter, found `'static`
   --> $DIR/generic_nondefining_use.rs:23:5
    |
@@ -61,6 +25,6 @@ LL | type OneConst<const X: usize> = impl Debug;
 LL |     7u32
    |     ^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/generic_not_used.rs b/tests/ui/type-alias-impl-trait/generic_not_used.rs
index c70f473cff5..6042cdd30a9 100644
--- a/tests/ui/type-alias-impl-trait/generic_not_used.rs
+++ b/tests/ui/type-alias-impl-trait/generic_not_used.rs
@@ -5,6 +5,7 @@ fn main() {}
 type WrongGeneric<T: 'static> = impl 'static;
 //~^ ERROR: at least one trait must be specified
 
+#[define_opaque(WrongGeneric)]
 fn wrong_generic<U: 'static, V: 'static>(_: U, v: V) -> WrongGeneric<U> {
     v
     //~^ ERROR type parameter `V` is part of concrete type but not used in parameter list
diff --git a/tests/ui/type-alias-impl-trait/generic_not_used.stderr b/tests/ui/type-alias-impl-trait/generic_not_used.stderr
index fd720239a52..5fe2fefcecf 100644
--- a/tests/ui/type-alias-impl-trait/generic_not_used.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_not_used.stderr
@@ -5,7 +5,7 @@ LL | type WrongGeneric<T: 'static> = impl 'static;
    |                                 ^^^^^^^^^^^^
 
 error: type parameter `V` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/generic_not_used.rs:9:5
+  --> $DIR/generic_not_used.rs:10:5
    |
 LL |     v
    |     ^
diff --git a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
index c60f5c11cd1..4b8a1cfc472 100644
--- a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
+++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
@@ -9,6 +9,7 @@ fn main() {
     type WrongGeneric<T> = impl 'static;
     //~^ ERROR: at least one trait must be specified
 
+    #[define_opaque(WrongGeneric)]
     fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
         t
         //~^ ERROR the parameter type `T` may not live long enough
diff --git a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
index c352a33fbbc..2b3f7d75028 100644
--- a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
@@ -14,7 +14,7 @@ LL |     type WrongGeneric<T> = impl 'static;
    |                       - this generic parameter must be used with a generic type parameter
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:13:9
+  --> $DIR/generic_type_does_not_live_long_enough.rs:14:9
    |
 LL |         t
    |         ^
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained.rs b/tests/ui/type-alias-impl-trait/generic_underconstrained.rs
index 1acacc778de..9c2180e92fc 100644
--- a/tests/ui/type-alias-impl-trait/generic_underconstrained.rs
+++ b/tests/ui/type-alias-impl-trait/generic_underconstrained.rs
@@ -6,6 +6,7 @@ trait Trait {}
 type Underconstrained<T: Trait> = impl Send;
 
 // no `Trait` bound
+#[define_opaque(Underconstrained)]
 fn underconstrain<T>(_: T) -> Underconstrained<T> {
     //~^ ERROR the trait bound `T: Trait`
     //~| ERROR the trait bound `T: Trait`
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
index c24f8fd867f..b1bc62c5910 100644
--- a/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `T: Trait` is not satisfied
-  --> $DIR/generic_underconstrained.rs:9:31
+  --> $DIR/generic_underconstrained.rs:10:31
    |
 LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
    |                               ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
@@ -15,7 +15,7 @@ LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> {
    |                    +++++++
 
 error[E0277]: the trait bound `T: Trait` is not satisfied
-  --> $DIR/generic_underconstrained.rs:9:31
+  --> $DIR/generic_underconstrained.rs:10:31
    |
 LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
    |                               ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained2.rs b/tests/ui/type-alias-impl-trait/generic_underconstrained2.rs
index 1e1bece9a1c..f05f9776006 100644
--- a/tests/ui/type-alias-impl-trait/generic_underconstrained2.rs
+++ b/tests/ui/type-alias-impl-trait/generic_underconstrained2.rs
@@ -5,6 +5,7 @@ fn main() {}
 type Underconstrained<T: std::fmt::Debug> = impl Send;
 
 // not a defining use, because it doesn't define *all* possible generics
+#[define_opaque(Underconstrained)]
 fn underconstrained<U>(_: U) -> Underconstrained<U> {
     //~^ ERROR `U` doesn't implement `Debug`
     //~| ERROR `U` doesn't implement `Debug`
@@ -14,6 +15,7 @@ fn underconstrained<U>(_: U) -> Underconstrained<U> {
 type Underconstrained2<T: std::fmt::Debug> = impl Send;
 
 // not a defining use, because it doesn't define *all* possible generics
+#[define_opaque(Underconstrained2)]
 fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
     //~^ ERROR `V` doesn't implement `Debug`
     //~| ERROR `V` doesn't implement `Debug`
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
index 93df5ddca79..429c3b9175a 100644
--- a/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
+++ b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `U` doesn't implement `Debug`
-  --> $DIR/generic_underconstrained2.rs:8:33
+  --> $DIR/generic_underconstrained2.rs:9:33
    |
 LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
    |                                 ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
@@ -15,13 +15,13 @@ LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> {
    |                      +++++++++++++++++
 
 error[E0277]: `V` doesn't implement `Debug`
-  --> $DIR/generic_underconstrained2.rs:17:43
+  --> $DIR/generic_underconstrained2.rs:19:43
    |
 LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
    |                                           ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
 note: required by a bound on the type alias `Underconstrained2`
-  --> $DIR/generic_underconstrained2.rs:14:27
+  --> $DIR/generic_underconstrained2.rs:15:27
    |
 LL | type Underconstrained2<T: std::fmt::Debug> = impl Send;
    |                           ^^^^^^^^^^^^^^^ required by this bound
@@ -31,7 +31,7 @@ LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained
    |                          +++++++++++++++++
 
 error[E0277]: `U` doesn't implement `Debug`
-  --> $DIR/generic_underconstrained2.rs:8:33
+  --> $DIR/generic_underconstrained2.rs:9:33
    |
 LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
    |                                 ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
@@ -48,13 +48,13 @@ LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> {
    |                      +++++++++++++++++
 
 error[E0277]: `V` doesn't implement `Debug`
-  --> $DIR/generic_underconstrained2.rs:17:43
+  --> $DIR/generic_underconstrained2.rs:19:43
    |
 LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
    |                                           ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
 note: required by a bound on the type alias `Underconstrained2`
-  --> $DIR/generic_underconstrained2.rs:14:27
+  --> $DIR/generic_underconstrained2.rs:15:27
    |
 LL | type Underconstrained2<T: std::fmt::Debug> = impl Send;
    |                           ^^^^^^^^^^^^^^^ required by this bound
diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs
index eb19b49c7e2..bf97dd9a25c 100644
--- a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs
+++ b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.rs
@@ -15,6 +15,7 @@ trait Trait: Sized {
 
 impl Trait for Bar {
     type Assoc = impl std::fmt::Debug;
+    //~^ ERROR: unconstrained opaque type
     fn foo() -> Foo<Bar> {
         Foo { field: () }
         //~^ ERROR: mismatched types
diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr
index 00aedfae463..879f024dee7 100644
--- a/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr
+++ b/tests/ui/type-alias-impl-trait/hidden_behind_projection_behind_struct_field.stderr
@@ -1,20 +1,23 @@
+error: unconstrained opaque type
+  --> $DIR/hidden_behind_projection_behind_struct_field.rs:17:18
+   |
+LL |     type Assoc = impl std::fmt::Debug;
+   |                  ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Assoc` must be used in combination with a concrete type within the same impl
+
 error[E0308]: mismatched types
-  --> $DIR/hidden_behind_projection_behind_struct_field.rs:19:22
+  --> $DIR/hidden_behind_projection_behind_struct_field.rs:20:22
    |
 LL |     type Assoc = impl std::fmt::Debug;
    |                  -------------------- the expected opaque type
-LL |     fn foo() -> Foo<Bar> {
+...
 LL |         Foo { field: () }
    |                      ^^ expected opaque type, found `()`
    |
    = note: expected opaque type `<Bar as Trait>::Assoc`
                 found unit type `()`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/hidden_behind_projection_behind_struct_field.rs:18:8
-   |
-LL |     fn foo() -> Foo<Bar> {
-   |        ^^^
 
-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/type-alias-impl-trait/hidden_behind_struct_field2.rs b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs
index 3117060cef0..b1dcf98f4dd 100644
--- a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs
+++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.rs
@@ -13,6 +13,7 @@ trait Trait: Sized {
 
 impl Trait for Bar {
     type Assoc = impl std::fmt::Debug;
+    //~^ ERROR: unconstrained opaque type
     fn foo() -> Foo {
         Foo { field: () }
         //~^ ERROR: mismatched types
diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr
index 4910e794e8d..1820560eadd 100644
--- a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr
+++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field2.stderr
@@ -1,20 +1,23 @@
+error: unconstrained opaque type
+  --> $DIR/hidden_behind_struct_field2.rs:15:18
+   |
+LL |     type Assoc = impl std::fmt::Debug;
+   |                  ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Assoc` must be used in combination with a concrete type within the same impl
+
 error[E0308]: mismatched types
-  --> $DIR/hidden_behind_struct_field2.rs:17:22
+  --> $DIR/hidden_behind_struct_field2.rs:18:22
    |
 LL |     type Assoc = impl std::fmt::Debug;
    |                  -------------------- the expected opaque type
-LL |     fn foo() -> Foo {
+...
 LL |         Foo { field: () }
    |                      ^^ expected opaque type, found `()`
    |
    = note: expected opaque type `<Bar as Trait>::Assoc`
                 found unit type `()`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/hidden_behind_struct_field2.rs:16:8
-   |
-LL |     fn foo() -> Foo {
-   |        ^^^
 
-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/type-alias-impl-trait/hidden_behind_struct_field3.rs b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs
index c1f13599412..70697e2fa65 100644
--- a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs
+++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs
@@ -14,6 +14,7 @@ trait Trait: Sized {
 
 impl Trait for Bar {
     type Assoc2 = impl std::fmt::Debug;
+    //~^ ERROR: unconstrained opaque type
     type Assoc = impl Iterator<Item = Foo>;
     fn foo() -> Self::Assoc {
         vec![Foo { field: () }].into_iter()
diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr
index f10ccc00299..9ce696fa26c 100644
--- a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr
+++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr
@@ -1,5 +1,13 @@
+error: unconstrained opaque type
+  --> $DIR/hidden_behind_struct_field3.rs:16:19
+   |
+LL |     type Assoc2 = impl std::fmt::Debug;
+   |                   ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Assoc2` must be used in combination with a concrete type within the same impl
+
 error[E0308]: mismatched types
-  --> $DIR/hidden_behind_struct_field3.rs:19:27
+  --> $DIR/hidden_behind_struct_field3.rs:20:27
    |
 LL |     type Assoc2 = impl std::fmt::Debug;
    |                   -------------------- the expected opaque type
@@ -9,12 +17,7 @@ LL |         vec![Foo { field: () }].into_iter()
    |
    = note: expected opaque type `<Bar as Trait>::Assoc2`
                 found unit type `()`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/hidden_behind_struct_field3.rs:18:8
-   |
-LL |     fn foo() -> Self::Assoc {
-   |        ^^^
 
-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/type-alias-impl-trait/hidden_type_mismatch.rs b/tests/ui/type-alias-impl-trait/hidden_type_mismatch.rs
index 5b5acb31812..0a8860321da 100644
--- a/tests/ui/type-alias-impl-trait/hidden_type_mismatch.rs
+++ b/tests/ui/type-alias-impl-trait/hidden_type_mismatch.rs
@@ -9,6 +9,7 @@
 mod sus {
     use super::*;
     pub type Sep = impl Sized + std::fmt::Display;
+    #[define_opaque(Sep)]
     pub fn mk_sep() -> Sep {
         String::from("hello")
     }
@@ -34,6 +35,7 @@ mod sus {
     // `define_tait` is not actually callable, and thus assumed
     // `Bar<()>: Copy` even though it isn't.
     pub type Tait = impl Copy + From<Bar<()>> + Into<Bar<()>>;
+    #[define_opaque(Tait)]
     pub fn define_tait() -> Tait
     where
         // this proves `Bar<()>: Copy`, but `define_tait` is
diff --git a/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr b/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr
index 8547fd53c18..20991a30b53 100644
--- a/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr
+++ b/tests/ui/type-alias-impl-trait/hidden_type_mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `<() as Proj>::Assoc == i32`
-  --> $DIR/hidden_type_mismatch.rs:43:9
+  --> $DIR/hidden_type_mismatch.rs:45:9
    |
 LL |     pub type Sep = impl Sized + std::fmt::Display;
    |                    ------------------------------ the found opaque type
@@ -8,26 +8,26 @@ LL |         Bar { inner: 1i32, _marker: () }
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<() as Proj>::Assoc == i32`
    |
 note: expected this to be `i32`
-  --> $DIR/hidden_type_mismatch.rs:20:22
+  --> $DIR/hidden_type_mismatch.rs:21:22
    |
 LL |         type Assoc = sus::Sep;
    |                      ^^^^^^^^
    = note:     expected type `i32`
            found opaque type `Sep`
 note: required for `Bar<()>` to implement `Copy`
-  --> $DIR/hidden_type_mismatch.rs:32:39
+  --> $DIR/hidden_type_mismatch.rs:33:39
    |
 LL |     impl<T: Proj<Assoc = i32> + Copy> Copy for Bar<T> {}
    |                  -----------          ^^^^     ^^^^^^
    |                  |
    |                  unsatisfied trait bound introduced here
 note: required by a bound in an opaque type
-  --> $DIR/hidden_type_mismatch.rs:36:26
+  --> $DIR/hidden_type_mismatch.rs:37:26
    |
 LL |     pub type Tait = impl Copy + From<Bar<()>> + Into<Bar<()>>;
    |                          ^^^^
 note: this definition site has more where clauses than the opaque type
-  --> $DIR/hidden_type_mismatch.rs:37:5
+  --> $DIR/hidden_type_mismatch.rs:39:5
    |
 LL | /     pub fn define_tait() -> Tait
 LL | |     where
diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params.rs
index e43f53e4057..6008df3b0a2 100644
--- a/tests/ui/type-alias-impl-trait/higher_kinded_params.rs
+++ b/tests/ui/type-alias-impl-trait/higher_kinded_params.rs
@@ -22,6 +22,7 @@ struct Terminator;
 type Successors<'a> = impl std::fmt::Debug + 'a;
 
 impl Terminator {
+    #[define_opaque(Successors)]
     fn successors(&self, _: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> {}
 }
 
diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs
index 19c6099135d..8ed7c1336f2 100644
--- a/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs
+++ b/tests/ui/type-alias-impl-trait/higher_kinded_params2.rs
@@ -2,6 +2,7 @@
 //! and normalizing something behind them actually works.
 
 //@ edition: 2021
+//@ check-pass
 
 #![feature(type_alias_impl_trait)]
 
@@ -22,9 +23,9 @@ struct Terminator;
 type Successors<'a> = impl std::fmt::Debug + 'a;
 
 impl Terminator {
+    #[define_opaque(Successors, Tait)]
     fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> {
         f = g;
-        //~^ ERROR mismatched types
     }
 }
 
diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr b/tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr
deleted file mode 100644
index 790e7fe8580..00000000000
--- a/tests/ui/type-alias-impl-trait/higher_kinded_params2.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/higher_kinded_params2.rs:26:13
-   |
-LL | type Tait = impl std::fmt::Debug;
-   |             -------------------- the expected opaque type
-...
-LL |         f = g;
-   |             ^ expected fn pointer, found fn item
-   |
-   = note: expected fn pointer `for<'x> fn(&'x ()) -> Tait`
-                 found fn item `for<'a> fn(&'a ()) -> String {g}`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/higher_kinded_params2.rs:25:8
-   |
-LL |     fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> {
-   |        ^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs
index 3845cde29fa..4fb2e60b5c5 100644
--- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs
+++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs
@@ -22,6 +22,7 @@ struct Terminator;
 type Successors<'a> = impl std::fmt::Debug + 'a;
 
 impl Terminator {
+    #[define_opaque(Successors, Tait)]
     fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> {
         f = g;
         //~^ ERROR mismatched types
diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr
index 41a3f9ce268..558792987f3 100644
--- a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr
+++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr
@@ -1,19 +1,14 @@
 error[E0308]: mismatched types
-  --> $DIR/higher_kinded_params3.rs:26:13
+  --> $DIR/higher_kinded_params3.rs:27:9
    |
 LL | type Tait<'a> = impl std::fmt::Debug + 'a;
    |                 ------------------------- the expected opaque type
 ...
 LL |         f = g;
-   |             ^ expected fn pointer, found fn item
+   |         ^^^^^ one type is more general than the other
    |
    = note: expected fn pointer `for<'x> fn(&'x ()) -> Tait<'x>`
-                 found fn item `for<'a> fn(&'a ()) -> &'a () {g}`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/higher_kinded_params3.rs:25:8
-   |
-LL |     fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> {
-   |        ^^^^^^^^^^
+              found fn pointer `for<'a> fn(&'a ()) -> &'a ()`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden.rs
index c6d1202ef85..994adc476e2 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden.rs
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden.rs
@@ -6,6 +6,7 @@ fn id(s: &str) -> &str {
 
 type Opaque<'a> = impl Sized + 'a;
 
+#[define_opaque(Opaque)]
 fn test(s: &str) -> (impl Fn(&str) -> Opaque<'_>, impl Fn(&str) -> Opaque<'_>) {
     (id, id) //~ ERROR expected generic lifetime parameter, found `'_`
 }
@@ -16,22 +17,26 @@ fn id2<'a, 'b>(s: (&'a str, &'b str)) -> (&'a str, &'b str) {
 
 type Opaque2<'a> = impl Sized + 'a;
 
+#[define_opaque(Opaque2)]
 fn test2() -> impl for<'a, 'b> Fn((&'a str, &'b str)) -> (Opaque2<'a>, Opaque2<'b>) {
     id2 //~ ERROR expected generic lifetime parameter, found `'a`
 }
 
 type Opaque3<'a> = impl Sized + 'a;
 
+#[define_opaque(Opaque3)]
 fn test3(s: &str) -> (impl Fn(&str) -> Opaque3<'_>, Opaque3<'_>) {
     (id, s) //~ ERROR expected generic lifetime parameter, found `'_`
 }
 
 type Opaque4<'a> = impl Sized + 'a;
+#[define_opaque(Opaque4)]
 fn test4(s: &str) -> (Opaque4<'_>, impl Fn(&str) -> Opaque4<'_>) {
     (s, id) //~ ERROR expected generic lifetime parameter, found `'_`
 }
 
 type Inner<'a> = impl Sized;
+#[define_opaque(Inner)]
 fn outer_impl() -> impl for<'a> Fn(&'a ()) -> Inner<'a> {
     |x| x //~ ERROR expected generic lifetime parameter, found `'a`
 }
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden.stderr
index d49be73d94e..d404d60f31e 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden.stderr
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/hkl_forbidden.rs:10:5
+  --> $DIR/hkl_forbidden.rs:11:5
    |
 LL | type Opaque<'a> = impl Sized + 'a;
    |             -- this generic parameter must be used with a generic lifetime parameter
@@ -8,7 +8,7 @@ LL |     (id, id)
    |     ^^^^^^^^
 
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/hkl_forbidden.rs:20:5
+  --> $DIR/hkl_forbidden.rs:22:5
    |
 LL | type Opaque2<'a> = impl Sized + 'a;
    |              -- this generic parameter must be used with a generic lifetime parameter
@@ -17,7 +17,7 @@ LL |     id2
    |     ^^^
 
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/hkl_forbidden.rs:26:5
+  --> $DIR/hkl_forbidden.rs:29:5
    |
 LL | type Opaque3<'a> = impl Sized + 'a;
    |              -- this generic parameter must be used with a generic lifetime parameter
@@ -26,20 +26,20 @@ LL |     (id, s)
    |     ^^^^^^^
 
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/hkl_forbidden.rs:31:5
+  --> $DIR/hkl_forbidden.rs:35:5
    |
 LL | type Opaque4<'a> = impl Sized + 'a;
    |              -- this generic parameter must be used with a generic lifetime parameter
-LL | fn test4(s: &str) -> (Opaque4<'_>, impl Fn(&str) -> Opaque4<'_>) {
+...
 LL |     (s, id)
    |     ^^^^^^^
 
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/hkl_forbidden.rs:36:5
+  --> $DIR/hkl_forbidden.rs:41:5
    |
 LL | type Inner<'a> = impl Sized;
    |            -- this generic parameter must be used with a generic lifetime parameter
-LL | fn outer_impl() -> impl for<'a> Fn(&'a ()) -> Inner<'a> {
+...
 LL |     |x| x
    |     ^^^^^
 
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden2.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden2.rs
index 3d583d4413d..92e383d11f1 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden2.rs
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden2.rs
@@ -10,6 +10,7 @@ impl<'a> Trait<'a> for () {
     type Assoc = ();
 }
 
+#[define_opaque(Opaque)]
 fn test() -> &'static dyn for<'a> Trait<'a, Assoc = Opaque<'a>> {
     &()
     //~^ ERROR: expected generic lifetime parameter, found `'a`
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr
index 0a9a9d6bcf4..7404c844ae7 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden2.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/hkl_forbidden2.rs:14:5
+  --> $DIR/hkl_forbidden2.rs:15:5
    |
 LL | type Opaque<'a> = impl Sized + 'a;
    |             -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs
index a4148599f77..c7f04dc07bb 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden3.rs
@@ -6,6 +6,7 @@ fn foo<'a>(x: &'a ()) -> &'a () {
     x
 }
 
+#[define_opaque(Opaque)]
 fn test() -> for<'a> fn(&'a ()) -> Opaque<'a> {
     foo //~ ERROR: mismatched types
 }
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr
index d262177a86b..b8c04185a7d 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden3.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/hkl_forbidden3.rs:10:5
+  --> $DIR/hkl_forbidden3.rs:11:5
    |
 LL | type Opaque<'a> = impl Sized + 'a;
    |                   --------------- the expected opaque type
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs
index fd06ea677c3..7e010918b29 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs
@@ -15,6 +15,7 @@ async fn operation(_: &mut ()) -> () {
     //~^ ERROR: expected generic lifetime parameter, found `'any`
 }
 
+#[define_opaque(FutNothing)]
 async fn call<F>(_f: F)
 //~^ ERROR item does not constrain
 where
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
index feb161c3b04..2ca6a199448 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
@@ -1,43 +1,43 @@
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/hkl_forbidden4.rs:12:1
-   |
-LL | async fn operation(_: &mut ()) -> () {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `FutNothing<'_>`, got `{async fn body of operation()}`
-   |
-note: previous use here
-  --> $DIR/hkl_forbidden4.rs:14:5
-   |
-LL |     call(operation).await
-   |     ^^^^^^^^^^^^^^^
-
-error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signature
-  --> $DIR/hkl_forbidden4.rs:18:10
+error: item does not constrain `FutNothing::{opaque#0}`
+  --> $DIR/hkl_forbidden4.rs:19:10
    |
 LL | async fn call<F>(_f: F)
    |          ^^^^
    |
-   = 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/hkl_forbidden4.rs:10:23
    |
 LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signature
-  --> $DIR/hkl_forbidden4.rs:22:1
+error: item does not constrain `FutNothing::{opaque#0}`
+  --> $DIR/hkl_forbidden4.rs:23:1
    |
 LL | / {
 ...  |
 LL | | }
    | |_^
    |
-   = 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/hkl_forbidden4.rs:10:23
    |
 LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/hkl_forbidden4.rs:12:1
+   |
+LL | async fn operation(_: &mut ()) -> () {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `FutNothing<'_>`, got `{async fn body of operation()}`
+   |
+note: previous use here
+  --> $DIR/hkl_forbidden4.rs:14:5
+   |
+LL |     call(operation).await
+   |     ^^^^^^^^^^^^^^^
+
 error[E0792]: expected generic lifetime parameter, found `'any`
   --> $DIR/hkl_forbidden4.rs:14:5
    |
@@ -48,7 +48,7 @@ LL |     call(operation).await
    |     ^^^^^^^^^^^^^^^
 
 error[E0792]: expected generic lifetime parameter, found `'any`
-  --> $DIR/hkl_forbidden4.rs:22:1
+  --> $DIR/hkl_forbidden4.rs:23:1
    |
 LL |   type FutNothing<'a> = impl 'a + Future<Output = ()>;
    |                   -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs
index 2bcb8f06f4f..29e7c7d19fc 100644
--- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs
+++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs
@@ -18,6 +18,7 @@ trait MyFrom<T>: Sized {
 trait F {}
 impl F for () {}
 type DummyT<T> = impl F;
+#[define_opaque(DummyT)]
 fn _dummy_t<T>() -> DummyT<T> {}
 
 struct Phantom1<T>(PhantomData<T>);
@@ -25,6 +26,7 @@ struct Phantom2<T>(PhantomData<T>);
 struct Scope<T>(Phantom2<DummyT<T>>);
 
 impl<T> Scope<T> {
+    #[define_opaque(DummyT)]
     fn new() -> Self {
         //~^ ERROR item does not constrain
         unimplemented!()
@@ -41,6 +43,7 @@ impl<T> MyFrom<Phantom2<T>> for Phantom1<T> {
 impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
     //~^ ERROR the type parameter `T` is not constrained by the impl
     type O = T;
+    #[define_opaque(DummyT)]
     fn my_index(self) -> Self::O {
         MyFrom::my_from(self.0).ok().unwrap()
     }
diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr
index 0ab4c34381a..d18a824287c 100644
--- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr
+++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr
@@ -1,17 +1,17 @@
 error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6
+  --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:43:6
    |
 LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
    |      ^ unconstrained type parameter
 
-error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature
-  --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:28:8
+error: item does not constrain `DummyT::{opaque#0}`
+  --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:30:8
    |
 LL |     fn new() -> Self {
    |        ^^^
    |
-   = 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/ice-failed-to-resolve-instance-for-110696.rs:20:18
    |
 LL | type DummyT<T> = impl F;
diff --git a/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.rs b/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.rs
index 71416eb531a..a9cae611ec5 100644
--- a/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.rs
+++ b/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.rs
@@ -18,6 +18,7 @@ impl Foo for () {
 
     type Baz<T> = impl Sized;
     //~^ ERROR type `Baz` has 1 type parameter but its trait declaration has 0 type parameters
+    //~| ERROR: unconstrained opaque type
 
     fn test<'a>() -> Self::Bar<'a> {
         &()
diff --git a/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr b/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr
index e5a21ff8b4e..13f5d8b8ea6 100644
--- a/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr
+++ b/tests/ui/type-alias-impl-trait/impl-trait-in-type-alias-with-bad-substs.stderr
@@ -7,6 +7,14 @@ LL |     type Baz<'a>;
 LL |     type Baz<T> = impl Sized;
    |              ^ found 1 type parameter
 
-error: aborting due to 1 previous error
+error: unconstrained opaque type
+  --> $DIR/impl-trait-in-type-alias-with-bad-substs.rs:19:19
+   |
+LL |     type Baz<T> = impl Sized;
+   |                   ^^^^^^^^^^
+   |
+   = note: `Baz` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs b/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs
index 00d1a1a226d..b50345bb637 100644
--- a/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs
+++ b/tests/ui/type-alias-impl-trait/impl_for_weak_alias.rs
@@ -7,6 +7,7 @@ auto trait Trait {}
 impl Trait for Alias {}
 //~^ ERROR traits with a default impl, like `Trait`, cannot be implemented for type alias `Alias`
 
+#[define_opaque(Alias)]
 fn _def() -> Alias {
     (42, 42)
 }
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs
index 91610c92d22..3bbfee42ef6 100644
--- a/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs
@@ -9,6 +9,7 @@ impl Foo for i32 {
     type Assoc = u32;
 }
 type ImplTrait = impl Sized;
+#[define_opaque(ImplTrait)]
 fn constrain() -> ImplTrait {
     1u64
 }
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs
index 3f1a9d12b44..a05c65be48b 100644
--- a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs
@@ -5,6 +5,7 @@ impl Foo for () {}
 impl Foo for i32 {}
 
 type Bar<T: Foo> = impl std::fmt::Debug;
+#[define_opaque(Bar)]
 fn defining_use<T: Foo>() -> Bar<T> {
     42
 }
@@ -18,6 +19,7 @@ impl Bop for Bar<i32> {}
 //~^ ERROR conflicting implementations
 
 type Barr = impl std::fmt::Debug;
+#[define_opaque(Barr)]
 fn defining_use2() -> Barr {
     42
 }
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr
index aaf75cc3db9..2f44ee481ad 100644
--- a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
-  --> $DIR/impl_trait_for_same_tait.rs:17:1
+  --> $DIR/impl_trait_for_same_tait.rs:18:1
    |
 LL | impl Bop for Bar<()> {}
    | -------------------- first implementation here
@@ -8,7 +8,7 @@ LL | impl Bop for Bar<i32> {}
    | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
 
 error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
-  --> $DIR/impl_trait_for_same_tait.rs:26:1
+  --> $DIR/impl_trait_for_same_tait.rs:28:1
    |
 LL | impl Bop for Bar<()> {}
    | -------------------- first implementation here
@@ -17,7 +17,7 @@ LL | impl Bop for Barr {}
    | ^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
 
 error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
-  --> $DIR/impl_trait_for_same_tait.rs:30:1
+  --> $DIR/impl_trait_for_same_tait.rs:32:1
    |
 LL | impl Bop for Bar<()> {}
    | -------------------- first implementation here
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs
index bce5ba7c91c..07ac284d501 100644
--- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs
@@ -4,6 +4,7 @@
 #![feature(type_alias_impl_trait)]
 type Alias = impl Sized;
 
+#[define_opaque(Alias)]
 fn constrain() -> Alias {
     1i32
 }
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs
index 8ec20acef4d..e0045df08ec 100644
--- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs
@@ -3,17 +3,18 @@
 use std::fmt::Debug;
 
 type Foo = impl Debug;
-pub trait Yay { }
-impl Yay for Foo { }
+pub trait Yay {}
+impl Yay for Foo {}
 
+#[define_opaque(Foo)]
 fn foo() {
-    is_yay::<u32>();   //~ ERROR: the trait bound `u32: Yay` is not satisfied
+    is_yay::<u32>(); //~ ERROR: the trait bound `u32: Yay` is not satisfied
     is_debug::<u32>(); // OK
-    is_yay::<Foo>();   // OK
+    is_yay::<Foo>(); // OK
     is_debug::<Foo>(); // OK
 }
 
-fn is_yay<T: Yay>() { }
-fn is_debug<T: Debug>() { }
+fn is_yay<T: Yay>() {}
+fn is_debug<T: Debug>() {}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr
index 9840bcef7d1..0ebf9f06437 100644
--- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr
@@ -1,14 +1,14 @@
 error[E0277]: the trait bound `u32: Yay` is not satisfied
-  --> $DIR/impl_trait_for_tait_bound.rs:10:14
+  --> $DIR/impl_trait_for_tait_bound.rs:11:14
    |
 LL |     is_yay::<u32>();
    |              ^^^ the trait `Yay` is not implemented for `u32`
    |
    = help: the trait `Yay` is implemented for `Foo`
 note: required by a bound in `is_yay`
-  --> $DIR/impl_trait_for_tait_bound.rs:16:14
+  --> $DIR/impl_trait_for_tait_bound.rs:17:14
    |
-LL | fn is_yay<T: Yay>() { }
+LL | fn is_yay<T: Yay>() {}
    |              ^^^ required by this bound in `is_yay`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs
index a4b8c2d190d..0a8dadb89e2 100644
--- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs
@@ -4,13 +4,14 @@ use std::fmt::Debug;
 
 type Foo = impl Debug;
 
-pub trait Yay { }
-impl Yay for u32 { }
+pub trait Yay {}
+impl Yay for u32 {}
 
+#[define_opaque(Foo)]
 fn foo() {
     is_yay::<Foo>(); //~ ERROR: the trait bound `Foo: Yay` is not satisfied
 }
 
-fn is_yay<T: Yay>() { }
+fn is_yay<T: Yay>() {}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr
index 2259aa7bb15..4fff9ad26cb 100644
--- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr
@@ -1,14 +1,14 @@
 error[E0277]: the trait bound `Foo: Yay` is not satisfied
-  --> $DIR/impl_trait_for_tait_bound2.rs:11:14
+  --> $DIR/impl_trait_for_tait_bound2.rs:12:14
    |
 LL |     is_yay::<Foo>();
    |              ^^^ the trait `Yay` is not implemented for `Foo`
    |
    = help: the trait `Yay` is implemented for `u32`
 note: required by a bound in `is_yay`
-  --> $DIR/impl_trait_for_tait_bound2.rs:14:14
+  --> $DIR/impl_trait_for_tait_bound2.rs:15:14
    |
-LL | fn is_yay<T: Yay>() { }
+LL | fn is_yay<T: Yay>() {}
    |              ^^^ required by this bound in `is_yay`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr
index 1d7a97c5367..a7e4ba29d3a 100644
--- a/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr
+++ b/tests/ui/type-alias-impl-trait/impl_trait_in_trait_defined_outside_trait.stderr
@@ -11,11 +11,6 @@ LL |         let x: Self::Assoc = 42;
    |
    = note: expected opaque type `<() as Trait>::Assoc`
                      found type `{integer}`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/impl_trait_in_trait_defined_outside_trait.rs:14:8
-   |
-LL |     fn foo() {
-   |        ^^^
 
 error[E0308]: mismatched types
   --> $DIR/impl_trait_in_trait_defined_outside_trait.rs:31:30
@@ -30,11 +25,6 @@ LL |         let x: Self::Assoc = 42;
    |
    = note: expected opaque type `<() as Trait2>::Assoc`
                      found type `{integer}`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/impl_trait_in_trait_defined_outside_trait.rs:30:11
-   |
-LL |     const FOO: () = {
-   |           ^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds.rs b/tests/ui/type-alias-impl-trait/implied_bounds.rs
index 269c0eff025..65d7234bd44 100644
--- a/tests/ui/type-alias-impl-trait/implied_bounds.rs
+++ b/tests/ui/type-alias-impl-trait/implied_bounds.rs
@@ -1,11 +1,8 @@
 #![feature(type_alias_impl_trait)]
 
-mod foo {
-    use super::Equals;
-    pub type WithLifetime<'a> = impl Equals<SelfType = ()>;
-    fn _defining_use<'a>() -> WithLifetime<'a> {}
-}
-use foo::WithLifetime;
+pub type WithLifetime<'a> = impl Equals<SelfType = ()>;
+#[define_opaque(WithLifetime)]
+fn _defining_use<'a>() -> WithLifetime<'a> {}
 
 trait Convert<'a> {
     type Witness;
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds.stderr b/tests/ui/type-alias-impl-trait/implied_bounds.stderr
index 23f1141e544..eda87bcbf90 100644
--- a/tests/ui/type-alias-impl-trait/implied_bounds.stderr
+++ b/tests/ui/type-alias-impl-trait/implied_bounds.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/implied_bounds.rs:21:9
+  --> $DIR/implied_bounds.rs:18:9
    |
 LL | impl<'a> Convert<'a> for () {
    |      -- lifetime `'a` defined here
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds2.rs b/tests/ui/type-alias-impl-trait/implied_bounds2.rs
index 845476ef974..0d829113ce7 100644
--- a/tests/ui/type-alias-impl-trait/implied_bounds2.rs
+++ b/tests/ui/type-alias-impl-trait/implied_bounds2.rs
@@ -2,12 +2,10 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod helper {
-    pub type Ty<'a, A> = impl Sized + 'a;
-    fn defining<'a, A>() -> Ty<'a, A> {}
-    pub fn assert_static<T: 'static>() {}
-}
-use helper::*;
+pub type Ty<'a, A> = impl Sized + 'a;
+#[define_opaque(Ty)]
+fn defining<'a, A>() -> Ty<'a, A> {}
+pub fn assert_static<T: 'static>() {}
 fn test<'a, A>()
 where
     Ty<'a, A>: 'static,
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs
index 76a63741e18..b6120cd4cc3 100644
--- a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs
+++ b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs
@@ -1,11 +1,8 @@
 #![feature(type_alias_impl_trait)]
 
-mod foo {
-    use super::Equals;
-    pub type WithLifetime<T> = impl Equals<SelfType = ()>;
-    fn _defining_use<T>() -> WithLifetime<T> {}
-}
-use foo::WithLifetime;
+pub type WithLifetime<T> = impl Equals<SelfType = ()>;
+#[define_opaque(WithLifetime)]
+fn _defining_use<T>() -> WithLifetime<T> {}
 
 trait Convert<'a> {
     type Witness;
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr
index 391a8a75786..887c8552d2f 100644
--- a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr
+++ b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/implied_bounds_from_types.rs:21:9
+  --> $DIR/implied_bounds_from_types.rs:18:9
    |
 LL | impl<'a> Convert<'a> for () {
    |      -- lifetime `'a` defined here
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr
index 49997b073c9..3bc6b9205ec 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Yay` for type `<() as HideIt>::Assoc`
-  --> $DIR/implied_lifetime_wf_check.rs:26:1
+  --> $DIR/implied_lifetime_wf_check.rs:27:1
    |
 LL | impl Yay for <() as HideIt>::Assoc {}
    | ---------------------------------- first implementation here
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs
index d85c7f60023..7950d6ad80c 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs
@@ -7,6 +7,7 @@
 
 type Alias = impl Sized;
 
+#[define_opaque(Alias)]
 fn constrain() -> Alias {
     1i32
 }
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 fb251e9bde1..889438d1b73 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
@@ -2,6 +2,7 @@
 
 mod test_lifetime_param {
     pub type Ty<'a> = impl Sized;
+    #[define_opaque(Ty)]
     fn defining(a: &str) -> Ty<'_> {
         a
     }
@@ -17,6 +18,7 @@ where
 
 mod test_higher_kinded_lifetime_param {
     pub type Ty<'a> = impl Sized + 'a;
+    #[define_opaque(Ty)]
     fn defining(a: &str) -> Ty<'_> {
         a
     }
@@ -40,6 +42,7 @@ mod test_higher_kinded_lifetime_param2 {
 
 mod test_type_param {
     pub type Ty<A> = impl Sized;
+    #[define_opaque(Ty)]
     fn defining<A>(s: A) -> Ty<A> {
         s
     }
@@ -54,13 +57,13 @@ where
 }
 
 mod test_implied_from_fn_sig {
-    mod foo {
-        pub type Opaque<T: 'static> = impl Sized;
-        fn defining<T: 'static>() -> Opaque<T> {}
-    }
+    pub type Opaque<T: 'static> = impl Sized;
+    #[define_opaque(Opaque)]
+    fn defining<T: 'static>() -> Opaque<T> {}
+
     fn assert_static<T: 'static>() {}
 
-    fn test<T>(_: foo::Opaque<T>) {
+    fn test<T>(_: Opaque<T>) {
         assert_static::<T>();
     }
 }
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
index c9af4bda572..7311f5882f7 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/implied_lifetime_wf_check3.rs:14:5
+  --> $DIR/implied_lifetime_wf_check3.rs:15:5
    |
 LL | fn test_lifetime_param_test<'a>()
    |                             -- lifetime `'a` defined here
@@ -8,7 +8,7 @@ LL |     test_lifetime_param::assert_static::<'a>()
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/implied_lifetime_wf_check3.rs:29:5
+  --> $DIR/implied_lifetime_wf_check3.rs:31:5
    |
 LL | fn test_higher_kinded_lifetime_param_test<'a>()
    |                                           -- lifetime `'a` defined here
@@ -17,7 +17,7 @@ LL |     test_higher_kinded_lifetime_param::assert_static::<'a>()
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/implied_lifetime_wf_check3.rs:36:9
+  --> $DIR/implied_lifetime_wf_check3.rs:38:9
    |
 LL |     fn test<'a>() {
    |             -- lifetime `'a` defined here
@@ -25,7 +25,7 @@ LL |         assert_static::<'a>()
    |         ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
 
 error[E0310]: the parameter type `A` may not live long enough
-  --> $DIR/implied_lifetime_wf_check3.rs:52:5
+  --> $DIR/implied_lifetime_wf_check3.rs:55:5
    |
 LL |     test_type_param::assert_static::<A>()
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs
index 7b2bbc99530..5484b91e6f1 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs
@@ -1,14 +1,12 @@
 #![feature(type_alias_impl_trait)]
 
-mod test_type_param_static {
-    pub type Ty<A> = impl Sized + 'static;
-    fn defining<A: 'static>(s: A) -> Ty<A> {
-        s
-        //~^ ERROR: the parameter type `A` may not live long enough
-    }
-    pub fn assert_static<A: 'static>() {}
+pub type Ty<A> = impl Sized + 'static;
+#[define_opaque(Ty)]
+fn defining<A: 'static>(s: A) -> Ty<A> {
+    s
+    //~^ ERROR: the parameter type `A` may not live long enough
 }
-use test_type_param_static::*;
+pub fn assert_static<A: 'static>() {}
 
 fn test<A>()
 where
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
index 060d68eb632..3cec4bbb099 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
@@ -1,24 +1,24 @@
 error[E0310]: the parameter type `A` may not live long enough
-  --> $DIR/implied_lifetime_wf_check4_static.rs:6:9
+  --> $DIR/implied_lifetime_wf_check4_static.rs:6:5
    |
-LL |         s
-   |         ^
-   |         |
-   |         the parameter type `A` must be valid for the static lifetime...
-   |         ...so that the type `A` will meet its required lifetime bounds...
+LL |     s
+   |     ^
+   |     |
+   |     the parameter type `A` must be valid for the static lifetime...
+   |     ...so that the type `A` will meet its required lifetime bounds...
    |
 note: ...that is required by this bound
-  --> $DIR/implied_lifetime_wf_check4_static.rs:4:35
+  --> $DIR/implied_lifetime_wf_check4_static.rs:3:31
    |
-LL |     pub type Ty<A> = impl Sized + 'static;
-   |                                   ^^^^^^^
+LL | pub type Ty<A> = impl Sized + 'static;
+   |                               ^^^^^^^
 help: consider adding an explicit lifetime bound
    |
-LL |     pub type Ty<A: 'static> = impl Sized + 'static;
-   |                  +++++++++
+LL | pub type Ty<A: 'static> = impl Sized + 'static;
+   |              +++++++++
 
 error[E0310]: the parameter type `A` may not live long enough
-  --> $DIR/implied_lifetime_wf_check4_static.rs:17:5
+  --> $DIR/implied_lifetime_wf_check4_static.rs:15:5
    |
 LL |     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 4a9f162823e..126fb66b9db 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
@@ -2,19 +2,17 @@
 
 #![feature(impl_trait_in_assoc_type, type_alias_impl_trait)]
 
-mod foo {
-    pub trait Callable {
-        type Output;
-        fn call() -> Self::Output;
-    }
+pub trait Callable {
+    type Output;
+    fn call() -> Self::Output;
+}
 
-    pub type OutputHelper = impl Sized;
-    impl<'a> Callable for &'a () {
-        type Output = OutputHelper;
-        fn call() -> Self::Output {}
-    }
+pub type OutputHelper = impl Sized;
+impl<'a> Callable for &'a () {
+    type Output = OutputHelper;
+    #[define_opaque(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/in-where-clause.rs b/tests/ui/type-alias-impl-trait/in-where-clause.rs
index 065af57a864..8d5bfc48a66 100644
--- a/tests/ui/type-alias-impl-trait/in-where-clause.rs
+++ b/tests/ui/type-alias-impl-trait/in-where-clause.rs
@@ -5,6 +5,7 @@
 type Bar = impl Sized;
 //~^ ERROR: cycle
 
+#[define_opaque(Bar)]
 fn foo() -> Bar
 where
     Bar: Send,
diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.stderr b/tests/ui/type-alias-impl-trait/in-where-clause.stderr
index 5ac09e20b02..114cac64573 100644
--- a/tests/ui/type-alias-impl-trait/in-where-clause.stderr
+++ b/tests/ui/type-alias-impl-trait/in-where-clause.stderr
@@ -1,12 +1,12 @@
 error[E0283]: type annotations needed: cannot satisfy `Bar: Send`
-  --> $DIR/in-where-clause.rs:12:9
+  --> $DIR/in-where-clause.rs:13:9
    |
 LL |     [0; 1 + 2]
    |         ^^^^^
    |
    = note: cannot satisfy `Bar: Send`
 note: required by a bound in `foo`
-  --> $DIR/in-where-clause.rs:10:10
+  --> $DIR/in-where-clause.rs:11:10
    |
 LL | fn foo() -> Bar
    |    --- required by a bound in this function
@@ -21,7 +21,7 @@ LL | type Bar = impl Sized;
    |            ^^^^^^^^^^
    |
 note: ...which requires type-checking `foo`...
-  --> $DIR/in-where-clause.rs:8:1
+  --> $DIR/in-where-clause.rs:9:1
    |
 LL | / fn foo() -> Bar
 LL | | where
diff --git a/tests/ui/type-alias-impl-trait/incomplete-inference.rs b/tests/ui/type-alias-impl-trait/incomplete-inference.rs
index 4c8bf2cfca1..70acb1870e2 100644
--- a/tests/ui/type-alias-impl-trait/incomplete-inference.rs
+++ b/tests/ui/type-alias-impl-trait/incomplete-inference.rs
@@ -2,11 +2,13 @@
 
 type Foo = impl Sized;
 
+#[define_opaque(Foo)]
 fn bar() -> Foo {
     None
     //~^ ERROR: type annotations needed [E0282]
 }
 
+#[define_opaque(Foo)]
 fn baz() -> Foo {
     Some(())
 }
diff --git a/tests/ui/type-alias-impl-trait/incomplete-inference.stderr b/tests/ui/type-alias-impl-trait/incomplete-inference.stderr
index 3976a43a89c..0b2bac0a153 100644
--- a/tests/ui/type-alias-impl-trait/incomplete-inference.stderr
+++ b/tests/ui/type-alias-impl-trait/incomplete-inference.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/incomplete-inference.rs:6:5
+  --> $DIR/incomplete-inference.rs:7:5
    |
 LL |     None
    |     ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
diff --git a/tests/ui/type-alias-impl-trait/inference-cycle.rs b/tests/ui/type-alias-impl-trait/inference-cycle.rs
index 6e4507ed460..951f177377a 100644
--- a/tests/ui/type-alias-impl-trait/inference-cycle.rs
+++ b/tests/ui/type-alias-impl-trait/inference-cycle.rs
@@ -1,24 +1,24 @@
 #![feature(type_alias_impl_trait)]
 #![allow(dead_code)]
 
-mod m {
-    pub type Foo = impl std::fmt::Debug;
+//@ check-pass
 
-    pub fn foo() -> Foo {
-        is_send(bar())
-    }
+pub type Foo = impl std::fmt::Debug;
 
-    pub fn bar() {
-        // Cycle: error today, but it'd be nice if it eventually worked
-        is_send(foo());
-        //~^ ERROR: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits
-    }
+#[define_opaque(Foo)]
+pub fn foo() -> Foo {
+    is_send(bar())
+}
 
-    fn baz() -> Foo {
-        ()
-    }
+pub fn bar() {
+    is_send(foo());
+}
 
-    fn is_send<T: Send>(_: T) {}
+#[define_opaque(Foo)]
+fn baz() -> Foo {
+    ()
 }
 
+fn is_send<T: Send>(_: T) {}
+
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/inference-cycle.stderr b/tests/ui/type-alias-impl-trait/inference-cycle.stderr
deleted file mode 100644
index 8b809ba014d..00000000000
--- a/tests/ui/type-alias-impl-trait/inference-cycle.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits
-  --> $DIR/inference-cycle.rs:13:17
-   |
-LL |         is_send(foo());
-   |         ------- ^^^^^
-   |         |
-   |         required by a bound introduced by this call
-   |
-   = note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
-note: opaque type is declared here
-  --> $DIR/inference-cycle.rs:5:20
-   |
-LL |     pub type Foo = impl std::fmt::Debug;
-   |                    ^^^^^^^^^^^^^^^^^^^^
-note: required by a bound in `is_send`
-  --> $DIR/inference-cycle.rs:21:19
-   |
-LL |     fn is_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `is_send`
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs
index 6609d4eb5a2..ef6871bec7c 100644
--- a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs
+++ b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs
@@ -3,6 +3,9 @@
 type T = impl Copy;
 //~^ ERROR cannot resolve opaque type
 
-static STATIC: T = None::<&'static T>;
+#[define_opaque(T)]
+fn foo() -> T {
+    None::<&'static T>
+}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs
index 93c52126d69..ae9712bd891 100644
--- a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs
+++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs
@@ -7,6 +7,7 @@ trait Foo {
 
 impl Foo for () {
     type Foo = impl std::fmt::Debug;
+    //~^ ERROR: unconstrained opaque type
     fn bar() {
         let x: Self::Foo = ();
         //~^ ERROR: mismatched types
diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr
index 169d8e41d20..82bd0025d6d 100644
--- a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr
+++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr
@@ -1,9 +1,17 @@
+error: unconstrained opaque type
+  --> $DIR/invalid_impl_trait_in_assoc_ty.rs:9:16
+   |
+LL |     type Foo = impl std::fmt::Debug;
+   |                ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Foo` must be used in combination with a concrete type within the same impl
+
 error[E0308]: mismatched types
-  --> $DIR/invalid_impl_trait_in_assoc_ty.rs:11:28
+  --> $DIR/invalid_impl_trait_in_assoc_ty.rs:12:28
    |
 LL |     type Foo = impl std::fmt::Debug;
    |                -------------------- the expected opaque type
-LL |     fn bar() {
+...
 LL |         let x: Self::Foo = ();
    |                ---------   ^^ expected opaque type, found `()`
    |                |
@@ -11,12 +19,7 @@ LL |         let x: Self::Foo = ();
    |
    = note: expected opaque type `<() as Foo>::Foo`
                 found unit type `()`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/invalid_impl_trait_in_assoc_ty.rs:10:8
-   |
-LL |     fn bar() {
-   |        ^^^
 
-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/type-alias-impl-trait/issue-101750.rs b/tests/ui/type-alias-impl-trait/issue-101750.rs
index 9367be8ca07..2f9304ce3bc 100644
--- a/tests/ui/type-alias-impl-trait/issue-101750.rs
+++ b/tests/ui/type-alias-impl-trait/issue-101750.rs
@@ -2,21 +2,18 @@
 
 //@ check-pass
 
-mod foo {
-    pub trait Trait {}
+pub trait Trait {}
 
-    pub type TAIT = impl Trait;
+pub type TAIT = impl Trait;
 
-    pub struct Concrete;
-    impl Trait for Concrete {}
+pub struct Concrete;
+impl Trait for Concrete {}
 
-    pub fn tait() -> TAIT {
-        Concrete
-    }
+#[define_opaque(TAIT)]
+pub fn tait() -> TAIT {
+    Concrete
 }
 
-use foo::*;
-
 trait OuterTrait {
     type Item;
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-104817.rs b/tests/ui/type-alias-impl-trait/issue-104817.rs
index 49146321614..13bbfa12a67 100644
--- a/tests/ui/type-alias-impl-trait/issue-104817.rs
+++ b/tests/ui/type-alias-impl-trait/issue-104817.rs
@@ -8,6 +8,7 @@
 trait OpaqueTrait {}
 impl<T> OpaqueTrait for T {}
 type OpaqueType = impl OpaqueTrait;
+#[define_opaque(OpaqueType)]
 fn mk_opaque() -> OpaqueType {
     || 0
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr
index df5a6c320a8..4f227310ee7 100644
--- a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `AnotherTrait`
-  --> $DIR/issue-104817.rs:16:1
+  --> $DIR/issue-104817.rs:17:1
    |
 LL | impl<T: Send> AnotherTrait for T {}
    | -------------------------------- first implementation here
diff --git a/tests/ui/type-alias-impl-trait/issue-109054.rs b/tests/ui/type-alias-impl-trait/issue-109054.rs
index d3eb6521593..0c9304a42f3 100644
--- a/tests/ui/type-alias-impl-trait/issue-109054.rs
+++ b/tests/ui/type-alias-impl-trait/issue-109054.rs
@@ -10,8 +10,10 @@ type FnType = impl Fn(&u32) -> ReturnType;
 impl std::ops::Deref for CallMe {
     type Target = FnType;
 
+    #[define_opaque(FnType)]
     fn deref(&self) -> &Self::Target {
         //~^ ERROR: item does not constrain `ReturnType
+        #[define_opaque(ReturnType)]
         fn inner(val: &u32) -> ReturnType {
             async move { *val * 2 }
         }
diff --git a/tests/ui/type-alias-impl-trait/issue-109054.stderr b/tests/ui/type-alias-impl-trait/issue-109054.stderr
index 2a4aa63bb8c..919b0a287c4 100644
--- a/tests/ui/type-alias-impl-trait/issue-109054.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-109054.stderr
@@ -1,18 +1,18 @@
-error: item does not constrain `ReturnType::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-109054.rs:13:8
+error: item does not constrain `ReturnType::{opaque#0}`
+  --> $DIR/issue-109054.rs:14:8
    |
 LL |     fn deref(&self) -> &Self::Target {
    |        ^^^^^
    |
-   = 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/issue-109054.rs:7:23
    |
 LL | type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/issue-109054.rs:19:9
+  --> $DIR/issue-109054.rs:21:9
    |
 LL | type ReturnType<'a> = impl std::future::Future<Output = u32> + 'a;
    |                 -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs b/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs
deleted file mode 100644
index 50eeff0b18f..00000000000
--- a/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Checks to ensure that we properly detect when a closure constrains an opaque type
-
-#![feature(type_alias_impl_trait)]
-
-use std::fmt::Debug;
-
-fn main() {
-    type Opaque = impl Debug;
-    fn _unused() -> Opaque { String::new() }
-    let null = || -> Opaque { 0 };
-    //~^ ERROR: concrete type differs from previous defining opaque type use
-    println!("{:?}", null());
-}
diff --git a/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr b/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr
deleted file mode 100644
index 4570ce8e41d..00000000000
--- a/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/issue-52843-closure-constrain.rs:10:31
-   |
-LL |     let null = || -> Opaque { 0 };
-   |                               ^ expected `String`, got `i32`
-   |
-note: previous use here
-  --> $DIR/issue-52843-closure-constrain.rs:9:30
-   |
-LL |     fn _unused() -> Opaque { String::new() }
-   |                              ^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/type-alias-impl-trait/issue-52843.rs b/tests/ui/type-alias-impl-trait/issue-52843.rs
index 159d3ccd27e..fd28eb8381d 100644
--- a/tests/ui/type-alias-impl-trait/issue-52843.rs
+++ b/tests/ui/type-alias-impl-trait/issue-52843.rs
@@ -3,6 +3,7 @@
 type Foo<T> = impl Default;
 
 #[allow(unused)]
+#[define_opaque(Foo)]
 fn foo<T: Default>(t: T) -> Foo<T> {
     t
     //~^ ERROR: the trait bound `T: Default` is not satisfied
diff --git a/tests/ui/type-alias-impl-trait/issue-52843.stderr b/tests/ui/type-alias-impl-trait/issue-52843.stderr
index 6673b03525d..ee2390d0945 100644
--- a/tests/ui/type-alias-impl-trait/issue-52843.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-52843.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `T: Default` is not satisfied
-  --> $DIR/issue-52843.rs:7:5
+  --> $DIR/issue-52843.rs:8:5
    |
 LL |     t
    |     ^ the trait `Default` is not implemented for `T`
@@ -10,7 +10,7 @@ note: required by a bound in an opaque type
 LL | type Foo<T> = impl Default;
    |                    ^^^^^^^
 note: this definition site has more where clauses than the opaque type
-  --> $DIR/issue-52843.rs:6:1
+  --> $DIR/issue-52843.rs:7:1
    |
 LL | fn foo<T: Default>(t: T) -> Foo<T> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.rs b/tests/ui/type-alias-impl-trait/issue-53092-2.rs
index 43df49adc42..5f44a9aa2df 100644
--- a/tests/ui/type-alias-impl-trait/issue-53092-2.rs
+++ b/tests/ui/type-alias-impl-trait/issue-53092-2.rs
@@ -2,15 +2,14 @@
 #![allow(dead_code)]
 
 type Bug<T, U> = impl Fn(T) -> U + Copy;
-//~^ ERROR cycle detected
 
+#[define_opaque(Bug)]
+//~^ ERROR: only functions and methods can define opaque types
 const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
-//~^ ERROR item does not constrain `Bug::{opaque#0}`, but has it in its signature
-//~| ERROR item does not constrain `Bug::{opaque#0}`, but has it in its signature
-//~| ERROR non-defining opaque type use in defining scope
 
+#[define_opaque(Bug)]
 fn make_bug<T, U: From<T>>() -> Bug<T, U> {
-    |x| x.into()
+    |x| x.into() //~ ERROR is not satisfied
 }
 
 fn main() {
diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
index 678b0c84f78..5739662ff80 100644
--- a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
@@ -1,68 +1,25 @@
-error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/issue-53092-2.rs:7:18
+error: only functions and methods can define opaque types
+  --> $DIR/issue-53092-2.rs:6:1
    |
-LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
-   |                  ^^^^^^^^^^^ argument `u8` is not a generic parameter
-   |
-note: for this opaque type
-  --> $DIR/issue-53092-2.rs:4:18
-   |
-LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
+LL | #[define_opaque(Bug)]
+   | ^^^^^^^^^^^^^^^^^^^^^
 
-error[E0391]: cycle detected when computing type of `Bug::{opaque#0}`
-  --> $DIR/issue-53092-2.rs:4:18
-   |
-LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires computing type of opaque `Bug::{opaque#0}`...
-  --> $DIR/issue-53092-2.rs:4:18
-   |
-LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires type-checking `CONST_BUG`...
-  --> $DIR/issue-53092-2.rs:7:1
-   |
-LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which requires computing layout of `Bug<u8, ()>`...
-   = note: ...which requires normalizing `Bug<u8, ()>`...
-   = note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle
-note: cycle used when checking that `Bug::{opaque#0}` is well-formed
-  --> $DIR/issue-53092-2.rs:4:18
+error[E0277]: the trait bound `U: From<T>` is not satisfied
+  --> $DIR/issue-53092-2.rs:12:5
    |
-LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error: item does not constrain `Bug::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-53092-2.rs:7:7
-   |
-LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
-   |       ^^^^^^^^^
-   |
-   = 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-53092-2.rs:4:18
-   |
-LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
-
-error: item does not constrain `Bug::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-53092-2.rs:7:61
+LL |     |x| x.into()
+   |     ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
    |
-LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
-   |                                                             ^^^^^^^
+note: required by a bound in `make_bug`
+  --> $DIR/issue-53092-2.rs:11:19
    |
-   = 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-53092-2.rs:4:18
+LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
+   |                   ^^^^^^^ required by this bound in `make_bug`
+help: consider restricting type parameter `U` with trait `From`
    |
-LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
+LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
+   |              +++++++++++++++++++++++
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0391, E0792.
-For more information about an error, try `rustc --explain E0391`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/issue-53092.rs b/tests/ui/type-alias-impl-trait/issue-53092.rs
index 83b51227aaa..a2e6ddc11b6 100644
--- a/tests/ui/type-alias-impl-trait/issue-53092.rs
+++ b/tests/ui/type-alias-impl-trait/issue-53092.rs
@@ -1,14 +1,13 @@
 #![feature(type_alias_impl_trait)]
 #![allow(dead_code)]
 
-mod bug {
-    pub type Bug<T, U> = impl Fn(T) -> U + Copy;
+pub type Bug<T, U> = impl Fn(T) -> U + Copy;
 
-    fn make_bug<T, U: From<T>>() -> Bug<T, U> {
-        |x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied
-    }
+#[define_opaque(Bug)]
+fn make_bug<T, U: From<T>>() -> Bug<T, U> {
+    |x| x.into()
+    //~^ ERROR the trait bound `U: From<T>` is not satisfied
 }
-use bug::Bug;
 
 union Moo {
     x: Bug<u8, ()>,
diff --git a/tests/ui/type-alias-impl-trait/issue-53092.stderr b/tests/ui/type-alias-impl-trait/issue-53092.stderr
index 579902aa3ab..a8554b9a989 100644
--- a/tests/ui/type-alias-impl-trait/issue-53092.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-53092.stderr
@@ -1,18 +1,18 @@
 error[E0277]: the trait bound `U: From<T>` is not satisfied
-  --> $DIR/issue-53092.rs:8:9
+  --> $DIR/issue-53092.rs:8:5
    |
-LL |         |x| x.into()
-   |         ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
+LL |     |x| x.into()
+   |     ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
    |
 note: required by a bound in `make_bug`
-  --> $DIR/issue-53092.rs:7:23
+  --> $DIR/issue-53092.rs:7:19
    |
-LL |     fn make_bug<T, U: From<T>>() -> Bug<T, U> {
-   |                       ^^^^^^^ required by this bound in `make_bug`
+LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
+   |                   ^^^^^^^ required by this bound in `make_bug`
 help: consider restricting type parameter `U` with trait `From`
    |
-LL |     pub type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
-   |                      +++++++++++++++++++++++
+LL | pub type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
+   |                  +++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/issue-53096.rs b/tests/ui/type-alias-impl-trait/issue-53096.rs
index 590fce84fc9..c24f1bf44fa 100644
--- a/tests/ui/type-alias-impl-trait/issue-53096.rs
+++ b/tests/ui/type-alias-impl-trait/issue-53096.rs
@@ -1,13 +1,11 @@
 #![feature(rustc_attrs)]
 #![feature(type_alias_impl_trait)]
 
-mod foo {
-    pub type Foo = impl Fn() -> usize;
-    pub const fn bar() -> Foo {
-        || 0usize
-    }
+pub type Foo = impl Fn() -> usize;
+#[define_opaque(Foo)]
+pub const fn bar() -> Foo {
+    || 0usize
 }
-use foo::*;
 const BAZR: Foo = bar();
 
 #[rustc_error]
diff --git a/tests/ui/type-alias-impl-trait/issue-53096.stderr b/tests/ui/type-alias-impl-trait/issue-53096.stderr
index 0a744e7be9c..53490896af7 100644
--- a/tests/ui/type-alias-impl-trait/issue-53096.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-53096.stderr
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/issue-53096.rs:14:1
+  --> $DIR/issue-53096.rs:12:1
    |
 LL | fn main() {}
    | ^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs b/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs
index 0d9126d3993..f02ccbbb93c 100644
--- a/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs
+++ b/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs
@@ -3,21 +3,20 @@
 
 //@ check-pass
 
-mod gen {
-    use std::ops::Coroutine;
+use std::ops::Coroutine;
 
-    pub type CoroOnce<Y, R> = impl Coroutine<Yield = Y, Return = R>;
+pub type CoroOnce<Y, R> = impl Coroutine<Yield = Y, Return = R>;
 
-    pub const fn const_coroutine<Y, R>(yielding: Y, returning: R) -> CoroOnce<Y, R> {
-        #[coroutine]
-        move || {
-            yield yielding;
+#[define_opaque(CoroOnce)]
+pub const fn const_coroutine<Y, R>(yielding: Y, returning: R) -> CoroOnce<Y, R> {
+    #[coroutine]
+    move || {
+        yield yielding;
 
-            return returning;
-        }
+        return returning;
     }
 }
 
-const FOO: gen::CoroOnce<usize, usize> = gen::const_coroutine(10, 100);
+const FOO: CoroOnce<usize, usize> = const_coroutine(10, 100);
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs b/tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs
index e54dd01122e..a3c37759ac0 100644
--- a/tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs
+++ b/tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs
@@ -18,6 +18,7 @@ struct Foo<'a> {
 type F = impl Future;
 
 impl<'a> Foo<'a> {
+    #[define_opaque(F)]
     fn reply(&mut self) -> F {
         AndThen(|| ())
     }
diff --git a/tests/ui/type-alias-impl-trait/issue-57961.rs b/tests/ui/type-alias-impl-trait/issue-57961.rs
index 61af7a0f625..0b39e21d8b7 100644
--- a/tests/ui/type-alias-impl-trait/issue-57961.rs
+++ b/tests/ui/type-alias-impl-trait/issue-57961.rs
@@ -11,6 +11,7 @@ impl Foo for () {
     //~^ ERROR expected `IntoIter<u32>` to be an iterator that yields `X`, but it yields `u32`
 }
 
+#[define_opaque(X)]
 fn incoherent() -> X {
     22_i32
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs b/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs
index 899e81ed562..c2a9f153815 100644
--- a/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs
+++ b/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs
@@ -7,6 +7,7 @@ use std::ops::{Coroutine, CoroutineState};
 use std::pin::Pin;
 
 type RandCoroutine<'a> = impl Coroutine<Return = (), Yield = u64> + 'a;
+#[define_opaque(RandCoroutine)]
 fn rand_coroutine<'a>(rng: &'a ()) -> RandCoroutine<'a> {
     #[coroutine]
     move || {
@@ -18,6 +19,7 @@ fn rand_coroutine<'a>(rng: &'a ()) -> RandCoroutine<'a> {
 }
 
 pub type RandCoroutineWithIndirection<'c> = impl Coroutine<Return = (), Yield = u64> + 'c;
+#[define_opaque(RandCoroutineWithIndirection)]
 pub fn rand_coroutine_with_indirection<'a>(rng: &'a ()) -> RandCoroutineWithIndirection<'a> {
     fn helper<'b>(rng: &'b ()) -> impl 'b + Coroutine<Return = (), Yield = u64> {
         #[coroutine]
diff --git a/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs b/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs
index 9d74c0687fe..aef13947f55 100644
--- a/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs
+++ b/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs
@@ -8,6 +8,8 @@ trait Trait {}
 impl<T> Trait for T {}
 
 type Foo<'c> = impl Trait + 'c;
+
+#[define_opaque(Foo)]
 fn foo<'a>(rng: &'a ()) -> Foo<'a> {
     fn helper<'b>(rng: &'b ()) -> impl 'b + Trait {
         rng
@@ -16,5 +18,4 @@ fn foo<'a>(rng: &'a ()) -> Foo<'a> {
     helper(rng)
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-58951-2.rs b/tests/ui/type-alias-impl-trait/issue-58951-2.rs
index fb92b127436..de6b9e74119 100644
--- a/tests/ui/type-alias-impl-trait/issue-58951-2.rs
+++ b/tests/ui/type-alias-impl-trait/issue-58951-2.rs
@@ -2,14 +2,12 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod defining_use_scope {
-    pub type A = impl Iterator;
+pub type A = impl Iterator;
 
-    pub fn def_a() -> A {
-        0..1
-    }
+#[define_opaque(A)]
+pub fn def_a() -> A {
+    0..1
 }
-use defining_use_scope::*;
 
 pub fn use_a() {
     def_a().map(|x| x);
diff --git a/tests/ui/type-alias-impl-trait/issue-58951.rs b/tests/ui/type-alias-impl-trait/issue-58951.rs
index b9f27b031c7..de6b9e74119 100644
--- a/tests/ui/type-alias-impl-trait/issue-58951.rs
+++ b/tests/ui/type-alias-impl-trait/issue-58951.rs
@@ -2,16 +2,15 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod helper {
-    pub type A = impl Iterator;
+pub type A = impl Iterator;
 
-    pub fn def_a() -> A {
-        0..1
-    }
+#[define_opaque(A)]
+pub fn def_a() -> A {
+    0..1
 }
 
 pub fn use_a() {
-    helper::def_a().map(|x| x);
+    def_a().map(|x| x);
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-60407.rs b/tests/ui/type-alias-impl-trait/issue-60407.rs
index 6c7c76b5ac7..5b8ff6b74de 100644
--- a/tests/ui/type-alias-impl-trait/issue-60407.rs
+++ b/tests/ui/type-alias-impl-trait/issue-60407.rs
@@ -1,13 +1,11 @@
 #![feature(type_alias_impl_trait, rustc_attrs)]
 
-mod bar {
-    pub type Debuggable = impl core::fmt::Debug;
+pub type Debuggable = impl core::fmt::Debug;
 
-    pub fn foo() -> Debuggable {
-        0u32
-    }
+#[define_opaque(Debuggable)]
+pub fn foo() -> Debuggable {
+    0u32
 }
-use bar::*;
 
 static mut TEST: Option<Debuggable> = None;
 
diff --git a/tests/ui/type-alias-impl-trait/issue-60407.stderr b/tests/ui/type-alias-impl-trait/issue-60407.stderr
index bba9092e977..f517d5b65fa 100644
--- a/tests/ui/type-alias-impl-trait/issue-60407.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-60407.stderr
@@ -1,5 +1,5 @@
 error: fatal error triggered by #[rustc_error]
-  --> $DIR/issue-60407.rs:15:1
+  --> $DIR/issue-60407.rs:13:1
    |
 LL | fn main() {
    | ^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/issue-60564.rs b/tests/ui/type-alias-impl-trait/issue-60564.rs
index 48bd70bcca9..f28258b3b22 100644
--- a/tests/ui/type-alias-impl-trait/issue-60564.rs
+++ b/tests/ui/type-alias-impl-trait/issue-60564.rs
@@ -16,8 +16,8 @@ where
     E: std::fmt::Debug,
 {
     type BitsIter = IterBitsIter<T, E, u8>;
+    #[define_opaque(IterBitsIter)]
     fn iter_bits(self, n: u8) -> Self::BitsIter {
-        //~^ ERROR non-defining opaque type use
         (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
         //~^ ERROR expected generic type parameter, found `u8`
     }
diff --git a/tests/ui/type-alias-impl-trait/issue-60564.stderr b/tests/ui/type-alias-impl-trait/issue-60564.stderr
index d42495e934d..6aaed7d4296 100644
--- a/tests/ui/type-alias-impl-trait/issue-60564.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-60564.stderr
@@ -1,15 +1,3 @@
-error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/issue-60564.rs:19:34
-   |
-LL |     fn iter_bits(self, n: u8) -> Self::BitsIter {
-   |                                  ^^^^^^^^^^^^^^ argument `u8` is not a generic parameter
-   |
-note: for this opaque type
-  --> $DIR/issue-60564.rs:8:30
-   |
-LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0792]: expected generic type parameter, found `u8`
   --> $DIR/issue-60564.rs:21:9
    |
@@ -19,6 +7,6 @@ LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
 LL |         (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs b/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs
index 38abc3ec7e8..6de026a26d5 100644
--- a/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs
+++ b/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs
@@ -8,6 +8,7 @@
 
 pub type Closure = impl FnOnce();
 
+#[define_opaque(Closure)]
 fn bop() -> Closure {
     || -> Closure { || () };
     panic!()
diff --git a/tests/ui/type-alias-impl-trait/issue-63279.rs b/tests/ui/type-alias-impl-trait/issue-63279.rs
index 02f2111468a..10da40d2f90 100644
--- a/tests/ui/type-alias-impl-trait/issue-63279.rs
+++ b/tests/ui/type-alias-impl-trait/issue-63279.rs
@@ -2,6 +2,7 @@
 
 type Closure = impl FnOnce();
 
+#[define_opaque(Closure)]
 fn c() -> Closure {
     //~^ ERROR: expected a `FnOnce()` closure, found `()`
     || -> Closure { || () }
diff --git a/tests/ui/type-alias-impl-trait/issue-63279.stderr b/tests/ui/type-alias-impl-trait/issue-63279.stderr
index 97158ee297d..8f0e9c5fde0 100644
--- a/tests/ui/type-alias-impl-trait/issue-63279.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-63279.stderr
@@ -1,5 +1,5 @@
 error[E0277]: expected a `FnOnce()` closure, found `()`
-  --> $DIR/issue-63279.rs:5:11
+  --> $DIR/issue-63279.rs:6:11
    |
 LL | fn c() -> Closure {
    |           ^^^^^^^ expected an `FnOnce()` closure, found `()`
@@ -8,7 +8,7 @@ LL | fn c() -> Closure {
    = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
 
 error[E0277]: expected a `FnOnce()` closure, found `()`
-  --> $DIR/issue-63279.rs:7:11
+  --> $DIR/issue-63279.rs:8:11
    |
 LL |     || -> Closure { || () }
    |           ^^^^^^^ expected an `FnOnce()` closure, found `()`
@@ -17,26 +17,26 @@ LL |     || -> Closure { || () }
    = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-63279.rs:7:21
+  --> $DIR/issue-63279.rs:8:21
    |
 LL |     || -> Closure { || () }
    |                     ^^^^^ expected `()`, found closure
    |
    = note: expected unit type `()`
-                found closure `{closure@$DIR/issue-63279.rs:7:21: 7:23}`
+                found closure `{closure@$DIR/issue-63279.rs:8:21: 8:23}`
 help: use parentheses to call this closure
    |
 LL |     || -> Closure { (|| ())() }
    |                     +     +++
 
 error[E0308]: mismatched types
-  --> $DIR/issue-63279.rs:7:5
+  --> $DIR/issue-63279.rs:8:5
    |
 LL |     || -> Closure { || () }
    |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure
    |
    = note: expected unit type `()`
-                found closure `{closure@$DIR/issue-63279.rs:7:5: 7:18}`
+                found closure `{closure@$DIR/issue-63279.rs:8:5: 8:18}`
 help: use parentheses to call this closure
    |
 LL |     (|| -> Closure { || () })()
diff --git a/tests/ui/type-alias-impl-trait/issue-63355.rs b/tests/ui/type-alias-impl-trait/issue-63355.rs
index a0d0355b5af..0b29bfeb98f 100644
--- a/tests/ui/type-alias-impl-trait/issue-63355.rs
+++ b/tests/ui/type-alias-impl-trait/issue-63355.rs
@@ -21,6 +21,7 @@ impl Foo for () {}
 impl Bar for () {
     type Foo = FooImpl;
 
+    #[define_opaque(FooImpl)]
     fn foo() -> Self::Foo {
         ()
     }
@@ -33,10 +34,12 @@ impl Baz for () {
     type Foo = FooImpl;
     type Bar = BarImpl;
 
+    #[define_opaque(FooImpl)]
     fn foo() -> Self::Foo {
         ()
     }
 
+    #[define_opaque(BarImpl)]
     fn bar() -> Self::Bar {
         //~^ ERROR: item does not constrain `FooImpl::{opaque#0}`
         ()
diff --git a/tests/ui/type-alias-impl-trait/issue-63355.stderr b/tests/ui/type-alias-impl-trait/issue-63355.stderr
index 6755c038056..cb1ef0ce41d 100644
--- a/tests/ui/type-alias-impl-trait/issue-63355.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-63355.stderr
@@ -1,12 +1,12 @@
-error: item does not constrain `FooImpl::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-63355.rs:40:8
+error: item does not constrain `FooImpl::{opaque#0}`
+  --> $DIR/issue-63355.rs:43:8
    |
 LL |     fn bar() -> Self::Bar {
    |        ^^^
    |
-   = 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-63355.rs:29:20
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/issue-63355.rs:30:20
    |
 LL | pub type FooImpl = impl Foo;
    |                    ^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs b/tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs
index 51f95637969..5ea73965701 100644
--- a/tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs
+++ b/tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs
@@ -16,6 +16,9 @@ impl<T> Trait for S1<T> {}
 impl<T: Trait> S2<T> {}
 impl T3 {}
 
-pub fn use_t1() -> T1 { S1(()) }
+#[define_opaque(T1)]
+pub fn use_t1() -> T1 {
+    S1(())
+}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-65384.rs b/tests/ui/type-alias-impl-trait/issue-65384.rs
index 44ca5cb94b0..86bbc93c8bd 100644
--- a/tests/ui/type-alias-impl-trait/issue-65384.rs
+++ b/tests/ui/type-alias-impl-trait/issue-65384.rs
@@ -9,6 +9,7 @@ type Bar = impl MyTrait;
 impl MyTrait for Bar {}
 //~^ ERROR: conflicting implementations of trait `MyTrait` for type `()`
 
-fn bazr() -> Bar { }
+#[define_opaque(Bar)]
+fn bazr() -> Bar {}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
index f98ce4a426c..6fc3aa8ce7e 100644
--- a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
+++ b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
@@ -1,20 +1,19 @@
 //@ check-pass
 
 #![feature(type_alias_impl_trait, rustc_attrs)]
-mod foo {
-    pub type T = impl Sized;
-    // The concrete type referred by impl-trait-type-alias(`T`) is guaranteed
-    // to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive;
-    // so difference assertion should not be declared on impl-trait-type-alias's instances.
-    // for details, check RFC-2515:
-    // https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md
 
-    fn bop(_: T) {
-        super::take(|| {});
-        super::take(|| {});
-    }
+pub type T = impl Sized;
+// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed
+// to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive;
+// so difference assertion should not be declared on impl-trait-type-alias's instances.
+// for details, check RFC-2515:
+// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md
+
+#[define_opaque(T)]
+fn bop() {
+    take(|| {});
+    take(|| {});
 }
-use foo::*;
 
 fn take(_: fn() -> T) {}
 
diff --git a/tests/ui/type-alias-impl-trait/issue-65918.rs b/tests/ui/type-alias-impl-trait/issue-65918.rs
index 275b9717cef..00dab6f2744 100644
--- a/tests/ui/type-alias-impl-trait/issue-65918.rs
+++ b/tests/ui/type-alias-impl-trait/issue-65918.rs
@@ -15,13 +15,11 @@ trait MyFrom<T>: Sized {
 }
 
 /* MCVE starts here */
-mod f {
-    pub trait F {}
-    impl F for () {}
-    pub type DummyT<T> = impl F;
-    fn _dummy_t<T>() -> DummyT<T> {}
-}
-use f::DummyT;
+pub trait F {}
+impl F for () {}
+pub type DummyT<T> = impl F;
+#[define_opaque(DummyT)]
+fn _dummy_t<T>() -> DummyT<T> {}
 
 struct Phantom1<T>(PhantomData<T>);
 struct Phantom2<T>(PhantomData<T>);
diff --git a/tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs b/tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs
index 0e3d01c2d61..009dc31ba26 100644
--- a/tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs
+++ b/tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs
@@ -6,6 +6,7 @@
 
 type Closure = impl FnOnce();
 
+#[define_opaque(Closure)]
 fn closure() -> Closure {
     || {}
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs b/tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs
index c320b0db31b..2d38b3030be 100644
--- a/tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs
+++ b/tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs
@@ -22,6 +22,7 @@ impl WithAssoc for MyStruct {
     type AssocType = MyParam;
 }
 
+#[define_opaque(Return)]
 fn my_fun<A>() -> Return<A> {
     MyStruct
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs
index 9dcdb578568..205d4832b0a 100644
--- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs
+++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs
@@ -6,9 +6,9 @@
 trait Trait<T> {}
 type Alias<'a, U> = impl Trait<U>;
 
+#[define_opaque(Alias)]
 fn f<'a>() -> Alias<'a, ()> {}
-//~^ ERROR non-defining opaque type use
-//~| ERROR expected generic type parameter, found `()`
+//~^ ERROR expected generic type parameter, found `()`
 
 fn main() {}
 
diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
index 085bffe907b..178aa5cf345 100644
--- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
@@ -1,24 +1,12 @@
-error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/issue-68368-non-defining-use-2.rs:9:15
-   |
-LL | fn f<'a>() -> Alias<'a, ()> {}
-   |               ^^^^^^^^^^^^^ argument `()` is not a generic parameter
-   |
-note: for this opaque type
-  --> $DIR/issue-68368-non-defining-use-2.rs:7:21
-   |
-LL | type Alias<'a, U> = impl Trait<U>;
-   |                     ^^^^^^^^^^^^^
-
 error[E0792]: expected generic type parameter, found `()`
-  --> $DIR/issue-68368-non-defining-use-2.rs:9:29
+  --> $DIR/issue-68368-non-defining-use-2.rs:10:29
    |
 LL | type Alias<'a, U> = impl Trait<U>;
    |                - this generic parameter must be used with a generic type parameter
-LL |
+...
 LL | fn f<'a>() -> Alias<'a, ()> {}
    |                             ^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
index dfe2ee8204c..f3fa4fea746 100644
--- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
+++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
@@ -6,9 +6,9 @@
 trait Trait<T> {}
 type Alias<'a, U> = impl Trait<U>;
 
+#[define_opaque(Alias)]
 fn f<'a>() -> Alias<'a, ()> {}
 //~^ ERROR expected generic type parameter, found `()`
-//~| ERROR non-defining opaque type use
 
 fn main() {}
 
diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
index ea704ffff97..bfbd506a7a5 100644
--- a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
@@ -1,24 +1,12 @@
-error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/issue-68368-non-defining-use.rs:9:15
-   |
-LL | fn f<'a>() -> Alias<'a, ()> {}
-   |               ^^^^^^^^^^^^^ argument `()` is not a generic parameter
-   |
-note: for this opaque type
-  --> $DIR/issue-68368-non-defining-use.rs:7:21
-   |
-LL | type Alias<'a, U> = impl Trait<U>;
-   |                     ^^^^^^^^^^^^^
-
 error[E0792]: expected generic type parameter, found `()`
-  --> $DIR/issue-68368-non-defining-use.rs:9:29
+  --> $DIR/issue-68368-non-defining-use.rs:10:29
    |
 LL | type Alias<'a, U> = impl Trait<U>;
    |                - this generic parameter must be used with a generic type parameter
-LL |
+...
 LL | fn f<'a>() -> Alias<'a, ()> {}
    |                             ^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs
index a0f8e48e268..f9a68a1b0b3 100644
--- a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs
+++ b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs
@@ -19,6 +19,7 @@ impl<T> WithAssoc<T> for () {
 type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
 //~^ ERROR use of undeclared lifetime name `'a`
 
+#[define_opaque(Return)]
 fn my_fun<T>() -> Return<T> {}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs
index 8e631fd1b6a..f62260bd3f0 100644
--- a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs
+++ b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs
@@ -18,6 +18,7 @@ impl WithAssoc for () {
 
 type Return<'a> = impl WithAssoc<AssocType = impl Sized + 'a>;
 
+#[define_opaque(Return)]
 fn my_fun<'a>() -> Return<'a> {}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-69323.rs b/tests/ui/type-alias-impl-trait/issue-69323.rs
index 18bc4cf9178..af536186f72 100644
--- a/tests/ui/type-alias-impl-trait/issue-69323.rs
+++ b/tests/ui/type-alias-impl-trait/issue-69323.rs
@@ -9,6 +9,7 @@ fn test1<A: Iterator<Item = &'static str>>(x: A) -> Chain<A, impl Iterator<Item
 }
 
 type I<A> = Chain<A, impl Iterator<Item = &'static str>>;
+#[define_opaque(I)]
 fn test2<A: Iterator<Item = &'static str>>(x: A) -> I<A> {
     x.chain(once(","))
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-70121.rs b/tests/ui/type-alias-impl-trait/issue-70121.rs
index b90bd312a0b..5aec99a1c37 100644
--- a/tests/ui/type-alias-impl-trait/issue-70121.rs
+++ b/tests/ui/type-alias-impl-trait/issue-70121.rs
@@ -2,6 +2,7 @@
 
 pub type Successors<'a> = impl Iterator<Item = &'a ()>;
 
+#[define_opaque(Successors)]
 pub fn f<'a>() -> Successors<'a> {
     None.into_iter()
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-70121.stderr b/tests/ui/type-alias-impl-trait/issue-70121.stderr
index ed2eb17fbea..8388998956f 100644
--- a/tests/ui/type-alias-impl-trait/issue-70121.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-70121.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-70121.rs:18:5
+  --> $DIR/issue-70121.rs:19:5
    |
 LL | pub type Successors<'a> = impl Iterator<Item = &'a ()>;
    |                           ---------------------------- the expected opaque type
@@ -11,8 +11,8 @@ LL |     None.into_iter()
    |
    = note: expected opaque type `Successors<'a>`
                    found struct `std::option::IntoIter<_>`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/issue-70121.rs:17:8
+note: this item must have a `#[define_opaque(Successors)]` attribute to be able to define hidden types
+  --> $DIR/issue-70121.rs:18:8
    |
 LL | pub fn kazusa<'a>() -> <&'a () as Tr>::Item {
    |        ^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/issue-72793.rs b/tests/ui/type-alias-impl-trait/issue-72793.rs
index 0353b7f3787..a51d7f5634a 100644
--- a/tests/ui/type-alias-impl-trait/issue-72793.rs
+++ b/tests/ui/type-alias-impl-trait/issue-72793.rs
@@ -3,24 +3,21 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod foo {
-    pub trait T {
-        type Item;
-    }
-
-    pub type Alias<'a> = impl T<Item = &'a ()>;
+pub trait T {
+    type Item;
+}
 
-    struct S;
-    impl<'a> T for &'a S {
-        type Item = &'a ();
-    }
+pub type Alias<'a> = impl T<Item = &'a ()>;
 
-    pub fn filter_positive<'a>() -> Alias<'a> {
-        &S
-    }
+struct S;
+impl<'a> T for &'a S {
+    type Item = &'a ();
 }
 
-use foo::*;
+#[define_opaque(Alias)]
+pub fn filter_positive<'a>() -> Alias<'a> {
+    &S
+}
 
 fn with_positive(fun: impl Fn(Alias<'_>)) {
     fun(filter_positive());
diff --git a/tests/ui/type-alias-impl-trait/issue-74244.rs b/tests/ui/type-alias-impl-trait/issue-74244.rs
index bb4104b3d25..60b1bee9ff6 100644
--- a/tests/ui/type-alias-impl-trait/issue-74244.rs
+++ b/tests/ui/type-alias-impl-trait/issue-74244.rs
@@ -13,6 +13,7 @@ impl<T> Allocator for DefaultAllocator {
 
 type A = impl Fn(<DefaultAllocator as Allocator>::Buffer);
 
+#[define_opaque(A)]
 fn foo() -> A {
     |_| ()
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-74280.rs b/tests/ui/type-alias-impl-trait/issue-74280.rs
index ad641eaa00d..c8dc1adec41 100644
--- a/tests/ui/type-alias-impl-trait/issue-74280.rs
+++ b/tests/ui/type-alias-impl-trait/issue-74280.rs
@@ -4,6 +4,7 @@
 
 type Test = impl Copy;
 
+#[define_opaque(Test)]
 fn test() -> Test {
     let y = || -> Test { () };
     7 //~ ERROR mismatched types
diff --git a/tests/ui/type-alias-impl-trait/issue-74280.stderr b/tests/ui/type-alias-impl-trait/issue-74280.stderr
index c09efbe4e13..a89a3f77b3d 100644
--- a/tests/ui/type-alias-impl-trait/issue-74280.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-74280.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-74280.rs:9:5
+  --> $DIR/issue-74280.rs:10:5
    |
 LL | fn test() -> Test {
    |              ---- expected `()` because of return type
diff --git a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
index 90ab4fd8d97..3e17126834c 100644
--- a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
+++ b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
@@ -7,19 +7,17 @@
 //@ check-pass
 #![feature(type_alias_impl_trait)]
 
-mod g {
-    pub trait Dummy {}
-    impl Dummy for () {}
-    pub type F = impl Dummy;
-    pub fn f() -> F {}
-}
-use g::*;
+pub trait Dummy {}
+impl Dummy for () {}
+pub type F = impl Dummy;
+#[define_opaque(F)]
+pub fn f() -> F {}
 
 trait Test {
     fn test(self);
 }
 
-impl Test for define::F {
+impl Test for F {
     fn test(self) {}
 }
 
@@ -29,17 +27,14 @@ impl Test for i32 {
     fn test(self) {}
 }
 
-mod define {
-    use super::*;
-
-    pub trait Dummy {}
-    impl Dummy for () {}
+pub trait Dummy2 {}
+impl Dummy2 for () {}
 
-    pub type F = impl Dummy;
-    pub fn f() -> F {}
-}
+pub type F2 = impl Dummy2;
+#[define_opaque(F2)]
+pub fn f2() -> F2 {}
 
 fn main() {
-    let x = define::f();
+    let x = f();
     x.test();
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-77179.rs b/tests/ui/type-alias-impl-trait/issue-77179.rs
index 1dc74c6b5fe..18afc54dbdc 100644
--- a/tests/ui/type-alias-impl-trait/issue-77179.rs
+++ b/tests/ui/type-alias-impl-trait/issue-77179.rs
@@ -4,10 +4,11 @@
 
 type Pointer<T> = impl std::ops::Deref<Target = T>;
 
+#[define_opaque(Pointer)]
 fn test() -> Pointer<_> {
     //~^ ERROR: the placeholder `_` is not allowed within types
     Box::new(1)
-    //~^ ERROR: mismatched types
+    //~^ ERROR: expected generic type parameter, found `i32`
 }
 
 fn main() {
diff --git a/tests/ui/type-alias-impl-trait/issue-77179.stderr b/tests/ui/type-alias-impl-trait/issue-77179.stderr
index 16bbc996d90..bc11283f328 100644
--- a/tests/ui/type-alias-impl-trait/issue-77179.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-77179.stderr
@@ -1,36 +1,28 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-77179.rs:9:5
-   |
-LL | type Pointer<T> = impl std::ops::Deref<Target = T>;
-   |                   -------------------------------- the expected opaque type
-LL |
-LL | fn test() -> Pointer<_> {
-   |              ---------- expected `Pointer<_>` because of return type
-LL |
-LL |     Box::new(1)
-   |     ^^^^^^^^^^^ expected opaque type, found `Box<{integer}>`
-   |
-   = note: expected opaque type `Pointer<_>`
-                   found struct `Box<{integer}>`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/issue-77179.rs:7:4
-   |
-LL | fn test() -> Pointer<_> {
-   |    ^^^^
-
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
-  --> $DIR/issue-77179.rs:7:22
+  --> $DIR/issue-77179.rs:8:22
    |
 LL | fn test() -> Pointer<_> {
-   |                      ^ not allowed in type signatures
+   |              --------^-
+   |              |       |
+   |              |       not allowed in type signatures
+   |              help: replace with the correct return type: `Pointer<i32>`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/issue-77179.rs:18:25
+  --> $DIR/issue-77179.rs:19:25
    |
 LL |     fn bar() -> Pointer<_>;
    |                         ^ not allowed in type signatures
 
+error[E0792]: expected generic type parameter, found `i32`
+  --> $DIR/issue-77179.rs:10:5
+   |
+LL | type Pointer<T> = impl std::ops::Deref<Target = T>;
+   |              - this generic parameter must be used with a generic type parameter
+...
+LL |     Box::new(1)
+   |     ^^^^^^^^^^^
+
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0121, E0308.
+Some errors have detailed explanations: E0121, E0792.
 For more information about an error, try `rustc --explain E0121`.
diff --git a/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs
index 2a39da1176c..99ad48c8c32 100644
--- a/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs
+++ b/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs
@@ -8,6 +8,7 @@
 trait Foo {}
 impl Foo for () {}
 type Bar = impl Foo;
+#[define_opaque(Bar)]
 fn _defining_use() -> Bar {}
 
 trait TraitArg<T> {
diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr
index ec7b9e0e12b..577d8667a57 100644
--- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
-  --> $DIR/issue-84660-unsoundness.rs:29:1
+  --> $DIR/issue-84660-unsoundness.rs:31:1
    |
 LL | impl<In, Out> Trait<Bar, In> for Out {
    | ------------------------------------ first implementation here
@@ -7,14 +7,14 @@ LL | impl<In, Out> Trait<Bar, In> for Out {
 LL | impl<In, Out> Trait<(), In> for Out {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
-error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
-  --> $DIR/issue-84660-unsoundness.rs:22:8
+error: item does not constrain `Bar::{opaque#0}`
+  --> $DIR/issue-84660-unsoundness.rs:24:8
    |
 LL |     fn convert(_i: In) -> Self::Out {
    |        ^^^^^^^
    |
-   = 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/issue-84660-unsoundness.rs:12:12
    |
 LL | type Bar = impl Foo;
diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr
index e33102f687c..9e83de5375f 100644
--- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
-  --> $DIR/issue-84660-unsoundness.rs:29:1
+  --> $DIR/issue-84660-unsoundness.rs:31:1
    |
 LL | impl<In, Out> Trait<Bar, In> for Out {
    | ------------------------------------ first implementation here
@@ -8,7 +8,7 @@ LL | impl<In, Out> Trait<(), In> for Out {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error[E0284]: type annotations needed: cannot satisfy `Bar == _`
-  --> $DIR/issue-84660-unsoundness.rs:22:37
+  --> $DIR/issue-84660-unsoundness.rs:24:37
    |
 LL |       fn convert(_i: In) -> Self::Out {
    |  _____________________________________^
diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
index f3234bafd11..4391bf01dc9 100644
--- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
+++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
@@ -10,6 +10,7 @@
 trait Foo {}
 impl Foo for () {}
 type Bar = impl Foo;
+#[define_opaque(Bar)]
 fn _defining_use() -> Bar {}
 
 trait Trait<T, In> {
@@ -19,9 +20,10 @@ trait Trait<T, In> {
 
 impl<In, Out> Trait<Bar, In> for Out {
     type Out = Out;
+    #[define_opaque(Bar)]
     fn convert(_i: In) -> Self::Out {
         //[next]~^  ERROR: cannot satisfy `Bar == _`
-        //[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`, but has it in its signature
+        //[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`
         unreachable!();
     }
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-89686.rs b/tests/ui/type-alias-impl-trait/issue-89686.rs
index f734c518dd2..5370b8844ff 100644
--- a/tests/ui/type-alias-impl-trait/issue-89686.rs
+++ b/tests/ui/type-alias-impl-trait/issue-89686.rs
@@ -11,6 +11,7 @@ trait Trait {
 
     fn f(&self) -> Self::F;
 
+    #[define_opaque(G)]
     fn g<'a>(&'a self) -> G<'a, Self>
     where
         Self: Sized,
diff --git a/tests/ui/type-alias-impl-trait/issue-89686.stderr b/tests/ui/type-alias-impl-trait/issue-89686.stderr
index 6fa7e197c40..7ad1442f666 100644
--- a/tests/ui/type-alias-impl-trait/issue-89686.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-89686.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `T: Trait` is not satisfied
-  --> $DIR/issue-89686.rs:18:9
+  --> $DIR/issue-89686.rs:19:9
    |
 LL |         async move { self.f().await }
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
diff --git a/tests/ui/type-alias-impl-trait/issue-93411.rs b/tests/ui/type-alias-impl-trait/issue-93411.rs
index 2d08b7ba4c1..11cbb876631 100644
--- a/tests/ui/type-alias-impl-trait/issue-93411.rs
+++ b/tests/ui/type-alias-impl-trait/issue-93411.rs
@@ -14,6 +14,7 @@ fn main() {
 }
 
 type BlahFut<'a> = impl Future<Output = ()> + Send + 'a;
+#[define_opaque(BlahFut)]
 fn blah<'a>(_value: &'a u8) -> BlahFut<'a> {
     async {}
 }
diff --git a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs
index 7097123d608..08f3c404bed 100644
--- a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs
+++ b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs
@@ -44,6 +44,7 @@ fn r#struct() {
 mod only_pattern {
     type T = impl Copy;
 
+    #[define_opaque(T)]
     fn foo(foo: T) {
         let (mut x, mut y) = foo;
         x = 42;
@@ -52,6 +53,7 @@ mod only_pattern {
 
     type U = impl Copy;
 
+    #[define_opaque(U)]
     fn bar(bar: Option<U>) {
         match bar {
             Some((mut x, mut y)) => {
@@ -64,6 +66,7 @@ mod only_pattern {
 
     type V = impl Copy;
 
+    #[define_opaque(V)]
     fn baz(baz: Option<V>) {
         match baz {
             _ => {}
diff --git a/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr b/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr
index c177201431a..5b38b83e4d9 100644
--- a/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr
+++ b/tests/ui/type-alias-impl-trait/itiat-forbid-nested-items.stderr
@@ -11,11 +11,6 @@ LL |             let x: <() as Foo>::Assoc = 42_i32;
    |
    = note: expected opaque type `<() as Foo>::Assoc`
                      found type `i32`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/itiat-forbid-nested-items.rs:11:12
-   |
-LL |         fn foo() -> <() as Foo>::Assoc {
-   |            ^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs
index 1bc352041a5..075b0bd75fa 100644
--- a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs
+++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs
@@ -6,6 +6,7 @@
 
 type Tait = impl FnOnce() -> ();
 
+#[define_opaque(Tait)]
 fn reify_as_tait() -> Thunk<Tait> {
     //~^ ERROR: expected a `FnOnce()` closure, found `()`
     Thunk::new(|cont| cont)
diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr
index 921667f577b..0bee0dfa9c7 100644
--- a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr
+++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/lazy_subtyping_of_opaques.rs:11:5
+  --> $DIR/lazy_subtyping_of_opaques.rs:12:5
    |
 LL | fn reify_as_tait() -> Thunk<Tait> {
    |                       ----------- expected `Thunk<_>` because of return type
@@ -11,7 +11,7 @@ LL |     Thunk::new(|cont| cont)
            found unit type `()`
 
 error[E0277]: expected a `FnOnce()` closure, found `()`
-  --> $DIR/lazy_subtyping_of_opaques.rs:11:23
+  --> $DIR/lazy_subtyping_of_opaques.rs:12:23
    |
 LL |     Thunk::new(|cont| cont)
    |                       ^^^^ expected an `FnOnce()` closure, found `()`
@@ -20,7 +20,7 @@ LL |     Thunk::new(|cont| cont)
    = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
 
 error[E0277]: expected a `FnOnce()` closure, found `()`
-  --> $DIR/lazy_subtyping_of_opaques.rs:9:23
+  --> $DIR/lazy_subtyping_of_opaques.rs:10:23
    |
 LL | fn reify_as_tait() -> Thunk<Tait> {
    |                       ^^^^^^^^^^^ expected an `FnOnce()` closure, found `()`
diff --git a/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs b/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs
index 45a55050c44..b58840718a3 100644
--- a/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs
+++ b/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs
@@ -2,6 +2,7 @@
 
 type Foo<'a> = impl Sized;
 
+#[define_opaque(Foo)]
 fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> (Foo<'a>, Foo<'b>) {
     (x, y)
     //~^ ERROR opaque type used twice with different lifetimes
@@ -9,6 +10,7 @@ fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> (Foo<'a>, Foo<'b>) {
 
 type Bar<'a, 'b> = impl std::fmt::Debug;
 
+#[define_opaque(Bar)]
 fn bar<'x, 'y>(i: &'x i32, j: &'y i32) -> (Bar<'x, 'y>, Bar<'y, 'x>) {
     (i, j)
     //~^ ERROR opaque type used twice with different lifetimes
diff --git a/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr b/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr
index 4f7b0f17407..719748edc01 100644
--- a/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr
+++ b/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr
@@ -1,5 +1,5 @@
 error: opaque type used twice with different lifetimes
-  --> $DIR/lifetime_mismatch.rs:6:5
+  --> $DIR/lifetime_mismatch.rs:7:5
    |
 LL |     (x, y)
    |     ^^^^^^
@@ -8,13 +8,13 @@ LL |     (x, y)
    |     lifetime `'b` previously used here
    |
 note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
-  --> $DIR/lifetime_mismatch.rs:6:5
+  --> $DIR/lifetime_mismatch.rs:7:5
    |
 LL |     (x, y)
    |     ^^^^^^
 
 error: opaque type used twice with different lifetimes
-  --> $DIR/lifetime_mismatch.rs:13:5
+  --> $DIR/lifetime_mismatch.rs:15:5
    |
 LL |     (i, j)
    |     ^^^^^^
@@ -23,7 +23,7 @@ LL |     (i, j)
    |     lifetime `'y` previously used here
    |
 note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
-  --> $DIR/lifetime_mismatch.rs:13:5
+  --> $DIR/lifetime_mismatch.rs:15:5
    |
 LL |     (i, j)
    |     ^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/method_resolution.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution.current.stderr
index a9c05ad3342..07e7126f8a0 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution.current.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution.current.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
-  --> $DIR/method_resolution.rs:21:14
+  --> $DIR/method_resolution.rs:22:14
    |
 LL | struct Bar<T>(T);
    | ------------- method `bar` not found for this struct
diff --git a/tests/ui/type-alias-impl-trait/method_resolution.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution.next.stderr
index 6b34358a56e..7462d2b478b 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution.next.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution.next.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
-  --> $DIR/method_resolution.rs:21:14
+  --> $DIR/method_resolution.rs:22:14
    |
 LL | struct Bar<T>(T);
    | ------------- method `bar` not found for this struct
diff --git a/tests/ui/type-alias-impl-trait/method_resolution.rs b/tests/ui/type-alias-impl-trait/method_resolution.rs
index f636aba15c0..a9162d0e28b 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution.rs
+++ b/tests/ui/type-alias-impl-trait/method_resolution.rs
@@ -11,6 +11,7 @@ type Foo = impl Sized;
 struct Bar<T>(T);
 
 impl Bar<Foo> {
+    #[define_opaque(Foo)]
     fn bar(mut self) {
         self.0 = 42_u32;
     }
@@ -23,6 +24,7 @@ impl Bar<u32> {
     }
 }
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     42_u32
 }
diff --git a/tests/ui/type-alias-impl-trait/method_resolution2.rs b/tests/ui/type-alias-impl-trait/method_resolution2.rs
index f69661db799..a4c4bbbace6 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution2.rs
+++ b/tests/ui/type-alias-impl-trait/method_resolution2.rs
@@ -12,6 +12,7 @@ type Foo = impl Sized;
 struct Bar<T>(T);
 
 impl Bar<Foo> {
+    #[define_opaque(Foo)]
     fn bar(self) {
         self.foo()
     }
@@ -21,6 +22,7 @@ impl Bar<u32> {
     fn foo(self) {}
 }
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     42_u32
 }
diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.rs b/tests/ui/type-alias-impl-trait/method_resolution3.rs
index 0e6176bfe03..a18dcc9a2fe 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution3.rs
+++ b/tests/ui/type-alias-impl-trait/method_resolution3.rs
@@ -27,6 +27,7 @@ impl Bar<u32> {
     fn foo(self) {}
 }
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     42_u32
 }
diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr
index e4c4d121733..569a9f49bbe 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr
@@ -1,5 +1,5 @@
 error[E0307]: invalid `self` parameter type: `Bar<Foo>`
-  --> $DIR/method_resolution4.rs:27:18
+  --> $DIR/method_resolution4.rs:25:18
    |
 LL |     fn foo(self: Bar<Foo>) {
    |                  ^^^^^^^^
@@ -8,7 +8,7 @@ LL |     fn foo(self: Bar<Foo>) {
    = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0307]: invalid `self` parameter type: `&Bar<Foo>`
-  --> $DIR/method_resolution4.rs:31:20
+  --> $DIR/method_resolution4.rs:29:20
    |
 LL |     fn foomp(self: &Bar<Foo>) {
    |                    ^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr
index e4c4d121733..569a9f49bbe 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr
@@ -1,5 +1,5 @@
 error[E0307]: invalid `self` parameter type: `Bar<Foo>`
-  --> $DIR/method_resolution4.rs:27:18
+  --> $DIR/method_resolution4.rs:25:18
    |
 LL |     fn foo(self: Bar<Foo>) {
    |                  ^^^^^^^^
@@ -8,7 +8,7 @@ LL |     fn foo(self: Bar<Foo>) {
    = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0307]: invalid `self` parameter type: `&Bar<Foo>`
-  --> $DIR/method_resolution4.rs:31:20
+  --> $DIR/method_resolution4.rs:29:20
    |
 LL |     fn foomp(self: &Bar<Foo>) {
    |                    ^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.rs b/tests/ui/type-alias-impl-trait/method_resolution4.rs
index f33b4e473ae..8a1b60b0c6e 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution4.rs
+++ b/tests/ui/type-alias-impl-trait/method_resolution4.rs
@@ -7,14 +7,12 @@
 
 #![feature(type_alias_impl_trait, arbitrary_self_types)]
 
-mod foo {
-    pub type Foo = impl Copy;
+pub type Foo = impl Copy;
 
-    fn foo() -> Foo {
-        42_u32
-    }
+#[define_opaque(Foo)]
+fn foo() -> Foo {
+    42_u32
 }
-use foo::Foo;
 
 #[derive(Copy, Clone)]
 struct Bar<T>(T);
diff --git a/tests/ui/type-alias-impl-trait/method_resolution5.rs b/tests/ui/type-alias-impl-trait/method_resolution5.rs
index 64355e4560d..b22c44ceb13 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution5.rs
+++ b/tests/ui/type-alias-impl-trait/method_resolution5.rs
@@ -12,20 +12,20 @@ type Foo = impl Sized;
 struct Bar<T>(T);
 
 impl Bar<Foo> {
+    #[define_opaque(Foo)]
     fn bar(mut self) {
         self.0 = 42_u32;
     }
 }
 
 impl Bar<u32> {
-    fn foo(self)
-    where
-        Foo:,
-    {
+    #[define_opaque(Foo)]
+    fn foo(self) {
         self.bar()
     }
 }
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     42_u32
 }
diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr
index f331da1af87..841aa12f983 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr
@@ -1,11 +1,11 @@
-error: item does not constrain `Tait::{opaque#0}`, but has it in its signature
-  --> $DIR/method_resolution_trait_method_from_opaque.rs:24:8
+error: item does not constrain `Tait::{opaque#0}`
+  --> $DIR/method_resolution_trait_method_from_opaque.rs:26:8
    |
 LL |     fn foo(&mut self) {
    |        ^^^
    |
-   = 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/method_resolution_trait_method_from_opaque.rs:17:13
    |
 LL | type Tait = impl Iterator<Item = ()>;
diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
index 2617ce124c1..bbdd3923821 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9
+  --> $DIR/method_resolution_trait_method_from_opaque.rs:28:9
    |
 LL |         self.bar.next().unwrap();
    |         ^^^^^^^^ cannot infer type
diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
index b6adf08853f..93461fcbb0b 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
+++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs
@@ -17,10 +17,12 @@ pub struct Foo {
 type Tait = impl Iterator<Item = ()>;
 
 impl Foo {
+    #[define_opaque(Tait)]
     pub fn new() -> Foo {
         Foo { bar: std::iter::empty() }
     }
 
+    #[define_opaque(Tait)]
     fn foo(&mut self) {
         //[current]~^ ERROR: item does not constrain
         self.bar.next().unwrap();
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 c178fcf5a91..d77efa39aeb 100644
--- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
@@ -2,6 +2,7 @@
 
 type Opaque2<T> = impl Sized;
 type Opaque<'a, T> = Opaque2<T>;
+#[define_opaque(Opaque)]
 fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x } //~ WARNING elided lifetime has a name
 //~^ ERROR: hidden type for `Opaque2<T>` captures lifetime that does not appear in bounds
 
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 e2c21f1636b..61eb76ffc5a 100644
--- a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
@@ -1,5 +1,5 @@
 warning: elided lifetime has a name
-  --> $DIR/missing_lifetime_bound.rs:5:41
+  --> $DIR/missing_lifetime_bound.rs:6:41
    |
 LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
    |             --                          ^ this elided lifetime gets resolved as `'a`
@@ -9,11 +9,11 @@ LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
    = note: `#[warn(elided_named_lifetimes)]` on by default
 
 error[E0700]: hidden type for `Opaque2<T>` captures lifetime that does not appear in bounds
-  --> $DIR/missing_lifetime_bound.rs:5:47
+  --> $DIR/missing_lifetime_bound.rs:6:47
    |
 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-infer.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs
index b887fcf3083..3dd2d53fe3d 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs
@@ -6,6 +6,7 @@
 
 type Y<A, B> = impl std::fmt::Debug;
 
+#[define_opaque(Y)]
 fn g<A, B>() -> (Y<A, B>, Y<B, A>) {
     (42_i64, 60) //~ ERROR concrete type differs from previous defining opaque type use
 }
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr
index b050b08a8e2..d6558576577 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr
@@ -1,5 +1,5 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/multiple-def-uses-in-one-fn-infer.rs:10:5
+  --> $DIR/multiple-def-uses-in-one-fn-infer.rs:11:5
    |
 LL |     (42_i64, 60)
    |     ^^^^^^^^^^^^
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 580fb58ef83..39e4912ae3a 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
@@ -2,6 +2,7 @@
 
 type Foo<'a, 'b> = impl std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) {
     (i, j)
     //~^ ERROR opaque type used twice with different lifetimes
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 b2b9e604a6b..03f2b1c532a 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: opaque type used twice with different lifetimes
-  --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
+  --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:7:5
    |
 LL |     (i, j)
    |     ^^^^^^
@@ -8,7 +8,7 @@ LL |     (i, j)
    |     lifetime `'y` previously used here
    |
 note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
-  --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
+  --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:7:5
    |
 LL |     (i, j)
    |     ^^^^^^
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 aba41a9d852..50c97060cef 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
@@ -3,11 +3,13 @@
 
 type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
 
+#[define_opaque(X)]
 fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
     (a.clone(), a)
 }
 
 type Tait<'x> = impl Sized;
+#[define_opaque(Tait)]
 fn define<'a: 'b, 'b: 'a>(x: &'a u8, y: &'b u8) -> (Tait<'a>, Tait<'b>) {
     ((), ())
 }
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
index da845e86147..5e2b140ef8b 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
@@ -6,6 +6,7 @@
 
 type X<A, B> = impl Into<&'static A>;
 
+#[define_opaque(X)]
 fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
     //~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied
     (a, a)
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
index b5f38074632..05a169882cb 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied
-  --> $DIR/multiple-def-uses-in-one-fn.rs:9:45
+  --> $DIR/multiple-def-uses-in-one-fn.rs:10:45
    |
 LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
    |                                             ^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B`
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
index 14510a5294e..1357d772be1 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
@@ -6,6 +6,7 @@
 
 type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
 
+#[define_opaque(X)]
 fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
     (a.clone(), a)
     //~^ ERROR concrete type differs from previous defining opaque type
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
index c7a4b2115bf..15e9b6fbf76 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
@@ -1,5 +1,5 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/multiple-def-uses-in-one-fn2.rs:10:5
+  --> $DIR/multiple-def-uses-in-one-fn2.rs:11:5
    |
 LL |     (a.clone(), a)
    |     ^^^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
index 11a922443e6..11d23efec75 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
@@ -6,10 +6,12 @@
 
 type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
 
+#[define_opaque(X)]
 fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
     (a, b)
 }
 
+#[define_opaque(X)]
 fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
     (a, b)
     //~^ ERROR mismatched types
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
index c3128ea6f5e..42ba769797b 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9
+  --> $DIR/multiple-def-uses-in-one-fn3.rs:16:9
    |
 LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
    |      -                    - found type parameter
diff --git a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr
index ca15b134a99..3a13ab7cb95 100644
--- a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr
+++ b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr
@@ -31,7 +31,7 @@ error: unconstrained opaque type
 LL | pub type Tait = impl Iterator<Item = (&'db LocalKey, impl Iterator)>;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `Tait` must be used in combination with a concrete type within the same module
+   = note: `Tait` must be used in combination with a concrete type within the same crate
 
 error: unconstrained opaque type
   --> $DIR/nested-impl-trait-in-tait.rs:3:54
@@ -39,7 +39,7 @@ error: unconstrained opaque type
 LL | pub type Tait = impl Iterator<Item = (&'db LocalKey, impl Iterator)>;
    |                                                      ^^^^^^^^^^^^^
    |
-   = note: `Tait` must be used in combination with a concrete type within the same module
+   = note: `Tait` 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/type-alias-impl-trait/nested-in-anon-const.stderr b/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr
index aa0c1076117..54389efc9c6 100644
--- a/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr
+++ b/tests/ui/type-alias-impl-trait/nested-in-anon-const.stderr
@@ -13,7 +13,7 @@ error: unconstrained opaque type
 LL |                     type B<Z> = impl Sized;
    |                                 ^^^^^^^^^^
    |
-   = note: `B` must be used in combination with a concrete type within the same item
+   = note: `B` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs
index ba705d6f85a..6ef6f31953f 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs
+++ b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs
@@ -4,11 +4,13 @@ trait Trait<'a> { type Assoc; }
 impl<'a> Trait<'a> for () { type Assoc = &'a str; }
 
 type WithoutLt = impl Sized;
+#[define_opaque(WithoutLt)]
 fn without_lt() -> impl for<'a> Trait<'a, Assoc = WithoutLt> {}
 //~^ ERROR captures lifetime that does not appear in bounds
 
 type WithLt<'a> = impl Sized + 'a;
 
+#[define_opaque(WithLt)]
 fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
 //~^ ERROR expected generic lifetime parameter, found `'a`
 
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr
index f208730552d..ad60d186dd3 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr
+++ b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr
@@ -1,19 +1,20 @@
 error[E0700]: hidden type for `WithoutLt` captures lifetime that does not appear in bounds
-  --> $DIR/nested-tait-hrtb.rs:7:62
+  --> $DIR/nested-tait-hrtb.rs:8:62
    |
 LL | type WithoutLt = impl Sized;
    |                  ---------- opaque type defined here
+LL | #[define_opaque(WithoutLt)]
 LL | fn without_lt() -> impl for<'a> Trait<'a, Assoc = WithoutLt> {}
    |                             --                               ^^
    |                             |
    |                             hidden type `&'a str` captures the lifetime `'a` as defined here
 
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/nested-tait-hrtb.rs:12:60
+  --> $DIR/nested-tait-hrtb.rs:14:60
    |
 LL | type WithLt<'a> = impl Sized + 'a;
    |             -- this generic parameter must be used with a generic lifetime parameter
-LL |
+...
 LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
    |                                                            ^^
 
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr
index 915432bbe67..b19f34a67ff 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr
+++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
-  --> $DIR/nested-tait-inference.rs:17:13
+  --> $DIR/nested-tait-inference.rs:18:13
    |
 LL | fn foo() -> impl Foo<FooX> {
    |             ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs
index 50d51c7faf9..d4ad72797cf 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs
+++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs
@@ -14,6 +14,7 @@ trait Foo<A> {}
 
 impl Foo<()> for () {}
 
+#[define_opaque(FooX)]
 fn foo() -> impl Foo<FooX> {
     //[current]~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
     // FIXME(type-alias-impl-trait): We could probably make this work.
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr
index 9da3926ac70..27372ceed94 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr
+++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
-  --> $DIR/nested-tait-inference2.rs:17:13
+  --> $DIR/nested-tait-inference2.rs:18:13
    |
 LL | fn foo() -> impl Foo<FooX> {
    |             ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr
index 9647d9e376e..b733739e4c8 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr
+++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr
@@ -1,5 +1,5 @@
 error[E0284]: type annotations needed: cannot satisfy `impl Foo<FooX> == ()`
-  --> $DIR/nested-tait-inference2.rs:19:5
+  --> $DIR/nested-tait-inference2.rs:20:5
    |
 LL |     ()
    |     ^^ cannot satisfy `impl Foo<FooX> == ()`
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs
index 28d72b0cbee..4aeecb9140c 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs
+++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs
@@ -14,6 +14,7 @@ trait Foo<A> {}
 impl Foo<()> for () {}
 impl Foo<u32> for () {}
 
+#[define_opaque(FooX)]
 fn foo() -> impl Foo<FooX> {
     //[current]~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
     ()
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs
index aaf2812532d..3e7b8c80d1b 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs
+++ b/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs
@@ -9,6 +9,7 @@ trait Foo<A> {}
 
 impl Foo<FooX> for () {}
 
+#[define_opaque(FooX)]
 fn foo() -> impl Foo<FooX> {
     //~^ ERROR: item does not constrain
     ()
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr
index 969409ebc59..be7aec92312 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr
+++ b/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr
@@ -1,11 +1,11 @@
-error: item does not constrain `FooX::{opaque#0}`, but has it in its signature
-  --> $DIR/nested-tait-inference3.rs:12:4
+error: item does not constrain `FooX::{opaque#0}`
+  --> $DIR/nested-tait-inference3.rs:13:4
    |
 LL | fn foo() -> impl Foo<FooX> {
    |    ^^^
    |
-   = 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/nested-tait-inference3.rs:6:13
    |
 LL | type FooX = impl Debug;
diff --git a/tests/ui/type-alias-impl-trait/nested.rs b/tests/ui/type-alias-impl-trait/nested.rs
index 524703939f1..1a89039af8a 100644
--- a/tests/ui/type-alias-impl-trait/nested.rs
+++ b/tests/ui/type-alias-impl-trait/nested.rs
@@ -7,6 +7,7 @@ trait Trait<T> {}
 
 impl<T, U> Trait<T> for U {}
 
+#[define_opaque(Bar)]
 fn bar() -> Bar {
     //~^ ERROR: item does not constrain
     42
diff --git a/tests/ui/type-alias-impl-trait/nested.stderr b/tests/ui/type-alias-impl-trait/nested.stderr
index ca1cf6058ea..59911f65a23 100644
--- a/tests/ui/type-alias-impl-trait/nested.stderr
+++ b/tests/ui/type-alias-impl-trait/nested.stderr
@@ -1,18 +1,18 @@
-error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
-  --> $DIR/nested.rs:10:4
+error: item does not constrain `Foo::{opaque#0}`
+  --> $DIR/nested.rs:11:4
    |
 LL | fn bar() -> Bar {
    |    ^^^
    |
-   = 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/nested.rs:3:12
    |
 LL | type Foo = impl std::fmt::Debug;
    |            ^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `Bar` doesn't implement `Debug`
-  --> $DIR/nested.rs:16:22
+  --> $DIR/nested.rs:17:22
    |
 LL |     println!("{:?}", bar());
    |                      ^^^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug`
diff --git a/tests/ui/type-alias-impl-trait/nested_inference_failure.rs b/tests/ui/type-alias-impl-trait/nested_inference_failure.rs
index 004e79d6738..c0581b018e9 100644
--- a/tests/ui/type-alias-impl-trait/nested_inference_failure.rs
+++ b/tests/ui/type-alias-impl-trait/nested_inference_failure.rs
@@ -22,6 +22,7 @@ struct Foo<T: Debug, F: FnOnce(T)> {
 type ImplT = impl Debug;
 type FooImpl = Foo<ImplT, impl FnOnce(ImplT)>;
 
+#[define_opaque(FooImpl)]
 fn bar() -> FooImpl {
     Foo::<i32, _> { f: |_| (), _phantom: PhantomData }
 }
diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs
index 4def8948708..5adae476bfe 100644
--- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs
+++ b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs
@@ -1,21 +1,21 @@
 #![feature(type_alias_impl_trait)]
 
-mod my_mod {
-    use std::fmt::Debug;
+use std::fmt::Debug;
 
-    pub type Foo = impl Debug;
-    pub type Foot = impl Debug;
+pub type Foo = impl Debug;
+pub type Foot = impl Debug;
 
-    pub fn get_foo() -> Foo {
-        5i32
-    }
+#[define_opaque(Foo)]
+pub fn get_foo() -> Foo {
+    5i32
+}
 
-    pub fn get_foot(_: Foo) -> Foot {
-        //~^ ERROR: item does not constrain `Foo::{opaque#0}`, but has it in its signature
-        get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type
-    }
+#[define_opaque(Foot, Foo)]
+pub fn get_foot(_: Foo) -> Foot {
+    //~^ ERROR: item does not constrain `Foo::{opaque#0}`
+    get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type
 }
 
 fn main() {
-    let _: my_mod::Foot = my_mod::get_foot(my_mod::get_foo());
+    let _: Foot = get_foot(get_foo());
 }
diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr
index 889cff1ba09..aabae315777 100644
--- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr
+++ b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr
@@ -1,32 +1,32 @@
-error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
-  --> $DIR/nested_type_alias_impl_trait.rs:13:12
+error: item does not constrain `Foo::{opaque#0}`
+  --> $DIR/nested_type_alias_impl_trait.rs:14:8
    |
-LL |     pub fn get_foot(_: Foo) -> Foot {
-   |            ^^^^^^^^
+LL | pub fn get_foot(_: Foo) -> Foot {
+   |        ^^^^^^^^
    |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
-  --> $DIR/nested_type_alias_impl_trait.rs:6:20
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/nested_type_alias_impl_trait.rs:5:16
    |
-LL |     pub type Foo = impl Debug;
-   |                    ^^^^^^^^^^
+LL | pub type Foo = impl Debug;
+   |                ^^^^^^^^^^
 
 error: opaque type's hidden type cannot be another opaque type from the same scope
-  --> $DIR/nested_type_alias_impl_trait.rs:15:9
+  --> $DIR/nested_type_alias_impl_trait.rs:16:5
    |
-LL |         get_foo()
-   |         ^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
+LL |     get_foo()
+   |     ^^^^^^^^^ 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/nested_type_alias_impl_trait.rs:7:21
+  --> $DIR/nested_type_alias_impl_trait.rs:6:17
    |
-LL |     pub type Foot = impl Debug;
-   |                     ^^^^^^^^^^
+LL | pub type Foot = impl Debug;
+   |                 ^^^^^^^^^^
 note: opaque type being used as hidden type
-  --> $DIR/nested_type_alias_impl_trait.rs:6:20
+  --> $DIR/nested_type_alias_impl_trait.rs:5:16
    |
-LL |     pub type Foo = impl Debug;
-   |                    ^^^^^^^^^^
+LL | pub type Foo = impl Debug;
+   |                ^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs b/tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs
index 590107d1038..fc47243d693 100644
--- a/tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs
+++ b/tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs
@@ -4,10 +4,12 @@ fn main() {}
 
 type NoReveal = impl std::fmt::Debug;
 
+#[define_opaque(NoReveal)]
 fn define_no_reveal() -> NoReveal {
     ""
 }
 
+#[define_opaque(NoReveal)]
 fn no_reveal(x: NoReveal) {
     let _: &'static str = x;
     let _ = x as &'static str;
diff --git a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
index 41238c27351..8e5e4719415 100644
--- a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
+++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
@@ -3,18 +3,17 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod foo {
-    pub type Foo = impl Copy;
+pub type Foo = impl Copy;
 
-    // make compiler happy about using 'Foo'
-    pub fn bar(x: Foo) -> Foo {
-        //~^ ERROR: item does not constrain `Foo::{opaque#0}`
-        x
-    }
+// make compiler happy about using 'Foo'
+#[define_opaque(Foo)]
+pub fn bar(x: Foo) -> Foo {
+    //~^ ERROR: item does not constrain `Foo::{opaque#0}`
+    x
 }
 
 fn main() {
     unsafe {
-        let _: foo::Foo = std::mem::transmute(0u8);
+        let _: Foo = std::mem::transmute(0u8);
     }
 }
diff --git a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr
index eed88c5df4f..a57793d5a77 100644
--- a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr
+++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr
@@ -1,15 +1,15 @@
-error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
-  --> $DIR/no_inferrable_concrete_type.rs:10:12
+error: item does not constrain `Foo::{opaque#0}`
+  --> $DIR/no_inferrable_concrete_type.rs:10:8
    |
-LL |     pub fn bar(x: Foo) -> Foo {
-   |            ^^^
+LL | pub fn bar(x: Foo) -> 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/no_inferrable_concrete_type.rs:7:20
+   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
+note: this opaque type is supposed to be constrained
+  --> $DIR/no_inferrable_concrete_type.rs:6:16
    |
-LL |     pub type Foo = impl Copy;
-   |                    ^^^^^^^^^
+LL | pub type Foo = impl Copy;
+   |                ^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs
index 61153b1e171..42161dcde66 100644
--- a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs
+++ b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs
@@ -2,11 +2,10 @@
 
 fn main() {}
 
-mod boo {
-    pub type Boo = impl ::std::fmt::Debug;
-    fn bomp() -> Boo {
-        ""
-    }
+pub type Boo = impl ::std::fmt::Debug;
+#[define_opaque(Boo)]
+fn define() -> Boo {
+    ""
 }
 
 // We don't actually know the type here.
@@ -15,10 +14,10 @@ fn bomp2() {
     let _: &str = bomp(); //~ ERROR mismatched types
 }
 
-fn bomp() -> boo::Boo {
+fn bomp() -> Boo {
     "" //~ ERROR mismatched types
 }
 
-fn bomp_loop() -> boo::Boo {
+fn bomp_loop() -> Boo {
     loop {}
 }
diff --git a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr
index 863282a0ff9..f4416eb009a 100644
--- a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr
+++ b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr
@@ -1,8 +1,8 @@
 error[E0308]: mismatched types
-  --> $DIR/no_revealing_outside_defining_module.rs:15:19
+  --> $DIR/no_revealing_outside_defining_module.rs:14:19
    |
-LL |     pub type Boo = impl ::std::fmt::Debug;
-   |                    ---------------------- the found opaque type
+LL | pub type Boo = impl ::std::fmt::Debug;
+   |                ---------------------- the found opaque type
 ...
 LL |     let _: &str = bomp();
    |            ----   ^^^^^^ expected `&str`, found opaque type
@@ -11,29 +11,29 @@ LL |     let _: &str = bomp();
    |
    = note: expected reference `&str`
             found opaque type `Boo`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/no_revealing_outside_defining_module.rs:14:4
+note: this item must have a `#[define_opaque(Boo)]` attribute to be able to define hidden types
+  --> $DIR/no_revealing_outside_defining_module.rs:13:4
    |
 LL | fn bomp2() {
    |    ^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/no_revealing_outside_defining_module.rs:19:5
+  --> $DIR/no_revealing_outside_defining_module.rs:18:5
    |
-LL |     pub type Boo = impl ::std::fmt::Debug;
-   |                    ---------------------- the expected opaque type
+LL | pub type Boo = impl ::std::fmt::Debug;
+   |                ---------------------- the expected opaque type
 ...
-LL | fn bomp() -> boo::Boo {
-   |              -------- expected `Boo` because of return type
+LL | fn bomp() -> Boo {
+   |              --- expected `Boo` because of return type
 LL |     ""
    |     ^^ expected opaque type, found `&str`
    |
    = note: expected opaque type `Boo`
                 found reference `&'static str`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/no_revealing_outside_defining_module.rs:18:4
+note: this item must have a `#[define_opaque(Boo)]` attribute to be able to define hidden types
+  --> $DIR/no_revealing_outside_defining_module.rs:17:4
    |
-LL | fn bomp() -> boo::Boo {
+LL | fn bomp() -> Boo {
    |    ^^^^
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/type-alias-impl-trait/normalize-alias-type.rs b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs
index 9fcf42e188c..d0fcfb438fb 100644
--- a/tests/ui/type-alias-impl-trait/normalize-alias-type.rs
+++ b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs
@@ -18,7 +18,7 @@ pub fn tr1() -> impl Tr {
 }
 
 struct Inner {
-    x: helper::X,
+    x: X,
 }
 impl Tr for Inner {
     fn get(&self) -> u32 {
@@ -26,14 +26,9 @@ impl Tr for Inner {
     }
 }
 
-mod helper {
-    pub use super::*;
-    pub type X = impl Tr;
+pub type X = impl Tr;
 
-    pub fn tr2() -> impl Tr
-    where
-        X:,
-    {
-        Inner { x: tr1() }
-    }
+#[define_opaque(X)]
+pub fn tr2() -> impl Tr {
+    Inner { x: tr1() }
 }
diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr
index a40dac06a01..75cc5948e93 100644
--- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr
+++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr
@@ -1,29 +1,29 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/normalize-hidden-types.rs:26:20
+  --> $DIR/normalize-hidden-types.rs:27:20
    |
 LL |     fn define() -> Opaque {
    |                    ^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)`
    |
 note: previous use here
-  --> $DIR/normalize-hidden-types.rs:27:9
+  --> $DIR/normalize-hidden-types.rs:28:9
    |
 LL |         dyn_hoops::<_>(0)
    |         ^^^^^^^^^^^^^^^^^
 
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/normalize-hidden-types.rs:34:22
+  --> $DIR/normalize-hidden-types.rs:36:22
    |
 LL |     fn define_1() -> Opaque { dyn_hoops::<_>(0) }
    |                      ^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)`
    |
 note: previous use here
-  --> $DIR/normalize-hidden-types.rs:34:31
+  --> $DIR/normalize-hidden-types.rs:36:31
    |
 LL |     fn define_1() -> Opaque { dyn_hoops::<_>(0) }
    |                               ^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/normalize-hidden-types.rs:43:25
+  --> $DIR/normalize-hidden-types.rs:47:25
    |
 LL |     type Opaque = impl Sized;
    |                   ---------- the expected opaque type
@@ -39,13 +39,13 @@ LL |         let _: Opaque = dyn_hoops::<u8>(0);
    = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/normalize-hidden-types.rs:52:25
+  --> $DIR/normalize-hidden-types.rs:57:25
    |
 LL |         let _: Opaque = dyn_hoops::<_>(0);
    |                         ^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)`
    |
 note: previous use here
-  --> $DIR/normalize-hidden-types.rs:53:9
+  --> $DIR/normalize-hidden-types.rs:58:9
    |
 LL |         None
    |         ^^^^
diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs b/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs
index 4028dba82bf..bc007169b83 100644
--- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs
+++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs
@@ -23,6 +23,7 @@ fn dyn_hoops<T: Trait>(_: T) -> *const dyn FnOnce(T::Gat<'_>) {
 mod typeof_1 {
     use super::*;
     type Opaque = impl Sized;
+    #[define_opaque(Opaque)]
     fn define() -> Opaque {
         dyn_hoops::<_>(0)
     }
@@ -31,13 +32,16 @@ mod typeof_1 {
 mod typeof_2 {
     use super::*;
     type Opaque = impl Sized;
+    #[define_opaque(Opaque)]
     fn define_1() -> Opaque { dyn_hoops::<_>(0) }
+    #[define_opaque(Opaque)]
     fn define_2() -> Opaque { dyn_hoops::<u8>(0) }
 }
 
 mod typeck {
     use super::*;
     type Opaque = impl Sized;
+    #[define_opaque(Opaque)]
     fn define() -> Option<Opaque> {
         let _: Opaque = dyn_hoops::<_>(0);
         let _: Opaque = dyn_hoops::<u8>(0);
@@ -48,6 +52,7 @@ mod typeck {
 mod borrowck {
     use super::*;
     type Opaque = impl Sized;
+    #[define_opaque(Opaque)]
     fn define() -> Option<Opaque> {
         let _: Opaque = dyn_hoops::<_>(0);
         None
diff --git a/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.rs b/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.rs
index 131f8d999d8..112ee4d5571 100644
--- a/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.rs
+++ b/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.rs
@@ -9,6 +9,7 @@ trait Foo<T> {
 struct DefinesOpaque;
 impl Foo<DefinesOpaque> for () {
     type Assoc = impl Sized;
+    //~^ ERROR: unconstrained opaque type
 
     // This test's return type is `u32`, *not* the opaque that is defined above.
     // Previously we were only checking that the self type of the assoc matched,
diff --git a/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr b/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr
index d4528fb76fe..1d1b14e1463 100644
--- a/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr
+++ b/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr
@@ -1,5 +1,13 @@
+error: unconstrained opaque type
+  --> $DIR/not-matching-trait-refs-isnt-defining.rs:11:18
+   |
+LL |     type Assoc = impl Sized;
+   |                  ^^^^^^^^^^
+   |
+   = note: `Assoc` must be used in combination with a concrete type within the same impl
+
 error[E0308]: mismatched types
-  --> $DIR/not-matching-trait-refs-isnt-defining.rs:17:54
+  --> $DIR/not-matching-trait-refs-isnt-defining.rs:18:54
    |
 LL |     type Assoc = impl Sized;
    |                  ---------- the expected opaque type
@@ -11,12 +19,7 @@ LL |         let _: <Self as Foo<DefinesOpaque>>::Assoc = "";
    |
    = note: expected opaque type `<() as Foo<DefinesOpaque>>::Assoc`
                 found reference `&'static str`
-note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/not-matching-trait-refs-isnt-defining.rs:16:8
-   |
-LL |     fn test() -> <() as Foo<NoOpaques>>::Assoc {
-   |        ^^^^
 
-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/type-alias-impl-trait/not_a_defining_use.rs b/tests/ui/type-alias-impl-trait/not_a_defining_use.rs
index b5ef1470629..d20622dc2e0 100644
--- a/tests/ui/type-alias-impl-trait/not_a_defining_use.rs
+++ b/tests/ui/type-alias-impl-trait/not_a_defining_use.rs
@@ -6,6 +6,7 @@ fn main() {}
 
 type Two<T, U> = impl Debug;
 
+#[define_opaque(Two)]
 fn three<T: Debug, U>(t: T) -> Two<T, U> {
     (t, 5i8)
 }
@@ -20,6 +21,7 @@ impl Bar for u32 {
     const FOO: i32 = 42;
 }
 
+#[define_opaque(Two)]
 fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
     (t, <U as Bar>::FOO)
     //~^ ERROR concrete type differs
diff --git a/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr b/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr
index b59f9c49b07..d90e4531879 100644
--- a/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr
+++ b/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/not_a_defining_use.rs:24:5
+  --> $DIR/not_a_defining_use.rs:26:5
    |
 LL |     (t, <U as Bar>::FOO)
    |     ^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
    |
 note: previous use here
-  --> $DIR/not_a_defining_use.rs:10:5
+  --> $DIR/not_a_defining_use.rs:11:5
    |
 LL |     (t, 5i8)
    |     ^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/not_well_formed.rs b/tests/ui/type-alias-impl-trait/not_well_formed.rs
index 0cf8d41c7fd..bd4477dbf0f 100644
--- a/tests/ui/type-alias-impl-trait/not_well_formed.rs
+++ b/tests/ui/type-alias-impl-trait/not_well_formed.rs
@@ -16,6 +16,7 @@ trait Trait<U> {}
 
 impl<W> Trait<W> for () {}
 
+#[define_opaque(Foo)]
 fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T> {
     ()
 }
diff --git a/tests/ui/type-alias-impl-trait/obligation_ice.rs b/tests/ui/type-alias-impl-trait/obligation_ice.rs
index e3698b23be8..134255e1eb2 100644
--- a/tests/ui/type-alias-impl-trait/obligation_ice.rs
+++ b/tests/ui/type-alias-impl-trait/obligation_ice.rs
@@ -8,6 +8,7 @@ trait Trait<'a, 'b: 'a> {}
 impl<'a, 'b: 'a, T> Trait<'a, 'b> for std::iter::Cloned<T> {}
 
 type I<'a, 'b: 'a, A: Trait<'a, 'b>> = Chain<A, impl Iterator<Item = &'static str>>;
+#[define_opaque(I)]
 fn test2<'a, 'b, A: Trait<'a, 'b> + Iterator<Item = &'static str>>(x: A) -> I<'a, 'b, A> {
     x.chain(once("5"))
 }
diff --git a/tests/ui/type-alias-impl-trait/outlives-bound-var.rs b/tests/ui/type-alias-impl-trait/outlives-bound-var.rs
index 2c6f44d5416..b1711e9eab8 100644
--- a/tests/ui/type-alias-impl-trait/outlives-bound-var.rs
+++ b/tests/ui/type-alias-impl-trait/outlives-bound-var.rs
@@ -5,11 +5,9 @@
 //@ check-pass
 #![feature(type_alias_impl_trait)]
 
-mod tait {
-    pub type Ty<'a> = impl Sized + 'a;
-    fn define<'a>() -> Ty<'a> {}
-}
-use tait::Ty;
+pub type Ty<'a> = impl Sized + 'a;
+#[define_opaque(Ty)]
+fn define<'a>() -> Ty<'a> {}
 
 // Ty<'^0>: 'static
 fn test1(_: &'static fn(Ty<'_>)) {}
diff --git a/tests/ui/type-alias-impl-trait/param_mismatch.rs b/tests/ui/type-alias-impl-trait/param_mismatch.rs
index c7465030713..4e4e06acfd4 100644
--- a/tests/ui/type-alias-impl-trait/param_mismatch.rs
+++ b/tests/ui/type-alias-impl-trait/param_mismatch.rs
@@ -8,6 +8,7 @@ fn id(s: &str) -> &str {
 }
 type Opaque<'a> = impl Sized + 'a;
 // The second `Opaque<'_>` has a higher kinded lifetime, not a generic parameter
+#[define_opaque(Opaque)]
 fn test(s: &str) -> (Opaque<'_>, impl Fn(&str) -> Opaque<'_>) {
     (s, id)
     //~^ ERROR: expected generic lifetime parameter, found `'_`
diff --git a/tests/ui/type-alias-impl-trait/param_mismatch.stderr b/tests/ui/type-alias-impl-trait/param_mismatch.stderr
index 09ec550d718..07a8ce38f98 100644
--- a/tests/ui/type-alias-impl-trait/param_mismatch.stderr
+++ b/tests/ui/type-alias-impl-trait/param_mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/param_mismatch.rs:12:5
+  --> $DIR/param_mismatch.rs:13:5
    |
 LL | type Opaque<'a> = impl Sized + 'a;
    |             -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/param_mismatch2.rs b/tests/ui/type-alias-impl-trait/param_mismatch2.rs
index c7d5eaa16aa..f6a99711411 100644
--- a/tests/ui/type-alias-impl-trait/param_mismatch2.rs
+++ b/tests/ui/type-alias-impl-trait/param_mismatch2.rs
@@ -9,6 +9,7 @@ fn id(s: &str) -> &str {
 
 type Opaque<'a> = impl Sized + 'a;
 
+#[define_opaque(Opaque)]
 fn test(s: &str) -> (impl Fn(&str) -> Opaque<'_>, impl Fn(&str) -> Opaque<'_>) {
     (id, id) //~ ERROR: expected generic lifetime parameter, found `'_`
 }
diff --git a/tests/ui/type-alias-impl-trait/param_mismatch2.stderr b/tests/ui/type-alias-impl-trait/param_mismatch2.stderr
index 1ecdd7c2b54..f5ecade2f02 100644
--- a/tests/ui/type-alias-impl-trait/param_mismatch2.stderr
+++ b/tests/ui/type-alias-impl-trait/param_mismatch2.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/param_mismatch2.rs:13:5
+  --> $DIR/param_mismatch2.rs:14:5
    |
 LL | type Opaque<'a> = impl Sized + 'a;
    |             -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/param_mismatch3.rs b/tests/ui/type-alias-impl-trait/param_mismatch3.rs
index 03c133d5d3c..17b6f8bce2a 100644
--- a/tests/ui/type-alias-impl-trait/param_mismatch3.rs
+++ b/tests/ui/type-alias-impl-trait/param_mismatch3.rs
@@ -9,6 +9,7 @@ fn id2<'a, 'b>(s: (&'a str, &'b str)) -> (&'a str, &'b str) {
 
 type Opaque<'a> = impl Sized + 'a;
 
+#[define_opaque(Opaque)]
 fn test() -> impl for<'a, 'b> Fn((&'a str, &'b str)) -> (Opaque<'a>, Opaque<'b>) {
     id2 //~ ERROR expected generic lifetime parameter, found `'a`
 }
@@ -19,6 +20,7 @@ fn id(s: &str) -> &str {
 
 type Opaque2<'a> = impl Sized + 'a;
 
+#[define_opaque(Opaque2)]
 fn test2(s: &str) -> (impl Fn(&str) -> Opaque2<'_>, Opaque2<'_>) {
     (id, s) //~ ERROR: expected generic lifetime parameter, found `'_`
 }
diff --git a/tests/ui/type-alias-impl-trait/param_mismatch3.stderr b/tests/ui/type-alias-impl-trait/param_mismatch3.stderr
index b8805f9b7f6..7565bbfc6ff 100644
--- a/tests/ui/type-alias-impl-trait/param_mismatch3.stderr
+++ b/tests/ui/type-alias-impl-trait/param_mismatch3.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'a`
-  --> $DIR/param_mismatch3.rs:13:5
+  --> $DIR/param_mismatch3.rs:14:5
    |
 LL | type Opaque<'a> = impl Sized + 'a;
    |             -- this generic parameter must be used with a generic lifetime parameter
@@ -8,7 +8,7 @@ LL |     id2
    |     ^^^
 
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/param_mismatch3.rs:23:5
+  --> $DIR/param_mismatch3.rs:25:5
    |
 LL | type Opaque2<'a> = impl Sized + 'a;
    |              -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/param_mismatch4.rs b/tests/ui/type-alias-impl-trait/param_mismatch4.rs
index e072f3ab8e0..bc32143d0eb 100644
--- a/tests/ui/type-alias-impl-trait/param_mismatch4.rs
+++ b/tests/ui/type-alias-impl-trait/param_mismatch4.rs
@@ -8,6 +8,7 @@ type Opq<'a> = impl Sized;
 // Two defining uses: Opq<'{empty}> and Opq<'a>.
 // This used to ICE.
 // issue: #122782
+#[define_opaque(Opq)]
 fn build<'a>() -> Opq<'a> {
     let _: Opq<'_> = ();
     //~^ ERROR expected generic lifetime parameter, found `'_`
diff --git a/tests/ui/type-alias-impl-trait/param_mismatch4.stderr b/tests/ui/type-alias-impl-trait/param_mismatch4.stderr
index d3fdea25a3d..647637ae32a 100644
--- a/tests/ui/type-alias-impl-trait/param_mismatch4.stderr
+++ b/tests/ui/type-alias-impl-trait/param_mismatch4.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/param_mismatch4.rs:12:12
+  --> $DIR/param_mismatch4.rs:13:12
    |
 LL | type Opq<'a> = impl Sized;
    |          -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/path_resolution_taint.rs b/tests/ui/type-alias-impl-trait/path_resolution_taint.rs
new file mode 100644
index 00000000000..b320e88450b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/path_resolution_taint.rs
@@ -0,0 +1,16 @@
+//! This test used to ICE #131298
+
+#![feature(type_alias_impl_trait)]
+
+fn dyn_hoops<T>() -> *const dyn Iterator<Item = impl Captures> {
+    //~^ ERROR: cannot find trait `Captures` in this scope
+    loop {}
+}
+
+type Opaque = impl Sized;
+#[define_opaque(Opaque)]
+fn define() -> Opaque {
+    let _: Opaque = dyn_hoops::<u8>();
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/path_resolution_taint.stderr b/tests/ui/type-alias-impl-trait/path_resolution_taint.stderr
new file mode 100644
index 00000000000..122c7c1ffbf
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/path_resolution_taint.stderr
@@ -0,0 +1,9 @@
+error[E0405]: cannot find trait `Captures` in this scope
+  --> $DIR/path_resolution_taint.rs:5:54
+   |
+LL | fn dyn_hoops<T>() -> *const dyn Iterator<Item = impl Captures> {
+   |                                                      ^^^^^^^^ not found in this scope
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0405`.
diff --git a/tests/ui/type-alias-impl-trait/privacy.rs b/tests/ui/type-alias-impl-trait/privacy.rs
index a5386bbec0d..4fbb9c7313f 100644
--- a/tests/ui/type-alias-impl-trait/privacy.rs
+++ b/tests/ui/type-alias-impl-trait/privacy.rs
@@ -3,6 +3,7 @@
 #![feature(type_alias_impl_trait)]
 
 type Foo = (impl Sized, u8);
+#[define_opaque(Foo)]
 pub fn foo() -> Foo {
     //~^ WARNING type alias `Foo` is more private than the item `foo`
     (42, 42)
diff --git a/tests/ui/type-alias-impl-trait/privacy.stderr b/tests/ui/type-alias-impl-trait/privacy.stderr
index 50870905c30..eeb49b1a4ac 100644
--- a/tests/ui/type-alias-impl-trait/privacy.stderr
+++ b/tests/ui/type-alias-impl-trait/privacy.stderr
@@ -1,5 +1,5 @@
 warning: type alias `Foo` is more private than the item `foo`
-  --> $DIR/privacy.rs:6:1
+  --> $DIR/privacy.rs:7:1
    |
 LL | pub fn foo() -> Foo {
    | ^^^^^^^^^^^^^^^^^^^ function `foo` is reachable at visibility `pub`
diff --git a/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs b/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
index 3d1759097d6..cfd7e1bf382 100644
--- a/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
+++ b/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
@@ -3,10 +3,12 @@
 
 pub type Diff = impl Fn(usize) -> usize;
 
+#[define_opaque(Diff)]
 pub fn lift() -> Diff {
     |_: usize |loop {}
 }
 
+#[define_opaque(Diff)]
 pub fn add(
     n: Diff,
     m: Diff,
diff --git a/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr b/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
index e8925b9b489..1a8ab219404 100644
--- a/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
+++ b/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
@@ -1,11 +1,11 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/recursive-fn-tait.rs:14:5
+  --> $DIR/recursive-fn-tait.rs:16:5
    |
 LL |     move |x: usize| m(n(x))
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:7:5: 7:16}`, got `{closure@$DIR/recursive-fn-tait.rs:14:5: 14:20}`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:8:5: 8:16}`, got `{closure@$DIR/recursive-fn-tait.rs:16:5: 16:20}`
    |
 note: previous use here
-  --> $DIR/recursive-fn-tait.rs:7:5
+  --> $DIR/recursive-fn-tait.rs:8:5
    |
 LL |     |_: usize |loop {}
    |     ^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs
index 10588398c9d..26ffd5c16a2 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs
@@ -3,11 +3,15 @@
 #![feature(type_alias_impl_trait)]
 
 type Op = impl std::fmt::Display;
-fn foo() -> Op { &"hello world" }
+#[define_opaque(Op)]
+fn foo() -> Op {
+    &"hello world"
+}
 
 fn transform<S>() -> impl std::fmt::Display {
     &0usize
 }
+#[define_opaque(Op)]
 fn bad() -> Op {
     transform::<Op>()
     //~^ ERROR concrete type differs from previous defining opaque type use
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr
index eec35548c55..259f3b2b9f3 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/recursive-tait-conflicting-defn-2.rs:12:5
+  --> $DIR/recursive-tait-conflicting-defn-2.rs:16:5
    |
 LL |     transform::<Op>()
    |     ^^^^^^^^^^^^^^^^^ expected `&'static &'static str`, got `impl std::fmt::Display`
    |
 note: previous use here
-  --> $DIR/recursive-tait-conflicting-defn-2.rs:6:18
+  --> $DIR/recursive-tait-conflicting-defn-2.rs:8:5
    |
-LL | fn foo() -> Op { &"hello world" }
-   |                  ^^^^^^^^^^^^^^
+LL |     &"hello world"
+   |     ^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs
index 38fb493b498..c9e2773905d 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs
@@ -14,24 +14,23 @@ struct B<T> {
 
 impl<T: Test> Test for B<T> {}
 
-mod helper {
-    use super::*;
-    pub type TestImpl = impl Test;
+pub type TestImpl = impl Test;
 
-    pub fn test() -> TestImpl {
-        A
-    }
+#[define_opaque(TestImpl)]
+pub fn test() -> TestImpl {
+    A
+}
 
-    fn make_option2() -> Option<TestImpl> {
-        let inner = make_option().unwrap();
+#[define_opaque(TestImpl)]
+fn make_option2() -> Option<TestImpl> {
+    let inner = make_option().unwrap();
 
-        Some(B { inner })
-        //~^ ERROR concrete type differs from previous defining opaque type use
-    }
+    Some(B { inner })
+    //~^ ERROR concrete type differs from previous defining opaque type use
 }
 
-fn make_option() -> Option<helper::TestImpl> {
-    Some(helper::test())
+fn make_option() -> Option<TestImpl> {
+    Some(test())
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr
index 252c5d7dfa7..47471c9728c 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr
@@ -1,14 +1,14 @@
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/recursive-tait-conflicting-defn.rs:28:9
+  --> $DIR/recursive-tait-conflicting-defn.rs:28:5
    |
-LL |         Some(B { inner })
-   |         ^^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
+LL |     Some(B { inner })
+   |     ^^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
    |
 note: previous use here
-  --> $DIR/recursive-tait-conflicting-defn.rs:22:9
+  --> $DIR/recursive-tait-conflicting-defn.rs:21:5
    |
-LL |         A
-   |         ^
+LL |     A
+   |     ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/reveal_local.rs b/tests/ui/type-alias-impl-trait/reveal_local.rs
index 34f3788e234..1e1e118937b 100644
--- a/tests/ui/type-alias-impl-trait/reveal_local.rs
+++ b/tests/ui/type-alias-impl-trait/reveal_local.rs
@@ -7,12 +7,13 @@ type Foo = impl Debug;
 fn is_send<T: Send>() {}
 
 fn not_good() {
-    // Error: this function does not constrain `Foo` to any particular
-    // hidden type, so it cannot rely on `Send` being true.
+    // This function does not define `Foo`,
+    // so it can actually check auto traits on the hidden type without
+    // risking cycle errors.
     is_send::<Foo>();
-    //~^ ERROR: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits
 }
 
+#[define_opaque(Foo)]
 fn not_gooder() -> Foo {
     // Constrain `Foo = u32`
     let x: Foo = 22_u32;
diff --git a/tests/ui/type-alias-impl-trait/reveal_local.stderr b/tests/ui/type-alias-impl-trait/reveal_local.stderr
index 9829c58cf73..bd082888591 100644
--- a/tests/ui/type-alias-impl-trait/reveal_local.stderr
+++ b/tests/ui/type-alias-impl-trait/reveal_local.stderr
@@ -1,23 +1,5 @@
-error: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits
-  --> $DIR/reveal_local.rs:12:15
-   |
-LL |     is_send::<Foo>();
-   |               ^^^
-   |
-   = note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
-note: opaque type is declared here
-  --> $DIR/reveal_local.rs:5:12
-   |
-LL | type Foo = impl Debug;
-   |            ^^^^^^^^^^
-note: required by a bound in `is_send`
-  --> $DIR/reveal_local.rs:7:15
-   |
-LL | fn is_send<T: Send>() {}
-   |               ^^^^ required by this bound in `is_send`
-
 error[E0283]: type annotations needed: cannot satisfy `Foo: Send`
-  --> $DIR/reveal_local.rs:22:15
+  --> $DIR/reveal_local.rs:23:15
    |
 LL |     is_send::<Foo>();
    |               ^^^
@@ -29,6 +11,6 @@ note: required by a bound in `is_send`
 LL | fn is_send<T: Send>() {}
    |               ^^^^ required by this bound in `is_send`
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
index 37d84feee4b..242a4b3cd3e 100644
--- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
+++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
@@ -12,19 +12,16 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod helper {
-    pub type Opaque = impl Sized;
+pub type Opaque = impl Sized;
 
-    pub fn get_rpit() -> impl Clone {}
+pub fn get_rpit() -> impl Clone {}
 
-    fn test() -> Opaque {
-        super::query(get_rpit);
-        get_rpit()
-    }
+#[define_opaque(Opaque)]
+fn test() -> Opaque {
+    query(get_rpit);
+    get_rpit()
 }
 
-use helper::*;
-
 fn query(_: impl FnOnce() -> Opaque) {}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs
index 80f1b1502d3..dc489c0d6fb 100644
--- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs
+++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs
@@ -5,16 +5,14 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod helper {
-    pub type Opaque = impl Sized;
+pub type Opaque = impl Sized;
 
-    pub fn get_rpit() -> impl Sized {}
+pub fn get_rpit() -> impl Sized {}
 
-    fn test(_: Opaque) {
-        super::query(get_rpit);
-    }
+#[define_opaque(Opaque)]
+fn test() {
+    query(get_rpit);
 }
-use helper::*;
 
 fn query(_: impl FnOnce() -> Opaque) {}
 
diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr
index e4399f2d8f4..dca3ae05bb0 100644
--- a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr
+++ b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `i32` with `Foo`
-  --> $DIR/self-referential-2.rs:10:13
+  --> $DIR/self-referential-2.rs:11:13
    |
 LL | fn bar() -> Bar {
    |             ^^^ no implementation for `i32 == Foo`
diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.rs b/tests/ui/type-alias-impl-trait/self-referential-2.rs
index f96364ccfcd..d3effe817b8 100644
--- a/tests/ui/type-alias-impl-trait/self-referential-2.rs
+++ b/tests/ui/type-alias-impl-trait/self-referential-2.rs
@@ -7,6 +7,7 @@
 type Foo = impl std::fmt::Debug;
 type Bar = impl PartialEq<Foo>;
 
+#[define_opaque(Bar)]
 fn bar() -> Bar {
     42_i32 //[current]~^ ERROR can't compare `i32` with `Foo`
 }
diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs
index 18f09b54867..b5562532893 100644
--- a/tests/ui/type-alias-impl-trait/self-referential-3.rs
+++ b/tests/ui/type-alias-impl-trait/self-referential-3.rs
@@ -2,6 +2,7 @@
 
 type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug;
 
+#[define_opaque(Bar)]
 fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
     //~^ ERROR can't compare `&i32` with `Bar<'a, 'b>`
     i
diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr
index 15ebcdafca6..d0b1d46c29e 100644
--- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr
+++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `&i32` with `Bar<'a, 'b>`
-  --> $DIR/self-referential-3.rs:5:31
+  --> $DIR/self-referential-3.rs:6:31
    |
 LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
    |                               ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>`
diff --git a/tests/ui/type-alias-impl-trait/self-referential-4.rs b/tests/ui/type-alias-impl-trait/self-referential-4.rs
index 36742c8ad57..36df087dfcb 100644
--- a/tests/ui/type-alias-impl-trait/self-referential-4.rs
+++ b/tests/ui/type-alias-impl-trait/self-referential-4.rs
@@ -2,18 +2,21 @@
 
 type Bar<'a, 'b> = impl PartialEq<Bar<'b, 'static>> + std::fmt::Debug;
 
+#[define_opaque(Bar)]
 fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
     i //~^ ERROR can't compare `&i32` with `Bar<'b, 'static>`
 }
 
 type Foo<'a, 'b> = impl PartialEq<Foo<'static, 'b>> + std::fmt::Debug;
 
+#[define_opaque(Foo)]
 fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
     i //~^ ERROR can't compare `&i32` with `Foo<'static, 'b>`
 }
 
 type Moo<'a, 'b> = impl PartialEq<Moo<'static, 'a>> + std::fmt::Debug;
 
+#[define_opaque(Moo)]
 fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
     i //~^ ERROR can't compare `&i32` with `Moo<'static, 'a>`
 }
diff --git a/tests/ui/type-alias-impl-trait/self-referential-4.stderr b/tests/ui/type-alias-impl-trait/self-referential-4.stderr
index 98c762e3d38..92534981eb9 100644
--- a/tests/ui/type-alias-impl-trait/self-referential-4.stderr
+++ b/tests/ui/type-alias-impl-trait/self-referential-4.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `&i32` with `Bar<'b, 'static>`
-  --> $DIR/self-referential-4.rs:5:31
+  --> $DIR/self-referential-4.rs:6:31
    |
 LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
    |                               ^^^^^^^^^^^ no implementation for `&i32 == Bar<'b, 'static>`
@@ -10,7 +10,7 @@ LL |     i
    = help: the trait `PartialEq` is implemented for `i32`
 
 error[E0277]: can't compare `&i32` with `Foo<'static, 'b>`
-  --> $DIR/self-referential-4.rs:11:31
+  --> $DIR/self-referential-4.rs:13:31
    |
 LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
    |                               ^^^^^^^^^^^ no implementation for `&i32 == Foo<'static, 'b>`
@@ -21,7 +21,7 @@ LL |     i
    = help: the trait `PartialEq` is implemented for `i32`
 
 error[E0277]: can't compare `&i32` with `Moo<'static, 'a>`
-  --> $DIR/self-referential-4.rs:17:31
+  --> $DIR/self-referential-4.rs:20:31
    |
 LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
    |                               ^^^^^^^^^^^ no implementation for `&i32 == Moo<'static, 'a>`
diff --git a/tests/ui/type-alias-impl-trait/self-referential.rs b/tests/ui/type-alias-impl-trait/self-referential.rs
index b899b12cc4a..a1d3b275b19 100644
--- a/tests/ui/type-alias-impl-trait/self-referential.rs
+++ b/tests/ui/type-alias-impl-trait/self-referential.rs
@@ -2,6 +2,7 @@
 
 type Bar<'a, 'b> = impl PartialEq<Bar<'b, 'a>> + std::fmt::Debug;
 
+#[define_opaque(Bar)]
 fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
     //~^ ERROR can't compare `&i32` with `Bar<'b, 'a>`
     i
@@ -9,6 +10,7 @@ fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
 
 type Foo<'a, 'b> = (i32, impl PartialEq<Foo<'a, 'b>> + std::fmt::Debug);
 
+#[define_opaque(Foo)]
 fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
     //~^ ERROR can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
     (42, i)
@@ -16,6 +18,7 @@ fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
 
 type Moo<'a, 'b> = (i32, impl PartialEq<Moo<'b, 'a>> + std::fmt::Debug);
 
+#[define_opaque(Moo)]
 fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
     //~^ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
     (42, i)
diff --git a/tests/ui/type-alias-impl-trait/self-referential.stderr b/tests/ui/type-alias-impl-trait/self-referential.stderr
index 57d67f69376..4bcf659e8e6 100644
--- a/tests/ui/type-alias-impl-trait/self-referential.stderr
+++ b/tests/ui/type-alias-impl-trait/self-referential.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `&i32` with `Bar<'b, 'a>`
-  --> $DIR/self-referential.rs:5:31
+  --> $DIR/self-referential.rs:6:31
    |
 LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
    |                               ^^^^^^^^^^^ no implementation for `&i32 == Bar<'b, 'a>`
@@ -11,7 +11,7 @@ LL |     i
    = help: the trait `PartialEq` is implemented for `i32`
 
 error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
-  --> $DIR/self-referential.rs:12:31
+  --> $DIR/self-referential.rs:14:31
    |
 LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
    |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
@@ -23,7 +23,7 @@ LL |     (42, i)
    = help: the trait `PartialEq` is implemented for `i32`
 
 error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
-  --> $DIR/self-referential.rs:19:31
+  --> $DIR/self-referential.rs:22:31
    |
 LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
    |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
diff --git a/tests/ui/type-alias-impl-trait/self_implication.rs b/tests/ui/type-alias-impl-trait/self_implication.rs
index 56464af96ed..d7f70159571 100644
--- a/tests/ui/type-alias-impl-trait/self_implication.rs
+++ b/tests/ui/type-alias-impl-trait/self_implication.rs
@@ -20,11 +20,10 @@ struct Foo<'a> {
     x: &'a mut u8,
 }
 // desugared
-mod foo {
-    pub type FooX = impl Sized;
-    impl<'a> super::Foo<'a> {
-        pub fn foo(&self) -> FooX {}
-    }
+pub type FooX = impl Sized;
+impl<'a> Foo<'a> {
+    #[define_opaque(FooX)]
+    pub fn foo(&self) -> FooX {}
 }
 
 fn bar() {
diff --git a/tests/ui/type-alias-impl-trait/static-const-types.rs b/tests/ui/type-alias-impl-trait/static-const-types.rs
deleted file mode 100644
index dad515aaa7b..00000000000
--- a/tests/ui/type-alias-impl-trait/static-const-types.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-#![feature(type_alias_impl_trait)]
-#![allow(dead_code)]
-
-//@ check-pass
-
-use std::fmt::Debug;
-
-type Foo = impl Debug;
-
-static FOO1: Foo = 22_u32;
-const FOO2: Foo = 22_u32;
-
-fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs b/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs
index 27f5799c380..a20ae814908 100644
--- a/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs
+++ b/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs
@@ -1,15 +1,15 @@
 #![feature(type_alias_impl_trait)]
 
-mod bar {
-    pub type Bar = impl Send;
+pub type Bar = impl Send;
 
-    // While i32 is structural-match, we do not want to leak this information.
-    // (See https://github.com/rust-lang/rust/issues/72156)
-    pub const fn leak_free() -> Bar {
-        7i32
-    }
+// While i32 is structural-match, we do not want to leak this information.
+// (See https://github.com/rust-lang/rust/issues/72156)
+#[define_opaque(Bar)]
+pub const fn leak_free() -> Bar {
+    7i32
 }
-const LEAK_FREE: bar::Bar = bar::leak_free();
+
+const LEAK_FREE: Bar = leak_free();
 
 fn leak_free_test() {
     match LEAK_FREE {
diff --git a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr
index 28f5d6728a9..5067d78d169 100644
--- a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr
+++ b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr
@@ -1,8 +1,8 @@
 error: opaque type `Bar` cannot be used in patterns
   --> $DIR/structural-match-no-leak.rs:16:9
    |
-LL | const LEAK_FREE: bar::Bar = bar::leak_free();
-   | ------------------------- constant defined here
+LL | const LEAK_FREE: Bar = leak_free();
+   | -------------------- constant defined here
 ...
 LL |         LEAK_FREE => (),
    |         ^^^^^^^^^ opaque type can't be used in patterns
diff --git a/tests/ui/type-alias-impl-trait/structural-match.rs b/tests/ui/type-alias-impl-trait/structural-match.rs
index 50259591539..68a95560a46 100644
--- a/tests/ui/type-alias-impl-trait/structural-match.rs
+++ b/tests/ui/type-alias-impl-trait/structural-match.rs
@@ -1,22 +1,21 @@
 #![feature(type_alias_impl_trait)]
 
-mod foo {
-    pub type Foo = impl Send;
+pub type Foo = impl Send;
 
-    // This is not structural-match
-    struct A;
+// This is not structural-match
+struct A;
 
-    pub const fn value() -> Foo {
-        A
-    }
+#[define_opaque(Foo)]
+pub const fn value() -> Foo {
+    A
 }
-use foo::*;
+
 const VALUE: Foo = value();
 
 fn test() {
     match VALUE {
         VALUE => (),
-        //~^ `foo::Foo` cannot be used in patterns
+        //~^ `Foo` cannot be used in patterns
         _ => (),
     }
 }
diff --git a/tests/ui/type-alias-impl-trait/structural-match.stderr b/tests/ui/type-alias-impl-trait/structural-match.stderr
index b06b31a060f..a86b7f42ead 100644
--- a/tests/ui/type-alias-impl-trait/structural-match.stderr
+++ b/tests/ui/type-alias-impl-trait/structural-match.stderr
@@ -1,5 +1,5 @@
-error: opaque type `foo::Foo` cannot be used in patterns
-  --> $DIR/structural-match.rs:18:9
+error: opaque type `Foo` cannot be used in patterns
+  --> $DIR/structural-match.rs:17:9
    |
 LL | const VALUE: Foo = value();
    | ---------------- constant defined here
diff --git a/tests/ui/type-alias-impl-trait/taint.rs b/tests/ui/type-alias-impl-trait/taint.rs
index dfb947637c0..3d67c9bca41 100644
--- a/tests/ui/type-alias-impl-trait/taint.rs
+++ b/tests/ui/type-alias-impl-trait/taint.rs
@@ -9,6 +9,7 @@ fn set(x: &mut isize) -> isize {
     *x
 }
 
+#[define_opaque(Two)]
 fn d(x: Two) {
     let c1 = || set(x); //~ ERROR: expected generic lifetime parameter, found `'_`
     c1;
diff --git a/tests/ui/type-alias-impl-trait/taint.stderr b/tests/ui/type-alias-impl-trait/taint.stderr
index 17fcd4b7e93..e2e34a5d1ba 100644
--- a/tests/ui/type-alias-impl-trait/taint.stderr
+++ b/tests/ui/type-alias-impl-trait/taint.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/taint.rs:13:17
+  --> $DIR/taint.rs:14:17
    |
 LL | type Two<'a, 'b> = impl std::fmt::Debug;
    |          -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs
index 109a70c766d..ab33e9e794e 100644
--- a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs
+++ b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs
@@ -19,6 +19,7 @@ type Sendable = impl Send + Duh;
 
 type Foo = impl Trait<Assoc = Sendable>;
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     || 42
 }
diff --git a/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs b/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs
index be743e8e270..488c581247d 100644
--- a/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs
+++ b/tests/ui/type-alias-impl-trait/tait-param-inference-issue-117310.rs
@@ -10,9 +10,11 @@ impl<A, B> Trait for (A, B, u8) where A: Deref, B: Deref<Target = A::Target>, {}
 impl<A, B> Trait for (A, B, i8) {}
 
 type TaitSized = impl Sized;
+#[define_opaque(TaitSized)]
 fn def_tait1() -> TaitSized {}
 
 type TaitCopy = impl Copy;
+#[define_opaque(TaitCopy)]
 fn def_tait2() -> TaitCopy {}
 
 fn impl_trait<T: Trait> () {}
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs
index 66a6c0a35b5..af787d66cc1 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs
@@ -5,6 +5,7 @@
 
 type Foo = Box<dyn Iterator<Item = impl Send>>;
 
+#[define_opaque(Foo)]
 fn make_foo() -> Foo {
     Box::new(vec![1, 2, 3].into_iter())
 }
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs
index e46d2bd559c..921dc17593d 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs
@@ -5,6 +5,7 @@
 
 type Foo = impl Iterator<Item = impl Send>;
 
+#[define_opaque(Foo)]
 fn make_foo() -> Foo {
     vec![1, 2].into_iter()
 }
@@ -12,6 +13,7 @@ fn make_foo() -> Foo {
 type Bar = impl Send;
 type Baz = impl Iterator<Item = Bar>;
 
+#[define_opaque(Baz)]
 fn make_baz() -> Baz {
     vec!["1", "2"].into_iter()
 }
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs
index 6b37552fed1..b5533eeecba 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs
@@ -1,11 +1,19 @@
 #![feature(type_alias_impl_trait)]
-//@ check-pass
-// Ensures that `const` items can constrain an opaque `impl Trait`.
+// Ensures that `const` items can not constrain an opaque `impl Trait`.
 
 use std::fmt::Debug;
 
 pub type Foo = impl Debug;
+//~^ ERROR unconstrained opaque type
 
+#[define_opaque(Foo)]
+//~^ ERROR only functions and methods can define opaque types
 const _FOO: Foo = 5;
+//~^ ERROR mismatched types
+
+#[define_opaque(Foo)]
+//~^ ERROR only functions and methods can define opaque types
+static _BAR: Foo = 22_u32;
+//~^ ERROR mismatched types
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr
new file mode 100644
index 00000000000..dc15da665f3
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.stderr
@@ -0,0 +1,57 @@
+error: only functions and methods can define opaque types
+  --> $DIR/type-alias-impl-trait-const.rs:9:1
+   |
+LL | #[define_opaque(Foo)]
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: only functions and methods can define opaque types
+  --> $DIR/type-alias-impl-trait-const.rs:14:1
+   |
+LL | #[define_opaque(Foo)]
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: unconstrained opaque type
+  --> $DIR/type-alias-impl-trait-const.rs:6:16
+   |
+LL | pub type Foo = impl Debug;
+   |                ^^^^^^^^^^
+   |
+   = note: `Foo` must be used in combination with a concrete type within the same crate
+
+error[E0308]: mismatched types
+  --> $DIR/type-alias-impl-trait-const.rs:11:19
+   |
+LL | pub type Foo = impl Debug;
+   |                ---------- the expected opaque type
+...
+LL | const _FOO: Foo = 5;
+   |                   ^ expected opaque type, found integer
+   |
+   = note: expected opaque type `Foo`
+                     found type `{integer}`
+note: this item must have a `#[define_opaque(Foo)]` attribute to be able to define hidden types
+  --> $DIR/type-alias-impl-trait-const.rs:11:7
+   |
+LL | const _FOO: Foo = 5;
+   |       ^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/type-alias-impl-trait-const.rs:16:20
+   |
+LL | pub type Foo = impl Debug;
+   |                ---------- the expected opaque type
+...
+LL | static _BAR: Foo = 22_u32;
+   |                    ^^^^^^ expected opaque type, found `u32`
+   |
+   = note: expected opaque type `Foo`
+                     found type `u32`
+note: this item must have a `#[define_opaque(Foo)]` attribute to be able to define hidden types
+  --> $DIR/type-alias-impl-trait-const.rs:16:8
+   |
+LL | static _BAR: Foo = 22_u32;
+   |        ^^^^
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs
index cbd91066c49..95d52e1ff96 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs
@@ -11,12 +11,14 @@ struct MyStruct {
 
 impl MyTrait for MyStruct {}
 
+#[define_opaque(TE)]
 fn bla() -> TE {
     return MyStruct { v: 1 };
 }
 
+#[define_opaque(TE)]
 fn bla2() -> TE {
-    //~^ ERROR: item does not constrain `TE::{opaque#0}`, but has it in its signature
+    //~^ ERROR: item does not constrain `TE::{opaque#0}`
     bla()
 }
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr
index 819bde02183..12aa94386dc 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr
@@ -1,12 +1,12 @@
-error: item does not constrain `TE::{opaque#0}`, but has it in its signature
-  --> $DIR/type-alias-impl-trait-fns.rs:18:4
+error: item does not constrain `TE::{opaque#0}`
+  --> $DIR/type-alias-impl-trait-fns.rs:20:4
    |
 LL | fn bla2() -> TE {
    |    ^^^^
    |
-   = note: consider moving the opaque type's declaration and defining uses into a separate module
-note: this opaque type is in the signature
-  --> $DIR/type-alias-impl-trait-fns.rs:23:11
+   = 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-fns.rs:25:11
    |
 LL | type TE = impl MyTrait;
    |           ^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs
index 188b23732f9..929dec39b2f 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs
@@ -3,21 +3,25 @@
 #![feature(type_alias_impl_trait)]
 
 type A = impl Sized;
+#[define_opaque(A)]
 fn f1() -> A {
     0
 }
 
 type B = impl ?Sized;
+#[define_opaque(B)]
 fn f2() -> &'static B {
     &[0]
 }
 
 type C = impl ?Sized + 'static;
+#[define_opaque(C)]
 fn f3() -> &'static C {
     &[0]
 }
 
 type D = impl ?Sized;
+#[define_opaque(D)]
 fn f4() -> &'static D {
     &1
 }
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs
index 1340a4214ee..3fcb40df832 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs
@@ -5,6 +5,7 @@
 
 type Foo = Vec<impl Send>;
 
+#[define_opaque(Foo)]
 fn make_foo() -> Foo {
     vec![true, false]
 }
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs
index 8e90f969953..32b39c8823d 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs
@@ -6,20 +6,17 @@
 #![feature(type_alias_impl_trait)]
 #![allow(dead_code)]
 
-mod foo {
-    pub trait MyTrait {}
+pub trait MyTrait {}
 
-    impl MyTrait for bool {}
+impl MyTrait for bool {}
 
-    pub type Foo = impl MyTrait;
+pub type Foo = impl MyTrait;
 
-    pub fn make_foo() -> Foo {
-        true
-    }
+#[define_opaque(Foo)]
+pub fn make_foo() -> Foo {
+    true
 }
 
-use foo::*;
-
 struct Blah {
     my_foo: Foo,
     my_u8: u8,
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr
index ee8922b673e..ad96a0eeb87 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr
@@ -1,9 +1,10 @@
-error[E0275]: overflow evaluating the requirement `<Foo as FnOnce<()>>::Output == Foo`
-  --> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:6:21
+error: unconstrained opaque type
+  --> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:4:12
    |
-LL | fn crash(x: Foo) -> Foo {
-   |                     ^^^
+LL | type Foo = impl Fn() -> Foo;
+   |            ^^^^^^^^^^^^^^^^
+   |
+   = note: `Foo` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr
index 3d0f1d30ca2..e5bb8163a81 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr
@@ -1,9 +1,10 @@
-error[E0275]: overflow evaluating the requirement `<Foo as Bar<Foo>>::Item == Foo`
-  --> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:10:21
+error: unconstrained opaque type
+  --> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:8:12
    |
-LL | fn crash(x: Foo) -> Foo {
-   |                     ^^^
+LL | type Foo = impl Bar<Foo, Item = Foo>;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Foo` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr
index 675689bac42..157310bf623 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr
@@ -1,9 +1,10 @@
-error[E0275]: overflow evaluating the requirement `<Foo<'_> as FnOnce<()>>::Output == Foo<'a>`
-  --> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:6:40
+error: unconstrained opaque type
+  --> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:4:16
    |
-LL | fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
-   |                                        ^^^^^^^
+LL | type Foo<'a> = impl Fn() -> Foo<'a>;
+   |                ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Foo` must be used in combination with a concrete type within the same crate
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs
index 8ca279eec92..115df16bd3e 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs
@@ -3,6 +3,7 @@
 type Foo = impl 'static;
 //~^ ERROR: at least one trait must be specified
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     "foo"
 }
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr
index 3f7acd33830..da8fc595f6a 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr
@@ -5,7 +5,7 @@ LL | type Foo = impl 'static;
    |            ^^^^^^^^^^^^
 
 error: at least one trait must be specified
-  --> $DIR/type-alias-impl-trait-with-no-traits.rs:10:13
+  --> $DIR/type-alias-impl-trait-with-no-traits.rs:11:13
    |
 LL | fn bar() -> impl 'static {
    |             ^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs
index 0fe653ac471..ff11fb4fcaf 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs
@@ -17,6 +17,7 @@ fn main() {
 // single definition
 type Foo = impl std::fmt::Display;
 
+#[define_opaque(Foo)]
 fn foo() -> Foo {
     "foo"
 }
@@ -24,30 +25,36 @@ fn foo() -> Foo {
 // two definitions
 type Bar = impl std::fmt::Display;
 
+#[define_opaque(Bar)]
 fn bar1() -> Bar {
     "bar1"
 }
 
+#[define_opaque(Bar)]
 fn bar2() -> Bar {
     "bar2"
 }
 
 type MyIter<T> = impl Iterator<Item = T>;
 
+#[define_opaque(MyIter)]
 fn my_iter<T>(t: T) -> MyIter<T> {
     std::iter::once(t)
 }
 
+#[define_opaque(MyIter)]
 fn my_iter2<T>(t: T) -> MyIter<T> {
     std::iter::once(t)
 }
 
 // param names should not have an effect!
+#[define_opaque(MyIter)]
 fn my_iter3<U>(u: U) -> MyIter<U> {
     std::iter::once(u)
 }
 
 // param position should not have an effect!
+#[define_opaque(MyIter)]
 fn my_iter4<U, V>(_: U, v: V) -> MyIter<V> {
     std::iter::once(v)
 }
@@ -55,6 +62,7 @@ fn my_iter4<U, V>(_: U, v: V) -> MyIter<V> {
 // param names should not have an effect!
 type MyOtherIter<T> = impl Iterator<Item = T>;
 
+#[define_opaque(MyOtherIter)]
 fn my_other_iter<U>(u: U) -> MyOtherIter<U> {
     std::iter::once(u)
 }
@@ -62,18 +70,18 @@ fn my_other_iter<U>(u: U) -> MyOtherIter<U> {
 trait Trait {}
 type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a;
 
+#[define_opaque(GenericBound)]
 fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> {
     t
 }
 
-mod pass_through {
-    pub type Passthrough<T: 'static> = impl Sized + 'static;
+pub type Passthrough<T: 'static> = impl Sized + 'static;
 
-    fn define_passthrough<T: 'static>(t: T) -> Passthrough<T> {
-        t
-    }
+#[define_opaque(Passthrough)]
+fn define_passthrough<T: 'static>(t: T) -> Passthrough<T> {
+    t
 }
 
-fn use_passthrough(x: pass_through::Passthrough<u32>) -> pass_through::Passthrough<u32> {
+fn use_passthrough(x: Passthrough<u32>) -> Passthrough<u32> {
     x
 }
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs
index 65e2feaf795..e87fda8159b 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs
@@ -14,71 +14,74 @@ fn main() {
     assert_eq!(my_iter(42u8).collect::<Vec<u8>>(), vec![42u8]);
 }
 
-use defining_use_scope::*;
+// single definition
+pub type Foo = impl std::fmt::Display;
 
-mod defining_use_scope {
-    // single definition
-    pub type Foo = impl std::fmt::Display;
-
-    pub fn foo() -> Foo {
-        "foo"
-    }
-
-    // two definitions
-    pub type Bar = impl std::fmt::Display;
+#[define_opaque(Foo)]
+pub fn foo() -> Foo {
+    "foo"
+}
 
-    pub fn bar1() -> Bar {
-        "bar1"
-    }
+// two definitions
+pub type Bar = impl std::fmt::Display;
 
-    pub fn bar2() -> Bar {
-        "bar2"
-    }
+#[define_opaque(Bar)]
+pub fn bar1() -> Bar {
+    "bar1"
+}
 
-    pub type MyIter<T> = impl Iterator<Item = T>;
+#[define_opaque(Bar)]
+pub fn bar2() -> Bar {
+    "bar2"
+}
 
-    pub fn my_iter<T>(t: T) -> MyIter<T> {
-        std::iter::once(t)
-    }
+pub type MyIter<T> = impl Iterator<Item = T>;
 
-    fn my_iter2<T>(t: T) -> MyIter<T> {
-        std::iter::once(t)
-    }
+#[define_opaque(MyIter)]
+pub fn my_iter<T>(t: T) -> MyIter<T> {
+    std::iter::once(t)
+}
 
-    // param names should not have an effect!
-    fn my_iter3<U>(u: U) -> MyIter<U> {
-        std::iter::once(u)
-    }
+#[define_opaque(MyIter)]
+fn my_iter2<T>(t: T) -> MyIter<T> {
+    std::iter::once(t)
+}
 
-    // param position should not have an effect!
-    fn my_iter4<U, V>(_: U, v: V) -> MyIter<V> {
-        std::iter::once(v)
-    }
+// param names should not have an effect!
+#[define_opaque(MyIter)]
+fn my_iter3<U>(u: U) -> MyIter<U> {
+    std::iter::once(u)
+}
 
-    // param names should not have an effect!
-    type MyOtherIter<T> = impl Iterator<Item = T>;
+// param position should not have an effect!
+#[define_opaque(MyIter)]
+fn my_iter4<U, V>(_: U, v: V) -> MyIter<V> {
+    std::iter::once(v)
+}
 
-    fn my_other_iter<U>(u: U) -> MyOtherIter<U> {
-        std::iter::once(u)
-    }
+// param names should not have an effect!
+type MyOtherIter<T> = impl Iterator<Item = T>;
 
-    trait Trait {}
-    type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a;
+#[define_opaque(MyOtherIter)]
+fn my_other_iter<U>(u: U) -> MyOtherIter<U> {
+    std::iter::once(u)
+}
 
-    fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> {
-        t
-    }
+trait Trait {}
+type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a;
 
-    mod pass_through {
-        pub type Passthrough<T: 'static> = impl Sized + 'static;
+#[define_opaque(GenericBound)]
+fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> {
+    t
+}
 
-        fn define_passthrough<T: 'static>(t: T) -> Passthrough<T> {
-            t
-        }
-    }
+pub type Passthrough<T: 'static> = impl Sized + 'static;
 
-    fn use_passthrough(x: pass_through::Passthrough<u32>) -> pass_through::Passthrough<u32> {
-        x
-    }
+#[define_opaque(Passthrough)]
+fn define_passthrough<T: 'static>(t: T) -> Passthrough<T> {
+    t
+}
 
+fn use_passthrough(x: Passthrough<u32>) -> Passthrough<u32> {
+    x
 }
diff --git a/tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs b/tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs
index af575a4ff36..20209c7b28c 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs
@@ -2,9 +2,10 @@
 
 #![feature(type_alias_impl_trait)]
 
-use std::iter::{once, Chain};
+use std::iter::{Chain, once};
 
 type I<A> = Chain<A, impl Iterator<Item = &'static str>>;
+#[define_opaque(I)]
 fn test2<A: Iterator<Item = &'static str>>(x: A) -> I<A> {
     x.chain(once("5"))
 }
diff --git a/tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr b/tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr
index 7cf2fe42da8..d4a2c23f7a7 100644
--- a/tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr
+++ b/tests/ui/type-alias-impl-trait/type_of_a_let.current.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `x`
-  --> $DIR/type_of_a_let.rs:21:16
+  --> $DIR/type_of_a_let.rs:23:16
    |
 LL |     let x: Foo = 22_u32;
    |         - move occurs because `x` has type `Foo`, which does not implement the `Copy` trait
@@ -9,7 +9,7 @@ LL |     same_type((x, y));
    |                ^ value used here after move
 
 error[E0382]: use of moved value: `y`
-  --> $DIR/type_of_a_let.rs:22:6
+  --> $DIR/type_of_a_let.rs:24:6
    |
 LL |     let y: Foo = x;
    |         - move occurs because `y` has type `Foo`, which does not implement the `Copy` trait
diff --git a/tests/ui/type-alias-impl-trait/type_of_a_let.rs b/tests/ui/type-alias-impl-trait/type_of_a_let.rs
index cc8caf886cf..9479b1084df 100644
--- a/tests/ui/type-alias-impl-trait/type_of_a_let.rs
+++ b/tests/ui/type-alias-impl-trait/type_of_a_let.rs
@@ -10,11 +10,13 @@ use std::fmt::Debug;
 
 type Foo = impl Debug;
 
+#[define_opaque(Foo)]
 fn foo1() -> (u32, Foo) {
     let x: Foo = 22_u32;
     (x, todo!())
 }
 
+#[define_opaque(Foo)]
 fn foo2() -> (u32, Foo) {
     let x: Foo = 22_u32;
     let y: Foo = x;
diff --git a/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs b/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs
index 09ff006acbd..063c4deaf06 100644
--- a/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs
+++ b/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs
@@ -2,12 +2,9 @@
 
 #![feature(type_alias_impl_trait)]
 
-mod opaque {
-    pub type Opaque<T> = impl Sized;
-    fn defining<T>() -> Opaque<T> {}
-}
-
-use opaque::Opaque;
+pub type Opaque<T> = impl Sized;
+#[define_opaque(Opaque)]
+fn defining<T>() -> Opaque<T> {}
 
 struct Ss<'a, T>(&'a Opaque<T>);
 
diff --git a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs
index ae3d317ab46..3f4d9d244ec 100644
--- a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs
+++ b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.rs
@@ -3,6 +3,7 @@
 type Tait = impl Copy;
 // Make sure that this TAIT isn't considered unconstrained...
 
+#[define_opaque(Tait)]
 fn empty_opaque() -> Tait {
     if false {
         match empty_opaque() {}
diff --git a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr
index 5c9a4688105..549e3bc8dc1 100644
--- a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr
+++ b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: type `Tait` is non-empty
-  --> $DIR/unconstrained-due-to-bad-pattern.rs:8:15
+  --> $DIR/unconstrained-due-to-bad-pattern.rs:9:15
    |
 LL |         match empty_opaque() {}
    |               ^^^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs
index b3510067047..415021a1808 100644
--- a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs
+++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs
@@ -3,6 +3,7 @@
 use std::fmt::Display;
 
 type Opaque<X> = impl Sized + 'static;
+#[define_opaque(Opaque)]
 fn define<X>() -> Opaque<X> {}
 
 trait Trait {
diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr
index 6206f169c5b..7a86685787c 100644
--- a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr
+++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr
@@ -1,5 +1,5 @@
 error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/unconstrained-impl-param.rs:11:6
+  --> $DIR/unconstrained-impl-param.rs:12:6
    |
 LL | impl<'a> Trait for Opaque<&'a str> {
    |      ^^ unconstrained lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/under-binder.rs b/tests/ui/type-alias-impl-trait/under-binder.rs
index caf21d64027..bf8635b7d81 100644
--- a/tests/ui/type-alias-impl-trait/under-binder.rs
+++ b/tests/ui/type-alias-impl-trait/under-binder.rs
@@ -2,6 +2,7 @@
 
 type Opaque<'a> = impl Sized + 'a;
 
+#[define_opaque(Opaque)]
 fn test(f: fn(u8)) -> fn(Opaque<'_>) {
     f //~ ERROR E0792
 }
diff --git a/tests/ui/type-alias-impl-trait/under-binder.stderr b/tests/ui/type-alias-impl-trait/under-binder.stderr
index f4a121ce440..0589f9ae11c 100644
--- a/tests/ui/type-alias-impl-trait/under-binder.stderr
+++ b/tests/ui/type-alias-impl-trait/under-binder.stderr
@@ -1,5 +1,5 @@
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/under-binder.rs:6:5
+  --> $DIR/under-binder.rs:7:5
    |
 LL | type Opaque<'a> = impl Sized + 'a;
    |             -- this generic parameter must be used with a generic lifetime parameter
diff --git a/tests/ui/type-alias-impl-trait/underconstrained_generic.rs b/tests/ui/type-alias-impl-trait/underconstrained_generic.rs
index aa537dfc917..dc2d37b9d05 100644
--- a/tests/ui/type-alias-impl-trait/underconstrained_generic.rs
+++ b/tests/ui/type-alias-impl-trait/underconstrained_generic.rs
@@ -18,11 +18,10 @@ impl<X: Trait> ProofForConversion<X> for () {
 
 type Converter<T> = impl ProofForConversion<T>;
 
+#[define_opaque(Converter)]
 fn _defining_use<T: Trait>() -> Converter<T> {
     ()
     //~^ ERROR the trait bound `T: Trait` is not satisfied
 }
 
-
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr b/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr
index e50949ed8f3..e05c3094d53 100644
--- a/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr
+++ b/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `T: Trait` is not satisfied
-  --> $DIR/underconstrained_generic.rs:22:5
+  --> $DIR/underconstrained_generic.rs:23:5
    |
 LL |     ()
    |     ^^ the trait `Trait` is not implemented for `T`
@@ -17,7 +17,7 @@ note: required by a bound in an opaque type
 LL | type Converter<T> = impl ProofForConversion<T>;
    |                          ^^^^^^^^^^^^^^^^^^^^^
 note: this definition site has more where clauses than the opaque type
-  --> $DIR/underconstrained_generic.rs:21:1
+  --> $DIR/underconstrained_generic.rs:22:1
    |
 LL | fn _defining_use<T: Trait>() -> Converter<T> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs b/tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs
index e8e7dd0ea08..f4611f33d23 100644
--- a/tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs
+++ b/tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs
@@ -15,6 +15,7 @@ impl<'a, 'b> ProofForConversion<'a, 'b> for &'b &'a () {
 type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
 
 // Even _defining_use with an explicit `'a: 'b` compiles fine, too.
+#[define_opaque(Converter)]
 fn _defining_use<'a, 'b>(x: &'b &'a ()) -> Converter<'a, 'b> {
     x
     //~^ ERROR reference has a longer lifetime than the data it references
diff --git a/tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr b/tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr
index 7c07578d887..6a1f2b49397 100644
--- a/tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr
+++ b/tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr
@@ -1,5 +1,5 @@
 error[E0491]: in type `&'b &'a ()`, reference has a longer lifetime than the data it references
-  --> $DIR/underconstrained_lifetime.rs:19:5
+  --> $DIR/underconstrained_lifetime.rs:20:5
    |
 LL |     x
    |     ^
diff --git a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs
index 56d975355c3..2dab81cba6f 100644
--- a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs
+++ b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs
@@ -5,6 +5,7 @@ mod foo {
     pub trait T {}
 
     pub type Alias<'a> = impl T;
+    //~^ ERROR: unconstrained opaque type
     fn bar() {
         super::with_positive(|&n| ());
         //~^ ERROR mismatched types
diff --git a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr
index 279bd3bca5a..b58eae67120 100644
--- a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr
+++ b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr
@@ -1,9 +1,17 @@
+error: unconstrained opaque type
+  --> $DIR/underef-index-out-of-bounds-121472.rs:7:26
+   |
+LL |     pub type Alias<'a> = impl T;
+   |                          ^^^^^^
+   |
+   = note: `Alias` must be used in combination with a concrete type within the same crate
+
 error[E0308]: mismatched types
-  --> $DIR/underef-index-out-of-bounds-121472.rs:9:31
+  --> $DIR/underef-index-out-of-bounds-121472.rs:10:31
    |
 LL |     pub type Alias<'a> = impl T;
    |                          ------ the expected opaque type
-LL |     fn bar() {
+...
 LL |         super::with_positive(|&n| ());
    |                               ^^
    |                               |
@@ -18,6 +26,6 @@ LL -         super::with_positive(|&n| ());
 LL +         super::with_positive(|n| ());
    |
 
-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/type-alias-impl-trait/unnameable_type.rs b/tests/ui/type-alias-impl-trait/unnameable_type.rs
index 5813f529dea..0b97cc2941f 100644
--- a/tests/ui/type-alias-impl-trait/unnameable_type.rs
+++ b/tests/ui/type-alias-impl-trait/unnameable_type.rs
@@ -16,6 +16,7 @@ use private::Trait;
 // downstream
 type MyPrivate = impl Sized;
 impl Trait for u32 {
+    #[define_opaque(MyPrivate)]
     fn dont_define_this(private: MyPrivate) {
         //~^ ERROR: incompatible type for trait
         let _: () = private;
diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
index 25dc41df419..6e4e024ce69 100644
--- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr
+++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
@@ -1,9 +1,9 @@
 error[E0053]: method `dont_define_this` has an incompatible type for trait
-  --> $DIR/unnameable_type.rs:19:34
+  --> $DIR/unnameable_type.rs:20:34
    |
 LL | type MyPrivate = impl Sized;
    |                  ---------- the found opaque type
-LL | impl Trait for u32 {
+...
 LL |     fn dont_define_this(private: MyPrivate) {
    |                                  ^^^^^^^^^ expected `Private`, found opaque type
    |
diff --git a/tests/ui/type-alias-impl-trait/unused_generic_param.rs b/tests/ui/type-alias-impl-trait/unused_generic_param.rs
index b675bc2e622..556e70d1c96 100644
--- a/tests/ui/type-alias-impl-trait/unused_generic_param.rs
+++ b/tests/ui/type-alias-impl-trait/unused_generic_param.rs
@@ -7,16 +7,19 @@ fn main() {}
 
 type PartiallyDefined<T> = impl Sized;
 
+#[define_opaque(PartiallyDefined)]
 fn partially_defined<T: std::fmt::Debug>(_: T) -> PartiallyDefined<T> {
     4u32
 }
 
 type PartiallyDefined2<T> = impl Sized;
 
+#[define_opaque(PartiallyDefined2)]
 fn partially_defined2<T: std::fmt::Debug>(_: T) -> PartiallyDefined2<T> {
     4u32
 }
 
+#[define_opaque(PartiallyDefined2)]
 fn partially_defined22<T>(_: T) -> PartiallyDefined2<T> {
     4u32
 }
diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs
index 40e8ec0129a..ecd7158223c 100644
--- a/tests/ui/type-alias-impl-trait/variance.rs
+++ b/tests/ui/type-alias-impl-trait/variance.rs
@@ -72,6 +72,7 @@ type NestedDeeply<'a> =
             >,
         >,
     >;
+#[define_opaque(NestedDeeply)]
 fn test<'a>() -> NestedDeeply<'a> {
     &()
 }
diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr
index 79ce8148f19..138e4080c29 100644
--- a/tests/ui/type-alias-impl-trait/variance.stderr
+++ b/tests/ui/type-alias-impl-trait/variance.stderr
@@ -28,7 +28,7 @@ error: unconstrained opaque type
 LL | type NotCapturedEarly<'a> = impl Sized;
    |                             ^^^^^^^^^^
    |
-   = note: `NotCapturedEarly` must be used in combination with a concrete type within the same module
+   = note: `NotCapturedEarly` must be used in combination with a concrete type within the same crate
 
 error: unconstrained opaque type
   --> $DIR/variance.rs:11:26
@@ -36,7 +36,7 @@ error: unconstrained opaque type
 LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `CapturedEarly` must be used in combination with a concrete type within the same module
+   = note: `CapturedEarly` must be used in combination with a concrete type within the same crate
 
 error: unconstrained opaque type
   --> $DIR/variance.rs:14:56
@@ -44,7 +44,7 @@ error: unconstrained opaque type
 LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
    |                                                        ^^^^^^^^^^
    |
-   = note: `NotCapturedLate` must be used in combination with a concrete type within the same module
+   = note: `NotCapturedLate` must be used in combination with a concrete type within the same crate
 
 error: unconstrained opaque type
   --> $DIR/variance.rs:18:49
@@ -52,7 +52,7 @@ error: unconstrained opaque type
 LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `Captured` must be used in combination with a concrete type within the same module
+   = note: `Captured` must be used in combination with a concrete type within the same crate
 
 error: unconstrained opaque type
   --> $DIR/variance.rs:22:27
@@ -60,7 +60,7 @@ error: unconstrained opaque type
 LL | type Bar<'a, 'b: 'b, T> = impl Sized;
    |                           ^^^^^^^^^^
    |
-   = note: `Bar` must be used in combination with a concrete type within the same module
+   = note: `Bar` must be used in combination with a concrete type within the same crate
 
 error: unconstrained opaque type
   --> $DIR/variance.rs:34:32
diff --git a/tests/ui/type-alias-impl-trait/weird-return-types.rs b/tests/ui/type-alias-impl-trait/weird-return-types.rs
index 29d4faa7ba9..05668c836f9 100644
--- a/tests/ui/type-alias-impl-trait/weird-return-types.rs
+++ b/tests/ui/type-alias-impl-trait/weird-return-types.rs
@@ -4,11 +4,12 @@
 #![feature(type_alias_impl_trait)]
 #![allow(dead_code)]
 
-use std::future::Future;
 use std::fmt::Debug;
+use std::future::Future;
 
 type Foo = impl Debug;
 
+#[define_opaque(Foo)]
 fn f() -> impl Future<Output = Foo> {
     async move { 22_u32 }
 }
diff --git a/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs b/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs
index 19dd4c17936..fd5edcc89ee 100644
--- a/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs
+++ b/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs
@@ -14,6 +14,7 @@
 struct Static<T: 'static>(T);
 
 type OpaqueRet<'a> = impl Sized + 'a;
+#[define_opaque(OpaqueRet)]
 fn test_return<'a>(msg: Static<&'static u8>) -> OpaqueRet<'a> {
     msg
 }
@@ -23,9 +24,9 @@ fn test_rpit<'a>(msg: Static<&'static u8>) -> impl Sized + 'a {
 }
 
 type OpaqueAssign<'a> = impl Sized + 'a;
-fn test_assign<'a>(msg: Static<&'static u8>) -> Option<OpaqueAssign<'a>> {
+#[define_opaque(OpaqueAssign)]
+fn test_assign<'a>(msg: Static<&'static u8>) {
     let _: OpaqueAssign<'a> = msg;
-    None
 }
 
 // `OpaqueRef<'a, T> = Ref<'a, T>`, vs
@@ -33,6 +34,7 @@ fn test_assign<'a>(msg: Static<&'static u8>) -> Option<OpaqueAssign<'a>> {
 trait RefAt<'a>: 'a {}
 struct Ref<'a, T: RefAt<'a>>(&'a T);
 type OpaqueRef<'a, T: RefAt<'static>> = impl Sized + 'a;
+#[define_opaque(OpaqueRef)]
 fn test_trait<'a, T: RefAt<'static>>(msg: Ref<'static, T>) -> OpaqueRef<'a, T> {
     msg
 }
diff --git a/tests/ui/type-alias-impl-trait/wf-check-fn-def.rs b/tests/ui/type-alias-impl-trait/wf-check-fn-def.rs
index 449e9fbd0d8..6de2c0ccc37 100644
--- a/tests/ui/type-alias-impl-trait/wf-check-fn-def.rs
+++ b/tests/ui/type-alias-impl-trait/wf-check-fn-def.rs
@@ -6,8 +6,11 @@ trait Bar {
 
 type FooFn<B> = impl FnOnce(B);
 
+#[define_opaque(FooFn)]
 fn foo<B: Bar>() -> FooFn<B> {
-    fn mop<B: Bar>(bar: B) { bar.bar() }
+    fn mop<B: Bar>(bar: B) {
+        bar.bar()
+    }
     mop // NOTE: no function pointer, but function zst item
     //~^ ERROR the trait bound `B: Bar` is not satisfied
 }
diff --git a/tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr b/tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr
index 9046a8a76b8..b52ed3f43f4 100644
--- a/tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr
+++ b/tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr
@@ -1,13 +1,13 @@
 error[E0277]: the trait bound `B: Bar` is not satisfied
-  --> $DIR/wf-check-fn-def.rs:11:5
+  --> $DIR/wf-check-fn-def.rs:14:5
    |
 LL |     mop // NOTE: no function pointer, but function zst item
    |     ^^^ the trait `Bar` is not implemented for `B`
    |
 note: required by a bound in `mop`
-  --> $DIR/wf-check-fn-def.rs:10:15
+  --> $DIR/wf-check-fn-def.rs:11:15
    |
-LL |     fn mop<B: Bar>(bar: B) { bar.bar() }
+LL |     fn mop<B: Bar>(bar: B) {
    |               ^^^ required by this bound in `mop`
 help: consider restricting type parameter `B` with trait `Bar`
    |
diff --git a/tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs b/tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs
index 1484d9fd073..fd9ed533756 100644
--- a/tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs
+++ b/tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs
@@ -8,8 +8,11 @@ trait Bar {
 
 type FooFn<B> = impl FnOnce(B);
 
+#[define_opaque(FooFn)]
 fn foo<B: Bar>() -> FooFn<B> {
-    fn mop<B: Bar>(bar: B) { bar.bar() }
+    fn mop<B: Bar>(bar: B) {
+        bar.bar()
+    }
     mop as fn(B)
     // function pointers don't have any obligations on them,
     // thus the above compiles. It's obviously unsound to just
diff --git a/tests/ui/type-alias-impl-trait/wf-nested.rs b/tests/ui/type-alias-impl-trait/wf-nested.rs
index 56c524c6db0..074ea8703a4 100644
--- a/tests/ui/type-alias-impl-trait/wf-nested.rs
+++ b/tests/ui/type-alias-impl-trait/wf-nested.rs
@@ -19,7 +19,6 @@ impl<T> Trait<&'static T> for () {
     type Out = IsStatic<T>;
 }
 
-
 // We could theoretically allow this (and previously did), as even
 // though the nested opaque is not well-formed, it can only be
 // used by normalizing the projection
@@ -27,6 +26,7 @@ impl<T> Trait<&'static T> for () {
 // Assuming that we check that this projection is well-formed, the wf
 // of the nested opaque is implied.
 type OuterOpaque1<T> = impl Trait<&'static T, Out = impl Sized>;
+#[define_opaque(OuterOpaque1)]
 fn define<T>() -> OuterOpaque1<T> {}
 //~^ ERROR `T` may not live long enough
 
@@ -38,6 +38,7 @@ fn define_rpit<T>() -> impl Trait<&'static T, Out = impl Sized> {}
 // soundness.
 type InnerOpaque<T> = impl Sized;
 type OuterOpaque2<T> = impl Trait<&'static T, Out = InnerOpaque<T>>;
+#[define_opaque(OuterOpaque2)]
 fn define_nested_rpit<T>() -> OuterOpaque2<T> {}
 //~^ ERROR the parameter type `T` may not live long enough
 
diff --git a/tests/ui/type-alias-impl-trait/wf-nested.stderr b/tests/ui/type-alias-impl-trait/wf-nested.stderr
index 6d50e11c5da..d7ac5146c1e 100644
--- a/tests/ui/type-alias-impl-trait/wf-nested.stderr
+++ b/tests/ui/type-alias-impl-trait/wf-nested.stderr
@@ -27,7 +27,7 @@ LL | fn define_rpit<T: 'static>() -> impl Trait<&'static T, Out = impl Sized> {}
    |                 +++++++++
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/wf-nested.rs:41:47
+  --> $DIR/wf-nested.rs:42:47
    |
 LL | fn define_nested_rpit<T>() -> OuterOpaque2<T> {}
    |                                               ^^
diff --git a/tests/ui/type-alias-impl-trait/wf_check_closures.rs b/tests/ui/type-alias-impl-trait/wf_check_closures.rs
index 2c70696ffcf..c633909f513 100644
--- a/tests/ui/type-alias-impl-trait/wf_check_closures.rs
+++ b/tests/ui/type-alias-impl-trait/wf_check_closures.rs
@@ -6,8 +6,9 @@ trait Bar {
 
 type FooFn<B> = impl FnOnce();
 
+#[define_opaque(FooFn)]
 fn foo<B: Bar>(bar: B) -> FooFn<B> {
-    move || { bar.bar() }
+    move || bar.bar()
     //~^ ERROR the trait bound `B: Bar` is not satisfied
 }
 
diff --git a/tests/ui/type-alias-impl-trait/wf_check_closures.stderr b/tests/ui/type-alias-impl-trait/wf_check_closures.stderr
index 4156f0ca96a..57e40445c87 100644
--- a/tests/ui/type-alias-impl-trait/wf_check_closures.stderr
+++ b/tests/ui/type-alias-impl-trait/wf_check_closures.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `B: Bar` is not satisfied
-  --> $DIR/wf_check_closures.rs:10:5
+  --> $DIR/wf_check_closures.rs:11:5
    |
-LL |     move || { bar.bar() }
-   |     ^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B`
+LL |     move || bar.bar()
+   |     ^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B`
    |
 note: required by a bound in `foo`
-  --> $DIR/wf_check_closures.rs:9:11
+  --> $DIR/wf_check_closures.rs:10:11
    |
 LL | fn foo<B: Bar>(bar: B) -> FooFn<B> {
    |           ^^^ required by this bound in `foo`
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs
index 9f1bfd7909e..d7351f2e51a 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item.rs
@@ -181,6 +181,7 @@ trait Trait<T> {}
 impl Trait<usize> for Struct {}
 type Y = impl Trait<_>;
 //~^ ERROR the placeholder `_` is not allowed within types on item signatures for type aliases
+#[define_opaque(Y)]
 fn foo() -> Y {
     Struct
 }
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index c5bf9a47e91..2a4a5a62ab4 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -29,7 +29,7 @@ LL | struct BadStruct2<_, T>(_, T);
    |                   ^ expected identifier, found reserved identifier
 
 error: associated constant in `impl` without body
-  --> $DIR/typeck_type_placeholder_item.rs:206:5
+  --> $DIR/typeck_type_placeholder_item.rs:207:5
    |
 LL |     const C: _;
    |     ^^^^^^^^^^-
@@ -578,13 +578,13 @@ LL | type Y = impl Trait<_>;
    |                     ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:206:14
+  --> $DIR/typeck_type_placeholder_item.rs:207:14
    |
 LL |     const C: _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:194:14
+  --> $DIR/typeck_type_placeholder_item.rs:195:14
    |
 LL |     const D: _ = 42;
    |              ^ not allowed in type signatures
@@ -596,13 +596,13 @@ LL +     const D: i32 = 42;
    |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:209:14
+  --> $DIR/typeck_type_placeholder_item.rs:210:14
    |
 LL |     const D: _ = 42;
    |              ^ not allowed in type signatures
 
 error[E0046]: not all trait items implemented, missing: `F`
-  --> $DIR/typeck_type_placeholder_item.rs:200:1
+  --> $DIR/typeck_type_placeholder_item.rs:201:1
    |
 LL |     type F: std::ops::Fn(_);
    |     ----------------------- `F` from trait
@@ -611,7 +611,7 @@ LL | impl Qux for Struct {
    | ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
-  --> $DIR/typeck_type_placeholder_item.rs:217:31
+  --> $DIR/typeck_type_placeholder_item.rs:218:31
    |
 LL | fn value() -> Option<&'static _> {
    |               ----------------^-
@@ -620,7 +620,7 @@ LL | fn value() -> Option<&'static _> {
    |               help: replace with the correct return type: `Option<&'static u8>`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
-  --> $DIR/typeck_type_placeholder_item.rs:222:17
+  --> $DIR/typeck_type_placeholder_item.rs:223:17
    |
 LL | const _: Option<_> = map(value);
    |                 ^ not allowed in type signatures
@@ -632,7 +632,7 @@ LL + const _: Option<u8> = map(value);
    |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
-  --> $DIR/typeck_type_placeholder_item.rs:226:31
+  --> $DIR/typeck_type_placeholder_item.rs:227:31
    |
 LL | fn evens_squared(n: usize) -> _ {
    |                               ^
@@ -641,13 +641,13 @@ LL | fn evens_squared(n: usize) -> _ {
    |                               help: replace with an appropriate return type: `impl Iterator<Item = usize>`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
-  --> $DIR/typeck_type_placeholder_item.rs:231:10
+  --> $DIR/typeck_type_placeholder_item.rs:232:10
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |          ^ not allowed in type signatures
    |
-note: however, the inferred type `Map<Filter<Range<i32>, {closure@typeck_type_placeholder_item.rs:231:29}>, {closure@typeck_type_placeholder_item.rs:231:49}>` cannot be named
-  --> $DIR/typeck_type_placeholder_item.rs:231:14
+note: however, the inferred type `Map<Filter<Range<i32>, {closure@typeck_type_placeholder_item.rs:232:29}>, {closure@typeck_type_placeholder_item.rs:232:49}>` cannot be named
+  --> $DIR/typeck_type_placeholder_item.rs:232:14
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -695,53 +695,53 @@ LL +         fn fn_test10<T>(&self, _x : T) { }
    |
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
-  --> $DIR/typeck_type_placeholder_item.rs:202:14
+  --> $DIR/typeck_type_placeholder_item.rs:203:14
    |
 LL |     type A = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
-  --> $DIR/typeck_type_placeholder_item.rs:204:14
+  --> $DIR/typeck_type_placeholder_item.rs:205:14
    |
 LL |     type B = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
-  --> $DIR/typeck_type_placeholder_item.rs:190:14
+  --> $DIR/typeck_type_placeholder_item.rs:191:14
    |
 LL |     type B = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:192:14
+  --> $DIR/typeck_type_placeholder_item.rs:193:14
    |
 LL |     const C: _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
-  --> $DIR/typeck_type_placeholder_item.rs:197:26
+  --> $DIR/typeck_type_placeholder_item.rs:198:26
    |
 LL |     type F: std::ops::Fn(_);
    |                          ^ not allowed in type signatures
 
 error[E0015]: cannot call non-const function `map::<u8>` in constants
-  --> $DIR/typeck_type_placeholder_item.rs:222:22
+  --> $DIR/typeck_type_placeholder_item.rs:223:22
    |
 LL | const _: Option<_> = map(value);
    |                      ^^^^^^^^^^
    |
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
-error[E0015]: cannot call non-const method `<std::ops::Range<i32> as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:231:29: 231:32}>` in constants
-  --> $DIR/typeck_type_placeholder_item.rs:231:22
+error[E0015]: cannot call non-const method `<std::ops::Range<i32> as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:232:29: 232:32}>` in constants
+  --> $DIR/typeck_type_placeholder_item.rs:232:22
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |                      ^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
-error[E0015]: cannot call non-const method `<Filter<std::ops::Range<i32>, {closure@$DIR/typeck_type_placeholder_item.rs:231:29: 231:32}> as Iterator>::map::<i32, {closure@$DIR/typeck_type_placeholder_item.rs:231:49: 231:52}>` in constants
-  --> $DIR/typeck_type_placeholder_item.rs:231:45
+error[E0015]: cannot call non-const method `<Filter<std::ops::Range<i32>, {closure@$DIR/typeck_type_placeholder_item.rs:232:29: 232:32}> as Iterator>::map::<i32, {closure@$DIR/typeck_type_placeholder_item.rs:232:49: 232:52}>` in constants
+  --> $DIR/typeck_type_placeholder_item.rs:232:45
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |                                             ^^^^^^^^^^^^^^