From: Ryo Yoshida Date: Sun, 19 Oct 2025 13:45:17 +0000 (+0900) Subject: gccrs: Fix ICE on enum in tuple struct pattern X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f11a2163d88aaa830924c73d4d94acb254bff683;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc index e8467f0c7b8..dd9a49f49dc 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 (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 00000000000..cf751cb407c --- /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'" } + } +}