summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-30 09:23:30 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-30 09:23:30 +0800
commit648da4ad68c903bb9bcfb8478675aac6e97ea937 (patch)
tree8c6fda53124cfa2170ffb877b49be9b90ed00211
parentd7174f22e22c1008cc434fcb9d2b700beb689751 (diff)
downloadmrust-648da4ad68c903bb9bcfb8478675aac6e97ea937.tar.gz
HIR Typecheck Expr - Don't do ivar possibilities on every pass, prevent possibilities on associated results
-rw-r--r--src/hir_typeck/expr_cs.cpp33
1 files changed, 26 insertions, 7 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index a3f82e07..e37f8a8a 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -4066,6 +4066,13 @@ namespace {
}
}
+ // If the output type is present, prevent it from being guessed
+ // - This generates an exact equation.
+ if( v.left_ty != ::HIR::TypeRef() )
+ {
+ context.equate_types_shadow(sp, v.left_ty);
+ }
+
// HACK! If the trait is `Unsize` then pretend `impl<T> Unsize<T> for T` exists to possibly propagate the type through
// - Also applies to CoerceUnsized (which may not get its impl detected because actually `T: !Unsize<T>`)
// - This is needed because `check_coerce` will emit coercions where they're not actually needed in some cases.
@@ -4562,15 +4569,27 @@ 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 nothing changed this pass, apply ivar possibilities
+ // - This essentially forces coercions not to happen.
+ if( ! context.m_ivars.peek_changed() )
+ {
+ // Check the possible equations
+ DEBUG("--- IVar possibilities");
+ unsigned int i = 0;
+ for(auto& ivar_ent : context.possible_ivar_vals)
+ {
+ check_ivar_poss(context, i, ivar_ent);
+ i ++ ;
+ }
+ }
+ else
{
- check_ivar_poss(context, i, ivar_ent);
- i ++ ;
+ // Clear ivar possibilities for next pass
+ for(auto& ivar_ent : context.possible_ivar_vals)
+ {
+ ivar_ent = Context::IVarPossible {};
+ }
}
-
// Finally. If nothing changed, apply ivar defaults
if( !context.m_ivars.peek_changed() )