diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index f7d54566cb704..9242a1a751bc7 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -121,6 +121,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
 }
 
 impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
+    #[instrument(skip(self), ret, level = "trace")]
     fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> ControlFlow<!> {
         self.visit_spanned(span, value);
         ControlFlow::Continue(())
diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs
index 1ab39974e0f2a..ccdc6120196ac 100644
--- a/compiler/rustc_ty_utils/src/sig_types.rs
+++ b/compiler/rustc_ty_utils/src/sig_types.rs
@@ -4,7 +4,7 @@
 use std::ops::ControlFlow;
 
 use rustc_hir::{def::DefKind, def_id::LocalDefId};
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
 use rustc_type_ir::visit::TypeVisitable;
 
@@ -25,24 +25,9 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
     let kind = tcx.def_kind(item);
     trace!(?kind);
     match kind {
-        DefKind::Coroutine => {
-            match tcx.type_of(item).instantiate_identity().kind() {
-                ty::Coroutine(_, args, _) => visitor.visit(tcx.def_span(item), args.as_coroutine().sig())?,
-                _ => bug!(),
-            }
-            for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
-                visitor.visit(span, pred)?;
-            }
-        }
-        // Walk over the signature of the function-like
-        DefKind::Closure | DefKind::AssocFn | DefKind::Fn => {
-            let ty_sig = match kind {
-                DefKind::Closure => match tcx.type_of(item).instantiate_identity().kind() {
-                    ty::Closure(_, args) => args.as_closure().sig(),
-                    _ => bug!(),
-                },
-                _ => tcx.fn_sig(item).instantiate_identity(),
-            };
+        // Walk over the signature of the function
+        DefKind::AssocFn | DefKind::Fn => {
+            let ty_sig = tcx.fn_sig(item).instantiate_identity();
             let hir_sig = tcx.hir().get_by_def_id(item).fn_decl().unwrap();
             // Walk over the inputs and outputs manually in order to get good spans for them.
             visitor.visit(hir_sig.output.span(), ty_sig.output());
@@ -61,7 +46,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
                 Some(ty) => ty.span,
                 _ => tcx.def_span(item),
             };
-            visitor.visit(span,  tcx.type_of(item).instantiate_identity());
+            visitor.visit(span, tcx.type_of(item).instantiate_identity());
             for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
                 visitor.visit(span, pred)?;
             }
@@ -74,13 +59,15 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
         // Look at field types
         DefKind::Struct | DefKind::Union | DefKind::Enum => {
             let span = tcx.def_ident_span(item).unwrap();
-            visitor.visit(span,  tcx.type_of(item).instantiate_identity());
+            visitor.visit(span, tcx.type_of(item).instantiate_identity());
             for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
                 visitor.visit(span, pred)?;
             }
         }
-        // Does not have a syntactical signature
-        DefKind::InlineConst => {}
+        // These are not part of a public API, they can only appear as hidden types, and there
+        // the interesting parts are solely in the signature of the containing item's opaque type
+        // or dyn type.
+        DefKind::InlineConst | DefKind::Closure | DefKind::Coroutine => {}
         DefKind::Impl { of_trait } => {
             if of_trait {
                 let span = tcx.hir().get_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
@@ -92,15 +79,11 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
                 _ => tcx.def_span(item),
             };
             visitor.visit(span, tcx.type_of(item).instantiate_identity());
-            for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
-                visitor.visit(span, pred)?;
-            }}
-        DefKind::Trait => {
             for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
                 visitor.visit(span, pred)?;
             }
         }
-        DefKind::TraitAlias => {
+        DefKind::TraitAlias | DefKind::Trait => {
             for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
                 visitor.visit(span, pred)?;
             }
diff --git a/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs
new file mode 100644
index 0000000000000..5f3dbaa179891
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs
@@ -0,0 +1,44 @@
+//! This test checks that we do not walk types in async blocks for
+//! determining the opaque types that appear in a signature. async blocks,
+//! all other coroutines and closures are always private and not part of
+//! a signature. They become part of a signature via `dyn Trait` or `impl Trait`,
+//! which is something that we process abstractly without looking at its hidden
+//! types.
+// edition: 2021
+// check-pass
+
+#![feature(impl_trait_in_assoc_type)]
+
+use std::future::Future;
+
+pub struct MemtableLocalStateStore {
+    mem_table: MemTable,
+}
+
+impl LocalStateStore for MemtableLocalStateStore {
+    type IterStream<'a> = impl Sized + 'a where Self: 'a;
+
+    fn iter(&self) -> impl Future<Output = Self::IterStream<'_>> + '_ {
+        async move { merge_stream(self.mem_table.iter()) }
+    }
+}
+
+trait LocalStateStore {
+    type IterStream<'a>
+    where
+        Self: 'a;
+
+    fn iter(&self) -> impl Future<Output = Self::IterStream<'_>> + '_;
+}
+
+struct MemTable;
+
+impl MemTable {
+    fn iter<'a>(&'a self) -> impl Iterator<Item = &'a ()> {
+        std::iter::empty()
+    }
+}
+
+pub(crate) async fn merge_stream<'a>(mem_table_iter: impl Iterator<Item = &'a ()>) {}
+
+fn main() {}