public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Add support for Wildcard pattern binding
@ 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:34710b497e44d96b661ee89d50776313ef91b6b2

commit 34710b497e44d96b661ee89d50776313ef91b6b2
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Thu Jan 6 16:57:52 2022 +0000

    Add support for Wildcard pattern binding
    
    Wildcard bindings allow us to bind expression to be unused such as:
    
      let _ = 123;
    
    They are more commonly used in destructuring of tuples such as:
    
      let my_tuple = (1,2);
      let (a,_) = my_tuple;
    
    This is the initial basic support for the basic form of let _ = ...; and
    it also allows us to ignore parameters within functions as well.
    
    Fixes #557

Diff:
---
 gcc/rust/backend/rust-compile-fnparam.h     |  10 +++
 gcc/rust/backend/rust-compile-var-decl.h    |   9 +++
 gcc/rust/hir/rust-ast-lower-pattern.cc      |  11 +++
 gcc/rust/hir/rust-ast-lower-pattern.h       |   2 +
 gcc/rust/hir/tree/rust-hir-path.h           |   5 ++
 gcc/rust/hir/tree/rust-hir-pattern.h        | 103 ++++++++++++++++------------
 gcc/rust/hir/tree/rust-hir.h                |  17 +++++
 gcc/rust/resolve/rust-ast-resolve-pattern.h |  11 +++
 gcc/testsuite/rust/compile/issue-557.rs     |   4 ++
 9 files changed, 128 insertions(+), 44 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h
index 92a735744d1..a7bf52a58b9 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -52,6 +52,16 @@ public:
       fndecl, pattern.get_identifier (), decl_type, address_taken, locus);
   }
 
+  void visit (HIR::WildcardPattern &pattern) override
+  {
+    decl_type = ctx->get_backend ()->immutable_type (decl_type);
+
+    bool address_taken = false;
+    compiled_param
+      = ctx->get_backend ()->parameter_variable (fndecl, "_", decl_type,
+						 address_taken, locus);
+  }
+
 private:
   CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus,
 		  const HIR::FunctionParam &param)
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
index a5c736d4b1c..4b52dcd4346 100644
--- a/gcc/rust/backend/rust-compile-var-decl.h
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -64,6 +64,15 @@ public:
 					     address_taken, locus);
   }
 
+  void visit (HIR::WildcardPattern &pattern) override
+  {
+    translated_type = ctx->get_backend ()->immutable_type (translated_type);
+    compiled_variable
+      = ctx->get_backend ()->local_variable (fndecl, "_", translated_type,
+					     NULL /*decl_var*/, address_taken,
+					     locus);
+  }
+
 private:
   CompileVarDecl (Context *ctx, tree fndecl)
     : HIRCompileBase (ctx), fndecl (fndecl),
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc
index 156f023281b..cdad5237368 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -135,5 +135,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..a8c4d9bd266 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.h
+++ b/gcc/rust/hir/rust-ast-lower-pattern.h
@@ -70,6 +70,8 @@ public:
 
   void visit (AST::TupleStructPattern &pattern) override;
 
+  void visit (AST::WildcardPattern &pattern) override;
+
 private:
   ASTLoweringPattern () : translated (nullptr) {}
 
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index 5bf1be55283..c62ba3f7f62 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -269,6 +269,11 @@ public:
   PathExprSegment &get_root_seg () { return segments.at (0); }
 
   PathExprSegment get_final_segment () const { return segments.back (); }
