X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcTyFuns.lhs;h=82e397f554cd23a23472bda17885983b9277cba8;hb=a010233a51a189fcef0fd94de4866f8bb5dd010b;hp=4e3f72835bc474af0595a75bf296434d5b56a9da;hpb=eb731f1519b868fa9686f2a56280dd1aaf8edc9d;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcTyFuns.lhs b/compiler/typecheck/TcTyFuns.lhs index 4e3f728..82e397f 100644 --- a/compiler/typecheck/TcTyFuns.lhs +++ b/compiler/typecheck/TcTyFuns.lhs @@ -11,7 +11,7 @@ module TcTyFuns ( substEqInDictInsts, -- errors - eqInstMisMatch, misMatchMsg, + misMatchMsg, failWithMisMatch ) where @@ -40,7 +40,7 @@ import Maybes -- standard import Data.List -import Control.Monad (liftM) +import Control.Monad \end{code} @@ -121,8 +121,10 @@ eqInstToRewrite :: Inst -> Maybe (Rewrite, Bool) -- True iff rewrite swapped equality eqInstToRewrite inst = ASSERT( isEqInst inst ) - go (eqInstLeftTy inst) (eqInstRightTy inst) (eqInstType inst) + go ty1 ty2 (eqInstType inst) where + (ty1,ty2) = eqInstTys inst + -- look through synonyms go ty1 ty2 co | Just ty1' <- tcView ty1 = go ty1' ty2 co go ty1 ty2 co | Just ty2' <- tcView ty2 = go ty1 ty2' co @@ -231,7 +233,7 @@ tcGenericNormaliseFamInst fun (ForAllTy tyvar ty1) } tcGenericNormaliseFamInst fun (NoteTy note ty1) = do { (coi,nty1) <- tcGenericNormaliseFamInst fun ty1 - ; return (mkNoteTyCoI note coi, NoteTy note nty1) + ; return (coi, NoteTy note nty1) } tcGenericNormaliseFamInst fun ty@(TyVarTy tv) | isTcTyVar tv @@ -386,14 +388,18 @@ normalise_dicts -- Fals <=> they are given -> TcM ([Inst],TcDictBinds) normalise_dicts given_eqs dicts is_wanted - = do { traceTc $ text "normalise???Dicts <-" <+> ppr dicts <+> + = do { traceTc $ let name | is_wanted = "normaliseWantedDicts <-" + | otherwise = "normaliseGivenDicts <-" + in + text name <+> ppr dicts <+> text "with" <+> ppr given_eqs ; (dicts0, binds0) <- normaliseInsts is_wanted dicts - ; (dicts1, binds1) <- substEqInDictInsts given_eqs dicts0 + ; (dicts1, binds1) <- substEqInDictInsts is_wanted given_eqs dicts0 ; let binds01 = binds0 `unionBags` binds1 ; if isEmptyBag binds1 then return (dicts1, binds01) - else do { (dicts2, binds2) <- normaliseGivenDicts given_eqs dicts1 + else do { (dicts2, binds2) <- + normalise_dicts given_eqs dicts1 is_wanted ; return (dicts2, binds01 `unionBags` binds2) } } \end{code} @@ -657,7 +663,7 @@ The following rules exploits the reflexivity of equality: \begin{code} trivialRule :: IdemRewriteRule trivialRule insts - = liftM catMaybes $ mappM trivial insts + = liftM catMaybes $ mapM trivial insts where trivial inst | ASSERT( isEqInst inst ) @@ -670,8 +676,7 @@ trivialRule insts | otherwise = return $ Just inst where - ty1 = eqInstLeftTy inst - ty2 = eqInstRightTy inst + (ty1,ty2) = eqInstTys inst \end{code} @@ -702,8 +707,9 @@ decompRule insts where decomp inst = ASSERT( isEqInst inst ) - go (eqInstLeftTy inst) (eqInstRightTy inst) + go ty1 ty2 where + (ty1,ty2) = eqInstTys inst go ty1 ty2 | Just ty1' <- tcView ty1 = go ty1' ty2 | Just ty2' <- tcView ty2 = go ty1 ty2' @@ -822,8 +828,7 @@ topRule insts } } where - ty1 = eqInstLeftTy inst - ty2 = eqInstRightTy inst + (ty1,ty2) = eqInstTys inst \end{code} @@ -921,8 +926,7 @@ substInst inst insts } } where - ty1 = eqInstLeftTy inst - ty2 = eqInstRightTy inst + (ty1,ty2) = eqInstTys inst \end{code} @@ -959,9 +963,10 @@ unifyMetaRule insts where unifyMeta inst = ASSERT( isEqInst inst ) - go (eqInstLeftTy inst) (eqInstRightTy inst) + go ty1 ty2 (fromWantedCo "unifyMetaRule" $ eqInstCoercion inst) where + (ty1,ty2) = eqInstTys inst go ty1 ty2 cotv | Just ty1' <- tcView ty1 = go ty1' ty2 cotv | Just ty2' <- tcView ty2 = go ty1 ty2' cotv @@ -1079,10 +1084,11 @@ form where F is a type family. \begin{code} -substEqInDictInsts :: [Inst] -- given equalities (used as rewrite rules) +substEqInDictInsts :: Bool -- whether the *dictionaries* are wanted/given + -> [Inst] -- given equalities (used as rewrite rules) -> [Inst] -- dictinaries to be normalised -> TcM ([Inst], TcDictBinds) -substEqInDictInsts eqInsts dictInsts +substEqInDictInsts isWanted eqInsts dictInsts = do { traceTc (text "substEqInDictInst <-" <+> ppr dictInsts) ; dictInsts' <- foldlM rewriteWithOneEquality (dictInsts, emptyBag) eqInsts @@ -1096,7 +1102,7 @@ substEqInDictInsts eqInsts dictInsts tci_right = target}) | isOpenSynTyConApp pattern || isTyVarTy pattern = do { (dictInsts', moreDictBinds) <- - genericNormaliseInsts True {- wanted -} applyThisEq dictInsts + genericNormaliseInsts isWanted applyThisEq dictInsts ; return (dictInsts', dictBinds `unionBags` moreDictBinds) } where @@ -1175,7 +1181,13 @@ genericNormaliseInsts isWanted fun insts rhs = L (instLocSpan loc) cast_expr binds = instToDictBind target_dict rhs -- return the new inst - ; traceTc $ text "genericNormaliseInst ->" <+> ppr dict' + ; traceTc $ let name | isWanted + = "genericNormaliseInst (wanted) ->" + | otherwise + = "genericNormaliseInst (given) ->" + in + text name <+> ppr dict' <+> + text "with" <+> ppr binds ; return (dict', binds) } } @@ -1183,6 +1195,8 @@ genericNormaliseInsts isWanted fun insts -- TOMDO: What do we have to do about ImplicInst, Method, and LitInst?? normaliseOneInst _isWanted _fun inst = do { inst' <- zonkInst inst + ; traceTc $ text "*** TcTyFuns.normaliseOneInst: Skipping" <+> + ppr inst ; return (inst', emptyBag) } \end{code} @@ -1201,45 +1215,49 @@ somethingdifferent message. eqInstMisMatch :: Inst -> TcM a eqInstMisMatch inst = ASSERT( isEqInst inst ) - do { (env, msg) <- misMatchMsg ty_act ty_exp - ; setErrCtxt ctxt $ - failWithTcM (env, msg) - } + setErrCtxt ctxt $ failWithMisMatch ty_act ty_exp where - ty_act = eqInstLeftTy inst - ty_exp = eqInstRightTy inst - InstLoc _ _ ctxt = instLoc inst + (ty_act, ty_exp) = eqInstTys inst + InstLoc _ _ ctxt = instLoc inst ----------------------- -misMatchMsg :: TcType -> TcType -> TcM (TidyEnv, SDoc) +failWithMisMatch :: TcType -> TcType -> TcM a -- Generate the message when two types fail to match, -- going to some trouble to make it helpful. -- The argument order is: actual type, expected type -misMatchMsg ty_act ty_exp +failWithMisMatch ty_act ty_exp = do { env0 <- tcInitTidyEnv ; ty_exp <- zonkTcType ty_exp ; ty_act <- zonkTcType ty_act - ; (env1, pp_exp, extra_exp) <- ppr_ty env0 ty_exp - ; (env2, pp_act, extra_act) <- ppr_ty env1 ty_act - ; return (env2, - sep [sep [ptext SLIT("Couldn't match expected type") <+> pp_exp, - nest 7 $ + ; failWithTcM (misMatchMsg env0 (ty_act, ty_exp)) + } + +misMatchMsg :: TidyEnv -> (TcType, TcType) -> (TidyEnv, SDoc) +misMatchMsg env0 (ty_act, ty_exp) + = let (env1, pp_exp, extra_exp) = ppr_ty env0 ty_exp + (env2, pp_act, extra_act) = ppr_ty env1 ty_act + msg = sep [sep [ptext SLIT("Couldn't match expected type") <+> pp_exp, + nest 7 $ ptext SLIT("against inferred type") <+> pp_act], - nest 2 (extra_exp $$ extra_act)]) } - -ppr_ty :: TidyEnv -> TcType -> TcM (TidyEnv, SDoc, SDoc) -ppr_ty env ty - = do { let (env1, tidy_ty) = tidyOpenType env ty - ; (env2, extra) <- ppr_extra env1 tidy_ty - ; return (env2, quotes (ppr tidy_ty), extra) } - --- (ppr_extra env ty) shows extra info about 'ty' -ppr_extra :: TidyEnv -> Type -> TcM (TidyEnv, SDoc) -ppr_extra env (TyVarTy tv) - | isTcTyVar tv && (isSkolemTyVar tv || isSigTyVar tv) - = return (env1, pprSkolTvBinding tv1) + nest 2 (extra_exp $$ extra_act)] + in + (env2, msg) + where - (env1, tv1) = tidySkolemTyVar env tv + ppr_ty :: TidyEnv -> TcType -> (TidyEnv, SDoc, SDoc) + ppr_ty env ty + = let (env1, tidy_ty) = tidyOpenType env ty + (env2, extra) = ppr_extra env1 tidy_ty + in + (env2, quotes (ppr tidy_ty), extra) + + -- (ppr_extra env ty) shows extra info about 'ty' + ppr_extra :: TidyEnv -> Type -> (TidyEnv, SDoc) + ppr_extra env (TyVarTy tv) + | isTcTyVar tv && (isSkolemTyVar tv || isSigTyVar tv) && not (isUnk tv) + = (env1, pprSkolTvBinding tv1) + where + (env1, tv1) = tidySkolemTyVar env tv -ppr_extra env _ty = return (env, empty) -- Normal case + ppr_extra env _ty = (env, empty) -- Normal case \end{code}