X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcBinds.lhs;h=aab8f012ac5eaf68857675df928ef340a0330ea6;hb=06f6f35dadc461336675e6d2b8a2192b1f518a1b;hp=93a90101575cfef04f905bb782e4cde01fa37d25;hpb=a8427a4125e9b78e88a487eeabf018f1c6e8bc08;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcBinds.lhs b/compiler/typecheck/TcBinds.lhs index 93a9010..aab8f01 100644 --- a/compiler/typecheck/TcBinds.lhs +++ b/compiler/typecheck/TcBinds.lhs @@ -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