From 0e61ec5eafddb980eac2d6577b2e20af9aceae02 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Sun, 18 Jan 2015 13:48:31 +0800 Subject: Up to requiring checks for trait implementations --- src/ast/ast.cpp | 7 +++-- src/ast/ast.hpp | 4 ++- src/ast/path.cpp | 2 +- src/ast/path.hpp | 11 +++++-- src/common.hpp | 2 +- src/convert/typecheck_params.cpp | 62 ++++++++++++++++++++++++++++++++++++++-- src/types.cpp | 16 ----------- src/types.hpp | 1 + 8 files changed, 78 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 696978fb..21a8b58a 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -291,7 +291,7 @@ SERIALISE_TYPE(Struct::, "AST_Struct", { ::std::ostream& operator<<(::std::ostream& os, const TypeParam& tp) { - os << "TypeParam("; + //os << "TypeParam("; switch(tp.m_class) { case TypeParam::LIFETIME: os << "'"; break; @@ -300,7 +300,7 @@ SERIALISE_TYPE(Struct::, "AST_Struct", { os << tp.m_name; os << " = "; os << tp.m_default; - os << ")"; + //os << ")"; return os; } SERIALISE_TYPE(TypeParam::, "AST_TypeParam", { @@ -338,7 +338,8 @@ SERIALISE_TYPE_S(GenericBound, { ::std::ostream& operator<<(::std::ostream& os, const TypeParams& tps) { - return os << "TypeParams({" << tps.m_params << "}, {" << tps.m_bounds << "})"; + //return os << "TypeParams({" << tps.m_params << "}, {" << tps.m_bounds << "})"; + return os << "<" << tps.m_params << "> where {" << tps.m_bounds << "}"; } SERIALISE_TYPE_S(TypeParams, { s.item(m_params); diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 20d28467..579cb058 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -68,9 +68,11 @@ public: { } bool is_trait() const { return m_lifetime == ""; } - TypeRef& type() { return m_trait; } + const ::std::string& name() const { return m_argname; } const TypeRef& type() const { return m_trait; } + TypeRef& type() { return m_trait; } + friend ::std::ostream& operator<<(::std::ostream& os, const GenericBound& x); SERIALISABLE_PROTOTYPES(); }; diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 16c9c5cc..aff3586d 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -156,7 +156,7 @@ void Path::resolve(const Crate& root_crate) DEBUG("Found trait"); if( is_last ) { m_binding_type = TRAIT; - m_binding.trait = &it->data; + m_binding.trait_ = &it->data; return; } else if( is_sec_last ) { diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 7d6f9462..e390d9aa 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -81,7 +81,7 @@ private: const Module* module_; const Enum* enum_; const Struct* struct_; - const Trait* trait; + const Trait* trait_; const Static* static_; const Function* func_; struct { @@ -155,8 +155,13 @@ public: bool is_bound() const { return m_binding_type != UNBOUND; } BindingType binding_type() const { return m_binding_type; } - const Module& bound_module() const { assert(m_binding_type == MODULE); return *m_binding.module_; } - const Trait& bound_trait() const { assert(m_binding_type == TRAIT); return *m_binding.trait; } + #define _(t, n, v) const t& bound_##n() const { assert(m_binding_type == v); return *m_binding.n##_; } + _(Module, module, MODULE) + _(Trait, trait, TRAIT) + _(Struct, struct, STRUCT) + _(Enum, enum, ENUM) + _(Function, func, FUNCTION) + #undef _ ::std::vector& nodes() { return m_nodes; } const ::std::vector& nodes() const { return m_nodes; } diff --git a/src/common.hpp b/src/common.hpp index 1e77d84a..3247ee7a 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -84,7 +84,7 @@ option None() { }; -namespace AST { +namespace std { template inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector& v) { diff --git a/src/convert/typecheck_params.cpp b/src/convert/typecheck_params.cpp index 07d15bf6..376627c7 100644 --- a/src/convert/typecheck_params.cpp +++ b/src/convert/typecheck_params.cpp @@ -30,9 +30,17 @@ public: /// \param info Generic item information (param names and bounds) /// \param types Type parameters being passed to the generic item /// \param allow_infer Allow inferrence (mutates \a types with conditions from \a info) -bool check_generic_params(const AST::TypeParams& info, ::std::vector& types, bool allow_infer = false) +void check_generic_params(const AST::TypeParams& info, ::std::vector& types, bool allow_infer = false) { + DEBUG("(info = " << info << ", types = {" << types << "}"); + // TODO: Need to correctly handle lifetime params here, they should be in a different list const auto& params = info.params(); + + { + for(const auto& p : params) + assert(p.is_type()); + } + if( types.size() > params.size() ) { throw ::std::runtime_error(FMT("Too many generic params ("<& t throw ::std::runtime_error(FMT("Too few generic params, ("< -inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector& v) { - if( v.size() > 0 ) - { - bool is_first = true; - for( const auto& i : v ) - { - if(!is_first) - os << ", "; - is_first = false; - os << i; - } - } - return os; -} - ::std::ostream& operator<<(::std::ostream& os, const TypeRef& tr) { os << "TypeRef("; diff --git a/src/types.hpp b/src/types.hpp index 2d052a06..01a50d0c 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -108,6 +108,7 @@ public: m_inner_types( {::std::move(base), ::std::move(trait)} ) {} + bool is_wildcard() const { return m_class == ANY; } bool is_path() const { return m_class == PATH; } AST::Path& path() { assert(is_path()); return m_path; } ::std::vector& sub_types() { return m_inner_types; } -- cgit v1.2.3