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