+
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::PATH;
+  }
 };
 
 /* HIR node representing a path-in-expression pattern (path that allows generic
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index b0b123fa699..8dca54dcb90 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -49,7 +49,7 @@ public:
       has_minus (has_minus), locus (locus), mappings (mappings)
   {}
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override { return locus; }
 
   void accept_vis (HIRFullVisitor &vis) override;
 
@@ -58,6 +58,11 @@ public:
     return mappings;
   }
 
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::LITERAL;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -122,7 +127,7 @@ public:
   IdentifierPattern (IdentifierPattern &&other) = default;
   IdentifierPattern &operator= (IdentifierPattern &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override { return locus; }
 
   bool is_mut () const { return mut == Mutability::Mut; }
 
@@ -135,6 +140,11 @@ public:
 
   Identifier get_identifier () const { return variable_ident; }
 
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::IDENTIFIER;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -157,7 +167,7 @@ public:
     : locus (locus), mappings (mappings)
   {}
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override { return locus; }
 
   void accept_vis (HIRFullVisitor &vis) override;
 
@@ -166,6 +176,11 @@ public:
     return mappings;
   }
 
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::WILDCARD;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -335,7 +350,7 @@ public:
   RangePattern (RangePattern &&other) = default;
   RangePattern &operator= (RangePattern &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override { return locus; }
 
   void accept_vis (HIRFullVisitor &vis) override;
 
@@ -344,6 +359,11 @@ public:
     return mappings;
   }
 
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::RANGE;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -406,6 +426,11 @@ public:
 
   Location get_locus () const override final { return locus; }
 
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::REFERENCE;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -671,7 +696,7 @@ public:
 
   bool has_struct_pattern_elems () const { return !elems.is_empty (); }
 
-  Location get_locus () const { return path.get_locus (); }
+  Location get_locus () const override { return path.get_locus (); }
 
   void accept_vis (HIRFullVisitor &vis) override;
 
@@ -683,6 +708,11 @@ public:
     return mappings;
   }
 
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::STRUCT;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -894,7 +924,7 @@ public:
   TupleStructPattern (TupleStructPattern &&other) = default;
   TupleStructPattern &operator= (TupleStructPattern &&other) = default;
 
-  Location get_locus () const { return path.get_locus (); }
+  Location get_locus () const override { return path.get_locus (); }
 
   void accept_vis (HIRFullVisitor &vis) override;
 
@@ -907,6 +937,11 @@ public:
     return mappings;
   }
 
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::TUPLE_STRUCT;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -940,41 +975,6 @@ protected:
   virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0;
 };
 
-// Class representing TuplePattern patterns where there is only a single pattern
-/*class TuplePatternItemsSingle : public TuplePatternItems {
-    // Pattern pattern;
-    std::unique_ptr<Pattern> pattern;
-
-  public:
-    TuplePatternItemsSingle(Pattern* pattern) : pattern(pattern) {}
-
-    // Copy constructor uses clone
-    TuplePatternItemsSingle(TuplePatternItemsSingle const& other) :
-      pattern(other.pattern->clone_pattern()) {}
-
-    // Destructor - define here if required
-
-    // Overload assignment operator to clone
-    TuplePatternItemsSingle& operator=(TuplePatternItemsSingle const& other) {
-	pattern = other.pattern->clone_pattern();
-
-	return *this;
-    }
-
-    // move constructors
-    TuplePatternItemsSingle(TuplePatternItemsSingle&& other) = default;
-    TuplePatternItemsSingle& operator=(TuplePatternItemsSingle&& other) =
-default;
-
-  protected:
-    // Use covariance to implement clone function as returning this object
-rather than base virtual TuplePatternItemsSingle*
-clone_tuple_pattern_items_impl() const override { return new
-TuplePatternItemsSingle(*this);
-    }
-};*/
-// removed in favour of single-element TuplePatternItemsMultiple
-
 // Class representing TuplePattern patterns where there are multiple patterns
 class TuplePatternItemsMultiple : public TuplePatternItems
 {
@@ -1113,7 +1113,7 @@ public:
     return *this;
   }
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override { return locus; }
 
   void accept_vis (HIRFullVisitor &vis) override;
 
@@ -1122,6 +1122,11 @@ public:
     return mappings;
   }
 
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::TUPLE;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -1170,7 +1175,7 @@ public:
   GroupedPattern (GroupedPattern &&other) = default;
   GroupedPattern &operator= (GroupedPattern &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override { return locus; }
 
   void accept_vis (HIRFullVisitor &vis) override;
 
@@ -1179,6 +1184,11 @@ public:
     return mappings;
   }
 
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::GROUPED;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -1229,7 +1239,7 @@ public:
   SlicePattern (SlicePattern &&other) = default;
   SlicePattern &operator= (SlicePattern &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override { return locus; }
 
   void accept_vis (HIRFullVisitor &vis) override;
 
@@ -1238,6 +1248,11 @@ public:
     return mappings;
   }
 
+  PatternType get_pattern_type () const override final
+  {
+    return PatternType::SLICE;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index 17d207a5c34..532b95b115f 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -314,6 +314,21 @@ protected:
 class Pattern
 {
 public:
+  enum PatternType
+  {
+    PATH,
+    LITERAL,
+    IDENTIFIER,
+    WILDCARD,
+    RANGE,
+    REFERENCE,
+    STRUCT,
+    TUPLE_STRUCT,
+    TUPLE,
+    GROUPED,
+    SLICE,
+  };
+
   // Unique pointer custom clone function
   std::unique_ptr<Pattern> clone_pattern () const
   {
@@ -332,6 +347,8 @@ public:
 
   virtual Location get_locus () const = 0;
 
+  virtual PatternType get_pattern_type () const = 0;
+
 protected:
   // Clone pattern implementation as pure virtual method
   virtual Pattern *clone_pattern_impl () const = 0;
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h
index 57c73ba3456..01a05346b80 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.h
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.h
@@ -83,6 +83,17 @@ public:
 				    pattern.get_is_mut ());
   }
 
+  void visit (AST::WildcardPattern &pattern) override
+  {
+    resolver->get_name_scope ().insert (
+      CanonicalPath::new_seg (pattern.get_node_id (), "_"),
+      pattern.get_node_id (), pattern.get_locus ());
+    resolver->insert_new_definition (pattern.get_node_id (),
+				     Definition{pattern.get_node_id (),
+						parent});
+    resolver->mark_decl_mutability (pattern.get_node_id (), false);
+  }
+
   // cases in a match expression
   void visit (AST::PathInExpression &pattern) override;
 
diff --git a/gcc/testsuite/rust/compile/issue-557.rs b/gcc/testsuite/rust/compile/issue-557.rs
new file mode 100644
index 00000000000..aeb5ba6755b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-557.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-w" }
+fn test(a: i32, _: i32) {
+    let _ = 42 + a;
+}


^ 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 pattern binding 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).