summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-07-05 20:11:45 +0800
committerJohn Hodge <tpg@mutabah.net>2016-07-05 20:11:45 +0800
commitdde5cfa67d37cc89738205684d6c4c3e6988bf19 (patch)
tree050d7cd0c6027cae350ca7090009142903f2da41 /src
parent96452c8d486d1284b0846a13ae5624711f3b5485 (diff)
downloadmrust-dde5cfa67d37cc89738205684d6c4c3e6988bf19.tar.gz
HIR Typecheck CS - Draft listing of ivar options
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp78
-rw-r--r--src/hir_typeck/helpers.cpp5
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);
}