From 783490da703617b030b29301c844c93fe672f777 Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Tue, 12 Mar 2024 06:03:43 +0000
Subject: [PATCH] Fix stack overflow with recursive associated types

---
 compiler/rustc_ty_utils/src/opaque_types.rs      |  4 ++++
 tests/ui/impl-trait/associated-type-cycle.rs     | 14 ++++++++++++++
 tests/ui/impl-trait/associated-type-cycle.stderr | 12 ++++++++++++
 3 files changed, 30 insertions(+)
 create mode 100644 tests/ui/impl-trait/associated-type-cycle.rs
 create mode 100644 tests/ui/impl-trait/associated-type-cycle.stderr

diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 4a1064b29f6..d86efe6b491 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -240,6 +240,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
                                 continue;
                             }
 
+                            if !self.seen.insert(assoc.def_id.expect_local()) {
+                                return;
+                            }
+
                             let impl_args = alias_ty.args.rebase_onto(
                                 self.tcx,
                                 impl_trait_ref.def_id,
diff --git a/tests/ui/impl-trait/associated-type-cycle.rs b/tests/ui/impl-trait/associated-type-cycle.rs
new file mode 100644
index 00000000000..4c1fc1a0fa6
--- /dev/null
+++ b/tests/ui/impl-trait/associated-type-cycle.rs
@@ -0,0 +1,14 @@
+trait Foo {
+    type Bar;
+    fn foo(self) -> Self::Bar;
+}
+
+impl Foo for Box<dyn Foo> {
+    //~^ ERROR: the value of the associated type `Bar` in `Foo` must be specified
+    type Bar = <Self as Foo>::Bar;
+    fn foo(self) -> <Self as Foo>::Bar {
+        (*self).foo()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/associated-type-cycle.stderr b/tests/ui/impl-trait/associated-type-cycle.stderr
new file mode 100644
index 00000000000..7eef8d1e338
--- /dev/null
+++ b/tests/ui/impl-trait/associated-type-cycle.stderr
@@ -0,0 +1,12 @@
+error[E0191]: the value of the associated type `Bar` in `Foo` must be specified
+  --> $DIR/associated-type-cycle.rs:6:22
+   |
+LL |     type Bar;
+   |     -------- `Bar` defined here
+...
+LL | impl Foo for Box<dyn Foo> {
+   |                      ^^^ help: specify the associated type: `Foo<Bar = Type>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0191`.