summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/expr.cpp1
-rw-r--r--src/ast/path.cpp6
-rw-r--r--src/ast/path.hpp5
-rw-r--r--src/convert/resolve.cpp8
-rw-r--r--src/parse/expr.cpp24
5 files changed, 34 insertions, 10 deletions
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp
index 3c1d3c66..97d951fc 100644
--- a/src/ast/expr.cpp
+++ b/src/ast/expr.cpp
@@ -75,7 +75,6 @@ SERIALISE_TYPE(Expr::, "Expr", {
else _(ExprNode_Field)
else _(ExprNode_Deref)
else _(ExprNode_Cast)
- else _(ExprNode_CallPath)
else _(ExprNode_BinOp)
else _(ExprNode_UniOp)
else
diff --git a/src/ast/path.cpp b/src/ast/path.cpp
index 1f07d4b0..fae2642e 100644
--- a/src/ast/path.cpp
+++ b/src/ast/path.cpp
@@ -48,6 +48,12 @@ SERIALISE_TYPE(PathNode::, "PathNode", {
})
// --- AST::Path
+AST::Path::Path(TagUfcs, TypeRef type, TypeRef trait):
+ m_class(UFCS),
+ m_ufcs({::std::move(type), ::std::move(trait)} )
+{
+}
+
template<typename T>
typename ::std::vector<Item<T> >::const_iterator find_named(const ::std::vector<Item<T> >& vec, const ::std::string& name)
{
diff --git a/src/ast/path.hpp b/src/ast/path.hpp
index 447ff0a0..4701b03a 100644
--- a/src/ast/path.hpp
+++ b/src/ast/path.hpp
@@ -80,6 +80,7 @@ private:
RELATIVE,
ABSOLUTE,
LOCAL,
+ UFCS,
};
/// The crate defining the root of this path (used for path resolution)
@@ -89,7 +90,9 @@ private:
/// - Absolute is "relative" to the crate root
/// - Relative doesn't have a set crate (and can't be resolved)
/// - Local is a special case to handle possible use of local varaibles
+ /// - UFCS is relative to a type
Class m_class;
+ ::std::vector<TypeRef> m_ufcs;
::std::vector<PathNode> m_nodes;
BindingType m_binding_type = UNBOUND;
@@ -114,6 +117,8 @@ public:
Path(TagAbsolute):
m_class(ABSOLUTE)
{}
+ struct TagUfcs {};
+ Path(TagUfcs, TypeRef type, TypeRef trait);
struct TagLocal {};
Path(TagLocal, ::std::string name):
m_class(LOCAL),
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index 95325da1..e519d485 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -435,13 +435,7 @@ void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& mod
case AST::Path::ENUM:
break;
- case AST::Path::ALIAS:
- case AST::Path::ENUM_VAR:
- case AST::Path::STRUCT:
- case AST::Path::STRUCT_METHOD:
- case AST::Path::TRAIT:
- case AST::Path::FUNCTION:
- case AST::Path::STATIC:
+ default:
throw ParseError::Generic("Wildcard imports are only allowed on modules and enums");
}
}
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index d618a9af..222a6a3a 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -903,6 +903,7 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)
case TOK_BRACE_OPEN:
lex.putback(tok);
return Parse_ExprBlockNode(lex);
+
case TOK_RWORD_LOOP:
return NEWNODE( AST::ExprNode_Loop, "", Parse_ExprBlockNode(lex) );
case TOK_RWORD_WHILE:
@@ -919,9 +920,28 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)
return rv;
}
- case TOK_RWORD_SUPER:
+ // UFCS
+ case TOK_DOUBLE_LT:
+ lex.putback(tok);
+ case TOK_LT: {
+ TypeRef ty = Parse_Type(lex);
+ TypeRef trait;
+ if( GET_TOK(tok, lex) == TOK_RWORD_AS ) {
+ trait = Parse_Type(lex);
+ }
+ 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 = Parse_PathFrom(lex, AST::Path(AST::Path::TagSuper()), PATH_GENERIC_EXPR);
+ path = Parse_PathFrom(lex, AST::Path(AST::Path::TagUfcs(), ty, trait), PATH_GENERIC_EXPR);
+ }
+ if(0)
+ case TOK_RWORD_SUPER:
+ {
+ GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
+ path = Parse_PathFrom(lex, AST::Path(AST::Path::TagSuper()), PATH_GENERIC_EXPR);
+ }
if(0)
case TOK_IDENT:
// Get path