summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-02-27 09:47:04 +0800
committerJohn Hodge <tpg@mutabah.net>2016-02-27 09:47:04 +0800
commit3057d238db0d80286d77b9341fc6f84e594229c4 (patch)
tree0a377fbcdd643c327d6a3abea07ab396ff47ec80
parent904a9eddbdd95f345e5ea6737a110cf657f5ddcf (diff)
downloadmrust-3057d238db0d80286d77b9341fc6f84e594229c4.tar.gz
Patterns - Clean up handling of ref/mut/ref mut
-rw-r--r--src/ast/pattern.hpp11
-rw-r--r--src/convert/resolve.cpp2
-rw-r--r--src/parse/pattern.cpp43
3 files changed, 49 insertions, 7 deletions
diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp
index ce4844f9..b844eba9 100644
--- a/src/ast/pattern.hpp
+++ b/src/ast/pattern.hpp
@@ -19,6 +19,11 @@ class Pattern:
public Serialisable
{
public:
+ enum BindType {
+ BIND_MOVE,
+ BIND_REF,
+ BIND_MUTREF,
+ };
TAGGED_UNION(Data, Any,
(MaybeBind, () ),
(Macro, (unique_ptr<::AST::MacroInvocation> inv;) ),
@@ -33,6 +38,8 @@ public:
);
private:
::std::string m_binding;
+ BindType m_binding_type;
+ bool m_binding_mut;
Data m_data;
public:
@@ -101,8 +108,10 @@ public:
{}
// Mutators
- void set_bind(::std::string name, bool is_ref, bool is_mut) {
+ void set_bind(::std::string name, BindType type, bool is_mut) {
m_binding = name;
+ m_binding_type = type;
+ m_binding_mut = is_mut;
}
::std::unique_ptr<ExprNode> take_node() {
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index 5072f57f..20785af5 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -1630,7 +1630,7 @@ void CPathResolver::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint)
{
// It's a name binding (desugar to 'name @ _')
pat = AST::Pattern();
- pat.set_bind(name, false, false);
+ pat.set_bind(name, AST::Pattern::BIND_MOVE, false);
}
else
{
diff --git a/src/parse/pattern.cpp b/src/parse/pattern.cpp
index 88abe196..c872cbaf 100644
--- a/src/parse/pattern.cpp
+++ b/src/parse/pattern.cpp
@@ -47,21 +47,33 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable)
}
bool expect_bind = false;
+ ::AST::Pattern::BindType bind_type = AST::Pattern::BIND_MOVE;
bool is_mut = false;
- bool is_ref = false;
// 1. Mutablity + Reference
if( tok.type() == TOK_RWORD_REF )
{
- is_ref = true;
expect_bind = true;
tok = lex.getToken();
+ if( tok.type() == TOK_RWORD_MUT )
+ {
+ bind_type = AST::Pattern::BIND_MUTREF;
+ GET_TOK(tok, lex);
+ }
+ else
+ {
+ bind_type = AST::Pattern::BIND_REF;
+ }
}
- if( tok.type() == TOK_RWORD_MUT )
+ else if( tok.type() == TOK_RWORD_MUT )
{
is_mut = true;
expect_bind = true;
tok = lex.getToken();
}
+ else
+ {
+ // Fall through
+ }
::std::string bind_name;
// If a 'ref' or 'mut' annotation was seen, the next name must be a binding name
@@ -133,7 +145,7 @@ AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable)
lex.putback(tok);
AST::Pattern pat = Parse_PatternReal(lex, is_refutable);
- pat.set_bind(bind_name, is_ref, is_mut);
+ pat.set_bind(bind_name, bind_type, is_mut);
return ::std::move(pat);
}
@@ -326,11 +338,27 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refut
}
bool is_short_bind = false;
+ bool is_box = false;
+ AST::Pattern::BindType bind_type = AST::Pattern::BIND_MOVE;
+ bool is_mut = false;
+ if( tok.type() == TOK_RWORD_BOX ) {
+ is_box = true;
+ is_short_bind = true;
+ GET_TOK(tok, lex);
+ }
if( tok.type() == TOK_RWORD_REF ) {
is_short_bind = true;
GET_TOK(tok, lex);
+ if( tok.type() == TOK_RWORD_MUT ) {
+ bind_type = AST::Pattern::BIND_MUTREF;
+ GET_TOK(tok, lex);
+ }
+ else {
+ bind_type = AST::Pattern::BIND_REF;
+ }
}
- if( tok.type() == TOK_RWORD_MUT ) {
+ else if( tok.type() == TOK_RWORD_MUT ) {
+ is_mut = true;
is_short_bind = true;
GET_TOK(tok, lex);
}
@@ -343,6 +371,11 @@ AST::Pattern Parse_PatternStruct(TokenStream& lex, AST::Path path, bool is_refut
if( is_short_bind || tok.type() != TOK_COLON ) {
lex.putback(tok);
pat = AST::Pattern(AST::Pattern::TagBind(), field);
+ pat.set_bind(field, bind_type, is_mut);
+ if( is_box )
+ {
+ pat = AST::Pattern(AST::Pattern::TagBox(), mv$(pat));
+ }
}
else {
CHECK_TOK(tok, TOK_COLON);