summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-05-02 12:51:05 +0800
committerJohn Hodge <tpg@mutabah.net>2016-05-02 12:51:05 +0800
commit809ac4b7f439a6f5b0fe97d3215ad79e510f4c10 (patch)
tree8cf11a34fd0c92d9a2a3e0aea3e2ade1a1df1d49 /src
parenta87c8d9ce4b789ba26146f2f574937558687789a (diff)
downloadmrust-809ac4b7f439a6f5b0fe97d3215ad79e510f4c10.tar.gz
AST - Make trait in UFCS paths be an optional Path
Diffstat (limited to 'src')
-rw-r--r--src/ast/path.cpp35
-rw-r--r--src/ast/path.hpp16
-rw-r--r--src/main.cpp2
-rw-r--r--src/parse/expr.cpp17
-rw-r--r--src/parse/paths.cpp24
-rw-r--r--src/parse/root.cpp2
-rw-r--r--src/resolve/absolute.cpp25
7 files changed, 80 insertions, 41 deletions
diff --git a/src/ast/path.cpp b/src/ast/path.cpp
index 5b1ba2f8..484ac7b7 100644
--- a/src/ast/path.cpp
+++ b/src/ast/path.cpp
@@ -58,14 +58,6 @@ PathNode::PathNode(::std::string name, ::std::vector<TypeRef> args):
m_params(args)
{
}
-const ::std::string& PathNode::name() const
-{
- return m_name;
-}
-const ::std::vector<TypeRef>& PathNode::args() const
-{
- return m_params;
-}
Ordering PathNode::ord(const PathNode& x) const
{
Ordering rv;
@@ -109,7 +101,11 @@ typename ::std::vector<Named<T> >::const_iterator find_named(const ::std::vector
}
// --- AST::Path
-AST::Path::Path(TagUfcs, TypeRef type, TypeRef trait, ::std::vector<AST::PathNode> nodes):
+AST::Path::Path(TagUfcs, TypeRef type, ::std::vector<AST::PathNode> nodes):
+ m_class( AST::Path::Class::make_UFCS({box$(type), nullptr, nodes}) )
+{
+}
+AST::Path::Path(TagUfcs, TypeRef type, Path trait, ::std::vector<AST::PathNode> nodes):
m_class( AST::Path::Class::make_UFCS({box$(type), box$(trait), nodes}) )
{
}
@@ -136,7 +132,10 @@ AST::Path::Path(const Path& x):
m_class = Class::make_Absolute({nodes: ent.nodes});
),
(UFCS,
- m_class = Class::make_UFCS({ box$(TypeRef(*ent.type)), box$(TypeRef(*ent.trait)), ent.nodes });
+ if( ent.trait )
+ m_class = Class::make_UFCS({ box$(TypeRef(*ent.type)), ::std::unique_ptr<Path>(new Path(*ent.trait)), ent.nodes });
+ else
+ m_class = Class::make_UFCS({ box$(TypeRef(*ent.type)), nullptr, ent.nodes });
)
)
@@ -505,8 +504,15 @@ void Path::print_pretty(::std::ostream& os, bool is_type_context) const
),
(UFCS,
//os << "/*ufcs*/";
- if( ! ent.trait->m_data.is_None() ) {
- os << "<" << *ent.type << " as " << *ent.trait << ">";
+ if( ent.trait ) {
+ os << "<" << *ent.type << " as ";
+ if( ent.trait->m_class.is_Invalid() ) {
+ os << "_";
+ }
+ else {
+ os << *ent.trait;
+ }
+ os << ">";
}
else {
os << "<" << *ent.type << ">";
@@ -546,6 +552,11 @@ void operator%(::Deserialiser& s, Path::Class::Tag& c) {
c = Path::Class::tag_from_str(n);
}
#define _D(VAR, ...) case Class::TAG_##VAR: { m_class = Class::make_null_##VAR(); auto& ent = m_class.as_##VAR(); (void)&ent; __VA_ARGS__ } break;
+::std::unique_ptr<Path> Path::from_deserialiser(Deserialiser& s) {
+ Path p;
+ s.item(p);
+ return ::std::unique_ptr<Path>( new Path( mv$(p) ) );
+}
SERIALISE_TYPE(Path::, "AST_Path", {
s % m_class.tag();
TU_MATCH(Path::Class, (m_class), (ent),
diff --git a/src/ast/path.hpp b/src/ast/path.hpp
index 3b2b9969..462ab946 100644
--- a/src/ast/path.hpp
+++ b/src/ast/path.hpp
@@ -91,9 +91,9 @@ class PathNode:
public:
PathNode() {}
PathNode(::std::string name, ::std::vector<TypeRef> args = {});
- const ::std::string& name() const;
- ::std::vector<TypeRef>& args() { return m_params; }
- const ::std::vector<TypeRef>& args() const;
+ const ::std::string& name() const { return m_name; }
+ ::std::vector<TypeRef>& args() { return m_params; }
+ const ::std::vector<TypeRef>& args() const { return m_params; }
Ordering ord(const PathNode& x) const;
void print_pretty(::std::ostream& os, bool is_type_context) const;
@@ -127,8 +127,8 @@ public:
::std::vector<PathNode> nodes;
} ),
(UFCS, struct { // Type-relative
- ::std::unique_ptr<TypeRef> type;
- ::std::unique_ptr<TypeRef> trait;
+ ::std::unique_ptr<TypeRef> type; // always non-null
+ ::std::unique_ptr<Path> trait; // nullptr = inherent, Invalid = unknown trait
::std::vector<PathNode> nodes;
} )
);
@@ -166,9 +166,8 @@ public:
// UFCS
struct TagUfcs {};
- // TODO: Replace with "Path(TagUfcs, TypeRef, Path, PathNode)" and "Path(TagUfcs, TypeRef, PathNode)"
- // - Making Class::UFCS.trait be a nullable Path pointer
- Path(TagUfcs, TypeRef type, TypeRef trait, ::std::vector<PathNode> nodes={});
+ Path(TagUfcs, TypeRef type, ::std::vector<PathNode> nodes={});
+ Path(TagUfcs, TypeRef type, Path trait, ::std::vector<PathNode> nodes={});
// VARIABLE
struct TagLocal {};
@@ -324,6 +323,7 @@ public:
bool operator!=(const Path& x) const { return ord(x) != OrdEqual; }
bool operator<(const Path& x) const { return ord(x) != OrdLess; }
+ static ::std::unique_ptr<Path> from_deserialiser(Deserialiser& s);
SERIALISABLE_PROTOTYPES();
void print_pretty(::std::ostream& os, bool is_type_context) const;
friend ::std::ostream& operator<<(::std::ostream& os, const Path& path);
diff --git a/src/main.cpp b/src/main.cpp
index 07e25f0f..2030a663 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -122,7 +122,7 @@ int main(int argc, char *argv[])
//Resolve_UfcsPaths(crate);
// OLD resolve code, kinda bad
- ResolvePaths(crate);
+ //ResolvePaths(crate);
});
// XXX: Dump crate before typecheck
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index 407afbf3..3c12941d 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -964,16 +964,19 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)
lex.putback(tok);
case TOK_LT: {
TypeRef ty = Parse_Type(lex);
- TypeRef trait;// = TypeRef(TypeRef::TagInvalid());
if( GET_TOK(tok, lex) == TOK_RWORD_AS ) {
- trait = Parse_Type(lex);
+ auto trait = Parse_Path(lex, PATH_GENERIC_TYPE);
+ GET_CHECK_TOK(tok, lex, TOK_GT);
+ GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
+ path = AST::Path(AST::Path::TagUfcs(), ty, trait, Parse_PathNodes(lex, PATH_GENERIC_EXPR));
}
- else
+ else {
lex.putback(tok);
- GET_CHECK_TOK(tok, lex, TOK_GT);
- // TODO: Terminating the "path" here is sometimes valid
- GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
- path = AST::Path(AST::Path::TagUfcs(), ty, trait, Parse_PathNodes(lex, PATH_GENERIC_EXPR));
+ GET_CHECK_TOK(tok, lex, TOK_GT);
+ // TODO: Terminating the "path" here is sometimes valid
+ GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
+ path = AST::Path(AST::Path::TagUfcs(), ty, Parse_PathNodes(lex, PATH_GENERIC_EXPR));
+ }
}
if(0)
case TOK_RWORD_SELF:
diff --git a/src/parse/paths.cpp b/src/parse/paths.cpp
index 1e0ddac1..2e463060 100644
--- a/src/parse/paths.cpp
+++ b/src/parse/paths.cpp
@@ -38,16 +38,26 @@ AST::Path Parse_Path(TokenStream& lex, eParsePathGenericMode generic_mode)
lex.putback( Token(TOK_LT) );
case TOK_LT: {
TypeRef ty = Parse_Type(lex);
- TypeRef trait;
if( GET_TOK(tok, lex) == TOK_RWORD_AS ) {
- trait = Parse_Type(lex);
+ ::AST::Path trait;
+ if( GET_TOK(tok, lex) == TOK_DOUBLE_COLON ) {
+ trait = Parse_Path(lex, false, PATH_GENERIC_TYPE);
+ }
+ else {
+ lex.putback(tok);
+ trait = Parse_Path(lex, true, PATH_GENERIC_TYPE);
+ }
+ GET_CHECK_TOK(tok, lex, TOK_GT);
+ GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
+ return AST::Path(AST::Path::TagUfcs(), ty, trait, Parse_PathNodes(lex, generic_mode));
}
- else
+ else {
lex.putback(tok);
- GET_CHECK_TOK(tok, lex, TOK_GT);
- // TODO: Terminating the "path" here is sometimes valid?
- GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
- return AST::Path(AST::Path::TagUfcs(), ty, trait, Parse_PathNodes(lex, generic_mode));
+ GET_CHECK_TOK(tok, lex, TOK_GT);
+ // TODO: Terminating the "path" here is sometimes valid?
+ GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
+ return AST::Path(AST::Path::TagUfcs(), ty, Parse_PathNodes(lex, generic_mode));
+ }
}
default:
lex.putback(tok);
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 4dc8f999..df149a5b 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -618,7 +618,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, AST::Module& mod, const AST::MetaIte
if( GET_TOK(tok, lex) == TOK_COLON )
{
// Bounded associated type
- TypeRef a_type = TypeRef( Span(), AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), "Self"), TypeRef(Span()), {AST::PathNode(name)}) );
+ TypeRef a_type = TypeRef( Span(), AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), "Self"), AST::Path(), {AST::PathNode(name)}) );
//TypeRef a_type = TypeRef(TypeRef::TagAssoc(), TypeRef(TypeRef::TagArg(), "Self"), TypeRef(), name);
Parse_TypeBound(lex, params, a_type);
GET_TOK(tok, lex);
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp
index 7d11c85e..b3df1a0e 100644
--- a/src/resolve/absolute.cpp
+++ b/src/resolve/absolute.cpp
@@ -227,7 +227,7 @@ struct Context
-void Resolve_Absolute_Path(const Context& context, const Span& sp, bool is_type, ::AST::Path& path);
+void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, bool is_type, ::AST::Path& path);
void Resolve_Absolute_Type(Context& context, TypeRef& type);
void Resolve_Absolute_Expr(Context& context, ::AST::Expr& expr);
void Resolve_Absolute_Expr(Context& context, ::AST::ExprNode& node);
@@ -235,9 +235,20 @@ void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pat
void Resolve_Absolute_Mod(const ::AST::Crate& crate, ::AST::Module& mod);
-void Resolve_Absolute_Path(const Context& context, const Span& sp, bool is_type, ::AST::Path& path)
+void Resolve_Absolute_PathNodes(/*const*/ Context& context, const Span& sp, bool is_type, ::std::vector< ::AST::PathNode >& nodes)
+{
+ for(auto& node : nodes)
+ {
+ for(auto& arg : node.args())
+ {
+ Resolve_Absolute_Type(context, arg);
+ }
+ }
+}
+void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, bool is_type, ::AST::Path& path)
{
DEBUG("is_type = " << is_type << ", path = " << path);
+
TU_MATCH(::AST::Path::Class, (path.m_class), (e),
(Invalid,
BUG(sp, "Encountered invalid path");
@@ -287,8 +298,12 @@ void Resolve_Absolute_Path(const Context& context, const Span& sp, bool is_type,
// Nothing to do (TODO: Bind?)
),
(UFCS,
- Resolve_Absolute_Type(context, e.type);
- TODO(sp, "Resolve_Absolute_Path - UFCS");
+ Resolve_Absolute_Type(context, *e.type);
+ if( e.trait ) {
+ Resolve_Absolute_Path(context, Span(), true, *e.trait);
+ }
+
+ Resolve_Absolute_PathNodes(context, Span(), is_type, e.nodes);
)
)
}
@@ -463,7 +478,7 @@ void Resolve_Absolute_Generic(Context& context, ::AST::GenericParams& params)
}
// Locals shouldn't be possible, as they'd end up as MaybeBind. Will assert the path class.
-void Resolve_Absolute_PatternValue(const Context& context, ::AST::Pattern::Value& val)
+void Resolve_Absolute_PatternValue(/*const*/ Context& context, ::AST::Pattern::Value& val)
{
TU_MATCH(::AST::Pattern::Value, (val), (e),
(Invalid, ),