From f910da73acb47e7d6bdf5efdf5dca26b78280a4a Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 4 Apr 2015 10:29:18 +0800 Subject: Further work on handling wildcard traits --- src/ast/ast.cpp | 59 ++++++++++++++++++++-------------------- src/convert/typecheck_params.cpp | 5 ++-- src/types.cpp | 27 ++++++++++++++++-- src/types.hpp | 1 + 4 files changed, 58 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index b5025e9c..93ac87ea 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -139,43 +139,36 @@ SERIALISE_TYPE(ImplDef::, "AST_ImplDef", { } else { - if( param_types.size() > 0 ) - { - for( auto& i : m_concrete_impls ) - { - if( i.first == param_types ) - { - return ::rust::option(i.second); - } - } - - m_concrete_impls.push_back( make_pair(param_types, this->make_concrete(param_types)) ); - return ::rust::option( m_concrete_impls.back().second ); - } + //if( param_types.size() > 0 ) + //{ + // for( auto& i : m_concrete_impls ) + // { + // if( i.first == param_types ) + // { + // return ::rust::option(i.second); + // } + // } + // + // m_concrete_impls.push_back( make_pair(param_types, this->make_concrete(param_types)) ); + // return ::rust::option( m_concrete_impls.back().second ); + //} } return ::rust::option( *this ); } Impl Impl::make_concrete(const ::std::vector& types) const { - DEBUG("types={" << types << "}"); - throw ParseError::Todo("Impl::make_concrete"); -/* - INDENT(); + TRACE_FUNCTION_F("*this = " << *this << ", types={" << types << "}"); + assert(m_def.params().ty_params().size()); - assert(m_params.n_params()); + GenericResolveClosure resolver(m_def.params(), types); - Impl ret( TypeParams(), m_trait, m_type ); - - auto resolver = [&](const char *name) { - int idx = m_params.find_name(name); - assert(idx >= 0); - return types[idx]; - }; - - ret.m_trait.resolve_args(resolver); - ret.m_type.resolve_args(resolver); + Impl ret( MetaItems(), TypeParams(), m_def.type(), m_def.trait() ); + ret.m_def.trait().resolve_args( resolver ); + ret.m_def.type().resolve_args( resolver ); + throw ParseError::Todo("Impl::make_concrete"); +/* for(const auto& fcn : m_functions) { TypeParams new_fcn_params = fcn.data.params(); @@ -260,7 +253,7 @@ const Module& Crate::get_root_module(const ::std::string& name) const { bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) { ::std::vector _params; - DEBUG("trait="< 0 ); while( !m_types_stack.back().is_separator() ) m_types_stack.pop_back(); + // pop the separator + m_types_stack.pop_back(); } void CGenericParamChecker::handle_params(AST::TypeParams& params) { diff --git a/src/types.cpp b/src/types.cpp index 4286f828..9d2e42d4 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -296,7 +296,7 @@ bool TypeRef::is_concrete() const int TypeRef::equal_no_generic(const TypeRef& x) const { DEBUG(*this << ", " << x); - if( m_class == TypeRef::GENERIC || x.m_class == TypeRef::GENERIC ) + if( m_class == TypeRef::GENERIC ) //|| x.m_class == TypeRef::GENERIC ) return 1; if( m_class != x.m_class ) return -1; switch(m_class) @@ -314,9 +314,30 @@ int TypeRef::equal_no_generic(const TypeRef& x) const throw CompileError::Todo("TypeRef::equal_no_generic - FUNCTION"); case TypeRef::PATH: return m_path.equal_no_generic( x.m_path ); - default: - throw CompileError::Todo("TypeRef::equal_no_generic"); + case TypeRef::REFERENCE: + case TypeRef::POINTER: + return m_inner_types[0].equal_no_generic( x.m_inner_types[0] ); + case TypeRef::ARRAY: + if( m_size_expr.get() || x.m_size_expr.get() ) + throw CompileError::Todo("TypeRef::equal_no_generic - sized array"); + return m_inner_types[0].equal_no_generic( x.m_inner_types[0] ); + case TypeRef::TUPLE: { + bool fuzzy = false; + if( m_inner_types.size() != x.m_inner_types.size() ) + return -1; + for( unsigned int i = 0; i < m_inner_types.size(); i ++ ) + { + int rv = m_inner_types[i].equal_no_generic( x.m_inner_types[i] ); + if(rv < 0) return -1; + if(rv > 0) fuzzy = true; + } + return (fuzzy ? 1 : 0); } + case TypeRef::MULTIDST: + throw CompileError::Todo("TypeRef::equal_no_generic - MULTIDST"); + case TypeRef::GENERIC: + throw CompileError::BugCheck("equal_no_generic - Generic should have been handled above"); } + throw CompileError::BugCheck("equal_no_generic - Ran off end"); } Ordering TypeRef::ord(const TypeRef& x) const { diff --git a/src/types.hpp b/src/types.hpp index 500e03f7..d963a058 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -179,6 +179,7 @@ public: 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; } + bool is_pointer() const { return m_class == POINTER; } bool is_tuple() const { return m_class == TUPLE; } const ::std::string& type_param() const { assert(is_type_param()); return m_path[0].name(); } AST::Path& path() { assert(is_path()); return m_path; } -- cgit v1.2.3