summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--samples/std.rs2
-rw-r--r--src/ast/ast.hpp21
-rw-r--r--src/convert/ast_iterate.cpp17
-rw-r--r--src/convert/typecheck_params.cpp50
-rw-r--r--src/types.hpp2
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);