summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2012-10-12 08:15:44 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2012-10-12 08:19:39 +0100
commitbeb2f7434feb63fef7f0a0993104253b4169ccad (patch)
tree579572d9072e46f04347421842e3940ca49ebf09
parent9991890d284272e03f95ad9995bf21ec56ec7524 (diff)
downloadhaskell-beb2f7434feb63fef7f0a0993104253b4169ccad.tar.gz
Be lazier when typechecking data type contexts (Trac #7321)
We should be lazy when type-checking the equality-contraint part of a data constructor's type, to make the knot-tying work out right. The fact that it's always worked before is a fluke: no one else wrote a GADT whose type index mentions itself data T a wher MkT :: T (T Int)
-rw-r--r--compiler/iface/TcIface.lhs25
1 files changed, 11 insertions, 14 deletions
diff --git a/compiler/iface/TcIface.lhs b/compiler/iface/TcIface.lhs
index 1efb11e21b..19b5cfe405 100644
--- a/compiler/iface/TcIface.lhs
+++ b/compiler/iface/TcIface.lhs
@@ -570,20 +570,17 @@ tcIfaceDataCons tycon_name tycon _ if_cons
= bindIfaceTyVars univ_tvs $ \ univ_tyvars -> do
bindIfaceTyVars ex_tvs $ \ ex_tyvars -> do
{ name <- lookupIfaceTop occ
- ; eq_spec <- tcIfaceEqSpec spec
- ; theta <- tcIfaceCtxt ctxt -- Laziness seems not worth the bother here
- -- At one stage I thought that this context checking *had*
- -- to be lazy, because of possible mutual recursion between the
- -- type and the classe:
- -- E.g.
- -- class Real a where { toRat :: a -> Ratio Integer }
- -- data (Real a) => Ratio a = ...
- -- But now I think that the laziness in checking class ops breaks
- -- the loop, so no laziness needed
-
- -- Read the argument types, but lazily to avoid faulting in
- -- the component types unless they are really needed
- ; arg_tys <- forkM (mk_doc name) (mapM tcIfaceType args)
+
+ -- Read the context and argument types, but lazily for two reasons
+ -- (a) to avoid looking tugging on a recursive use of
+ -- the type itself, which is knot-tied
+ -- (b) to avoid faulting in the component types unless
+ -- they are really needed
+ ; ~(eq_spec, theta, arg_tys) <- forkM (mk_doc name) $
+ do { eq_spec <- tcIfaceEqSpec spec
+ ; theta <- tcIfaceCtxt ctxt
+ ; arg_tys <- mapM tcIfaceType args
+ ; return (eq_spec, theta, arg_tys) }
; lbl_names <- mapM lookupIfaceTop field_lbls
-- Remember, tycon is the representation tycon