summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2015-04-05 13:47:01 +0800
committerJohn Hodge <tpg@mutabah.net>2015-04-05 13:47:01 +0800
commitcae16a7a72a75f08e01b63ef31a56e75125556b6 (patch)
tree0413915c3eb2925585d844bf7f72d1abd2a0d687 /src
parent89788c5801e03b0c5b0b288d0fefb717f75c67f0 (diff)
downloadmrust-cae16a7a72a75f08e01b63ef31a56e75125556b6.tar.gz
Move handling of wildcard trait destructure to TypeRef
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.cpp80
-rw-r--r--src/ast/ast.hpp20
-rw-r--r--src/types.cpp83
-rw-r--r--src/types.hpp2
4 files changed, 106 insertions, 79 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index 63e33ba6..aadade4f 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -10,26 +10,6 @@
namespace AST {
-class GenericResolveClosure
-{
- const TypeParams& m_params;
- const ::std::vector<TypeRef>& m_args;
-public:
- GenericResolveClosure(const TypeParams& params, const ::std::vector<TypeRef>& args):
- m_params(params),
- m_args(args)
- {}
- TypeRef operator()(const char *argname) {
- for(unsigned int i = 0; i < m_params.ty_params().size(); i ++)
- {
- if( m_params.ty_params()[i].name() == argname ) {
- return m_args.at(i);
- }
- }
- throw ::std::runtime_error("BUGCHECK - Unknown arg in field type");
- }
-};
-
void MetaItems::push_back(MetaItem i)
{
@@ -278,65 +258,7 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type)
DEBUG("No positive impl of " << trait << " for " << type);
// 3. If none found, destructure the type
- // Primitives always impl
- if( type.is_primitive() || type.is_unit() ) {
- return true;
- }
- else if( type.is_reference() ) {
- return find_impl(trait, type.sub_types()[0], nullptr);
- }
- else if( type.is_pointer() ) {
- return find_impl(trait, type.sub_types()[0], nullptr);
- }
- else if( type.is_type_param() ) {
- // TODO: Include an annotation to the TypeParams structure relevant to this type
- // - Allows searching the params for the impl, without having to pass the params down
- throw CompileError::Todo("check_impls_wildcard - param");
- }
- else if( type.is_path() ) {
- // - structs need all fields to impl this trait (cache result)
- // - same for enums, tuples, arrays, pointers...
- // - traits check the Self bounds
- // CATCH: Need to handle recursion, keep a list of currently processing paths and assume true if found
- switch(type.path().binding().type())
- {
- case AST::PathBinding::STRUCT: {
- const auto &s = type.path().binding().bound_struct();
- GenericResolveClosure resolve_fn( s.params(), type.path().nodes().back().args() );
- for(const auto& fld : s.fields())
- {
- TypeRef fld_ty = fld.data;
- fld_ty.resolve_args( resolve_fn );
- DEBUG("- Fld '" << fld.name << "' := " << fld.data << " => " << fld_ty);
- // TODO: Defer failure until after all fields are processed
- if( !find_impl(trait, fld_ty, nullptr) )
- return false;
- }
- return true; }
- case AST::PathBinding::ENUM: {
- const auto& i = type.path().binding().bound_enum();
- GenericResolveClosure resolve_fn( i.params(), type.path().nodes().back().args() );
- for( const auto& var : i.variants() )
- {
- for( const auto& ty : var.m_sub_types )
- {
- TypeRef real_ty = ty;
- real_ty.resolve_args( resolve_fn );
- DEBUG("- Var '" << var.m_name << "' := " << ty << " => " << real_ty);
- // TODO: Defer failure until after all fields are processed
- if( !find_impl(trait, real_ty, nullptr) )
- return false;
- }
- }
- return true; }
- default:
- throw CompileError::Todo("wildcard impls - auto determine path");
- }
- }
- else {
- DEBUG("type = " << type);
- throw CompileError::Todo("wildcard impls - auto determine");
- }
+ return type.impls_wildcard(*this, trait);
}
bool Crate::find_impl(const Path& trait, const TypeRef& type, Impl** out_impl)
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index 2f6ab45f..671a0aa9 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -823,6 +823,26 @@ public:
}
+class GenericResolveClosure
+{
+ const AST::TypeParams& m_params;
+ const ::std::vector<TypeRef>& m_args;
+public:
+ GenericResolveClosure(const AST::TypeParams& params, const ::std::vector<TypeRef>& args):
+ m_params(params),
+ m_args(args)
+ {}
+ TypeRef operator()(const char *argname) {
+ for(unsigned int i = 0; i < m_params.ty_params().size(); i ++)
+ {
+ if( m_params.ty_params()[i].name() == argname ) {
+ return m_args.at(i);
+ }
+ }
+ throw ::std::runtime_error("BUGCHECK - Unknown arg in field type");
+ }
+};
+
extern AST::Module g_compiler_module;
extern void AST_InitProvidedModule();
diff --git a/src/types.cpp b/src/types.cpp
index 5c15323b..99312d13 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -252,6 +252,89 @@ void TypeRef::match_args(const TypeRef& other, ::std::function<void(const char*,
}
}
+bool TypeRef::impls_wildcard(AST::Crate& crate, const AST::Path& trait) const
+{
+ switch(m_class)
+ {
+ case TypeRef::NONE:
+ throw CompileError::BugCheck("TypeRef::impls_wildcard on !");
+ case TypeRef::ANY:
+ throw CompileError::BugCheck("TypeRef::impls_wildcard on _");
+ // Generics are an error?
+ case GENERIC:
+ // TODO: Include an annotation to the TypeParams structure relevant to this type
+ // - Allows searching the params for the impl, without having to pass the params down
+ throw CompileError::Todo("TypeRef::impls_wildcard - param");
+ // Primitives always impl
+ case UNIT:
+ case PRIMITIVE:
+ return true;
+ // Functions are pointers (currently), so they implement the trait
+ case FUNCTION:
+ return true;
+ // Pointers/arrays inherit directly
+ case REFERENCE:
+ return crate.find_impl(trait, sub_types()[0], nullptr);
+ case POINTER:
+ return crate.find_impl(trait, sub_types()[0], nullptr);
+ case ARRAY:
+ return crate.find_impl(trait, sub_types()[0], nullptr);
+ // Tuples just destructure
+ case TUPLE:
+ for( const auto& fld : sub_types() )
+ {
+ if( !crate.find_impl(trait, fld, nullptr) )
+ return false;
+ }
+ return true;
+ // MultiDST is special - It only impls if this trait is in the list
+ // (or if a listed trait requires/impls the trait)
+ case MULTIDST:
+ throw CompileError::Todo("TypeRef::impls_wildcard - MULTIDST");
+ // Path types destructure
+ case PATH:
+ // - structs need all fields to impl this trait (cache result)
+ // - same for enums, tuples, arrays, pointers...
+ // - traits check the Self bounds
+ // CATCH: Need to handle recursion, keep a list of currently processing paths and assume true if found
+ switch(m_path.binding().type())
+ {
+ case AST::PathBinding::STRUCT: {
+ const auto &s = m_path.binding().bound_struct();
+ GenericResolveClosure resolve_fn( s.params(), m_path.nodes().back().args() );
+ for(const auto& fld : s.fields())
+ {
+ TypeRef fld_ty = fld.data;
+ fld_ty.resolve_args( resolve_fn );
+ DEBUG("- Fld '" << fld.name << "' := " << fld.data << " => " << fld_ty);
+ // TODO: Defer failure until after all fields are processed
+ if( !crate.find_impl(trait, fld_ty, nullptr) )
+ return false;
+ }
+ return true; }
+ case AST::PathBinding::ENUM: {
+ const auto& i = m_path.binding().bound_enum();
+ GenericResolveClosure resolve_fn( i.params(), m_path.nodes().back().args() );
+ for( const auto& var : i.variants() )
+ {
+ for( const auto& ty : var.m_sub_types )
+ {
+ TypeRef real_ty = ty;
+ real_ty.resolve_args( resolve_fn );
+ DEBUG("- Var '" << var.m_name << "' := " << ty << " => " << real_ty);
+ // TODO: Defer failure until after all fields are processed
+ if( !crate.find_impl(trait, real_ty, nullptr) )
+ return false;
+ }
+ }
+ return true; }
+ default:
+ throw CompileError::Todo("wildcard impls - auto determine path");
+ }
+ }
+ throw CompileError::BugCheck("TypeRef::impls_wildcard - Fell off end");
+}
+
/// Checks if the type is fully bounded
bool TypeRef::is_concrete() const
{
diff --git a/src/types.hpp b/src/types.hpp
index c56875f9..5a296e3d 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -178,6 +178,8 @@ public:
/// Match 'GENERIC' entries with another type, passing matches to a closure
void match_args(const TypeRef& other, ::std::function<void(const char*,const TypeRef&)> fcn) const;
+ bool impls_wildcard(AST::Crate& crate, const AST::Path& trait) const;
+
/// Returns true if the type is fully known (all sub-types are not wildcards)
bool is_concrete() const;