https://gcc.gnu.org/g:c7c0d7d99e46cdf2b468ef5768c62de2d082e049

commit r16-7767-gc7c0d7d99e46cdf2b468ef5768c62de2d082e049
Author: Harishankar <[email protected]>
Date:   Tue Jan 6 19:20:29 2026 +0530

    gccrs: Fix ICE in insert_associated_trait_impl due to recursion
    
    Recursive const blocks containing trait implementations previously caused
    an assertion failure (ICE) because the compiler re-visited existing IDs.
    This patch adds a check to return early if the ID exists, enabling
    graceful handling of recursion.
    
    Fixes Rust-GCC/gccrs#4166
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-typecheck-context.cc 
(insert_associated_trait_impl):
            Prevent ICE by checking for existing ID.
            * typecheck/rust-hir-type-check.h: Update declarations.
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/issue-4166.rs: New test.
    
    Signed-off-by: Harishankar <[email protected]>

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check.h     |  2 +-
 gcc/rust/typecheck/rust-typecheck-context.cc | 10 +++++++---
 gcc/testsuite/rust/compile/issue-4166.rs     | 19 +++++++++++++++++++
 3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check.h 
b/gcc/rust/typecheck/rust-hir-type-check.h
index 36a8834ca268..e356f05c0ea6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -235,7 +235,7 @@ public:
   void insert_trait_reference (DefId id, TraitReference &&ref);
   bool lookup_trait_reference (DefId id, TraitReference **ref);
 
-  void insert_associated_trait_impl (HirId id,
+  bool insert_associated_trait_impl (HirId id,
                                     AssociatedImplTrait &&associated);
   bool lookup_associated_trait_impl (HirId id,
                                     AssociatedImplTrait **associated);
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc 
b/gcc/rust/typecheck/rust-typecheck-context.cc
index 37f88e97ca9e..f2c186fb063d 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -248,13 +248,17 @@ TypeCheckContext::lookup_trait_reference (DefId id, 
TraitReference **ref)
   return true;
 }
 
-void
+bool
 TypeCheckContext::insert_associated_trait_impl (
   HirId id, AssociatedImplTrait &&associated)
 {
-  rust_assert (associated_impl_traits.find (id)
-              == associated_impl_traits.end ());
+  auto it = associated_impl_traits.find (id);
+  if (it != associated_impl_traits.end ())
+    {
+      return false;
+    }
   associated_impl_traits.emplace (id, std::move (associated));
+  return true;
 }
 
 bool
diff --git a/gcc/testsuite/rust/compile/issue-4166.rs 
b/gcc/testsuite/rust/compile/issue-4166.rs
new file mode 100644
index 000000000000..b9042d88cdce
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4166.rs
@@ -0,0 +1,19 @@
+
+pub trait Foo {
+    type Bar;
+    fn foo(bar: Self::bar); // { dg-error "failed to resolve path segment 
using an impl Probe" }
+}
+
+pub struct FooImpl;
+
+const foo_impl: () = {
+    impl Foo for FooImpl {
+        type Bar = ();
+        fn foo(_bar: Self::Bar) { // { dg-error "method .foo. has an 
incompatible type|mismatched types" }
+            // This is the recursive reference that used to cause the ICE
+            let () = foo_impl; 
+        }
+    }
+};
+
+fn main() {}
\ No newline at end of file

Reply via email to