summaryrefslogtreecommitdiff
path: root/compiler/GHC/Iface
diff options
context:
space:
mode:
authorKrzysztof Gogolewski <krzysztof.gogolewski@tweag.io>2020-06-15 19:58:10 +0200
committerBen Gamari <ben@smart-cactus.org>2020-06-17 16:21:58 -0400
commit40fa237e1daab7a76b9871bb6c50b953a1addf23 (patch)
tree79751e932434be440ba35b4d65c54f25a437e134 /compiler/GHC/Iface
parent20616959a7f4821034e14a64c3c9bf288c9bc956 (diff)
downloadhaskell-40fa237e1daab7a76b9871bb6c50b953a1addf23.tar.gz
Linear types (#15981)
This is the first step towards implementation of the linear types proposal (https://github.com/ghc-proposals/ghc-proposals/pull/111). It features * A language extension -XLinearTypes * Syntax for linear functions in the surface language * Linearity checking in Core Lint, enabled with -dlinear-core-lint * Core-to-core passes are mostly compatible with linearity * Fields in a data type can be linear or unrestricted; linear fields have multiplicity-polymorphic constructors. If -XLinearTypes is disabled, the GADT syntax defaults to linear fields The following items are not yet supported: * a # m -> b syntax (only prefix FUN is supported for now) * Full multiplicity inference (multiplicities are really only checked) * Decent linearity error messages * Linear let, where, and case expressions in the surface language (each of these currently introduce the unrestricted variant) * Multiplicity-parametric fields * Syntax for annotating lambda-bound or let-bound with a multiplicity * Syntax for non-linear/multiple-field-multiplicity records * Linear projections for records with a single linear field * Linear pattern synonyms * Multiplicity coercions (test LinearPolyType) A high-level description can be found at https://ghc.haskell.org/trac/ghc/wiki/LinearTypes/Implementation Following the link above you will find a description of the changes made to Core. This commit has been authored by * Richard Eisenberg * Krzysztof Gogolewski * Matthew Pickering * Arnaud Spiwack With contributions from: * Mark Barbone * Alexander Vershilov Updates haddock submodule.
Diffstat (limited to 'compiler/GHC/Iface')
-rw-r--r--compiler/GHC/Iface/Env.hs2
-rw-r--r--compiler/GHC/Iface/Ext/Ast.hs29
-rw-r--r--compiler/GHC/Iface/Ext/Types.hs7
-rw-r--r--compiler/GHC/Iface/Ext/Utils.hs12
-rw-r--r--compiler/GHC/Iface/Load.hs2
-rw-r--r--compiler/GHC/Iface/Make.hs25
-rw-r--r--compiler/GHC/Iface/Rename.hs15
-rw-r--r--compiler/GHC/Iface/Syntax.hs27
-rw-r--r--compiler/GHC/Iface/Tidy.hs2
-rw-r--r--compiler/GHC/Iface/Type.hs207
10 files changed, 199 insertions, 129 deletions
diff --git a/compiler/GHC/Iface/Env.hs b/compiler/GHC/Iface/Env.hs
index 088bce8d77..09679d0542 100644
--- a/compiler/GHC/Iface/Env.hs
+++ b/compiler/GHC/Iface/Env.hs
@@ -251,7 +251,7 @@ lookupIfaceTyVar (occ, _)
; return (lookupFsEnv (if_tv_env lcl) occ) }
lookupIfaceVar :: IfaceBndr -> IfL (Maybe TyCoVar)
-lookupIfaceVar (IfaceIdBndr (occ, _))
+lookupIfaceVar (IfaceIdBndr (_, occ, _))
= do { lcl <- getLclEnv
; return (lookupFsEnv (if_id_env lcl) occ) }
lookupIfaceVar (IfaceTvBndr (occ, _))
diff --git a/compiler/GHC/Iface/Ext/Ast.hs b/compiler/GHC/Iface/Ext/Ast.hs
index 24a3aa7c5b..968acbb3c2 100644
--- a/compiler/GHC/Iface/Ext/Ast.hs
+++ b/compiler/GHC/Iface/Ext/Ast.hs
@@ -31,15 +31,17 @@ import GHC.Types.Basic
import GHC.Data.BooleanFormula
import GHC.Core.Class ( FunDep, className, classSCSelIds )
import GHC.Core.Utils ( exprType )
-import GHC.Core.ConLike ( conLikeName )
+import GHC.Core.ConLike ( conLikeName, ConLike(RealDataCon) )
import GHC.Core.TyCon ( TyCon, tyConClass_maybe )
import GHC.Core.FVs
+import GHC.Core.DataCon ( dataConNonlinearType )
import GHC.HsToCore ( deSugarExpr )
import GHC.Types.FieldLabel
import GHC.Hs
import GHC.Driver.Types
import GHC.Unit.Module ( ModuleName, ml_hs_file )
import GHC.Utils.Monad ( concatMapM, liftIO )
+import GHC.Types.Id ( isDataConId_maybe )
import GHC.Types.Name ( Name, nameSrcSpan, setNameLoc, nameUnique )
import GHC.Types.Name.Env ( NameEnv, emptyNameEnv, extendNameEnv, lookupNameEnv )
import GHC.Types.SrcLoc
@@ -606,11 +608,14 @@ instance ToHie (Context (Located Var)) where
let name = case lookupNameEnv m (varName name') of
Just var -> var
Nothing-> name'
+ ty = case isDataConId_maybe name' of
+ Nothing -> varType name'
+ Just dc -> dataConNonlinearType dc
pure
[Node
(mkSourcedNodeInfo org $ NodeInfo S.empty [] $
M.singleton (Right $ varName name)
- (IdentifierDetails (Just $ varType name')
+ (IdentifierDetails (Just ty)
(S.singleton context)))
span
[]]
@@ -646,7 +651,7 @@ evVarsOfTermList (EvTypeable _ ev) =
case ev of
EvTypeableTyCon _ e -> concatMap evVarsOfTermList e
EvTypeableTyApp e1 e2 -> concatMap evVarsOfTermList [e1,e2]
- EvTypeableTrFun e1 e2 -> concatMap evVarsOfTermList [e1,e2]
+ EvTypeableTrFun e1 e2 e3 -> concatMap evVarsOfTermList [e1,e2,e3]
EvTypeableTyLit e -> evVarsOfTermList e
evVarsOfTermList (EvFun{}) = []
@@ -718,6 +723,8 @@ instance HiePass p => HasType (LHsExpr (GhcPass p)) where
HsLit _ l -> Just (hsLitType l)
HsOverLit _ o -> Just (overLitType o)
+ HsConLikeOut _ (RealDataCon con) -> Just (dataConNonlinearType con)
+
HsLam _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy)
HsLamCase _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy)
HsCase _ _ (MG { mg_ext = groupTy }) -> Just (mg_res_ty groupTy)
@@ -1514,6 +1521,9 @@ instance ToHie (Located (DerivStrategy GhcRn)) where
instance ToHie (Located OverlapMode) where
toHie (L span _) = locOnly span
+instance ToHie a => ToHie (HsScaled GhcRn a) where
+ toHie (HsScaled w t) = concatM [toHie (arrowToHsType w), toHie t]
+
instance ToHie (LConDecl GhcRn) where
toHie (L span decl) = concatM $ makeNode decl span : case decl of
ConDeclGADT { con_names = names, con_qvars = exp_vars, con_g_ext = imp_vars
@@ -1543,9 +1553,11 @@ instance ToHie (LConDecl GhcRn) where
rhsScope = combineScopes ctxScope argsScope
ctxScope = maybe NoScope mkLScope ctx
argsScope = condecl_scope dets
- where condecl_scope args = case args of
- PrefixCon xs -> foldr combineScopes NoScope $ map mkLScope xs
- InfixCon a b -> combineScopes (mkLScope a) (mkLScope b)
+ where condecl_scope :: HsConDeclDetails p -> Scope
+ condecl_scope args = case args of
+ PrefixCon xs -> foldr combineScopes NoScope $ map (mkLScope . hsScaledThing) xs
+ InfixCon a b -> combineScopes (mkLScope (hsScaledThing a))
+ (mkLScope (hsScaledThing b))
RecCon x -> mkLScope x
instance ToHie (Located [LConDeclField GhcRn]) where
@@ -1657,8 +1669,9 @@ instance ToHie (TScoped (LHsType GhcRn)) where
[ toHie ty
, toHie $ TS (ResolvedScopes []) ki
]
- HsFunTy _ a b ->
- [ toHie a
+ HsFunTy _ w a b ->
+ [ toHie (arrowToHsType w)
+ , toHie a
, toHie b
]
HsListTy _ a ->
diff --git a/compiler/GHC/Iface/Ext/Types.hs b/compiler/GHC/Iface/Ext/Types.hs
index 3419e441a7..ce6b564b13 100644
--- a/compiler/GHC/Iface/Ext/Types.hs
+++ b/compiler/GHC/Iface/Ext/Types.hs
@@ -141,7 +141,7 @@ data HieType a
| HAppTy a (HieArgs a)
| HTyConApp IfaceTyCon (HieArgs a)
| HForAllTy ((Name, a),ArgFlag) a
- | HFunTy a a
+ | HFunTy a a a
| HQualTy a a -- ^ type with constraint: @t1 => t2@ (see 'IfaceDFunTy')
| HLitTy IfaceTyLit
| HCastTy a
@@ -169,8 +169,9 @@ instance Binary (HieType TypeIndex) where
putByte bh 3
put_ bh bndr
put_ bh a
- put_ bh (HFunTy a b) = do
+ put_ bh (HFunTy w a b) = do
putByte bh 4
+ put_ bh w
put_ bh a
put_ bh b
put_ bh (HQualTy a b) = do
@@ -192,7 +193,7 @@ instance Binary (HieType TypeIndex) where
1 -> HAppTy <$> get bh <*> get bh
2 -> HTyConApp <$> get bh <*> get bh
3 -> HForAllTy <$> get bh <*> get bh
- 4 -> HFunTy <$> get bh <*> get bh
+ 4 -> HFunTy <$> get bh <*> get bh <*> get bh
5 -> HQualTy <$> get bh <*> get bh
6 -> HLitTy <$> get bh
7 -> HCastTy <$> get bh
diff --git a/compiler/GHC/Iface/Ext/Utils.hs b/compiler/GHC/Iface/Ext/Utils.hs
index b0a6f84404..102f6db656 100644
--- a/compiler/GHC/Iface/Ext/Utils.hs
+++ b/compiler/GHC/Iface/Ext/Utils.hs
@@ -12,6 +12,7 @@ import GHC.Core.Map
import GHC.Driver.Session ( DynFlags )
import GHC.Data.FastString ( FastString, mkFastString )
import GHC.Iface.Type
+import GHC.Core.Multiplicity
import GHC.Types.Name hiding (varName)
import GHC.Types.Name.Set
import GHC.Utils.Outputable hiding ( (<>) )
@@ -156,8 +157,8 @@ hieTypeToIface = foldType go
go (HLitTy l) = IfaceLitTy l
go (HForAllTy ((n,k),af) t) = let b = (occNameFS $ getOccName n, k)
in IfaceForAllTy (Bndr (IfaceTvBndr b) af) t
- go (HFunTy a b) = IfaceFunTy VisArg a b
- go (HQualTy pred b) = IfaceFunTy InvisArg pred b
+ go (HFunTy w a b) = IfaceFunTy VisArg w a b
+ go (HQualTy pred b) = IfaceFunTy InvisArg many_ty pred b
go (HCastTy a) = a
go HCoercionTy = IfaceTyVar "<coercion type>"
go (HTyConApp a xs) = IfaceTyConApp a (hieToIfaceArgs xs)
@@ -233,12 +234,13 @@ getTypeIndex t
k <- getTypeIndex (varType v)
i <- getTypeIndex t
return $ HForAllTy ((varName v,k),a) i
- go (FunTy { ft_af = af, ft_arg = a, ft_res = b }) = do
+ go (FunTy { ft_af = af, ft_mult = w, ft_arg = a, ft_res = b }) = do
ai <- getTypeIndex a
bi <- getTypeIndex b
+ wi <- getTypeIndex w
return $ case af of
- InvisArg -> HQualTy ai bi
- VisArg -> HFunTy ai bi
+ InvisArg -> case w of Many -> HQualTy ai bi; _ -> error "Unexpected non-unrestricted predicate"
+ VisArg -> HFunTy wi ai bi
go (LitTy a) = return $ HLitTy $ toIfaceTyLit a
go (CastTy t _) = do
i <- getTypeIndex t
diff --git a/compiler/GHC/Iface/Load.hs b/compiler/GHC/Iface/Load.hs
index 37ad1db8fe..53560ca732 100644
--- a/compiler/GHC/Iface/Load.hs
+++ b/compiler/GHC/Iface/Load.hs
@@ -54,7 +54,6 @@ import GHC.Builtin.Names
import GHC.Builtin.Utils
import GHC.Builtin.PrimOps ( allThePrimOps, primOpFixity, primOpOcc )
import GHC.Types.Id.Make ( seqId )
-import GHC.Builtin.Types.Prim ( funTyConName )
import GHC.Core.Rules
import GHC.Core.TyCon
import GHC.Types.Annotations
@@ -1060,7 +1059,6 @@ ghcPrimIface
-- The fixities listed here for @`seq`@ or @->@ should match
-- those in primops.txt.pp (from which Haddock docs are generated).
fixities = (getOccName seqId, Fixity NoSourceText 0 InfixR)
- : (occName funTyConName, funTyFixity) -- trac #10145
: mapMaybe mkFixity allThePrimOps
mkFixity op = (,) (primOpOcc op) <$> primOpFixity op
diff --git a/compiler/GHC/Iface/Make.hs b/compiler/GHC/Iface/Make.hs
index b93d46e2d0..53385600ae 100644
--- a/compiler/GHC/Iface/Make.hs
+++ b/compiler/GHC/Iface/Make.hs
@@ -38,6 +38,7 @@ import GHC.Core.Coercion.Axiom
import GHC.Core.ConLike
import GHC.Core.DataCon
import GHC.Core.Type
+import GHC.Core.Multiplicity
import GHC.StgToCmm.Types (CgInfos (..))
import GHC.Tc.Utils.TcType
import GHC.Core.InstEnv
@@ -223,7 +224,7 @@ mkIface_ hsc_env
= do
let semantic_mod = canonicalizeHomeModule (hsc_dflags hsc_env) (moduleName this_mod)
entities = typeEnvElts type_env
- decls = [ tyThingToIfaceDecl entity
+ decls = [ tyThingToIfaceDecl (hsc_dflags hsc_env) entity
| entity <- entities,
let name = getName entity,
not (isImplicitTyThing entity),
@@ -384,12 +385,12 @@ Names too: see Note [Binders in Template Haskell] in "GHC.ThToHs", and
************************************************************************
-}
-tyThingToIfaceDecl :: TyThing -> IfaceDecl
-tyThingToIfaceDecl (AnId id) = idToIfaceDecl id
-tyThingToIfaceDecl (ATyCon tycon) = snd (tyConToIfaceDecl emptyTidyEnv tycon)
-tyThingToIfaceDecl (ACoAxiom ax) = coAxiomToIfaceDecl ax
-tyThingToIfaceDecl (AConLike cl) = case cl of
- RealDataCon dc -> dataConToIfaceDecl dc -- for ppr purposes only
+tyThingToIfaceDecl :: DynFlags -> TyThing -> IfaceDecl
+tyThingToIfaceDecl _ (AnId id) = idToIfaceDecl id
+tyThingToIfaceDecl _ (ATyCon tycon) = snd (tyConToIfaceDecl emptyTidyEnv tycon)
+tyThingToIfaceDecl _ (ACoAxiom ax) = coAxiomToIfaceDecl ax
+tyThingToIfaceDecl dflags (AConLike cl) = case cl of
+ RealDataCon dc -> dataConToIfaceDecl dflags dc -- for ppr purposes only
PatSynCon ps -> patSynToIfaceDecl ps
--------------------------
@@ -405,10 +406,10 @@ idToIfaceDecl id
ifIdInfo = toIfaceIdInfo (idInfo id) }
--------------------------
-dataConToIfaceDecl :: DataCon -> IfaceDecl
-dataConToIfaceDecl dataCon
+dataConToIfaceDecl :: DynFlags -> DataCon -> IfaceDecl
+dataConToIfaceDecl dflags dataCon
= IfaceId { ifName = getName dataCon,
- ifType = toIfaceType (dataConUserType dataCon),
+ ifType = toIfaceType (dataConDisplayType dflags dataCon),
ifIdDetails = IfVanillaId,
ifIdInfo = [] }
@@ -555,7 +556,9 @@ tyConToIfaceDecl env tycon
ifConUserTvBinders = map toIfaceForAllBndr user_bndrs',
ifConEqSpec = map (to_eq_spec . eqSpecPair) eq_spec,
ifConCtxt = tidyToIfaceContext con_env2 theta,
- ifConArgTys = map (tidyToIfaceType con_env2) arg_tys,
+ ifConArgTys =
+ map (\(Scaled w t) -> (tidyToIfaceType con_env2 w
+ , (tidyToIfaceType con_env2 t))) arg_tys,
ifConFields = dataConFieldLabels data_con,
ifConStricts = map (toIfaceBang con_env2)
(dataConImplBangs data_con),
diff --git a/compiler/GHC/Iface/Rename.hs b/compiler/GHC/Iface/Rename.hs
index 0c7603c79a..50c73e56a9 100644
--- a/compiler/GHC/Iface/Rename.hs
+++ b/compiler/GHC/Iface/Rename.hs
@@ -557,7 +557,7 @@ rnIfaceConDecl d = do
let rnIfConEqSpec (n,t) = (,) n <$> rnIfaceType t
con_eq_spec <- mapM rnIfConEqSpec (ifConEqSpec d)
con_ctxt <- mapM rnIfaceType (ifConCtxt d)
- con_arg_tys <- mapM rnIfaceType (ifConArgTys d)
+ con_arg_tys <- mapM rnIfaceScaledType (ifConArgTys d)
con_fields <- mapM rnFieldLabel (ifConFields d)
let rnIfaceBang (IfUnpackCo co) = IfUnpackCo <$> rnIfaceCo co
rnIfaceBang bang = pure bang
@@ -644,7 +644,7 @@ rnIfaceBndrs :: Rename [IfaceBndr]
rnIfaceBndrs = mapM rnIfaceBndr
rnIfaceBndr :: Rename IfaceBndr
-rnIfaceBndr (IfaceIdBndr (fs, ty)) = IfaceIdBndr <$> ((,) fs <$> rnIfaceType ty)
+rnIfaceBndr (IfaceIdBndr (w, fs, ty)) = IfaceIdBndr <$> ((,,) w fs <$> rnIfaceType ty)
rnIfaceBndr (IfaceTvBndr tv_bndr) = IfaceTvBndr <$> rnIfaceTvBndr tv_bndr
rnIfaceTvBndr :: Rename IfaceTvBndr
@@ -676,8 +676,8 @@ rnIfaceCo :: Rename IfaceCoercion
rnIfaceCo (IfaceReflCo ty) = IfaceReflCo <$> rnIfaceType ty
rnIfaceCo (IfaceGReflCo role ty mco)
= IfaceGReflCo role <$> rnIfaceType ty <*> rnIfaceMCo mco
-rnIfaceCo (IfaceFunCo role co1 co2)
- = IfaceFunCo role <$> rnIfaceCo co1 <*> rnIfaceCo co2
+rnIfaceCo (IfaceFunCo role w co1 co2)
+ = IfaceFunCo role <$> rnIfaceCo w <*> rnIfaceCo co1 <*> rnIfaceCo co2
rnIfaceCo (IfaceTyConAppCo role tc cos)
= IfaceTyConAppCo role <$> rnIfaceTyCon tc <*> mapM rnIfaceCo cos
rnIfaceCo (IfaceAppCo co1 co2)
@@ -722,8 +722,8 @@ rnIfaceType (IfaceTyVar n) = pure (IfaceTyVar n)
rnIfaceType (IfaceAppTy t1 t2)
= IfaceAppTy <$> rnIfaceType t1 <*> rnIfaceAppArgs t2
rnIfaceType (IfaceLitTy l) = return (IfaceLitTy l)
-rnIfaceType (IfaceFunTy af t1 t2)
- = IfaceFunTy af <$> rnIfaceType t1 <*> rnIfaceType t2
+rnIfaceType (IfaceFunTy af w t1 t2)
+ = IfaceFunTy af <$> rnIfaceType w <*> rnIfaceType t1 <*> rnIfaceType t2
rnIfaceType (IfaceTupleTy s i tks)
= IfaceTupleTy s i <$> rnIfaceAppArgs tks
rnIfaceType (IfaceTyConApp tc tks)
@@ -735,6 +735,9 @@ rnIfaceType (IfaceCoercionTy co)
rnIfaceType (IfaceCastTy ty co)
= IfaceCastTy <$> rnIfaceType ty <*> rnIfaceCo co
+rnIfaceScaledType :: Rename (IfaceMult, IfaceType)
+rnIfaceScaledType (m, t) = (,) <$> rnIfaceType m <*> rnIfaceType t
+
rnIfaceForAllBndr :: Rename (VarBndr IfaceBndr flag)
rnIfaceForAllBndr (Bndr tv vis) = Bndr <$> rnIfaceBndr tv <*> pure vis
diff --git a/compiler/GHC/Iface/Syntax.hs b/compiler/GHC/Iface/Syntax.hs
index 84e96f0706..2b0fcd2b76 100644
--- a/compiler/GHC/Iface/Syntax.hs
+++ b/compiler/GHC/Iface/Syntax.hs
@@ -69,7 +69,7 @@ import GHC.Data.BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue )
import GHC.Types.Var( VarBndr(..), binderVar, tyVarSpecToBinders )
import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag )
import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn,
- seqList )
+ seqList, zipWithEqual )
import GHC.Core.DataCon (SrcStrictness(..), SrcUnpackedness(..))
import GHC.Utils.Lexeme (isLexSym)
import GHC.Builtin.Types ( constraintKindTyConName )
@@ -259,7 +259,7 @@ data IfaceConDecl
-- See Note [DataCon user type variable binders] in GHC.Core.DataCon
ifConEqSpec :: IfaceEqSpec, -- Equality constraints
ifConCtxt :: IfaceContext, -- Non-stupid context
- ifConArgTys :: [IfaceType], -- Arg types
+ ifConArgTys :: [(IfaceMult, IfaceType)],-- Arg types
ifConFields :: [FieldLabel], -- ...ditto... (field labels)
ifConStricts :: [IfaceBang],
-- Empty (meaning all lazy),
@@ -1026,7 +1026,7 @@ pprIfaceDecl _ (IfacePatSyn { ifName = name,
, ppWhen insert_empty_ctxt $ parens empty <+> darrow
, ex_msg
, pprIfaceContextArr prov_ctxt
- , pprIfaceType $ foldr (IfaceFunTy VisArg) pat_ty arg_tys ])
+ , pprIfaceType $ foldr (IfaceFunTy VisArg many_ty) pat_ty arg_tys ])
where
univ_msg = pprUserIfaceForAll $ tyVarSpecToBinders univ_bndrs
ex_msg = pprUserIfaceForAll $ tyVarSpecToBinders ex_bndrs
@@ -1148,7 +1148,7 @@ pprIfaceConDecl ss gadt_style tycon tc_binders parent
how_much = ss_how_much ss
tys_w_strs :: [(IfaceBang, IfaceType)]
- tys_w_strs = zip stricts arg_tys
+ tys_w_strs = zip stricts (map snd arg_tys)
pp_prefix_con = pprPrefixIfDeclBndr how_much (occName name)
-- If we're pretty-printing a H98-style declaration with existential
@@ -1165,11 +1165,17 @@ pprIfaceConDecl ss gadt_style tycon tc_binders parent
-- because we don't have a Name for the tycon, only an OccName
pp_tau | null fields
= case pp_args ++ [pp_gadt_res_ty] of
- (t:ts) -> fsep (t : map (arrow <+>) ts)
+ (t:ts) -> fsep (t : zipWithEqual "pprIfaceConDecl" (\(w,_) d -> ppr_arr w <+> d) arg_tys ts)
[] -> panic "pp_con_taus"
| otherwise
= sep [pp_field_args, arrow <+> pp_gadt_res_ty]
+ -- Constructors are linear by default, but we don't want to show
+ -- linear arrows when -XLinearTypes is disabled
+ ppr_arr w = sdocOption sdocLinearTypes (\linearTypes -> if linearTypes
+ then ppr_fun_arrow w
+ else arrow)
+
ppr_bang IfNoBang = whenPprDebug $ char '_'
ppr_bang IfStrict = char '!'
ppr_bang IfUnpack = text "{-# UNPACK #-}"
@@ -1600,7 +1606,8 @@ freeNamesIfConDecl (IfCon { ifConExTCvs = ex_tvs, ifConCtxt = ctxt
, ifConStricts = bangs })
= fnList freeNamesIfBndr ex_tvs &&&
freeNamesIfContext ctxt &&&
- fnList freeNamesIfType arg_tys &&&
+ fnList freeNamesIfType (map fst arg_tys) &&& -- these are multiplicities, represented as types
+ fnList freeNamesIfType (map snd arg_tys) &&&
mkNameSet (map flSelector flds) &&&
fnList freeNamesIfType (map snd eq_spec) &&& -- equality constraints
fnList freeNamesIfBang bangs
@@ -1624,7 +1631,7 @@ freeNamesIfType (IfaceTyConApp tc ts) = freeNamesIfTc tc &&& freeNamesIfAppArgs
freeNamesIfType (IfaceTupleTy _ _ ts) = freeNamesIfAppArgs ts
freeNamesIfType (IfaceLitTy _) = emptyNameSet
freeNamesIfType (IfaceForAllTy tv t) = freeNamesIfVarBndr tv &&& freeNamesIfType t
-freeNamesIfType (IfaceFunTy _ s t) = freeNamesIfType s &&& freeNamesIfType t
+freeNamesIfType (IfaceFunTy _ w s t) = freeNamesIfType s &&& freeNamesIfType t &&& freeNamesIfType w
freeNamesIfType (IfaceCastTy t c) = freeNamesIfType t &&& freeNamesIfCoercion c
freeNamesIfType (IfaceCoercionTy c) = freeNamesIfCoercion c
@@ -1636,8 +1643,8 @@ freeNamesIfCoercion :: IfaceCoercion -> NameSet
freeNamesIfCoercion (IfaceReflCo t) = freeNamesIfType t
freeNamesIfCoercion (IfaceGReflCo _ t mco)
= freeNamesIfType t &&& freeNamesIfMCoercion mco
-freeNamesIfCoercion (IfaceFunCo _ c1 c2)
- = freeNamesIfCoercion c1 &&& freeNamesIfCoercion c2
+freeNamesIfCoercion (IfaceFunCo _ c_mult c1 c2)
+ = freeNamesIfCoercion c_mult &&& freeNamesIfCoercion c1 &&& freeNamesIfCoercion c2
freeNamesIfCoercion (IfaceTyConAppCo _ tc cos)
= freeNamesIfTc tc &&& fnList freeNamesIfCoercion cos
freeNamesIfCoercion (IfaceAppCo c1 c2)
@@ -1699,7 +1706,7 @@ freeNamesIfTvBndr (_fs,k) = freeNamesIfKind k
-- kinds can have Names inside, because of promotion
freeNamesIfIdBndr :: IfaceIdBndr -> NameSet
-freeNamesIfIdBndr (_fs,k) = freeNamesIfKind k
+freeNamesIfIdBndr (_, _fs,k) = freeNamesIfKind k
freeNamesIfIdInfo :: IfaceIdInfo -> NameSet
freeNamesIfIdInfo = fnList freeNamesItem
diff --git a/compiler/GHC/Iface/Tidy.hs b/compiler/GHC/Iface/Tidy.hs
index efb72dc77d..5121c11681 100644
--- a/compiler/GHC/Iface/Tidy.hs
+++ b/compiler/GHC/Iface/Tidy.hs
@@ -217,7 +217,7 @@ globaliseAndTidyBootId :: Id -> Id
-- * VanillaIdInfo (makes a conservative assumption about arity)
-- * BootUnfolding (see Note [Inlining and hs-boot files] in GHC.CoreToIface)
globaliseAndTidyBootId id
- = globaliseId id `setIdType` tidyTopType (idType id)
+ = updateIdTypeAndMult tidyTopType (globaliseId id)
`setIdUnfolding` BootUnfolding
{-
diff --git a/compiler/GHC/Iface/Type.hs b/compiler/GHC/Iface/Type.hs
index 6ed05e3338..acd7b51330 100644
--- a/compiler/GHC/Iface/Type.hs
+++ b/compiler/GHC/Iface/Type.hs
@@ -26,6 +26,7 @@ module GHC.Iface.Type (
IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..),
IfaceMCoercion(..),
IfaceUnivCoProv(..),
+ IfaceMult,
IfaceTyCon(..), IfaceTyConInfo(..), IfaceTyConSort(..),
IfaceTyLit(..), IfaceAppArgs(..),
IfaceContext, IfaceBndr(..), IfaceOneShot(..), IfaceLamBndr,
@@ -58,13 +59,16 @@ module GHC.Iface.Type (
pprIfaceCoercion, pprParendIfaceCoercion,
splitIfaceSigmaTy, pprIfaceTypeApp, pprUserIfaceForAll,
pprIfaceCoTcApp, pprTyTcApp, pprIfacePrefixApp,
+ ppr_fun_arrow,
isIfaceTauType,
suppressIfaceInvisibles,
stripIfaceInvisVars,
stripInvisArgs,
- mkIfaceTySubst, substIfaceTyVar, substIfaceAppArgs, inDomIfaceTySubst
+ mkIfaceTySubst, substIfaceTyVar, substIfaceAppArgs, inDomIfaceTySubst,
+
+ many_ty
) where
#include "HsVersions.h"
@@ -73,8 +77,9 @@ import GHC.Prelude
import {-# SOURCE #-} GHC.Builtin.Types
( coercibleTyCon, heqTyCon
- , liftedRepDataConTyCon, tupleTyConName )
-import {-# SOURCE #-} GHC.Core.Type ( isRuntimeRepTy )
+ , liftedRepDataConTyCon, tupleTyConName
+ , manyDataConTyCon, oneDataConTyCon )
+import {-# SOURCE #-} GHC.Core.Type ( isRuntimeRepTy, isMultiplicityTy )
import GHC.Core.TyCon hiding ( pprPromotionQuote )
import GHC.Core.Coercion.Axiom
@@ -85,7 +90,6 @@ import GHC.Types.Basic
import GHC.Utils.Binary
import GHC.Utils.Outputable
import GHC.Data.FastString
-import GHC.Data.FastString.Env
import GHC.Utils.Misc
import Data.Maybe( isJust )
@@ -109,21 +113,21 @@ data IfaceBndr -- Local (non-top-level) binders
= IfaceIdBndr {-# UNPACK #-} !IfaceIdBndr
| IfaceTvBndr {-# UNPACK #-} !IfaceTvBndr
-type IfaceIdBndr = (IfLclName, IfaceType)
+type IfaceIdBndr = (IfaceType, IfLclName, IfaceType)
type IfaceTvBndr = (IfLclName, IfaceKind)
ifaceTvBndrName :: IfaceTvBndr -> IfLclName
ifaceTvBndrName (n,_) = n
ifaceIdBndrName :: IfaceIdBndr -> IfLclName
-ifaceIdBndrName (n,_) = n
+ifaceIdBndrName (_,n,_) = n
ifaceBndrName :: IfaceBndr -> IfLclName
ifaceBndrName (IfaceTvBndr bndr) = ifaceTvBndrName bndr
ifaceBndrName (IfaceIdBndr bndr) = ifaceIdBndrName bndr
ifaceBndrType :: IfaceBndr -> IfaceType
-ifaceBndrType (IfaceIdBndr (_, t)) = t
+ifaceBndrType (IfaceIdBndr (_, _, t)) = t
ifaceBndrType (IfaceTvBndr (_, t)) = t
type IfaceLamBndr = (IfaceBndr, IfaceOneShot)
@@ -159,7 +163,7 @@ data IfaceType
-- See Note [Suppressing invisible arguments] for
-- an explanation of why the second field isn't
-- IfaceType, analogous to AppTy.
- | IfaceFunTy AnonArgFlag IfaceType IfaceType
+ | IfaceFunTy AnonArgFlag IfaceMult IfaceType IfaceType
| IfaceForAllTy IfaceForAllBndr IfaceType
| IfaceTyConApp IfaceTyCon IfaceAppArgs -- Not necessarily saturated
-- Includes newtypes, synonyms, tuples
@@ -172,6 +176,8 @@ data IfaceType
IfaceAppArgs -- arity = length args
-- For promoted data cons, the kind args are omitted
+type IfaceMult = IfaceType
+
type IfacePredType = IfaceType
type IfaceContext = [IfacePredType]
@@ -194,7 +200,7 @@ mkIfaceTyConKind :: [IfaceTyConBinder] -> IfaceKind -> IfaceKind
mkIfaceTyConKind bndrs res_kind = foldr mk res_kind bndrs
where
mk :: IfaceTyConBinder -> IfaceKind -> IfaceKind
- mk (Bndr tv (AnonTCB af)) k = IfaceFunTy af (ifaceBndrType tv) k
+ mk (Bndr tv (AnonTCB af)) k = IfaceFunTy af many_ty (ifaceBndrType tv) k
mk (Bndr tv (NamedTCB vis)) k = IfaceForAllTy (Bndr tv vis) k
ifaceForAllSpecToBndrs :: [IfaceForAllSpecBndr] -> [IfaceForAllBndr]
@@ -354,7 +360,7 @@ data IfaceMCoercion
data IfaceCoercion
= IfaceReflCo IfaceType
| IfaceGReflCo Role IfaceType (IfaceMCoercion)
- | IfaceFunCo Role IfaceCoercion IfaceCoercion
+ | IfaceFunCo Role IfaceCoercion IfaceCoercion IfaceCoercion
| IfaceTyConAppCo Role IfaceTyCon [IfaceCoercion]
| IfaceAppCo IfaceCoercion IfaceCoercion
| IfaceForAllCo IfaceBndr IfaceCoercion IfaceCoercion
@@ -438,7 +444,7 @@ splitIfaceSigmaTy ty
= case split_foralls ty of { (bndrs, rho) -> (bndr:bndrs, rho) }
split_foralls rho = ([], rho)
- split_rho (IfaceFunTy InvisArg ty1 ty2)
+ split_rho (IfaceFunTy InvisArg _ ty1 ty2)
= case split_rho ty2 of { (ps, tau) -> (ty1:ps, tau) }
split_rho tau = ([], tau)
@@ -481,7 +487,7 @@ ifTypeIsVarFree ty = go ty
go (IfaceTyVar {}) = False
go (IfaceFreeTyVar {}) = False
go (IfaceAppTy fun args) = go fun && go_args args
- go (IfaceFunTy _ arg res) = go arg && go res
+ go (IfaceFunTy _ w arg res) = go w && go arg && go res
go (IfaceForAllTy {}) = False
go (IfaceTyConApp _ args) = go_args args
go (IfaceTupleTy _ _ args) = go_args args
@@ -516,7 +522,7 @@ substIfaceType env ty
go (IfaceFreeTyVar tv) = IfaceFreeTyVar tv
go (IfaceTyVar tv) = substIfaceTyVar env tv
go (IfaceAppTy t ts) = IfaceAppTy (go t) (substIfaceAppArgs env ts)
- go (IfaceFunTy af t1 t2) = IfaceFunTy af (go t1) (go t2)
+ go (IfaceFunTy af w t1 t2) = IfaceFunTy af (go w) (go t1) (go t2)
go ty@(IfaceLitTy {}) = ty
go (IfaceTyConApp tc tys) = IfaceTyConApp tc (substIfaceAppArgs env tys)
go (IfaceTupleTy s i tys) = IfaceTupleTy s i (substIfaceAppArgs env tys)
@@ -529,7 +535,7 @@ substIfaceType env ty
go_co (IfaceReflCo ty) = IfaceReflCo (go ty)
go_co (IfaceGReflCo r ty mco) = IfaceGReflCo r (go ty) (go_mco mco)
- go_co (IfaceFunCo r c1 c2) = IfaceFunCo r (go_co c1) (go_co c2)
+ go_co (IfaceFunCo r w c1 c2) = IfaceFunCo r (go_co w) (go_co c1) (go_co c2)
go_co (IfaceTyConAppCo r tc cos) = IfaceTyConAppCo r tc (go_cos cos)
go_co (IfaceAppCo c1 c2) = IfaceAppCo (go_co c1) (go_co c2)
go_co (IfaceForAllCo {}) = pprPanic "substIfaceCoercion" (ppr ty)
@@ -729,7 +735,7 @@ pprIfacePrefixApp ctxt_prec pp_fun pp_tys
isIfaceTauType :: IfaceType -> Bool
isIfaceTauType (IfaceForAllTy _ _) = False
-isIfaceTauType (IfaceFunTy InvisArg _ _) = False
+isIfaceTauType (IfaceFunTy InvisArg _ _ _) = False
isIfaceTauType _ = True
-- ----------------------------- Printing binders ------------------------------------
@@ -747,7 +753,7 @@ pprIfaceLamBndr (b, IfaceNoOneShot) = ppr b
pprIfaceLamBndr (b, IfaceOneShot) = ppr b <> text "[OneShot]"
pprIfaceIdBndr :: IfaceIdBndr -> SDoc
-pprIfaceIdBndr (name, ty) = parens (ppr name <+> dcolon <+> ppr ty)
+pprIfaceIdBndr (w, name, ty) = parens (ppr name <> brackets (ppr w) <+> dcolon <+> ppr ty)
{- Note [Suppressing binder signatures]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -844,17 +850,26 @@ pprIfaceType = pprPrecIfaceType topPrec
pprParendIfaceType = pprPrecIfaceType appPrec
pprPrecIfaceType :: PprPrec -> IfaceType -> SDoc
--- We still need `eliminateRuntimeRep`, since the `pprPrecIfaceType` maybe
+-- We still need `hideNonStandardTypes`, since the `pprPrecIfaceType` may be
-- called from other places, besides `:type` and `:info`.
-pprPrecIfaceType prec ty = eliminateRuntimeRep (ppr_ty prec) ty
+pprPrecIfaceType prec ty =
+ hideNonStandardTypes (ppr_ty prec) ty
+
+ppr_fun_arrow :: IfaceMult -> SDoc
+ppr_fun_arrow w
+ | (IfaceTyConApp tc _) <- w
+ , tc `ifaceTyConHasKey` (getUnique manyDataConTyCon) = arrow
+ | (IfaceTyConApp tc _) <- w
+ , tc `ifaceTyConHasKey` (getUnique oneDataConTyCon) = lollipop
+ | otherwise = mulArrow (pprIfaceType w)
ppr_sigma :: PprPrec -> IfaceType -> SDoc
ppr_sigma ctxt_prec ty
= maybeParen ctxt_prec funPrec (pprIfaceSigmaType ShowForAllMust ty)
ppr_ty :: PprPrec -> IfaceType -> SDoc
-ppr_ty ctxt_prec ty@(IfaceForAllTy {}) = ppr_sigma ctxt_prec ty
-ppr_ty ctxt_prec ty@(IfaceFunTy InvisArg _ _) = ppr_sigma ctxt_prec ty
+ppr_ty ctxt_prec ty@(IfaceForAllTy {}) = ppr_sigma ctxt_prec ty
+ppr_ty ctxt_prec ty@(IfaceFunTy InvisArg _ _ _) = ppr_sigma ctxt_prec ty
ppr_ty _ (IfaceFreeTyVar tyvar) = ppr tyvar -- This is the main reason for IfaceFreeTyVar!
ppr_ty _ (IfaceTyVar tyvar) = ppr tyvar -- See Note [TcTyVars in IfaceType]
@@ -862,15 +877,15 @@ ppr_ty ctxt_prec (IfaceTyConApp tc tys) = pprTyTcApp ctxt_prec tc tys
ppr_ty ctxt_prec (IfaceTupleTy i p tys) = pprTuple ctxt_prec i p tys
ppr_ty _ (IfaceLitTy n) = pprIfaceTyLit n
-- Function types
-ppr_ty ctxt_prec (IfaceFunTy _ ty1 ty2) -- Should be VisArg
+ppr_ty ctxt_prec (IfaceFunTy _ w ty1 ty2) -- Should be VisArg
= -- We don't want to lose synonyms, so we mustn't use splitFunTys here.
maybeParen ctxt_prec funPrec $
- sep [ppr_ty funPrec ty1, sep (ppr_fun_tail ty2)]
+ sep [ppr_ty funPrec ty1, sep (ppr_fun_tail w ty2)]
where
- ppr_fun_tail (IfaceFunTy VisArg ty1 ty2)
- = (arrow <+> ppr_ty funPrec ty1) : ppr_fun_tail ty2
- ppr_fun_tail other_ty
- = [arrow <+> pprIfaceType other_ty]
+ ppr_fun_tail wthis (IfaceFunTy VisArg wnext ty1 ty2)
+ = (ppr_fun_arrow wthis <+> ppr_ty funPrec ty1) : ppr_fun_tail wnext ty2
+ ppr_fun_tail wthis other_ty
+ = [ppr_fun_arrow wthis <+> pprIfaceType other_ty]
ppr_ty ctxt_prec (IfaceAppTy t ts)
= if_print_coercions
@@ -928,9 +943,12 @@ syntactic overhead.
For this reason it was decided that we would hide RuntimeRep variables
for now (see #11549). We do this by defaulting all type variables of
-kind RuntimeRep to LiftedRep. This is done in a pass right before
-pretty-printing (defaultRuntimeRepVars, controlled by
--fprint-explicit-runtime-reps)
+kind RuntimeRep to LiftedRep.
+Likewise, we default all Multiplicity variables to Many.
+
+This is done in a pass right before pretty-printing
+(defaultNonStandardVars, controlled by
+-fprint-explicit-runtime-reps and -XLinearTypes)
This applies to /quantified/ variables like 'w' above. What about
variables that are /free/ in the type being printed, which certainly
@@ -948,33 +966,36 @@ Conclusion: keep track of whether we we are in the kind of a
binder; only if so, convert free RuntimeRep variables to LiftedRep.
-}
--- | Default 'RuntimeRep' variables to 'LiftedRep'. e.g.
+-- | Default 'RuntimeRep' variables to 'LiftedRep', and 'Multiplicity'
+-- variables to 'Many'. For example:
--
-- @
-- ($) :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r).
-- (a -> b) -> a -> b
+-- Just :: forall (k :: Multiplicity) a. a # k -> Maybe a
-- @
--
-- turns in to,
--
-- @ ($) :: forall a (b :: *). (a -> b) -> a -> b @
+-- @ Just :: forall a . a -> Maybe a @
--
--- We do this to prevent RuntimeRep variables from incurring a significant
--- syntactic overhead in otherwise simple type signatures (e.g. ($)). See
--- Note [Defaulting RuntimeRep variables] and #11549 for further discussion.
---
-defaultRuntimeRepVars :: IfaceType -> IfaceType
-defaultRuntimeRepVars ty = go False emptyFsEnv ty
+-- We do this to prevent RuntimeRep and Multiplicity variables from
+-- incurring a significant syntactic overhead in otherwise simple
+-- type signatures (e.g. ($)). See Note [Defaulting RuntimeRep variables]
+-- and #11549 for further discussion.
+defaultNonStandardVars :: Bool -> Bool -> IfaceType -> IfaceType
+defaultNonStandardVars do_runtimereps do_multiplicities ty = go False emptyFsEnv ty
where
go :: Bool -- True <=> Inside the kind of a binder
- -> FastStringEnv () -- Set of enclosing forall-ed RuntimeRep variables
- -> IfaceType -- (replace them with LiftedRep)
+ -> FastStringEnv IfaceType -- Set of enclosing forall-ed RuntimeRep/Multiplicity variables
+ -> IfaceType
-> IfaceType
go ink subs (IfaceForAllTy (Bndr (IfaceTvBndr (var, var_kind)) argf) ty)
- | isRuntimeRep var_kind
- , isInvisibleArgFlag argf -- Don't default *visible* quantification
+ | isInvisibleArgFlag argf -- Don't default *visible* quantification
-- or we get the mess in #13963
- = let subs' = extendFsEnv subs var ()
+ , Just substituted_ty <- check_substitution var_kind
+ = let subs' = extendFsEnv subs var substituted_ty
-- Record that we should replace it with LiftedRep,
-- and recurse, discarding the forall
in go ink subs' ty
@@ -982,16 +1003,16 @@ defaultRuntimeRepVars ty = go False emptyFsEnv ty
go ink subs (IfaceForAllTy bndr ty)
= IfaceForAllTy (go_ifacebndr subs bndr) (go ink subs ty)
- go _ subs ty@(IfaceTyVar tv)
- | tv `elemFsEnv` subs
- = IfaceTyConApp liftedRep IA_Nil
- | otherwise
- = ty
+ go _ subs ty@(IfaceTyVar tv) = case lookupFsEnv subs tv of
+ Just s -> s
+ Nothing -> ty
go in_kind _ ty@(IfaceFreeTyVar tv)
-- See Note [Defaulting RuntimeRep variables], about free vars
- | in_kind && GHC.Core.Type.isRuntimeRepTy (tyVarKind tv)
- = IfaceTyConApp liftedRep IA_Nil
+ | in_kind && do_runtimereps && GHC.Core.Type.isRuntimeRepTy (tyVarKind tv)
+ = liftedRep_ty
+ | do_multiplicities && GHC.Core.Type.isMultiplicityTy (tyVarKind tv)
+ = many_ty
| otherwise
= ty
@@ -1001,8 +1022,8 @@ defaultRuntimeRepVars ty = go False emptyFsEnv ty
go ink subs (IfaceTupleTy sort is_prom tc_args)
= IfaceTupleTy sort is_prom (go_args ink subs tc_args)
- go ink subs (IfaceFunTy af arg res)
- = IfaceFunTy af (go ink subs arg) (go ink subs res)
+ go ink subs (IfaceFunTy af w arg res)
+ = IfaceFunTy af (go ink subs w) (go ink subs arg) (go ink subs res)
go ink subs (IfaceAppTy t ts)
= IfaceAppTy (go ink subs t) (go_args ink subs ts)
@@ -1013,33 +1034,45 @@ defaultRuntimeRepVars ty = go False emptyFsEnv ty
go _ _ ty@(IfaceLitTy {}) = ty
go _ _ ty@(IfaceCoercionTy {}) = ty
- go_ifacebndr :: FastStringEnv () -> IfaceForAllBndr -> IfaceForAllBndr
- go_ifacebndr subs (Bndr (IfaceIdBndr (n, t)) argf)
- = Bndr (IfaceIdBndr (n, go True subs t)) argf
+ go_ifacebndr :: FastStringEnv IfaceType -> IfaceForAllBndr -> IfaceForAllBndr
+ go_ifacebndr subs (Bndr (IfaceIdBndr (w, n, t)) argf)
+ = Bndr (IfaceIdBndr (w, n, go True subs t)) argf
go_ifacebndr subs (Bndr (IfaceTvBndr (n, t)) argf)
= Bndr (IfaceTvBndr (n, go True subs t)) argf
- go_args :: Bool -> FastStringEnv () -> IfaceAppArgs -> IfaceAppArgs
+ go_args :: Bool -> FastStringEnv IfaceType -> IfaceAppArgs -> IfaceAppArgs
go_args _ _ IA_Nil = IA_Nil
go_args ink subs (IA_Arg ty argf args)
= IA_Arg (go ink subs ty) argf (go_args ink subs args)
- liftedRep :: IfaceTyCon
- liftedRep = IfaceTyCon dc_name (IfaceTyConInfo IsPromoted IfaceNormalTyCon)
- where dc_name = getName liftedRepDataConTyCon
-
- isRuntimeRep :: IfaceType -> Bool
- isRuntimeRep (IfaceTyConApp tc _) =
- tc `ifaceTyConHasKey` runtimeRepTyConKey
- isRuntimeRep _ = False
-
-eliminateRuntimeRep :: (IfaceType -> SDoc) -> IfaceType -> SDoc
-eliminateRuntimeRep f ty
+ check_substitution :: IfaceType -> Maybe IfaceType
+ check_substitution (IfaceTyConApp tc _)
+ | do_runtimereps, tc `ifaceTyConHasKey` runtimeRepTyConKey = Just liftedRep_ty
+ | do_multiplicities, tc `ifaceTyConHasKey` multiplicityTyConKey = Just many_ty
+ check_substitution _ = Nothing
+
+liftedRep_ty :: IfaceType
+liftedRep_ty =
+ IfaceTyConApp (IfaceTyCon dc_name (IfaceTyConInfo IsPromoted IfaceNormalTyCon))
+ IA_Nil
+ where dc_name = getName liftedRepDataConTyCon
+
+many_ty :: IfaceType
+many_ty =
+ IfaceTyConApp (IfaceTyCon dc_name (IfaceTyConInfo IsPromoted IfaceNormalTyCon))
+ IA_Nil
+ where dc_name = getName manyDataConTyCon
+
+hideNonStandardTypes :: (IfaceType -> SDoc) -> IfaceType -> SDoc
+hideNonStandardTypes f ty
= sdocOption sdocPrintExplicitRuntimeReps $ \printExplicitRuntimeReps ->
+ sdocOption sdocLinearTypes $ \linearTypes ->
getPprStyle $ \sty ->
- if userStyle sty && not printExplicitRuntimeReps
- then f (defaultRuntimeRepVars ty)
- else f ty
+ let do_runtimerep = not printExplicitRuntimeReps
+ do_multiplicity = not linearTypes
+ in if userStyle sty
+ then f (defaultNonStandardVars do_runtimerep do_multiplicity ty)
+ else f ty
instance Outputable IfaceAppArgs where
ppr tca = pprIfaceAppArgs tca
@@ -1148,7 +1181,7 @@ data ShowForAllFlag = ShowForAllMust | ShowForAllWhen
pprIfaceSigmaType :: ShowForAllFlag -> IfaceType -> SDoc
pprIfaceSigmaType show_forall ty
- = eliminateRuntimeRep ppr_fn ty
+ = hideNonStandardTypes ppr_fn ty
where
ppr_fn iface_ty =
let (tvs, theta, tau) = splitIfaceSigmaTy iface_ty
@@ -1339,6 +1372,11 @@ pprTyTcApp' ctxt_prec tc tys printExplicitKinds debug
, rep `ifaceTyConHasKey` liftedRepDataConKey
= ppr_kind_type ctxt_prec
+ | tc `ifaceTyConHasKey` funTyConKey
+ , IA_Arg (IfaceTyConApp rep IA_Nil) Required args <- tys
+ , rep `ifaceTyConHasKey` manyDataConKey
+ = pprIfacePrefixApp ctxt_prec (parens arrow) (map (ppr_ty appPrec) (appArgsIfaceTypes $ stripInvisArgs printExplicitKinds args))
+
| otherwise
= getPprDebug $ \dbg ->
if | not dbg && tc `ifaceTyConHasKey` errorMessageTypeErrorFamKey
@@ -1550,14 +1588,15 @@ ppr_co _ (IfaceGReflCo r ty IfaceMRefl)
ppr_co ctxt_prec (IfaceGReflCo r ty (IfaceMCo co))
= ppr_special_co ctxt_prec
(text "GRefl" <+> ppr r <+> pprParendIfaceType ty) [co]
-ppr_co ctxt_prec (IfaceFunCo r co1 co2)
+ppr_co ctxt_prec (IfaceFunCo r cow co1 co2)
= maybeParen ctxt_prec funPrec $
- sep (ppr_co funPrec co1 : ppr_fun_tail co2)
+ sep (ppr_co funPrec co1 : ppr_fun_tail cow co2)
where
- ppr_fun_tail (IfaceFunCo r co1 co2)
- = (arrow <> ppr_role r <+> ppr_co funPrec co1) : ppr_fun_tail co2
- ppr_fun_tail other_co
- = [arrow <> ppr_role r <+> pprIfaceCoercion other_co]
+ ppr_fun_tail cow' (IfaceFunCo r cow co1 co2)
+ = (coercionArrow cow' <> ppr_role r <+> ppr_co funPrec co1) : ppr_fun_tail cow co2
+ ppr_fun_tail cow' other_co
+ = [coercionArrow cow' <> ppr_role r <+> pprIfaceCoercion other_co]
+ coercionArrow w = mulArrow (ppr_co topPrec w)
ppr_co _ (IfaceTyConAppCo r tc cos)
= parens (pprIfaceCoTcApp topPrec tc cos) <> ppr_role r
@@ -1572,7 +1611,7 @@ ppr_co ctxt_prec co@(IfaceForAllCo {})
split_co (IfaceForAllCo (IfaceTvBndr (name, _)) kind_co co')
= let (tvs, co'') = split_co co' in ((name,kind_co):tvs,co'')
- split_co (IfaceForAllCo (IfaceIdBndr (name, _)) kind_co co')
+ split_co (IfaceForAllCo (IfaceIdBndr (_, name, _)) kind_co co')
= let (tvs, co'') = split_co co' in ((name,kind_co):tvs,co'')
split_co co' = ([], co')
@@ -1777,9 +1816,10 @@ instance Binary IfaceType where
putByte bh 2
put_ bh ae
put_ bh af
- put_ bh (IfaceFunTy af ag ah) = do
+ put_ bh (IfaceFunTy af aw ag ah) = do
putByte bh 3
put_ bh af
+ put_ bh aw
put_ bh ag
put_ bh ah
put_ bh (IfaceTyConApp tc tys)
@@ -1805,9 +1845,10 @@ instance Binary IfaceType where
af <- get bh
return (IfaceAppTy ae af)
3 -> do af <- get bh
+ aw <- get bh
ag <- get bh
ah <- get bh
- return (IfaceFunTy af ag ah)
+ return (IfaceFunTy af aw ag ah)
5 -> do { tc <- get bh; tys <- get bh
; return (IfaceTyConApp tc tys) }
6 -> do { a <- get bh; b <- get bh
@@ -1844,9 +1885,10 @@ instance Binary IfaceCoercion where
put_ bh a
put_ bh b
put_ bh c
- put_ bh (IfaceFunCo a b c) = do
+ put_ bh (IfaceFunCo a w b c) = do
putByte bh 3
put_ bh a
+ put_ bh w
put_ bh b
put_ bh c
put_ bh (IfaceTyConAppCo a b c) = do
@@ -1922,9 +1964,10 @@ instance Binary IfaceCoercion where
c <- get bh
return $ IfaceGReflCo a b c
3 -> do a <- get bh
+ w <- get bh
b <- get bh
c <- get bh
- return $ IfaceFunCo a b c
+ return $ IfaceFunCo a w b c
4 -> do a <- get bh
b <- get bh
c <- get bh
@@ -2008,7 +2051,7 @@ instance NFData IfaceType where
IfaceTyVar f1 -> rnf f1
IfaceLitTy f1 -> rnf f1
IfaceAppTy f1 f2 -> rnf f1 `seq` rnf f2
- IfaceFunTy f1 f2 f3 -> f1 `seq` rnf f2 `seq` rnf f3
+ IfaceFunTy f1 f2 f3 f4 -> f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4
IfaceForAllTy f1 f2 -> f1 `seq` rnf f2
IfaceTyConApp f1 f2 -> rnf f1 `seq` rnf f2
IfaceCastTy f1 f2 -> rnf f1 `seq` rnf f2
@@ -2024,7 +2067,7 @@ instance NFData IfaceCoercion where
rnf = \case
IfaceReflCo f1 -> rnf f1
IfaceGReflCo f1 f2 f3 -> f1 `seq` rnf f2 `seq` rnf f3
- IfaceFunCo f1 f2 f3 -> f1 `seq` rnf f2 `seq` rnf f3
+ IfaceFunCo f1 f2 f3 f4 -> f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4
IfaceTyConAppCo f1 f2 f3 -> f1 `seq` rnf f2 `seq` rnf f3
IfaceAppCo f1 f2 -> rnf f1 `seq` rnf f2
IfaceForAllCo f1 f2 f3 -> rnf f1 `seq` rnf f2 `seq` rnf f3