From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 4DFD33AA8C4A; Wed, 8 Jun 2022 11:58:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4DFD33AA8C4A Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] Add support for Wildcard pattern binding X-Act-Checkin: gcc X-Git-Author: Philip Herron X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: 69f6be3ee483c9895b4b5187a44b3e1c8be2ba63 X-Git-Newrev: 34710b497e44d96b661ee89d50776313ef91b6b2 Message-Id: <20220608115846.4DFD33AA8C4A@sourceware.org> Date: Wed, 8 Jun 2022 11:58:46 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jun 2022 11:58:46 -0000 https://gcc.gnu.org/g:34710b497e44d96b661ee89d50776313ef91b6b2 commit 34710b497e44d96b661ee89d50776313ef91b6b2 Author: Philip Herron 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 ¶m) 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; - - 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 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; +}