diff options
| -rw-r--r-- | src/ast/ast.cpp | 59 | ||||
| -rw-r--r-- | src/convert/typecheck_params.cpp | 5 | ||||
| -rw-r--r-- | src/types.cpp | 27 | ||||
| -rw-r--r-- | src/types.hpp | 1 | 
4 files changed, 58 insertions, 34 deletions
| 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<Impl&>(i.second);
 -                }
 -            }
 -            
 -            m_concrete_impls.push_back( make_pair(param_types, this->make_concrete(param_types)) );
 -            return ::rust::option<Impl&>( m_concrete_impls.back().second );
 -        }
 +        //if( param_types.size() > 0 )
 +        //{ 
 +        //    for( auto& i : m_concrete_impls )
 +        //    {
 +        //        if( i.first == param_types )
 +        //        {
 +        //            return ::rust::option<Impl&>(i.second);
 +        //        }
 +        //    }
 +        //    
 +        //    m_concrete_impls.push_back( make_pair(param_types, this->make_concrete(param_types)) );
 +        //    return ::rust::option<Impl&>( m_concrete_impls.back().second );
 +        //}
      }
      return ::rust::option<Impl&>( *this );
  }
  Impl Impl::make_concrete(const ::std::vector<TypeRef>& 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<TypeRef>  _params;
 -    DEBUG("trait="<<trait);
 +    TRACE_FUNCTION_F("trait="<<trait<<", type="<<type);
      // 1. Look for a negative impl for this type
      for( auto implptr : m_neg_impl_index )
 @@ -293,6 +286,14 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type)      else if( type.is_reference() ) {
          return check_impls_wildcard(trait, type.sub_types()[0]);
      }
 +    else if( type.is_pointer() ) {
 +        return check_impls_wildcard(trait, type.sub_types()[0]);
 +    }
 +    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...
 diff --git a/src/convert/typecheck_params.cpp b/src/convert/typecheck_params.cpp index bdc83be0..34061e85 100644 --- a/src/convert/typecheck_params.cpp +++ b/src/convert/typecheck_params.cpp @@ -71,7 +71,6 @@ bool CGenericParamChecker::has_impl_for_param(const ::std::string name, const AS      // Locate params set that contains the passed name      for( const auto lt : m_types_stack )      { -        DEBUG("lt = " << lt.name);          if( lt.name == name )          {              if( lt.source_params != nullptr ) { @@ -79,6 +78,7 @@ bool CGenericParamChecker::has_impl_for_param(const ::std::string name, const AS              }              else {                  DEBUG("Type name '" << name << "' isn't a param"); +                return has_impl(lt.fixed_type, trait);              }              //break ;          } @@ -219,7 +219,6 @@ void CGenericParamChecker::check_generic_params(const AST::TypeParams& info, ::s              auto trait = bound.bound();              trait.resolve_args(ra_fcn); -            // TODO: Also resolve args in the trait              // Check if 'type' impls 'trait'              if( !has_impl(bound_type, trait) ) @@ -296,6 +295,8 @@ void CGenericParamChecker::end_scope()      assert( m_types_stack.size() > 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; }
 | 
