From: Ryo Yoshida <[email protected]>
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]>
---
.../typecheck/rust-hir-type-check-pattern.cc | 19 +++++++++++++++---
.../match-tuplestructpattern-non-variant.rs | 20 +++++++++++++++++++
2 files changed, 36 insertions(+), 3 deletions(-)
create mode 100644
gcc/testsuite/rust/compile/match-tuplestructpattern-non-variant.rs
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<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 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'" }
+ }
+}
--
2.50.1