public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Add support for wildcard patterns within MatchExprs
@ 2022-06-08 11:58 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 11:58 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:6d0892636e9642e75a858c40c45acd1df79c63e1

commit 6d0892636e9642e75a858c40c45acd1df79c63e1
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Thu Jan 6 14:45:15 2022 +0000

    Add support for wildcard patterns within MatchExprs
    
    GCC CASE_LABEL_EXPR's contain operand 0 and 1, operand 0 is used for the
    low value of a case label and operand 1 for a high value. So with this
    CASE_LABEL_EXPR is is possible to support a range of values from low->high
    if set apropriately, but for the wildcard case this is effectively a
    default case which means we set both operand 0 and 1 to NULL_TREE.
    
    Fixes #853

Diff:
---
 gcc/rust/backend/rust-compile-expr.cc             |  7 ----
 gcc/rust/backend/rust-compile-pattern.cc          |  9 ++++
 gcc/rust/backend/rust-compile-pattern.h           |  2 +
 gcc/rust/hir/rust-ast-lower-pattern.cc            | 28 +++++++++++++
 gcc/rust/hir/rust-ast-lower-pattern.h             | 18 ++------
 gcc/rust/typecheck/rust-hir-type-check-expr.h     |  2 +-
 gcc/rust/typecheck/rust-hir-type-check-pattern.cc |  9 ++++
 gcc/rust/typecheck/rust-hir-type-check-pattern.h  | 15 ++++---
 gcc/testsuite/rust/execute/torture/match3.rs      | 51 +++++++++++++++++++++++
 9 files changed, 113 insertions(+), 28 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index b77a4d5d57c..5e43f5a197d 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -275,19 +275,12 @@ CompileExpr::visit (HIR::MatchExpr &expr)
       tree case_label = ctx->get_backend ()->label (
 	fndecl, "" /* empty creates an artificial label */, arm_locus);
 
-      // not sure if we need to add this to the block or if the CASE_LABEL_EXPR
-      // does this implicitly
-      //
-      // tree case_label_decl_statement
-      //   = ctx->get_backend ()->label_definition_statement (case_label);
-
       // setup the bindings for the block
       for (auto &kase_pattern : kase_arm.get_patterns ())
 	{
 	  tree switch_kase_expr
 	    = CompilePatternCaseLabelExpr::Compile (kase_pattern.get (),
 						    case_label, ctx);
-	  // ctx->add_statement (case_label_decl_statement);
 	  ctx->add_statement (switch_kase_expr);
 
 	  CompilePatternBindings::Compile (kase_pattern.get (),
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index e634dbd03c3..27ee48723a5 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -77,6 +77,15 @@ CompilePatternCaseLabelExpr::visit (HIR::TupleStructPattern &pattern)
   CompilePatternCaseLabelExpr::visit (pattern.get_path ());
 }
 
+void
+CompilePatternCaseLabelExpr::visit (HIR::WildcardPattern &pattern)
+{
+  // operand 0 being NULL_TREE signifies this is the default case label see:
+  // tree.def for documentation for CASE_LABEL_EXPR
+  case_label_expr
+    = build_case_label (NULL_TREE, NULL_TREE, associated_case_label);
+}
+
 // setup the bindings
 
 void
diff --git a/gcc/rust/backend/rust-compile-pattern.h b/gcc/rust/backend/rust-compile-pattern.h
index e49f75c70c7..b12ea93007e 100644
--- a/gcc/rust/backend/rust-compile-pattern.h
+++ b/gcc/rust/backend/rust-compile-pattern.h
@@ -40,6 +40,8 @@ public:
 
   void visit (HIR::TupleStructPattern &pattern) override;
 
+  void visit (HIR::WildcardPattern &pattern) override;
+
 private:
   CompilePatternCaseLabelExpr (Context *ctx, tree associated_case_label)
     : HIRCompileBase (ctx), case_label_expr (error_mark_node),
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc
index 156f023281b..4bf3c51caef 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -22,6 +22,23 @@
 namespace Rust {
 namespace HIR {
 
+void
+ASTLoweringPattern::visit (AST::IdentifierPattern &pattern)
+{
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  std::unique_ptr<Pattern> to_bind;
+  translated
+    = new HIR::IdentifierPattern (mapping, pattern.get_ident (),
+				  pattern.get_locus (), pattern.get_is_ref (),
+				  pattern.get_is_mut () ? Mutability::Mut
+							: Mutability::Imm,
+				  std::move (to_bind));
+}
+
 void
 ASTLoweringPattern::visit (AST::PathInExpression &pattern)
 {
@@ -135,5 +152,16 @@ ASTLoweringPattern::visit (AST::StructPattern &pattern)
   translated = new HIR::StructPattern (mapping, *path, std::move (elems));
 }
 
+void
+ASTLoweringPattern::visit (AST::WildcardPattern &pattern)
+{
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 UNKNOWN_LOCAL_DEFID);
+
+  translated = new HIR::WildcardPattern (mapping, pattern.get_locus ());
+}
+
 } // namespace HIR
 } // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.h b/gcc/rust/hir/rust-ast-lower-pattern.h
