aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-12-16 10:47:11 +0000
committerGitHub <noreply@github.com>2021-12-16 10:47:11 +0000
commit83a984b1a12694d8e06eb139089429b61e236fdd (patch)
tree715954488f9c719a3db3d98d29e8828df325c750 /gcc
parent768f926074a27a7b1a2179613eeeb8291648b8a7 (diff)
parenta688913ac153a85aa803faad9d243e66fd12889d (diff)
downloadgcc-83a984b1a12694d8e06eb139089429b61e236fdd.zip
gcc-83a984b1a12694d8e06eb139089429b61e236fdd.tar.gz
gcc-83a984b1a12694d8e06eb139089429b61e236fdd.tar.bz2
Merge #835
835: Add name-resolution and HIR lowering pass for MatchExpr r=philberty a=philberty This adds the name-resolution and HIR lowering pass for the match-expr the type checking pass patch needs some work to be split up but these are two nice isolated commits which are easier to read. Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in2
-rw-r--r--gcc/rust/ast/rust-expr.h9
-rw-r--r--gcc/rust/ast/rust-pattern.h61
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h51
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.cc115
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.h12
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h52
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-decls.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc10
-rw-r--r--gcc/rust/hir/tree/rust-hir-pattern.h62
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h36
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.cc104
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.h7
13 files changed, 396 insertions, 126 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 3a5e7cc..1274578 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -76,7 +76,9 @@ 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 \
rust/rust-tyty.o \
rust/rust-tyctx.o \
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 7f6714a..48dcc10 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4337,23 +4337,26 @@ struct MatchCase
private:
MatchArm arm;
std::unique_ptr<Expr> expr;
+ NodeId node_id;
/* 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))
+ : arm (std::move (arm)), expr (std::move (expr)),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
MatchCase (const MatchCase &other)
- : arm (other.arm), expr (other.expr->clone_expr ())
+ : arm (other.arm), expr (other.expr->clone_expr ()), node_id (other.node_id)
{}
MatchCase &operator= (const MatchCase &other)
{
arm = other.arm;
expr = other.expr->clone_expr ();
+ node_id = other.node_id;
return *this;
}
@@ -4378,6 +4381,8 @@ public:
rust_assert (!arm.is_error ());
return arm;
}
+
+ NodeId get_node_id () const { return node_id; }
};
#if 0
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index b2c3686..d46bf0e 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -456,7 +456,17 @@ class StructPatternField
std::vector<Attribute> outer_attrs;
Location locus;
+protected:
+ NodeId node_id;
+
public:
+ enum ItemType
+ {
+ TUPLE_PAT,
+ IDENT_PAT,
+ IDENT
+ };
+
virtual ~StructPatternField () {}
// Unique pointer custom clone function
@@ -474,14 +484,18 @@ public:
virtual void mark_for_strip () = 0;
virtual bool is_marked_for_strip () const = 0;
+ virtual ItemType get_item_type () const = 0;
+
+ NodeId get_node_id () const { return node_id; }
// TODO: seems kinda dodgy. Think of better way.
std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
protected:
- StructPatternField (std::vector<Attribute> outer_attribs, Location locus)
- : outer_attrs (std::move (outer_attribs)), locus (locus)
+ StructPatternField (std::vector<Attribute> outer_attribs, Location locus,
+ NodeId node_id)
+ : outer_attrs (std::move (outer_attribs)), locus (locus), node_id (node_id)
{}
// Clone function implementation as pure virtual method
@@ -499,8 +513,9 @@ public:
std::unique_ptr<Pattern> tuple_pattern,
std::vector<Attribute> outer_attribs,
Location locus)
- : StructPatternField (std::move (outer_attribs), locus), index (index),
- tuple_pattern (std::move (tuple_pattern))
+ : StructPatternField (std::move (outer_attribs), locus,
+ Analysis::Mappings::get ()->get_next_node_id ()),
+ index (index), tuple_pattern (std::move (tuple_pattern))
{}
// Copy constructor requires clone
@@ -508,6 +523,7 @@ public:
: StructPatternField (other), index (other.index)
{
// guard to prevent null dereference (only required if error state)
+ node_id = other.get_node_id ();
if (other.tuple_pattern != nullptr)
tuple_pattern = other.tuple_pattern->clone_pattern ();
}
@@ -519,6 +535,7 @@ public:
StructPatternField::operator= (other);
index = other.index;
// outer_attrs = other.outer_attrs;
+ node_id = other.get_node_id ();
// guard to prevent null dereference (only required if error state)
if (other.tuple_pattern != nullptr)
@@ -552,6 +569,8 @@ public:
return tuple_pattern;
}
+ ItemType get_item_type () const override final { return ItemType::TUPLE_PAT; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -572,7 +591,8 @@ public:
std::unique_ptr<Pattern> ident_pattern,
std::vector<Attribute> outer_attrs,
Location locus)
- : StructPatternField (std::move (outer_attrs), locus),
+ : StructPatternField (std::move (outer_attrs), locus,
+ Analysis::Mappings::get ()->get_next_node_id ()),
ident (std::move (ident)), ident_pattern (std::move (ident_pattern))
{}
@@ -581,6 +601,7 @@ public:
: StructPatternField (other), ident (other.ident)
{
// guard to prevent null dereference (only required if error state)
+ node_id = other.get_node_id ();
if (other.ident_pattern != nullptr)
ident_pattern = other.ident_pattern->clone_pattern ();
}
@@ -592,6 +613,7 @@ public:
StructPatternField::operator= (other);
ident = other.ident;
// outer_attrs = other.outer_attrs;
+ node_id = other.get_node_id ();
// guard to prevent null dereference (only required if error state)
if (other.ident_pattern != nullptr)
@@ -618,6 +640,8 @@ public:
return ident_pattern == nullptr;
}
+ const Identifier &get_identifier () const { return ident; }
+
// TODO: is this better? Or is a "vis_pattern" better?
std::unique_ptr<Pattern> &get_ident_pattern ()
{
@@ -625,6 +649,8 @@ public:
return ident_pattern;
}
+ ItemType get_item_type () const override final { return ItemType::IDENT_PAT; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -644,8 +670,9 @@ class StructPatternFieldIdent : public StructPatternField
public:
StructPatternFieldIdent (Identifier ident, bool is_ref, bool is_mut,
std::vector<Attribute> outer_attrs, Location locus)
- : StructPatternField (std::move (outer_attrs), locus), has_ref (is_ref),
- has_mut (is_mut), ident (std::move (ident))
+ : StructPatternField (std::move (outer_attrs), locus,
+ Analysis::Mappings::get ()->get_next_node_id ()),
+ has_ref (is_ref), has_mut (is_mut), ident (std::move (ident))
{}
std::string as_string () const override;
@@ -656,6 +683,14 @@ public:
void mark_for_strip () override { ident = {}; }
bool is_marked_for_strip () const override { return ident.empty (); }
+ const Identifier &get_identifier () const { return ident; }
+
+ ItemType get_item_type () const override final { return ItemType::IDENT; }
+
+ bool is_ref () const { return has_ref; }
+
+ bool is_mut () const { return has_mut; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -827,6 +862,12 @@ protected:
class TupleStructItems
{
public:
+ enum ItemType
+ {
+ RANGE,
+ NO_RANGE
+ };
+
virtual ~TupleStructItems () {}
// TODO: should this store location data?
@@ -841,6 +882,8 @@ public:
virtual void accept_vis (ASTVisitor &vis) = 0;
+ virtual ItemType get_item_type () const = 0;
+
protected:
// pure virtual clone implementation
virtual TupleStructItems *clone_tuple_struct_items_impl () const = 0;
@@ -890,6 +933,8 @@ public:
return patterns;
}
+ ItemType get_item_type () const override final { return ItemType::NO_RANGE; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -966,6 +1011,8 @@ public:
return upper_patterns;
}
+ ItemType get_item_type () const override final { return ItemType::RANGE; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index d6e2194..8cd4fb5 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 0000000..4ff61cd
--- /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 d7b6a47..d8c03ce 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 901feda..0e5d97b 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 3e9d8b2..79f3789 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 843e32c..76b8825 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 4f0bfe6..1373cc7 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 (); }
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 05d116f..5f496a6 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -24,6 +24,7 @@
#include "rust-ast-resolve-struct-expr-field.h"
#include "rust-ast-verify-assignee.h"
#include "rust-ast-resolve-type.h"
+#include "rust-ast-resolve-pattern.h"
namespace Rust {
namespace Resolver {
@@ -409,6 +410,41 @@ public:
ResolveExpr::go (expr.get_dereferenced_expr ().get (), expr.get_node_id ());
}
+ void visit (AST::MatchExpr &expr) override
+ {
+ ResolveExpr::go (expr.get_scrutinee_expr ().get (), expr.get_node_id ());
+ for (auto &match_case : expr.get_match_cases ())
+ {
+ // each arm is in its own scope
+ NodeId scope_node_id = match_case.get_node_id ();
+ resolver->get_name_scope ().push (scope_node_id);
+ resolver->get_type_scope ().push (scope_node_id);
+ resolver->get_label_scope ().push (scope_node_id);
+ resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
+ resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
+ resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+
+ // resolve
+ AST::MatchArm &arm = match_case.get_arm ();
+ if (arm.has_match_arm_guard ())
+ ResolveExpr::go (arm.get_guard_expr ().get (), expr.get_node_id ());
+
+ // insert any possible new patterns
+ for (auto &pattern : arm.get_patterns ())
+ {
+ PatternDeclaration::go (pattern.get (), expr.get_node_id ());
+ }
+
+ // resolve the body
+ ResolveExpr::go (match_case.get_expr ().get (), expr.get_node_id ());
+
+ // done
+ resolver->get_name_scope ().pop ();
+ resolver->get_type_scope ().pop ();
+ resolver->get_label_scope ().pop ();
+ }
+ }
+
private:
ResolveExpr (NodeId parent) : ResolverBase (parent) {}
};
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
new file mode 100644
index 0000000..c97a83f
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
@@ -0,0 +1,104 @@
+// 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-resolve-pattern.h"
+#include "rust-ast-resolve-expr.h"
+
+namespace Rust {
+namespace Resolver {
+
+void
+PatternDeclaration::visit (AST::PathInExpression &pattern)
+{
+ ResolveExpr::go (&pattern, parent);
+}
+
+void
+PatternDeclaration::visit (AST::TupleStructPattern &pattern)
+{
+ ResolveExpr::go (&pattern.get_path (), parent);
+
+ std::unique_ptr<AST::TupleStructItems> &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 ());
+
+ for (auto &inner_pattern : items_no_range.get_patterns ())
+ {
+ PatternDeclaration::go (inner_pattern.get (),
+ pattern.get_node_id ());
+ }
+ }
+ break;
+ }
+}
+
+void
+PatternDeclaration::visit (AST::StructPattern &pattern)
+{
+ ResolveExpr::go (&pattern.get_path (), parent);
+
+ auto &struct_pattern_elems = pattern.get_struct_pattern_elems ();
+ for (auto &field : struct_pattern_elems.get_struct_pattern_fields ())
+ {
+ 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 ());
+
+ resolver->get_name_scope ().insert (
+ CanonicalPath::new_seg (ident.get_node_id (),
+ ident.get_identifier ()),
+ ident.get_node_id (), pattern.get_locus ());
+ resolver->insert_new_definition (
+ ident.get_node_id (),
+ Definition{ident.get_node_id (), pattern.get_node_id ()});
+ resolver->mark_decl_mutability (ident.get_node_id (),
+ ident.is_mut ());
+ }
+ break;
+ }
+ }
+
+ // TODO
+ rust_assert (!struct_pattern_elems.has_etc ());
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h
index a88811e..57c73ba 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.h
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.h
@@ -83,6 +83,13 @@ public:
pattern.get_is_mut ());
}
+ // cases in a match expression
+ void visit (AST::PathInExpression &pattern) override;
+
+ void visit (AST::StructPattern &pattern) override;
+
+ void visit (AST::TupleStructPattern &pattern) override;
+
private:
PatternDeclaration (NodeId parent) : ResolverBase (parent) {}
};