diff options
| -rw-r--r-- | src/hir_typeck/expr_cs.cpp | 71 | 
1 files changed, 54 insertions, 17 deletions
| diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 47b83356..abca0507 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -221,7 +221,7 @@ static void fix_param_count(const Span& sp, Context& context, const ::HIR::TypeR  namespace { -    void apply_bounds_as_rules(Context& context, const Span& sp, const ::HIR::GenericParams& params_def, t_cb_generic monomorph_cb) +    void apply_bounds_as_rules(Context& context, const Span& sp, const ::HIR::GenericParams& params_def, t_cb_generic monomorph_cb, bool is_impl_level)      {          for(const auto& bound : params_def.m_bounds)          { @@ -264,6 +264,15 @@ namespace {                  )              )          } + +        for(size_t i = 0; i < params_def.m_types.size(); i++) +        { +            if( params_def.m_types[i].m_is_sized ) +            { +                ::HIR::TypeRef  ty("", (is_impl_level ? 0 : 256) + i); +                context.require_sized(sp, monomorph_cb(ty)); +            } +        }      }      bool visit_call_populate_cache(Context& context, const Span& sp, ::HIR::Path& path, ::HIR::ExprCallCache& cache) __attribute__((warn_unused_result)); @@ -374,7 +383,7 @@ namespace {          cache.m_arg_types.push_back( monomorphise_type_with(sp, fcn.m_return,  monomorph_cb, false) );          // --- Apply bounds by adding them to the associated type ruleset -        apply_bounds_as_rules(context, sp, *cache.m_fcn_params, cache.m_monomorph_cb); +        apply_bounds_as_rules(context, sp, *cache.m_fcn_params, cache.m_monomorph_cb, /*is_impl_level=*/false);          return true;      } @@ -497,7 +506,7 @@ namespace {              };          // Add trait bounds for all impl and function bounds -        apply_bounds_as_rules(context, sp, impl_ptr->m_params, cache.m_monomorph_cb); +        apply_bounds_as_rules(context, sp, impl_ptr->m_params, cache.m_monomorph_cb, /*is_impl_level=*/true);          // Equate `Self` and `impl_ptr->m_type` (after monomorph)          { @@ -1256,7 +1265,7 @@ namespace {              }              // Convert bounds on the type into rules -            apply_bounds_as_rules(context, node.span(), *generics, monomorph_cb); +            apply_bounds_as_rules(context, node.span(), *generics, monomorph_cb, /*is_impl_level=*/true);              auto _ = this->push_inner_coerce_scoped(true);              for( auto& val : node.m_values ) { @@ -1283,7 +1292,7 @@ namespace {              auto monomorph_cb = monomorphise_type_get_cb(node.span(), &ty, &node.m_path.m_params, nullptr);              // Convert bounds on the type into rules -            apply_bounds_as_rules(context, node.span(), unm.m_params, monomorph_cb); +            apply_bounds_as_rules(context, node.span(), unm.m_params, monomorph_cb, /*is_impl_level=*/true);              auto it = ::std::find_if(unm.m_variants.begin(), unm.m_variants.end(), [&](const auto& v)->bool{ return v.first == node.m_variant_name; });              assert(it != unm.m_variants.end()); @@ -1589,7 +1598,7 @@ namespace {                      }                      // Apply bounds -                    apply_bounds_as_rules(this->context, sp, f.m_params, monomorph_cb); +                    apply_bounds_as_rules(this->context, sp, f.m_params, monomorph_cb, /*is_impl_level=*/false);                      auto ty = ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Function(mv$(ft)) );                      DEBUG("> " << node.m_path << " = " << ty); @@ -1610,7 +1619,7 @@ namespace {                      {                          ft.m_arg_types.push_back( monomorphise_type(sp, s.m_params, e.m_params, arg.ent) );                      } -                    //apply_bounds_as_rules(this->context, sp, s.m_params, monomorph_cb); +                    //apply_bounds_as_rules(this->context, sp, s.m_params, monomorph_cb, /*is_impl_level=*/true);                      auto ty = ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Function(mv$(ft)) );                      this->context.equate_types(sp, node.m_res_type, ty); @@ -1638,7 +1647,7 @@ namespace {                      {                          ft.m_arg_types.push_back( monomorphise_type(sp, enm.m_params, e.m_params, arg.ent) );                      } -                    //apply_bounds_as_rules(this->context, sp, enm.m_params, monomorph_cb); +                    //apply_bounds_as_rules(this->context, sp, enm.m_params, monomorph_cb, /*is_impl_level=*/true);                      auto ty = ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Function(mv$(ft)) );                      this->context.equate_types(sp, node.m_res_type, ty); @@ -1695,7 +1704,7 @@ namespace {                          };                      for(const auto& arg : ie.m_args)                          ft.m_arg_types.push_back( monomorphise_type_with(sp, arg.second,  monomorph_cb) ); -                    apply_bounds_as_rules(this->context, sp, ie.m_params, monomorph_cb); +                    apply_bounds_as_rules(this->context, sp, ie.m_params, monomorph_cb, /*is_impl_level=*/false);                      auto ty = ::HIR::TypeRef(mv$(ft));                      this->context.equate_types(node.span(), node.m_res_type, ty); @@ -1804,8 +1813,8 @@ namespace {                          };                      // Bounds (both impl and fn) -                    apply_bounds_as_rules(this->context, sp, impl_ptr->m_params, monomorph_cb); -                    apply_bounds_as_rules(this->context, sp, fcn_ptr->m_params, monomorph_cb); +                    apply_bounds_as_rules(this->context, sp, impl_ptr->m_params, monomorph_cb, /*is_impl_level=*/true); +                    apply_bounds_as_rules(this->context, sp, fcn_ptr->m_params, monomorph_cb, /*is_impl_level=*/false);                      ::HIR::FunctionType ft {                          fcn_ptr->m_unsafe, fcn_ptr->m_abi, @@ -1826,7 +1835,7 @@ namespace {                      ::HIR::TypeRef  tmp;                      const auto& ty = ( monomorphise_type_needed(const_ptr->m_type) ? tmp = monomorphise_type_with(sp, const_ptr->m_type, monomorph_cb) : const_ptr->m_type ); -                    apply_bounds_as_rules(this->context, sp, impl_ptr->m_params, monomorph_cb); +                    apply_bounds_as_rules(this->context, sp, impl_ptr->m_params, monomorph_cb, /*is_impl_level=*/true);                      this->context.equate_types(node.span(), node.m_res_type, ty);                  }                  ) @@ -4222,10 +4231,8 @@ void fix_param_count_(const Span& sp, Context& context, const ::HIR::TypeRef& se  {      if( params.m_types.size() == param_defs.m_types.size() ) {          // Nothing to do, all good -        return ;      } - -    if( params.m_types.size() > param_defs.m_types.size() ) { +    else if( params.m_types.size() > param_defs.m_types.size() ) {          ERROR(sp, E0000, "Too many type parameters passed to " << path);      }      else { @@ -4352,6 +4359,13 @@ namespace {              return CoerceResult::Equality;          } +        // Can't Unsize to a known-Sized type. +        if( dst.m_data.is_Infer() && dst.m_data.as_Infer().index < context.m_ivars_sized.size() && context.m_ivars_sized.at( dst.m_data.as_Infer().index ) ) +        { +            DEBUG("Can't unsize to known-Sized type"); +            return CoerceResult::Equality; +        } +          // Handle ivars specially          if(dst.m_data.is_Infer() && src.m_data.is_Infer())          { @@ -4757,6 +4771,8 @@ namespace {          if( TU_TEST1(src.m_data, Infer, .is_lit()) ) {              return CoerceResult::Equality;          } + +        // TODO: If the destination is bounded to be Sized, equate and return.          // If both sides are `_`, then can't know about coerce yet          if( dst.m_data.is_Infer() && src.m_data.is_Infer() ) {              // Add possibilities both ways @@ -6183,12 +6199,13 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR:          {              // Check the possible equations              DEBUG("--- IVar possibilities"); -            for(unsigned int i = 0; i < context.possible_ivar_vals.size(); i ++ ) +            for(unsigned int i = context.possible_ivar_vals.size(); i --; ) +            //for(unsigned int i = 0; i < context.possible_ivar_vals.size(); i ++ )              {                  if( check_ivar_poss(context, i, context.possible_ivar_vals[i]) ) {                      static Span sp;                      assert( context.possible_ivar_vals[i].has_rules() ); -                    // TODO: Disable all metioned ivars in the possibilities +                    // Disable all metioned ivars in the possibilities                      for(const auto& ty : context.possible_ivar_vals[i].types_coerce_to)                          context.equate_types_from_shadow(sp,ty);                      for(const auto& ty : context.possible_ivar_vals[i].types_unsize_to) @@ -6197,6 +6214,26 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR:                          context.equate_types_to_shadow(sp,ty);                      for(const auto& ty : context.possible_ivar_vals[i].types_unsize_from)                          context.equate_types_to_shadow(sp,ty); + +                    // Also disable inferrence (for this pass) for all ivars in affected bounds +                    for(const auto& la : context.link_assoc) +                    { +                        bool found = false; +                        auto cb = [&](const auto& t) { return TU_TEST1(t.m_data, Infer, .index == i); }; +                        if( la.left_ty != ::HIR::TypeRef() ) +                            found |= visit_ty_with( la.left_ty, cb ); +                        found |= visit_ty_with( la.impl_ty, cb ); +                        for(const auto& t : la.params.m_types) +                            found |= visit_ty_with( t, cb ); +                        if( found ) +                        { +                            if(la.left_ty != ::HIR::TypeRef()) +                                context.equate_types_shadow(sp, la.left_ty, false); +                            context.equate_types_shadow(sp, la.impl_ty, false); +                            for(const auto& t : la.params.m_types) +                                context.equate_types_shadow(sp, t, false); +                        } +                    }                  }                  else {                      //assert( !context.m_ivars.peek_changed() ); | 
