X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcTyFuns.lhs;h=4c5be1c8993ce7d226b2bcc797d1a56eb7ad36a9;hb=183839ef216ee152d1c150641fed1120bc50f95a;hp=d7da2f76e5ee3d5d3633e30454e26876b65b437e;hpb=2e68d0410f319a99f3f36c5e9d9be656ca10dc70;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcTyFuns.lhs b/compiler/typecheck/TcTyFuns.lhs index d7da2f7..4c5be1c 100644 --- a/compiler/typecheck/TcTyFuns.lhs +++ b/compiler/typecheck/TcTyFuns.lhs @@ -7,8 +7,6 @@ module TcTyFuns ( normaliseGivenEqs, normaliseGivenDicts, normaliseWantedEqs, normaliseWantedDicts, - solveWantedEqs, - substEqInDictInsts, -- errors misMatchMsg, failWithMisMatch @@ -37,10 +35,11 @@ import Bag import Outputable import SrcLoc ( Located(..) ) import Maybes +import FastString -- standard import Data.List -import Control.Monad (liftM) +import Control.Monad \end{code} @@ -231,10 +230,6 @@ tcGenericNormaliseFamInst fun (ForAllTy tyvar ty1) = do { (coi,nty1) <- tcGenericNormaliseFamInst fun ty1 ; return (mkForAllTyCoI tyvar coi, mkForAllTy tyvar nty1) } -tcGenericNormaliseFamInst fun (NoteTy note ty1) - = do { (coi,nty1) <- tcGenericNormaliseFamInst fun ty1 - ; return (mkNoteTyCoI note coi, NoteTy note nty1) - } tcGenericNormaliseFamInst fun ty@(TyVarTy tv) | isTcTyVar tv = do { traceTc (text "tcGenericNormaliseFamInst" <+> ppr ty) @@ -311,38 +306,12 @@ normaliseGivenEqs givens \end{code} \begin{code} -normaliseWantedEqs :: [Inst] -> TcM [Inst] -normaliseWantedEqs insts - = do { traceTc (text "normaliseWantedEqs <-" <+> ppr insts) - ; result <- liftM fst $ rewriteToFixedPoint Nothing - [ ("(ZONK)", dontRerun $ zonkInsts) - , ("(TRIVIAL)", dontRerun $ trivialRule) - , ("(DECOMP)", decompRule) - , ("(TOP)", topRule) - , ("(UNIFY)", unifyMetaRule) -- incl. occurs check - , ("(SUBST)", substRule) -- incl. occurs check - ] insts - ; traceTc (text "normaliseWantedEqs ->" <+> ppr result) - ; return result - } -\end{code} - - -%************************************************************************ -%* * -\section{Solving of wanted constraints with respect to a given set} -%* * -%************************************************************************ - -The set of given equalities must have been normalised already. - -\begin{code} -solveWantedEqs :: [Inst] -- givens - -> [Inst] -- wanteds - -> TcM [Inst] -- irreducible wanteds -solveWantedEqs givens wanteds - = do { traceTc $ text "solveWantedEqs <-" <+> ppr wanteds <+> text "with" <+> - ppr givens +normaliseWantedEqs :: [Inst] -- givens + -> [Inst] -- wanteds + -> TcM [Inst] -- irreducible wanteds +normaliseWantedEqs givens wanteds + = do { traceTc $ text "normaliseWantedEqs <-" <+> ppr wanteds + <+> text "with" <+> ppr givens ; result <- liftM fst $ rewriteToFixedPoint Nothing [ ("(ZONK)", dontRerun $ zonkInsts) , ("(TRIVIAL)", dontRerun $ trivialRule) @@ -350,8 +319,9 @@ solveWantedEqs givens wanteds , ("(TOP)", topRule) , ("(GIVEN)", substGivens givens) -- incl. occurs check , ("(UNIFY)", unifyMetaRule) -- incl. occurs check + , ("(SUBST)", substRule) -- incl. occurs check ] wanteds - ; traceTc (text "solveWantedEqs ->" <+> ppr result) + ; traceTc (text "normaliseWantedEqs ->" <+> ppr result) ; return result } where @@ -388,14 +358,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} @@ -659,7 +633,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 ) @@ -982,26 +956,30 @@ unifyMetaRule insts uMeta _swapped _tv (IndirectTv _) _ty _cotv = return ([inst], False) - -- signature skolem meets non-variable type - -- => cannot update! - uMeta _swapped _tv (DoneTv (MetaTv (SigTv _) _)) ty _cotv - | not $ isTyVarTy ty - = return ([inst], False) - -- type variable meets type variable -- => check that tv2 hasn't been updated yet and choose which to update uMeta swapped tv1 (DoneTv details1) (TyVarTy tv2) cotv + | tv1 == tv2 + = return ([inst], False) -- The two types are already identical + + | otherwise = do { lookupTV2 <- lookupTcTyVar tv2 ; case lookupTV2 of - IndirectTv ty -> uMeta swapped tv1 (DoneTv details1) ty cotv - DoneTv details2 -> - uMetaVar swapped tv1 details1 tv2 details2 cotv + IndirectTv ty -> uMeta swapped tv1 (DoneTv details1) ty cotv + DoneTv details2 -> uMetaVar swapped tv1 details1 tv2 details2 cotv } + ------ Beyond this point we know that ty2 is not a type variable + + -- signature skolem meets non-variable type + -- => cannot update! + uMeta _swapped _tv (DoneTv (MetaTv (SigTv _) _)) _non_tv_ty _cotv + = return ([inst], False) + -- updatable meta variable meets non-variable type -- => occurs check, monotype check, and kinds match check, then update - uMeta swapped tv (DoneTv (MetaTv _ ref)) ty cotv - = do { mb_ty' <- checkTauTvUpdate tv ty -- occurs + monotype check + uMeta swapped tv (DoneTv (MetaTv _ ref)) non_tv_ty cotv + = do { mb_ty' <- checkTauTvUpdate tv non_tv_ty -- occurs + monotype check ; case mb_ty' of Nothing -> return ([inst], False) -- tv occurs in faminst Just ty' -> @@ -1013,6 +991,7 @@ unifyMetaRule insts uMeta _ _ _ _ _ = panic "uMeta" + -- uMetaVar: unify two type variables -- meta variable meets skolem -- => just update uMetaVar swapped tv1 (MetaTv _ ref) tv2 (SkolemTv _) cotv @@ -1080,10 +1059,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 @@ -1097,7 +1077,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 @@ -1172,11 +1152,17 @@ genericNormaliseInsts isWanted fun insts -- else -- dict' = dict `cast` co expr = HsVar $ instToId source_dict - cast_expr = HsWrap (WpCo st_co) expr + cast_expr = HsWrap (WpCast st_co) expr 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) } } @@ -1184,6 +1170,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} @@ -1223,9 +1211,9 @@ 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, + msg = sep [sep [ptext (sLit "Couldn't match expected type") <+> pp_exp, nest 7 $ - ptext SLIT("against inferred type") <+> pp_act], + ptext (sLit "against inferred type") <+> pp_act], nest 2 (extra_exp $$ extra_act)] in (env2, msg)