Reorganise TcSimplify (again); FIX Trac #1919
[ghc-hetmet.git] / compiler / typecheck / TcBinds.lhs
index 93a9010..aab8f01 100644 (file)
@@ -5,6 +5,13 @@
 \section[TcBinds]{TcBinds}
 
 \begin{code}
+{-# OPTIONS -w #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and fix
+-- any warnings in the module. See
+--     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
+-- for details
+
 module TcBinds ( tcLocalBinds, tcTopBinds, 
                 tcHsBootSigs, tcMonoBinds, 
                 TcPragFun, tcSpecPrag, tcPrags, mkPragFun, 
@@ -30,11 +37,12 @@ import TcPat
 import TcMType
 import TcType
 import {- Kind parts of -} Type
+import Coercion
 import VarEnv
 import TysPrim
 import Id
 import IdInfo
-import Var ( TyVar )
+import Var ( TyVar, varType )
 import Name
 import NameSet
 import NameEnv
@@ -241,7 +249,7 @@ tc_haskell98 top_lvl sig_fn prag_fn rec_flag binds thing_inside
 bindLocalInsts :: TopLevelFlag -> TcM ([LHsBinds TcId], [TcId], a) -> TcM ([LHsBinds TcId], a)
 bindLocalInsts top_lvl thing_inside
   | isTopLevel top_lvl = do { (binds, ids, thing) <- thing_inside; return (binds, thing) }
-       -- For the top level don't bother will all this bindInstsOfLocalFuns stuff. 
+       -- For the top level don't bother with all this bindInstsOfLocalFuns stuff. 
        -- All the top level things are rec'd together anyway, so it's fine to
        -- leave them to the tcSimplifyTop, and quite a bit faster too
 
@@ -336,15 +344,15 @@ tcPolyBinds top_lvl sig_fn prag_fn rec_group rec_tc binds
           generalise dflags top_lvl bind_list sig_fn mono_bind_infos lie_req
 
        -- BUILD THE POLYMORPHIC RESULT IDs
-  ; let dict_ids = map instToId dicts
-  ; exports <- mapM (mkExport top_lvl prag_fn tyvars_to_gen (map idType dict_ids))
+  ; let dict_vars = map instToVar dicts        -- May include equality constraints
+  ; exports <- mapM (mkExport top_lvl prag_fn tyvars_to_gen (map varType dict_vars))
                    mono_bind_infos
 
   ; let        poly_ids = [poly_id | (_, poly_id, _, _) <- exports]
   ; traceTc (text "binding:" <+> ppr (poly_ids `zip` map idType poly_ids))
 
   ; let abs_bind = L loc $ AbsBinds tyvars_to_gen
-                                   dict_ids exports
+                                   dict_vars exports
                                    (dict_binds `unionBags` binds')
 
   ; return ([unitBag abs_bind], poly_ids)      -- poly_ids are guaranteed zonked by mkExport
@@ -370,17 +378,18 @@ mkExport top_lvl prag_fn inferred_tvs dict_tys (poly_name, mb_sig, mono_id)
   = do { warn_missing_sigs <- doptM Opt_WarnMissingSigs
        ; let warn = isTopLevel top_lvl && warn_missing_sigs
        ; (tvs, poly_id) <- mk_poly_id warn mb_sig
+               -- poly_id has a zonked type
 
-       ; poly_id' <- zonkId poly_id
-       ; prags <- tcPrags poly_id' (prag_fn poly_name)
+       ; prags <- tcPrags poly_id (prag_fn poly_name)
                -- tcPrags requires a zonked poly_id
 
-       ; return (tvs, poly_id', mono_id, prags) }
+       ; return (tvs, poly_id, mono_id, prags) }
   where
     poly_ty = mkForAllTys inferred_tvs (mkFunTys dict_tys (idType mono_id))
 
-    mk_poly_id warn Nothing    = do { missingSigWarn warn poly_name poly_ty
-                                   ; return (inferred_tvs, mkLocalId poly_name poly_ty) }
+    mk_poly_id warn Nothing    = do { poly_ty' <- zonkTcType poly_ty
+                                   ; missingSigWarn warn poly_name poly_ty'
+                                   ; return (inferred_tvs, mkLocalId poly_name poly_ty') }
     mk_poly_id warn (Just sig) = do { tvs <- mapM zonk_tv (sig_tvs sig)
                                    ; return (tvs,  sig_id sig) }
 
@@ -415,8 +424,9 @@ tcPrag poly_id (InlineSig v inl)             = return (InlinePrag inl)
 
 tcSpecPrag :: TcId -> LHsType Name -> InlineSpec -> TcM Prag
 tcSpecPrag poly_id hs_ty inl
-  = do { spec_ty <- tcHsSigType (FunSigCtxt (idName poly_id)) hs_ty
-       ; (co_fn, lie) <- getLIE (tcSubExp (idType poly_id) spec_ty)
+  = do { let name = idName poly_id
+       ; spec_ty <- tcHsSigType (FunSigCtxt name) hs_ty
+       ; (co_fn, lie) <- getLIE (tcSubExp (SpecPragOrigin name) (idType poly_id) spec_ty)
        ; extendLIEs lie
        ; let const_dicts = map instToId lie
        ; return (SpecPrag (mkHsWrap co_fn (HsVar poly_id)) spec_ty const_dicts inl) }
@@ -732,9 +742,9 @@ generalise dflags top_lvl bind_list sig_fn mono_infos lie_req
   where
     bndrs   = bndrNames mono_infos
     sigs    = [sig | (_, Just sig, _) <- mono_infos]
-    tau_tvs = foldr (unionVarSet . exactTyVarsOfType . getMonoType) emptyVarSet mono_infos
-               -- NB: exactTyVarsOfType; see Note [Silly type synonym] 
-               --     near defn of TcType.exactTyVarsOfType
+    get_tvs | isTopLevel top_lvl = tyVarsOfType         -- See Note [Silly type synonym] in TcType
+           | otherwise          = exactTyVarsOfType
+    tau_tvs = foldr (unionVarSet . get_tvs . getMonoType) emptyVarSet mono_infos
     is_mono_sig sig = null (sig_theta sig)
     doc = ptext SLIT("type signature(s) for") <+> pprBinders bndrs
 
@@ -769,7 +779,17 @@ unifyCtxts (sig1 : sigs)   -- Argument is always non-empty
     unify_ctxt sig@(TcSigInfo { sig_theta = theta })
        = setSrcSpan (instLocSpan (sig_loc sig))        $
          addErrCtxt (sigContextsCtxt sig1 sig)         $
-         unifyTheta theta1 theta
+         do { cois <- unifyTheta theta1 theta
+            ; -- Check whether all coercions are identity coercions
+              -- That can happen if we have, say
+              --         f :: C [a]   => ...
+              --         g :: C (F a) => ...
+              -- where F is a type function and (F a ~ [a])
+              -- Then unification might succeed with a coercion.  But it's much
+              -- much simpler to require that such signatures have identical contexts
+              checkTc (all isIdentityCoercion cois)
+                      (ptext SLIT("Mutually dependent functions have syntactically distinct contexts"))
+            }
 
 checkSigsTyVars :: [TcTyVar] -> [TcSigInfo] -> TcM [TcTyVar]
 checkSigsTyVars qtvs sigs