diff options
Diffstat (limited to 'src/ast')
-rw-r--r-- | src/ast/ast.cpp | 106 | ||||
-rw-r--r-- | src/ast/ast.hpp | 89 |
2 files changed, 129 insertions, 66 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index f7ebaa2b..fb289a20 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -295,13 +295,18 @@ bool Crate::find_impl(const Path& trait, const TypeRef& type, Impl** out_impl, : for( const auto& bound : type.type_params_ptr()->bounds() )
{
DEBUG("bound = " << bound);
- if( bound.is_trait() && bound.test() == type && bound.bound() == trait ) {
- // If found, success!
- DEBUG("- Success!");
- // TODO: What should be returned, kinda need to return a boolean
- if(out_impl) throw CompileError::BugCheck("find_impl - Asking for a concrete impl, but generic passed");
- return true;
- }
+ TU_MATCH_DEF(GenericBound, (bound), (ent),
+ (),
+ (IsTrait,
+ if(ent.type == type && ent.trait == trait) {
+ // If found, success!
+ DEBUG("- Success!");
+ // TODO: What should be returned, kinda need to return a boolean
+ if(out_impl) throw CompileError::BugCheck("find_impl - Asking for a concrete impl, but generic passed");
+ return true;
+ }
+ )
+ )
}
// Else, failure
DEBUG("- No impl :(");
@@ -855,18 +860,75 @@ SERIALISE_TYPE(TypeParam::, "AST_TypeParam", { ::std::ostream& operator<<(::std::ostream& os, const GenericBound& x)
{
- os << x.m_type << ": ";
- if( x.m_lifetime_bound != "" )
- return os << "'" << x.m_lifetime_bound;
- else
- return os << x.m_trait;
+ TU_MATCH(GenericBound, (x), (ent),
+ (Lifetime,
+ os << "'" << ent.test << ": '" << ent.bound;
+ ),
+ (TypeLifetime,
+ 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;
+ ),
+ (MaybeTrait,
+ os << ent.type << ": ?" << ent.trait;
+ ),
+ (NotTrait,
+ os << ent.type << ": !" << ent.trait;
+ ),
+ (Equality,
+ os << ent.type << " = " << ent.replacement;
+ )
+ )
+ return os;
}
-SERIALISE_TYPE_S(GenericBound, {
- s.item(m_lifetime_test);
- s.item(m_type);
- s.item(m_lifetime_bound);
- s.item(m_trait);
-})
+
+
+#define SERIALISE_TU_ARM(CLASS, NAME, TAG, ...) case CLASS::TAG: { *this = CLASS::make_null_##TAG(); auto& NAME = this->as_##TAG(); (void)&NAME; __VA_ARGS__ } break;
+#define SERIALISE_TU_ARMS(CLASS, NAME, ...) TU_GMA(__VA_ARGS__)(SERIALISE_TU_ARM, (CLASS, NAME), __VA_ARGS__)
+#define SERIALISE_TU(PATH, TAG, NAME, ...) \
+ void operator%(::Serialiser& s, PATH::Tag c) { s << PATH::tag_to_str(c); } \
+ void operator%(::Deserialiser& s, PATH::Tag& c) { ::std::string n; s.item(n); c = PATH::tag_from_str(n); }\
+ SERIALISE_TYPE(PATH::, TAG, {\
+ s % this->tag(); TU_MATCH(PATH, ((*this)), (NAME), __VA_ARGS__)\
+ }, {\
+ PATH::Tag tag; s % tag; switch(tag) { SERIALISE_TU_ARMS(PATH, NAME, __VA_ARGS__) } \
+ })
+
+SERIALISE_TU(GenericBound, "GenericBound", ent,
+ (Lifetime,
+ s.item(ent.test);
+ s.item(ent.bound);
+ ),
+ (TypeLifetime,
+ s.item(ent.type);
+ s.item(ent.bound);
+ ),
+ (IsTrait,
+ s.item(ent.type);
+ s.item(ent.hrls);
+ s.item(ent.trait);
+ ),
+ (MaybeTrait,
+ s.item(ent.type);
+ s.item(ent.trait);
+ ),
+ (NotTrait,
+ s.item(ent.type);
+ s.item(ent.trait);
+ ),
+ (Equality,
+ s.item(ent.type);
+ s.item(ent.replacement);
+ )
+)
int TypeParams::find_name(const char* name) const
{
@@ -918,9 +980,9 @@ bool TypeParams::check_params(Crate& crate, ::std::vector<TypeRef>& types, bool {
for( const auto& bound : m_bounds )
{
- if( bound.is_trait() && bound.test() == test )
+ if( bound.is_IsTrait() && bound.as_IsTrait().type == test )
{
- const auto& trait = bound.bound();
+ const auto& trait = bound.as_IsTrait().trait;
//const auto& ty_traits = type.traits();
//auto it = ::std::find(ty_traits.begin(), ty_traits.end(), trait);
@@ -937,9 +999,9 @@ bool TypeParams::check_params(Crate& crate, ::std::vector<TypeRef>& types, bool // Check that the type fits the bounds applied to it
for( const auto& bound : m_bounds )
{
- if( bound.is_trait() && bound.test() == test )
+ if( bound.is_IsTrait() && bound.as_IsTrait().type == test )
{
- const auto& trait = bound.bound();
+ const auto& trait = bound.as_IsTrait().trait;
// Check if 'type' impls 'trait'
if( !crate.find_impl(trait, trait) )
{
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index c04a8927..301c94bb 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -54,13 +54,18 @@ public: SERIALISABLE_PROTOTYPES();
};
-#if 0
-TAGGED_UNION( GenericBound, Lifetime,
+TAGGED_UNION_EX( GenericBound, (: public Serialisable), Lifetime,
+ (
// Lifetime bound: 'test must be valid for 'bound
(Lifetime, (
::std::string test;
::std::string bound;
)),
+ // Type lifetime bound
+ (TypeLifetime, (
+ TypeRef type;
+ ::std::string bound;
+ )),
// Standard trait bound: "Type: [for<'a>] Trait"
(IsTrait, (
TypeRef type;
@@ -82,50 +87,26 @@ TAGGED_UNION( GenericBound, Lifetime, TypeRef type;
TypeRef replacement;
))
+ ),
+ (
+ public:
+ SERIALISABLE_PROTOTYPES();
+
+ GenericBound clone() const {
+ TU_MATCH(GenericBound, ( (*this) ), (ent),
+ (Lifetime, return make_Lifetime({ent.test, ent.bound}); ),
+ (TypeLifetime, return make_TypeLifetime({ent.type, ent.bound}); ),
+ (IsTrait, return make_IsTrait({ent.type, ent.hrls, ent.trait}); ),
+ (MaybeTrait, return make_MaybeTrait({ent.type, ent.trait}); ),
+ (NotTrait, return make_NotTrait({ent.type, ent.trait}); ),
+ (Equality, return make_Equality({ent.type, ent.replacement}); )
+ )
+ return GenericBound();
+ }
+ )
);
-#endif
-class GenericBound:
- public Serialisable
-{
- ::std::string m_lifetime_test; // if "", use m_type
- TypeRef m_type;
- ::std::string m_lifetime_bound; // if "", use m_trait
- bool m_optional;
- AST::Path m_trait;
- ::std::vector< ::std::string> m_hrls; // Higher-ranked lifetimes
-public:
-
- GenericBound() {}
- GenericBound(::std::string test, ::std::string bound):
- m_lifetime_test( ::std::move(test) ),
- m_lifetime_bound( ::std::move(bound) )
- { }
- GenericBound(TypeRef type, ::std::string lifetime):
- m_type( ::std::move(type) ),
- m_lifetime_bound( ::std::move(lifetime) )
- { }
- GenericBound(TypeRef type, AST::Path trait, bool optional=false):
- m_type( ::std::move(type) ),
- m_optional(optional),
- m_trait( ::std::move(trait) )
- { }
-
- void set_higherrank( ::std::vector< ::std::string> hrls ) {
- m_hrls = mv$(hrls);
- }
-
- bool is_trait() const { return m_lifetime_bound == ""; }
- const ::std::string& lifetime() const { return m_lifetime_bound; }
- const TypeRef& test() const { return m_type; }
- const AST::Path& bound() const { return m_trait; }
-
- TypeRef& test() { return m_type; }
- AST::Path& bound() { return m_trait; }
-
- friend ::std::ostream& operator<<(::std::ostream& os, const GenericBound& x);
- SERIALISABLE_PROTOTYPES();
-};
+::std::ostream& operator<<(::std::ostream& os, const GenericBound& x);
class TypeParams:
public Serialisable
@@ -135,6 +116,26 @@ class TypeParams: ::std::vector<GenericBound> m_bounds;
public:
TypeParams() {}
+ TypeParams(TypeParams&& x) noexcept:
+ m_type_params( mv$(x.m_type_params) ),
+ m_lifetime_params( mv$(x.m_lifetime_params) ),
+ m_bounds( mv$(x.m_bounds) )
+ {}
+ TypeParams& operator=(TypeParams&& x) {
+ m_type_params = mv$(x.m_type_params);
+ m_lifetime_params = mv$(x.m_lifetime_params);
+ m_bounds = mv$(x.m_bounds);
+ return *this;
+ }
+ TypeParams(const TypeParams& x):
+ m_type_params(x.m_type_params),
+ m_lifetime_params(x.m_lifetime_params),
+ m_bounds()
+ {
+ m_bounds.reserve( x.m_bounds.size() );
+ for(auto& e: x.m_bounds)
+ m_bounds.push_back( e.clone() );
+ }
const ::std::vector<TypeParam>& ty_params() const { return m_type_params; }
const ::std::vector< ::std::string>& lft_params() const { return m_lifetime_params; }
|