diff options
author | John Hodge <tpg@mutabah.net> | 2015-03-15 21:33:46 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-03-15 21:33:46 +0800 |
commit | 6b506092f331a26328a45c00565336ac810b7559 (patch) | |
tree | 0dfaa28925dd7c3ae28176161cb420b5f01aabda /src/ast | |
parent | 2fffea5c08283746f0b6609024f6c1ea05bf8367 (diff) | |
download | mrust-6b506092f331a26328a45c00565336ac810b7559.tar.gz |
Rework type params, add ! "type"
Diffstat (limited to 'src/ast')
-rw-r--r-- | src/ast/ast.cpp | 18 | ||||
-rw-r--r-- | src/ast/ast.hpp | 44 | ||||
-rw-r--r-- | src/ast/expr.cpp | 4 | ||||
-rw-r--r-- | src/ast/expr.hpp | 1 |
4 files changed, 47 insertions, 20 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 0caa41a2..870d4eff 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -621,11 +621,14 @@ SERIALISE_TYPE(TypeParam::, "AST_TypeParam", { ::std::ostream& operator<<(::std::ostream& os, const GenericBound& x)
{
- //return os << "GenericBound(" << x.m_argname << "," << x.m_lifetime << "," << x.m_trait << ")";
- return os << x.m_argname << ": ('" << x.m_lifetime << " + " << x.m_trait << ")";
+ os << x.m_type << ": ";
+ if( x.m_lifetime != "" )
+ return os << "'" << x.m_lifetime;
+ else
+ return os << x.m_trait;
}
SERIALISE_TYPE_S(GenericBound, {
- s.item(m_argname);
+ s.item(m_type);
s.item(m_lifetime);
s.item(m_trait);
})
@@ -680,13 +683,14 @@ bool TypeParams::check_params(Crate& crate, ::std::vector<TypeRef>& types, bool {
auto& type = types[i];
auto& param = m_params[i].name();
+ TypeRef test(TypeRef::TagArg(), param);
if( type.is_wildcard() )
{
for( const auto& bound : m_bounds )
{
- if( bound.is_trait() && bound.name() == param )
+ if( bound.is_trait() && bound.test() == test )
{
- const auto& trait = bound.type();
+ const auto& trait = bound.bound();
const auto& ty_traits = type.traits();
auto it = ::std::find(ty_traits.begin(), ty_traits.end(), trait);
@@ -703,9 +707,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.name() == param )
+ if( bound.is_trait() && bound.test() == test )
{
- const auto& trait = bound.type();
+ const auto& trait = bound.bound();
// Check if 'type' impls 'trait'
if( !crate.find_impl(type, trait).is_some() )
{
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 81a0dbd6..8928aa97 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -41,7 +41,10 @@ public: m_class( is_lifetime ? LIFETIME : TYPE ),
m_name( ::std::move(name) )
{}
- void setDefault(TypeRef type);
+ void setDefault(TypeRef type) {
+ assert(m_default.is_wildcard());
+ m_default = ::std::move(type);
+ }
const ::std::string& name() const { return m_name; }
const TypeRef& get_default() const { return m_default; }
@@ -55,25 +58,32 @@ public: class GenericBound:
public Serialisable
{
- ::std::string m_argname;
+ TypeRef m_type;
+
::std::string m_lifetime;
- TypeRef m_trait;
+
+ bool m_optional;
+ AST::Path m_trait;
public:
+
GenericBound() {}
- GenericBound(::std::string argname, ::std::string lifetime):
- m_argname(argname),
+ GenericBound(TypeRef type, ::std::string lifetime):
+ m_type( ::std::move(type) ),
m_lifetime(lifetime)
{ }
- GenericBound(::std::string argname, TypeRef trait):
- m_argname(argname),
+ GenericBound(TypeRef type, AST::Path trait, bool optional=false):
+ m_type( ::std::move(type) ),
+ m_optional(optional),
m_trait( ::std::move(trait) )
{ }
bool is_trait() const { return m_lifetime == ""; }
- const ::std::string& name() const { return m_argname; }
- const TypeRef& type() const { return m_trait; }
+ const ::std::string& lifetime() const { return m_lifetime; }
+ const TypeRef& test() const { return m_type; }
+ const AST::Path& bound() const { return m_trait; }
- TypeRef& type() { 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();
@@ -394,16 +404,26 @@ class Impl: TypeRef m_trait;
TypeRef m_type;
+ bool m_is_negative;
ItemList<TypeRef> m_types;
ItemList<Function> m_functions;
::std::vector< ::std::pair< ::std::vector<TypeRef>, Impl > > m_concrete_impls;
public:
- Impl() {}
+ Impl(): m_is_negative(false) {}
Impl(TypeParams params, TypeRef impl_type, TypeRef trait_type):
m_params( move(params) ),
m_trait( move(trait_type) ),
- m_type( move(impl_type) )
+ m_type( move(impl_type) ),
+ m_is_negative(true)
+ {}
+
+ struct TagNegative {};
+ Impl(TagNegative, TypeParams params, TypeRef impl_type, TypeRef trait_type):
+ m_params( move(params) ),
+ m_trait( move(trait_type) ),
+ m_type( move(impl_type) ),
+ m_is_negative(true)
{}
void add_function(bool is_public, ::std::string name, Function fcn) {
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp index 1246ad29..1f5eb377 100644 --- a/src/ast/expr.cpp +++ b/src/ast/expr.cpp @@ -454,6 +454,7 @@ void operator%(::Serialiser& s, const ExprNode_UniOp::Type t) { _(INVERT) _(BOX) _(REF) + _(REFMUT) #undef _ } } @@ -466,9 +467,10 @@ void operator%(::Deserialiser& s, enum ExprNode_UniOp::Type& t) { _(INVERT) _(BOX) _(REF) + _(REFMUT) + #undef _ else throw ::std::runtime_error( FMT("No uniop type for '" << n << "'") ); - #undef _ } NODE(ExprNode_UniOp, { s % m_type; diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index 121a1f09..21f67c2f 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -547,6 +547,7 @@ struct ExprNode_UniOp: { enum Type { REF, + REFMUT, BOX, INVERT, NEGATE, |