summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2018-05-20 22:01:59 +0800
committerJohn Hodge <tpg@mutabah.net>2018-05-20 22:01:59 +0800
commitde9ecd7a2d70359b34e77ded57e5aa9284345ac5 (patch)
tree29ab42c6c06960720bd67f0b8ebaec807ad0284e
parent134be5198993096ab5216b6d52a8937430c733b0 (diff)
downloadmrust-de9ecd7a2d70359b34e77ded57e5aa9284345ac5.tar.gz
AST - Refactor lifetime/HRB handling
-rw-r--r--src/ast/ast.cpp30
-rw-r--r--src/ast/attrs.hpp21
-rw-r--r--src/ast/dump.cpp8
-rw-r--r--src/ast/generics.hpp74
-rw-r--r--src/ast/path.hpp5
-rw-r--r--src/ast/types.cpp33
-rw-r--r--src/ast/types.hpp77
-rw-r--r--src/expand/derive.cpp25
-rw-r--r--src/expand/mod.cpp8
-rw-r--r--src/expand/proc_macro.cpp48
-rw-r--r--src/hir/from_ast.cpp57
-rw-r--r--src/parse/common.hpp2
-rw-r--r--src/parse/paths.cpp4
-rw-r--r--src/parse/root.cpp52
-rw-r--r--src/parse/tokenstream.cpp4
-rw-r--r--src/parse/types.cpp77
-rw-r--r--src/resolve/absolute.cpp16
17 files changed, 376 insertions, 165 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index 641bd633..1a19a10f 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -379,10 +379,31 @@ Item Item::clone() const
//os << ")";
return os;
}
+::std::ostream& operator<<(::std::ostream& os, const LifetimeParam& p)
+{
+ os << "'" << p.m_name;
+ return os;
+}
+
+::std::ostream& operator<<(::std::ostream& os, const HigherRankedBounds& x)
+{
+ if( x.m_lifetimes.empty() ) {
+ return os;
+ }
+ os << "for<";
+ for(const auto& l : x.m_lifetimes)
+ os << "'" << l << ",";
+ os << "> ";
+ return os;
+}
+
::std::ostream& operator<<(::std::ostream& os, const GenericBound& x)
{
TU_MATCH(GenericBound, (x), (ent),
+ (None,
+ os << "/*-*/";
+ ),
(Lifetime,
os << "'" << ent.test << ": '" << ent.bound;
),
@@ -390,14 +411,7 @@ Item Item::clone() const
os << ent.type << ": '" << ent.bound;
),
(IsTrait,
- if( ! ent.hrls.empty() )
- {
- os << "for<";
- for(const auto& l : ent.hrls)
- os << "'" << l;
- os << ">";
- }
- os << ent.type << ": " << ent.trait;
+ os << ent.outer_hrbs << ent.type << ": " << ent.inner_hrbs << ent.trait;
),
(MaybeTrait,
os << ent.type << ": ?" << ent.trait;
diff --git a/src/ast/attrs.hpp b/src/ast/attrs.hpp
index 4afbdbc1..1926e96a 100644
--- a/src/ast/attrs.hpp
+++ b/src/ast/attrs.hpp
@@ -30,8 +30,8 @@ public:
// Move present
AttributeList(AttributeList&&) = default;
AttributeList& operator=(AttributeList&&) = default;
- // No copy
- AttributeList(const AttributeList&) = delete;
+ // No copy assign, but explicit copy
+ explicit AttributeList(const AttributeList&) = default;
AttributeList& operator=(const AttributeList&) = delete;
// Explicit clone
AttributeList clone() const;
@@ -97,7 +97,22 @@ public:
{
}
- Attribute(const Attribute& ) = delete;
+ explicit Attribute(const Attribute& x):
+ m_span(x.m_span),
+ m_name(x.m_name),
+ m_is_used(x.m_is_used)
+ {
+ TU_MATCHA( (x.m_data), (e),
+ (None,
+ ),
+ (String,
+ m_data = AttributeData::make_String({ e.val });
+ ),
+ (List,
+ m_data = AttributeData::make_List({ ::std::vector<Attribute>(e.sub_items) });
+ )
+ )
+ }
Attribute& operator=(const Attribute&& ) = delete;
Attribute(Attribute&& ) = default;
Attribute& operator=(Attribute&& ) = default;
diff --git a/src/ast/dump.cpp b/src/ast/dump.cpp
index b6336a02..73b332c0 100644
--- a/src/ast/dump.cpp
+++ b/src/ast/dump.cpp
@@ -829,6 +829,9 @@ void RustPrinter::print_bounds(const AST::GenericParams& params)
m_os << indent();
TU_MATCH(AST::GenericBound, (b), (ent),
+ (None,
+ m_os << "/*-*/";
+ ),
(Lifetime,
m_os << "'" << ent.test << ": '" << ent.bound;
),
@@ -836,10 +839,7 @@ void RustPrinter::print_bounds(const AST::GenericParams& params)
m_os << ent.type << ": '" << ent.bound;
),
(IsTrait,
- if( ent.hrls.size() > 0 ) {
- m_os << "for<'" << ::join(", '", ent.hrls) << "> ";
- }
- m_os << ent.type << ": " << ent.trait;
+ m_os << ent.outer_hrbs << ent.type << ": " << ent.inner_hrbs << ent.trait;
),
(MaybeTrait,
m_os << ent.type << ": ?" << ent.trait;
diff --git a/src/ast/generics.hpp b/src/ast/generics.hpp
index bc14202e..c222044c 100644
--- a/src/ast/generics.hpp
+++ b/src/ast/generics.hpp
@@ -14,49 +14,86 @@ namespace AST {
class TypeParam
{
+ ::AST::AttributeList m_attrs;
+ Span m_span;
+ // TODO: use an Ident?
::std::string m_name;
::TypeRef m_default;
public:
TypeParam(TypeParam&& x) = default;
TypeParam& operator=(TypeParam&& x) = default;
- TypeParam(const TypeParam& x):
- m_name(x.m_name),
- m_default(x.m_default.clone())
- {}
- //TypeParam(): m_name("") {}
- TypeParam(::std::string name):
+ explicit TypeParam(const TypeParam& x):
+ m_attrs( x.m_attrs ),
+ m_span( x.m_span ),
+ m_name( x.m_name ),
+ m_default( x.m_default.clone() )
+ {
+ }
+
+ TypeParam(Span sp, ::AST::AttributeList attrs, ::std::string name):
+ m_attrs( ::std::move(attrs) ),
+ m_span( ::std::move(sp) ),
m_name( ::std::move(name) ),
- m_default( Span() )
+ m_default(m_span)
{}
+
void setDefault(TypeRef type) {
assert(m_default.is_wildcard());
m_default = ::std::move(type);
}
- const ::std::string& name() const { return m_name; }
+ const ::AST::AttributeList& attrs() const { return m_attrs; }
+ const Span& span() const { return m_span; }
+ const ::std::string& name() const { return m_name; }
const TypeRef& get_default() const { return m_default; }
TypeRef& get_default() { return m_default; }
friend ::std::ostream& operator<<(::std::ostream& os, const TypeParam& tp);
};
+class LifetimeParam
+{
+ ::AST::AttributeList m_attrs;
+ Span m_span;
+ Ident m_name;
+public:
+ LifetimeParam(Span sp, ::AST::AttributeList attrs, Ident name):
+ m_attrs( ::std::move(attrs) ),
+ m_span( ::std::move(sp) ),
+ m_name( ::std::move(name) )
+ {
+ }
+ LifetimeParam(LifetimeParam&&) = default;
+ LifetimeParam& operator=(LifetimeParam&&) = default;
+ explicit LifetimeParam(const LifetimeParam&) = default;
+
+ const ::AST::AttributeList& attrs() const { return m_attrs; }
+ const Span& span() const { return m_span; }
+ const Ident& name() const { return m_name; }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const LifetimeParam& p);
+};
+
+// HigherRankedBounds is defined in `types.hpp`
-TAGGED_UNION_EX( GenericBound, (), Lifetime,
+TAGGED_UNION_EX( GenericBound, (), None,
(
+ (None, struct{}),
// Lifetime bound: 'test must be valid for 'bound
(Lifetime, struct {
- ::std::string test;
- ::std::string bound;
+ LifetimeRef test;
+ LifetimeRef bound;
}),
// Type lifetime bound
(TypeLifetime, struct {
TypeRef type;
- ::std::string bound;
+ LifetimeRef bound;
}),
// Standard trait bound: "Type: [for<'a>] Trait"
(IsTrait, struct {
+ HigherRankedBounds outer_hrbs;
TypeRef type;
- ::std::vector< ::std::string> hrls; // Higher-ranked lifetimes
+ HigherRankedBounds inner_hrbs;
AST::Path trait;
}),
// Removed trait bound: "Type: ?Trait"
@@ -84,9 +121,10 @@ TAGGED_UNION_EX( GenericBound, (), Lifetime,
GenericBound clone() const {
TU_MATCH(GenericBound, ( (*this) ), (ent),
+ (None, return make_None({}); ),
(Lifetime, return make_Lifetime({ent.test, ent.bound}); ),
(TypeLifetime, return make_TypeLifetime({ent.type.clone(), ent.bound}); ),
- (IsTrait, return make_IsTrait({ent.type.clone(), ent.hrls, ent.trait}); ),
+ (IsTrait, return make_IsTrait({ent.outer_hrbs, ent.type.clone(), ent.inner_hrbs, ent.trait}); ),
(MaybeTrait, return make_MaybeTrait({ent.type.clone(), ent.trait}); ),
(NotTrait, return make_NotTrait({ent.type.clone(), ent.trait}); ),
(Equality, return make_Equality({ent.type.clone(), ent.replacement.clone()}); )
@@ -101,7 +139,7 @@ TAGGED_UNION_EX( GenericBound, (), Lifetime,
class GenericParams
{
::std::vector<TypeParam> m_type_params;
- ::std::vector< ::std::string > m_lifetime_params;
+ ::std::vector<LifetimeParam> m_lifetime_params;
::std::vector<GenericBound> m_bounds;
public:
GenericParams() {}
@@ -112,7 +150,7 @@ public:
GenericParams clone() const {
GenericParams rv;
rv.m_type_params = ::std::vector<TypeParam>( m_type_params ); // Copy-constructable
- rv.m_lifetime_params = m_lifetime_params;
+ rv.m_lifetime_params = ::std::vector<LifetimeParam>(m_lifetime_params);
rv.m_bounds.reserve( m_bounds.size() );
for(auto& e: m_bounds)
rv.m_bounds.push_back( e.clone() );
@@ -121,12 +159,12 @@ public:
const ::std::vector<TypeParam>& ty_params() const { return m_type_params; }
::std::vector<TypeParam>& ty_params() { return m_type_params; }
- const ::std::vector< ::std::string>& lft_params() const { return m_lifetime_params; }
+ const ::std::vector<LifetimeParam>& lft_params() const { return m_lifetime_params; }
const ::std::vector<GenericBound>& bounds() const { return m_bounds; }
::std::vector<GenericBound>& bounds() { return m_bounds; }
void add_ty_param(TypeParam param) { m_type_params.push_back( ::std::move(param) ); }
- void add_lft_param(::std::string name) { m_lifetime_params.push_back( ::std::move(name) ); }
+ void add_lft_param(LifetimeParam lft) { m_lifetime_params.push_back( ::std::move(lft) ); }
void add_bound(GenericBound bound) {
m_bounds.push_back( ::std::move(bound) );
}
diff --git a/src/ast/path.hpp b/src/ast/path.hpp
index 2126e3b2..0470084b 100644
--- a/src/ast/path.hpp
+++ b/src/ast/path.hpp
@@ -28,6 +28,7 @@ class Static;
namespace AST {
+class LifetimeRef;
class GenericParams;
class Crate;
class Module;
@@ -109,14 +110,14 @@ extern ::std::ostream& operator<<(::std::ostream& os, const PathBinding& x);
struct PathParams
{
- ::std::vector< ::std::string > m_lifetimes;
+ ::std::vector< LifetimeRef > m_lifetimes;
::std::vector< TypeRef > m_types;
::std::vector< ::std::pair< ::std::string, TypeRef> > m_assoc;
PathParams(PathParams&& x) = default;
PathParams(const PathParams& x);
PathParams() {}
- PathParams(::std::vector<::std::string> lfts, ::std::vector<TypeRef> tys, ::std::vector<::std::pair<::std::string,TypeRef>> a):
+ PathParams(::std::vector<LifetimeRef> lfts, ::std::vector<TypeRef> tys, ::std::vector<::std::pair<::std::string,TypeRef>> a):
m_lifetimes(mv$(lfts)),
m_types(mv$(tys)),
m_assoc(mv$(a))
diff --git a/src/ast/types.cpp b/src/ast/types.cpp
index af99f3d7..8065a3ba 100644
--- a/src/ast/types.cpp
+++ b/src/ast/types.cpp
@@ -141,6 +141,15 @@ TypeRef TypeRef::clone() const
throw "";
}
+Ordering Type_TraitPath::ord(const Type_TraitPath& x) const
+{
+ Ordering rv;
+
+ rv = ::ord( this->path, x.path );
+ if(rv != OrdEqual) return rv;
+
+ return rv;
+}
Ordering TypeRef::ord(const TypeRef& x) const
{
Ordering rv;
@@ -277,7 +286,8 @@ void TypeRef::print(::std::ostream& os, bool is_debug/*=false*/) const
for( const auto& it : ent.traits ) {
if( &it != &ent.traits.front() )
os << "+";
- it.print_pretty(os, true, is_debug);
+ os << it.hrbs;
+ it.path.print_pretty(os, true, is_debug);
}
os << ")";
)
@@ -286,7 +296,8 @@ void TypeRef::print(::std::ostream& os, bool is_debug/*=false*/) const
for( const auto& it : ent.traits ) {
if( &it != &ent.traits.front() )
os << "+";
- it.print_pretty(os, true, is_debug);
+ os << it.hrbs;
+ it.path.print_pretty(os, true, is_debug);
}
os << "";
)
@@ -303,3 +314,21 @@ void TypeRef::print(::std::ostream& os, bool is_debug/*=false*/) const
return os;
}
+namespace AST {
+ ::std::ostream& operator<<(::std::ostream& os, const LifetimeRef& x) {
+ if( x.m_binding == LifetimeRef::BINDING_STATIC ) {
+ os << "'static";
+ }
+ else if( x.m_binding == LifetimeRef::BINDING_INFER ) {
+ os << "'_";
+ }
+ else {
+ os << "'" << x.m_name;
+ if( x.m_binding != LifetimeRef::BINDING_UNBOUND ) {
+ os << "/*" << x.m_binding << "*/";
+ }
+ }
+ return os;
+ }
+}
+
diff --git a/src/ast/types.hpp b/src/ast/types.hpp
index 820bcf27..49cae373 100644
--- a/src/ast/types.hpp
+++ b/src/ast/types.hpp
@@ -13,6 +13,63 @@
namespace AST {
class ExprNode;
class Expr;
+class LifetimeParam;
+}
+
+namespace AST {
+
+ // Defined here for dependency reasons
+ class HigherRankedBounds
+ {
+ public:
+ ::std::vector<LifetimeParam> m_lifetimes;
+ //::std::vector<TypeParam> m_types;
+ //::std::vector<GenericBound> m_bounds;
+
+ bool empty() const {
+ return m_lifetimes.empty();
+ }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const HigherRankedBounds& x);
+ };
+
+ class LifetimeRef
+ {
+ static const uint16_t BINDING_STATIC = 0xFFFF;
+ static const uint16_t BINDING_UNBOUND = 0xFFFE;
+ static const uint16_t BINDING_INFER = 0xFFFD;
+
+ Ident m_name;
+ uint16_t m_binding;
+
+ LifetimeRef(Ident name, uint32_t binding):
+ m_name( ::std::move(name) ),
+ m_binding( binding )
+ {
+ }
+ public:
+ LifetimeRef():
+ LifetimeRef("", BINDING_INFER)
+ {
+ }
+ LifetimeRef(Ident name):
+ LifetimeRef(::std::move(name), BINDING_UNBOUND)
+ {
+ }
+ static LifetimeRef new_static() {
+ return LifetimeRef("static", BINDING_STATIC);
+ }
+
+ void set_binding(uint16_t b) { assert(m_binding == BINDING_UNBOUND); m_binding = b; }
+
+ const Ident& name() const { return m_name; }
+ Ordering ord(const LifetimeRef& x) const { return ::ord(m_name.name, x.m_name.name); }
+ bool operator==(const LifetimeRef& x) const { return ord(x) == OrdEqual; }
+ bool operator!=(const LifetimeRef& x) const { return ord(x) != OrdEqual; }
+ bool operator<(const LifetimeRef& x) const { return ord(x) == OrdLess; };
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const LifetimeRef& x);
+ };
}
class PrettyPrintType
@@ -57,6 +114,14 @@ struct Type_Function
Ordering ord(const Type_Function& x) const;
};
+struct Type_TraitPath
+{
+ AST::HigherRankedBounds hrbs;
+ AST::Path path;
+
+ Ordering ord(const Type_TraitPath& x) const;
+};
+
TAGGED_UNION(TypeData, None,
(None, struct { }),
(Any, struct { }),
@@ -94,12 +159,12 @@ TAGGED_UNION(TypeData, None,
AST::Path path;
}),
(TraitObject, struct {
- ::std::vector<::std::string> hrls;
- ::std::vector<AST::Path> traits;
+ ::std::vector<Type_TraitPath> traits;
+ ::std::vector<AST::LifetimeRef> lifetimes;
}),
(ErasedType, struct {
- ::std::vector<::std::string> hrls;
- ::std::vector<AST::Path> traits;
+ ::std::vector<Type_TraitPath> traits;
+ ::std::vector<AST::LifetimeRef> lifetimes;
})
);
@@ -215,9 +280,9 @@ public:
TypeRef(TagPath(), mv$(sp), mv$(path))
{}
- TypeRef( Span sp, ::std::vector<::std::string> hrls, ::std::vector<AST::Path> traits ):
+ TypeRef( Span sp, ::std::vector<Type_TraitPath> traits, ::std::vector<AST::LifetimeRef> lifetimes ):
m_span(mv$(sp)),
- m_data(TypeData::make_TraitObject({ mv$(hrls), ::std::move(traits) }))
+ m_data(TypeData::make_TraitObject({ ::std::move(traits), mv$(lifetimes) }))
{}
diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp
index 077c4b70..0e28b6da 100644
--- a/src/expand/derive.cpp
+++ b/src/expand/derive.cpp
@@ -86,7 +86,7 @@ struct Deriver
for(const auto& arg : params.ty_params())
{
params.add_bound( ::AST::GenericBound::make_IsTrait({
- TypeRef(sp, arg.name(), i), {}, trait_path
+ {}, TypeRef(sp, arg.name(), i), {}, trait_path
}) );
i ++;
}
@@ -96,7 +96,7 @@ struct Deriver
for(auto& ty : additional_bounded_types)
{
params.add_bound( ::AST::GenericBound::make_IsTrait({
- mv$(ty), {}, trait_path
+ {}, mv$(ty), {}, trait_path
}) );
}
@@ -1563,11 +1563,10 @@ class Deriver_Hash:
::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "state"), TypeRef(TypeRef::TagReference(), sp, true, TypeRef(sp, "H", 0x100|0)) )
)
);
- fcn.params().add_ty_param( AST::TypeParam("H") );
+ fcn.params().add_ty_param( AST::TypeParam(sp, {}, "H") );
fcn.params().add_bound( AST::GenericBound::make_IsTrait({
- TypeRef(sp, "H", 0x100|0),
- {},
- this->get_trait_path_Hasher(core_name)
+ {}, TypeRef(sp, "H", 0x100|0),
+ {}, this->get_trait_path_Hasher(core_name)
}) );
fcn.set_code( NEWNODE(Block, vec$(mv$(node))) );
@@ -1717,11 +1716,10 @@ class Deriver_RustcEncodable:
::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "s"), TypeRef(TypeRef::TagReference(), sp, true, TypeRef(sp, "S", 0x100|0)) )
)
);
- fcn.params().add_ty_param( AST::TypeParam("S") );
+ fcn.params().add_ty_param( AST::TypeParam(sp, {}, "S") );
fcn.params().add_bound( AST::GenericBound::make_IsTrait({
- TypeRef(sp, "S", 0x100|0),
- {},
- this->get_trait_path_Encoder()
+ {}, TypeRef(sp, "S", 0x100|0),
+ {}, this->get_trait_path_Encoder()
}) );
fcn.set_code( NEWNODE(Block, vec$(mv$(node))) );
@@ -1951,11 +1949,10 @@ class Deriver_RustcDecodable:
::std::make_pair( AST::Pattern(AST::Pattern::TagBind(), "d"), TypeRef(TypeRef::TagReference(), sp, true, TypeRef(sp, "D", 0x100|0)) )
)
);
- fcn.params().add_ty_param( AST::TypeParam("D") );
+ fcn.params().add_ty_param( AST::TypeParam(sp, {}, "D") );
fcn.params().add_bound( AST::GenericBound::make_IsTrait({
- TypeRef(sp, "D", 0x100|0),
- {},
- this->get_trait_path_Decoder()
+ {}, TypeRef(sp, "D", 0x100|0),
+ {}, this->get_trait_path_Decoder()
}) );
fcn.set_code( NEWNODE(Block, vec$(mv$(node))) );
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index aa7655e3..4470b2bb 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -272,13 +272,15 @@ void Expand_Type(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST:
(TraitObject,
for(auto& p : e.traits)
{
- Expand_Path(crate, modstack, mod, p);
+ // TODO: p.hrbs? Not needed until types are in those
+ Expand_Path(crate, modstack, mod, p.path);
}
),
(ErasedType,
for(auto& p : e.traits)
{
- Expand_Path(crate, modstack, mod, p);
+ // TODO: p.hrbs?
+ Expand_Path(crate, modstack, mod, p.path);
}
)
)
@@ -859,6 +861,8 @@ void Expand_GenericParams(::AST::Crate& crate, LList<const AST::Module*> modstac
for(auto& bound : params.bounds())
{
TU_MATCHA( (bound), (be),
+ (None,
+ ),
(Lifetime,
),
(TypeLifetime,
diff --git a/src/expand/proc_macro.cpp b/src/expand/proc_macro.cpp
index cdd13a42..28d9f613 100644
--- a/src/expand/proc_macro.cpp
+++ b/src/expand/proc_macro.cpp
@@ -345,45 +345,41 @@ namespace {
),
(TraitObject,
m_pmi.send_symbol("(");
- if( te.hrls.size() > 0 )
- {
- m_pmi.send_ident("for");
- m_pmi.send_symbol("<");
- for(const auto& v : te.hrls)
- {
- m_pmi.send_lifetime(v.c_str());
- m_pmi.send_symbol(",");
- }
- m_pmi.send_symbol(">");
- }
for(const auto& t : te.traits)
{
- this->visit_path(t);
+ this->visit_hrbs(t.hrbs);
+ this->visit_path(t.path);
m_pmi.send_symbol("+");
}
+ // TODO: Lifetimes
m_pmi.send_symbol(")");
),
(ErasedType,
m_pmi.send_ident("impl");
- if( te.hrls.size() > 0 )
- {
- m_pmi.send_ident("for");
- m_pmi.send_symbol("<");
- for(const auto& v : te.hrls)
- {
- m_pmi.send_lifetime(v.c_str());
- m_pmi.send_symbol(",");
- }
- m_pmi.send_symbol(">");
- }
for(const auto& t : te.traits)
{
- this->visit_path(t);
+ this->visit_hrbs(t.hrbs);
+ this->visit_path(t.path);
m_pmi.send_symbol("+");
}
+ // TODO: Lifetimes
)
)
}
+ void visit_hrbs(const AST::HigherRankedBounds& hrbs)
+ {
+ if( !hrbs.empty() )
+ {
+ m_pmi.send_ident("for");
+ m_pmi.send_symbol("<");
+ for(const auto& v : hrbs.m_lifetimes)
+ {
+ m_pmi.send_lifetime(v.name().name.c_str());
+ m_pmi.send_symbol(",");
+ }
+ m_pmi.send_symbol(">");
+ }
+ }
void visit_path(const AST::Path& path, bool is_expr=false)
{
@@ -445,7 +441,7 @@ namespace {
m_pmi.send_symbol("<");
for(const auto& l : e.args().m_lifetimes)
{
- m_pmi.send_lifetime(l.c_str());
+ m_pmi.send_lifetime(l.name().name.c_str());
m_pmi.send_symbol(",");
}
for(const auto& t : e.args().m_types)
@@ -475,7 +471,7 @@ namespace {
{
if( !is_first )
m_pmi.send_symbol(",");
- m_pmi.send_lifetime(p.c_str());
+ m_pmi.send_lifetime(p.name().name.c_str());
is_first = false;
}
// Types
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 1dbfdad2..6353a0ea 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -28,6 +28,11 @@
::HIR::Crate* g_crate_ptr = nullptr;
// --------------------------------------------------------------------
+::std::string LowerHIR_LifetimeRef(const ::AST::LifetimeRef& r)
+{
+ return r.name().name;
+}
+
::HIR::GenericParams LowerHIR_GenericParams(const ::AST::GenericParams& gp, bool* self_is_sized)
{
::HIR::GenericParams rv;
@@ -41,24 +46,26 @@
}
if( gp.lft_params().size() > 0 )
{
- for(const auto& lft_name : gp.lft_params())
- rv.m_lifetimes.push_back( lft_name );
+ for(const auto& lft_def : gp.lft_params())
+ rv.m_lifetimes.push_back( lft_def.name().name );
}
if( gp.bounds().size() > 0 )
{
for(const auto& bound : gp.bounds())
{
TU_MATCH(::AST::GenericBound, (bound), (e),
+ (None,
+ ),
(Lifetime,
rv.m_bounds.push_back(::HIR::GenericBound::make_Lifetime({
- e.test,
- e.bound
+ LowerHIR_LifetimeRef(e.test),
+ LowerHIR_LifetimeRef(e.bound)
}));
),
(TypeLifetime,
rv.m_bounds.push_back(::HIR::GenericBound::make_TypeLifetime({
LowerHIR_Type(e.type),
- e.bound
+ LowerHIR_LifetimeRef(e.bound)
}));
),
(IsTrait,
@@ -66,8 +73,8 @@
// TODO: Check if this trait is `Sized` and ignore if it is
- rv.m_bounds.push_back(::HIR::GenericBound::make_TraitBound({ mv$(type), LowerHIR_TraitPath(bound.span, e.trait) }));
- rv.m_bounds.back().as_TraitBound().trait.m_hrls = e.hrls;
+ rv.m_bounds.push_back(::HIR::GenericBound::make_TraitBound({ /*LowerHIR_HigherRankedBounds(e.outer_hrbs),*/ mv$(type), LowerHIR_TraitPath(bound.span, e.trait) }));
+ //rv.m_bounds.back().as_TraitBound().trait.m_hrls = LowerHIR_HigherRankedBounds(e.inner_hrbs);
),
(MaybeTrait,
auto type = LowerHIR_Type(e.type);
@@ -755,47 +762,59 @@
}
),
(TraitObject,
- //if( e.hrls.size() > 0 )
- // TODO(ty.span(), "TraitObjects with HRLS - " << ty);
::HIR::TypeRef::Data::Data_TraitObject v;
// TODO: Lifetime
for(const auto& t : e.traits)
{
- DEBUG("t = " << t);
- const auto& tb = t.binding().as_Trait();
+ DEBUG("t = " << t.path);
+ const auto& tb = t.path.binding().as_Trait();
assert( tb.trait_ || tb.hir );
- if( (tb.trait_ ? tb.trait_->is_marker() : tb.hir->m_is_marker) ) {
+ if( (tb.trait_ ? tb.trait_->is_marker() : tb.hir->m_is_marker) )
+ {
if( tb.hir ) {
DEBUG(tb.hir->m_values.size());
}
- v.m_markers.push_back( LowerHIR_GenericPath(ty.span(), t) );
+ // TODO: If this has HRBs, what?
+ v.m_markers.push_back( LowerHIR_GenericPath(ty.span(), t.path) );
}
else {
// TraitPath -> GenericPath -> SimplePath
if( v.m_trait.m_path.m_path.m_components.size() > 0 ) {
ERROR(ty.span(), E0000, "Multiple data traits in trait object - " << ty);
}
- v.m_trait = LowerHIR_TraitPath(ty.span(), t);
+ // TODO: Handle HRBs
+ v.m_trait = LowerHIR_TraitPath(ty.span(), t.path);
}
}
return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_TraitObject( mv$(v) ) );
),
(ErasedType,
- //if( e.hrls.size() > 0 )
- // TODO(ty.span(), "ErasedType with HRLS - " << ty);
ASSERT_BUG(ty.span(), e.traits.size() > 0, "ErasedType with no traits");
::std::vector< ::HIR::TraitPath> traits;
for(const auto& t : e.traits)
{
- DEBUG("t = " << t);
- traits.push_back( LowerHIR_TraitPath(ty.span(), t) );
+ DEBUG("t = " << t.path);
+ // TODO: Pass the HRBs down
+ traits.push_back( LowerHIR_TraitPath(ty.span(), t.path) );
+ }
+ ::HIR::LifetimeRef lft;
+ if( e.lifetimes.size() == 0 )
+ {
+ }
+ else if( e.lifetimes.size() == 1 )
+ {
+ // TODO: Convert the lifetime reference
+ }
+ else
+ {
+ TODO(ty.span(), "Handle multiple lifetime parameters - " << ty);
}
// Leave `m_origin` until the bind pass
return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_ErasedType(::HIR::TypeRef::Data::Data_ErasedType {
::HIR::Path(::HIR::SimplePath()), 0,
mv$(traits),
- ::HIR::LifetimeRef() // TODO: Lifetime ref
+ lft
} ) );
),
(Function,
diff --git a/src/parse/common.hpp b/src/parse/common.hpp
index 1ca86128..49499c86 100644
--- a/src/parse/common.hpp
+++ b/src/parse/common.hpp
@@ -40,7 +40,7 @@ extern ::std::vector<AST::PathNode> Parse_PathNodes(TokenStream& lex, eParsePath
extern AST::PathParams Parse_Path_GenericList(TokenStream& lex);
-extern ::std::vector< ::std::string> Parse_HRB(TokenStream& lex);
+extern AST::HigherRankedBounds Parse_HRB(TokenStream& lex);
extern AST::AttributeList Parse_ItemAttrs(TokenStream& lex);
extern void Parse_ParentAttrs(TokenStream& lex, AST::AttributeList& out);
extern AST::Attribute Parse_MetaItem(TokenStream& lex);
diff --git a/src/parse/paths.cpp b/src/parse/paths.cpp
index 59b6b939..d103840e 100644
--- a/src/parse/paths.cpp
+++ b/src/parse/paths.cpp
@@ -203,7 +203,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi
Token tok;
::std::vector<TypeRef> types;
- ::std::vector< ::std::string> lifetimes;
+ ::std::vector<AST::LifetimeRef> lifetimes;
::std::vector< ::std::pair< ::std::string, TypeRef > > assoc_bounds;
do {
@@ -214,7 +214,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi
switch(GET_TOK(tok, lex))
{
case TOK_LIFETIME:
- lifetimes.push_back( tok.str() );
+ lifetimes.push_back(AST::LifetimeRef(/*lex.point_span(),*/ lex.get_ident(mv$(tok)) ));
break;
case TOK_IDENT:
if( LOOK_AHEAD(lex) == TOK_EQUAL )
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 35da3a76..2b027bf9 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -119,12 +119,12 @@ bool Parse_Publicity(TokenStream& lex, bool allow_restricted=true)
}
}
-::std::vector< ::std::string> Parse_HRB(TokenStream& lex)
+::AST::HigherRankedBounds Parse_HRB(TokenStream& lex)
{
TRACE_FUNCTION;
Token tok;
- ::std::vector< ::std::string> lifetimes;
+ ::AST::HigherRankedBounds rv;
GET_CHECK_TOK(tok, lex, TOK_LT);
do {
auto attrs = Parse_ItemAttrs(lex);
@@ -133,17 +133,25 @@ bool Parse_Publicity(TokenStream& lex, bool allow_restricted=true)
switch(GET_TOK(tok, lex))
{
case TOK_LIFETIME:
- lifetimes.push_back(tok.str());
+ rv.m_lifetimes.push_back(::AST::LifetimeParam(lex.point_span(), ::std::move(attrs), Ident(lex.getHygiene(), tok.str())));
break;
default:
throw ParseError::Unexpected(lex, tok, Token(TOK_LIFETIME));
}
} while( GET_TOK(tok, lex) == TOK_COMMA );
CHECK_TOK(tok, TOK_GT);
- return lifetimes;
+ return rv;
+}
+
+namespace {
+ AST::LifetimeRef get_LifetimeRef(TokenStream& lex, Token tok)
+ {
+ CHECK_TOK(tok, TOK_LIFETIME);
+ return AST::LifetimeRef(/*lex.point_span(), */Ident(lex.getHygiene(), mv$(tok.str())));
+ }
}
/// Parse type parameters in a definition
-void Parse_TypeBound(TokenStream& lex, AST::GenericParams& ret, TypeRef checked_type, ::std::vector< ::std::string> lifetimes = {})
+void Parse_TypeBound(TokenStream& lex, AST::GenericParams& ret, TypeRef checked_type, AST::HigherRankedBounds outer_hrbs = {})
{
TRACE_FUNCTION;
Token tok;
@@ -156,10 +164,9 @@ void Parse_TypeBound(TokenStream& lex, AST::GenericParams& ret, TypeRef checked_
// return;
//}
- ::std::vector< ::std::string> hrls;
if(GET_TOK(tok, lex) == TOK_LIFETIME) {
ret.add_bound(AST::GenericBound::make_TypeLifetime( {
- checked_type.clone(), tok.str()
+ checked_type.clone(), get_LifetimeRef(lex, mv$(tok))
} ));
}
else if( tok.type() == TOK_QMARK ) {
@@ -168,17 +175,17 @@ void Parse_TypeBound(TokenStream& lex, AST::GenericParams& ret, TypeRef checked_
} ));
}
else {
+ ::AST::HigherRankedBounds inner_hrls;
if( tok.type() == TOK_RWORD_FOR )
{
- hrls = Parse_HRB(lex);
+ inner_hrls = Parse_HRB(lex);
}
else {
PUTBACK(tok, lex);
}
- (void)hrls; // TODO: HRLs
ret.add_bound( AST::GenericBound::make_IsTrait({
- checked_type.clone(), mv$(lifetimes), Parse_Path(lex, PATH_GENERIC_TYPE)
+ mv$(outer_hrbs), checked_type.clone(), mv$(inner_hrls), Parse_Path(lex, PATH_GENERIC_TYPE)
}) );
}
} while( GET_TOK(tok, lex) == TOK_PLUS );
@@ -199,14 +206,12 @@ AST::GenericParams Parse_GenericParams(TokenStream& lex)
PUTBACK(tok, lex);
auto attrs = Parse_ItemAttrs(lex);
- (void)attrs; // TODO: Attributes on generic params
GET_TOK(tok, lex);
if( tok.type() == TOK_IDENT )
{
- // TODO: Hygine
::std::string param_name = mv$(tok.str());
- ret.add_ty_param( AST::TypeParam( param_name ) );
+ ret.add_ty_param( AST::TypeParam( lex.point_span(), ::std::move(attrs), param_name ) );
auto param_ty = TypeRef(lex.point_span(), param_name);
if( GET_TOK(tok, lex) == TOK_COLON )
@@ -223,14 +228,14 @@ AST::GenericParams Parse_GenericParams(TokenStream& lex)
}
else if( tok.type() == TOK_LIFETIME )
{
- // TODO: Should lifetimes have hygine?
- ::std::string param_name = tok.str();
- ret.add_lft_param( param_name );
+ auto param_name = tok.str();
+ auto ref = get_LifetimeRef(lex, mv$(tok));
+ ret.add_lft_param(::AST::LifetimeParam(lex.point_span(), ::std::move(attrs), Ident(lex.getHygiene(), param_name) ));
if( GET_TOK(tok, lex) == TOK_COLON )
{
do {
GET_CHECK_TOK(tok, lex, TOK_LIFETIME);
- ret.add_bound(AST::GenericBound::make_Lifetime( {param_name, tok.str()} ));
+ ret.add_bound(AST::GenericBound::make_Lifetime({ AST::LifetimeRef(ref), get_LifetimeRef(lex, mv$(tok)) }));
} while( GET_TOK(tok, lex) == TOK_PLUS );
}
}
@@ -258,11 +263,11 @@ void Parse_WhereClause(TokenStream& lex, AST::GenericParams& params)
if( tok.type() == TOK_LIFETIME )
{
- auto lhs = mv$(tok.str());
+ auto lhs = get_LifetimeRef(lex, mv$(tok));
GET_CHECK_TOK(tok, lex, TOK_COLON);
do {
GET_CHECK_TOK(tok, lex, TOK_LIFETIME);
- auto rhs = mv$(tok.str());
+ auto rhs = get_LifetimeRef(lex, mv$(tok));
params.add_bound( AST::GenericBound::make_Lifetime({lhs, rhs}) );
} while( GET_TOK(tok, lex) == TOK_PLUS );
PUTBACK(tok, lex);
@@ -270,11 +275,11 @@ void Parse_WhereClause(TokenStream& lex, AST::GenericParams& params)
// Higher-ranked types/lifetimes
else if( tok.type() == TOK_RWORD_FOR )
{
- ::std::vector< ::std::string> lifetimes = Parse_HRB(lex);
+ auto hrbs = Parse_HRB(lex);
TypeRef type = Parse_Type(lex);
GET_CHECK_TOK(tok, lex, TOK_COLON);
- Parse_TypeBound(lex,params, mv$(type), mv$(lifetimes));
+ Parse_TypeBound(lex,params, mv$(type), mv$(hrbs));
}
else
{
@@ -355,9 +360,9 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, bool allow_
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;
+ AST::LifetimeRef lifetime;
if( GET_TOK(tok, lex) == TOK_LIFETIME ) {
- lifetime = tok.str();
+ lifetime = get_LifetimeRef(lex, mv$(tok));
GET_TOK(tok, lex);
}
auto ty_sp = lex.end_span(ps);
@@ -622,6 +627,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::AttributeList& meta_items
do {
if( GET_TOK(tok, lex) == TOK_LIFETIME ) {
// TODO: Need a better way of indiciating 'static than just an invalid path
+ // TODO: Ensure that it's 'static
supertraits.push_back( make_spanned( Span(tok.get_pos()), AST::Path() ) );
}
else if( tok.type() == TOK_BRACE_OPEN ) {
diff --git a/src/parse/tokenstream.cpp b/src/parse/tokenstream.cpp
index 625f12db..611df2ff 100644
--- a/src/parse/tokenstream.cpp
+++ b/src/parse/tokenstream.cpp
@@ -140,6 +140,10 @@ Ident TokenStream::get_ident(Token tok) const
if(tok.type() == TOK_IDENT) {
return Ident(getHygiene(), tok.str());
}
+ else if(tok.type() == TOK_LIFETIME) {
+ // TODO: Maybe only when it's explicitly asked for?
+ return Ident(getHygiene(), tok.str());
+ }
else if( tok.type() == TOK_INTERPOLATED_IDENT ) {
TODO(getPosition(), "get_ident from TOK_INTERPOLATED_IDENT");
}
diff --git a/src/parse/types.cpp b/src/parse/types.cpp
index 26785cf7..b0b43426 100644
--- a/src/parse/types.cpp
+++ b/src/parse/types.cpp
@@ -13,8 +13,8 @@
// === PROTOTYPES ===
//TypeRef Parse_Type(TokenStream& lex, bool allow_trait_list);
TypeRef Parse_Type_Int(TokenStream& lex, bool allow_trait_list);
-TypeRef Parse_Type_Fn(TokenStream& lex, ::std::vector<::std::string> hrls = {});
-TypeRef Parse_Type_Path(TokenStream& lex, ::std::vector<::std::string> hrls, bool allow_trait_list);
+TypeRef Parse_Type_Fn(TokenStream& lex, AST::HigherRankedBounds hrbs = {});
+TypeRef Parse_Type_Path(TokenStream& lex, AST::HigherRankedBounds hrbs, bool allow_trait_list);
TypeRef Parse_Type_ErasedType(TokenStream& lex, bool allow_trait_list);
// === CODE ===
@@ -196,7 +196,7 @@ TypeRef Parse_Type_Int(TokenStream& lex, bool allow_trait_list)
throw ParseError::BugCheck("Reached end of Parse_Type");
}
-TypeRef Parse_Type_Fn(TokenStream& lex, ::std::vector<::std::string> hrls)
+TypeRef Parse_Type_Fn(TokenStream& lex, ::AST::HigherRankedBounds hrbs)
{
auto ps = lex.start_span();
// TODO: HRLs
@@ -262,36 +262,52 @@ TypeRef Parse_Type_Fn(TokenStream& lex, ::std::vector<::std::string> hrls)
return TypeRef(TypeRef::TagFunction(), lex.end_span(ps), is_unsafe, mv$(abi), mv$(args), is_variadic, mv$(ret_type));
}
-TypeRef Parse_Type_Path(TokenStream& lex, ::std::vector<::std::string> hrls, bool allow_trait_list)
+TypeRef Parse_Type_Path(TokenStream& lex, ::AST::HigherRankedBounds hrbs, bool allow_trait_list)
{
Token tok;
auto ps = lex.start_span();
- if( ! allow_trait_list )
+ if( hrbs.empty() && !allow_trait_list )
{
return TypeRef(TypeRef::TagPath(), lex.end_span(ps), Parse_Path(lex, PATH_GENERIC_TYPE));
}
else
{
- ::std::vector<AST::Path> traits;
- ::std::vector< ::std::string> lifetimes;
- do {
- if( LOOK_AHEAD(lex) == TOK_LIFETIME ) {
- GET_TOK(tok, lex);
- lifetimes.push_back( tok.str() );
+ ::std::vector<Type_TraitPath> traits;
+ ::std::vector<AST::LifetimeRef> lifetimes;
+
+ traits.push_back(Type_TraitPath { mv$(hrbs), Parse_Path(lex, PATH_GENERIC_TYPE) });
+
+ if( allow_trait_list )
+ {
+ while( GET_TOK(tok, lex) == TOK_PLUS )
+ {
+ if( LOOK_AHEAD(lex) == TOK_LIFETIME ) {
+ GET_TOK(tok, lex);
+ lifetimes.push_back(AST::LifetimeRef( /*lex.point_span(),*/ lex.get_ident(mv$(tok)) ));
+ }
+ else
+ {
+ if( lex.lookahead(0) == TOK_RWORD_FOR )
+ {
+ hrbs = Parse_HRB(lex);
+ }
+ traits.push_back({ mv$(hrbs), Parse_Path(lex, PATH_GENERIC_TYPE) });
+ }
}
- else
- traits.push_back( Parse_Path(lex, PATH_GENERIC_TYPE) );
- } while( GET_TOK(tok, lex) == TOK_PLUS );
- PUTBACK(tok, lex);
- if( hrls.size() > 0 || traits.size() > 1 || lifetimes.size() > 0 ) {
- if( lifetimes.size() )
- DEBUG("TODO: Lifetime bounds on trait objects");
- return TypeRef(lex.end_span(ps), mv$(hrls), ::std::move(traits));
+ PUTBACK(tok, lex);
}
- else {
- return TypeRef(TypeRef::TagPath(), lex.end_span(ps), mv$(traits.at(0)));
+
+ if( !traits[0].hrbs.empty() || traits.size() > 1 || lifetimes.size() > 0 )
+ {
+ if( lifetimes.empty())
+ lifetimes.push_back(AST::LifetimeRef());
+ return TypeRef(lex.end_span(ps), mv$(traits), mv$(lifetimes));
+ }
+ else
+ {
+ return TypeRef(TypeRef::TagPath(), lex.end_span(ps), mv$(traits.at(0).path));
}
}
}
@@ -300,20 +316,25 @@ TypeRef Parse_Type_ErasedType(TokenStream& lex, bool allow_trait_list)
Token tok;
auto ps = lex.start_span();
- ::std::vector<AST::Path> traits;
- ::std::vector< ::std::string> lifetimes;
+ ::std::vector<Type_TraitPath> traits;
+ ::std::vector<AST::LifetimeRef> lifetimes;
do {
if( LOOK_AHEAD(lex) == TOK_LIFETIME ) {
GET_TOK(tok, lex);
- lifetimes.push_back( tok.str() );
+ lifetimes.push_back(AST::LifetimeRef( /*lex.point_span(),*/ lex.get_ident(mv$(tok)) ));
}
else
- traits.push_back( Parse_Path(lex, PATH_GENERIC_TYPE) );
+ {
+ AST::HigherRankedBounds hrbs;
+ if( lex.lookahead(0) == TOK_RWORD_FOR )
+ {
+ hrbs = Parse_HRB(lex);
+ }
+ traits.push_back({ mv$(hrbs), Parse_Path(lex, PATH_GENERIC_TYPE) });
+ }
} while( GET_TOK(tok, lex) == TOK_PLUS );
PUTBACK(tok, lex);
- if( lifetimes.size() )
- DEBUG("TODO: Lifetime bounds on erased types");
- return TypeRef(lex.end_span(ps), TypeData::make_ErasedType({ {}, mv$(traits) }));
+ return TypeRef(lex.end_span(ps), TypeData::make_ErasedType({ mv$(traits), mv$(lifetimes) }));
}
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp
index 2c17592c..d05e3bc6 100644
--- a/src/resolve/absolute.cpp
+++ b/src/resolve/absolute.cpp
@@ -1500,24 +1500,24 @@ void Resolve_Absolute_Type(Context& context, TypeRef& type)
)
TU_IFLET(::AST::PathBinding, e.path.binding(), Trait, be,
- auto ty = ::TypeRef( type.span(), {}, ::make_vec1(mv$(e.path)) );
+ auto ty = ::TypeRef( type.span(), ::make_vec1(Type_TraitPath { {}, mv$(e.path)}), {} );
type = mv$(ty);
return ;
)
),
(TraitObject,
- //context.push_lifetimes( e.hrls );
for(auto& trait : e.traits) {
- Resolve_Absolute_Path(context, type.span(), Context::LookupMode::Type, trait);
+ //context.push_lifetimes( trait.hrbs.m_lifetimes );
+ Resolve_Absolute_Path(context, type.span(), Context::LookupMode::Type, trait.path);
+ //context.pop_lifetimes();
}
- //context.pop_lifetimes();
),
(ErasedType,
- //context.push_lifetimes( e.hrls );
for(auto& trait : e.traits) {
- Resolve_Absolute_Path(context, type.span(), Context::LookupMode::Type, trait);
+ //context.push_lifetimes( trait.hrbs.m_lifetimes );
+ Resolve_Absolute_Path(context, type.span(), Context::LookupMode::Type, trait.path);
+ //context.pop_lifetimes();
}
- //context.pop_lifetimes();
)
)
}
@@ -1683,6 +1683,8 @@ void Resolve_Absolute_Generic(Context& context, ::AST::GenericParams& params)
for( auto& bound : params.bounds() )
{
TU_MATCH(::AST::GenericBound, (bound), (e),
+ (None,
+ ),
(Lifetime,
// TODO: Link lifetime names to params
),