From 1e2b0cc4fc9ce65ffe8212c9feca4eec945b46f3 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Sun, 18 Jan 2015 14:50:41 +0800 Subject: Add handlers for more item types to AST iterator, fix bad name in std --- src/ast/ast.hpp | 21 +++++++++++++---- src/convert/ast_iterate.cpp | 17 ++++++++++++++ src/convert/typecheck_params.cpp | 50 +++++++++++++++++++++++++++++----------- src/types.hpp | 2 ++ 4 files changed, 73 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 579cb058..849587f1 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -120,6 +120,9 @@ struct Item: { } + //friend ::std::ostream& operator<<(::std::ostream& os, const Item& i) { + // return os << (i.is_pub ? "pub " : " ") << i.name << ": " << i.data; + //} SERIALISE_TYPE(, "Item", { s << name << data << is_pub; },{ @@ -286,8 +289,11 @@ public: m_variants( move(variants) ) {} - const TypeParams params() const { return m_params; } - const ::std::vector variants() const { return m_variants; } + const TypeParams& params() const { return m_params; } + const ::std::vector& variants() const { return m_variants; } + + TypeParams& params() { return m_params; } + ::std::vector& variants() { return m_variants; } SERIALISABLE_PROTOTYPES(); }; @@ -304,8 +310,11 @@ public: m_fields( move(fields) ) {} - const TypeParams params() const { return m_params; } - const ::std::vector fields() const { return m_fields; } + const TypeParams& params() const { return m_params; } + const ::std::vector& fields() const { return m_fields; } + + TypeParams& params() { return m_params; } + ::std::vector& fields() { return m_fields; } SERIALISABLE_PROTOTYPES(); }; @@ -436,6 +445,10 @@ public: ::std::vector >& type_aliases() { return m_type_aliases; } itemlist_ext_t& extern_crates() { return m_extern_crates; } ::std::vector& impls() { return m_impls; } + itemlist_static_t& statics() { return m_statics; } + ItemList& traits() { return m_traits; } + itemlist_enum_t& enums () { return m_enums; } + itemlist_struct_t& structs() { return m_structs; } const ::std::vector& attrs() const { return m_attrs; } const itemlist_fcn_t& functions() const { return m_functions; } diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp index 1e01d37d..f9d1f927 100644 --- a/src/convert/ast_iterate.cpp +++ b/src/convert/ast_iterate.cpp @@ -98,6 +98,16 @@ void CASTIterator::handle_module(AST::Path path, AST::Module& mod) DEBUG("Handling function '" << fcn.name << "'"); handle_function(path + fcn.name, fcn.data); } + for( auto& item : mod.structs() ) + { + DEBUG("Handling struct " << item.name); + handle_struct(path + item.name, item.data); + } + for( auto& item : mod.enums() ) + { + DEBUG("Handling enum " << item.name); + handle_enum(path + item.name, item.data); + } for( auto& impl : mod.impls() ) { @@ -158,10 +168,17 @@ void CASTIterator::handle_impl(AST::Path modpath, AST::Impl& impl) void CASTIterator::handle_struct(AST::Path path, AST::Struct& str) { + handle_params( str.params() ); + for( auto& f : str.fields() ) + handle_type( f.second ); } void CASTIterator::handle_enum(AST::Path path, AST::Enum& enm) { + handle_params( enm.params() ); + for( auto& f : enm.variants() ) + handle_type( f.second ); } void CASTIterator::handle_alias(AST::Path path, AST::TypeAlias& alias) { + throw ::std::runtime_error("TODO - handle_alias"); } diff --git a/src/convert/typecheck_params.cpp b/src/convert/typecheck_params.cpp index 376627c7..31b578d7 100644 --- a/src/convert/typecheck_params.cpp +++ b/src/convert/typecheck_params.cpp @@ -25,6 +25,23 @@ public: {} }; +bool has_impl(const TypeRef& type, const TypeRef& trait) +{ + if( type.is_type_param() ) + { + // TODO: Search current scope (requires access to CGenericParamChecker) for this type, + // and search the bounds for this trait + // - Also accept bounded generic impls (somehow) + throw ::std::runtime_error( FMT("TODO: Enumerate bounds on type param " << type.type_param() << " for matches to trait") ); + } + else + { + // Search all known impls of this trait (TODO: keep a list at the crate level) for a match to this type + throw ::std::runtime_error( FMT("TODO: Search for impls on " << type << " for the trait") ); + } + return false; +} + /// Check that the passed set of parameters match the requiremens for a generic item /// /// \param info Generic item information (param names and bounds) @@ -93,6 +110,11 @@ void check_generic_params(const AST::TypeParams& info, ::std::vector& t { const auto& trait = bound.type(); // Check if 'type' impls 'trait' + if( !has_impl(type, trait) ) + { + throw ::std::runtime_error( FMT("No matching impl of "< 0)); + check_generic_params(*params, last_node.args(), (m_within_expr > 0)); } catch( const ::std::exception& e ) { diff --git a/src/types.hpp b/src/types.hpp index 01a50d0c..175e9c48 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -110,7 +110,9 @@ public: bool is_wildcard() const { return m_class == ANY; } bool is_path() const { return m_class == PATH; } + bool is_type_param() const { return m_class == GENERIC; } AST::Path& path() { assert(is_path()); return m_path; } + const ::std::string& type_param() const { assert(is_type_param()); return m_path[0].name(); } ::std::vector& sub_types() { return m_inner_types; } friend ::std::ostream& operator<<(::std::ostream& os, const TypeRef& tr); -- cgit v1.2.3