]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: [E0164] Neither tuple struct nor tuple variant used as a pattern
authorMuhammad Mahad <mahadtxt@gmail.com>
Wed, 16 Aug 2023 12:40:09 +0000 (17:40 +0500)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 18:00:31 +0000 (19:00 +0100)
Checking if pattern has items, before returing solves ICE.
Added error code and rich location.
Also, fixes https://github.com/Rust-GCC/gccrs/issues/2430

gcc/rust/ChangeLog:

* ast/rust-pattern.h: No need of assertion, we are handling it.
* resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit):
Added check which emits error instead of using assertion.
* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit):
Added rich location and error code.

gcc/testsuite/ChangeLog:

* rust/compile/match5.rs:
Updated comment for dejagnu.
* rust/compile/pattern-struct.rs: New test for ICE.

Signed-off-by: Muhammad Mahad <mahadtxt@gmail.com>
gcc/rust/ast/rust-pattern.h
gcc/rust/resolve/rust-early-name-resolver.cc
gcc/rust/typecheck/rust-hir-type-check-pattern.cc
gcc/testsuite/rust/compile/match5.rs
gcc/testsuite/rust/compile/pattern-struct.rs [new file with mode: 0644]

index 95655f5c097e7f25a78e1b58b827c392f0899737..18fe99957901d574b61cf3a7c6eb472226a553aa 100644 (file)
@@ -1176,12 +1176,7 @@ public:
 
   void accept_vis (ASTVisitor &vis) override;
 
-  // TODO: seems kinda dodgy. Think of better way.
-  std::unique_ptr<TupleStructItems> &get_items ()
-  {
-    rust_assert (has_items ());
-    return items;
-  }
+  std::unique_ptr<TupleStructItems> &get_items () { return items; }
 
   PathInExpression &get_path () { return path; }
   const PathInExpression &get_path () const { return path; }
index 47d4e1b7bd1fcdb5b23ae3dd49d8b7f53bdc2c34..5b701f5c0c1af7642407a00d5fd0cff09520c2a4 100644 (file)
@@ -1105,6 +1105,16 @@ EarlyNameResolver::visit (AST::TupleStructItemsRange &tuple_items)
 void
 EarlyNameResolver::visit (AST::TupleStructPattern &pattern)
 {
+  if (!pattern.has_items ())
+    {
+      rich_location rich_locus (line_table, pattern.get_locus ());
+      rich_locus.add_fixit_replace (
+       "function calls are not allowed in patterns");
+      rust_error_at (
+       rich_locus, ErrorCode::E0164,
+       "expected tuple struct or tuple variant, found associated function");
+      return;
+    }
   pattern.get_items ()->accept_vis (*this);
 }
 
index 97370454bbd12ed873056c4c28060b0044dcdb80..18e9b3442ac8322b83030d8d5fad8ab1d19b40b7 100644 (file)
@@ -76,14 +76,16 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
     }
 
   // error[E0532]: expected tuple struct or tuple variant, found struct variant
-  // `Foo::D`
+  // `Foo::D`, E0532 by rustc 1.49.0 , E0164 by rustc 1.71.0
   if (variant->get_variant_type () != TyTy::VariantDef::VariantType::TUPLE)
     {
       std::string variant_type
        = TyTy::VariantDef::variant_type_string (variant->get_variant_type ());
 
+      rich_location rich_locus (line_table, pattern.get_locus ());
+      rich_locus.add_fixit_replace ("not a tuple struct or tuple variant");
       rust_error_at (
-       pattern.get_locus (),
+       rich_locus, ErrorCode::E0164,
        "expected tuple struct or tuple variant, found %s variant %<%s::%s%>",
        variant_type.c_str (), adt->get_name ().c_str (),
        variant->get_identifier ().c_str ());
index a5f934d6aebf020982142011de38048560484aef..6741ee8664ffc5efc571d9dd8fe42121e7569073 100644 (file)
@@ -10,6 +10,6 @@ fn inspect(f: Foo) {
         Foo::A => {}
         Foo::B => {}
         Foo::C(a) => {}
-        Foo::D(x, y) => {} // { dg-error "expected tuple struct or tuple variant, found struct variant 'Foo::D'" }
+        Foo::D(x, y) => {} // { dg-error "expected tuple struct or tuple variant, found struct variant .Foo::D." }
     }
 }
diff --git a/gcc/testsuite/rust/compile/pattern-struct.rs b/gcc/testsuite/rust/compile/pattern-struct.rs
new file mode 100644 (file)
index 0000000..1727509
--- /dev/null
@@ -0,0 +1,18 @@
+fn main() {
+    enum A {
+        B,
+        C,
+    }
+
+    impl A {
+        fn new() {}
+    }
+
+    fn bar(foo: A) {
+        match foo {
+            A::new() => (), 
+            // { dg-error "expected tuple struct or tuple variant, found associated function" "" { target *-*-* } .-1 }
+            _ => {}
+        }
+    }
+}