diff options
-rw-r--r-- | src/ast/ast.cpp | 57 | ||||
-rw-r--r-- | src/ast/ast.hpp | 5 | ||||
-rw-r--r-- | src/ast/provided_module.cpp | 4 | ||||
-rw-r--r-- | src/types.hpp | 1 |
4 files changed, 53 insertions, 14 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 8a598977..7350bab8 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -40,6 +40,7 @@ SERIALISE_TYPE(MetaItem::, "AST_MetaItem", { bool ImplDef::matches(::std::vector<TypeRef>& out_types, const Path& trait, const TypeRef& type) const
{
+ TRACE_FUNCTION_F("m_trait=" << m_trait << ", m_type=" << m_type);
// 1. Check the type/trait counting parameters as wildcards (but flagging if one was seen)
// > If that fails, just early return
int trait_match = m_trait.equal_no_generic(trait);
@@ -204,9 +205,9 @@ void Crate::post_parse() // Iterate all modules, grabbing pointers to all impl blocks
auto cb = [this](Module& mod){
for( auto& impl : mod.impls() )
- {
m_impl_index.push_back( &impl );
- }
+ for( auto& impl : mod.neg_impls() )
+ m_neg_impl_index.push_back( &impl );
};
iterate_module(m_root_module, cb);
iterate_module(g_compiler_module, cb);
@@ -228,16 +229,45 @@ const Module& Crate::get_root_module(const ::std::string& name) const { throw ParseError::Generic("crate name unknown");
}
-#if 0
bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type)
{
+ ::std::vector<TypeRef> _params;
+ DEBUG("trait="<<trait);
// 1. Look for a negative impl for this type
+ for( auto implptr : m_neg_impl_index )
+ {
+ const ImplDef& impl = *implptr;
+
+ if( impl.matches(_params, trait, type) )
+ {
+ return false;
+ }
+ }
+ DEBUG("No negative impl of " << trait << " for " << type);
// 2. Look for a positive impl for this type (i.e. an unsafe impl)
+ for( auto implptr : m_impl_index )
+ {
+ const Impl& impl = *implptr;
+ if( impl.def().matches(_params, trait, type) )
+ {
+ return true;
+ }
+ }
+ DEBUG("No positive impl of " << trait << " for " << type);
// If none found, destructure the type
// - structs need all fields to impl this trait (cache result)
- // -
+ // - same for enums, tuples, arrays, pointers...
+ // - traits check the Self bounds
+ if( type.is_primitive() ) {
+ return true;
+ }
+ else if( type.is_unit() ) {
+ return true;
+ }
+ else {
+ throw CompileError::Todo("wildcard impls - auto determine");
+ }
}
-#endif
::rust::option<Impl&> Crate::find_impl(const Path& trait, const TypeRef& type)
{
@@ -247,19 +277,22 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) for( auto implptr : m_impl_index )
{
Impl& impl = *implptr;
- ::rust::option<Impl&> oimpl = impl.matches(trait, TypeRef());
- if( oimpl.is_some() )
+ ::std::vector<TypeRef> _p;
+ if( impl.def().matches(_p, trait, TypeRef()) )
{
// This is a wildcard trait, need to locate either a negative, or check contents
- //if( check_impls_wildcard(trait, type) )
- //{
- // return ::rust::option<Impl&>(oimpl);
- //}
- throw CompileError::Todo("wildcard impls");
+ if( check_impls_wildcard(trait, type) )
+ {
+ return ::rust::option<Impl&>(impl);
+ }
+ else {
+ return ::rust::option<Impl&>();
+ }
}
}
+ DEBUG("Not wildcard");
for( auto implptr : m_impl_index )
{
Impl& impl = *implptr;
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index ff798fed..5cedab2f 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -674,6 +674,8 @@ public: const itemlist_struct_t& structs() const { return m_structs; }
const ::std::vector<Module*>& anon_mods() const { return m_anon_modules; }
+ const ::std::vector<ImplDef>& neg_impls() const { return m_neg_impls; }
+
const itemlist_macros_t& macros() const { return m_macros; }
const macro_imports_t& macro_imports() const { return m_macro_imports; }
const ::std::vector<ItemNS<const MacroRules*> > macro_imports_res() const { return m_macro_import_res; }
@@ -688,6 +690,7 @@ class Crate: public Serialisable
{
::std::vector<Impl*> m_impl_index;
+ ::std::vector<const ImplDef*> m_neg_impl_index;
public:
Module m_root_module;
::std::map< ::std::string, ExternCrate> m_extern_crates;
@@ -716,6 +719,8 @@ public: void iterate_functions( fcn_visitor_t* visitor );
SERIALISABLE_PROTOTYPES();
+private:
+ bool check_impls_wildcard(const Path& trait, const TypeRef& type);
};
/// Representation of an imported crate
diff --git a/src/ast/provided_module.cpp b/src/ast/provided_module.cpp index d82f9716..a72869a6 100644 --- a/src/ast/provided_module.cpp +++ b/src/ast/provided_module.cpp @@ -29,12 +29,12 @@ void AST_InitProvidedModule() // A hacky default impl of 'Sized', with a negative impl on [T] AST::Path sized_marker_path({AST::PathNode("marker"),AST::PathNode("Sized")}); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(), copy_marker_path)); + g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(), sized_marker_path)); AST::TypeParams tps; tps.add_ty_param( AST::TypeParam("T") ); g_compiler_module.add_neg_impl(AST::ImplDef( ::std::move(tps), - copy_marker_path, + sized_marker_path, TypeRef(TypeRef::TagUnsizedArray(), TypeRef(TypeRef::TagArg(), "T")) )); } diff --git a/src/types.hpp b/src/types.hpp index 443f9912..7c026500 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -175,6 +175,7 @@ public: bool is_wildcard() const { return m_class == ANY; }
bool is_unit() const { return m_class == UNIT; }
+ bool is_primitive() const { return m_class == PRIMITIVE; }
bool is_path() const { return m_class == PATH; }
bool is_type_param() const { return m_class == GENERIC; }
bool is_reference() const { return m_class == REFERENCE; }
|