diff options
author | John Hodge <tpg@mutabah.net> | 2016-07-05 20:11:45 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-07-05 20:11:45 +0800 |
commit | dde5cfa67d37cc89738205684d6c4c3e6988bf19 (patch) | |
tree | 050d7cd0c6027cae350ca7090009142903f2da41 /src | |
parent | 96452c8d486d1284b0846a13ae5624711f3b5485 (diff) | |
download | mrust-dde5cfa67d37cc89738205684d6c4c3e6988bf19.tar.gz |
HIR Typecheck CS - Draft listing of ivar options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 78 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 5 |
2 files changed, 79 insertions, 4 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index b848c5cc..8aeca858 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -50,6 +50,11 @@ struct Context } }; + struct IVarPossible + { + ::std::vector<const ::HIR::TypeRef*> types; + }; + const ::HIR::Crate& m_crate; ::std::vector<Binding> m_bindings; @@ -61,6 +66,8 @@ struct Context /// Nodes that need revisiting (e.g. method calls when the receiver isn't known) ::std::vector< ::HIR::ExprNode*> to_visit; + ::std::vector< IVarPossible> possible_ivar_vals; + Context(const ::HIR::Crate& crate, const ::HIR::GenericParams* impl_params, const ::HIR::GenericParams* item_params): m_crate(crate), m_resolve(m_ivars, crate, impl_params, item_params) @@ -83,8 +90,11 @@ struct Context void equate_types(const Span& sp, const ::HIR::TypeRef& l, const ::HIR::TypeRef& r); // - Equate two types, allowing inferrence void equate_types_coerce(const Span& sp, const ::HIR::TypeRef& l, ::HIR::ExprNodeP& node_ptr); - // - Equate + // - Equate a type to an associated type (if name == "", no equation is done, but trait is searched) void equate_types_assoc(const Span& sp, const ::HIR::TypeRef& l, const ::HIR::SimplePath& trait, ::std::vector< ::HIR::TypeRef> ty_args, const ::HIR::TypeRef& impl_ty, const char *name); + + // - List `t` as a possible type for `ivar_index` + void possible_equate_type(unsigned int ivar_index, const ::HIR::TypeRef& t); // - Add a pattern binding (forcing the type to match) void add_binding(const Span& sp, ::HIR::Pattern& pat, ::HIR::TypeRef& type); @@ -1851,6 +1861,13 @@ void Context::add_revisit(::HIR::ExprNode& node) { this->to_visit.push_back( &node ); } +void Context::possible_equate_type(unsigned int ivar_index, const ::HIR::TypeRef& t) { + if( ivar_index >= possible_ivar_vals.size() ) { + possible_ivar_vals.resize( ivar_index + 1 ); + } + possible_ivar_vals[ivar_index].types.push_back( &t ); +} + void Context::add_var(unsigned int index, const ::std::string& name, ::HIR::TypeRef type) { if( m_bindings.size() <= index ) m_bindings.resize(index+1); @@ -1924,6 +1941,7 @@ namespace { context.equate_types(sp, ty_dst, ty_src); return true; } + context.possible_equate_type(r_e.index, ty_dst); return false; ) @@ -2036,6 +2054,8 @@ namespace { } // Can't do anything yet? // - Later code can handle "only path" coercions + + context.possible_equate_type(l_e.index, ty_r); return false; ), (Diverge, @@ -2105,6 +2125,8 @@ namespace { context.equate_types(sp, ty, ty_r); BUG(sp, "Type error expected " << ty << " == " << ty_r); } + + context.possible_equate_type(r_e.index, ty); return false; ) else { @@ -2148,6 +2170,7 @@ namespace { BUG(sp, "Type error expected " << ty << " == " << ty_r); } // Can't do much for now + context.possible_equate_type(r_e.index, ty); return false; ) else { @@ -2202,11 +2225,13 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: unsigned int count = 0; while( context.take_changed() && context.has_rules() && count < MAX_ITERATIONS ) { - DEBUG("=== PASS " << count << " ==="); + TRACE_FUNCTION_F("=== PASS " << count << " ==="); context.dump(); // 1. Check coercions for ones that cannot coerce due to RHS type (e.g. `str` which doesn't coerce to anything) // 2. (???) Locate coercions that cannot coerce (due to being the only way to know a type) + // - Keep a list in the ivar of what types that ivar could be equated to. + DEBUG("--- Coercion checking"); for(auto it = context.link_coerce.begin(); it != context.link_coerce.end(); ) { if( check_coerce(context, *it) ) { DEBUG("- Consumed coercion " << it->left_ty << " := " << (**it->right_node_ptr).m_res_type); @@ -2217,6 +2242,7 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: } } // 3. Check associated type rules + DEBUG("--- Associated types"); for(auto it = context.link_assoc.begin(); it != context.link_assoc.end(); ) { if( check_associated(context, *it) ) { DEBUG("- Consumed associated type rule - " << *it); @@ -2227,6 +2253,7 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: } } // 4. Revisit nodes that require revisiting + DEBUG("--- Node revisits"); for( auto it = context.to_visit.begin(); it != context.to_visit.end(); ) { ::HIR::ExprNode& node = **it; @@ -2242,7 +2269,54 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: } } + // Check the possible equations + DEBUG("--- IVar possibilities"); + unsigned int i = 0; + for(auto& ivar_ent : context.possible_ivar_vals) + { + if( ivar_ent.types.size() == 0 ) { + // No idea! (or unused) + i ++ ; + continue ; + } + else if( ivar_ent.types.size() > 1 ) { + // De-duplicate list (taking into account other ivars) + for( auto it = ivar_ent.types.begin(); it != ivar_ent.types.end(); ) + { + bool found = false; + for( auto it2 = ivar_ent.types.begin(); it2 != it; ++ it2 ) { + if( context.m_ivars.types_equal( **it, **it2 ) ) { + found = true; + break; + } + } + if( found ) { + it = ivar_ent.types.erase(it); + } + else { + ++ it; + } + } + } + else { + // One possibility, no need to dedup + } + + if( ivar_ent.types.size() == 1 ) { + const ::HIR::TypeRef& ty_r = *ivar_ent.types[0]; + ::HIR::TypeRef ty_l; + ty_l.m_data.as_Infer().index = i; + // Only one possibility + DEBUG("- IVar " << ty_l << " = " << ty_r); + context.equate_types(Span(), ty_l, ty_r); + } + + ivar_ent.types.clear(); + i ++ ; + } + count ++; + context.m_ivars.compact_ivars(); } // - Validate typeck diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index e7d20223..bad7e81a 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -262,12 +262,13 @@ void HMTypeInferrence::dump() const } void HMTypeInferrence::compact_ivars() { - #if 0 + #if 1 unsigned int i = 0; for(auto& v : m_ivars) { if( !v.is_alias() ) { - auto nt = this->expand_associated_types(Span(), v.type->clone()); + //auto nt = this->expand_associated_types(Span(), v.type->clone()); + auto nt = v.type->clone(); DEBUG("- " << i << " " << *v.type << " -> " << nt); *v.type = mv$(nt); } |