From: Harishankar <[email protected]>

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]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/341fc108d9402cd8b63479aa9d85b5fafb49803f

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4361

 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(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-4166.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check.h 
b/gcc/rust/typecheck/rust-hir-type-check.h
index 36a8834ca..e356f05c0 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 37f88e97c..f2c186fb0 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 000000000..b9042d88c
--- /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

base-commit: edad96f60e57b6a2938b6c5f41e17b4da3590cd8
-- 
2.52.0

Reply via email to