diff options
-rw-r--r-- | samples/std.rs | 2 | ||||
-rw-r--r-- | src/ast/ast.hpp | 21 | ||||
-rw-r--r-- | src/convert/ast_iterate.cpp | 17 | ||||
-rw-r--r-- | src/convert/typecheck_params.cpp | 50 | ||||
-rw-r--r-- | src/types.hpp | 2 |
5 files changed, 74 insertions, 18 deletions
diff --git a/samples/std.rs b/samples/std.rs index 2900ddae..125021b4 100644 --- a/samples/std.rs +++ b/samples/std.rs @@ -13,7 +13,7 @@ pub mod result pub enum Result<G,E> { Ok(G), - Err(T) + Err(E) } } 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<StructItem> variants() const { return m_variants; }
+ const TypeParams& params() const { return m_params; }
+ const ::std::vector<StructItem>& variants() const { return m_variants; }
+
+ TypeParams& params() { return m_params; }
+ ::std::vector<StructItem>& 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<StructItem> fields() const { return m_fields; }
+ const TypeParams& params() const { return m_params; }
+ const ::std::vector<StructItem>& fields() const { return m_fields; }
+
+ TypeParams& params() { return m_params; }
+ ::std::vector<StructItem>& fields() { return m_fields; }
SERIALISABLE_PROTOTYPES();
};
@@ -436,6 +445,10 @@ public: ::std::vector<Item<TypeAlias> >& type_aliases() { return m_type_aliases; }
itemlist_ext_t& extern_crates() { return m_extern_crates; }
::std::vector<Impl>& impls() { return m_impls; }
+ itemlist_static_t& statics() { return m_statics; }
+ ItemList<Trait>& traits() { return m_traits; }
+ itemlist_enum_t& enums () { return m_enums; }
+ itemlist_struct_t& structs() { return m_structs; }
const ::std::vector<MetaItem>& 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<TypeRef>& 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 "<<trait<<" for "<<type)); + } + throw ::std::runtime_error( FMT("TODO: Check if " << type << " impls " << trait) ); } } @@ -105,24 +127,26 @@ void CGenericParamChecker::handle_path(AST::Path& path, CASTIterator::PathMode p { DEBUG("path = " << path); AST::PathNode& last_node = path[path.size()-1]; + const AST::TypeParams* params = nullptr; switch(path.binding_type()) { - case AST::Path::TRAIT: - // Outside of expressions, param types must match perfectly - if( m_within_expr == 0 ) - { - try { - check_generic_params(path.bound_trait().params(), last_node.args()); - } - catch( const ::std::exception& e ) - { - throw ::std::runtime_error( FMT("Checking '" << path << "', threw : " << e.what()) ); - } - } + case AST::Path::MODULE: + DEBUG("WTF - Module path, isn't this invalid at this stage?"); break; + case AST::Path::TRAIT: + params = &path.bound_trait().params(); + if(0) case AST::Path::STRUCT: + params = &path.bound_struct().params(); + if(0) + case AST::Path::ENUM: + params = &path.bound_enum().params(); + if(0) + case AST::Path::FUNCTION: + params = &path.bound_func().params(); + try { - check_generic_params(path.bound_struct().params(), last_node.args(), (m_within_expr > 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<TypeRef>& sub_types() { return m_inner_types; }
friend ::std::ostream& operator<<(::std::ostream& os, const TypeRef& tr);
|