public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Thomas Schwinge <tschwinge@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] Add hir lowering for match-expr Date: Wed, 8 Jun 2022 11:56:49 +0000 (GMT) [thread overview] Message-ID: <20220608115649.85EED3AA88A0@sourceware.org> (raw) https://gcc.gnu.org/g:a688913ac153a85aa803faad9d243e66fd12889d commit a688913ac153a85aa803faad9d243e66fd12889d Author: Philip Herron <philip.herron@embecosm.com> Date: Wed Dec 15 01:06:52 2021 +0000 Add hir lowering for match-expr Diff: --- gcc/rust/Make-lang.in | 1 + gcc/rust/hir/rust-ast-lower-expr.h | 51 ++++++++++++++ gcc/rust/hir/rust-ast-lower-pattern.cc | 115 ++++++++++++++++++++++++++++++++ gcc/rust/hir/rust-ast-lower-pattern.h | 12 ++-- gcc/rust/hir/tree/rust-hir-expr.h | 52 +++------------ gcc/rust/hir/tree/rust-hir-full-decls.h | 1 - gcc/rust/hir/tree/rust-hir-full-test.cc | 10 --- gcc/rust/hir/tree/rust-hir-pattern.h | 62 +---------------- 8 files changed, 187 insertions(+), 117 deletions(-) diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index a4054285bbd..1274578a714 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -76,6 +76,7 @@ GRS_OBJS = \ rust/rust-hir-full-test.o \ rust/rust-hir-map.o \ rust/rust-ast-lower.o \ + rust/rust-ast-lower-pattern.o \ rust/rust-ast-resolve.o \ rust/rust-ast-resolve-pattern.o \ rust/rust-hir-type-check.o \ diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index d6e21946d11..8cd4fb537d1 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -23,6 +23,7 @@ #include "rust-ast-lower-base.h" #include "rust-ast-lower-block.h" #include "rust-ast-lower-struct-field-expr.h" +#include "rust-ast-lower-pattern.h" namespace Rust { namespace HIR { @@ -667,6 +668,56 @@ public: expr.get_outer_attrs (), expr.get_locus ()); } + void visit (AST::MatchExpr &expr) override + { + HIR::Expr *branch_value + = ASTLoweringExpr::translate (expr.get_scrutinee_expr ().get ()); + + std::vector<HIR::MatchCase> match_arms; + for (auto &match_case : expr.get_match_cases ()) + { + HIR::Expr *kase_expr + = ASTLoweringExpr::translate (match_case.get_expr ().get ()); + + HIR::Expr *kase_guard_expr = nullptr; + if (match_case.get_arm ().has_match_arm_guard ()) + { + kase_guard_expr = ASTLoweringExpr::translate ( + match_case.get_arm ().get_guard_expr ().get ()); + } + + std::vector<std::unique_ptr<HIR::Pattern> > match_arm_patterns; + for (auto &pattern : match_case.get_arm ().get_patterns ()) + { + HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ()); + match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn)); + } + + HIR::MatchArm arm (std::move (match_arm_patterns), + std::unique_ptr<HIR::Expr> (kase_guard_expr), + match_case.get_arm ().get_outer_attrs ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + HIR::MatchCase kase (std::move (mapping), std::move (arm), + std::unique_ptr<HIR::Expr> (kase_expr)); + match_arms.push_back (std::move (kase)); + } + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value), + std::move (match_arms), expr.get_inner_attrs (), + expr.get_outer_attrs (), expr.get_locus ()); + } + private: ASTLoweringExpr () : ASTLoweringBase (), translated (nullptr), diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc new file mode 100644 index 00000000000..4ff61cd2a47 --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower-pattern.cc @@ -0,0 +1,115 @@ +// Copyright (C) 2020-2021 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include "rust-ast-lower-pattern.h" +#include "rust-ast-lower-expr.h" + +namespace Rust { +namespace HIR { + +void +ASTLoweringPattern::visit (AST::PathInExpression &pattern) +{ + translated = ASTLowerPathInExpression::translate (&pattern); +} + +void +ASTLoweringPattern::visit (AST::TupleStructPattern &pattern) +{ + HIR::PathInExpression *path + = ASTLowerPathInExpression::translate (&pattern.get_path ()); + + TupleStructItems *lowered = nullptr; + auto &items = pattern.get_items (); + switch (items->get_item_type ()) + { + case AST::TupleStructItems::RANGE: { + // TODO + gcc_unreachable (); + } + break; + + case AST::TupleStructItems::NO_RANGE: { + AST::TupleStructItemsNoRange &items_no_range + = static_cast<AST::TupleStructItemsNoRange &> (*items.get ()); + + std::vector<std::unique_ptr<HIR::Pattern> > patterns; + for (auto &inner_pattern : items_no_range.get_patterns ()) + { + HIR::Pattern *p + = ASTLoweringPattern::translate (inner_pattern.get ()); + patterns.push_back (std::unique_ptr<HIR::Pattern> (p)); + } + + lowered = new HIR::TupleStructItemsNoRange (std::move (patterns)); + } + break; + } + + translated = new HIR::TupleStructPattern ( + *path, std::unique_ptr<HIR::TupleStructItems> (lowered)); +} + +void +ASTLoweringPattern::visit (AST::StructPattern &pattern) +{ + HIR::PathInExpression *path + = ASTLowerPathInExpression::translate (&pattern.get_path ()); + + auto &raw_elems = pattern.get_struct_pattern_elems (); + rust_assert (!raw_elems.has_etc ()); + + std::vector<std::unique_ptr<HIR::StructPatternField> > fields; + for (auto &field : raw_elems.get_struct_pattern_fields ()) + { + HIR::StructPatternField *f = nullptr; + switch (field->get_item_type ()) + { + case AST::StructPatternField::ItemType::TUPLE_PAT: { + // TODO + gcc_unreachable (); + } + break; + + case AST::StructPatternField::ItemType::IDENT_PAT: { + // TODO + gcc_unreachable (); + } + break; + + case AST::StructPatternField::ItemType::IDENT: { + AST::StructPatternFieldIdent &ident + = static_cast<AST::StructPatternFieldIdent &> (*field.get ()); + + f = new HIR::StructPatternFieldIdent ( + ident.get_identifier (), ident.is_ref (), + ident.is_mut () ? Mutability::Mut : Mutability::Imm, + ident.get_outer_attrs (), ident.get_locus ()); + } + break; + } + + fields.push_back (std::unique_ptr<HIR::StructPatternField> (f)); + } + + HIR::StructPatternElements elems (std::move (fields)); + translated = new HIR::StructPattern (*path, std::move (elems)); +} + +} // 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 d7b6a47e3bb..d8c03cef744 100644 --- a/gcc/rust/hir/rust-ast-lower-pattern.h +++ b/gcc/rust/hir/rust-ast-lower-pattern.h @@ -20,7 +20,6 @@ #define RUST_AST_LOWER_PATTERN #include "rust-ast-lower-base.h" -#include "rust-diagnostics.h" namespace Rust { namespace HIR { @@ -34,12 +33,11 @@ public: { ASTLoweringPattern resolver; pattern->accept_vis (resolver); + rust_assert (resolver.translated != nullptr); return resolver.translated; } - virtual ~ASTLoweringPattern () override {} - - void visit (AST::IdentifierPattern &pattern) + void visit (AST::IdentifierPattern &pattern) override { std::unique_ptr<Pattern> to_bind; translated @@ -50,6 +48,12 @@ public: std::move (to_bind)); } + void visit (AST::PathInExpression &pattern) override; + + void visit (AST::StructPattern &pattern) override; + + void visit (AST::TupleStructPattern &pattern) override; + private: ASTLoweringPattern () : translated (nullptr) {} diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 901feda5e31..0e5d97b5c53 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -3681,57 +3681,29 @@ public: std::string as_string () const; }; -/* -// Base "match case" for a match expression - abstract -class MatchCase -{ - MatchArm arm; - -protected: - MatchCase (MatchArm arm) : arm (std::move (arm)) {} - - // Should not require copy constructor or assignment operator overloading - - // Clone function implementation as pure virtual method - virtual MatchCase *clone_match_case_impl () const = 0; - -public: - virtual ~MatchCase () {} - - // Unique pointer custom clone function - std::unique_ptr<MatchCase> clone_match_case () const - { - return std::unique_ptr<MatchCase> (clone_match_case_impl ()); - } - - virtual std::string as_string () const; - - virtual void accept_vis (HIRVisitor &vis) = 0; -}; -*/ - /* A "match case" - a correlated match arm and resulting expression. Not * abstract. */ struct MatchCase { private: + Analysis::NodeMapping mappings; MatchArm arm; std::unique_ptr<Expr> expr; - /* TODO: does whether trailing comma exists need to be stored? currently - * assuming it is only syntactical and has no effect on meaning. */ - public: - MatchCase (MatchArm arm, std::unique_ptr<Expr> expr) - : arm (std::move (arm)), expr (std::move (expr)) + MatchCase (Analysis::NodeMapping mappings, MatchArm arm, + std::unique_ptr<Expr> expr) + : mappings (mappings), arm (std::move (arm)), expr (std::move (expr)) {} MatchCase (const MatchCase &other) - : arm (other.arm), expr (other.expr->clone_expr ()) + : mappings (other.mappings), arm (other.arm), + expr (other.expr->clone_expr ()) {} MatchCase &operator= (const MatchCase &other) { + mappings = other.mappings; arm = other.arm; expr = other.expr->clone_expr (); @@ -3744,6 +3716,8 @@ public: ~MatchCase () = default; std::string as_string () const; + + Analysis::NodeMapping get_mappings () const { return mappings; } }; #if 0 @@ -3841,23 +3815,15 @@ class MatchExpr : public ExprWithBlock { std::unique_ptr<Expr> branch_value; AST::AttrVec inner_attrs; - - // bool has_match_arms; - // MatchArms match_arms; - // std::vector<std::unique_ptr<MatchCase> > match_arms; // inlined from - // MatchArms std::vector<MatchCase> match_arms; - Location locus; public: std::string as_string () const override; - // Returns whether the match expression has any match arms. bool has_match_arms () const { return !match_arms.empty (); } MatchExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> branch_value, - // std::vector<std::unique_ptr<MatchCase> > match_arms, std::vector<MatchCase> match_arms, AST::AttrVec inner_attrs, AST::AttrVec outer_attrs, Location locus) : ExprWithBlock (std::move (mappings), std::move (outer_attrs)), diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h index 3e9d8b24bef..79f3789cb5a 100644 --- a/gcc/rust/hir/tree/rust-hir-full-decls.h +++ b/gcc/rust/hir/tree/rust-hir-full-decls.h @@ -199,7 +199,6 @@ class StructPatternField; class StructPatternFieldTuplePat; class StructPatternFieldIdentPat; class StructPatternFieldIdent; -struct StructPatternElements; class StructPattern; class TupleStructItems; class TupleStructItemsNoRange; diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc index 843e32ca1af..76b88255d9a 100644 --- a/gcc/rust/hir/tree/rust-hir-full-test.cc +++ b/gcc/rust/hir/tree/rust-hir-full-test.cc @@ -2575,16 +2575,6 @@ StructPatternElements::as_string () const } } - str += "\n Etc: "; - if (has_struct_pattern_etc) - { - str += "true"; - } - else - { - str += "false"; - } - return str; } diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h index 4f0bfe61518..1373cc7a491 100644 --- a/gcc/rust/hir/tree/rust-hir-pattern.h +++ b/gcc/rust/hir/tree/rust-hir-pattern.h @@ -377,26 +377,6 @@ protected: } }; -// aka StructPatternEtCetera; potential element in struct pattern -struct StructPatternEtc -{ -private: - AST::AttrVec outer_attrs; - - // should this store location data? - -public: - StructPatternEtc (AST::AttrVec outer_attribs) - : outer_attrs (std::move (outer_attribs)) - {} - - // Creates an empty StructPatternEtc - static StructPatternEtc create_empty () - { - return StructPatternEtc (AST::AttrVec ()); - } -}; - // Base class for a single field in a struct pattern - abstract class StructPatternField { @@ -561,45 +541,24 @@ protected: struct StructPatternElements { private: - // bool has_struct_pattern_fields; std::vector<std::unique_ptr<StructPatternField> > fields; - bool has_struct_pattern_etc; - StructPatternEtc etc; - - // must have at least one of the two and maybe both - - // should this store location data? - public: // Returns whether there are any struct pattern fields bool has_struct_pattern_fields () const { return !fields.empty (); } /* Returns whether the struct pattern elements is entirely empty (no fields, * no etc). */ - bool is_empty () const - { - return !has_struct_pattern_fields () && !has_struct_pattern_etc; - } + bool is_empty () const { return !has_struct_pattern_fields (); } // Constructor for StructPatternElements with both (potentially) - StructPatternElements ( - std::vector<std::unique_ptr<StructPatternField> > fields, - StructPatternEtc etc) - : fields (std::move (fields)), has_struct_pattern_etc (true), - etc (std::move (etc)) - {} - - // Constructor for StructPatternElements with no StructPatternEtc StructPatternElements ( std::vector<std::unique_ptr<StructPatternField> > fields) - : fields (std::move (fields)), has_struct_pattern_etc (false), - etc (StructPatternEtc::create_empty ()) + : fields (std::move (fields)) {} // Copy constructor with vector clone StructPatternElements (StructPatternElements const &other) - : has_struct_pattern_etc (other.has_struct_pattern_etc), etc (other.etc) { fields.reserve (other.fields.size ()); for (const auto &e : other.fields) @@ -609,9 +568,6 @@ public: // Overloaded assignment operator with vector clone StructPatternElements &operator= (StructPatternElements const &other) { - etc = other.etc; - has_struct_pattern_etc = other.has_struct_pattern_etc; - fields.reserve (other.fields.size ()); for (const auto &e : other.fields) fields.push_back (e->clone_struct_pattern_field ()); @@ -637,27 +593,15 @@ public: class StructPattern : public Pattern { PathInExpression path; - - // bool has_struct_pattern_elements; StructPatternElements elems; - // TODO: should this store location data? Accessor uses path location data. - public: std::string as_string () const override; - // Constructs a struct pattern from specified StructPatternElements - StructPattern (PathInExpression struct_path, - StructPatternElements elems - = StructPatternElements::create_empty ()) + StructPattern (PathInExpression struct_path, StructPatternElements elems) : path (std::move (struct_path)), elems (std::move (elems)) {} - /* TODO: constructor to construct via elements included in - * StructPatternElements */ - - /* Returns whether struct pattern has any struct pattern elements (if not, it - * is empty). */ bool has_struct_pattern_elems () const { return !elems.is_empty (); } Location get_locus () const { return path.get_locus (); }
reply other threads:[~2022-06-08 11:56 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220608115649.85EED3AA88A0@sourceware.org \ --to=tschwinge@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).