diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2018-11-15 09:02:11 +0000 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2018-11-15 11:50:52 +0000 |
commit | ae2c9b40f5b6bf272251d1f4107c60003f541b62 (patch) | |
tree | eb786f1cd10c872df876871a44baf7a2ef97abef /compiler/iface | |
parent | 0ce66be953becf7c9de3cbea406953306b4db3b1 (diff) | |
download | haskell-ae2c9b40f5b6bf272251d1f4107c60003f541b62.tar.gz |
Smarter HsType pretty-print for promoted datacons
Fix Trac #15898, by being smarter about when to print
a space before a promoted data constructor, in a HsType.
I had to implement a mildly tiresome function
HsType.lhsTypeHasLeadingPromotionQuote
It has multiple cases, of course, but it's very simple.
The patch improves the error-message output in a bunch of
cases, and (to my surprise) actually fixes a bug in the
output of T14343 (Trac #14343), thus
- In the expression: _ :: Proxy '('( 'True, 'False), 'False)
+ In the expression: _ :: Proxy '( '( 'True, 'False), 'False)
I discovered that there were two copies of the PromotionFlag
type (a boolean, with helpfully named data cons), one in
IfaceType and one in HsType. So I combined into one,
PromotionFlag, and moved it to BasicTypes. That's why
quite a few files are touched, but it's all routine.
Diffstat (limited to 'compiler/iface')
-rw-r--r-- | compiler/iface/IfaceType.hs | 44 | ||||
-rw-r--r-- | compiler/iface/TcIface.hs | 6 | ||||
-rw-r--r-- | compiler/iface/ToIface.hs | 8 |
3 files changed, 28 insertions, 30 deletions
diff --git a/compiler/iface/IfaceType.hs b/compiler/iface/IfaceType.hs index 264dfa0c57..4d6a3b3be3 100644 --- a/compiler/iface/IfaceType.hs +++ b/compiler/iface/IfaceType.hs @@ -16,7 +16,7 @@ module IfaceType ( IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..), IfaceMCoercion(..), IfaceUnivCoProv(..), - IfaceTyCon(..), IfaceTyConInfo(..), IfaceTyConSort(..), IsPromoted(..), + IfaceTyCon(..), IfaceTyConInfo(..), IfaceTyConSort(..), IfaceTyLit(..), IfaceAppArgs(..), IfaceContext, IfaceBndr(..), IfaceOneShot(..), IfaceLamBndr, IfaceTvBndr, IfaceIdBndr, IfaceTyConBinder, @@ -143,7 +143,7 @@ data IfaceType | IfaceTupleTy -- Saturated tuples (unsaturated ones use IfaceTyConApp) TupleSort -- What sort of tuple? - IsPromoted -- A bit like IfaceTyCon + PromotionFlag -- A bit like IfaceTyCon IfaceAppArgs -- arity = length args -- For promoted data cons, the kind args are omitted @@ -186,10 +186,6 @@ data IfaceTyCon = IfaceTyCon { ifaceTyConName :: IfExtName , ifaceTyConInfo :: IfaceTyConInfo } deriving (Eq) --- | Is a TyCon a promoted data constructor or just a normal type constructor? -data IsPromoted = IsNotPromoted | IsPromoted - deriving (Eq) - -- | The various types of TyCons which have special, built-in syntax. data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon @@ -290,7 +286,7 @@ See Note [The equality types story] in TysPrim. data IfaceTyConInfo -- Used to guide pretty-printing -- and to disambiguate D from 'D (they share a name) - = IfaceTyConInfo { ifaceTyConIsPromoted :: IsPromoted + = IfaceTyConInfo { ifaceTyConIsPromoted :: PromotionFlag , ifaceTyConSort :: IfaceTyConSort } deriving (Eq) @@ -1033,11 +1029,24 @@ criteria are met: in TyCoRep. N.B. Until now (Aug 2018) we didn't check anything for coercion variables. + +Note [Printing promoted type constructors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider this GHCi session (Trac #14343) + > _ :: Proxy '[ 'True ] + error: + Found hole: _ :: Proxy '['True] + +This would be bad, because the '[' looks like a character literal. +Solution: in type-level lists and tuples, add a leading space +if the first type is itself promoted. See pprSpaceIfPromotedTyCon. -} + ------------------- -- | Prefix a space if the given 'IfaceType' is a promoted 'TyCon'. +-- See Note [Printing promoted type constructors] pprSpaceIfPromotedTyCon :: IfaceType -> SDoc -> SDoc pprSpaceIfPromotedTyCon (IfaceTyConApp tyCon _) = case ifaceTyConIsPromoted (ifaceTyConInfo tyCon) of @@ -1229,7 +1238,7 @@ ppr_iface_tc_app pp ctxt_prec tc tys | otherwise = pprIfacePrefixApp ctxt_prec (parens (ppr tc)) (map (pp appPrec) tys) -pprSum :: Arity -> IsPromoted -> IfaceAppArgs -> SDoc +pprSum :: Arity -> PromotionFlag -> IfaceAppArgs -> SDoc pprSum _arity is_promoted args = -- drop the RuntimeRep vars. -- See Note [Unboxed tuple RuntimeRep vars] in TyCon @@ -1238,8 +1247,8 @@ pprSum _arity is_promoted args in pprPromotionQuoteI is_promoted <> sumParens (pprWithBars (ppr_ty topPrec) args') -pprTuple :: PprPrec -> TupleSort -> IsPromoted -> IfaceAppArgs -> SDoc -pprTuple ctxt_prec ConstraintTuple IsNotPromoted IA_Nil +pprTuple :: PprPrec -> TupleSort -> PromotionFlag -> IfaceAppArgs -> SDoc +pprTuple ctxt_prec ConstraintTuple NotPromoted IA_Nil = maybeParen ctxt_prec appPrec $ text "() :: Constraint" @@ -1375,8 +1384,8 @@ pprPromotionQuote :: IfaceTyCon -> SDoc pprPromotionQuote tc = pprPromotionQuoteI $ ifaceTyConIsPromoted $ ifaceTyConInfo tc -pprPromotionQuoteI :: IsPromoted -> SDoc -pprPromotionQuoteI IsNotPromoted = empty +pprPromotionQuoteI :: PromotionFlag -> SDoc +pprPromotionQuoteI NotPromoted = empty pprPromotionQuoteI IsPromoted = char '\'' instance Outputable IfaceCoercion where @@ -1389,17 +1398,6 @@ instance Binary IfaceTyCon where i <- get bh return (IfaceTyCon n i) -instance Binary IsPromoted where - put_ bh IsNotPromoted = putByte bh 0 - put_ bh IsPromoted = putByte bh 1 - - get bh = do - n <- getByte bh - case n of - 0 -> return IsNotPromoted - 1 -> return IsPromoted - _ -> fail "Binary(IsPromoted): fail)" - instance Binary IfaceTyConSort where put_ bh IfaceNormalTyCon = putByte bh 0 put_ bh (IfaceTupleTyCon arity sort) = putByte bh 1 >> put_ bh arity >> put_ bh sort diff --git a/compiler/iface/TcIface.hs b/compiler/iface/TcIface.hs index 248f7d3c38..34bcdb7cd5 100644 --- a/compiler/iface/TcIface.hs +++ b/compiler/iface/TcIface.hs @@ -1153,13 +1153,13 @@ tcIfaceType = go go (IfaceCastTy ty co) = CastTy <$> go ty <*> tcIfaceCo co go (IfaceCoercionTy co) = CoercionTy <$> tcIfaceCo co -tcIfaceTupleTy :: TupleSort -> IsPromoted -> IfaceAppArgs -> IfL Type +tcIfaceTupleTy :: TupleSort -> PromotionFlag -> IfaceAppArgs -> IfL Type tcIfaceTupleTy sort is_promoted args = do { args' <- tcIfaceAppArgs args ; let arity = length args' ; base_tc <- tcTupleTyCon True sort arity ; case is_promoted of - IsNotPromoted + NotPromoted -> return (mkTyConApp base_tc args') IsPromoted @@ -1673,7 +1673,7 @@ tcIfaceTyCon :: IfaceTyCon -> IfL TyCon tcIfaceTyCon (IfaceTyCon name info) = do { thing <- tcIfaceGlobal name ; return $ case ifaceTyConIsPromoted info of - IsNotPromoted -> tyThingTyCon thing + NotPromoted -> tyThingTyCon thing IsPromoted -> promoteDataCon $ tyThingDataCon thing } tcIfaceCoAxiom :: Name -> IfL (CoAxiom Branched) diff --git a/compiler/iface/ToIface.hs b/compiler/iface/ToIface.hs index 653b7407da..a3d11e8891 100644 --- a/compiler/iface/ToIface.hs +++ b/compiler/iface/ToIface.hs @@ -150,7 +150,7 @@ toIfaceTypeX fr (TyConApp tc tys) -- tuples | Just sort <- tyConTuple_maybe tc , n_tys == arity - = IfaceTupleTy sort IsNotPromoted (toIfaceTcArgsX fr tc tys) + = IfaceTupleTy sort NotPromoted (toIfaceTcArgsX fr tc tys) | Just dc <- isPromotedDataCon_maybe tc , isTupleDataCon dc @@ -159,7 +159,7 @@ toIfaceTypeX fr (TyConApp tc tys) | tc `elem` [ eqPrimTyCon, eqReprPrimTyCon, heqTyCon ] , (k1:k2:_) <- tys - = let info = IfaceTyConInfo IsNotPromoted sort + = let info = IfaceTyConInfo NotPromoted sort sort | k1 `eqType` k2 = IfaceEqualityTyCon | otherwise = IfaceNormalTyCon in IfaceTyConApp (IfaceTyCon (tyConName tc) info) (toIfaceTcArgsX fr tc tys) @@ -191,7 +191,7 @@ toIfaceTyCon tc tc_name = tyConName tc info = IfaceTyConInfo promoted sort promoted | isPromotedDataCon tc = IsPromoted - | otherwise = IsNotPromoted + | otherwise = NotPromoted tupleSort :: TyCon -> Maybe IfaceTyConSort tupleSort tc' = @@ -217,7 +217,7 @@ toIfaceTyCon tc toIfaceTyCon_name :: Name -> IfaceTyCon toIfaceTyCon_name n = IfaceTyCon n info - where info = IfaceTyConInfo IsNotPromoted IfaceNormalTyCon + where info = IfaceTyConInfo NotPromoted IfaceNormalTyCon -- Used for the "rough-match" tycon stuff, -- where pretty-printing is not an issue |