From d39629e988c3eb2ef1def1e423a18dd1289a7a52 Mon Sep 17 00:00:00 2001 From: "simonpj@microsoft.com" Date: Fri, 8 Oct 2010 11:12:27 +0000 Subject: [PATCH] Fix Trac #4361: be more discerning when inferring types Note [Avoid unecessary constraint simplification] in TcSimplify --- compiler/typecheck/TcSimplify.lhs | 44 ++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/compiler/typecheck/TcSimplify.lhs b/compiler/typecheck/TcSimplify.lhs index 48258ed..f66cc07 100644 --- a/compiler/typecheck/TcSimplify.lhs +++ b/compiler/typecheck/TcSimplify.lhs @@ -198,12 +198,26 @@ simplifyInfer apply_mr tau_tvs wanted , ptext (sLit "tau_tvs =") <+> ppr tau_tvs ] - ; (simple_wanted, tc_binds) - <- simplifyAsMuchAsPossible SimplInfer zonked_wanted + -- Make a guess at the quantified type variables + -- Then split the constraints on the baisis of those tyvars + -- to avoid unnecessarily simplifying a class constraint + -- See Note [Avoid unecessary constraint simplification] + ; gbl_tvs <- tcGetGlobalTyVars + ; zonked_tau_tvs <- zonkTcTyVarsAndFV tau_tvs + ; let proto_qtvs = zonked_tau_tvs `minusVarSet` gbl_tvs + (perhaps_bound, surely_free) + = partitionBag (quantifyMeWC proto_qtvs) zonked_wanted + ; emitConstraints surely_free + + -- Now simplify the possibly-bound constraints + ; (simplified_perhaps_bound, tc_binds) + <- simplifyAsMuchAsPossible SimplInfer perhaps_bound + -- Sigh: must re-zonk because because simplifyAsMuchAsPossible + -- may have done some unification ; gbl_tvs <- tcGetGlobalTyVars ; zonked_tau_tvs <- zonkTcTyVarsAndFV tau_tvs - ; zonked_simples <- mapBagM zonkWantedEvVar simple_wanted + ; zonked_simples <- mapBagM zonkWantedEvVar simplified_perhaps_bound ; let qtvs = findQuantifiedTyVars apply_mr zonked_simples zonked_tau_tvs gbl_tvs (bound, free) | apply_mr = (emptyBag, zonked_simples) | otherwise = partitionBag (quantifyMe qtvs) zonked_simples @@ -337,8 +351,32 @@ quantifyMe qtvs wev | otherwise = tyVarsOfPred pred `intersectsVarSet` qtvs where pred = wantedEvVarPred wev + +quantifyMeWC :: TyVarSet -> WantedConstraint -> Bool +quantifyMeWC qtvs (WcImplic implic) + = anyBag (quantifyMeWC (qtvs `minusVarSet` ic_skols implic)) (ic_wanted implic) +quantifyMeWC qtvs (WcEvVar wev) + = quantifyMe qtvs wev \end{code} +Note [Avoid unecessary constraint simplification] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When inferring the type of a let-binding, with simplifyInfer, +try to avoid unnecessariliy simplifying class constraints. +Doing so aids sharing, but it also helps with delicate +situations like + instance C t => C [t] where .. + f :: C [t] => .... + f x = let g y = ...(constraint C [t])... + in ... +When inferring a type for 'g', we don't want to apply the +instance decl, because then we can't satisfy (C t). So we +just notice that g isn't quantified over 't' and partition +the contraints before simplifying. + +This only half-works, but then let-generalisation only half-works. + + Note [Inheriting implicit parameters] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this: -- 1.7.10.4