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

commit r16-4895-gf11a2163d88aaa830924c73d4d94acb254bff683
Author: Ryo Yoshida <[email protected]>
Date:   Sun Oct 19 22:45:17 2025 +0900

    gccrs: Fix ICE on enum in tuple struct pattern
    
    When we typecheck a tuple struct pattern and the type of its path is
    an enum, it may refer to the enum itself and not a variant. Emit an
    E0532 error on such cases.
    
    Fixes Rust-GCC/gccrs#3917
    Fixes Rust-GCC/gccrs#3918
    Fixes Rust-GCC/gccrs#3926
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-hir-type-check-pattern.cc 
(TypeCheckPattern::visit): Emit
            an error when the path refers to an enum itself rather than its 
variant.
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/match-tuplestructpattern-non-variant.rs: New test.
    
    Signed-off-by: Ryo Yoshida <[email protected]>

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-pattern.cc    | 19 ++++++++++++++++---
 .../compile/match-tuplestructpattern-non-variant.rs  | 20 ++++++++++++++++++++
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc 
b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index e8467f0c7b8a..dd9a49f49dc5 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -162,19 +162,32 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
 
   infered = pattern_ty;
   TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered);
-  rust_assert (adt->number_of_variants () > 0);
 
-  TyTy::VariantDef *variant = adt->get_variants ().at (0);
+  TyTy::VariantDef *variant = nullptr;
   if (adt->is_enum ())
     {
       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)
+       {
+         rust_error_at (
+           pattern.get_locus (), ErrorCode::E0532,
+           "expected tuple struct or tuple variant, found enum %qs",
+           pattern_ty->get_name ().c_str ());
+         return;
+       }
 
       ok = adt->lookup_variant_by_id (variant_id, &variant);
       rust_assert (ok);
     }
+  else
+    {
+      rust_assert (adt->number_of_variants () > 0);
+      variant = adt->get_variants ().at (0);
+    }
+
+  rust_assert (variant != nullptr);
 
   // error[E0532]: expected tuple struct or tuple variant, found struct
   // variant `Foo::D`, E0532 by rustc 1.49.0 , E0164 by rustc 1.71.0
diff --git a/gcc/testsuite/rust/compile/match-tuplestructpattern-non-variant.rs 
b/gcc/testsuite/rust/compile/match-tuplestructpattern-non-variant.rs
new file mode 100644
index 000000000000..cf751cb407cf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-tuplestructpattern-non-variant.rs
@@ -0,0 +1,20 @@
+enum Empty {}
+enum NonEmpty {
+    Foo(i32),
+}
+
+fn f(e: Empty) {
+    match e { 
+        Empty(0) => {} // { dg-error "expected tuple struct or tuple variant, 
found enum 'Empty'" }
+    }
+
+    match e {
+        Empty(Empty(..)) => {} // { dg-error "expected tuple struct or tuple 
variant, found enum 'Empty'" }
+    }
+}
+
+fn g(e: NonEmpty) {
+    match e {
+        NonEmpty(0) => {} // { dg-error "expected tuple struct or tuple 
variant, found enum 'NonEmpty'" }
+    }
+}

Reply via email to