+getWantedEqExtra :: TvSubst -> TidyEnv -> CtOrigin -> TcType -> TcType
+ -> TcM (TidyEnv, SDoc)
+getWantedEqExtra subst env0 (TypeEqOrigin item) ty1 ty2
+ -- If the types in the error message are the same
+ -- as the types we are unifying (remember to zonk the latter)
+ -- don't add the extra expected/actual message
+ --
+ -- The complication is that the types in the TypeEqOrigin must
+ -- (a) be zonked
+ -- (b) have any TcS-monad pending equalities applied to them
+ -- (hence the passed-in substitution)
+ = do { (env1, act) <- zonkSubstTidy env0 subst (uo_actual item)
+ ; (env2, exp) <- zonkSubstTidy env1 subst (uo_expected item)
+ ; if (act `tcEqType` ty1 && exp `tcEqType` ty2)
+ || (exp `tcEqType` ty1 && act `tcEqType` ty2)
+ then
+ return (env0, empty)
+ else
+ return (env2, mkExpectedActualMsg act exp) }
+
+getWantedEqExtra _ env0 orig _ _
+ = return (env0, pprArising orig)
+
+zonkSubstTidy :: TidyEnv -> TvSubst -> TcType -> TcM (TidyEnv, TcType)
+-- In general, becore printing a type, we want to
+-- a) Zonk it. Even during constraint simplification this is
+-- is important, to un-flatten the flatten skolems in a type
+-- b) Substitute any solved unification variables. This is
+-- only important *during* solving, becuase after solving
+-- the substitution is expressed in the mutable type variables
+-- But during solving there may be constraint (F xi ~ ty)
+-- where the substitution has not been applied to the RHS
+zonkSubstTidy env subst ty
+ = do { ty' <- zonkTcTypeAndSubst subst ty
+ ; return (tidyOpenType env ty') }