index bd25b83741e..60a3ad10bd0 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.h
+++ b/gcc/rust/hir/rust-ast-lower-pattern.h
@@ -48,21 +48,7 @@ public:
     return resolver.translated;
   }
 
-  void visit (AST::IdentifierPattern &pattern) override
-  {
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   UNKNOWN_LOCAL_DEFID);
-
-    std::unique_ptr<Pattern> to_bind;
-    translated
-      = new HIR::IdentifierPattern (mapping, pattern.get_ident (),
-				    pattern.get_locus (), pattern.get_is_ref (),
-				    pattern.get_is_mut () ? Mutability::Mut
-							  : Mutability::Imm,
-				    std::move (to_bind));
-  }
+  void visit (AST::IdentifierPattern &pattern) override;
 
   void visit (AST::PathInExpression &pattern) override;
 
@@ -70,6 +56,8 @@ public:
 
   void visit (AST::TupleStructPattern &pattern) override;
 
+  void visit (AST::WildcardPattern &pattern) override;
+
 private:
   ASTLoweringPattern () : translated (nullptr) {}
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 8de736db542..631bc86840a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -1294,7 +1294,7 @@ public:
 	for (auto &pattern : kase_arm.get_patterns ())
 	  {
 	    TyTy::BaseType *kase_arm_ty
-	      = TypeCheckPattern::Resolve (pattern.get ());
+	      = TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty);
 
 	    TyTy::BaseType *checked_kase = scrutinee_tyty->unify (kase_arm_ty);
 	    if (checked_kase->get_kind () == TyTy::TypeKind::ERROR)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 2b939585b82..bc6631201a5 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -219,5 +219,14 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
     }
 }
 
+void
+TypeCheckPattern::visit (HIR::WildcardPattern &pattern)
+{
+  // wildcard patterns within the MatchArm's are simply just the same type as
+  // the parent
+  infered = parent->clone ();
+  infered->set_ref (pattern.get_pattern_mappings ().get_hirid ());
+}
+
 } // namespace Resolver
 } // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.h b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
index ac348fb1297..a5e542dcd72 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
@@ -30,14 +30,14 @@ class TypeCheckPattern : public TypeCheckBase
   using Rust::Resolver::TypeCheckBase::visit;
 
 public:
-  static TyTy::BaseType *Resolve (HIR::Pattern *pattern)
+  static TyTy::BaseType *Resolve (HIR::Pattern *pattern, TyTy::BaseType *parent)
   {
-    TypeCheckPattern resolver;
+    TypeCheckPattern resolver (parent);
     pattern->accept_vis (resolver);
 
-    // FIXME need to check how we do mappings here
     if (resolver.infered == nullptr)
-      return new TyTy::ErrorType (1);
+      return new TyTy::ErrorType (
+	pattern->get_pattern_mappings ().get_hirid ());
 
     return resolver.infered;
   }
@@ -48,10 +48,15 @@ public:
 
   void visit (HIR::TupleStructPattern &pattern) override;
 
+  void visit (HIR::WildcardPattern &pattern) override;
+
 private:
-  TypeCheckPattern () : TypeCheckBase (), infered (nullptr) {}
+  TypeCheckPattern (TyTy::BaseType *parent)
+    : TypeCheckBase (), infered (nullptr), parent (parent)
+  {}
 
   TyTy::BaseType *infered;
+  TyTy::BaseType *parent;
 };
 
 } // namespace Resolver
diff --git a/gcc/testsuite/rust/execute/torture/match3.rs b/gcc/testsuite/rust/execute/torture/match3.rs
new file mode 100644
index 00000000000..3d1fa0cc5e8
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match3.rs
@@ -0,0 +1,51 @@
+// { dg-output "Foo::A\nwildcard\nwildcard\nFoo::D 20 80\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+enum Foo {
+    A,
+    B,
+    C(char),
+    D { x: i64, y: i64 },
+}
+
+fn inspect(f: Foo) {
+    match f {
+        Foo::A => unsafe {
+            let a = "Foo::A\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        },
+        Foo::D { x, y } => unsafe {
+            let a = "Foo::D %i %i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, x, y);
+        },
+        _ => unsafe {
+            let a = "wildcard\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        },
+    }
+}
+
+fn main() -> i32 {
+    let a = Foo::A;
+    let b = Foo::B;
+    let c = Foo::C('x');
+    let d = Foo::D { x: 20, y: 80 };
+
+    inspect(a);
+    inspect(b);
+    inspect(c);
+    inspect(d);
+
+    0
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 11:58 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 11:58 [gcc/devel/rust/master] Add support for wildcard patterns within MatchExprs Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).