summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-03-13 17:59:41 +0800
committerJohn Hodge <tpg@mutabah.net>2016-03-13 17:59:41 +0800
commit9a3987bb1575c4ab1eae9c065e907773fa3dcf17 (patch)
treed3e227819939f337afa7bff4d8e9cfa6522ef8cc
parent5c2691b60c870f4669ba0b8e7ecc593f64a4265b (diff)
downloadmrust-9a3987bb1575c4ab1eae9c065e907773fa3dcf17.tar.gz
Parse - Rework to place spans on types
-rw-r--r--src/ast/ast.cpp2
-rw-r--r--src/ast/path.hpp4
-rw-r--r--src/ast/provided_module.cpp28
-rw-r--r--src/convert/resolve.cpp28
-rw-r--r--src/convert/typecheck_expr.cpp30
-rw-r--r--src/convert/typecheck_params.cpp4
-rw-r--r--src/expand/derive.cpp10
-rw-r--r--src/parse/expr.cpp2
-rw-r--r--src/parse/paths.cpp5
-rw-r--r--src/parse/root.cpp11
-rw-r--r--src/parse/types.cpp41
-rw-r--r--src/span.cpp2
-rw-r--r--src/types.hpp46
13 files changed, 107 insertions, 106 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index 15b425c8..a8a8c342 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -708,7 +708,7 @@ bool GenericParams::check_params(Crate& crate, ::std::vector<TypeRef>& types, bo
{
const auto& trait = bound.as_IsTrait().trait;
// Check if 'type' impls 'trait'
- if( !crate.find_impl(trait, trait, nullptr, nullptr) )
+ if( !crate.find_impl(trait, TypeRef(Span(), trait), nullptr, nullptr) )
{
throw ::std::runtime_error( FMT("No matching impl of "<<trait<<" for "<<type));
}
diff --git a/src/ast/path.hpp b/src/ast/path.hpp
index 4fc08bb1..1260ece3 100644
--- a/src/ast/path.hpp
+++ b/src/ast/path.hpp
@@ -130,7 +130,6 @@ public:
private:
/// The crate defining the root of this path (used for path resolution)
::std::string m_crate;
- Span m_span;
public:
Class m_class;
@@ -198,9 +197,6 @@ public:
}
- const Span& span() const {
- return m_span;
- }
Class::Tag class_tag() const {
return m_class.tag();
}
diff --git a/src/ast/provided_module.cpp b/src/ast/provided_module.cpp
index 0cbd2955..13b3b910 100644
--- a/src/ast/provided_module.cpp
+++ b/src/ast/provided_module.cpp
@@ -13,7 +13,7 @@ void AST_InitProvidedModule()
// "struct str([u8])"
g_compiler_module.add_struct(true, "str",
AST::Struct( AST::GenericParams(), ::std::vector<AST::StructItem> {
- AST::StructItem("", TypeRef(TypeRef::TagUnsizedArray(), TypeRef(CORETYPE_U8)), false),
+ AST::StructItem("", TypeRef(TypeRef::TagUnsizedArray(), Span(), TypeRef(Span(), CORETYPE_U8)), false),
}), AST::MetaItems());
// TODO: Defer this until AFTER
@@ -32,18 +32,18 @@ void AST_InitProvidedModule_Impls()
#define impl(trait, type) \
g_compiler_module.add_impl(AST::Impl(AST::MetaItems(), AST::GenericParams(), type, trait))
- impl(g_copy_marker_path, TypeRef(CORETYPE_U8));
- impl(g_copy_marker_path, TypeRef(CORETYPE_U16));
- impl(g_copy_marker_path, TypeRef(CORETYPE_U32));
- impl(g_copy_marker_path, TypeRef(CORETYPE_U64));
- impl(g_copy_marker_path, TypeRef(CORETYPE_UINT));
- impl(g_copy_marker_path, TypeRef(CORETYPE_I8));
- impl(g_copy_marker_path, TypeRef(CORETYPE_I16));
- impl(g_copy_marker_path, TypeRef(CORETYPE_I32));
- impl(g_copy_marker_path, TypeRef(CORETYPE_I64));
- impl(g_copy_marker_path, TypeRef(CORETYPE_INT));
- impl(g_copy_marker_path, TypeRef(CORETYPE_F32));
- impl(g_copy_marker_path, TypeRef(CORETYPE_F64));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_U8));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_U16));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_U32));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_U64));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_UINT));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_I8));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_I16));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_I32));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_I64));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_INT));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_F32));
+ impl(g_copy_marker_path, TypeRef(Span(), CORETYPE_F64));
// A hacky default impl of 'Sized', with a negative impl on [T]
impl(g_sized_marker_path, TypeRef());
@@ -54,7 +54,7 @@ void AST_InitProvidedModule_Impls()
g_compiler_module.add_neg_impl(AST::ImplDef(
AST::MetaItems(), ::std::move(tps),
g_sized_marker_path,
- TypeRef(TypeRef::TagUnsizedArray(), TypeRef(TypeRef::TagArg(), "T"))
+ TypeRef(TypeRef::TagUnsizedArray(), Span(), TypeRef(TypeRef::TagArg(), "T"))
));
}
}
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index e061e5e0..b20df695 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -1036,10 +1036,10 @@ void CPathResolver::handle_path_abs__into_ufcs(const Span& span, AST::Path& path
resolve_path(span, m_crate, type_path);
// If the type path refers to a trait, put it in the trait location
if(type_path.binding().is_Trait()) {
- type_path = AST::Path(AST::Path::TagUfcs(), TypeRef(), TypeRef(mv$(type_path)), {mv$(nodes[i])} );
+ type_path = AST::Path(AST::Path::TagUfcs(), TypeRef(span), TypeRef(span, mv$(type_path)), {mv$(nodes[i])} );
}
else {
- type_path = AST::Path(AST::Path::TagUfcs(), TypeRef(mv$(type_path)), TypeRef(), {mv$(nodes[i])} );
+ type_path = AST::Path(AST::Path::TagUfcs(), TypeRef(span, mv$(type_path)), TypeRef(span), {mv$(nodes[i])} );
}
}
@@ -1108,20 +1108,20 @@ void CPathResolver::handle_path_ufcs(const Span& span, AST::Path& path, CASTIter
if( this->find_trait_item(span, p, t, item_name, is_method, ptr, found_trait_path) ) {
if( is_method ) {
if( info.nodes.size() != 1 )
- ERROR(path.span(), E0000, "CPathResolver::handle_path_ufcs - Sub-nodes to method");
+ ERROR(span, E0000, "CPathResolver::handle_path_ufcs - Sub-nodes to method");
auto f = reinterpret_cast<const ::AST::Function*>(ptr);
path.bind_function(*f, path.nodes()[0].args());
}
else {
if( info.nodes.size() != 1 )
- throw ParseError::Todo("CPathResolver::handle_path_ufcs - Sub nodes on associated type");
+ TODO(span, "CPathResolver::handle_path_ufcs - Sub nodes on associated type");
auto t = reinterpret_cast<const ::AST::TypeAlias*>(ptr);
path.bind_type_alias(*t);
}
- *info.trait = TypeRef( mv$(found_trait_path) );
+ *info.trait = TypeRef( span, mv$(found_trait_path) );
}
else {
- ERROR(path.span(), E0000, "Cannot find item '" << item_name << "' on Self");
+ ERROR(span, E0000, "Cannot find item '" << item_name << "' on Self");
}
}
else if( info.type->is_type_param() )
@@ -1183,9 +1183,9 @@ void CPathResolver::handle_path_ufcs(const Span& span, AST::Path& path, CASTIter
DEBUG("Searching impl " << impl);
for( const auto& fcn : impl.functions() )
{
- if( fcn.name == name) {
+ if( fcn.name == name ) {
path.bind_function(fcn.data, path.nodes()[0].args());
- info.trait = make_unique_ptr( TypeRef(TypeRef::TagInvalid()) );
+ info.trait = make_unique_ptr( TypeRef(TypeRef::TagInvalid(), span) );
return true;
}
}
@@ -1205,7 +1205,7 @@ void CPathResolver::handle_path_ufcs(const Span& span, AST::Path& path, CASTIter
bool is_fcn;
if( trait.has_named_item(item_name, is_fcn) ) {
IF_OPTION_SOME(impl, m_crate.find_impl( trait_p, *info.type ),
- *info.trait = TypeRef( trait_p );
+ *info.trait = TypeRef( span, trait_p );
return ;
)
}
@@ -1229,7 +1229,7 @@ void CPathResolver::handle_path_ufcs(const Span& span, AST::Path& path, CASTIter
{
if( var.m_name == name ) {
path.bind_enum_var(e, name);
- info.trait = make_unique_ptr( TypeRef(TypeRef::TagInvalid()) );
+ info.trait = make_unique_ptr( TypeRef(TypeRef::TagInvalid(), span) );
return ;
}
}
@@ -1352,7 +1352,7 @@ void CPathResolver::handle_path_rel(const Span& span, AST::Path& path, CASTItera
TODO(span, "Expand `str` to internal path");
}
else if( auto ct = coretype_fromstring(path[0].name()) ) {
- auto ty = TypeRef(TypeRef::TagPrimitive(), ct);
+ auto ty = TypeRef(TypeRef::TagPrimitive(), span, ct);
auto newpath = AST::Path(AST::Path::TagUfcs(), ty, TypeRef());
newpath.add_tailing(path);
path = mv$(newpath);
@@ -1407,9 +1407,9 @@ bool CPathResolver::find_trait_item(const Span& span, const AST::Path& path, AST
out_trait_path.resolve_args([&](const char* name) -> TypeRef {
int idx = trait.params().find_name(name);
if(idx < 0)
- ERROR(st.span(), E0000, "Parameter " << name << " not found");
+ ERROR(span, E0000, "Parameter " << name << " not found");
if(static_cast<unsigned int>(idx) >= path.nodes().back().args().size())
- ERROR(st.span(), E0000, "Path '"<<path<<"' had too few args");
+ ERROR(span, E0000, "Path '"<<path<<"' had too few args");
const auto& tr = path.nodes().back().args().at(idx);
DEBUG("Replacing '" << name << "' with " << tr);
return tr;
@@ -1531,7 +1531,7 @@ void CPathResolver::handle_type(TypeRef& type)
// TODO: Should I always resolve `Self` when it's concretely known?
// If the name was "Self", but Self isn't already defined... then we need to make it an arg?
if( this->m_self_type.empty() || this->m_self_type.back().is_None() ) {
- ERROR(type.path().span(), E0000, "Unexpected 'Self'");
+ ERROR(Span(), E0000, "Unexpected 'Self'");
}
else {
TU_MATCH(SelfType, (this->m_self_type.back()), (ent),
diff --git a/src/convert/typecheck_expr.cpp b/src/convert/typecheck_expr.cpp
index 1c7099e4..314102ef 100644
--- a/src/convert/typecheck_expr.cpp
+++ b/src/convert/typecheck_expr.cpp
@@ -208,24 +208,6 @@ void CTypeChecker::handle_function(AST::Path path, AST::Function& fcn)
handle_type(fcn.rettype());
- //switch(fcn.fcn_class())
- //{
- //case AST::Function::CLASS_UNBOUND:
- // break;
- //case AST::Function::CLASS_REFMETHOD:
- // local_variable(false, "self", TypeRef(TypeRef::TagReference(), false, get_local_type("Self")));
- // break;
- //case AST::Function::CLASS_MUTMETHOD:
- // local_variable(false, "self", TypeRef(TypeRef::TagReference(), true, get_local_type("Self")));
- // break;
- //case AST::Function::CLASS_VALMETHOD:
- // local_variable(false, "self", TypeRef(get_local_type("Self")));
- // break;
- //case AST::Function::CLASS_MUTVALMETHOD:
- // local_variable(true, "self", TypeRef(get_local_type("Self")));
- // break;
- //}
-
for( auto& arg : fcn.args() )
{
handle_type(arg.second);
@@ -248,7 +230,7 @@ void CTypeChecker::iterate_traits(::std::function<bool(const TypeRef& trait)> fc
{
for( auto& trait : scopei->traits )
{
- if( !fcn(trait) )
+ if( !fcn(TypeRef(Span(), trait)) )
{
return;
}
@@ -273,7 +255,7 @@ void CTypeChecker::check_enum_variant(::std::vector<TypeRef>& path_args, const :
for( unsigned int i = 0; i < var.m_sub_types.size(); i ++ )
{
var.m_sub_types[i].match_args(
- TypeRef(TypeRef::TagTuple(), argtypes),
+ TypeRef(TypeRef::TagTuple(), Span(), argtypes),
[&](const char *name, const TypeRef& t) {
DEBUG("Binding " << name << " to type " << t);
int idx = params.find_name(name);
@@ -325,7 +307,7 @@ void CTC_NodeVisitor::visit(AST::ExprNode_NamedValue& node)
throw ::std::runtime_error( FMT("Too many arguments to enum variant - " << p) );
while(pn.args().size() < num_params)
pn.args().push_back( TypeRef() );
- node.get_res_type() = TypeRef(tp);
+ node.get_res_type() = TypeRef(Span(node.get_pos()), tp);
)
)
}
@@ -342,7 +324,7 @@ void CTC_NodeVisitor::visit(AST::ExprNode_LetBinding& node)
{
DEBUG("ExprNode_LetBinding");
- node.get_res_type() = TypeRef(TypeRef::TagUnit());
+ node.get_res_type() = TypeRef(TypeRef::TagUnit(), Span(node.get_pos()));
// Evaluate value
AST::NodeVisitor::visit(node.m_value);
@@ -371,7 +353,7 @@ void CTC_NodeVisitor::visit(AST::ExprNode_LetBinding& node)
void CTC_NodeVisitor::visit(AST::ExprNode_Assign& node)
{
- node.get_res_type() = TypeRef(TypeRef::TagUnit());
+ node.get_res_type() = TypeRef(TypeRef::TagUnit(), Span(node.get_pos()));
AST::NodeVisitor::visit(node.m_slot);
AST::NodeVisitor::visit(node.m_value);
}
@@ -601,7 +583,7 @@ void CTC_NodeVisitor::visit(AST::ExprNode_CallPath& node)
AST::Path p = node.m_path;
p.nodes().pop_back();
- TypeRef ty( ::std::move(p) );
+ TypeRef ty(Span(), ::std::move(p) );
DEBUG("ExprNode_CallPath - enum t = " << ty);
node.get_res_type().merge_with(ty);
diff --git a/src/convert/typecheck_params.cpp b/src/convert/typecheck_params.cpp
index 2abcc099..aa53d3bd 100644
--- a/src/convert/typecheck_params.cpp
+++ b/src/convert/typecheck_params.cpp
@@ -212,7 +212,7 @@ void CGenericParamChecker::check_generic_params(const AST::GenericParams& info,
TU_IFLET(AST::GenericBound, bound, IsTrait, ent,
auto ra_fcn = [&](const char *a){
if( strcmp(a, "Self") == 0 ) {
- if( self_type == TypeRef(TypeRef::TagInvalid()) )
+ if( ! self_type.is_valid() )
throw CompileError::Generic("Unexpected use of 'Self' in bounds");
return self_type;
}
@@ -266,7 +266,7 @@ void CGenericParamChecker::handle_path(AST::Path& path, CASTIterator::PathMode p
comm( info.alias_->params() );
),
(Function,
- check_generic_params(info.func_->params(), last_node.args(), TypeRef(TypeRef::TagInvalid()), (m_within_expr > 0));
+ check_generic_params(info.func_->params(), last_node.args(), TypeRef(TypeRef::TagInvalid(), Span()), (m_within_expr > 0));
),
(EnumVar,
diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp
index e4c10f4e..028a8d9b 100644
--- a/src/expand/derive.cpp
+++ b/src/expand/derive.cpp
@@ -50,9 +50,9 @@ public:
// TODO: be correct herhe and use "core" as the crate name
// - Requires handling the crate_name crate attribute correctly
const AST::Path debug_trait("", { AST::PathNode("fmt", {}), AST::PathNode("Debug", {}) });
- const TypeRef ret_type(AST::Path("", {AST::PathNode("fmt",{}), AST::PathNode("Result",{})}) );
- const TypeRef f_type(TypeRef::TagReference(), true,
- TypeRef(AST::Path("", {AST::PathNode("fmt",{}), AST::PathNode("Formatter", {})}))
+ const TypeRef ret_type(Span(), AST::Path("", {AST::PathNode("fmt",{}), AST::PathNode("Result",{})}) );
+ const TypeRef f_type(TypeRef::TagReference(), Span(), true,
+ TypeRef(Span(), AST::Path("", {AST::PathNode("fmt",{}), AST::PathNode("Formatter", {})}))
);
const ::std::string& name = type.path().nodes().back().name();
@@ -86,7 +86,7 @@ public:
AST::GenericParams(),
ret_type,
vec$(
- ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "self"), TypeRef(TypeRef::TagReference(), false, TypeRef("Self")) ),
+ ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "self"), TypeRef(TypeRef::TagReference(), Span(), false, TypeRef("Self")) ),
::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "f"), f_type )
)
);
@@ -122,7 +122,7 @@ static void derive_item(AST::Module& mod, const AST::MetaItem& attr, const AST::
bool fail = false;
const auto& params = item.params();
- TypeRef type(path);
+ TypeRef type(Span(), path);
for( const auto& param : params.ty_params() )
type.path().nodes().back().args().push_back( TypeRef(TypeRef::TagArg(), param.name()) );
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index eea4f101..ee5698e8 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -874,7 +874,7 @@ ExprNodeP Parse_ExprVal_Closure(TokenStream& lex, bool is_move)
if( GET_TOK(tok, lex) == TOK_THINARROW ) {
if( GET_TOK(tok, lex) == TOK_EXCLAM ) {
- rt = TypeRef(TypeRef::TagInvalid());
+ rt = TypeRef(TypeRef::TagInvalid(), Span(tok.get_pos()));
}
else {
lex.putback(tok);
diff --git a/src/parse/paths.cpp b/src/parse/paths.cpp
index 1c8695d7..1e0ddac1 100644
--- a/src/parse/paths.cpp
+++ b/src/parse/paths.cpp
@@ -110,6 +110,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi
// HACK - 'Fn*(...) -> ...' notation
else if( tok.type() == TOK_PAREN_OPEN )
{
+ auto ps = lex.start_span();
DEBUG("Fn() hack");
::std::vector<TypeRef> args;
if( GET_TOK(tok, lex) == TOK_PAREN_CLOSE )
@@ -125,7 +126,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi
}
CHECK_TOK(tok, TOK_PAREN_CLOSE);
- TypeRef ret_type = TypeRef( TypeRef::TagUnit() );
+ TypeRef ret_type = TypeRef( TypeRef::TagUnit(), Span(tok.get_pos()) );
if( GET_TOK(tok, lex) == TOK_THINARROW ) {
ret_type = Parse_Type(lex);
}
@@ -135,7 +136,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi
DEBUG("- Fn("<<args<<")->"<<ret_type<<"");
// Encode into path, by converting Fn(A,B)->C into Fn<(A,B),Ret=C>
- params = ::std::vector<TypeRef> { TypeRef(TypeRef::TagTuple(), ::std::move(args)) };
+ params = ::std::vector<TypeRef> { TypeRef(TypeRef::TagTuple(), lex.end_span(ps), ::std::move(args)) };
// TODO: Use 'ret_type' as an associated type bound
GET_TOK(tok, lex);
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 83afc191..91f68867 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -248,6 +248,7 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaIt
if( lex.lookahead(ofs) == TOK_RWORD_SELF || (lex.lookahead(ofs) == TOK_RWORD_MUT && lex.lookahead(ofs+1) == TOK_RWORD_SELF) )
{
+ auto ps = lex.start_span();
::std::string lifetime;
if( GET_TOK(tok, lex) == TOK_LIFETIME ) {
lifetime = tok.str();
@@ -256,11 +257,11 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaIt
if( tok.type() == TOK_RWORD_MUT )
{
GET_CHECK_TOK(tok, lex, TOK_RWORD_SELF);
- args.push_back( ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "self"), TypeRef(TypeRef::TagReference(), true, TypeRef("Self"))) );
+ args.push_back( ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "self"), TypeRef(TypeRef::TagReference(), lex.end_span(ps), true, TypeRef("Self"))) );
}
else
{
- args.push_back( ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "self"), TypeRef(TypeRef::TagReference(), false, TypeRef("Self"))) );
+ args.push_back( ::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "self"), TypeRef(TypeRef::TagReference(), lex.end_span(ps), false, TypeRef("Self"))) );
}
DEBUG("TODO: UFCS / self lifetimes");
if( allow_self == false )
@@ -351,12 +352,12 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaIt
// Eat 'tok', negative comparison
}
- TypeRef ret_type = TypeRef(TypeRef::TagUnit());;
+ TypeRef ret_type = TypeRef(TypeRef::TagUnit(), Span(tok.get_pos()));
if( GET_TOK(tok, lex) == TOK_THINARROW )
{
// Return type
if( GET_TOK(tok, lex) == TOK_EXCLAM ) {
- ret_type = TypeRef(TypeRef::TagInvalid());
+ ret_type = TypeRef(TypeRef::TagInvalid(), Span(tok.get_pos()));
}
else {
lex.putback(tok);
@@ -619,7 +620,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( AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), "Self"), TypeRef(), {AST::PathNode(name)}) );
+ TypeRef a_type = TypeRef( Span(), AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), "Self"), TypeRef(Span()), {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/parse/types.cpp b/src/parse/types.cpp
index d5a2679f..01acf074 100644
--- a/src/parse/types.cpp
+++ b/src/parse/types.cpp
@@ -41,7 +41,7 @@ TypeRef Parse_Type_Int(TokenStream& lex)
throw ParseError::Generic(lex, "! is not a real type");
// '_' = Wildcard (type inferrence variable)
case TOK_UNDERSCORE:
- return TypeRef();
+ return TypeRef(Span(tok.get_pos()));
// 'unsafe' - An unsafe function type
case TOK_RWORD_UNSAFE:
@@ -54,9 +54,11 @@ TypeRef Parse_Type_Int(TokenStream& lex)
// '<' - An associated type cast
case TOK_LT:
- case TOK_DOUBLE_LT:
+ case TOK_DOUBLE_LT: {
lex.putback(tok);
- return TypeRef(TypeRef::TagPath(), Parse_Path(lex, PATH_GENERIC_TYPE));
+ auto path = Parse_Path(lex, PATH_GENERIC_TYPE);
+ return TypeRef(TypeRef::TagPath(), lex.end_span(ps), mv$(path));
+ }
//
case TOK_RWORD_FOR: {
GET_CHECK_TOK(tok, lex, TOK_LT);
@@ -82,11 +84,11 @@ TypeRef Parse_Type_Int(TokenStream& lex)
// or a primitive
if( auto ct = coretype_fromstring(tok.str()) )
{
- return TypeRef(TypeRef::TagPrimitive(), ct);
+ return TypeRef(TypeRef::TagPrimitive(), Span(tok.get_pos()), ct);
}
if( tok.str() == "str" )
{
- return TypeRef(TypeRef::TagPath(), AST::Path("", { AST::PathNode("#",{}), AST::PathNode("str",{}) }));
+ return TypeRef(TypeRef::TagPath(), Span(tok.get_pos()), AST::Path("", { AST::PathNode("#",{}), AST::PathNode("str",{}) }));
}
lex.putback(tok);
return Parse_Type_Path(lex, {});
@@ -114,12 +116,12 @@ TypeRef Parse_Type_Int(TokenStream& lex)
}
if( tok.type() == TOK_RWORD_MUT ) {
// Mutable reference
- return TypeRef(TypeRef::TagReference(), true, Parse_Type(lex));
+ return TypeRef(TypeRef::TagReference(), lex.end_span(ps), true, Parse_Type(lex));
}
else {
lex.putback(tok);
// Immutable reference
- return TypeRef(TypeRef::TagReference(), false, Parse_Type(lex));
+ return TypeRef(TypeRef::TagReference(), lex.end_span(ps), false, Parse_Type(lex));
}
throw ParseError::BugCheck("Reached end of Parse_Type:AMP");
}
@@ -130,12 +132,12 @@ TypeRef Parse_Type_Int(TokenStream& lex)
{
case TOK_RWORD_MUT:
// Mutable pointer
- return TypeRef(TypeRef::TagPointer(), true, Parse_Type(lex));
+ return TypeRef(TypeRef::TagPointer(), lex.end_span(ps), true, Parse_Type(lex));
case TOK_RWORD_CONST:
// Immutable pointer
- return TypeRef(TypeRef::TagPointer(), false, Parse_Type(lex));
+ return TypeRef(TypeRef::TagPointer(), lex.end_span(ps), false, Parse_Type(lex));
default:
- throw ParseError::Unexpected(lex, tok, Token(TOK_RWORD_CONST));
+ throw ParseError::Unexpected(lex, tok, {TOK_RWORD_CONST, TOK_RWORD_MUT});
}
throw ParseError::BugCheck("Reached end of Parse_Type:STAR");
// '[' - Array type
@@ -146,11 +148,11 @@ TypeRef Parse_Type_Int(TokenStream& lex)
// Sized array
AST::Expr array_size = Parse_Expr(lex);
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
- return TypeRef(TypeRef::TagSizedArray(), inner, array_size.take_node());
+ return TypeRef(TypeRef::TagSizedArray(), lex.end_span(ps), inner, array_size.take_node());
}
else if( tok.type() == TOK_SQUARE_CLOSE )
{
- return TypeRef(TypeRef::TagUnsizedArray(), inner);
+ return TypeRef(TypeRef::TagUnsizedArray(), lex.end_span(ps), inner);
}
else {
throw ParseError::Unexpected(lex, tok/*, "; or ]"*/);
@@ -161,7 +163,7 @@ TypeRef Parse_Type_Int(TokenStream& lex)
case TOK_PAREN_OPEN: {
DEBUG("Tuple");
if( GET_TOK(tok, lex) == TOK_PAREN_CLOSE )
- return TypeRef(TypeRef::TagTuple(), {});
+ return TypeRef(TypeRef::TagTuple(), lex.end_span(ps), {});
lex.putback(tok);
TypeRef inner = Parse_Type(lex);
@@ -189,7 +191,7 @@ TypeRef Parse_Type_Int(TokenStream& lex)
types.push_back(Parse_Type(lex));
}
CHECK_TOK(tok, TOK_PAREN_CLOSE);
- return TypeRef(TypeRef::TagTuple(), types); }
+ return TypeRef(TypeRef::TagTuple(), lex.end_span(ps), types); }
}
default:
throw ParseError::Unexpected(lex, tok);
@@ -199,6 +201,7 @@ TypeRef Parse_Type_Int(TokenStream& lex)
TypeRef Parse_Type_Fn(TokenStream& lex, ::std::vector<::std::string> hrls)
{
+ auto ps = lex.start_span();
// TODO: HRLs
TRACE_FUNCTION;
Token tok;
@@ -246,7 +249,7 @@ TypeRef Parse_Type_Fn(TokenStream& lex, ::std::vector<::std::string> hrls)
}
GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE);
- TypeRef ret_type = TypeRef(TypeRef::TagUnit());
+ TypeRef ret_type = TypeRef(TypeRef::TagUnit(), Span(tok.get_pos()));
if( GET_TOK(tok, lex) == TOK_THINARROW )
{
ret_type = Parse_Type(lex);
@@ -255,13 +258,15 @@ TypeRef Parse_Type_Fn(TokenStream& lex, ::std::vector<::std::string> hrls)
lex.putback(tok);
}
- return TypeRef(TypeRef::TagFunction(), ::std::move(abi), ::std::move(args), ::std::move(ret_type));
+ return TypeRef(TypeRef::TagFunction(), lex.end_span(ps), ::std::move(abi), ::std::move(args), ::std::move(ret_type));
}
TypeRef Parse_Type_Path(TokenStream& lex, ::std::vector<::std::string> hrls)
{
Token tok;
+ auto ps = lex.start_span();
+
::std::vector<AST::Path> traits;
::std::vector< ::std::string> lifetimes;
do {
@@ -276,10 +281,10 @@ TypeRef Parse_Type_Path(TokenStream& lex, ::std::vector<::std::string> hrls)
if( hrls.size() > 0 || traits.size() > 1 || lifetimes.size() > 0 ) {
if( lifetimes.size() )
DEBUG("TODO: Lifetime bounds on trait objects");
- return TypeRef(mv$(hrls), ::std::move(traits));
+ return TypeRef(lex.end_span(ps), mv$(hrls), ::std::move(traits));
}
else {
- return TypeRef(TypeRef::TagPath(), traits.at(0));
+ return TypeRef(TypeRef::TagPath(), lex.end_span(ps), traits.at(0));
}
}
diff --git a/src/span.cpp b/src/span.cpp
index 763bb748..b720b263 100644
--- a/src/span.cpp
+++ b/src/span.cpp
@@ -32,7 +32,7 @@ Span::Span():
start_line(0), start_ofs(0),
end_line(0), end_ofs(0) // */
{
- //DEBUG("Empty span");
+ DEBUG("Empty span");
//filename = FMT(":" << __builtin_return_address(0));
}
diff --git a/src/types.hpp b/src/types.hpp
index 6bdfb9a7..66121d37 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -116,6 +116,7 @@ public:
TypeRef(const TypeRef& other);
TypeRef& operator=(TypeRef&& other) {
m_data = mv$( other.m_data );
+ m_span = mv$( other.m_span );
return *this;
}
TypeRef& operator=(const TypeRef& other) {
@@ -123,56 +124,67 @@ public:
return *this;
}
- TypeRef():
+ TypeRef(Span sp=Span()):
m_data(TypeData::make_Any({}))
{}
struct TagInvalid {};
- TypeRef(TagInvalid):
+ TypeRef(TagInvalid, Span sp):
+ m_span(mv$(sp)),
m_data(TypeData::make_None({}))
{}
struct TagMacro {};
TypeRef(TagMacro, ::AST::MacroInvocation inv):
+ m_span(inv.span()),
m_data(TypeData::make_Macro({mv$(inv)}))
{}
struct TagUnit {}; // unit maps to a zero-length tuple, just easier to type
- TypeRef(TagUnit):
+ TypeRef(TagUnit, Span sp):
+ m_span(mv$(sp)),
m_data(TypeData::make_Unit({}))
{}
struct TagPrimitive {};
- TypeRef(TagPrimitive, enum eCoreType type):
+ TypeRef(TagPrimitive, Span sp, enum eCoreType type):
+ m_span(mv$(sp)),
m_data(TypeData::make_Primitive({type}))
{}
- TypeRef(enum eCoreType type):
+ TypeRef(Span sp, enum eCoreType type):
+ m_span(mv$(sp)),
m_data(TypeData::make_Primitive({type}))
{}
struct TagTuple {};
- TypeRef(TagTuple _, ::std::vector<TypeRef> inner_types):
+ TypeRef(TagTuple _, Span sp, ::std::vector<TypeRef> inner_types):
+ m_span(mv$(sp)),
m_data(TypeData::make_Tuple({::std::move(inner_types)}))
{}
struct TagFunction {};
- TypeRef(TagFunction, ::std::string abi, ::std::vector<TypeRef> args, TypeRef ret):
+ TypeRef(TagFunction, Span sp, ::std::string abi, ::std::vector<TypeRef> args, TypeRef ret):
+ m_span(mv$(sp)),
m_data(TypeData::make_Function({ Type_Function( false, abi, box$(ret), mv$(args) ) }))
{}
struct TagReference {};
- TypeRef(TagReference _, bool is_mut, TypeRef inner_type):
+ TypeRef(TagReference _, Span sp, bool is_mut, TypeRef inner_type):
+ m_span(mv$(sp)),
m_data(TypeData::make_Borrow({ is_mut, ::make_unique_ptr(mv$(inner_type)) }))
{}
struct TagPointer {};
- TypeRef(TagPointer _, bool is_mut, TypeRef inner_type):
+ TypeRef(TagPointer _, Span sp, bool is_mut, TypeRef inner_type):
+ m_span(mv$(sp)),
m_data(TypeData::make_Pointer({ is_mut, ::make_unique_ptr(mv$(inner_type)) }))
{}
struct TagSizedArray {};
- TypeRef(TagSizedArray _, TypeRef inner_type, ::std::shared_ptr<AST::ExprNode> size):
+ TypeRef(TagSizedArray _, Span sp, TypeRef inner_type, ::std::shared_ptr<AST::ExprNode> size):
+ m_span(mv$(sp)),
m_data(TypeData::make_Array({ ::make_unique_ptr(mv$(inner_type)), mv$(size) }))
{}
struct TagUnsizedArray {};
- TypeRef(TagUnsizedArray _, TypeRef inner_type):
+ TypeRef(TagUnsizedArray _, Span sp, TypeRef inner_type):
+ m_span(mv$(sp)),
m_data(TypeData::make_Array({ ::make_unique_ptr(mv$(inner_type)), ::std::shared_ptr<AST::ExprNode>() }))
{}
@@ -188,14 +200,16 @@ public:
{}
struct TagPath {};
- TypeRef(TagPath, AST::Path path):
+ TypeRef(TagPath, Span sp, AST::Path path):
+ m_span(mv$(sp)),
m_data(TypeData::make_Path({ ::std::move(path) }))
{}
- TypeRef(AST::Path path):
- TypeRef(TagPath(), ::std::move(path))
+ TypeRef(Span sp, AST::Path path):
+ TypeRef(TagPath(), mv$(sp), mv$(path))
{}
- TypeRef( ::std::vector<::std::string> hrls, ::std::vector<AST::Path> traits ):
+ TypeRef( Span sp, ::std::vector<::std::string> hrls, ::std::vector<AST::Path> traits ):
+ m_span(mv$(sp)),
m_data(TypeData::make_TraitObject({ mv$(hrls), ::std::move(traits) }))
{}
@@ -215,6 +229,8 @@ public:
/// Returns true if the type is fully known (all sub-types are not wildcards)
bool is_concrete() const;
+
+ bool is_valid() const { return ! m_data.is_None(); }
bool is_unbounded() const { return m_data.is_Any(); }
bool is_wildcard() const { return m_data.is_Any(); }