[COMMITTED 07/32] gccrs: Fix ICE on invalid match arms

arthur.cohen@embecosm.com arthur.cohen@embecosm.com
Tue Apr 8 08:17:16 GMT 2025


From: Philip Herron <herron.philip@googlemail.com>

We hit assertions on empty enum or unknown variant, this catches the error
and emits a new diagnostic.

Fixes Rust-GCC#3656

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): emit error

gcc/testsuite/ChangeLog:

	* rust/compile/issue-3656.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
---
 .../typecheck/rust-hir-type-check-pattern.cc  | 21 +++++++++++++++++--
 gcc/testsuite/rust/compile/issue-3656.rs      | 10 +++++++++
 2 files changed, 29 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3656.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 3f9557a5c3e..bd13f7a5618 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -277,7 +277,15 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
 
   infered = pattern_ty;
   TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered);
-  rust_assert (adt->number_of_variants () > 0);
+  if (adt->number_of_variants () == 0)
+    {
+      HIR::PathInExpression &path = pattern.get_path ();
+      const AST::SimplePath &sp = path.as_simple_path ();
+      rust_error_at (pattern.get_locus (), ErrorCode::E0574,
+		     "expected struct, variant or union type, found enum %qs",
+		     sp.as_string ().c_str ());
+      return;
+    }
 
   TyTy::VariantDef *variant = adt->get_variants ().at (0);
   if (adt->is_enum ())
@@ -285,7 +293,16 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
       HirId variant_id = UNKNOWN_HIRID;
       bool ok = context->lookup_variant_definition (
 	pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
-      rust_assert (ok);
+      if (!ok)
+	{
+	  HIR::PathInExpression &path = pattern.get_path ();
+	  const AST::SimplePath &sp = path.as_simple_path ();
+	  rust_error_at (
+	    pattern.get_locus (), ErrorCode::E0574,
+	    "expected struct, variant or union type, found enum %qs",
+	    sp.as_string ().c_str ());
+	  return;
+	}
 
       ok = adt->lookup_variant_by_id (variant_id, &variant);
       rust_assert (ok);
diff --git a/gcc/testsuite/rust/compile/issue-3656.rs b/gcc/testsuite/rust/compile/issue-3656.rs
new file mode 100644
index 00000000000..e0bec2fa4a6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3656.rs
@@ -0,0 +1,10 @@
+enum Foo {
+    Bar(isize),
+}
+
+fn main() {
+    match Foo::Bar(205) {
+        Foo { i } => (),
+        // { dg-error "expected struct, variant or union type, found enum .Foo. .E0574." "" { target *-*-* } .-1 }
+    }
+}
-- 
2.49.0



More information about the Gcc-rust mailing list