aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-04-21 17:24:27 +0000
committerGitHub <noreply@github.com>2022-04-21 17:24:27 +0000
commitcb42c3674a5a9ab77cb0c1216a1b776c323037e2 (patch)
tree223139b9b80a2c0473cb42c87d7d85fcb33a9f84
parentfc22f12c9c707b258f35a1bab0e8154441b972b8 (diff)
parentdd9e4c1e0ca0b14388a3cd43f18a4e1a7aebe6e5 (diff)
downloadgcc-cb42c3674a5a9ab77cb0c1216a1b776c323037e2.zip
gcc-cb42c3674a5a9ab77cb0c1216a1b776c323037e2.tar.gz
gcc-cb42c3674a5a9ab77cb0c1216a1b776c323037e2.tar.bz2
Merge #1144
1144: Add name and type resolution support TuplePatterns in MatchArms r=philberty a=philberty This adds support for the name and type resolution of match expressions. The code generation and checks for all cases possible cases needs more thought so this will be done as part of a separate PR. Addresses #1081 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc7
-rw-r--r--gcc/rust/ast/rust-pattern.h42
-rw-r--r--gcc/rust/ast/rust-stmt.h17
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc75
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.h8
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h36
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.cc45
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.h4
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h4
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc9
-rw-r--r--gcc/rust/hir/tree/rust-hir-pattern.h41
-rw-r--r--gcc/rust/parse/rust-parse-impl.h32
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.cc30
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc172
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-enumitem.h6
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h170
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.cc41
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.h10
20 files changed, 507 insertions, 247 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index e6bad4b..5c6a754 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -2819,12 +2819,7 @@ StructPattern::as_string () const
std::string
LiteralPattern::as_string () const
{
- std::string str;
-
- if (has_minus)
- str += "-";
-
- return str + lit.as_string ();
+ return lit.as_string ();
}
std::string
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 5d937d7..a3193f7 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -27,14 +27,6 @@ namespace AST {
class LiteralPattern : public Pattern
{
Literal lit;
- /* make literal have a type given by enum, etc. rustc uses an extended form of
- * its literal token implementation */
- // TODO: literal representation - use LiteralExpr? or another thing?
-
- // Minus prefixed to literal (if integer or floating-point)
- bool has_minus;
- // Actually, this might be a good place to use a template.
-
Location locus;
NodeId node_id;
@@ -42,16 +34,14 @@ public:
std::string as_string () const override;
// Constructor for a literal pattern
- LiteralPattern (Literal lit, Location locus, bool has_minus = false)
- : lit (std::move (lit)), has_minus (has_minus), locus (locus),
+ LiteralPattern (Literal lit, Location locus)
+ : lit (std::move (lit)), locus (locus),
node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
- LiteralPattern (std::string val, Literal::LitType type, Location locus,
- bool has_minus = false)
+ LiteralPattern (std::string val, Literal::LitType type, Location locus)
: lit (Literal (std::move (val), type, PrimitiveCoreType::CORETYPE_STR)),
- has_minus (has_minus), locus (locus),
- node_id (Analysis::Mappings::get ()->get_next_node_id ())
+ locus (locus), node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
Location get_locus () const override final { return locus; }
@@ -62,6 +52,10 @@ public:
NodeId get_pattern_node_id () const override final { return node_id; }
+ Literal &get_literal () { return lit; }
+
+ const Literal &get_literal () const { return lit; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1110,7 +1104,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 (ASTVisitor &vis) override;
@@ -1141,6 +1135,12 @@ protected:
class TuplePatternItems
{
public:
+ enum TuplePatternItemType
+ {
+ MULTIPLE,
+ RANGED,
+ };
+
virtual ~TuplePatternItems () {}
// TODO: should this store location data?
@@ -1156,6 +1156,8 @@ public:
virtual void accept_vis (ASTVisitor &vis) = 0;
+ virtual TuplePatternItemType get_pattern_type () const = 0;
+
protected:
// pure virtual clone implementation
virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0;
@@ -1240,6 +1242,11 @@ public:
return patterns;
}
+ TuplePatternItemType get_pattern_type () const override
+ {
+ return TuplePatternItemType::MULTIPLE;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1318,6 +1325,11 @@ public:
return upper_patterns;
}
+ TuplePatternItemType get_pattern_type () const override
+ {
+ return TuplePatternItemType::RANGED;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index 942da7f..9d95c3e 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -183,8 +183,14 @@ protected:
* expression) */
class ExprStmt : public Stmt
{
- // TODO: add any useful virtual functions
+public:
+ enum ExprStmtType
+ {
+ WITH_BLOCK,
+ WITHOUT_BLOCK
+ };
+protected:
Location locus;
public:
@@ -192,6 +198,8 @@ public:
bool is_item () const override final { return false; }
+ virtual ExprStmtType get_type () const = 0;
+
protected:
ExprStmt (Location locus) : locus (locus) {}
};
@@ -261,6 +269,11 @@ public:
return expr;
}
+ ExprStmtType get_type () const override
+ {
+ return ExprStmtType::WITHOUT_BLOCK;
+ };
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -328,6 +341,8 @@ public:
bool is_semicolon_followed () const { return semicolon_followed; }
+ ExprStmtType get_type () const override { return ExprStmtType::WITH_BLOCK; };
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index fa7c700..28895ba 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -18,6 +18,7 @@
#include "rust-ast-lower-base.h"
#include "rust-ast-lower-type.h"
+#include "rust-ast-lower-pattern.h"
namespace Rust {
namespace HIR {
@@ -885,5 +886,79 @@ ASTLoweringBase::attribute_handled_in_another_pass (
return lookup.handler != Analysis::CompilerPass::HIR_LOWERING;
}
+std::unique_ptr<HIR::TuplePatternItems>
+ASTLoweringBase::lower_tuple_pattern_multiple (
+ AST::TuplePatternItemsMultiple &pattern)
+{
+ std::vector<std::unique_ptr<HIR::Pattern> > patterns;
+ for (auto &p : pattern.get_patterns ())
+ {
+ HIR::Pattern *translated = ASTLoweringPattern::translate (p.get ());
+ patterns.push_back (std::unique_ptr<HIR::Pattern> (translated));
+ }
+
+ return std::unique_ptr<HIR::TuplePatternItems> (
+ new HIR::TuplePatternItemsMultiple (std::move (patterns)));
+}
+
+std::unique_ptr<TuplePatternItems>
+ASTLoweringBase::lower_tuple_pattern_ranged (
+ AST::TuplePatternItemsRanged &pattern)
+{
+ std::vector<std::unique_ptr<HIR::Pattern> > lower_patterns;
+ std::vector<std::unique_ptr<HIR::Pattern> > upper_patterns;
+
+ for (auto &p : pattern.get_lower_patterns ())
+ {
+ HIR::Pattern *translated = ASTLoweringPattern::translate (p.get ());
+ lower_patterns.push_back (std::unique_ptr<HIR::Pattern> (translated));
+ }
+
+ for (auto &p : pattern.get_upper_patterns ())
+ {
+ HIR::Pattern *translated = ASTLoweringPattern::translate (p.get ());
+ upper_patterns.push_back (std::unique_ptr<HIR::Pattern> (translated));
+ }
+
+ return std::unique_ptr<HIR::TuplePatternItems> (
+ new HIR::TuplePatternItemsRanged (std::move (lower_patterns),
+ std::move (upper_patterns)));
+}
+
+HIR::Literal
+ASTLoweringBase::lower_literal (const AST::Literal &literal)
+{
+ HIR::Literal::LitType type = HIR::Literal::LitType::CHAR;
+ switch (literal.get_lit_type ())
+ {
+ case AST::Literal::LitType::CHAR:
+ type = HIR::Literal::LitType::CHAR;
+ break;
+ case AST::Literal::LitType::STRING:
+ type = HIR::Literal::LitType::STRING;
+ break;
+ case AST::Literal::LitType::BYTE:
+ type = HIR::Literal::LitType::BYTE;
+ break;
+ case AST::Literal::LitType::BYTE_STRING:
+ type = HIR::Literal::LitType::BYTE_STRING;
+ break;
+ case AST::Literal::LitType::INT:
+ type = HIR::Literal::LitType::INT;
+ break;
+ case AST::Literal::LitType::FLOAT:
+ type = HIR::Literal::LitType::FLOAT;
+ break;
+ case AST::Literal::LitType::BOOL:
+ type = HIR::Literal::LitType::BOOL;
+ break;
+ case AST::Literal::LitType::ERROR:
+ gcc_unreachable ();
+ break;
+ }
+
+ return HIR::Literal (literal.as_string (), type, literal.get_type_hint ());
+}
+
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h
index 185f467..33009ae 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -272,6 +272,14 @@ protected:
bool
attribute_handled_in_another_pass (const std::string &attribute_path) const;
+
+ std::unique_ptr<TuplePatternItems>
+ lower_tuple_pattern_multiple (AST::TuplePatternItemsMultiple &pattern);
+
+ std::unique_ptr<TuplePatternItems>
+ lower_tuple_pattern_ranged (AST::TuplePatternItemsRanged &pattern);
+
+ HIR::Literal lower_literal (const AST::Literal &literal);
};
} // namespace HIR
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index 022002e..5ae5386 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -327,43 +327,15 @@ public:
void visit (AST::LiteralExpr &expr) override
{
- HIR::Literal::LitType type = HIR::Literal::LitType::CHAR;
- switch (expr.get_lit_type ())
- {
- case AST::Literal::LitType::CHAR:
- type = HIR::Literal::LitType::CHAR;
- break;
- case AST::Literal::LitType::STRING:
- type = HIR::Literal::LitType::STRING;
- break;
- case AST::Literal::LitType::BYTE:
- type = HIR::Literal::LitType::BYTE;
- break;
- case AST::Literal::LitType::BYTE_STRING:
- type = HIR::Literal::LitType::BYTE_STRING;
- break;
- case AST::Literal::LitType::INT:
- type = HIR::Literal::LitType::INT;
- break;
- case AST::Literal::LitType::FLOAT:
- type = HIR::Literal::LitType::FLOAT;
- break;
- case AST::Literal::LitType::BOOL:
- type = HIR::Literal::LitType::BOOL;
- break;
- // Error literals should have been stripped during expansion
- case AST::Literal::LitType::ERROR:
- gcc_unreachable ();
- break;
- }
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::LiteralExpr (mapping, expr.as_string (), type,
- expr.get_literal ().get_type_hint (),
- expr.get_locus ());
+ HIR::Literal l = lower_literal (expr.get_literal ());
+ translated
+ = new HIR::LiteralExpr (mapping, std::move (l), expr.get_locus (),
+ expr.get_outer_attrs ());
}
void visit (AST::ArithmeticOrLogicalExpr &expr) override
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc
index 9d733f3..957f8cd 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -163,5 +163,50 @@ ASTLoweringPattern::visit (AST::WildcardPattern &pattern)
translated = new HIR::WildcardPattern (mapping, pattern.get_locus ());
}
+void
+ASTLoweringPattern::visit (AST::TuplePattern &pattern)
+{
+ std::unique_ptr<HIR::TuplePatternItems> items;
+ switch (pattern.get_items ()->get_pattern_type ())
+ {
+ case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
+ AST::TuplePatternItemsMultiple &ref
+ = *static_cast<AST::TuplePatternItemsMultiple *> (
+ pattern.get_items ().get ());
+ items = lower_tuple_pattern_multiple (ref);
+ }
+ break;
+
+ case AST::TuplePatternItems::TuplePatternItemType::RANGED: {
+ AST::TuplePatternItemsRanged &ref
+ = *static_cast<AST::TuplePatternItemsRanged *> (
+ pattern.get_items ().get ());
+ items = lower_tuple_pattern_ranged (ref);
+ }
+ break;
+ }
+
+ 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::TuplePattern (mapping, std::move (items), pattern.get_locus ());
+}
+
+void
+ASTLoweringPattern::visit (AST::LiteralPattern &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);
+
+ HIR::Literal l = lower_literal (pattern.get_literal ());
+ translated
+ = new HIR::LiteralPattern (mapping, std::move (l), 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 80ff97a..32e9dac 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.h
+++ b/gcc/rust/hir/rust-ast-lower-pattern.h
@@ -58,6 +58,10 @@ public:
void visit (AST::WildcardPattern &pattern) override;
+ void visit (AST::TuplePattern &pattern) override;
+
+ void visit (AST::LiteralPattern &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 40c9fef..e585dd2 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -77,13 +77,13 @@ public:
LiteralExpr (Analysis::NodeMapping mappings, std::string value_as_string,
Literal::LitType type, PrimitiveCoreType type_hint,
- Location locus, AST::AttrVec outer_attrs = AST::AttrVec ())
+ Location locus, AST::AttrVec outer_attrs)
: ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
literal (std::move (value_as_string), type, type_hint), locus (locus)
{}
LiteralExpr (Analysis::NodeMapping mappings, Literal literal, Location locus,
- AST::AttrVec outer_attrs = AST::AttrVec ())
+ AST::AttrVec outer_attrs)
: ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
literal (std::move (literal)), locus (locus)
{}
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index a996228..a53210b 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -2589,14 +2589,7 @@ StructPattern::as_string () const
std::string
LiteralPattern::as_string () const
{
- std::string str;
-
- if (has_minus)
- {
- str += "-";
- }
-
- return str + lit.as_string ();
+ return lit.as_string ();
}
std::string
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index de4a83e..880fc3e 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -29,7 +29,6 @@ namespace HIR {
class LiteralPattern : public Pattern
{
Literal lit;
- bool has_minus;
Location locus;
Analysis::NodeMapping mappings;
@@ -37,16 +36,14 @@ public:
std::string as_string () const override;
// Constructor for a literal pattern
- LiteralPattern (Analysis::NodeMapping mappings, Literal lit, Location locus,
- bool has_minus = false)
- : lit (std::move (lit)), has_minus (has_minus), locus (locus),
- mappings (mappings)
+ LiteralPattern (Analysis::NodeMapping mappings, Literal lit, Location locus)
+ : lit (std::move (lit)), locus (locus), mappings (mappings)
{}
LiteralPattern (Analysis::NodeMapping mappings, std::string val,
- Literal::LitType type, Location locus, bool has_minus = false)
+ Literal::LitType type, Location locus)
: lit (Literal (std::move (val), type, PrimitiveCoreType::CORETYPE_STR)),
- has_minus (has_minus), locus (locus), mappings (mappings)
+ locus (locus), mappings (mappings)
{}
Location get_locus () const override { return locus; }
@@ -64,6 +61,9 @@ public:
return PatternType::LITERAL;
}
+ Literal &get_literal () { return lit; }
+ const Literal &get_literal () const { return lit; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -962,6 +962,12 @@ protected:
class TuplePatternItems
{
public:
+ enum TuplePatternItemType
+ {
+ MULTIPLE,
+ RANGED,
+ };
+
virtual ~TuplePatternItems () {}
// TODO: should this store location data?
@@ -977,6 +983,8 @@ public:
virtual void accept_vis (HIRFullVisitor &vis) = 0;
+ virtual TuplePatternItemType get_pattern_type () const = 0;
+
protected:
// pure virtual clone implementation
virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0;
@@ -1019,6 +1027,17 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
+ TuplePatternItemType get_pattern_type () const override
+ {
+ return TuplePatternItemType::MULTIPLE;
+ }
+
+ std::vector<std::unique_ptr<Pattern> > &get_patterns () { return patterns; }
+ const std::vector<std::unique_ptr<Pattern> > &get_patterns () const
+ {
+ return patterns;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1077,6 +1096,11 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
+ TuplePatternItemType get_pattern_type () const override
+ {
+ return TuplePatternItemType::RANGED;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1135,6 +1159,9 @@ public:
return PatternType::TUPLE;
}
+ std::unique_ptr<TuplePatternItems> &get_items () { return items; }
+ const std::unique_ptr<TuplePatternItems> &get_items () const { return items; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index c95afd6..25979ce 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -8563,7 +8563,11 @@ Parser<ManagedTokenSource>::parse_match_expr (AST::AttrVec outer_attrs,
return nullptr;
}
- std::unique_ptr<AST::Expr> expr = parse_expr ();
+ ParseRestrictions restrictions;
+ restrictions.expr_can_be_stmt = true;
+ restrictions.consume_semi = false;
+
+ std::unique_ptr<AST::ExprStmt> expr = parse_expr_stmt ({}, restrictions);
if (expr == nullptr)
{
Error error (lexer.peek_token ()->get_locus (),
@@ -8573,10 +8577,30 @@ Parser<ManagedTokenSource>::parse_match_expr (AST::AttrVec outer_attrs,
// skip somewhere?
return nullptr;
}
- bool is_expr_without_block = expr->is_expr_without_block ();
+ bool is_expr_without_block
+ = expr->get_type () == AST::ExprStmt::ExprStmtType::WITHOUT_BLOCK;
// construct match case expr and add to cases
- match_arms.push_back (AST::MatchCase (std::move (arm), std::move (expr)));
+ switch (expr->get_type ())
+ {
+ case AST::ExprStmt::ExprStmtType::WITH_BLOCK: {
+ AST::ExprStmtWithBlock *cast
+ = static_cast<AST::ExprStmtWithBlock *> (expr.get ());
+ std::unique_ptr<AST::Expr> e = cast->get_expr ()->clone_expr ();
+ match_arms.push_back (
+ AST::MatchCase (std::move (arm), std::move (e)));
+ }
+ break;
+
+ case AST::ExprStmt::ExprStmtType::WITHOUT_BLOCK: {
+ AST::ExprStmtWithoutBlock *cast
+ = static_cast<AST::ExprStmtWithoutBlock *> (expr.get ());
+ std::unique_ptr<AST::Expr> e = cast->get_expr ()->clone_expr ();
+ match_arms.push_back (
+ AST::MatchCase (std::move (arm), std::move (e)));
+ }
+ break;
+ }
// handle comma presence
if (lexer.peek_token ()->get_id () != COMMA)
@@ -10400,7 +10424,7 @@ Parser<ManagedTokenSource>::parse_literal_or_range_pattern ()
// literal pattern
return std::unique_ptr<AST::LiteralPattern> (
new AST::LiteralPattern (range_lower->get_str (), type,
- range_lower->get_locus (), has_minus));
+ range_lower->get_locus ()));
}
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
index 0c7c8f3..24cd171 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
@@ -100,5 +100,35 @@ PatternDeclaration::visit (AST::StructPattern &pattern)
rust_assert (!struct_pattern_elems.has_etc ());
}
+void
+PatternDeclaration::visit (AST::TuplePattern &pattern)
+{
+ std::unique_ptr<AST::TuplePatternItems> &items = pattern.get_items ();
+ switch (items->get_pattern_type ())
+ {
+ case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
+ AST::TuplePatternItemsMultiple &ref
+ = *static_cast<AST::TuplePatternItemsMultiple *> (
+ pattern.get_items ().get ());
+
+ for (auto &p : ref.get_patterns ())
+ p->accept_vis (*this);
+ }
+ break;
+
+ case AST::TuplePatternItems::TuplePatternItemType::RANGED: {
+ AST::TuplePatternItemsRanged &ref
+ = *static_cast<AST::TuplePatternItemsRanged *> (
+ pattern.get_items ().get ());
+
+ for (auto &p : ref.get_lower_patterns ())
+ p->accept_vis (*this);
+ for (auto &p : ref.get_upper_patterns ())
+ p->accept_vis (*this);
+ }
+ break;
+ }
+}
+
} // 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 dca8258..464e362 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.h
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.h
@@ -101,6 +101,8 @@ public:
void visit (AST::TupleStructPattern &pattern) override;
+ void visit (AST::TuplePattern &pattern) override;
+
private:
PatternDeclaration (NodeId parent) : ResolverBase (parent) {}
};
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 32c5881..a924866 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -80,5 +80,177 @@ TypeCheckBase::check_for_unconstrained (
return unconstrained;
}
+TyTy::BaseType *
+TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
+ HIR::Literal &literal, Location locus)
+{
+ TyTy::BaseType *infered = nullptr;
+ switch (literal.get_lit_type ())
+ {
+ case HIR::Literal::LitType::INT: {
+ bool ok = false;
+
+ switch (literal.get_type_hint ())
+ {
+ case CORETYPE_I8:
+ ok = context->lookup_builtin ("i8", &infered);
+ break;
+ case CORETYPE_I16:
+ ok = context->lookup_builtin ("i16", &infered);
+ break;
+ case CORETYPE_I32:
+ ok = context->lookup_builtin ("i32", &infered);
+ break;
+ case CORETYPE_I64:
+ ok = context->lookup_builtin ("i64", &infered);
+ break;
+ case CORETYPE_I128:
+ ok = context->lookup_builtin ("i128", &infered);
+ break;
+
+ case CORETYPE_U8:
+ ok = context->lookup_builtin ("u8", &infered);
+ break;
+ case CORETYPE_U16:
+ ok = context->lookup_builtin ("u16", &infered);
+ break;
+ case CORETYPE_U32:
+ ok = context->lookup_builtin ("u32", &infered);
+ break;
+ case CORETYPE_U64:
+ ok = context->lookup_builtin ("u64", &infered);
+ break;
+ case CORETYPE_U128:
+ ok = context->lookup_builtin ("u128", &infered);
+ break;
+
+ case CORETYPE_F32:
+ literal.set_lit_type (HIR::Literal::LitType::FLOAT);
+ ok = context->lookup_builtin ("f32", &infered);
+ break;
+ case CORETYPE_F64:
+ literal.set_lit_type (HIR::Literal::LitType::FLOAT);
+ ok = context->lookup_builtin ("f64", &infered);
+ break;
+
+ default:
+ ok = true;
+ infered
+ = new TyTy::InferType (expr_mappings.get_hirid (),
+ TyTy::InferType::InferTypeKind::INTEGRAL,
+ locus);
+ break;
+ }
+ rust_assert (ok);
+ }
+ break;
+
+ case HIR::Literal::LitType::FLOAT: {
+ bool ok = false;
+
+ switch (literal.get_type_hint ())
+ {
+ case CORETYPE_F32:
+ ok = context->lookup_builtin ("f32", &infered);
+ break;
+ case CORETYPE_F64:
+ ok = context->lookup_builtin ("f64", &infered);
+ break;
+
+ default:
+ ok = true;
+ infered
+ = new TyTy::InferType (expr_mappings.get_hirid (),
+ TyTy::InferType::InferTypeKind::FLOAT,
+ locus);
+ break;
+ }
+ rust_assert (ok);
+ }
+ break;
+
+ case HIR::Literal::LitType::BOOL: {
+ auto ok = context->lookup_builtin ("bool", &infered);
+ rust_assert (ok);
+ }
+ break;
+
+ case HIR::Literal::LitType::CHAR: {
+ auto ok = context->lookup_builtin ("char", &infered);
+ rust_assert (ok);
+ }
+ break;
+
+ case HIR::Literal::LitType::BYTE: {
+ auto ok = context->lookup_builtin ("u8", &infered);
+ rust_assert (ok);
+ }
+ break;
+
+ case HIR::Literal::LitType::STRING: {
+ TyTy::BaseType *base = nullptr;
+ auto ok = context->lookup_builtin ("str", &base);
+ rust_assert (ok);
+
+ infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
+ TyTy::TyVar (base->get_ref ()),
+ Mutability::Imm);
+ }
+ break;
+
+ case HIR::Literal::LitType::BYTE_STRING: {
+ /* This is an arraytype of u8 reference (&[u8;size]). It isn't in
+ UTF-8, but really just a byte array. Code to construct the array
+ reference copied from ArrayElemsValues and ArrayType. */
+ TyTy::BaseType *u8;
+ auto ok = context->lookup_builtin ("u8", &u8);
+ rust_assert (ok);
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping capacity_mapping (crate_num, UNKNOWN_NODEID,
+ mappings->get_next_hir_id (
+ crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ /* Capacity is the size of the string (number of chars).
+ It is a constant, but for fold it to get a tree. */
+ std::string capacity_str
+ = std::to_string (literal.as_string ().size ());
+ HIR::LiteralExpr *literal_capacity
+ = new HIR::LiteralExpr (capacity_mapping, capacity_str,
+ HIR::Literal::LitType::INT,
+ PrimitiveCoreType::CORETYPE_USIZE, locus, {});
+
+ // mark the type for this implicit node
+ TyTy::BaseType *expected_ty = nullptr;
+ ok = context->lookup_builtin ("usize", &expected_ty);
+ rust_assert (ok);
+ context->insert_type (capacity_mapping, expected_ty);
+
+ Analysis::NodeMapping array_mapping (crate_num, UNKNOWN_NODEID,
+ mappings->get_next_hir_id (
+ crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ TyTy::ArrayType *array
+ = new TyTy::ArrayType (array_mapping.get_hirid (), locus,
+ *literal_capacity,
+ TyTy::TyVar (u8->get_ref ()));
+ context->insert_type (array_mapping, array);
+
+ infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
+ TyTy::TyVar (array->get_ref ()),
+ Mutability::Imm);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ return infered;
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index 5a3f553..159f826 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -55,6 +55,9 @@ protected:
const TyTy::SubstitutionArgumentMappings &constraint_b,
const TyTy::BaseType *reference);
+ TyTy::BaseType *resolve_literal (const Analysis::NodeMapping &mappings,
+ HIR::Literal &literal, Location locus);
+
Analysis::Mappings *mappings;
Resolver *resolver;
TypeCheckContext *context;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.h b/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
index 9701a20..d6baff1 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.h
@@ -57,7 +57,7 @@ public:
= new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
HIR::Literal::LitType::INT,
PrimitiveCoreType::CORETYPE_I64,
- item.get_locus ());
+ item.get_locus (), {});
TyTy::BaseType *isize = nullptr;
bool ok = context->lookup_builtin ("isize", &isize);
@@ -135,7 +135,7 @@ public:
= new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
HIR::Literal::LitType::INT,
PrimitiveCoreType::CORETYPE_I64,
- item.get_locus ());
+ item.get_locus (), {});
TyTy::BaseType *isize = nullptr;
bool ok = context->lookup_builtin ("isize", &isize);
@@ -182,7 +182,7 @@ public:
= new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
HIR::Literal::LitType::INT,
PrimitiveCoreType::CORETYPE_I64,
- item.get_locus ());
+ item.get_locus (), {});
TyTy::BaseType *isize = nullptr;
bool ok = context->lookup_builtin ("isize", &isize);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 560581d..5db00a4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -535,172 +535,8 @@ public:
void visit (HIR::LiteralExpr &expr) override
{
- switch (expr.get_lit_type ())
- {
- case HIR::Literal::LitType::INT: {
- bool ok = false;
-
- switch (expr.get_literal ().get_type_hint ())
- {
- case CORETYPE_I8:
- ok = context->lookup_builtin ("i8", &infered);
- break;
- case CORETYPE_I16:
- ok = context->lookup_builtin ("i16", &infered);
- break;
- case CORETYPE_I32:
- ok = context->lookup_builtin ("i32", &infered);
- break;
- case CORETYPE_I64:
- ok = context->lookup_builtin ("i64", &infered);
- break;
- case CORETYPE_I128:
- ok = context->lookup_builtin ("i128", &infered);
- break;
-
- case CORETYPE_U8:
- ok = context->lookup_builtin ("u8", &infered);
- break;
- case CORETYPE_U16:
- ok = context->lookup_builtin ("u16", &infered);
- break;
- case CORETYPE_U32:
- ok = context->lookup_builtin ("u32", &infered);
- break;
- case CORETYPE_U64:
- ok = context->lookup_builtin ("u64", &infered);
- break;
- case CORETYPE_U128:
- ok = context->lookup_builtin ("u128", &infered);
- break;
-
- case CORETYPE_F32:
- expr.get_literal ().set_lit_type (HIR::Literal::LitType::FLOAT);
- ok = context->lookup_builtin ("f32", &infered);
- break;
- case CORETYPE_F64:
- expr.get_literal ().set_lit_type (HIR::Literal::LitType::FLOAT);
- ok = context->lookup_builtin ("f64", &infered);
- break;
-
- default:
- ok = true;
- infered
- = new TyTy::InferType (expr.get_mappings ().get_hirid (),
- TyTy::InferType::InferTypeKind::INTEGRAL,
- expr.get_locus ());
- break;
- }
- rust_assert (ok);
- }
- break;
-
- case HIR::Literal::LitType::FLOAT: {
- bool ok = false;
-
- switch (expr.get_literal ().get_type_hint ())
- {
- case CORETYPE_F32:
- ok = context->lookup_builtin ("f32", &infered);
- break;
- case CORETYPE_F64:
- ok = context->lookup_builtin ("f64", &infered);
- break;
-
- default:
- ok = true;
- infered
- = new TyTy::InferType (expr.get_mappings ().get_hirid (),
- TyTy::InferType::InferTypeKind::FLOAT,
- expr.get_locus ());
- break;
- }
- rust_assert (ok);
- }
- break;
-
- case HIR::Literal::LitType::BOOL: {
- auto ok = context->lookup_builtin ("bool", &infered);
- rust_assert (ok);
- }
- break;
-
- case HIR::Literal::LitType::CHAR: {
- auto ok = context->lookup_builtin ("char", &infered);
- rust_assert (ok);
- }
- break;
-
- case HIR::Literal::LitType::BYTE: {
- auto ok = context->lookup_builtin ("u8", &infered);
- rust_assert (ok);
- }
- break;
-
- case HIR::Literal::LitType::STRING: {
- TyTy::BaseType *base = nullptr;
- auto ok = context->lookup_builtin ("str", &base);
- rust_assert (ok);
-
- infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
- TyTy::TyVar (base->get_ref ()),
- Mutability::Imm);
- }
- break;
-
- case HIR::Literal::LitType::BYTE_STRING: {
- /* This is an arraytype of u8 reference (&[u8;size]). It isn't in
- UTF-8, but really just a byte array. Code to construct the array
- reference copied from ArrayElemsValues and ArrayType. */
- TyTy::BaseType *u8;
- auto ok = context->lookup_builtin ("u8", &u8);
- rust_assert (ok);
-
- auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping capacity_mapping (crate_num, UNKNOWN_NODEID,
- mappings->get_next_hir_id (
- crate_num),
- UNKNOWN_LOCAL_DEFID);
-
- /* Capacity is the size of the string (number of chars).
- It is a constant, but for fold it to get a tree. */
- std::string capacity_str
- = std::to_string (expr.get_literal ().as_string ().size ());
- HIR::LiteralExpr *literal_capacity
- = new HIR::LiteralExpr (capacity_mapping, capacity_str,
- HIR::Literal::LitType::INT,
- PrimitiveCoreType::CORETYPE_USIZE,
- expr.get_locus ());
-
- // mark the type for this implicit node
- TyTy::BaseType *expected_ty = nullptr;
- ok = context->lookup_builtin ("usize", &expected_ty);
- rust_assert (ok);
- context->insert_type (capacity_mapping, expected_ty);
-
- Analysis::NodeMapping array_mapping (crate_num, UNKNOWN_NODEID,
- mappings->get_next_hir_id (
- crate_num),
- UNKNOWN_LOCAL_DEFID);
-
- TyTy::ArrayType *array
- = new TyTy::ArrayType (array_mapping.get_hirid (),
- expr.get_locus (), *literal_capacity,
- TyTy::TyVar (u8->get_ref ()));
- context->insert_type (array_mapping, array);
-
- infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
- TyTy::TyVar (array->get_ref ()),
- Mutability::Imm);
- }
- break;
-
- default:
- gcc_unreachable ();
- break;
- }
-
- infered = infered->clone ();
+ infered = resolve_literal (expr.get_mappings (), expr.get_literal (),
+ expr.get_locus ());
}
void visit (HIR::ArithmeticOrLogicalExpr &expr) override
@@ -929,7 +765,7 @@ public:
= new HIR::LiteralExpr (mapping, capacity_str,
HIR::Literal::LitType::INT,
PrimitiveCoreType::CORETYPE_USIZE,
- Location ());
+ Location (), {});
// mark the type for this implicit node
TyTy::BaseType *expected_ty = nullptr;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index feedbc5..52d0d47 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -232,5 +232,46 @@ TypeCheckPattern::visit (HIR::WildcardPattern &pattern)
infered->set_ref (pattern.get_pattern_mappings ().get_hirid ());
}
+void
+TypeCheckPattern::visit (HIR::TuplePattern &pattern)
+{
+ std::unique_ptr<HIR::TuplePatternItems> items;
+ switch (pattern.get_items ()->get_pattern_type ())
+ {
+ case HIR::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
+ HIR::TuplePatternItemsMultiple &ref
+ = *static_cast<HIR::TuplePatternItemsMultiple *> (
+ pattern.get_items ().get ());
+
+ std::vector<TyTy::TyVar> pattern_elems;
+ for (auto &p : ref.get_patterns ())
+ {
+ TyTy::BaseType *elem = TypeCheckPattern::Resolve (p.get (), parent);
+ pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
+ }
+ infered
+ = new TyTy::TupleType (pattern.get_pattern_mappings ().get_hirid (),
+ pattern.get_locus (), pattern_elems);
+ }
+ break;
+
+ case HIR::TuplePatternItems::TuplePatternItemType::RANGED: {
+ // HIR::TuplePatternItemsRanged &ref
+ // = *static_cast<HIR::TuplePatternItemsRanged *> (
+ // pattern.get_items ().get ());
+ // TODO
+ gcc_unreachable ();
+ }
+ break;
+ }
+}
+
+void
+TypeCheckPattern::visit (HIR::LiteralPattern &pattern)
+{
+ infered = resolve_literal (pattern.get_pattern_mappings (),
+ pattern.get_literal (), pattern.get_locus ());
+}
+
} // 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 ef530b3..b76c7ba 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
@@ -39,6 +39,8 @@ public:
return new TyTy::ErrorType (
pattern->get_pattern_mappings ().get_hirid ());
+ resolver.context->insert_type (pattern->get_pattern_mappings (),
+ resolver.infered);
return resolver.infered;
}
@@ -50,13 +52,17 @@ public:
void visit (HIR::WildcardPattern &pattern) override;
+ void visit (HIR::TuplePattern &pattern) override;
+
+ void visit (HIR::LiteralPattern &pattern) override;
+
private:
TypeCheckPattern (TyTy::BaseType *parent)
- : TypeCheckBase (), infered (nullptr), parent (parent)
+ : TypeCheckBase (), parent (parent), infered (nullptr)
{}
- TyTy::BaseType *infered;
TyTy::BaseType *parent;
+ TyTy::BaseType *infered;
};
} // namespace Resolver