diff options
author | Krzysztof Gogolewski <krzysztof.gogolewski@tweag.io> | 2020-06-15 19:58:10 +0200 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-06-17 16:21:58 -0400 |
commit | 40fa237e1daab7a76b9871bb6c50b953a1addf23 (patch) | |
tree | 79751e932434be440ba35b4d65c54f25a437e134 /compiler/GHC/Iface | |
parent | 20616959a7f4821034e14a64c3c9bf288c9bc956 (diff) | |
download | haskell-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.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Iface/Ext/Ast.hs | 29 | ||||
-rw-r--r-- | compiler/GHC/Iface/Ext/Types.hs | 7 | ||||
-rw-r--r-- | compiler/GHC/Iface/Ext/Utils.hs | 12 | ||||
-rw-r--r-- | compiler/GHC/Iface/Load.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Iface/Make.hs | 25 | ||||
-rw-r--r-- | compiler/GHC/Iface/Rename.hs | 15 | ||||
-rw-r--r-- | compiler/GHC/Iface/Syntax.hs | 27 | ||||
-rw-r--r-- | compiler/GHC/Iface/Tidy.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Iface/Type.hs | 207 |
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 |