normaliseGivenEqs, normaliseGivenDicts,
normaliseWantedEqs, normaliseWantedDicts,
- solveWantedEqs,
- substEqInDictInsts,
-- errors
misMatchMsg, failWithMisMatch
import Outputable
import SrcLoc ( Located(..) )
import Maybes
+import FastString
-- standard
import Data.List
= 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 (coi, NoteTy note nty1)
- }
tcGenericNormaliseFamInst fun ty@(TyVarTy tv)
| isTcTyVar tv
= do { traceTc (text "tcGenericNormaliseFamInst" <+> ppr ty)
\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)
, ("(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
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' ->
uMeta _ _ _ _ _ = panic "uMeta"
+ -- uMetaVar: unify two type variables
-- meta variable meets skolem
-- => just update
uMetaVar swapped tv1 (MetaTv _ ref) tv2 (SkolemTv _) cotv
-- 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
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)