summaryrefslogtreecommitdiff
path: root/compiler/types/TypeRep.lhs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/types/TypeRep.lhs')
-rw-r--r--compiler/types/TypeRep.lhs44
1 files changed, 39 insertions, 5 deletions
diff --git a/compiler/types/TypeRep.lhs b/compiler/types/TypeRep.lhs
index ef035bb3e1..92ed53dec7 100644
--- a/compiler/types/TypeRep.lhs
+++ b/compiler/types/TypeRep.lhs
@@ -60,7 +60,7 @@ module TypeRep (
import {-# SOURCE #-} DataCon( dataConTyCon )
import ConLike ( ConLike(..) )
-import {-# SOURCE #-} Type( isPredTy ) -- Transitively pulls in a LOT of stuff, better to break the loop
+import {-# SOURCE #-} Type( isPredTy, cmpType ) -- Transitively pulls in a LOT of stuff, better to break the loop
-- friends:
import Var
@@ -77,10 +77,12 @@ import PrelNames
import Outputable
import FastString
import Util
+import ListSetOps
import DynFlags
-- libraries
-import Data.List( mapAccumL, partition )
+import Data.Function
+import Data.List( mapAccumL, partition, sortBy )
import qualified Data.Data as Data hiding ( TyCon )
\end{code}
@@ -533,7 +535,35 @@ pprClassPred clas tys = pprTypeApp (classTyCon clas) tys
------------
pprTheta :: ThetaType -> SDoc
-- pprTheta [pred] = pprPred pred -- I'm in two minds about this
-pprTheta theta = parens (sep (punctuate comma (map (ppr_type TopPrec) theta)))
+pprTheta theta = pprParenTheta sep theta
+
+pprParenTheta :: ([SDoc] -> SDoc) -> ThetaType -> SDoc
+pprParenTheta sepf theta = parens (sepf (punctuate comma preds))
+ where
+ (hasTriples, theta1) = partitionWith hasPred theta
+ theta0 = equivClasses (cmpType `on` fstOf3) hasTriples
+ preds = map pprTriples theta0 ++ map (ppr_type TopPrec) theta1
+
+ hasPred (TyConApp tc [r, LitTy (StrTyLit f), t])
+ | tc `hasKey` recordHasClassNameKey = Left (r, f, t)
+ hasPred p = Right p
+
+ pprTriples rfts@((r,_,_):_) = pprHasPred r (map (\ (_, f, t) -> (f, t)) rfts)
+ pprTriples [] = empty
+
+-- Pretty-print a bunch of Has constraints using the OverloadedRecordFields
+-- syntactic sugar, e.g
+-- (Has r "foo" Int, Has r "bar" (GetResult r "bar"))
+-- becomes
+-- r { foo :: Int, bar :: ... }
+pprHasPred :: Type -> [(FastString, Type)] -> SDoc
+pprHasPred r fs = pprParendType r <+> braces (sep (punctuate comma (map pprField fs')))
+ where
+ fs' = sortBy (compare `on` fst) fs
+ pprField (f, t) = (ftext f <+> ptext (sLit "::") <+> pprTypeOrDots f t)
+ pprTypeOrDots f (TyConApp tc [_, LitTy (StrTyLit f')])
+ | tc `hasKey` fldTyFamNameKey && f == f' = ptext (sLit "...")
+ pprTypeOrDots _ t = pprType t
pprThetaArrowTy :: ThetaType -> SDoc
pprThetaArrowTy [] = empty
@@ -541,8 +571,7 @@ pprThetaArrowTy [pred] = ppr_type TyOpPrec pred <+> darrow
-- TyOpPrec: Num a => a -> a does not need parens
-- bug (a :~: b) => a -> b currently does
-- Trac # 9658
-pprThetaArrowTy preds = parens (fsep (punctuate comma (map (ppr_type TopPrec) preds)))
- <+> darrow
+pprThetaArrowTy preds = pprParenTheta fsep preds <+> darrow
-- Notice 'fsep' here rather that 'sep', so that
-- type contexts don't get displayed in a giant column
-- Rather than
@@ -577,6 +606,11 @@ instance Outputable TyLit where
ppr_type :: TyPrec -> Type -> SDoc
ppr_type _ (TyVarTy tv) = ppr_tvar tv
+
+ppr_type _ (TyConApp tc [r, LitTy (StrTyLit f), ty])
+ | tc `hasKey` recordHasClassNameKey
+ = pprHasPred r [(f, ty)]
+
ppr_type p (TyConApp tc tys) = pprTyTcApp p tc tys
ppr_type p (LitTy l) = ppr_tylit p l
ppr_type p ty@(ForAllTy {}) = ppr_forall_type p ty