diff options
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 89 |
1 files changed, 58 insertions, 31 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 90146635..423ad3a1 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -45,6 +45,7 @@ struct Context class Revisitor { public: + virtual const Span& span() const = 0; virtual void fmt(::std::ostream& os) const = 0; virtual bool revisit(Context& context, bool is_fallback) = 0; }; @@ -3809,11 +3810,15 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T m_outer_mode(binding_mode) {} + const Span& span() const override { + return sp; + } void fmt(::std::ostream& os) const override { os << "MatchErgonomicsRevisit { " << m_pattern << " : " << m_outer_ty << " }"; } bool revisit(Context& context, bool is_fallback_mode) override { TRACE_FUNCTION_F("Match ergonomics - " << m_pattern << " : " << m_outer_ty << (is_fallback_mode ? " (fallback)": "")); + m_outer_ty = context.m_resolve.expand_associated_types(sp, mv$(m_outer_ty)); return this->revisit_inner_real(context, m_pattern, m_outer_ty, m_outer_mode, is_fallback_mode); } // TODO: Recurse into inner patterns, creating new revisitors? @@ -3876,7 +3881,8 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T n_deref ++; } DEBUG("- " << n_deref << " derefs of class " << bt << " to get " << *ty_p); - if( ty_p->m_data.is_Infer() ) { + if( ty_p->m_data.is_Infer() || TU_TEST1(ty_p->m_data, Path, .binding.is_Unbound()) ) + { // Still pure infer, can't do anything // - What if it's a literal? @@ -3957,11 +3963,6 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T MatchErgonomicsRevisit::disable_possibilities_on_bindings(sp, context, pattern); return false; } - if( TU_TEST1(ty_p->m_data, Path, .binding.is_Unbound()) ) { - // TODO: Visit all inner bindings and disable coercion fallbacks on them. - MatchErgonomicsRevisit::disable_possibilities_on_bindings(sp, context, pattern); - return false; - } const auto& ty = *ty_p; // Here we have a known type and binding mode for this pattern @@ -4092,14 +4093,20 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T ASSERT_BUG(sp, str.m_data.is_Tuple(), "Struct-tuple pattern on non-Tuple struct"); const auto& sd = str.m_data.as_Tuple(); const auto& params = e.path.m_params; + ::HIR::TypeRef tmp; + auto maybe_monomorph = [&](const ::HIR::TypeRef& field_type)->const ::HIR::TypeRef& { + return (monomorphise_type_needed(field_type) + ? (tmp = context.m_resolve.expand_associated_types(sp, monomorphise_type(sp, str.m_params, params, field_type))) + : field_type + ); + }; rv = true; for( unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) { /*const*/ auto& sub_pat = e.sub_patterns[i]; const auto& field_type = sd[i].ent; - ::HIR::TypeRef tmp; - const auto& var_ty = (monomorphise_type_needed(field_type) ? (tmp = monomorphise_type(sp, str.m_params, params, field_type)) : field_type); + const auto& var_ty = maybe_monomorph(field_type); rv &= this->revisit_inner(context, sub_pat, var_ty, binding_mode); } } @@ -4122,6 +4129,14 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T const auto& sd = str.m_data.as_Named(); const auto& params = e.path.m_params; + ::HIR::TypeRef tmp; + auto maybe_monomorph = [&](const ::HIR::TypeRef& field_type)->const ::HIR::TypeRef& { + return (monomorphise_type_needed(field_type) + ? (tmp = context.m_resolve.expand_associated_types(sp, monomorphise_type(sp, str.m_params, params, field_type))) + : field_type + ); + }; + rv = true; for( auto& field_pat : e.sub_patterns ) { @@ -4129,14 +4144,8 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T if( f_idx == sd.size() ) { ERROR(sp, E0000, "Struct " << e.path << " doesn't have a field " << field_pat.first); } - const ::HIR::TypeRef& field_type = sd[f_idx].second.ent; - if( monomorphise_type_needed(field_type) ) { - auto field_type_mono = monomorphise_type(sp, str.m_params, params, field_type); - rv &= this->revisit_inner(context, field_pat.second, field_type_mono, binding_mode); - } - else { - rv &= this->revisit_inner(context, field_pat.second, field_type, binding_mode); - } + const ::HIR::TypeRef& field_type = maybe_monomorph(sd[f_idx].second.ent); + rv &= this->revisit_inner(context, field_pat.second, field_type, binding_mode); } } } @@ -4155,6 +4164,14 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T const auto& params = e.path.m_params; + ::HIR::TypeRef tmp; + auto maybe_monomorph = [&](const ::HIR::TypeRef& field_type)->const ::HIR::TypeRef& { + return (monomorphise_type_needed(field_type) + ? (tmp = context.m_resolve.expand_associated_types(sp, monomorphise_type(sp, str.m_params, params, field_type))) + : field_type + ); + }; + if( e.sub_patterns.size() != tup_var.size() ) { ERROR(sp, E0000, "Enum pattern with an incorrect number of fields - " << e.path << " - expected " << tup_var.size() << ", got " << e.sub_patterns.size() ); } @@ -4162,13 +4179,8 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T rv = true; // &= below ensures that all must be complete to return complete for( unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) { - if( monomorphise_type_needed(tup_var[i].ent) ) { - auto var_ty = monomorphise_type(sp, enm.m_params, params, tup_var[i].ent); - rv &= this->revisit_inner(context, e.sub_patterns[i], var_ty, binding_mode); - } - else { - rv &= this->revisit_inner(context, e.sub_patterns[i], tup_var[i].ent, binding_mode); - } + const auto& var_ty = maybe_monomorph(tup_var[i].ent); + rv &= this->revisit_inner(context, e.sub_patterns[i], var_ty, binding_mode); } } TU_ARM(pattern.m_data, EnumStruct, e) { @@ -4181,6 +4193,14 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T const auto& tup_var = str.m_data.as_Named(); const auto& params = e.path.m_params; + ::HIR::TypeRef tmp; + auto maybe_monomorph = [&](const ::HIR::TypeRef& field_type)->const ::HIR::TypeRef& { + return (monomorphise_type_needed(field_type) + ? (tmp = context.m_resolve.expand_associated_types(sp, monomorphise_type(sp, str.m_params, params, field_type))) + : field_type + ); + }; + rv = true; // &= below ensures that all must be complete to return complete for( auto& field_pat : e.sub_patterns ) { @@ -4188,14 +4208,8 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T if( f_idx == tup_var.size() ) { ERROR(sp, E0000, "Enum variant " << e.path << " doesn't have a field " << field_pat.first); } - const ::HIR::TypeRef& field_type = tup_var[f_idx].second.ent; - if( monomorphise_type_needed(field_type) ) { - auto field_type_mono = monomorphise_type(sp, enm.m_params, params, field_type); - rv &= this->revisit_inner(context, field_pat.second, field_type_mono, binding_mode); - } - else { - rv &= this->revisit_inner(context, field_pat.second, field_type, binding_mode); - } + const ::HIR::TypeRef& field_type = maybe_monomorph(tup_var[f_idx].second.ent); + rv &= this->revisit_inner(context, field_pat.second, field_type, binding_mode); } } } @@ -4510,6 +4524,9 @@ void Context::handle_pattern_direct_inner(const Span& sp, ::HIR::Pattern& pat, c m_pat_total_size(pat_total_size) {} + const Span& span() const override { + return sp; + } void fmt(::std::ostream& os) const override { os << "SplitTuplePatRevisit { " << m_outer_ty << " = (" << m_leading_tys << ", ..., " << m_trailing_tys << ") }"; } @@ -4566,6 +4583,9 @@ void Context::handle_pattern_direct_inner(const Span& sp, ::HIR::Pattern& pat, c sp(mv$(sp)), inner(mv$(inner)), type(mv$(type)), size(size) {} + const Span& span() const override { + return sp; + } void fmt(::std::ostream& os) const override { os << "SlicePatRevisit { " << inner << ", " << type << ", " << size; } bool revisit(Context& context, bool is_fallback) override { const auto& ty = context.get_type(type); @@ -4641,6 +4661,9 @@ void Context::handle_pattern_direct_inner(const Span& sp, ::HIR::Pattern& pat, c sp(mv$(sp)), inner(mv$(inner)), type(mv$(type)), var_ty(mv$(var_ty)), min_size(size) {} + const Span& span() const override { + return sp; + } void fmt(::std::ostream& os) const override { os << "SplitSlice inner=" << inner << ", outer=" << type << ", binding="<<var_ty<<", " << min_size; } bool revisit(Context& context, bool is_fallback) override { const auto& ty = context.get_type(this->type); @@ -7293,6 +7316,10 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: { } } + for(const auto& adv : context.adv_revisits) + { + WARNING(adv->span(), W0000, "Spare Rule - " << FMT_CB(os, adv->fmt(os))); + } BUG(root_ptr->span(), "Spare rules left after typecheck stabilised"); } DEBUG("root_ptr = " << typeid(*root_ptr).name() << " " << root_ptr->m_res_type); |