]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix ICE in insert_associated_trait_impl due to recursion
authorHarishankar <harishankarpp7@gmail.com>
Tue, 6 Jan 2026 13:50:29 +0000 (19:20 +0530)
committerArthur Cohen <arthur.cohen@embecosm.com>
Fri, 27 Feb 2026 14:57:04 +0000 (15:57 +0100)
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 <harishankarpp7@gmail.com>
gcc/rust/typecheck/rust-hir-type-check.h
gcc/rust/typecheck/rust-typecheck-context.cc
gcc/testsuite/rust/compile/issue-4166.rs [new file with mode: 0644]

index 36a8834ca268c60a7a9b3290d703008d3a427d9f..e356f05c0ea6c8f9eb82e3ce40cfbb13f90b134e 100644 (file)
@@ -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);
index 37f88e97ca9e954c1eaafcc54baa15851d0fa5f9..f2c186fb063d546ef8425b25c15f04fb8cf706b9 100644 (file)
@@ -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 (file)
index 0000000..b9042d8
--- /dev/null
@@ -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