summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorsimonpj@microsoft.com <unknown>2010-10-08 11:12:27 +0000
committersimonpj@microsoft.com <unknown>2010-10-08 11:12:27 +0000
commitd39629e988c3eb2ef1def1e423a18dd1289a7a52 (patch)
tree27cfc2d1ec68ab482c5fe0f003df70bee64a67e5 /compiler
parenta66541af84d102f32b73fb7f89f48008c01092a6 (diff)
downloadhaskell-d39629e988c3eb2ef1def1e423a18dd1289a7a52.tar.gz
Fix Trac #4361: be more discerning when inferring types
Note [Avoid unecessary constraint simplification] in TcSimplify
Diffstat (limited to 'compiler')
-rw-r--r--compiler/typecheck/TcSimplify.lhs44
1 files changed, 41 insertions, 3 deletions
diff --git a/compiler/typecheck/TcSimplify.lhs b/compiler/typecheck/TcSimplify.lhs
index 48258ed011..f66cc07fa1 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: