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>
This commit is contained in:
commit
cb42c3674a
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 ()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -101,6 +101,8 @@ public:
|
|||
|
||||
void visit (AST::TupleStructPattern &pattern) override;
|
||||
|
||||
void visit (AST::TuplePattern &pattern) override;
|
||||
|
||||
private:
|
||||
PatternDeclaration (NodeId parent) : ResolverBase (parent) {}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue