ghc-lib-parser 0.20200102 → 0.20200201
raw patch · 133 files changed
+14587/−7239 lines, 133 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- CmmType: AddrHint :: ForeignHint
- CmmType: NoHint :: ForeignHint
- CmmType: SignedHint :: ForeignHint
- CmmType: W128 :: Width
- CmmType: W16 :: Width
- CmmType: W256 :: Width
- CmmType: W32 :: Width
- CmmType: W512 :: Width
- CmmType: W64 :: Width
- CmmType: W8 :: Width
- CmmType: b128 :: CmmType
- CmmType: b16 :: CmmType
- CmmType: b256 :: CmmType
- CmmType: b32 :: CmmType
- CmmType: b512 :: CmmType
- CmmType: b64 :: CmmType
- CmmType: b8 :: CmmType
- CmmType: bHalfWord :: DynFlags -> CmmType
- CmmType: bWord :: DynFlags -> CmmType
- CmmType: cInt :: DynFlags -> CmmType
- CmmType: cIntWidth :: DynFlags -> Width
- CmmType: cmmBits :: Width -> CmmType
- CmmType: cmmEqType :: CmmType -> CmmType -> Bool
- CmmType: cmmEqType_ignoring_ptrhood :: CmmType -> CmmType -> Bool
- CmmType: cmmFloat :: Width -> CmmType
- CmmType: cmmVec :: Int -> CmmType -> CmmType
- CmmType: data CmmType
- CmmType: data ForeignHint
- CmmType: data Width
- CmmType: f32 :: CmmType
- CmmType: f64 :: CmmType
- CmmType: gcWord :: DynFlags -> CmmType
- CmmType: halfWordMask :: DynFlags -> Integer
- CmmType: halfWordWidth :: DynFlags -> Width
- CmmType: instance GHC.Classes.Eq CmmType.CmmCat
- CmmType: instance GHC.Classes.Eq CmmType.ForeignHint
- CmmType: instance GHC.Classes.Eq CmmType.Width
- CmmType: instance GHC.Classes.Ord CmmType.Width
- CmmType: instance GHC.Show.Show CmmType.Width
- CmmType: instance Outputable.Outputable CmmType.CmmCat
- CmmType: instance Outputable.Outputable CmmType.CmmType
- CmmType: instance Outputable.Outputable CmmType.Width
- CmmType: isBitsType :: CmmType -> Bool
- CmmType: isFloat32 :: CmmType -> Bool
- CmmType: isFloat64 :: CmmType -> Bool
- CmmType: isFloatType :: CmmType -> Bool
- CmmType: isGcPtrType :: CmmType -> Bool
- CmmType: isVecType :: CmmType -> Bool
- CmmType: isWord32 :: CmmType -> Bool
- CmmType: isWord64 :: CmmType -> Bool
- CmmType: narrowS :: Width -> Integer -> Integer
- CmmType: narrowU :: Width -> Integer -> Integer
- CmmType: rEP_CostCentreStack_mem_alloc :: DynFlags -> CmmType
- CmmType: rEP_CostCentreStack_scc_count :: DynFlags -> CmmType
- CmmType: rEP_StgEntCounter_allocd :: DynFlags -> CmmType
- CmmType: rEP_StgEntCounter_allocs :: DynFlags -> CmmType
- CmmType: type Length = Int
- CmmType: typeWidth :: CmmType -> Width
- CmmType: vec :: Length -> CmmType -> CmmType
- CmmType: vec16 :: CmmType -> CmmType
- CmmType: vec16b8 :: CmmType
- CmmType: vec2 :: CmmType -> CmmType
- CmmType: vec2b64 :: CmmType
- CmmType: vec2f64 :: CmmType
- CmmType: vec4 :: CmmType -> CmmType
- CmmType: vec4b32 :: CmmType
- CmmType: vec4f32 :: CmmType
- CmmType: vec8 :: CmmType -> CmmType
- CmmType: vec8b16 :: CmmType
- CmmType: vecElemType :: CmmType -> CmmType
- CmmType: vecLength :: CmmType -> Length
- CmmType: widthFromBytes :: Int -> Width
- CmmType: widthInBits :: Width -> Int
- CmmType: widthInBytes :: Width -> Int
- CmmType: widthInLog :: Width -> Int
- CmmType: wordWidth :: DynFlags -> Width
- DynFlags: GlobalPkgConf :: PkgConfRef
- DynFlags: PkgConfFile :: FilePath -> PkgConfRef
- DynFlags: UserPkgConf :: PkgConfRef
- DynFlags: [fileSettings_systemPackageConfig] :: FileSettings -> FilePath
- DynFlags: data PkgConfRef
- DynFlags: instance GHC.Classes.Eq DynFlags.PkgConfRef
- DynFlags: sSystemPackageConfig :: Settings -> FilePath
- DynFlags: systemPackageConfig :: DynFlags -> FilePath
- FileSettings: [fileSettings_systemPackageConfig] :: FileSettings -> FilePath
- GHC.Hs: instance Data.Data.Data (GHC.Hs.HsModule GHC.Hs.Extension.GhcPs)
- GHC.Hs: instance Data.Data.Data (GHC.Hs.HsModule GHC.Hs.Extension.GhcRn)
- GHC.Hs: instance Data.Data.Data (GHC.Hs.HsModule GHC.Hs.Extension.GhcTc)
- GHC.Hs: instance GHC.Hs.Extension.OutputableBndrId p => Outputable.Outputable (GHC.Hs.HsModule (GHC.Hs.Extension.GhcPass p))
- GHC.Hs.Types: splitLHsForAllTy :: LHsType pass -> ([LHsTyVarBndr pass], LHsType pass)
- GHC.Hs.Types: splitLHsSigmaTy :: LHsType pass -> ([LHsTyVarBndr pass], LHsContext pass, LHsType pass)
- IfaceSyn: AltPpr :: Maybe (OccName -> SDoc) -> AltPpr
- IfaceSyn: HasInfo :: [IfaceInfoItem] -> IfaceIdInfo
- IfaceSyn: HsArity :: Arity -> IfaceInfoItem
- IfaceSyn: HsInline :: InlinePragma -> IfaceInfoItem
- IfaceSyn: HsLevity :: IfaceInfoItem
- IfaceSyn: HsNoCafRefs :: IfaceInfoItem
- IfaceSyn: HsStrictness :: StrictSig -> IfaceInfoItem
- IfaceSyn: HsUnfold :: Bool -> IfaceUnfolding -> IfaceInfoItem
- IfaceSyn: IfAbstractClass :: IfaceClassBody
- IfaceSyn: IfAbstractTyCon :: IfaceConDecls
- IfaceSyn: IfCompulsory :: IfaceExpr -> IfaceUnfolding
- IfaceSyn: IfCon :: IfaceTopBndr -> Bool -> Bool -> [IfaceBndr] -> [IfaceForAllBndr] -> IfaceEqSpec -> IfaceContext -> [IfaceType] -> [FieldLabel] -> [IfaceBang] -> [IfaceSrcBang] -> IfaceConDecl
- IfaceSyn: IfConcreteClass :: IfaceContext -> [IfaceAT] -> [IfaceClassOp] -> BooleanFormula IfLclName -> IfaceClassBody
- IfaceSyn: IfCoreUnfold :: Bool -> IfaceExpr -> IfaceUnfolding
- IfaceSyn: IfDFunId :: IfaceIdDetails
- IfaceSyn: IfDFunUnfold :: [IfaceBndr] -> [IfaceExpr] -> IfaceUnfolding
- IfaceSyn: IfDataInstance :: IfExtName -> IfaceTyCon -> IfaceAppArgs -> IfaceTyConParent
- IfaceSyn: IfDataTyCon :: [IfaceConDecl] -> IfaceConDecls
- IfaceSyn: IfInlineRule :: Arity -> Bool -> Bool -> IfaceExpr -> IfaceUnfolding
- IfaceSyn: IfLetBndr :: IfLclName -> IfaceType -> IfaceIdInfo -> IfaceJoinInfo -> IfaceLetBndr
- IfaceSyn: IfNewTyCon :: IfaceConDecl -> IfaceConDecls
- IfaceSyn: IfNoBang :: IfaceBang
- IfaceSyn: IfNoParent :: IfaceTyConParent
- IfaceSyn: IfRecSelId :: Either IfaceTyCon IfaceDecl -> Bool -> IfaceIdDetails
- IfaceSyn: IfSrcBang :: SrcUnpackedness -> SrcStrictness -> IfaceSrcBang
- IfaceSyn: IfStrict :: IfaceBang
- IfaceSyn: IfUnpack :: IfaceBang
- IfaceSyn: IfUnpackCo :: IfaceCoercion -> IfaceBang
- IfaceSyn: IfVanillaId :: IfaceIdDetails
- IfaceSyn: IfaceAT :: IfaceDecl -> Maybe IfaceType -> IfaceAT
- IfaceSyn: IfaceAbstractClosedSynFamilyTyCon :: IfaceFamTyConFlav
- IfaceSyn: IfaceAnnotation :: IfaceAnnTarget -> AnnPayload -> IfaceAnnotation
- IfaceSyn: IfaceApp :: IfaceExpr -> IfaceExpr -> IfaceExpr
- IfaceSyn: IfaceAxBranch :: [IfaceTvBndr] -> [IfaceTvBndr] -> [IfaceIdBndr] -> IfaceAppArgs -> [Role] -> IfaceType -> [BranchIndex] -> IfaceAxBranch
- IfaceSyn: IfaceAxiom :: IfaceTopBndr -> IfaceTyCon -> Role -> [IfaceAxBranch] -> IfaceDecl
- IfaceSyn: IfaceBuiltInSynFamTyCon :: IfaceFamTyConFlav
- IfaceSyn: IfaceCase :: IfaceExpr -> IfLclName -> [IfaceAlt] -> IfaceExpr
- IfaceSyn: IfaceCast :: IfaceExpr -> IfaceCoercion -> IfaceExpr
- IfaceSyn: IfaceClass :: IfaceTopBndr -> [Role] -> [IfaceTyConBinder] -> [FunDep IfLclName] -> IfaceClassBody -> IfaceDecl
- IfaceSyn: IfaceClassOp :: IfaceTopBndr -> IfaceType -> Maybe (DefMethSpec IfaceType) -> IfaceClassOp
- IfaceSyn: IfaceClosedSynFamilyTyCon :: Maybe (IfExtName, [IfaceAxBranch]) -> IfaceFamTyConFlav
- IfaceSyn: IfaceClsInst :: IfExtName -> [Maybe IfaceTyCon] -> IfExtName -> OverlapFlag -> IsOrphan -> IfaceClsInst
- IfaceSyn: IfaceCo :: IfaceCoercion -> IfaceExpr
- IfaceSyn: IfaceCompleteMatch :: [IfExtName] -> IfExtName -> IfaceCompleteMatch
- IfaceSyn: IfaceData :: IfaceTopBndr -> [IfaceTyConBinder] -> IfaceType -> Maybe CType -> [Role] -> IfaceContext -> IfaceConDecls -> Bool -> IfaceTyConParent -> IfaceDecl
- IfaceSyn: IfaceDataAlt :: IfExtName -> IfaceConAlt
- IfaceSyn: IfaceDataFamilyTyCon :: IfaceFamTyConFlav
- IfaceSyn: IfaceDefault :: IfaceConAlt
- IfaceSyn: IfaceECase :: IfaceExpr -> IfaceType -> IfaceExpr
- IfaceSyn: IfaceExt :: IfExtName -> IfaceExpr
- IfaceSyn: IfaceFCall :: ForeignCall -> IfaceType -> IfaceExpr
- IfaceSyn: IfaceFamInst :: IfExtName -> [Maybe IfaceTyCon] -> IfExtName -> IsOrphan -> IfaceFamInst
- IfaceSyn: IfaceFamily :: IfaceTopBndr -> Maybe IfLclName -> [IfaceTyConBinder] -> IfaceKind -> IfaceFamTyConFlav -> Injectivity -> IfaceDecl
- IfaceSyn: IfaceHpcTick :: Module -> Int -> IfaceTickish
- IfaceSyn: IfaceId :: IfaceTopBndr -> IfaceType -> IfaceIdDetails -> IfaceIdInfo -> IfaceDecl
- IfaceSyn: IfaceJoinPoint :: JoinArity -> IfaceJoinInfo
- IfaceSyn: IfaceLam :: IfaceLamBndr -> IfaceExpr -> IfaceExpr
- IfaceSyn: IfaceLcl :: IfLclName -> IfaceExpr
- IfaceSyn: IfaceLet :: IfaceBinding -> IfaceExpr -> IfaceExpr
- IfaceSyn: IfaceLit :: Literal -> IfaceExpr
- IfaceSyn: IfaceLitAlt :: Literal -> IfaceConAlt
- IfaceSyn: IfaceNonRec :: IfaceLetBndr -> IfaceExpr -> IfaceBinding
- IfaceSyn: IfaceNotJoinPoint :: IfaceJoinInfo
- IfaceSyn: IfaceOpenSynFamilyTyCon :: IfaceFamTyConFlav
- IfaceSyn: IfacePatSyn :: IfaceTopBndr -> Bool -> (IfExtName, Bool) -> Maybe (IfExtName, Bool) -> [IfaceForAllBndr] -> [IfaceForAllBndr] -> IfaceContext -> IfaceContext -> [IfaceType] -> IfaceType -> [FieldLabel] -> IfaceDecl
- IfaceSyn: IfaceRec :: [(IfaceLetBndr, IfaceExpr)] -> IfaceBinding
- IfaceSyn: IfaceRule :: RuleName -> Activation -> [IfaceBndr] -> IfExtName -> [IfaceExpr] -> IfaceExpr -> Bool -> IsOrphan -> IfaceRule
- IfaceSyn: IfaceSCC :: CostCentre -> Bool -> Bool -> IfaceTickish
- IfaceSyn: IfaceSource :: RealSrcSpan -> String -> IfaceTickish
- IfaceSyn: IfaceSynonym :: IfaceTopBndr -> [Role] -> [IfaceTyConBinder] -> IfaceKind -> IfaceType -> IfaceDecl
- IfaceSyn: IfaceTick :: IfaceTickish -> IfaceExpr -> IfaceExpr
- IfaceSyn: IfaceTuple :: TupleSort -> [IfaceExpr] -> IfaceExpr
- IfaceSyn: IfaceType :: IfaceType -> IfaceExpr
- IfaceSyn: NoInfo :: IfaceIdInfo
- IfaceSyn: NoSrcStrict :: SrcStrictness
- IfaceSyn: NoSrcUnpack :: SrcUnpackedness
- IfaceSyn: ShowHeader :: AltPpr -> ShowHowMuch
- IfaceSyn: ShowIface :: ShowHowMuch
- IfaceSyn: ShowSome :: [OccName] -> AltPpr -> ShowHowMuch
- IfaceSyn: ShowSub :: ShowHowMuch -> ShowForAllFlag -> ShowSub
- IfaceSyn: SrcLazy :: SrcStrictness
- IfaceSyn: SrcNoUnpack :: SrcUnpackedness
- IfaceSyn: SrcStrict :: SrcStrictness
- IfaceSyn: SrcUnpack :: SrcUnpackedness
- IfaceSyn: [ifATs] :: IfaceClassBody -> [IfaceAT]
- IfaceSyn: [ifActivation] :: IfaceRule -> Activation
- IfaceSyn: [ifAnnotatedTarget] :: IfaceAnnotation -> IfaceAnnTarget
- IfaceSyn: [ifAnnotatedValue] :: IfaceAnnotation -> AnnPayload
- IfaceSyn: [ifAxBranches] :: IfaceDecl -> [IfaceAxBranch]
- IfaceSyn: [ifBinders] :: IfaceDecl -> [IfaceTyConBinder]
- IfaceSyn: [ifBody] :: IfaceDecl -> IfaceClassBody
- IfaceSyn: [ifCType] :: IfaceDecl -> Maybe CType
- IfaceSyn: [ifClassCtxt] :: IfaceClassBody -> IfaceContext
- IfaceSyn: [ifConArgTys] :: IfaceConDecl -> [IfaceType]
- IfaceSyn: [ifConCtxt] :: IfaceConDecl -> IfaceContext
- IfaceSyn: [ifConEqSpec] :: IfaceConDecl -> IfaceEqSpec
- IfaceSyn: [ifConExTCvs] :: IfaceConDecl -> [IfaceBndr]
- IfaceSyn: [ifConFields] :: IfaceConDecl -> [FieldLabel]
- IfaceSyn: [ifConInfix] :: IfaceConDecl -> Bool
- IfaceSyn: [ifConName] :: IfaceConDecl -> IfaceTopBndr
- IfaceSyn: [ifConSrcStricts] :: IfaceConDecl -> [IfaceSrcBang]
- IfaceSyn: [ifConStricts] :: IfaceConDecl -> [IfaceBang]
- IfaceSyn: [ifConUserTvBinders] :: IfaceConDecl -> [IfaceForAllBndr]
- IfaceSyn: [ifConWrapper] :: IfaceConDecl -> Bool
- IfaceSyn: [ifCons] :: IfaceDecl -> IfaceConDecls
- IfaceSyn: [ifCtxt] :: IfaceDecl -> IfaceContext
- IfaceSyn: [ifDFun] :: IfaceClsInst -> IfExtName
- IfaceSyn: [ifFDs] :: IfaceDecl -> [FunDep IfLclName]
- IfaceSyn: [ifFamFlav] :: IfaceDecl -> IfaceFamTyConFlav
- IfaceSyn: [ifFamInj] :: IfaceDecl -> Injectivity
- IfaceSyn: [ifFamInstAxiom] :: IfaceFamInst -> IfExtName
- IfaceSyn: [ifFamInstFam] :: IfaceFamInst -> IfExtName
- IfaceSyn: [ifFamInstOrph] :: IfaceFamInst -> IsOrphan
- IfaceSyn: [ifFamInstTys] :: IfaceFamInst -> [Maybe IfaceTyCon]
- IfaceSyn: [ifFieldLabels] :: IfaceDecl -> [FieldLabel]
- IfaceSyn: [ifGadtSyntax] :: IfaceDecl -> Bool
- IfaceSyn: [ifIdDetails] :: IfaceDecl -> IfaceIdDetails
- IfaceSyn: [ifIdInfo] :: IfaceDecl -> IfaceIdInfo
- IfaceSyn: [ifInstCls] :: IfaceClsInst -> IfExtName
- IfaceSyn: [ifInstOrph] :: IfaceClsInst -> IsOrphan
- IfaceSyn: [ifInstTys] :: IfaceClsInst -> [Maybe IfaceTyCon]
- IfaceSyn: [ifMinDef] :: IfaceClassBody -> BooleanFormula IfLclName
- IfaceSyn: [ifName] :: IfaceDecl -> IfaceTopBndr
- IfaceSyn: [ifOFlag] :: IfaceClsInst -> OverlapFlag
- IfaceSyn: [ifParent] :: IfaceDecl -> IfaceTyConParent
- IfaceSyn: [ifPatArgs] :: IfaceDecl -> [IfaceType]
- IfaceSyn: [ifPatBuilder] :: IfaceDecl -> Maybe (IfExtName, Bool)
- IfaceSyn: [ifPatExBndrs] :: IfaceDecl -> [IfaceForAllBndr]
- IfaceSyn: [ifPatIsInfix] :: IfaceDecl -> Bool
- IfaceSyn: [ifPatMatcher] :: IfaceDecl -> (IfExtName, Bool)
- IfaceSyn: [ifPatProvCtxt] :: IfaceDecl -> IfaceContext
- IfaceSyn: [ifPatReqCtxt] :: IfaceDecl -> IfaceContext
- IfaceSyn: [ifPatTy] :: IfaceDecl -> IfaceType
- IfaceSyn: [ifPatUnivBndrs] :: IfaceDecl -> [IfaceForAllBndr]
- IfaceSyn: [ifResKind] :: IfaceDecl -> IfaceKind
- IfaceSyn: [ifResVar] :: IfaceDecl -> Maybe IfLclName
- IfaceSyn: [ifRole] :: IfaceDecl -> Role
- IfaceSyn: [ifRoles] :: IfaceDecl -> [Role]
- IfaceSyn: [ifRuleArgs] :: IfaceRule -> [IfaceExpr]
- IfaceSyn: [ifRuleAuto] :: IfaceRule -> Bool
- IfaceSyn: [ifRuleBndrs] :: IfaceRule -> [IfaceBndr]
- IfaceSyn: [ifRuleHead] :: IfaceRule -> IfExtName
- IfaceSyn: [ifRuleName] :: IfaceRule -> RuleName
- IfaceSyn: [ifRuleOrph] :: IfaceRule -> IsOrphan
- IfaceSyn: [ifRuleRhs] :: IfaceRule -> IfaceExpr
- IfaceSyn: [ifSigs] :: IfaceClassBody -> [IfaceClassOp]
- IfaceSyn: [ifSynRhs] :: IfaceDecl -> IfaceType
- IfaceSyn: [ifTyCon] :: IfaceDecl -> IfaceTyCon
- IfaceSyn: [ifType] :: IfaceDecl -> IfaceType
- IfaceSyn: [ifaxbCoVars] :: IfaceAxBranch -> [IfaceIdBndr]
- IfaceSyn: [ifaxbEtaTyVars] :: IfaceAxBranch -> [IfaceTvBndr]
- IfaceSyn: [ifaxbIncomps] :: IfaceAxBranch -> [BranchIndex]
- IfaceSyn: [ifaxbLHS] :: IfaceAxBranch -> IfaceAppArgs
- IfaceSyn: [ifaxbRHS] :: IfaceAxBranch -> IfaceType
- IfaceSyn: [ifaxbRoles] :: IfaceAxBranch -> [Role]
- IfaceSyn: [ifaxbTyVars] :: IfaceAxBranch -> [IfaceTvBndr]
- IfaceSyn: [ss_forall] :: ShowSub -> ShowForAllFlag
- IfaceSyn: [ss_how_much] :: ShowSub -> ShowHowMuch
- IfaceSyn: data IfaceAT
- IfaceSyn: data IfaceAnnotation
- IfaceSyn: data IfaceAxBranch
- IfaceSyn: data IfaceBang
- IfaceSyn: data IfaceBinding
- IfaceSyn: data IfaceClassBody
- IfaceSyn: data IfaceClassOp
- IfaceSyn: data IfaceClsInst
- IfaceSyn: data IfaceCompleteMatch
- IfaceSyn: data IfaceConAlt
- IfaceSyn: data IfaceConDecl
- IfaceSyn: data IfaceConDecls
- IfaceSyn: data IfaceDecl
- IfaceSyn: data IfaceExpr
- IfaceSyn: data IfaceFamInst
- IfaceSyn: data IfaceFamTyConFlav
- IfaceSyn: data IfaceIdDetails
- IfaceSyn: data IfaceIdInfo
- IfaceSyn: data IfaceInfoItem
- IfaceSyn: data IfaceJoinInfo
- IfaceSyn: data IfaceLetBndr
- IfaceSyn: data IfaceRule
- IfaceSyn: data IfaceSrcBang
- IfaceSyn: data IfaceTickish
- IfaceSyn: data IfaceTyConParent
- IfaceSyn: data IfaceUnfolding
- IfaceSyn: data ShowHowMuch
- IfaceSyn: data ShowSub
- IfaceSyn: data SrcStrictness
- IfaceSyn: data SrcUnpackedness
- IfaceSyn: freeNamesIfDecl :: IfaceDecl -> NameSet
- IfaceSyn: freeNamesIfFamInst :: IfaceFamInst -> NameSet
- IfaceSyn: freeNamesIfRule :: IfaceRule -> NameSet
- IfaceSyn: getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr
- IfaceSyn: ifaceDeclFingerprints :: Fingerprint -> IfaceDecl -> [(OccName, Fingerprint)]
- IfaceSyn: ifaceDeclImplicitBndrs :: IfaceDecl -> [OccName]
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceAT
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceAnnotation
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceAxBranch
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceBang
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceBinding
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceClassOp
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceClsInst
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceCompleteMatch
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceConAlt
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceConDecl
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceConDecls
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceDecl
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceExpr
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceFamInst
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceFamTyConFlav
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceIdDetails
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceIdInfo
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceInfoItem
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceJoinInfo
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceLetBndr
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceRule
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceSrcBang
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceTickish
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceTyConParent
- IfaceSyn: instance Binary.Binary IfaceSyn.IfaceUnfolding
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceAT
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceAnnotation
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceAxBranch
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceBang
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceBinding
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceClassBody
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceClassOp
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceClsInst
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceCompleteMatch
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceConAlt
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceConDecl
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceConDecls
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceDecl
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceExpr
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceFamInst
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceFamTyConFlav
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceIdDetails
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceIdInfo
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceInfoItem
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceJoinInfo
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceLetBndr
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceRule
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceSrcBang
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceTickish
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceTyConParent
- IfaceSyn: instance Control.DeepSeq.NFData IfaceSyn.IfaceUnfolding
- IfaceSyn: instance Name.NamedThing IfaceSyn.IfaceClassOp
- IfaceSyn: instance Name.NamedThing IfaceSyn.IfaceConDecl
- IfaceSyn: instance Name.NamedThing IfaceSyn.IfaceDecl
- IfaceSyn: instance OccName.HasOccName IfaceSyn.IfaceClassOp
- IfaceSyn: instance OccName.HasOccName IfaceSyn.IfaceConDecl
- IfaceSyn: instance OccName.HasOccName IfaceSyn.IfaceDecl
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceAT
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceAnnotation
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceClassOp
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceClsInst
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceCompleteMatch
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceConAlt
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceDecl
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceExpr
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceFamInst
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceIdDetails
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceIdInfo
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceInfoItem
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceJoinInfo
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceRule
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceTyConParent
- IfaceSyn: instance Outputable.Outputable IfaceSyn.IfaceUnfolding
- IfaceSyn: instance Outputable.Outputable IfaceSyn.ShowHowMuch
- IfaceSyn: newtype AltPpr
- IfaceSyn: pprIfaceDecl :: ShowSub -> IfaceDecl -> SDoc
- IfaceSyn: pprIfaceExpr :: (SDoc -> SDoc) -> IfaceExpr -> SDoc
- IfaceSyn: putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO ()
- IfaceSyn: showToHeader :: ShowSub
- IfaceSyn: showToIface :: ShowSub
- IfaceSyn: type IfaceAlt = (IfaceConAlt, [IfLclName], IfaceExpr)
- IfaceSyn: type IfaceAnnTarget = AnnTarget OccName
- IfaceSyn: type IfaceEqSpec = [(IfLclName, IfaceType)]
- IfaceSyn: type IfaceTopBndr = Name
- IfaceSyn: visibleIfConDecls :: IfaceConDecls -> [IfaceConDecl]
- IfaceType: ForallInvis :: ForallVisFlag
- IfaceType: ForallVis :: ForallVisFlag
- IfaceType: IA_Arg :: IfaceType -> ArgFlag -> IfaceAppArgs -> IfaceAppArgs
- IfaceType: IA_Nil :: IfaceAppArgs
- IfaceType: IfaceAppCo :: IfaceCoercion -> IfaceCoercion -> IfaceCoercion
- IfaceType: IfaceAppTy :: IfaceType -> IfaceAppArgs -> IfaceType
- IfaceType: IfaceAxiomInstCo :: IfExtName -> BranchIndex -> [IfaceCoercion] -> IfaceCoercion
- IfaceType: IfaceAxiomRuleCo :: IfLclName -> [IfaceCoercion] -> IfaceCoercion
- IfaceType: IfaceCastTy :: IfaceType -> IfaceCoercion -> IfaceType
- IfaceType: IfaceCoVarCo :: IfLclName -> IfaceCoercion
- IfaceType: IfaceCoercionTy :: IfaceCoercion -> IfaceType
- IfaceType: IfaceEqualityTyCon :: IfaceTyConSort
- IfaceType: IfaceForAllCo :: IfaceBndr -> IfaceCoercion -> IfaceCoercion -> IfaceCoercion
- IfaceType: IfaceForAllTy :: IfaceForAllBndr -> IfaceType -> IfaceType
- IfaceType: IfaceFreeCoVar :: CoVar -> IfaceCoercion
- IfaceType: IfaceFreeTyVar :: TyVar -> IfaceType
- IfaceType: IfaceFunCo :: Role -> IfaceCoercion -> IfaceCoercion -> IfaceCoercion
- IfaceType: IfaceFunTy :: AnonArgFlag -> IfaceType -> IfaceType -> IfaceType
- IfaceType: IfaceGReflCo :: Role -> IfaceType -> IfaceMCoercion -> IfaceCoercion
- IfaceType: IfaceHoleCo :: CoVar -> IfaceCoercion
- IfaceType: IfaceIdBndr :: {-# UNPACK #-} !IfaceIdBndr -> IfaceBndr
- IfaceType: IfaceInstCo :: IfaceCoercion -> IfaceCoercion -> IfaceCoercion
- IfaceType: IfaceKindCo :: IfaceCoercion -> IfaceCoercion
- IfaceType: IfaceLRCo :: LeftOrRight -> IfaceCoercion -> IfaceCoercion
- IfaceType: IfaceLitTy :: IfaceTyLit -> IfaceType
- IfaceType: IfaceMCo :: IfaceCoercion -> IfaceMCoercion
- IfaceType: IfaceMRefl :: IfaceMCoercion
- IfaceType: IfaceNoOneShot :: IfaceOneShot
- IfaceType: IfaceNormalTyCon :: IfaceTyConSort
- IfaceType: IfaceNthCo :: Int -> IfaceCoercion -> IfaceCoercion
- IfaceType: IfaceNumTyLit :: Integer -> IfaceTyLit
- IfaceType: IfaceOneShot :: IfaceOneShot
- IfaceType: IfacePhantomProv :: IfaceCoercion -> IfaceUnivCoProv
- IfaceType: IfacePluginProv :: String -> IfaceUnivCoProv
- IfaceType: IfaceProofIrrelProv :: IfaceCoercion -> IfaceUnivCoProv
- IfaceType: IfaceReflCo :: IfaceType -> IfaceCoercion
- IfaceType: IfaceStrTyLit :: FastString -> IfaceTyLit
- IfaceType: IfaceSubCo :: IfaceCoercion -> IfaceCoercion
- IfaceType: IfaceSumTyCon :: !Arity -> IfaceTyConSort
- IfaceType: IfaceSymCo :: IfaceCoercion -> IfaceCoercion
- IfaceType: IfaceTransCo :: IfaceCoercion -> IfaceCoercion -> IfaceCoercion
- IfaceType: IfaceTupleTy :: TupleSort -> PromotionFlag -> IfaceAppArgs -> IfaceType
- IfaceType: IfaceTupleTyCon :: !Arity -> !TupleSort -> IfaceTyConSort
- IfaceType: IfaceTvBndr :: {-# UNPACK #-} !IfaceTvBndr -> IfaceBndr
- IfaceType: IfaceTyCon :: IfExtName -> IfaceTyConInfo -> IfaceTyCon
- IfaceType: IfaceTyConApp :: IfaceTyCon -> IfaceAppArgs -> IfaceType
- IfaceType: IfaceTyConAppCo :: Role -> IfaceTyCon -> [IfaceCoercion] -> IfaceCoercion
- IfaceType: IfaceTyConInfo :: PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
- IfaceType: IfaceTyVar :: IfLclName -> IfaceType
- IfaceType: IfaceUnivCo :: IfaceUnivCoProv -> Role -> IfaceType -> IfaceType -> IfaceCoercion
- IfaceType: IfaceUnsafeCoerceProv :: IfaceUnivCoProv
- IfaceType: Inferred :: ArgFlag
- IfaceType: InvisArg :: AnonArgFlag
- IfaceType: Required :: ArgFlag
- IfaceType: ShowForAllMust :: ShowForAllFlag
- IfaceType: ShowForAllWhen :: ShowForAllFlag
- IfaceType: Specified :: ArgFlag
- IfaceType: SuppressBndrSig :: Bool -> SuppressBndrSig
- IfaceType: UseBndrParens :: Bool -> UseBndrParens
- IfaceType: VisArg :: AnonArgFlag
- IfaceType: [ifaceTyConInfo] :: IfaceTyCon -> IfaceTyConInfo
- IfaceType: [ifaceTyConIsPromoted] :: IfaceTyConInfo -> PromotionFlag
- IfaceType: [ifaceTyConName] :: IfaceTyCon -> IfExtName
- IfaceType: [ifaceTyConSort] :: IfaceTyConInfo -> IfaceTyConSort
- IfaceType: appArgsIfaceTypes :: IfaceAppArgs -> [IfaceType]
- IfaceType: appArgsIfaceTypesArgFlags :: IfaceAppArgs -> [(IfaceType, ArgFlag)]
- IfaceType: data AnonArgFlag
- IfaceType: data ArgFlag
- IfaceType: data ForallVisFlag
- IfaceType: data IfaceAppArgs
- IfaceType: data IfaceBndr
- IfaceType: data IfaceCoercion
- IfaceType: data IfaceMCoercion
- IfaceType: data IfaceOneShot
- IfaceType: data IfaceTyCon
- IfaceType: data IfaceTyConInfo
- IfaceType: data IfaceTyConSort
- IfaceType: data IfaceTyLit
- IfaceType: data IfaceType
- IfaceType: data IfaceUnivCoProv
- IfaceType: data ShowForAllFlag
- IfaceType: ifForAllBndrName :: IfaceForAllBndr -> IfLclName
- IfaceType: ifForAllBndrVar :: IfaceForAllBndr -> IfaceBndr
- IfaceType: ifTyConBinderName :: IfaceTyConBinder -> IfLclName
- IfaceType: ifTyConBinderVar :: IfaceTyConBinder -> IfaceBndr
- IfaceType: ifaceBndrName :: IfaceBndr -> IfLclName
- IfaceType: inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool
- IfaceType: instance Binary.Binary (BasicTypes.DefMethSpec IfaceType.IfaceType)
- IfaceType: instance Binary.Binary IfaceType.IfaceAppArgs
- IfaceType: instance Binary.Binary IfaceType.IfaceBndr
- IfaceType: instance Binary.Binary IfaceType.IfaceCoercion
- IfaceType: instance Binary.Binary IfaceType.IfaceMCoercion
- IfaceType: instance Binary.Binary IfaceType.IfaceOneShot
- IfaceType: instance Binary.Binary IfaceType.IfaceTyCon
- IfaceType: instance Binary.Binary IfaceType.IfaceTyConInfo
- IfaceType: instance Binary.Binary IfaceType.IfaceTyConSort
- IfaceType: instance Binary.Binary IfaceType.IfaceTyLit
- IfaceType: instance Binary.Binary IfaceType.IfaceType
- IfaceType: instance Binary.Binary IfaceType.IfaceUnivCoProv
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceAppArgs
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceBndr
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceCoercion
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceMCoercion
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceOneShot
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceTyCon
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceTyConInfo
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceTyConSort
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceTyLit
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceType
- IfaceType: instance Control.DeepSeq.NFData IfaceType.IfaceUnivCoProv
- IfaceType: instance GHC.Base.Monoid IfaceType.IfaceAppArgs
- IfaceType: instance GHC.Base.Semigroup IfaceType.IfaceAppArgs
- IfaceType: instance GHC.Classes.Eq IfaceType.IfaceTyCon
- IfaceType: instance GHC.Classes.Eq IfaceType.IfaceTyConInfo
- IfaceType: instance GHC.Classes.Eq IfaceType.IfaceTyConSort
- IfaceType: instance GHC.Classes.Eq IfaceType.IfaceTyLit
- IfaceType: instance Outputable.Outputable IfaceType.IfaceAppArgs
- IfaceType: instance Outputable.Outputable IfaceType.IfaceBndr
- IfaceType: instance Outputable.Outputable IfaceType.IfaceCoercion
- IfaceType: instance Outputable.Outputable IfaceType.IfaceTyCon
- IfaceType: instance Outputable.Outputable IfaceType.IfaceTyLit
- IfaceType: instance Outputable.Outputable IfaceType.IfaceType
- IfaceType: isIfaceLiftedTypeKind :: IfaceKind -> Bool
- IfaceType: isIfaceTauType :: IfaceType -> Bool
- IfaceType: mkIfaceForAllTvBndr :: ArgFlag -> IfaceTvBndr -> IfaceForAllBndr
- IfaceType: mkIfaceTyConKind :: [IfaceTyConBinder] -> IfaceKind -> IfaceKind
- IfaceType: mkIfaceTySubst :: [(IfLclName, IfaceType)] -> IfaceTySubst
- IfaceType: newtype SuppressBndrSig
- IfaceType: newtype UseBndrParens
- IfaceType: pprIfaceAppArgs :: IfaceAppArgs -> SDoc
- IfaceType: pprIfaceBndrs :: [IfaceBndr] -> SDoc
- IfaceType: pprIfaceCoTcApp :: PprPrec -> IfaceTyCon -> [IfaceCoercion] -> SDoc
- IfaceType: pprIfaceCoercion :: IfaceCoercion -> SDoc
- IfaceType: pprIfaceContext :: PprPrec -> [IfacePredType] -> SDoc
- IfaceType: pprIfaceContextArr :: [IfacePredType] -> SDoc
- IfaceType: pprIfaceForAll :: [IfaceForAllBndr] -> SDoc
- IfaceType: pprIfaceForAllPart :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc
- IfaceType: pprIfaceForAllPartMust :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc
- IfaceType: pprIfaceIdBndr :: IfaceIdBndr -> SDoc
- IfaceType: pprIfaceLamBndr :: IfaceLamBndr -> SDoc
- IfaceType: pprIfacePrefixApp :: PprPrec -> SDoc -> [SDoc] -> SDoc
- IfaceType: pprIfaceSigmaType :: ShowForAllFlag -> IfaceType -> SDoc
- IfaceType: pprIfaceTvBndr :: IfaceTvBndr -> SuppressBndrSig -> UseBndrParens -> SDoc
- IfaceType: pprIfaceTyConBinders :: SuppressBndrSig -> [IfaceTyConBinder] -> SDoc
- IfaceType: pprIfaceTyLit :: IfaceTyLit -> SDoc
- IfaceType: pprIfaceType :: IfaceType -> SDoc
- IfaceType: pprIfaceTypeApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
- IfaceType: pprParendIfaceAppArgs :: IfaceAppArgs -> SDoc
- IfaceType: pprParendIfaceCoercion :: IfaceCoercion -> SDoc
- IfaceType: pprParendIfaceType :: IfaceType -> SDoc
- IfaceType: pprPrecIfaceType :: PprPrec -> IfaceType -> SDoc
- IfaceType: pprTyTcApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
- IfaceType: pprUserIfaceForAll :: [IfaceForAllBndr] -> SDoc
- IfaceType: splitIfaceSigmaTy :: IfaceType -> ([IfaceForAllBndr], [IfacePredType], IfaceType)
- IfaceType: stripIfaceInvisVars :: DynFlags -> [IfaceTyConBinder] -> [IfaceTyConBinder]
- IfaceType: stripInvisArgs :: DynFlags -> IfaceAppArgs -> IfaceAppArgs
- IfaceType: substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
- IfaceType: substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType
- IfaceType: suppressIfaceInvisibles :: DynFlags -> [IfaceTyConBinder] -> [a] -> [a]
- IfaceType: type IfExtName = Name
- IfaceType: type IfLclName = FastString
- IfaceType: type IfaceContext = [IfacePredType]
- IfaceType: type IfaceForAllBndr = VarBndr IfaceBndr ArgFlag
- IfaceType: type IfaceIdBndr = (IfLclName, IfaceType)
- IfaceType: type IfaceKind = IfaceType
- IfaceType: type IfaceLamBndr = (IfaceBndr, IfaceOneShot)
- IfaceType: type IfacePredType = IfaceType
- IfaceType: type IfaceTvBndr = (IfLclName, IfaceKind)
- IfaceType: type IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis
- Language.Haskell.TH.Syntax: bindQ :: Q a -> (a -> Q b) -> Q b
- Language.Haskell.TH.Syntax: returnQ :: a -> Q a
- PackageConfig: ComponentId :: FastString -> ComponentId
- PackageConfig: InstalledPackageInfo :: instunitid -> compid -> [(modulename, mod)] -> srcpkgid -> srcpkgname -> Version -> Maybe srcpkgname -> String -> [instunitid] -> [(instunitid, String)] -> [FilePath] -> [String] -> [String] -> [String] -> [FilePath] -> [FilePath] -> [String] -> [FilePath] -> [String] -> [String] -> [String] -> [FilePath] -> [FilePath] -> [FilePath] -> [(modulename, Maybe mod)] -> [modulename] -> Bool -> Bool -> Bool -> InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod
- PackageConfig: PackageName :: FastString -> PackageName
- PackageConfig: SourcePackageId :: FastString -> SourcePackageId
- PackageConfig: Version :: [Int] -> [String] -> Version
- PackageConfig: [abiDepends] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [(instunitid, String)]
- PackageConfig: [abiHash] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> String
- PackageConfig: [ccOptions] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
- PackageConfig: [componentId] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> compid
- PackageConfig: [depends] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [instunitid]
- PackageConfig: [exposedModules] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [(modulename, Maybe mod)]
- PackageConfig: [exposed] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> Bool
- PackageConfig: [extraGHCiLibraries] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
- PackageConfig: [extraLibraries] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
- PackageConfig: [frameworkDirs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
- PackageConfig: [frameworks] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
- PackageConfig: [haddockHTMLs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
- PackageConfig: [haddockInterfaces] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
- PackageConfig: [hiddenModules] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [modulename]
- PackageConfig: [hsLibraries] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
- PackageConfig: [importDirs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
- PackageConfig: [includeDirs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
- PackageConfig: [includes] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
- PackageConfig: [indefinite] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> Bool
- PackageConfig: [instantiatedWith] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [(modulename, mod)]
- PackageConfig: [ldOptions] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
- PackageConfig: [libraryDirs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
- PackageConfig: [libraryDynDirs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
- PackageConfig: [packageName] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> srcpkgname
- PackageConfig: [packageVersion] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> Version
- PackageConfig: [sourceLibName] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> Maybe srcpkgname
- PackageConfig: [sourcePackageId] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> srcpkgid
- PackageConfig: [trusted] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> Bool
- PackageConfig: [unitId] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> instunitid
- PackageConfig: [versionBranch] :: Version -> [Int]
- PackageConfig: [versionTags] :: Version -> [String]
- PackageConfig: data InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod
- PackageConfig: data Version
- PackageConfig: defaultPackageConfig :: PackageConfig
- PackageConfig: definitePackageConfigId :: PackageConfig -> Maybe DefUnitId
- PackageConfig: expandedPackageConfigId :: PackageConfig -> UnitId
- PackageConfig: installedPackageConfigId :: PackageConfig -> InstalledUnitId
- PackageConfig: instance GHC.Classes.Eq PackageConfig.PackageName
- PackageConfig: instance GHC.Classes.Eq PackageConfig.SourcePackageId
- PackageConfig: instance GHC.Classes.Ord PackageConfig.PackageName
- PackageConfig: instance GHC.Classes.Ord PackageConfig.SourcePackageId
- PackageConfig: instance GHC.PackageDb.BinaryStringRep PackageConfig.PackageName
- PackageConfig: instance GHC.PackageDb.BinaryStringRep PackageConfig.SourcePackageId
- PackageConfig: instance Outputable.Outputable PackageConfig.PackageName
- PackageConfig: instance Outputable.Outputable PackageConfig.SourcePackageId
- PackageConfig: instance Unique.Uniquable PackageConfig.PackageName
- PackageConfig: instance Unique.Uniquable PackageConfig.SourcePackageId
- PackageConfig: newtype ComponentId
- PackageConfig: newtype PackageName
- PackageConfig: newtype SourcePackageId
- PackageConfig: packageConfigId :: PackageConfig -> UnitId
- PackageConfig: packageNameString :: PackageConfig -> String
- PackageConfig: pprPackageConfig :: PackageConfig -> SDoc
- PackageConfig: sourcePackageIdString :: PackageConfig -> String
- PackageConfig: type PackageConfig = InstalledPackageInfo ComponentId SourcePackageId PackageName InstalledUnitId UnitId ModuleName Module
- Packages: data PackageConfigMap
- Packages: getPackageConfigMap :: DynFlags -> PackageConfigMap
- Packages: listPackageConfigMap :: DynFlags -> [PackageConfig]
- Packages: lookupPackage :: DynFlags -> UnitId -> Maybe PackageConfig
- Packages: lookupPackage' :: Bool -> PackageConfigMap -> UnitId -> Maybe PackageConfig
- Packages: readPackageConfig :: DynFlags -> FilePath -> IO (FilePath, [PackageConfig])
- Packages: readPackageConfigs :: DynFlags -> IO [(FilePath, [PackageConfig])]
- Packages: resolvePackageConfig :: DynFlags -> PkgConfRef -> IO (Maybe FilePath)
- Settings: sSystemPackageConfig :: Settings -> FilePath
- ToIface: patSynToIfaceDecl :: PatSyn -> IfaceDecl
- ToIface: tidyToIfaceContext :: TidyEnv -> ThetaType -> IfaceContext
- ToIface: tidyToIfaceTcArgs :: TidyEnv -> TyCon -> [Type] -> IfaceAppArgs
- ToIface: tidyToIfaceType :: TidyEnv -> Type -> IfaceType
- ToIface: toIfUnfolding :: Bool -> Unfolding -> Maybe IfaceInfoItem
- ToIface: toIfaceAlt :: (AltCon, [Var], CoreExpr) -> (IfaceConAlt, [FastString], IfaceExpr)
- ToIface: toIfaceApp :: Expr CoreBndr -> [Arg CoreBndr] -> IfaceExpr
- ToIface: toIfaceBang :: TidyEnv -> HsImplBang -> IfaceBang
- ToIface: toIfaceBind :: Bind Id -> IfaceBinding
- ToIface: toIfaceBndr :: Var -> IfaceBndr
- ToIface: toIfaceCoercion :: Coercion -> IfaceCoercion
- ToIface: toIfaceCoercionX :: VarSet -> Coercion -> IfaceCoercion
- ToIface: toIfaceCon :: AltCon -> IfaceConAlt
- ToIface: toIfaceExpr :: CoreExpr -> IfaceExpr
- ToIface: toIfaceForAllBndr :: TyCoVarBinder -> IfaceForAllBndr
- ToIface: toIfaceIdBndr :: Id -> IfaceIdBndr
- ToIface: toIfaceIdDetails :: IdDetails -> IfaceIdDetails
- ToIface: toIfaceIdInfo :: IdInfo -> IfaceIdInfo
- ToIface: toIfaceKind :: Type -> IfaceType
- ToIface: toIfaceLetBndr :: Id -> IfaceLetBndr
- ToIface: toIfaceOneShot :: Id -> IfaceOneShot
- ToIface: toIfaceSrcBang :: HsSrcBang -> IfaceSrcBang
- ToIface: toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs
- ToIface: toIfaceTickish :: Tickish Id -> Maybe IfaceTickish
- ToIface: toIfaceTvBndr :: TyVar -> IfaceTvBndr
- ToIface: toIfaceTvBndrs :: [TyVar] -> [IfaceTvBndr]
- ToIface: toIfaceTyCoVarBinders :: [VarBndr Var vis] -> [VarBndr IfaceBndr vis]
- ToIface: toIfaceTyCon :: TyCon -> IfaceTyCon
- ToIface: toIfaceTyCon_name :: Name -> IfaceTyCon
- ToIface: toIfaceTyLit :: TyLit -> IfaceTyLit
- ToIface: toIfaceTyVar :: TyVar -> FastString
- ToIface: toIfaceType :: Type -> IfaceType
- ToIface: toIfaceTypeX :: VarSet -> Type -> IfaceType
- ToIface: toIfaceVar :: Id -> IfaceExpr
+ DynFlags: GlobalPkgDb :: PkgDbRef
+ DynFlags: PkgDbPath :: FilePath -> PkgDbRef
+ DynFlags: UserPkgDb :: PkgDbRef
+ DynFlags: [fileSettings_globalPackageDatabase] :: FileSettings -> FilePath
+ DynFlags: data PkgDbRef
+ DynFlags: globalPackageDatabasePath :: DynFlags -> FilePath
+ DynFlags: instance GHC.Classes.Eq DynFlags.PkgDbRef
+ DynFlags: sGlobalPackageDatabasePath :: Settings -> FilePath
+ FileSettings: [fileSettings_globalPackageDatabase] :: FileSettings -> FilePath
+ GHC.Cmm: BasicBlock :: BlockId -> [i] -> GenBasicBlock i
+ GHC.Cmm: BlackHole :: ClosureTypeInfo
+ GHC.Cmm: CString :: SectionType
+ GHC.Cmm: CmmData :: Section -> d -> GenCmmDecl d h g
+ GHC.Cmm: CmmGraph :: BlockId -> Graph n C C -> GenCmmGraph n
+ GHC.Cmm: CmmInfoTable :: CLabel -> SMRep -> ProfilingInfo -> Maybe CLabel -> Maybe (Id, CostCentreStack) -> CmmInfoTable
+ GHC.Cmm: CmmProc :: h -> CLabel -> [GlobalReg] -> g -> GenCmmDecl d h g
+ GHC.Cmm: CmmStaticLit :: CmmLit -> CmmStatic
+ GHC.Cmm: CmmString :: ByteString -> CmmStatic
+ GHC.Cmm: CmmUninitialised :: Int -> CmmStatic
+ GHC.Cmm: Constr :: ConTagZ -> ConstrDescription -> ClosureTypeInfo
+ GHC.Cmm: Data :: SectionType
+ GHC.Cmm: Fun :: FunArity -> ArgDescr -> ClosureTypeInfo
+ GHC.Cmm: IndStatic :: ClosureTypeInfo
+ GHC.Cmm: ListGraph :: [GenBasicBlock i] -> ListGraph i
+ GHC.Cmm: NoProfilingInfo :: ProfilingInfo
+ GHC.Cmm: OtherSection :: String -> SectionType
+ GHC.Cmm: ProfilingInfo :: ByteString -> ByteString -> ProfilingInfo
+ GHC.Cmm: ReadOnlyData :: SectionType
+ GHC.Cmm: ReadOnlyData16 :: SectionType
+ GHC.Cmm: RelocatableReadOnlyData :: SectionType
+ GHC.Cmm: Section :: SectionType -> CLabel -> Section
+ GHC.Cmm: StackInfo :: ByteOff -> Maybe ByteOff -> Bool -> CmmStackInfo
+ GHC.Cmm: Statics :: CLabel -> [CmmStatic] -> CmmStatics
+ GHC.Cmm: Text :: SectionType
+ GHC.Cmm: Thunk :: ClosureTypeInfo
+ GHC.Cmm: ThunkSelector :: SelectorOffset -> ClosureTypeInfo
+ GHC.Cmm: TopInfo :: LabelMap CmmInfoTable -> CmmStackInfo -> CmmTopInfo
+ GHC.Cmm: UninitialisedData :: SectionType
+ GHC.Cmm: [arg_space] :: CmmStackInfo -> ByteOff
+ GHC.Cmm: [cit_clo] :: CmmInfoTable -> Maybe (Id, CostCentreStack)
+ GHC.Cmm: [cit_lbl] :: CmmInfoTable -> CLabel
+ GHC.Cmm: [cit_prof] :: CmmInfoTable -> ProfilingInfo
+ GHC.Cmm: [cit_rep] :: CmmInfoTable -> SMRep
+ GHC.Cmm: [cit_srt] :: CmmInfoTable -> Maybe CLabel
+ GHC.Cmm: [do_layout] :: CmmStackInfo -> Bool
+ GHC.Cmm: [g_entry] :: GenCmmGraph n -> BlockId
+ GHC.Cmm: [g_graph] :: GenCmmGraph n -> Graph n C C
+ GHC.Cmm: [info_tbls] :: CmmTopInfo -> LabelMap CmmInfoTable
+ GHC.Cmm: [stack_info] :: CmmTopInfo -> CmmStackInfo
+ GHC.Cmm: [updfr_space] :: CmmStackInfo -> Maybe ByteOff
+ GHC.Cmm: blockId :: GenBasicBlock i -> BlockId
+ GHC.Cmm: data ClosureTypeInfo
+ GHC.Cmm: data CmmInfoTable
+ GHC.Cmm: data CmmStackInfo
+ GHC.Cmm: data CmmStatic
+ GHC.Cmm: data CmmStatics
+ GHC.Cmm: data CmmTopInfo
+ GHC.Cmm: data GenBasicBlock i
+ GHC.Cmm: data GenCmmDecl d h g
+ GHC.Cmm: data GenCmmGraph n
+ GHC.Cmm: data ProfilingInfo
+ GHC.Cmm: data Section
+ GHC.Cmm: data SectionType
+ GHC.Cmm: instance GHC.Show.Show GHC.Cmm.SectionType
+ GHC.Cmm: instance Outputable.Outputable instr => Outputable.Outputable (GHC.Cmm.GenBasicBlock instr)
+ GHC.Cmm: instance Outputable.Outputable instr => Outputable.Outputable (GHC.Cmm.ListGraph instr)
+ GHC.Cmm: isSecConstant :: Section -> Bool
+ GHC.Cmm: newtype ListGraph i
+ GHC.Cmm: pprBBlock :: Outputable stmt => GenBasicBlock stmt -> SDoc
+ GHC.Cmm: topInfoTable :: GenCmmDecl a CmmTopInfo (GenCmmGraph n) -> Maybe CmmInfoTable
+ GHC.Cmm: type CmmBlock = Block CmmNode C C
+ GHC.Cmm: type CmmDecl = GenCmmDecl CmmStatics CmmTopInfo CmmGraph
+ GHC.Cmm: type CmmGraph = GenCmmGraph CmmNode
+ GHC.Cmm: type CmmGroup = GenCmmGroup CmmStatics CmmTopInfo CmmGraph
+ GHC.Cmm: type CmmProgram = [CmmGroup]
+ GHC.Cmm: type ConstrDescription = ByteString
+ GHC.Cmm: type GenCmmGroup d h g = [GenCmmDecl d h g]
+ GHC.Cmm: type RawCmmDecl = GenCmmDecl CmmStatics (LabelMap CmmStatics) CmmGraph
+ GHC.Cmm: type RawCmmGroup = GenCmmGroup CmmStatics (LabelMap CmmStatics) CmmGraph
+ GHC.Cmm.BlockId: blockLbl :: BlockId -> CLabel
+ GHC.Cmm.BlockId: infoTblLbl :: BlockId -> CLabel
+ GHC.Cmm.BlockId: mkBlockId :: Unique -> BlockId
+ GHC.Cmm.BlockId: newBlockId :: MonadUnique m => m BlockId
+ GHC.Cmm.BlockId: type BlockId = Label
+ GHC.Cmm.CLabel: CodeStub :: DynamicLinkerLabelInfo
+ GHC.Cmm.CLabel: ForeignLabelInExternalPackage :: ForeignLabelSource
+ GHC.Cmm.CLabel: ForeignLabelInPackage :: UnitId -> ForeignLabelSource
+ GHC.Cmm.CLabel: ForeignLabelInThisPackage :: ForeignLabelSource
+ GHC.Cmm.CLabel: GotSymbolOffset :: DynamicLinkerLabelInfo
+ GHC.Cmm.CLabel: GotSymbolPtr :: DynamicLinkerLabelInfo
+ GHC.Cmm.CLabel: SymbolPtr :: DynamicLinkerLabelInfo
+ GHC.Cmm.CLabel: addLabelSize :: CLabel -> Int -> CLabel
+ GHC.Cmm.CLabel: data CLabel
+ GHC.Cmm.CLabel: data DynamicLinkerLabelInfo
+ GHC.Cmm.CLabel: data ForeignLabelSource
+ GHC.Cmm.CLabel: dynamicLinkerLabelInfo :: CLabel -> Maybe (DynamicLinkerLabelInfo, CLabel)
+ GHC.Cmm.CLabel: externallyVisibleCLabel :: CLabel -> Bool
+ GHC.Cmm.CLabel: foreignLabelStdcallInfo :: CLabel -> Maybe Int
+ GHC.Cmm.CLabel: hasCAF :: CLabel -> Bool
+ GHC.Cmm.CLabel: hasHaskellName :: CLabel -> Maybe Name
+ GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.CLabel
+ GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.CmmLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.DynamicLinkerLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.ForeignLabelSource
+ GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.IdLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Classes.Eq GHC.Cmm.CLabel.RtsLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.CLabel
+ GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.CmmLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.DynamicLinkerLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.ForeignLabelSource
+ GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.IdLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Classes.Ord GHC.Cmm.CLabel.RtsLabelInfo
+ GHC.Cmm.CLabel: instance GHC.Show.Show GHC.Cmm.CLabel.IdLabelInfo
+ GHC.Cmm.CLabel: instance Outputable.Outputable GHC.Cmm.CLabel.CLabel
+ GHC.Cmm.CLabel: instance Outputable.Outputable GHC.Cmm.CLabel.ForeignLabelSource
+ GHC.Cmm.CLabel: isBytesLabel :: CLabel -> Bool
+ GHC.Cmm.CLabel: isCFunctionLabel :: CLabel -> Bool
+ GHC.Cmm.CLabel: isConInfoTableLabel :: CLabel -> Bool
+ GHC.Cmm.CLabel: isForeignLabel :: CLabel -> Bool
+ GHC.Cmm.CLabel: isGcPtrLabel :: CLabel -> Bool
+ GHC.Cmm.CLabel: isInfoTableLabel :: CLabel -> Bool
+ GHC.Cmm.CLabel: isLocalCLabel :: Module -> CLabel -> Bool
+ GHC.Cmm.CLabel: isMathFun :: CLabel -> Bool
+ GHC.Cmm.CLabel: isSomeRODataLabel :: CLabel -> Bool
+ GHC.Cmm.CLabel: isStaticClosureLabel :: CLabel -> Bool
+ GHC.Cmm.CLabel: labelDynamic :: DynFlags -> Module -> CLabel -> Bool
+ GHC.Cmm.CLabel: mayRedirectTo :: CLabel -> CLabel -> Bool
+ GHC.Cmm.CLabel: maybeLocalBlockLabel :: CLabel -> Maybe BlockId
+ GHC.Cmm.CLabel: mkApEntryLabel :: Bool -> Int -> CLabel
+ GHC.Cmm.CLabel: mkApInfoTableLabel :: Bool -> Int -> CLabel
+ GHC.Cmm.CLabel: mkArrWords_infoLabel :: CLabel
+ GHC.Cmm.CLabel: mkAsmTempDerivedLabel :: CLabel -> FastString -> CLabel
+ GHC.Cmm.CLabel: mkAsmTempDieLabel :: CLabel -> CLabel
+ GHC.Cmm.CLabel: mkAsmTempEndLabel :: CLabel -> CLabel
+ GHC.Cmm.CLabel: mkAsmTempLabel :: Uniquable a => a -> CLabel
+ GHC.Cmm.CLabel: mkBHUpdInfoLabel :: CLabel
+ GHC.Cmm.CLabel: mkBadAlignmentLabel :: CLabel
+ GHC.Cmm.CLabel: mkBitmapLabel :: Unique -> CLabel
+ GHC.Cmm.CLabel: mkBlockInfoTableLabel :: Name -> CafInfo -> CLabel
+ GHC.Cmm.CLabel: mkBytesLabel :: Name -> CLabel
+ GHC.Cmm.CLabel: mkCAFBlackHoleInfoTableLabel :: CLabel
+ GHC.Cmm.CLabel: mkCCLabel :: CostCentre -> CLabel
+ GHC.Cmm.CLabel: mkCCSLabel :: CostCentreStack -> CLabel
+ GHC.Cmm.CLabel: mkClosureLabel :: Name -> CafInfo -> CLabel
+ GHC.Cmm.CLabel: mkClosureTableLabel :: Name -> CafInfo -> CLabel
+ GHC.Cmm.CLabel: mkCmmClosureLabel :: UnitId -> FastString -> CLabel
+ GHC.Cmm.CLabel: mkCmmCodeLabel :: UnitId -> FastString -> CLabel
+ GHC.Cmm.CLabel: mkCmmDataLabel :: UnitId -> FastString -> CLabel
+ GHC.Cmm.CLabel: mkCmmEntryLabel :: UnitId -> FastString -> CLabel
+ GHC.Cmm.CLabel: mkCmmInfoLabel :: UnitId -> FastString -> CLabel
+ GHC.Cmm.CLabel: mkCmmRetInfoLabel :: UnitId -> FastString -> CLabel
+ GHC.Cmm.CLabel: mkCmmRetLabel :: UnitId -> FastString -> CLabel
+ GHC.Cmm.CLabel: mkConInfoTableLabel :: Name -> CafInfo -> CLabel
+ GHC.Cmm.CLabel: mkDeadStripPreventer :: CLabel -> CLabel
+ GHC.Cmm.CLabel: mkDirty_MUT_VAR_Label :: CLabel
+ GHC.Cmm.CLabel: mkDynamicLinkerLabel :: DynamicLinkerLabelInfo -> CLabel -> CLabel
+ GHC.Cmm.CLabel: mkEntryLabel :: Name -> CafInfo -> CLabel
+ GHC.Cmm.CLabel: mkForeignLabel :: FastString -> Maybe Int -> ForeignLabelSource -> FunctionOrData -> CLabel
+ GHC.Cmm.CLabel: mkHpcTicksLabel :: Module -> CLabel
+ GHC.Cmm.CLabel: mkIndStaticInfoLabel :: CLabel
+ GHC.Cmm.CLabel: mkInfoTableLabel :: Name -> CafInfo -> CLabel
+ GHC.Cmm.CLabel: mkLocalBlockLabel :: Unique -> CLabel
+ GHC.Cmm.CLabel: mkLocalClosureLabel :: Name -> CafInfo -> CLabel
+ GHC.Cmm.CLabel: mkLocalClosureTableLabel :: Name -> CafInfo -> CLabel
+ GHC.Cmm.CLabel: mkLocalInfoTableLabel :: Name -> CafInfo -> CLabel
+ GHC.Cmm.CLabel: mkMAP_DIRTY_infoLabel :: CLabel
+ GHC.Cmm.CLabel: mkMAP_FROZEN_CLEAN_infoLabel :: CLabel
+ GHC.Cmm.CLabel: mkMAP_FROZEN_DIRTY_infoLabel :: CLabel
+ GHC.Cmm.CLabel: mkMainCapabilityLabel :: CLabel
+ GHC.Cmm.CLabel: mkNonmovingWriteBarrierEnabledLabel :: CLabel
+ GHC.Cmm.CLabel: mkPicBaseLabel :: CLabel
+ GHC.Cmm.CLabel: mkPrimCallLabel :: PrimCall -> CLabel
+ GHC.Cmm.CLabel: mkRednCountsLabel :: Name -> CLabel
+ GHC.Cmm.CLabel: mkRtsApFastLabel :: FastString -> CLabel
+ GHC.Cmm.CLabel: mkRtsPrimOpLabel :: PrimOp -> CLabel
+ GHC.Cmm.CLabel: mkRtsSlowFastTickyCtrLabel :: String -> CLabel
+ GHC.Cmm.CLabel: mkSMAP_DIRTY_infoLabel :: CLabel
+ GHC.Cmm.CLabel: mkSMAP_FROZEN_CLEAN_infoLabel :: CLabel
+ GHC.Cmm.CLabel: mkSMAP_FROZEN_DIRTY_infoLabel :: CLabel
+ GHC.Cmm.CLabel: mkSRTInfoLabel :: Int -> CLabel
+ GHC.Cmm.CLabel: mkSRTLabel :: Unique -> CLabel
+ GHC.Cmm.CLabel: mkSelectorEntryLabel :: Bool -> Int -> CLabel
+ GHC.Cmm.CLabel: mkSelectorInfoLabel :: Bool -> Int -> CLabel
+ GHC.Cmm.CLabel: mkStringLitLabel :: Unique -> CLabel
+ GHC.Cmm.CLabel: mkTopTickyCtrLabel :: CLabel
+ GHC.Cmm.CLabel: mkUpdInfoLabel :: CLabel
+ GHC.Cmm.CLabel: needsCDecl :: CLabel -> Bool
+ GHC.Cmm.CLabel: pprCLabel :: DynFlags -> CLabel -> SDoc
+ GHC.Cmm.CLabel: pprDebugCLabel :: CLabel -> SDoc
+ GHC.Cmm.CLabel: toClosureLbl :: CLabel -> CLabel
+ GHC.Cmm.CLabel: toEntryLbl :: CLabel -> CLabel
+ GHC.Cmm.CLabel: toInfoLbl :: CLabel -> CLabel
+ GHC.Cmm.CLabel: toSlowEntryLbl :: CLabel -> CLabel
+ GHC.Cmm.Dataflow.Block: Closed :: Extensibility
+ GHC.Cmm.Dataflow.Block: Open :: Extensibility
+ GHC.Cmm.Dataflow.Block: [BCat] :: Block n O O -> Block n O O -> Block n O O
+ GHC.Cmm.Dataflow.Block: [BCons] :: n O O -> Block n O O -> Block n O O
+ GHC.Cmm.Dataflow.Block: [BMiddle] :: n O O -> Block n O O
+ GHC.Cmm.Dataflow.Block: [BNil] :: Block n O O
+ GHC.Cmm.Dataflow.Block: [BSnoc] :: Block n O O -> n O O -> Block n O O
+ GHC.Cmm.Dataflow.Block: [BlockCC] :: n C O -> Block n O O -> n O C -> Block n C C
+ GHC.Cmm.Dataflow.Block: [BlockCO] :: n C O -> Block n O O -> Block n C O
+ GHC.Cmm.Dataflow.Block: [BlockOC] :: Block n O O -> n O C -> Block n O C
+ GHC.Cmm.Dataflow.Block: [JustO] :: t -> MaybeO O t
+ GHC.Cmm.Dataflow.Block: [NothingO] :: MaybeO C t
+ GHC.Cmm.Dataflow.Block: blockAppend :: Block n e O -> Block n O x -> Block n e x
+ GHC.Cmm.Dataflow.Block: blockCons :: n O O -> Block n O x -> Block n O x
+ GHC.Cmm.Dataflow.Block: blockFromList :: [n O O] -> Block n O O
+ GHC.Cmm.Dataflow.Block: blockJoin :: n C O -> Block n O O -> n O C -> Block n C C
+ GHC.Cmm.Dataflow.Block: blockJoinHead :: n C O -> Block n O x -> Block n C x
+ GHC.Cmm.Dataflow.Block: blockJoinTail :: Block n e O -> n O C -> Block n e C
+ GHC.Cmm.Dataflow.Block: blockSnoc :: Block n e O -> n O O -> Block n e O
+ GHC.Cmm.Dataflow.Block: blockSplit :: Block n C C -> (n C O, Block n O O, n O C)
+ GHC.Cmm.Dataflow.Block: blockSplitHead :: Block n C x -> (n C O, Block n O x)
+ GHC.Cmm.Dataflow.Block: blockSplitTail :: Block n e C -> (Block n e O, n O C)
+ GHC.Cmm.Dataflow.Block: blockToList :: Block n O O -> [n O O]
+ GHC.Cmm.Dataflow.Block: data Block n e x
+ GHC.Cmm.Dataflow.Block: data Extensibility
+ GHC.Cmm.Dataflow.Block: data MaybeO ex t
+ GHC.Cmm.Dataflow.Block: emptyBlock :: Block n O O
+ GHC.Cmm.Dataflow.Block: firstNode :: Block n C x -> n C O
+ GHC.Cmm.Dataflow.Block: foldBlockNodesB :: forall n a. (forall e x. n e x -> a -> a) -> forall e x. Block n e x -> IndexedCO x a a -> IndexedCO e a a
+ GHC.Cmm.Dataflow.Block: foldBlockNodesB3 :: forall n a b c. (n C O -> b -> c, n O O -> b -> b, n O C -> a -> b) -> forall e x. Block n e x -> IndexedCO x a b -> IndexedCO e c b
+ GHC.Cmm.Dataflow.Block: foldBlockNodesF :: forall n a. (forall e x. n e x -> a -> a) -> forall e x. Block n e x -> IndexedCO e a a -> IndexedCO x a a
+ GHC.Cmm.Dataflow.Block: instance GHC.Base.Functor (GHC.Cmm.Dataflow.Block.MaybeC ex)
+ GHC.Cmm.Dataflow.Block: instance GHC.Base.Functor (GHC.Cmm.Dataflow.Block.MaybeO ex)
+ GHC.Cmm.Dataflow.Block: isEmptyBlock :: Block n e x -> Bool
+ GHC.Cmm.Dataflow.Block: lastNode :: Block n x C -> n O C
+ GHC.Cmm.Dataflow.Block: mapBlock :: (forall e x. n e x -> n' e x) -> Block n e x -> Block n' e x
+ GHC.Cmm.Dataflow.Block: mapBlock' :: (forall e x. n e x -> n' e x) -> Block n e x -> Block n' e x
+ GHC.Cmm.Dataflow.Block: mapBlock3' :: forall n n' e x. (n C O -> n' C O, n O O -> n' O O, n O C -> n' O C) -> Block n e x -> Block n' e x
+ GHC.Cmm.Dataflow.Block: replaceFirstNode :: Block n C x -> n C O -> Block n C x
+ GHC.Cmm.Dataflow.Block: replaceLastNode :: Block n x C -> n O C -> Block n x C
+ GHC.Cmm.Dataflow.Block: type C = 'Closed
+ GHC.Cmm.Dataflow.Block: type O = 'Open
+ GHC.Cmm.Dataflow.Block: type family IndexedCO (ex :: Extensibility) (a :: k) (b :: k) :: k
+ GHC.Cmm.Dataflow.Collections: class IsMap map where {
+ GHC.Cmm.Dataflow.Collections: class IsSet set where {
+ GHC.Cmm.Dataflow.Collections: data UniqueMap v
+ GHC.Cmm.Dataflow.Collections: data UniqueSet
+ GHC.Cmm.Dataflow.Collections: instance Data.Foldable.Foldable GHC.Cmm.Dataflow.Collections.UniqueMap
+ GHC.Cmm.Dataflow.Collections: instance Data.Traversable.Traversable GHC.Cmm.Dataflow.Collections.UniqueMap
+ GHC.Cmm.Dataflow.Collections: instance GHC.Base.Functor GHC.Cmm.Dataflow.Collections.UniqueMap
+ GHC.Cmm.Dataflow.Collections: instance GHC.Base.Monoid GHC.Cmm.Dataflow.Collections.UniqueSet
+ GHC.Cmm.Dataflow.Collections: instance GHC.Base.Semigroup GHC.Cmm.Dataflow.Collections.UniqueSet
+ GHC.Cmm.Dataflow.Collections: instance GHC.Classes.Eq GHC.Cmm.Dataflow.Collections.UniqueSet
+ GHC.Cmm.Dataflow.Collections: instance GHC.Classes.Eq v => GHC.Classes.Eq (GHC.Cmm.Dataflow.Collections.UniqueMap v)
+ GHC.Cmm.Dataflow.Collections: instance GHC.Classes.Ord GHC.Cmm.Dataflow.Collections.UniqueSet
+ GHC.Cmm.Dataflow.Collections: instance GHC.Classes.Ord v => GHC.Classes.Ord (GHC.Cmm.Dataflow.Collections.UniqueMap v)
+ GHC.Cmm.Dataflow.Collections: instance GHC.Cmm.Dataflow.Collections.IsMap GHC.Cmm.Dataflow.Collections.UniqueMap
+ GHC.Cmm.Dataflow.Collections: instance GHC.Cmm.Dataflow.Collections.IsSet GHC.Cmm.Dataflow.Collections.UniqueSet
+ GHC.Cmm.Dataflow.Collections: instance GHC.Show.Show GHC.Cmm.Dataflow.Collections.UniqueSet
+ GHC.Cmm.Dataflow.Collections: instance GHC.Show.Show v => GHC.Show.Show (GHC.Cmm.Dataflow.Collections.UniqueMap v)
+ GHC.Cmm.Dataflow.Collections: mapAdjust :: IsMap map => (a -> a) -> KeyOf map -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapAlter :: IsMap map => (Maybe a -> Maybe a) -> KeyOf map -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapDelete :: IsMap map => KeyOf map -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapDeleteList :: IsMap map => [KeyOf map] -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapDifference :: IsMap map => map a -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapElems :: IsMap map => map a -> [a]
+ GHC.Cmm.Dataflow.Collections: mapEmpty :: IsMap map => map a
+ GHC.Cmm.Dataflow.Collections: mapFilter :: IsMap map => (a -> Bool) -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapFilterWithKey :: IsMap map => (KeyOf map -> a -> Bool) -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapFindWithDefault :: IsMap map => a -> KeyOf map -> map a -> a
+ GHC.Cmm.Dataflow.Collections: mapFoldMapWithKey :: (IsMap map, Monoid m) => (KeyOf map -> a -> m) -> map a -> m
+ GHC.Cmm.Dataflow.Collections: mapFoldl :: IsMap map => (b -> a -> b) -> b -> map a -> b
+ GHC.Cmm.Dataflow.Collections: mapFoldlWithKey :: IsMap map => (b -> KeyOf map -> a -> b) -> b -> map a -> b
+ GHC.Cmm.Dataflow.Collections: mapFoldr :: IsMap map => (a -> b -> b) -> b -> map a -> b
+ GHC.Cmm.Dataflow.Collections: mapFromList :: IsMap map => [(KeyOf map, a)] -> map a
+ GHC.Cmm.Dataflow.Collections: mapFromListWith :: IsMap map => (a -> a -> a) -> [(KeyOf map, a)] -> map a
+ GHC.Cmm.Dataflow.Collections: mapInsert :: IsMap map => KeyOf map -> a -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapInsertList :: IsMap map => [(KeyOf map, a)] -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapInsertWith :: IsMap map => (a -> a -> a) -> KeyOf map -> a -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapIntersection :: IsMap map => map a -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapIsSubmapOf :: (IsMap map, Eq a) => map a -> map a -> Bool
+ GHC.Cmm.Dataflow.Collections: mapKeys :: IsMap map => map a -> [KeyOf map]
+ GHC.Cmm.Dataflow.Collections: mapLookup :: IsMap map => KeyOf map -> map a -> Maybe a
+ GHC.Cmm.Dataflow.Collections: mapMap :: IsMap map => (a -> b) -> map a -> map b
+ GHC.Cmm.Dataflow.Collections: mapMapWithKey :: IsMap map => (KeyOf map -> a -> b) -> map a -> map b
+ GHC.Cmm.Dataflow.Collections: mapMember :: IsMap map => KeyOf map -> map a -> Bool
+ GHC.Cmm.Dataflow.Collections: mapNull :: IsMap map => map a -> Bool
+ GHC.Cmm.Dataflow.Collections: mapSingleton :: IsMap map => KeyOf map -> a -> map a
+ GHC.Cmm.Dataflow.Collections: mapSize :: IsMap map => map a -> Int
+ GHC.Cmm.Dataflow.Collections: mapToList :: IsMap map => map a -> [(KeyOf map, a)]
+ GHC.Cmm.Dataflow.Collections: mapUnion :: IsMap map => map a -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapUnionWithKey :: IsMap map => (KeyOf map -> a -> a -> a) -> map a -> map a -> map a
+ GHC.Cmm.Dataflow.Collections: mapUnions :: IsMap map => [map a] -> map a
+ GHC.Cmm.Dataflow.Collections: setDelete :: IsSet set => ElemOf set -> set -> set
+ GHC.Cmm.Dataflow.Collections: setDeleteList :: IsSet set => [ElemOf set] -> set -> set
+ GHC.Cmm.Dataflow.Collections: setDifference :: IsSet set => set -> set -> set
+ GHC.Cmm.Dataflow.Collections: setElems :: IsSet set => set -> [ElemOf set]
+ GHC.Cmm.Dataflow.Collections: setEmpty :: IsSet set => set
+ GHC.Cmm.Dataflow.Collections: setFilter :: IsSet set => (ElemOf set -> Bool) -> set -> set
+ GHC.Cmm.Dataflow.Collections: setFoldl :: IsSet set => (b -> ElemOf set -> b) -> b -> set -> b
+ GHC.Cmm.Dataflow.Collections: setFoldr :: IsSet set => (ElemOf set -> b -> b) -> b -> set -> b
+ GHC.Cmm.Dataflow.Collections: setFromList :: IsSet set => [ElemOf set] -> set
+ GHC.Cmm.Dataflow.Collections: setInsert :: IsSet set => ElemOf set -> set -> set
+ GHC.Cmm.Dataflow.Collections: setInsertList :: IsSet set => [ElemOf set] -> set -> set
+ GHC.Cmm.Dataflow.Collections: setIntersection :: IsSet set => set -> set -> set
+ GHC.Cmm.Dataflow.Collections: setIsSubsetOf :: IsSet set => set -> set -> Bool
+ GHC.Cmm.Dataflow.Collections: setMember :: IsSet set => ElemOf set -> set -> Bool
+ GHC.Cmm.Dataflow.Collections: setNull :: IsSet set => set -> Bool
+ GHC.Cmm.Dataflow.Collections: setSingleton :: IsSet set => ElemOf set -> set
+ GHC.Cmm.Dataflow.Collections: setSize :: IsSet set => set -> Int
+ GHC.Cmm.Dataflow.Collections: setUnion :: IsSet set => set -> set -> set
+ GHC.Cmm.Dataflow.Collections: setUnions :: IsSet set => [set] -> set
+ GHC.Cmm.Dataflow.Collections: type family KeyOf map;
+ GHC.Cmm.Dataflow.Collections: }
+ GHC.Cmm.Dataflow.Graph: [GMany] :: MaybeO e (block n O C) -> Body' block n -> MaybeO x (block n C O) -> Graph' block n e x
+ GHC.Cmm.Dataflow.Graph: [GNil] :: Graph' block n O O
+ GHC.Cmm.Dataflow.Graph: [GUnit] :: block n O O -> Graph' block n O O
+ GHC.Cmm.Dataflow.Graph: addBlock :: (NonLocal block, HasDebugCallStack) => block C C -> LabelMap (block C C) -> LabelMap (block C C)
+ GHC.Cmm.Dataflow.Graph: bodyList :: Body' block n -> [(Label, block n C C)]
+ GHC.Cmm.Dataflow.Graph: class NonLocal thing
+ GHC.Cmm.Dataflow.Graph: data Graph' block (n :: Extensibility -> Extensibility -> *) e x
+ GHC.Cmm.Dataflow.Graph: emptyBody :: Body' block n
+ GHC.Cmm.Dataflow.Graph: entryLabel :: NonLocal thing => thing C x -> Label
+ GHC.Cmm.Dataflow.Graph: instance GHC.Cmm.Dataflow.Graph.NonLocal n => GHC.Cmm.Dataflow.Graph.NonLocal (GHC.Cmm.Dataflow.Block.Block n)
+ GHC.Cmm.Dataflow.Graph: labelsDefined :: forall block n e x. NonLocal (block n) => Graph' block n e x -> LabelSet
+ GHC.Cmm.Dataflow.Graph: mapGraph :: (forall e x. n e x -> n' e x) -> Graph n e x -> Graph n' e x
+ GHC.Cmm.Dataflow.Graph: mapGraphBlocks :: forall block n block' n' e x. (forall e x. block n e x -> block' n' e x) -> Graph' block n e x -> Graph' block' n' e x
+ GHC.Cmm.Dataflow.Graph: revPostorderFrom :: forall block. NonLocal block => LabelMap (block C C) -> Label -> [block C C]
+ GHC.Cmm.Dataflow.Graph: successors :: NonLocal thing => thing e C -> [Label]
+ GHC.Cmm.Dataflow.Graph: type Body n = LabelMap (Block n C C)
+ GHC.Cmm.Dataflow.Graph: type Graph = Graph' Block
+ GHC.Cmm.Dataflow.Label: data Label
+ GHC.Cmm.Dataflow.Label: data LabelMap v
+ GHC.Cmm.Dataflow.Label: data LabelSet
+ GHC.Cmm.Dataflow.Label: instance Data.Foldable.Foldable GHC.Cmm.Dataflow.Label.LabelMap
+ GHC.Cmm.Dataflow.Label: instance Data.Traversable.Traversable GHC.Cmm.Dataflow.Label.LabelMap
+ GHC.Cmm.Dataflow.Label: instance GHC.Base.Functor GHC.Cmm.Dataflow.Label.LabelMap
+ GHC.Cmm.Dataflow.Label: instance GHC.Base.Monoid GHC.Cmm.Dataflow.Label.LabelSet
+ GHC.Cmm.Dataflow.Label: instance GHC.Base.Semigroup GHC.Cmm.Dataflow.Label.LabelSet
+ GHC.Cmm.Dataflow.Label: instance GHC.Classes.Eq GHC.Cmm.Dataflow.Label.Label
+ GHC.Cmm.Dataflow.Label: instance GHC.Classes.Eq GHC.Cmm.Dataflow.Label.LabelSet
+ GHC.Cmm.Dataflow.Label: instance GHC.Classes.Eq v => GHC.Classes.Eq (GHC.Cmm.Dataflow.Label.LabelMap v)
+ GHC.Cmm.Dataflow.Label: instance GHC.Classes.Ord GHC.Cmm.Dataflow.Label.Label
+ GHC.Cmm.Dataflow.Label: instance GHC.Classes.Ord GHC.Cmm.Dataflow.Label.LabelSet
+ GHC.Cmm.Dataflow.Label: instance GHC.Classes.Ord v => GHC.Classes.Ord (GHC.Cmm.Dataflow.Label.LabelMap v)
+ GHC.Cmm.Dataflow.Label: instance GHC.Cmm.Dataflow.Collections.IsMap GHC.Cmm.Dataflow.Label.LabelMap
+ GHC.Cmm.Dataflow.Label: instance GHC.Cmm.Dataflow.Collections.IsSet GHC.Cmm.Dataflow.Label.LabelSet
+ GHC.Cmm.Dataflow.Label: instance GHC.Show.Show GHC.Cmm.Dataflow.Label.Label
+ GHC.Cmm.Dataflow.Label: instance GHC.Show.Show GHC.Cmm.Dataflow.Label.LabelSet
+ GHC.Cmm.Dataflow.Label: instance GHC.Show.Show v => GHC.Show.Show (GHC.Cmm.Dataflow.Label.LabelMap v)
+ GHC.Cmm.Dataflow.Label: instance Outputable.Outputable GHC.Cmm.Dataflow.Label.Label
+ GHC.Cmm.Dataflow.Label: instance Outputable.Outputable GHC.Cmm.Dataflow.Label.LabelSet
+ GHC.Cmm.Dataflow.Label: instance Outputable.Outputable a => Outputable.Outputable (GHC.Cmm.Dataflow.Label.LabelMap a)
+ GHC.Cmm.Dataflow.Label: instance TrieMap.TrieMap GHC.Cmm.Dataflow.Label.LabelMap
+ GHC.Cmm.Dataflow.Label: instance Unique.Uniquable GHC.Cmm.Dataflow.Label.Label
+ GHC.Cmm.Dataflow.Label: lookupFact :: Label -> FactBase f -> Maybe f
+ GHC.Cmm.Dataflow.Label: mkHooplLabel :: Int -> Label
+ GHC.Cmm.Dataflow.Label: type FactBase f = LabelMap f
+ GHC.Cmm.Expr: BaseReg :: GlobalReg
+ GHC.Cmm.Expr: CCCS :: GlobalReg
+ GHC.Cmm.Expr: CmmBlock :: {-# UNPACK #-} !BlockId -> CmmLit
+ GHC.Cmm.Expr: CmmFloat :: Rational -> Width -> CmmLit
+ GHC.Cmm.Expr: CmmGlobal :: GlobalReg -> CmmReg
+ GHC.Cmm.Expr: CmmHighStackMark :: CmmLit
+ GHC.Cmm.Expr: CmmInt :: !Integer -> Width -> CmmLit
+ GHC.Cmm.Expr: CmmLabel :: CLabel -> CmmLit
+ GHC.Cmm.Expr: CmmLabelDiffOff :: CLabel -> CLabel -> Int -> Width -> CmmLit
+ GHC.Cmm.Expr: CmmLabelOff :: CLabel -> Int -> CmmLit
+ GHC.Cmm.Expr: CmmLit :: CmmLit -> CmmExpr
+ GHC.Cmm.Expr: CmmLoad :: !CmmExpr -> !CmmType -> CmmExpr
+ GHC.Cmm.Expr: CmmLocal :: {-# UNPACK #-} !LocalReg -> CmmReg
+ GHC.Cmm.Expr: CmmMachOp :: MachOp -> [CmmExpr] -> CmmExpr
+ GHC.Cmm.Expr: CmmReg :: !CmmReg -> CmmExpr
+ GHC.Cmm.Expr: CmmRegOff :: !CmmReg -> Int -> CmmExpr
+ GHC.Cmm.Expr: CmmStackSlot :: Area -> {-# UNPACK #-} !Int -> CmmExpr
+ GHC.Cmm.Expr: CmmVec :: [CmmLit] -> CmmLit
+ GHC.Cmm.Expr: CurrentNursery :: GlobalReg
+ GHC.Cmm.Expr: CurrentTSO :: GlobalReg
+ GHC.Cmm.Expr: DoubleReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: EagerBlackholeInfo :: GlobalReg
+ GHC.Cmm.Expr: FloatReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: GCEnter1 :: GlobalReg
+ GHC.Cmm.Expr: GCFun :: GlobalReg
+ GHC.Cmm.Expr: Hp :: GlobalReg
+ GHC.Cmm.Expr: HpAlloc :: GlobalReg
+ GHC.Cmm.Expr: HpLim :: GlobalReg
+ GHC.Cmm.Expr: LocalReg :: {-# UNPACK #-} !Unique -> CmmType -> LocalReg
+ GHC.Cmm.Expr: LongReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: MachSp :: GlobalReg
+ GHC.Cmm.Expr: Old :: Area
+ GHC.Cmm.Expr: PicBaseReg :: GlobalReg
+ GHC.Cmm.Expr: Sp :: GlobalReg
+ GHC.Cmm.Expr: SpLim :: GlobalReg
+ GHC.Cmm.Expr: UnwindReturnReg :: GlobalReg
+ GHC.Cmm.Expr: VGcPtr :: VGcPtr
+ GHC.Cmm.Expr: VNonGcPtr :: VGcPtr
+ GHC.Cmm.Expr: VanillaReg :: {-# UNPACK #-} !Int -> VGcPtr -> GlobalReg
+ GHC.Cmm.Expr: XmmReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: YmmReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: Young :: {-# UNPACK #-} !BlockId -> Area
+ GHC.Cmm.Expr: ZmmReg :: {-# UNPACK #-} !Int -> GlobalReg
+ GHC.Cmm.Expr: baseReg :: CmmReg
+ GHC.Cmm.Expr: cccsReg :: CmmReg
+ GHC.Cmm.Expr: class Ord r => DefinerOfRegs r a
+ GHC.Cmm.Expr: class Ord r => UserOfRegs r a
+ GHC.Cmm.Expr: cmmExprAlignment :: CmmExpr -> Alignment
+ GHC.Cmm.Expr: cmmExprType :: DynFlags -> CmmExpr -> CmmType
+ GHC.Cmm.Expr: cmmExprWidth :: DynFlags -> CmmExpr -> Width
+ GHC.Cmm.Expr: cmmLitType :: DynFlags -> CmmLit -> CmmType
+ GHC.Cmm.Expr: cmmRegType :: DynFlags -> CmmReg -> CmmType
+ GHC.Cmm.Expr: cmmRegWidth :: DynFlags -> CmmReg -> Width
+ GHC.Cmm.Expr: currentNurseryReg :: CmmReg
+ GHC.Cmm.Expr: currentTSOReg :: CmmReg
+ GHC.Cmm.Expr: data Area
+ GHC.Cmm.Expr: data CmmExpr
+ GHC.Cmm.Expr: data CmmLit
+ GHC.Cmm.Expr: data CmmReg
+ GHC.Cmm.Expr: data GlobalReg
+ GHC.Cmm.Expr: data LocalReg
+ GHC.Cmm.Expr: data VGcPtr
+ GHC.Cmm.Expr: deleteFromRegSet :: Ord r => RegSet r -> r -> RegSet r
+ GHC.Cmm.Expr: elemRegSet :: Ord r => r -> RegSet r -> Bool
+ GHC.Cmm.Expr: emptyRegSet :: RegSet r
+ GHC.Cmm.Expr: extendRegSet :: Ord r => RegSet r -> r -> RegSet r
+ GHC.Cmm.Expr: foldLocalRegsDefd :: DefinerOfRegs LocalReg a => DynFlags -> (b -> LocalReg -> b) -> b -> a -> b
+ GHC.Cmm.Expr: foldLocalRegsUsed :: UserOfRegs LocalReg a => DynFlags -> (b -> LocalReg -> b) -> b -> a -> b
+ GHC.Cmm.Expr: foldRegsDefd :: DefinerOfRegs r a => DynFlags -> (b -> r -> b) -> b -> a -> b
+ GHC.Cmm.Expr: foldRegsUsed :: UserOfRegs r a => DynFlags -> (b -> r -> b) -> b -> a -> b
+ GHC.Cmm.Expr: globalRegType :: DynFlags -> GlobalReg -> CmmType
+ GHC.Cmm.Expr: hpAllocReg :: CmmReg
+ GHC.Cmm.Expr: hpLimReg :: CmmReg
+ GHC.Cmm.Expr: hpReg :: CmmReg
+ GHC.Cmm.Expr: instance (GHC.Classes.Ord r, GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Expr.CmmReg) => GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Expr.CmmExpr
+ GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.Area
+ GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.CmmExpr
+ GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.CmmLit
+ GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.CmmReg
+ GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.GlobalReg
+ GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.LocalReg
+ GHC.Cmm.Expr: instance GHC.Classes.Eq GHC.Cmm.Expr.VGcPtr
+ GHC.Cmm.Expr: instance GHC.Classes.Ord GHC.Cmm.Expr.Area
+ GHC.Cmm.Expr: instance GHC.Classes.Ord GHC.Cmm.Expr.CmmReg
+ GHC.Cmm.Expr: instance GHC.Classes.Ord GHC.Cmm.Expr.GlobalReg
+ GHC.Cmm.Expr: instance GHC.Classes.Ord GHC.Cmm.Expr.LocalReg
+ GHC.Cmm.Expr: instance GHC.Classes.Ord r => GHC.Cmm.Expr.DefinerOfRegs r r
+ GHC.Cmm.Expr: instance GHC.Classes.Ord r => GHC.Cmm.Expr.UserOfRegs r r
+ GHC.Cmm.Expr: instance GHC.Cmm.Expr.DefinerOfRegs GHC.Cmm.Expr.GlobalReg GHC.Cmm.Expr.CmmReg
+ GHC.Cmm.Expr: instance GHC.Cmm.Expr.DefinerOfRegs GHC.Cmm.Expr.LocalReg GHC.Cmm.Expr.CmmReg
+ GHC.Cmm.Expr: instance GHC.Cmm.Expr.DefinerOfRegs r a => GHC.Cmm.Expr.DefinerOfRegs r [a]
+ GHC.Cmm.Expr: instance GHC.Cmm.Expr.UserOfRegs GHC.Cmm.Expr.GlobalReg GHC.Cmm.Expr.CmmReg
+ GHC.Cmm.Expr: instance GHC.Cmm.Expr.UserOfRegs GHC.Cmm.Expr.LocalReg GHC.Cmm.Expr.CmmReg
+ GHC.Cmm.Expr: instance GHC.Cmm.Expr.UserOfRegs r a => GHC.Cmm.Expr.UserOfRegs r [a]
+ GHC.Cmm.Expr: instance GHC.Show.Show GHC.Cmm.Expr.GlobalReg
+ GHC.Cmm.Expr: instance GHC.Show.Show GHC.Cmm.Expr.VGcPtr
+ GHC.Cmm.Expr: instance Unique.Uniquable GHC.Cmm.Expr.LocalReg
+ GHC.Cmm.Expr: isArgReg :: GlobalReg -> Bool
+ GHC.Cmm.Expr: localRegType :: LocalReg -> CmmType
+ GHC.Cmm.Expr: maybeInvertCmmExpr :: CmmExpr -> Maybe CmmExpr
+ GHC.Cmm.Expr: minusRegSet :: Ord r => RegSet r -> RegSet r -> RegSet r
+ GHC.Cmm.Expr: mkRegSet :: Ord r => [r] -> RegSet r
+ GHC.Cmm.Expr: node :: GlobalReg
+ GHC.Cmm.Expr: nodeReg :: CmmReg
+ GHC.Cmm.Expr: nullRegSet :: RegSet r -> Bool
+ GHC.Cmm.Expr: plusRegSet :: Ord r => RegSet r -> RegSet r -> RegSet r
+ GHC.Cmm.Expr: regSetToList :: RegSet r -> [r]
+ GHC.Cmm.Expr: sizeRegSet :: RegSet r -> Int
+ GHC.Cmm.Expr: spLimReg :: CmmReg
+ GHC.Cmm.Expr: spReg :: CmmReg
+ GHC.Cmm.Expr: timesRegSet :: Ord r => RegSet r -> RegSet r -> RegSet r
+ GHC.Cmm.Expr: type GlobalRegSet = RegSet GlobalReg
+ GHC.Cmm.Expr: type LocalRegSet = RegSet LocalReg
+ GHC.Cmm.Expr: type RegSet r = Set r
+ GHC.Cmm.MachOp: AMO_Add :: AtomicMachOp
+ GHC.Cmm.MachOp: AMO_And :: AtomicMachOp
+ GHC.Cmm.MachOp: AMO_Nand :: AtomicMachOp
+ GHC.Cmm.MachOp: AMO_Or :: AtomicMachOp
+ GHC.Cmm.MachOp: AMO_Sub :: AtomicMachOp
+ GHC.Cmm.MachOp: AMO_Xor :: AtomicMachOp
+ GHC.Cmm.MachOp: MO_Add :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_Add2 :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_AddIntC :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_AddWordC :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_AlignmentCheck :: Int -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_And :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_AtomicRMW :: Width -> AtomicMachOp -> CallishMachOp
+ GHC.Cmm.MachOp: MO_AtomicRead :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_AtomicWrite :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_BRev :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_BSwap :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Clz :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Cmpxchg :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Ctz :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Eq :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F32_Acos :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Acosh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Asin :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Asinh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Atan :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Atanh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Cos :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Cosh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Exp :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_ExpM1 :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Fabs :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Log :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Log1P :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Pwr :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Sin :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Sinh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Sqrt :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Tan :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F32_Tanh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Acos :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Acosh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Asin :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Asinh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Atan :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Atanh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Cos :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Cosh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Exp :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_ExpM1 :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Fabs :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Log :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Log1P :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Pwr :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Sin :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Sinh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Sqrt :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Tan :: CallishMachOp
+ GHC.Cmm.MachOp: MO_F64_Tanh :: CallishMachOp
+ GHC.Cmm.MachOp: MO_FF_Conv :: Width -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_FS_Conv :: Width -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Add :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Eq :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Ge :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Gt :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Le :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Lt :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Mul :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Ne :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Neg :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Quot :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_F_Sub :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_Memcmp :: Int -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Memcpy :: Int -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Memmove :: Int -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Memset :: Int -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Mul :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_Ne :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_Not :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_Or :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_Pdep :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Pext :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_PopCnt :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Prefetch_Data :: Int -> CallishMachOp
+ GHC.Cmm.MachOp: MO_ReadBarrier :: CallishMachOp
+ GHC.Cmm.MachOp: MO_SF_Conv :: Width -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_SS_Conv :: Width -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_S_Ge :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_S_Gt :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_S_Le :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_S_Lt :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_S_Mul2 :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_S_MulMayOflo :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_S_Neg :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_S_Quot :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_S_QuotRem :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_S_Rem :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_S_Shr :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_Shl :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_Sub :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_SubIntC :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_SubWordC :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_Touch :: CallishMachOp
+ GHC.Cmm.MachOp: MO_UF_Conv :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_UU_Conv :: Width -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_U_Ge :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_U_Gt :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_U_Le :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_U_Lt :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_U_Mul2 :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_U_MulMayOflo :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_U_Quot :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_U_QuotRem :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_U_QuotRem2 :: Width -> CallishMachOp
+ GHC.Cmm.MachOp: MO_U_Rem :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_U_Shr :: Width -> MachOp
+ GHC.Cmm.MachOp: MO_VF_Add :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VF_Extract :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VF_Insert :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VF_Mul :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VF_Neg :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VF_Quot :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VF_Sub :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VS_Neg :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VS_Quot :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VS_Rem :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VU_Quot :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_VU_Rem :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_V_Add :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_V_Extract :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_V_Insert :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_V_Mul :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_V_Sub :: Length -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_WriteBarrier :: CallishMachOp
+ GHC.Cmm.MachOp: MO_XX_Conv :: Width -> Width -> MachOp
+ GHC.Cmm.MachOp: MO_Xor :: Width -> MachOp
+ GHC.Cmm.MachOp: callishMachOpHints :: CallishMachOp -> ([ForeignHint], [ForeignHint])
+ GHC.Cmm.MachOp: data AtomicMachOp
+ GHC.Cmm.MachOp: data CallishMachOp
+ GHC.Cmm.MachOp: data MachOp
+ GHC.Cmm.MachOp: instance GHC.Classes.Eq GHC.Cmm.MachOp.AtomicMachOp
+ GHC.Cmm.MachOp: instance GHC.Classes.Eq GHC.Cmm.MachOp.CallishMachOp
+ GHC.Cmm.MachOp: instance GHC.Classes.Eq GHC.Cmm.MachOp.MachOp
+ GHC.Cmm.MachOp: instance GHC.Show.Show GHC.Cmm.MachOp.AtomicMachOp
+ GHC.Cmm.MachOp: instance GHC.Show.Show GHC.Cmm.MachOp.CallishMachOp
+ GHC.Cmm.MachOp: instance GHC.Show.Show GHC.Cmm.MachOp.MachOp
+ GHC.Cmm.MachOp: isAssociativeMachOp :: MachOp -> Bool
+ GHC.Cmm.MachOp: isCommutableMachOp :: MachOp -> Bool
+ GHC.Cmm.MachOp: isComparisonMachOp :: MachOp -> Bool
+ GHC.Cmm.MachOp: isFloatComparison :: MachOp -> Bool
+ GHC.Cmm.MachOp: machOpArgReps :: DynFlags -> MachOp -> [Width]
+ GHC.Cmm.MachOp: machOpMemcpyishAlign :: CallishMachOp -> Maybe Int
+ GHC.Cmm.MachOp: machOpResultType :: DynFlags -> MachOp -> [CmmType] -> CmmType
+ GHC.Cmm.MachOp: maybeIntComparison :: MachOp -> Maybe Width
+ GHC.Cmm.MachOp: maybeInvertComparison :: MachOp -> Maybe MachOp
+ GHC.Cmm.MachOp: mo_32To16 :: MachOp
+ GHC.Cmm.MachOp: mo_32To8 :: MachOp
+ GHC.Cmm.MachOp: mo_WordTo16 :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_WordTo32 :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_WordTo64 :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_WordTo8 :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_s_16To32 :: MachOp
+ GHC.Cmm.MachOp: mo_s_16ToWord :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_s_32ToWord :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_s_8To32 :: MachOp
+ GHC.Cmm.MachOp: mo_s_8ToWord :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_u_16To32 :: MachOp
+ GHC.Cmm.MachOp: mo_u_16ToWord :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_u_32ToWord :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_u_8To32 :: MachOp
+ GHC.Cmm.MachOp: mo_u_8ToWord :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordAdd :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordAnd :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordEq :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordMul :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordNe :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordNot :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordOr :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordSGe :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordSGt :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordSLe :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordSLt :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordSNeg :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordSQuot :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordSRem :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordSShr :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordShl :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordSub :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordUGe :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordUGt :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordULe :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordULt :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordUQuot :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordURem :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordUShr :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: mo_wordXor :: DynFlags -> MachOp
+ GHC.Cmm.MachOp: pprCallishMachOp :: CallishMachOp -> SDoc
+ GHC.Cmm.MachOp: pprMachOp :: MachOp -> SDoc
+ GHC.Cmm.Node: CmmMayReturn :: CmmReturnInfo
+ GHC.Cmm.Node: CmmNeverReturns :: CmmReturnInfo
+ GHC.Cmm.Node: CombinedScope :: CmmTickScope -> CmmTickScope -> CmmTickScope
+ GHC.Cmm.Node: ForeignConvention :: CCallConv -> [ForeignHint] -> [ForeignHint] -> CmmReturnInfo -> ForeignConvention
+ GHC.Cmm.Node: ForeignTarget :: CmmExpr -> ForeignConvention -> ForeignTarget
+ GHC.Cmm.Node: GC :: Convention
+ GHC.Cmm.Node: GlobalScope :: CmmTickScope
+ GHC.Cmm.Node: NativeDirectCall :: Convention
+ GHC.Cmm.Node: NativeNodeCall :: Convention
+ GHC.Cmm.Node: NativeReturn :: Convention
+ GHC.Cmm.Node: PrimTarget :: CallishMachOp -> ForeignTarget
+ GHC.Cmm.Node: Slow :: Convention
+ GHC.Cmm.Node: SubScope :: !Unique -> CmmTickScope -> CmmTickScope
+ GHC.Cmm.Node: [CmmAssign] :: !CmmReg -> !CmmExpr -> CmmNode O O
+ GHC.Cmm.Node: [CmmBranch] :: {-# UNPACK #-} !Label -> CmmNode O C
+ GHC.Cmm.Node: [CmmCall] :: {cml_target :: CmmExpr, cml_cont :: Maybe Label, cml_args_regs :: [GlobalReg], cml_args :: ByteOff, cml_ret_args :: ByteOff, cml_ret_off :: ByteOff} -> CmmNode O C
+ GHC.Cmm.Node: [CmmComment] :: FastString -> CmmNode O O
+ GHC.Cmm.Node: [CmmCondBranch] :: {cml_pred :: CmmExpr, cml_true, cml_false :: {-# UNPACK #-} !Label, cml_likely :: Maybe Bool} -> CmmNode O C
+ GHC.Cmm.Node: [CmmEntry] :: {-# UNPACK #-} !Label -> CmmTickScope -> CmmNode C O
+ GHC.Cmm.Node: [CmmForeignCall] :: {tgt :: ForeignTarget, res :: [CmmFormal], args :: [CmmActual], succ :: {-# UNPACK #-} !Label, ret_args :: ByteOff, ret_off :: ByteOff, intrbl :: Bool} -> CmmNode O C
+ GHC.Cmm.Node: [CmmStore] :: !CmmExpr -> !CmmExpr -> CmmNode O O
+ GHC.Cmm.Node: [CmmSwitch] :: CmmExpr -> SwitchTargets -> CmmNode O C
+ GHC.Cmm.Node: [CmmTick] :: !CmmTickish -> CmmNode O O
+ GHC.Cmm.Node: [CmmUnsafeForeignCall] :: ForeignTarget -> [CmmFormal] -> [CmmActual] -> CmmNode O O
+ GHC.Cmm.Node: [CmmUnwind] :: [(GlobalReg, Maybe CmmExpr)] -> CmmNode O O
+ GHC.Cmm.Node: combineTickScopes :: CmmTickScope -> CmmTickScope -> CmmTickScope
+ GHC.Cmm.Node: data CmmNode e x
+ GHC.Cmm.Node: data CmmReturnInfo
+ GHC.Cmm.Node: data CmmTickScope
+ GHC.Cmm.Node: data Convention
+ GHC.Cmm.Node: data ForeignConvention
+ GHC.Cmm.Node: data ForeignTarget
+ GHC.Cmm.Node: foldExp :: (CmmExpr -> z -> z) -> CmmNode e x -> z -> z
+ GHC.Cmm.Node: foldExpDeep :: (CmmExpr -> z -> z) -> CmmNode e x -> z -> z
+ GHC.Cmm.Node: foreignTargetHints :: ForeignTarget -> ([ForeignHint], [ForeignHint])
+ GHC.Cmm.Node: instance (GHC.Classes.Ord r, GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Expr.CmmReg) => GHC.Cmm.Expr.UserOfRegs r GHC.Cmm.Node.ForeignTarget
+ GHC.Cmm.Node: instance GHC.Classes.Eq (GHC.Cmm.Node.CmmNode e x)
+ GHC.Cmm.Node: instance GHC.Classes.Eq GHC.Cmm.Node.CmmReturnInfo
+ GHC.Cmm.Node: instance GHC.Classes.Eq GHC.Cmm.Node.CmmTickScope
+ GHC.Cmm.Node: instance GHC.Classes.Eq GHC.Cmm.Node.Convention
+ GHC.Cmm.Node: instance GHC.Classes.Eq GHC.Cmm.Node.ForeignConvention
+ GHC.Cmm.Node: instance GHC.Classes.Eq GHC.Cmm.Node.ForeignTarget
+ GHC.Cmm.Node: instance GHC.Classes.Ord GHC.Cmm.Node.CmmTickScope
+ GHC.Cmm.Node: instance GHC.Cmm.Dataflow.Graph.NonLocal GHC.Cmm.Node.CmmNode
+ GHC.Cmm.Node: instance GHC.Cmm.Expr.DefinerOfRegs GHC.Cmm.Expr.GlobalReg (GHC.Cmm.Node.CmmNode e x)
+ GHC.Cmm.Node: instance GHC.Cmm.Expr.DefinerOfRegs GHC.Cmm.Expr.LocalReg (GHC.Cmm.Node.CmmNode e x)
+ GHC.Cmm.Node: instance GHC.Cmm.Expr.UserOfRegs GHC.Cmm.Expr.GlobalReg (GHC.Cmm.Node.CmmNode e x)
+ GHC.Cmm.Node: instance GHC.Cmm.Expr.UserOfRegs GHC.Cmm.Expr.LocalReg (GHC.Cmm.Node.CmmNode e x)
+ GHC.Cmm.Node: instance Outputable.Outputable GHC.Cmm.Node.CmmTickScope
+ GHC.Cmm.Node: isTickSubScope :: CmmTickScope -> CmmTickScope -> Bool
+ GHC.Cmm.Node: mapCollectSuccessors :: forall a. (Label -> (Label, a)) -> CmmNode O C -> (CmmNode O C, [a])
+ GHC.Cmm.Node: mapExp :: (CmmExpr -> CmmExpr) -> CmmNode e x -> CmmNode e x
+ GHC.Cmm.Node: mapExpDeep :: (CmmExpr -> CmmExpr) -> CmmNode e x -> CmmNode e x
+ GHC.Cmm.Node: mapExpDeepM :: (CmmExpr -> Maybe CmmExpr) -> CmmNode e x -> Maybe (CmmNode e x)
+ GHC.Cmm.Node: mapExpM :: (CmmExpr -> Maybe CmmExpr) -> CmmNode e x -> Maybe (CmmNode e x)
+ GHC.Cmm.Node: mapSuccessors :: (Label -> Label) -> CmmNode O C -> CmmNode O C
+ GHC.Cmm.Node: type CmmActual = CmmExpr
+ GHC.Cmm.Node: type CmmFormal = LocalReg
+ GHC.Cmm.Node: type CmmTickish = Tickish ()
+ GHC.Cmm.Node: type UpdFrameOffset = ByteOff
+ GHC.Cmm.Node: wrapRecExp :: (CmmExpr -> CmmExpr) -> CmmExpr -> CmmExpr
+ GHC.Cmm.Node: wrapRecExpM :: (CmmExpr -> Maybe CmmExpr) -> CmmExpr -> Maybe CmmExpr
+ GHC.Cmm.Node: wrapRecExpf :: (CmmExpr -> z -> z) -> CmmExpr -> z -> z
+ GHC.Cmm.Switch: IfEqual :: Integer -> Label -> SwitchPlan -> SwitchPlan
+ GHC.Cmm.Switch: IfLT :: Bool -> Integer -> SwitchPlan -> SwitchPlan -> SwitchPlan
+ GHC.Cmm.Switch: JumpTable :: SwitchTargets -> SwitchPlan
+ GHC.Cmm.Switch: Unconditionally :: Label -> SwitchPlan
+ GHC.Cmm.Switch: createSwitchPlan :: SwitchTargets -> SwitchPlan
+ GHC.Cmm.Switch: data SwitchPlan
+ GHC.Cmm.Switch: data SwitchTargets
+ GHC.Cmm.Switch: eqSwitchTargetWith :: (Label -> Label -> Bool) -> SwitchTargets -> SwitchTargets -> Bool
+ GHC.Cmm.Switch: instance GHC.Classes.Eq GHC.Cmm.Switch.SwitchTargets
+ GHC.Cmm.Switch: instance GHC.Show.Show GHC.Cmm.Switch.SwitchPlan
+ GHC.Cmm.Switch: instance GHC.Show.Show GHC.Cmm.Switch.SwitchTargets
+ GHC.Cmm.Switch: mapSwitchTargets :: (Label -> Label) -> SwitchTargets -> SwitchTargets
+ GHC.Cmm.Switch: mkSwitchTargets :: Bool -> (Integer, Integer) -> Maybe Label -> Map Integer Label -> SwitchTargets
+ GHC.Cmm.Switch: switchTargetsCases :: SwitchTargets -> [(Integer, Label)]
+ GHC.Cmm.Switch: switchTargetsDefault :: SwitchTargets -> Maybe Label
+ GHC.Cmm.Switch: switchTargetsFallThrough :: SwitchTargets -> ([([Integer], Label)], Maybe Label)
+ GHC.Cmm.Switch: switchTargetsRange :: SwitchTargets -> (Integer, Integer)
+ GHC.Cmm.Switch: switchTargetsSigned :: SwitchTargets -> Bool
+ GHC.Cmm.Switch: switchTargetsToList :: SwitchTargets -> [Label]
+ GHC.Cmm.Switch: switchTargetsToTable :: SwitchTargets -> (Int, [Maybe Label])
+ GHC.Cmm.Switch: targetSupportsSwitch :: HscTarget -> Bool
+ GHC.Cmm.Type: AddrHint :: ForeignHint
+ GHC.Cmm.Type: NoHint :: ForeignHint
+ GHC.Cmm.Type: SignedHint :: ForeignHint
+ GHC.Cmm.Type: W128 :: Width
+ GHC.Cmm.Type: W16 :: Width
+ GHC.Cmm.Type: W256 :: Width
+ GHC.Cmm.Type: W32 :: Width
+ GHC.Cmm.Type: W512 :: Width
+ GHC.Cmm.Type: W64 :: Width
+ GHC.Cmm.Type: W8 :: Width
+ GHC.Cmm.Type: b128 :: CmmType
+ GHC.Cmm.Type: b16 :: CmmType
+ GHC.Cmm.Type: b256 :: CmmType
+ GHC.Cmm.Type: b32 :: CmmType
+ GHC.Cmm.Type: b512 :: CmmType
+ GHC.Cmm.Type: b64 :: CmmType
+ GHC.Cmm.Type: b8 :: CmmType
+ GHC.Cmm.Type: bHalfWord :: DynFlags -> CmmType
+ GHC.Cmm.Type: bWord :: DynFlags -> CmmType
+ GHC.Cmm.Type: cInt :: DynFlags -> CmmType
+ GHC.Cmm.Type: cIntWidth :: DynFlags -> Width
+ GHC.Cmm.Type: cmmBits :: Width -> CmmType
+ GHC.Cmm.Type: cmmEqType :: CmmType -> CmmType -> Bool
+ GHC.Cmm.Type: cmmEqType_ignoring_ptrhood :: CmmType -> CmmType -> Bool
+ GHC.Cmm.Type: cmmFloat :: Width -> CmmType
+ GHC.Cmm.Type: cmmVec :: Int -> CmmType -> CmmType
+ GHC.Cmm.Type: data CmmType
+ GHC.Cmm.Type: data ForeignHint
+ GHC.Cmm.Type: data Width
+ GHC.Cmm.Type: f32 :: CmmType
+ GHC.Cmm.Type: f64 :: CmmType
+ GHC.Cmm.Type: gcWord :: DynFlags -> CmmType
+ GHC.Cmm.Type: halfWordMask :: DynFlags -> Integer
+ GHC.Cmm.Type: halfWordWidth :: DynFlags -> Width
+ GHC.Cmm.Type: instance GHC.Classes.Eq GHC.Cmm.Type.CmmCat
+ GHC.Cmm.Type: instance GHC.Classes.Eq GHC.Cmm.Type.ForeignHint
+ GHC.Cmm.Type: instance GHC.Classes.Eq GHC.Cmm.Type.Width
+ GHC.Cmm.Type: instance GHC.Classes.Ord GHC.Cmm.Type.Width
+ GHC.Cmm.Type: instance GHC.Show.Show GHC.Cmm.Type.Width
+ GHC.Cmm.Type: instance Outputable.Outputable GHC.Cmm.Type.CmmCat
+ GHC.Cmm.Type: instance Outputable.Outputable GHC.Cmm.Type.CmmType
+ GHC.Cmm.Type: instance Outputable.Outputable GHC.Cmm.Type.Width
+ GHC.Cmm.Type: isBitsType :: CmmType -> Bool
+ GHC.Cmm.Type: isFloat32 :: CmmType -> Bool
+ GHC.Cmm.Type: isFloat64 :: CmmType -> Bool
+ GHC.Cmm.Type: isFloatType :: CmmType -> Bool
+ GHC.Cmm.Type: isGcPtrType :: CmmType -> Bool
+ GHC.Cmm.Type: isVecType :: CmmType -> Bool
+ GHC.Cmm.Type: isWord32 :: CmmType -> Bool
+ GHC.Cmm.Type: isWord64 :: CmmType -> Bool
+ GHC.Cmm.Type: narrowS :: Width -> Integer -> Integer
+ GHC.Cmm.Type: narrowU :: Width -> Integer -> Integer
+ GHC.Cmm.Type: rEP_CostCentreStack_mem_alloc :: DynFlags -> CmmType
+ GHC.Cmm.Type: rEP_CostCentreStack_scc_count :: DynFlags -> CmmType
+ GHC.Cmm.Type: rEP_StgEntCounter_allocd :: DynFlags -> CmmType
+ GHC.Cmm.Type: rEP_StgEntCounter_allocs :: DynFlags -> CmmType
+ GHC.Cmm.Type: type Length = Int
+ GHC.Cmm.Type: typeWidth :: CmmType -> Width
+ GHC.Cmm.Type: vec :: Length -> CmmType -> CmmType
+ GHC.Cmm.Type: vec16 :: CmmType -> CmmType
+ GHC.Cmm.Type: vec16b8 :: CmmType
+ GHC.Cmm.Type: vec2 :: CmmType -> CmmType
+ GHC.Cmm.Type: vec2b64 :: CmmType
+ GHC.Cmm.Type: vec2f64 :: CmmType
+ GHC.Cmm.Type: vec4 :: CmmType -> CmmType
+ GHC.Cmm.Type: vec4b32 :: CmmType
+ GHC.Cmm.Type: vec4f32 :: CmmType
+ GHC.Cmm.Type: vec8 :: CmmType -> CmmType
+ GHC.Cmm.Type: vec8b16 :: CmmType
+ GHC.Cmm.Type: vecElemType :: CmmType -> CmmType
+ GHC.Cmm.Type: vecLength :: CmmType -> Length
+ GHC.Cmm.Type: widthFromBytes :: Int -> Width
+ GHC.Cmm.Type: widthInBits :: Width -> Int
+ GHC.Cmm.Type: widthInBytes :: Width -> Int
+ GHC.Cmm.Type: widthInLog :: Width -> Int
+ GHC.Cmm.Type: wordWidth :: DynFlags -> Width
+ GHC.CoreToIface: patSynToIfaceDecl :: PatSyn -> IfaceDecl
+ GHC.CoreToIface: tidyToIfaceContext :: TidyEnv -> ThetaType -> IfaceContext
+ GHC.CoreToIface: tidyToIfaceTcArgs :: TidyEnv -> TyCon -> [Type] -> IfaceAppArgs
+ GHC.CoreToIface: tidyToIfaceType :: TidyEnv -> Type -> IfaceType
+ GHC.CoreToIface: toIfUnfolding :: Bool -> Unfolding -> Maybe IfaceInfoItem
+ GHC.CoreToIface: toIfaceAlt :: (AltCon, [Var], CoreExpr) -> (IfaceConAlt, [FastString], IfaceExpr)
+ GHC.CoreToIface: toIfaceApp :: Expr CoreBndr -> [Arg CoreBndr] -> IfaceExpr
+ GHC.CoreToIface: toIfaceBang :: TidyEnv -> HsImplBang -> IfaceBang
+ GHC.CoreToIface: toIfaceBind :: Bind Id -> IfaceBinding
+ GHC.CoreToIface: toIfaceBndr :: Var -> IfaceBndr
+ GHC.CoreToIface: toIfaceCoercion :: Coercion -> IfaceCoercion
+ GHC.CoreToIface: toIfaceCoercionX :: VarSet -> Coercion -> IfaceCoercion
+ GHC.CoreToIface: toIfaceCon :: AltCon -> IfaceConAlt
+ GHC.CoreToIface: toIfaceExpr :: CoreExpr -> IfaceExpr
+ GHC.CoreToIface: toIfaceForAllBndr :: TyCoVarBinder -> IfaceForAllBndr
+ GHC.CoreToIface: toIfaceIdBndr :: Id -> IfaceIdBndr
+ GHC.CoreToIface: toIfaceIdDetails :: IdDetails -> IfaceIdDetails
+ GHC.CoreToIface: toIfaceIdInfo :: IdInfo -> IfaceIdInfo
+ GHC.CoreToIface: toIfaceKind :: Type -> IfaceType
+ GHC.CoreToIface: toIfaceLetBndr :: Id -> IfaceLetBndr
+ GHC.CoreToIface: toIfaceOneShot :: Id -> IfaceOneShot
+ GHC.CoreToIface: toIfaceSrcBang :: HsSrcBang -> IfaceSrcBang
+ GHC.CoreToIface: toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs
+ GHC.CoreToIface: toIfaceTickish :: Tickish Id -> Maybe IfaceTickish
+ GHC.CoreToIface: toIfaceTvBndr :: TyVar -> IfaceTvBndr
+ GHC.CoreToIface: toIfaceTvBndrs :: [TyVar] -> [IfaceTvBndr]
+ GHC.CoreToIface: toIfaceTyCoVarBinders :: [VarBndr Var vis] -> [VarBndr IfaceBndr vis]
+ GHC.CoreToIface: toIfaceTyCon :: TyCon -> IfaceTyCon
+ GHC.CoreToIface: toIfaceTyCon_name :: Name -> IfaceTyCon
+ GHC.CoreToIface: toIfaceTyLit :: TyLit -> IfaceTyLit
+ GHC.CoreToIface: toIfaceTyVar :: TyVar -> FastString
+ GHC.CoreToIface: toIfaceType :: Type -> IfaceType
+ GHC.CoreToIface: toIfaceTypeX :: VarSet -> Type -> IfaceType
+ GHC.CoreToIface: toIfaceVar :: Id -> IfaceExpr
+ GHC.Hs: instance Data.Data.Data GHC.Hs.HsModule
+ GHC.Hs: instance Outputable.Outputable GHC.Hs.HsModule
+ GHC.Hs.Decls: hsGroupTopLevelFixitySigs :: HsGroup (GhcPass p) -> [LFixitySig (GhcPass p)]
+ GHC.Iface.Syntax: AltPpr :: Maybe (OccName -> SDoc) -> AltPpr
+ GHC.Iface.Syntax: HasInfo :: [IfaceInfoItem] -> IfaceIdInfo
+ GHC.Iface.Syntax: HsArity :: Arity -> IfaceInfoItem
+ GHC.Iface.Syntax: HsInline :: InlinePragma -> IfaceInfoItem
+ GHC.Iface.Syntax: HsLevity :: IfaceInfoItem
+ GHC.Iface.Syntax: HsNoCafRefs :: IfaceInfoItem
+ GHC.Iface.Syntax: HsStrictness :: StrictSig -> IfaceInfoItem
+ GHC.Iface.Syntax: HsUnfold :: Bool -> IfaceUnfolding -> IfaceInfoItem
+ GHC.Iface.Syntax: IfAbstractClass :: IfaceClassBody
+ GHC.Iface.Syntax: IfAbstractTyCon :: IfaceConDecls
+ GHC.Iface.Syntax: IfCompulsory :: IfaceExpr -> IfaceUnfolding
+ GHC.Iface.Syntax: IfCon :: IfaceTopBndr -> Bool -> Bool -> [IfaceBndr] -> [IfaceForAllBndr] -> IfaceEqSpec -> IfaceContext -> [IfaceType] -> [FieldLabel] -> [IfaceBang] -> [IfaceSrcBang] -> IfaceConDecl
+ GHC.Iface.Syntax: IfConcreteClass :: IfaceContext -> [IfaceAT] -> [IfaceClassOp] -> BooleanFormula IfLclName -> IfaceClassBody
+ GHC.Iface.Syntax: IfCoreUnfold :: Bool -> IfaceExpr -> IfaceUnfolding
+ GHC.Iface.Syntax: IfDFunId :: IfaceIdDetails
+ GHC.Iface.Syntax: IfDFunUnfold :: [IfaceBndr] -> [IfaceExpr] -> IfaceUnfolding
+ GHC.Iface.Syntax: IfDataInstance :: IfExtName -> IfaceTyCon -> IfaceAppArgs -> IfaceTyConParent
+ GHC.Iface.Syntax: IfDataTyCon :: [IfaceConDecl] -> IfaceConDecls
+ GHC.Iface.Syntax: IfInlineRule :: Arity -> Bool -> Bool -> IfaceExpr -> IfaceUnfolding
+ GHC.Iface.Syntax: IfLetBndr :: IfLclName -> IfaceType -> IfaceIdInfo -> IfaceJoinInfo -> IfaceLetBndr
+ GHC.Iface.Syntax: IfNewTyCon :: IfaceConDecl -> IfaceConDecls
+ GHC.Iface.Syntax: IfNoBang :: IfaceBang
+ GHC.Iface.Syntax: IfNoParent :: IfaceTyConParent
+ GHC.Iface.Syntax: IfRecSelId :: Either IfaceTyCon IfaceDecl -> Bool -> IfaceIdDetails
+ GHC.Iface.Syntax: IfSrcBang :: SrcUnpackedness -> SrcStrictness -> IfaceSrcBang
+ GHC.Iface.Syntax: IfStrict :: IfaceBang
+ GHC.Iface.Syntax: IfUnpack :: IfaceBang
+ GHC.Iface.Syntax: IfUnpackCo :: IfaceCoercion -> IfaceBang
+ GHC.Iface.Syntax: IfVanillaId :: IfaceIdDetails
+ GHC.Iface.Syntax: IfaceAT :: IfaceDecl -> Maybe IfaceType -> IfaceAT
+ GHC.Iface.Syntax: IfaceAbstractClosedSynFamilyTyCon :: IfaceFamTyConFlav
+ GHC.Iface.Syntax: IfaceAnnotation :: IfaceAnnTarget -> AnnPayload -> IfaceAnnotation
+ GHC.Iface.Syntax: IfaceApp :: IfaceExpr -> IfaceExpr -> IfaceExpr
+ GHC.Iface.Syntax: IfaceAxBranch :: [IfaceTvBndr] -> [IfaceTvBndr] -> [IfaceIdBndr] -> IfaceAppArgs -> [Role] -> IfaceType -> [BranchIndex] -> IfaceAxBranch
+ GHC.Iface.Syntax: IfaceAxiom :: IfaceTopBndr -> IfaceTyCon -> Role -> [IfaceAxBranch] -> IfaceDecl
+ GHC.Iface.Syntax: IfaceBuiltInSynFamTyCon :: IfaceFamTyConFlav
+ GHC.Iface.Syntax: IfaceCase :: IfaceExpr -> IfLclName -> [IfaceAlt] -> IfaceExpr
+ GHC.Iface.Syntax: IfaceCast :: IfaceExpr -> IfaceCoercion -> IfaceExpr
+ GHC.Iface.Syntax: IfaceClass :: IfaceTopBndr -> [Role] -> [IfaceTyConBinder] -> [FunDep IfLclName] -> IfaceClassBody -> IfaceDecl
+ GHC.Iface.Syntax: IfaceClassOp :: IfaceTopBndr -> IfaceType -> Maybe (DefMethSpec IfaceType) -> IfaceClassOp
+ GHC.Iface.Syntax: IfaceClosedSynFamilyTyCon :: Maybe (IfExtName, [IfaceAxBranch]) -> IfaceFamTyConFlav
+ GHC.Iface.Syntax: IfaceClsInst :: IfExtName -> [Maybe IfaceTyCon] -> IfExtName -> OverlapFlag -> IsOrphan -> IfaceClsInst
+ GHC.Iface.Syntax: IfaceCo :: IfaceCoercion -> IfaceExpr
+ GHC.Iface.Syntax: IfaceCompleteMatch :: [IfExtName] -> IfExtName -> IfaceCompleteMatch
+ GHC.Iface.Syntax: IfaceData :: IfaceTopBndr -> [IfaceTyConBinder] -> IfaceType -> Maybe CType -> [Role] -> IfaceContext -> IfaceConDecls -> Bool -> IfaceTyConParent -> IfaceDecl
+ GHC.Iface.Syntax: IfaceDataAlt :: IfExtName -> IfaceConAlt
+ GHC.Iface.Syntax: IfaceDataFamilyTyCon :: IfaceFamTyConFlav
+ GHC.Iface.Syntax: IfaceDefault :: IfaceConAlt
+ GHC.Iface.Syntax: IfaceECase :: IfaceExpr -> IfaceType -> IfaceExpr
+ GHC.Iface.Syntax: IfaceExt :: IfExtName -> IfaceExpr
+ GHC.Iface.Syntax: IfaceFCall :: ForeignCall -> IfaceType -> IfaceExpr
+ GHC.Iface.Syntax: IfaceFamInst :: IfExtName -> [Maybe IfaceTyCon] -> IfExtName -> IsOrphan -> IfaceFamInst
+ GHC.Iface.Syntax: IfaceFamily :: IfaceTopBndr -> Maybe IfLclName -> [IfaceTyConBinder] -> IfaceKind -> IfaceFamTyConFlav -> Injectivity -> IfaceDecl
+ GHC.Iface.Syntax: IfaceHpcTick :: Module -> Int -> IfaceTickish
+ GHC.Iface.Syntax: IfaceId :: IfaceTopBndr -> IfaceType -> IfaceIdDetails -> IfaceIdInfo -> IfaceDecl
+ GHC.Iface.Syntax: IfaceJoinPoint :: JoinArity -> IfaceJoinInfo
+ GHC.Iface.Syntax: IfaceLam :: IfaceLamBndr -> IfaceExpr -> IfaceExpr
+ GHC.Iface.Syntax: IfaceLcl :: IfLclName -> IfaceExpr
+ GHC.Iface.Syntax: IfaceLet :: IfaceBinding -> IfaceExpr -> IfaceExpr
+ GHC.Iface.Syntax: IfaceLit :: Literal -> IfaceExpr
+ GHC.Iface.Syntax: IfaceLitAlt :: Literal -> IfaceConAlt
+ GHC.Iface.Syntax: IfaceNonRec :: IfaceLetBndr -> IfaceExpr -> IfaceBinding
+ GHC.Iface.Syntax: IfaceNotJoinPoint :: IfaceJoinInfo
+ GHC.Iface.Syntax: IfaceOpenSynFamilyTyCon :: IfaceFamTyConFlav
+ GHC.Iface.Syntax: IfacePatSyn :: IfaceTopBndr -> Bool -> (IfExtName, Bool) -> Maybe (IfExtName, Bool) -> [IfaceForAllBndr] -> [IfaceForAllBndr] -> IfaceContext -> IfaceContext -> [IfaceType] -> IfaceType -> [FieldLabel] -> IfaceDecl
+ GHC.Iface.Syntax: IfaceRec :: [(IfaceLetBndr, IfaceExpr)] -> IfaceBinding
+ GHC.Iface.Syntax: IfaceRule :: RuleName -> Activation -> [IfaceBndr] -> IfExtName -> [IfaceExpr] -> IfaceExpr -> Bool -> IsOrphan -> IfaceRule
+ GHC.Iface.Syntax: IfaceSCC :: CostCentre -> Bool -> Bool -> IfaceTickish
+ GHC.Iface.Syntax: IfaceSource :: RealSrcSpan -> String -> IfaceTickish
+ GHC.Iface.Syntax: IfaceSynonym :: IfaceTopBndr -> [Role] -> [IfaceTyConBinder] -> IfaceKind -> IfaceType -> IfaceDecl
+ GHC.Iface.Syntax: IfaceTick :: IfaceTickish -> IfaceExpr -> IfaceExpr
+ GHC.Iface.Syntax: IfaceTuple :: TupleSort -> [IfaceExpr] -> IfaceExpr
+ GHC.Iface.Syntax: IfaceType :: IfaceType -> IfaceExpr
+ GHC.Iface.Syntax: NoInfo :: IfaceIdInfo
+ GHC.Iface.Syntax: NoSrcStrict :: SrcStrictness
+ GHC.Iface.Syntax: NoSrcUnpack :: SrcUnpackedness
+ GHC.Iface.Syntax: ShowHeader :: AltPpr -> ShowHowMuch
+ GHC.Iface.Syntax: ShowIface :: ShowHowMuch
+ GHC.Iface.Syntax: ShowSome :: [OccName] -> AltPpr -> ShowHowMuch
+ GHC.Iface.Syntax: ShowSub :: ShowHowMuch -> ShowForAllFlag -> ShowSub
+ GHC.Iface.Syntax: SrcLazy :: SrcStrictness
+ GHC.Iface.Syntax: SrcNoUnpack :: SrcUnpackedness
+ GHC.Iface.Syntax: SrcStrict :: SrcStrictness
+ GHC.Iface.Syntax: SrcUnpack :: SrcUnpackedness
+ GHC.Iface.Syntax: [ifATs] :: IfaceClassBody -> [IfaceAT]
+ GHC.Iface.Syntax: [ifActivation] :: IfaceRule -> Activation
+ GHC.Iface.Syntax: [ifAnnotatedTarget] :: IfaceAnnotation -> IfaceAnnTarget
+ GHC.Iface.Syntax: [ifAnnotatedValue] :: IfaceAnnotation -> AnnPayload
+ GHC.Iface.Syntax: [ifAxBranches] :: IfaceDecl -> [IfaceAxBranch]
+ GHC.Iface.Syntax: [ifBinders] :: IfaceDecl -> [IfaceTyConBinder]
+ GHC.Iface.Syntax: [ifBody] :: IfaceDecl -> IfaceClassBody
+ GHC.Iface.Syntax: [ifCType] :: IfaceDecl -> Maybe CType
+ GHC.Iface.Syntax: [ifClassCtxt] :: IfaceClassBody -> IfaceContext
+ GHC.Iface.Syntax: [ifConArgTys] :: IfaceConDecl -> [IfaceType]
+ GHC.Iface.Syntax: [ifConCtxt] :: IfaceConDecl -> IfaceContext
+ GHC.Iface.Syntax: [ifConEqSpec] :: IfaceConDecl -> IfaceEqSpec
+ GHC.Iface.Syntax: [ifConExTCvs] :: IfaceConDecl -> [IfaceBndr]
+ GHC.Iface.Syntax: [ifConFields] :: IfaceConDecl -> [FieldLabel]
+ GHC.Iface.Syntax: [ifConInfix] :: IfaceConDecl -> Bool
+ GHC.Iface.Syntax: [ifConName] :: IfaceConDecl -> IfaceTopBndr
+ GHC.Iface.Syntax: [ifConSrcStricts] :: IfaceConDecl -> [IfaceSrcBang]
+ GHC.Iface.Syntax: [ifConStricts] :: IfaceConDecl -> [IfaceBang]
+ GHC.Iface.Syntax: [ifConUserTvBinders] :: IfaceConDecl -> [IfaceForAllBndr]
+ GHC.Iface.Syntax: [ifConWrapper] :: IfaceConDecl -> Bool
+ GHC.Iface.Syntax: [ifCons] :: IfaceDecl -> IfaceConDecls
+ GHC.Iface.Syntax: [ifCtxt] :: IfaceDecl -> IfaceContext
+ GHC.Iface.Syntax: [ifDFun] :: IfaceClsInst -> IfExtName
+ GHC.Iface.Syntax: [ifFDs] :: IfaceDecl -> [FunDep IfLclName]
+ GHC.Iface.Syntax: [ifFamFlav] :: IfaceDecl -> IfaceFamTyConFlav
+ GHC.Iface.Syntax: [ifFamInj] :: IfaceDecl -> Injectivity
+ GHC.Iface.Syntax: [ifFamInstAxiom] :: IfaceFamInst -> IfExtName
+ GHC.Iface.Syntax: [ifFamInstFam] :: IfaceFamInst -> IfExtName
+ GHC.Iface.Syntax: [ifFamInstOrph] :: IfaceFamInst -> IsOrphan
+ GHC.Iface.Syntax: [ifFamInstTys] :: IfaceFamInst -> [Maybe IfaceTyCon]
+ GHC.Iface.Syntax: [ifFieldLabels] :: IfaceDecl -> [FieldLabel]
+ GHC.Iface.Syntax: [ifGadtSyntax] :: IfaceDecl -> Bool
+ GHC.Iface.Syntax: [ifIdDetails] :: IfaceDecl -> IfaceIdDetails
+ GHC.Iface.Syntax: [ifIdInfo] :: IfaceDecl -> IfaceIdInfo
+ GHC.Iface.Syntax: [ifInstCls] :: IfaceClsInst -> IfExtName
+ GHC.Iface.Syntax: [ifInstOrph] :: IfaceClsInst -> IsOrphan
+ GHC.Iface.Syntax: [ifInstTys] :: IfaceClsInst -> [Maybe IfaceTyCon]
+ GHC.Iface.Syntax: [ifMinDef] :: IfaceClassBody -> BooleanFormula IfLclName
+ GHC.Iface.Syntax: [ifName] :: IfaceDecl -> IfaceTopBndr
+ GHC.Iface.Syntax: [ifOFlag] :: IfaceClsInst -> OverlapFlag
+ GHC.Iface.Syntax: [ifParent] :: IfaceDecl -> IfaceTyConParent
+ GHC.Iface.Syntax: [ifPatArgs] :: IfaceDecl -> [IfaceType]
+ GHC.Iface.Syntax: [ifPatBuilder] :: IfaceDecl -> Maybe (IfExtName, Bool)
+ GHC.Iface.Syntax: [ifPatExBndrs] :: IfaceDecl -> [IfaceForAllBndr]
+ GHC.Iface.Syntax: [ifPatIsInfix] :: IfaceDecl -> Bool
+ GHC.Iface.Syntax: [ifPatMatcher] :: IfaceDecl -> (IfExtName, Bool)
+ GHC.Iface.Syntax: [ifPatProvCtxt] :: IfaceDecl -> IfaceContext
+ GHC.Iface.Syntax: [ifPatReqCtxt] :: IfaceDecl -> IfaceContext
+ GHC.Iface.Syntax: [ifPatTy] :: IfaceDecl -> IfaceType
+ GHC.Iface.Syntax: [ifPatUnivBndrs] :: IfaceDecl -> [IfaceForAllBndr]
+ GHC.Iface.Syntax: [ifResKind] :: IfaceDecl -> IfaceKind
+ GHC.Iface.Syntax: [ifResVar] :: IfaceDecl -> Maybe IfLclName
+ GHC.Iface.Syntax: [ifRole] :: IfaceDecl -> Role
+ GHC.Iface.Syntax: [ifRoles] :: IfaceDecl -> [Role]
+ GHC.Iface.Syntax: [ifRuleArgs] :: IfaceRule -> [IfaceExpr]
+ GHC.Iface.Syntax: [ifRuleAuto] :: IfaceRule -> Bool
+ GHC.Iface.Syntax: [ifRuleBndrs] :: IfaceRule -> [IfaceBndr]
+ GHC.Iface.Syntax: [ifRuleHead] :: IfaceRule -> IfExtName
+ GHC.Iface.Syntax: [ifRuleName] :: IfaceRule -> RuleName
+ GHC.Iface.Syntax: [ifRuleOrph] :: IfaceRule -> IsOrphan
+ GHC.Iface.Syntax: [ifRuleRhs] :: IfaceRule -> IfaceExpr
+ GHC.Iface.Syntax: [ifSigs] :: IfaceClassBody -> [IfaceClassOp]
+ GHC.Iface.Syntax: [ifSynRhs] :: IfaceDecl -> IfaceType
+ GHC.Iface.Syntax: [ifTyCon] :: IfaceDecl -> IfaceTyCon
+ GHC.Iface.Syntax: [ifType] :: IfaceDecl -> IfaceType
+ GHC.Iface.Syntax: [ifaxbCoVars] :: IfaceAxBranch -> [IfaceIdBndr]
+ GHC.Iface.Syntax: [ifaxbEtaTyVars] :: IfaceAxBranch -> [IfaceTvBndr]
+ GHC.Iface.Syntax: [ifaxbIncomps] :: IfaceAxBranch -> [BranchIndex]
+ GHC.Iface.Syntax: [ifaxbLHS] :: IfaceAxBranch -> IfaceAppArgs
+ GHC.Iface.Syntax: [ifaxbRHS] :: IfaceAxBranch -> IfaceType
+ GHC.Iface.Syntax: [ifaxbRoles] :: IfaceAxBranch -> [Role]
+ GHC.Iface.Syntax: [ifaxbTyVars] :: IfaceAxBranch -> [IfaceTvBndr]
+ GHC.Iface.Syntax: [ss_forall] :: ShowSub -> ShowForAllFlag
+ GHC.Iface.Syntax: [ss_how_much] :: ShowSub -> ShowHowMuch
+ GHC.Iface.Syntax: data IfaceAT
+ GHC.Iface.Syntax: data IfaceAnnotation
+ GHC.Iface.Syntax: data IfaceAxBranch
+ GHC.Iface.Syntax: data IfaceBang
+ GHC.Iface.Syntax: data IfaceBinding
+ GHC.Iface.Syntax: data IfaceClassBody
+ GHC.Iface.Syntax: data IfaceClassOp
+ GHC.Iface.Syntax: data IfaceClsInst
+ GHC.Iface.Syntax: data IfaceCompleteMatch
+ GHC.Iface.Syntax: data IfaceConAlt
+ GHC.Iface.Syntax: data IfaceConDecl
+ GHC.Iface.Syntax: data IfaceConDecls
+ GHC.Iface.Syntax: data IfaceDecl
+ GHC.Iface.Syntax: data IfaceExpr
+ GHC.Iface.Syntax: data IfaceFamInst
+ GHC.Iface.Syntax: data IfaceFamTyConFlav
+ GHC.Iface.Syntax: data IfaceIdDetails
+ GHC.Iface.Syntax: data IfaceIdInfo
+ GHC.Iface.Syntax: data IfaceInfoItem
+ GHC.Iface.Syntax: data IfaceJoinInfo
+ GHC.Iface.Syntax: data IfaceLetBndr
+ GHC.Iface.Syntax: data IfaceRule
+ GHC.Iface.Syntax: data IfaceSrcBang
+ GHC.Iface.Syntax: data IfaceTickish
+ GHC.Iface.Syntax: data IfaceTyConParent
+ GHC.Iface.Syntax: data IfaceUnfolding
+ GHC.Iface.Syntax: data ShowHowMuch
+ GHC.Iface.Syntax: data ShowSub
+ GHC.Iface.Syntax: data SrcStrictness
+ GHC.Iface.Syntax: data SrcUnpackedness
+ GHC.Iface.Syntax: freeNamesIfDecl :: IfaceDecl -> NameSet
+ GHC.Iface.Syntax: freeNamesIfFamInst :: IfaceFamInst -> NameSet
+ GHC.Iface.Syntax: freeNamesIfRule :: IfaceRule -> NameSet
+ GHC.Iface.Syntax: getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr
+ GHC.Iface.Syntax: ifaceDeclFingerprints :: Fingerprint -> IfaceDecl -> [(OccName, Fingerprint)]
+ GHC.Iface.Syntax: ifaceDeclImplicitBndrs :: IfaceDecl -> [OccName]
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceAT
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceAnnotation
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceAxBranch
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceBang
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceBinding
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceClassOp
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceClsInst
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceCompleteMatch
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceConAlt
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceConDecl
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceConDecls
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceDecl
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceExpr
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceFamInst
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceFamTyConFlav
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceIdDetails
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceIdInfo
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceInfoItem
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceJoinInfo
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceLetBndr
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceRule
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceSrcBang
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceTickish
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceTyConParent
+ GHC.Iface.Syntax: instance Binary.Binary GHC.Iface.Syntax.IfaceUnfolding
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceAT
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceAnnotation
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceAxBranch
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceBang
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceBinding
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceClassBody
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceClassOp
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceClsInst
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceCompleteMatch
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceConAlt
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceConDecl
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceConDecls
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceDecl
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceExpr
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceFamInst
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceFamTyConFlav
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceIdDetails
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceIdInfo
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceInfoItem
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceJoinInfo
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceLetBndr
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceRule
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceSrcBang
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceTickish
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceTyConParent
+ GHC.Iface.Syntax: instance Control.DeepSeq.NFData GHC.Iface.Syntax.IfaceUnfolding
+ GHC.Iface.Syntax: instance Name.NamedThing GHC.Iface.Syntax.IfaceClassOp
+ GHC.Iface.Syntax: instance Name.NamedThing GHC.Iface.Syntax.IfaceConDecl
+ GHC.Iface.Syntax: instance Name.NamedThing GHC.Iface.Syntax.IfaceDecl
+ GHC.Iface.Syntax: instance OccName.HasOccName GHC.Iface.Syntax.IfaceClassOp
+ GHC.Iface.Syntax: instance OccName.HasOccName GHC.Iface.Syntax.IfaceConDecl
+ GHC.Iface.Syntax: instance OccName.HasOccName GHC.Iface.Syntax.IfaceDecl
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceAT
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceAnnotation
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceClassOp
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceClsInst
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceCompleteMatch
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceConAlt
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceDecl
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceExpr
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceFamInst
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceIdDetails
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceIdInfo
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceInfoItem
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceJoinInfo
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceRule
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceTyConParent
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.IfaceUnfolding
+ GHC.Iface.Syntax: instance Outputable.Outputable GHC.Iface.Syntax.ShowHowMuch
+ GHC.Iface.Syntax: newtype AltPpr
+ GHC.Iface.Syntax: pprIfaceDecl :: ShowSub -> IfaceDecl -> SDoc
+ GHC.Iface.Syntax: pprIfaceExpr :: (SDoc -> SDoc) -> IfaceExpr -> SDoc
+ GHC.Iface.Syntax: putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO ()
+ GHC.Iface.Syntax: showToHeader :: ShowSub
+ GHC.Iface.Syntax: showToIface :: ShowSub
+ GHC.Iface.Syntax: type IfaceAlt = (IfaceConAlt, [IfLclName], IfaceExpr)
+ GHC.Iface.Syntax: type IfaceAnnTarget = AnnTarget OccName
+ GHC.Iface.Syntax: type IfaceEqSpec = [(IfLclName, IfaceType)]
+ GHC.Iface.Syntax: type IfaceTopBndr = Name
+ GHC.Iface.Syntax: visibleIfConDecls :: IfaceConDecls -> [IfaceConDecl]
+ GHC.Iface.Type: ForallInvis :: ForallVisFlag
+ GHC.Iface.Type: ForallVis :: ForallVisFlag
+ GHC.Iface.Type: IA_Arg :: IfaceType -> ArgFlag -> IfaceAppArgs -> IfaceAppArgs
+ GHC.Iface.Type: IA_Nil :: IfaceAppArgs
+ GHC.Iface.Type: IfaceAppCo :: IfaceCoercion -> IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceAppTy :: IfaceType -> IfaceAppArgs -> IfaceType
+ GHC.Iface.Type: IfaceAxiomInstCo :: IfExtName -> BranchIndex -> [IfaceCoercion] -> IfaceCoercion
+ GHC.Iface.Type: IfaceAxiomRuleCo :: IfLclName -> [IfaceCoercion] -> IfaceCoercion
+ GHC.Iface.Type: IfaceCastTy :: IfaceType -> IfaceCoercion -> IfaceType
+ GHC.Iface.Type: IfaceCoVarCo :: IfLclName -> IfaceCoercion
+ GHC.Iface.Type: IfaceCoercionTy :: IfaceCoercion -> IfaceType
+ GHC.Iface.Type: IfaceEqualityTyCon :: IfaceTyConSort
+ GHC.Iface.Type: IfaceForAllCo :: IfaceBndr -> IfaceCoercion -> IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceForAllTy :: IfaceForAllBndr -> IfaceType -> IfaceType
+ GHC.Iface.Type: IfaceFreeCoVar :: CoVar -> IfaceCoercion
+ GHC.Iface.Type: IfaceFreeTyVar :: TyVar -> IfaceType
+ GHC.Iface.Type: IfaceFunCo :: Role -> IfaceCoercion -> IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceFunTy :: AnonArgFlag -> IfaceType -> IfaceType -> IfaceType
+ GHC.Iface.Type: IfaceGReflCo :: Role -> IfaceType -> IfaceMCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceHoleCo :: CoVar -> IfaceCoercion
+ GHC.Iface.Type: IfaceIdBndr :: {-# UNPACK #-} !IfaceIdBndr -> IfaceBndr
+ GHC.Iface.Type: IfaceInstCo :: IfaceCoercion -> IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceKindCo :: IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceLRCo :: LeftOrRight -> IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceLitTy :: IfaceTyLit -> IfaceType
+ GHC.Iface.Type: IfaceMCo :: IfaceCoercion -> IfaceMCoercion
+ GHC.Iface.Type: IfaceMRefl :: IfaceMCoercion
+ GHC.Iface.Type: IfaceNoOneShot :: IfaceOneShot
+ GHC.Iface.Type: IfaceNormalTyCon :: IfaceTyConSort
+ GHC.Iface.Type: IfaceNthCo :: Int -> IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceNumTyLit :: Integer -> IfaceTyLit
+ GHC.Iface.Type: IfaceOneShot :: IfaceOneShot
+ GHC.Iface.Type: IfacePhantomProv :: IfaceCoercion -> IfaceUnivCoProv
+ GHC.Iface.Type: IfacePluginProv :: String -> IfaceUnivCoProv
+ GHC.Iface.Type: IfaceProofIrrelProv :: IfaceCoercion -> IfaceUnivCoProv
+ GHC.Iface.Type: IfaceReflCo :: IfaceType -> IfaceCoercion
+ GHC.Iface.Type: IfaceStrTyLit :: FastString -> IfaceTyLit
+ GHC.Iface.Type: IfaceSubCo :: IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceSumTyCon :: !Arity -> IfaceTyConSort
+ GHC.Iface.Type: IfaceSymCo :: IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceTransCo :: IfaceCoercion -> IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: IfaceTupleTy :: TupleSort -> PromotionFlag -> IfaceAppArgs -> IfaceType
+ GHC.Iface.Type: IfaceTupleTyCon :: !Arity -> !TupleSort -> IfaceTyConSort
+ GHC.Iface.Type: IfaceTvBndr :: {-# UNPACK #-} !IfaceTvBndr -> IfaceBndr
+ GHC.Iface.Type: IfaceTyCon :: IfExtName -> IfaceTyConInfo -> IfaceTyCon
+ GHC.Iface.Type: IfaceTyConApp :: IfaceTyCon -> IfaceAppArgs -> IfaceType
+ GHC.Iface.Type: IfaceTyConAppCo :: Role -> IfaceTyCon -> [IfaceCoercion] -> IfaceCoercion
+ GHC.Iface.Type: IfaceTyConInfo :: PromotionFlag -> IfaceTyConSort -> IfaceTyConInfo
+ GHC.Iface.Type: IfaceTyVar :: IfLclName -> IfaceType
+ GHC.Iface.Type: IfaceUnivCo :: IfaceUnivCoProv -> Role -> IfaceType -> IfaceType -> IfaceCoercion
+ GHC.Iface.Type: IfaceUnsafeCoerceProv :: IfaceUnivCoProv
+ GHC.Iface.Type: Inferred :: ArgFlag
+ GHC.Iface.Type: InvisArg :: AnonArgFlag
+ GHC.Iface.Type: Required :: ArgFlag
+ GHC.Iface.Type: ShowForAllMust :: ShowForAllFlag
+ GHC.Iface.Type: ShowForAllWhen :: ShowForAllFlag
+ GHC.Iface.Type: Specified :: ArgFlag
+ GHC.Iface.Type: SuppressBndrSig :: Bool -> SuppressBndrSig
+ GHC.Iface.Type: UseBndrParens :: Bool -> UseBndrParens
+ GHC.Iface.Type: VisArg :: AnonArgFlag
+ GHC.Iface.Type: [ifaceTyConInfo] :: IfaceTyCon -> IfaceTyConInfo
+ GHC.Iface.Type: [ifaceTyConIsPromoted] :: IfaceTyConInfo -> PromotionFlag
+ GHC.Iface.Type: [ifaceTyConName] :: IfaceTyCon -> IfExtName
+ GHC.Iface.Type: [ifaceTyConSort] :: IfaceTyConInfo -> IfaceTyConSort
+ GHC.Iface.Type: appArgsIfaceTypes :: IfaceAppArgs -> [IfaceType]
+ GHC.Iface.Type: appArgsIfaceTypesArgFlags :: IfaceAppArgs -> [(IfaceType, ArgFlag)]
+ GHC.Iface.Type: data AnonArgFlag
+ GHC.Iface.Type: data ArgFlag
+ GHC.Iface.Type: data ForallVisFlag
+ GHC.Iface.Type: data IfaceAppArgs
+ GHC.Iface.Type: data IfaceBndr
+ GHC.Iface.Type: data IfaceCoercion
+ GHC.Iface.Type: data IfaceMCoercion
+ GHC.Iface.Type: data IfaceOneShot
+ GHC.Iface.Type: data IfaceTyCon
+ GHC.Iface.Type: data IfaceTyConInfo
+ GHC.Iface.Type: data IfaceTyConSort
+ GHC.Iface.Type: data IfaceTyLit
+ GHC.Iface.Type: data IfaceType
+ GHC.Iface.Type: data IfaceUnivCoProv
+ GHC.Iface.Type: data ShowForAllFlag
+ GHC.Iface.Type: ifForAllBndrName :: IfaceForAllBndr -> IfLclName
+ GHC.Iface.Type: ifForAllBndrVar :: IfaceForAllBndr -> IfaceBndr
+ GHC.Iface.Type: ifTyConBinderName :: IfaceTyConBinder -> IfLclName
+ GHC.Iface.Type: ifTyConBinderVar :: IfaceTyConBinder -> IfaceBndr
+ GHC.Iface.Type: ifaceBndrName :: IfaceBndr -> IfLclName
+ GHC.Iface.Type: inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool
+ GHC.Iface.Type: instance Binary.Binary (BasicTypes.DefMethSpec GHC.Iface.Type.IfaceType)
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceAppArgs
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceBndr
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceCoercion
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceMCoercion
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceOneShot
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceTyCon
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceTyConInfo
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceTyConSort
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceTyLit
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceType
+ GHC.Iface.Type: instance Binary.Binary GHC.Iface.Type.IfaceUnivCoProv
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceAppArgs
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceBndr
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceCoercion
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceMCoercion
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceOneShot
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceTyCon
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceTyConInfo
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceTyConSort
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceTyLit
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceType
+ GHC.Iface.Type: instance Control.DeepSeq.NFData GHC.Iface.Type.IfaceUnivCoProv
+ GHC.Iface.Type: instance GHC.Base.Monoid GHC.Iface.Type.IfaceAppArgs
+ GHC.Iface.Type: instance GHC.Base.Semigroup GHC.Iface.Type.IfaceAppArgs
+ GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceTyCon
+ GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceTyConInfo
+ GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceTyConSort
+ GHC.Iface.Type: instance GHC.Classes.Eq GHC.Iface.Type.IfaceTyLit
+ GHC.Iface.Type: instance Outputable.Outputable GHC.Iface.Type.IfaceAppArgs
+ GHC.Iface.Type: instance Outputable.Outputable GHC.Iface.Type.IfaceBndr
+ GHC.Iface.Type: instance Outputable.Outputable GHC.Iface.Type.IfaceCoercion
+ GHC.Iface.Type: instance Outputable.Outputable GHC.Iface.Type.IfaceTyCon
+ GHC.Iface.Type: instance Outputable.Outputable GHC.Iface.Type.IfaceTyLit
+ GHC.Iface.Type: instance Outputable.Outputable GHC.Iface.Type.IfaceType
+ GHC.Iface.Type: isIfaceLiftedTypeKind :: IfaceKind -> Bool
+ GHC.Iface.Type: isIfaceTauType :: IfaceType -> Bool
+ GHC.Iface.Type: mkIfaceForAllTvBndr :: ArgFlag -> IfaceTvBndr -> IfaceForAllBndr
+ GHC.Iface.Type: mkIfaceTyConKind :: [IfaceTyConBinder] -> IfaceKind -> IfaceKind
+ GHC.Iface.Type: mkIfaceTySubst :: [(IfLclName, IfaceType)] -> IfaceTySubst
+ GHC.Iface.Type: newtype SuppressBndrSig
+ GHC.Iface.Type: newtype UseBndrParens
+ GHC.Iface.Type: pprIfaceAppArgs :: IfaceAppArgs -> SDoc
+ GHC.Iface.Type: pprIfaceBndrs :: [IfaceBndr] -> SDoc
+ GHC.Iface.Type: pprIfaceCoTcApp :: PprPrec -> IfaceTyCon -> [IfaceCoercion] -> SDoc
+ GHC.Iface.Type: pprIfaceCoercion :: IfaceCoercion -> SDoc
+ GHC.Iface.Type: pprIfaceContext :: PprPrec -> [IfacePredType] -> SDoc
+ GHC.Iface.Type: pprIfaceContextArr :: [IfacePredType] -> SDoc
+ GHC.Iface.Type: pprIfaceForAll :: [IfaceForAllBndr] -> SDoc
+ GHC.Iface.Type: pprIfaceForAllPart :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc
+ GHC.Iface.Type: pprIfaceForAllPartMust :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc
+ GHC.Iface.Type: pprIfaceIdBndr :: IfaceIdBndr -> SDoc
+ GHC.Iface.Type: pprIfaceLamBndr :: IfaceLamBndr -> SDoc
+ GHC.Iface.Type: pprIfacePrefixApp :: PprPrec -> SDoc -> [SDoc] -> SDoc
+ GHC.Iface.Type: pprIfaceSigmaType :: ShowForAllFlag -> IfaceType -> SDoc
+ GHC.Iface.Type: pprIfaceTvBndr :: IfaceTvBndr -> SuppressBndrSig -> UseBndrParens -> SDoc
+ GHC.Iface.Type: pprIfaceTyConBinders :: SuppressBndrSig -> [IfaceTyConBinder] -> SDoc
+ GHC.Iface.Type: pprIfaceTyLit :: IfaceTyLit -> SDoc
+ GHC.Iface.Type: pprIfaceType :: IfaceType -> SDoc
+ GHC.Iface.Type: pprIfaceTypeApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
+ GHC.Iface.Type: pprParendIfaceAppArgs :: IfaceAppArgs -> SDoc
+ GHC.Iface.Type: pprParendIfaceCoercion :: IfaceCoercion -> SDoc
+ GHC.Iface.Type: pprParendIfaceType :: IfaceType -> SDoc
+ GHC.Iface.Type: pprPrecIfaceType :: PprPrec -> IfaceType -> SDoc
+ GHC.Iface.Type: pprTyTcApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc
+ GHC.Iface.Type: pprUserIfaceForAll :: [IfaceForAllBndr] -> SDoc
+ GHC.Iface.Type: splitIfaceSigmaTy :: IfaceType -> ([IfaceForAllBndr], [IfacePredType], IfaceType)
+ GHC.Iface.Type: stripIfaceInvisVars :: DynFlags -> [IfaceTyConBinder] -> [IfaceTyConBinder]
+ GHC.Iface.Type: stripInvisArgs :: DynFlags -> IfaceAppArgs -> IfaceAppArgs
+ GHC.Iface.Type: substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs
+ GHC.Iface.Type: substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType
+ GHC.Iface.Type: suppressIfaceInvisibles :: DynFlags -> [IfaceTyConBinder] -> [a] -> [a]
+ GHC.Iface.Type: type IfExtName = Name
+ GHC.Iface.Type: type IfLclName = FastString
+ GHC.Iface.Type: type IfaceContext = [IfacePredType]
+ GHC.Iface.Type: type IfaceForAllBndr = VarBndr IfaceBndr ArgFlag
+ GHC.Iface.Type: type IfaceIdBndr = (IfLclName, IfaceType)
+ GHC.Iface.Type: type IfaceKind = IfaceType
+ GHC.Iface.Type: type IfaceLamBndr = (IfaceBndr, IfaceOneShot)
+ GHC.Iface.Type: type IfacePredType = IfaceType
+ GHC.Iface.Type: type IfaceTvBndr = (IfLclName, IfaceKind)
+ GHC.Iface.Type: type IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis
+ GHC.Platform.ARM: activeStgRegs :: [GlobalReg]
+ GHC.Platform.ARM: callerSaves :: GlobalReg -> Bool
+ GHC.Platform.ARM: freeReg :: RegNo -> Bool
+ GHC.Platform.ARM: globalRegMaybe :: GlobalReg -> Maybe RealReg
+ GHC.Platform.ARM: haveRegBase :: Bool
+ GHC.Platform.ARM64: activeStgRegs :: [GlobalReg]
+ GHC.Platform.ARM64: callerSaves :: GlobalReg -> Bool
+ GHC.Platform.ARM64: freeReg :: RegNo -> Bool
+ GHC.Platform.ARM64: globalRegMaybe :: GlobalReg -> Maybe RealReg
+ GHC.Platform.ARM64: haveRegBase :: Bool
+ GHC.Platform.NoRegs: activeStgRegs :: [GlobalReg]
+ GHC.Platform.NoRegs: callerSaves :: GlobalReg -> Bool
+ GHC.Platform.NoRegs: freeReg :: RegNo -> Bool
+ GHC.Platform.NoRegs: globalRegMaybe :: GlobalReg -> Maybe RealReg
+ GHC.Platform.NoRegs: haveRegBase :: Bool
+ GHC.Platform.PPC: activeStgRegs :: [GlobalReg]
+ GHC.Platform.PPC: callerSaves :: GlobalReg -> Bool
+ GHC.Platform.PPC: freeReg :: RegNo -> Bool
+ GHC.Platform.PPC: globalRegMaybe :: GlobalReg -> Maybe RealReg
+ GHC.Platform.PPC: haveRegBase :: Bool
+ GHC.Platform.Regs: activeStgRegs :: Platform -> [GlobalReg]
+ GHC.Platform.Regs: callerSaves :: Platform -> GlobalReg -> Bool
+ GHC.Platform.Regs: freeReg :: Platform -> RegNo -> Bool
+ GHC.Platform.Regs: globalRegMaybe :: Platform -> GlobalReg -> Maybe RealReg
+ GHC.Platform.Regs: haveRegBase :: Platform -> Bool
+ GHC.Platform.S390X: activeStgRegs :: [GlobalReg]
+ GHC.Platform.S390X: callerSaves :: GlobalReg -> Bool
+ GHC.Platform.S390X: freeReg :: RegNo -> Bool
+ GHC.Platform.S390X: globalRegMaybe :: GlobalReg -> Maybe RealReg
+ GHC.Platform.S390X: haveRegBase :: Bool
+ GHC.Platform.SPARC: activeStgRegs :: [GlobalReg]
+ GHC.Platform.SPARC: callerSaves :: GlobalReg -> Bool
+ GHC.Platform.SPARC: freeReg :: RegNo -> Bool
+ GHC.Platform.SPARC: globalRegMaybe :: GlobalReg -> Maybe RealReg
+ GHC.Platform.SPARC: haveRegBase :: Bool
+ GHC.Platform.X86: activeStgRegs :: [GlobalReg]
+ GHC.Platform.X86: callerSaves :: GlobalReg -> Bool
+ GHC.Platform.X86: freeReg :: RegNo -> Bool
+ GHC.Platform.X86: freeRegBase :: RegNo -> Bool
+ GHC.Platform.X86: globalRegMaybe :: GlobalReg -> Maybe RealReg
+ GHC.Platform.X86: haveRegBase :: Bool
+ GHC.Platform.X86_64: activeStgRegs :: [GlobalReg]
+ GHC.Platform.X86_64: callerSaves :: GlobalReg -> Bool
+ GHC.Platform.X86_64: freeReg :: RegNo -> Bool
+ GHC.Platform.X86_64: freeRegBase :: RegNo -> Bool
+ GHC.Platform.X86_64: globalRegMaybe :: GlobalReg -> Maybe RealReg
+ GHC.Platform.X86_64: haveRegBase :: Bool
+ GHC.Runtime.Layout: ArgGen :: Liveness -> ArgDescr
+ GHC.Runtime.Layout: ArgSpec :: !Int -> ArgDescr
+ GHC.Runtime.Layout: ArrayPtrsRep :: !WordOff -> !WordOff -> SMRep
+ GHC.Runtime.Layout: ArrayWordsRep :: !WordOff -> SMRep
+ GHC.Runtime.Layout: BlackHole :: ClosureTypeInfo
+ GHC.Runtime.Layout: Constr :: ConTagZ -> ConstrDescription -> ClosureTypeInfo
+ GHC.Runtime.Layout: Fun :: FunArity -> ArgDescr -> ClosureTypeInfo
+ GHC.Runtime.Layout: HeapRep :: IsStatic -> !WordOff -> !WordOff -> ClosureTypeInfo -> SMRep
+ GHC.Runtime.Layout: IndStatic :: ClosureTypeInfo
+ GHC.Runtime.Layout: RTSRep :: Int -> SMRep -> SMRep
+ GHC.Runtime.Layout: SmallArrayPtrsRep :: !WordOff -> SMRep
+ GHC.Runtime.Layout: StackRep :: Liveness -> SMRep
+ GHC.Runtime.Layout: Thunk :: ClosureTypeInfo
+ GHC.Runtime.Layout: ThunkSelector :: SelectorOffset -> ClosureTypeInfo
+ GHC.Runtime.Layout: aRG_GEN :: Int
+ GHC.Runtime.Layout: aRG_GEN_BIG :: Int
+ GHC.Runtime.Layout: arrPtrsHdrSize :: DynFlags -> ByteOff
+ GHC.Runtime.Layout: arrPtrsHdrSizeW :: DynFlags -> WordOff
+ GHC.Runtime.Layout: arrPtrsRep :: DynFlags -> WordOff -> SMRep
+ GHC.Runtime.Layout: arrWordsHdrSize :: DynFlags -> ByteOff
+ GHC.Runtime.Layout: arrWordsHdrSizeW :: DynFlags -> WordOff
+ GHC.Runtime.Layout: arrWordsRep :: DynFlags -> ByteOff -> SMRep
+ GHC.Runtime.Layout: blackHoleRep :: SMRep
+ GHC.Runtime.Layout: bytesToWordsRoundUp :: DynFlags -> ByteOff -> WordOff
+ GHC.Runtime.Layout: card :: DynFlags -> Int -> Int
+ GHC.Runtime.Layout: cardRoundUp :: DynFlags -> Int -> Int
+ GHC.Runtime.Layout: cardTableSizeB :: DynFlags -> Int -> ByteOff
+ GHC.Runtime.Layout: cardTableSizeW :: DynFlags -> Int -> WordOff
+ GHC.Runtime.Layout: data ArgDescr
+ GHC.Runtime.Layout: data ClosureTypeInfo
+ GHC.Runtime.Layout: data SMRep
+ GHC.Runtime.Layout: data StgHalfWord
+ GHC.Runtime.Layout: data StgWord
+ GHC.Runtime.Layout: fixedHdrSize :: DynFlags -> ByteOff
+ GHC.Runtime.Layout: fixedHdrSizeW :: DynFlags -> WordOff
+ GHC.Runtime.Layout: fromStgHalfWord :: StgHalfWord -> Integer
+ GHC.Runtime.Layout: fromStgWord :: StgWord -> Integer
+ GHC.Runtime.Layout: halfWordSize :: DynFlags -> ByteOff
+ GHC.Runtime.Layout: halfWordSizeInBits :: DynFlags -> Int
+ GHC.Runtime.Layout: hdrSize :: DynFlags -> SMRep -> ByteOff
+ GHC.Runtime.Layout: hdrSizeW :: DynFlags -> SMRep -> WordOff
+ GHC.Runtime.Layout: heapClosureSizeW :: DynFlags -> SMRep -> WordOff
+ GHC.Runtime.Layout: indStaticRep :: SMRep
+ GHC.Runtime.Layout: instance Data.Bits.Bits GHC.Runtime.Layout.StgWord
+ GHC.Runtime.Layout: instance GHC.Classes.Eq GHC.Runtime.Layout.StgHalfWord
+ GHC.Runtime.Layout: instance GHC.Classes.Eq GHC.Runtime.Layout.StgWord
+ GHC.Runtime.Layout: instance Outputable.Outputable GHC.Runtime.Layout.ArgDescr
+ GHC.Runtime.Layout: instance Outputable.Outputable GHC.Runtime.Layout.ClosureTypeInfo
+ GHC.Runtime.Layout: instance Outputable.Outputable GHC.Runtime.Layout.SMRep
+ GHC.Runtime.Layout: instance Outputable.Outputable GHC.Runtime.Layout.StgHalfWord
+ GHC.Runtime.Layout: instance Outputable.Outputable GHC.Runtime.Layout.StgWord
+ GHC.Runtime.Layout: isConRep :: SMRep -> Bool
+ GHC.Runtime.Layout: isFunRep :: SMRep -> Bool
+ GHC.Runtime.Layout: isStackRep :: SMRep -> Bool
+ GHC.Runtime.Layout: isStaticNoCafCon :: SMRep -> Bool
+ GHC.Runtime.Layout: isStaticRep :: SMRep -> IsStatic
+ GHC.Runtime.Layout: isThunkRep :: SMRep -> Bool
+ GHC.Runtime.Layout: mkHeapRep :: DynFlags -> IsStatic -> WordOff -> WordOff -> ClosureTypeInfo -> SMRep
+ GHC.Runtime.Layout: mkRTSRep :: Int -> SMRep -> SMRep
+ GHC.Runtime.Layout: mkStackRep :: [Bool] -> SMRep
+ GHC.Runtime.Layout: nonHdrSize :: DynFlags -> SMRep -> ByteOff
+ GHC.Runtime.Layout: nonHdrSizeW :: SMRep -> WordOff
+ GHC.Runtime.Layout: profHdrSize :: DynFlags -> WordOff
+ GHC.Runtime.Layout: rET_BIG :: Int
+ GHC.Runtime.Layout: rET_SMALL :: Int
+ GHC.Runtime.Layout: roundUpTo :: ByteOff -> ByteOff -> ByteOff
+ GHC.Runtime.Layout: roundUpToWords :: DynFlags -> ByteOff -> ByteOff
+ GHC.Runtime.Layout: rtsClosureType :: SMRep -> Int
+ GHC.Runtime.Layout: smallArrPtrsHdrSize :: DynFlags -> ByteOff
+ GHC.Runtime.Layout: smallArrPtrsHdrSizeW :: DynFlags -> WordOff
+ GHC.Runtime.Layout: smallArrPtrsRep :: WordOff -> SMRep
+ GHC.Runtime.Layout: thunkHdrSize :: DynFlags -> WordOff
+ GHC.Runtime.Layout: toStgHalfWord :: DynFlags -> Integer -> StgHalfWord
+ GHC.Runtime.Layout: toStgWord :: DynFlags -> Integer -> StgWord
+ GHC.Runtime.Layout: type ByteOff = Int
+ GHC.Runtime.Layout: type ConstrDescription = ByteString
+ GHC.Runtime.Layout: type IsStatic = Bool
+ GHC.Runtime.Layout: type Liveness = [Bool]
+ GHC.Runtime.Layout: type WordOff = Int
+ GHC.Runtime.Layout: wordsToBytes :: Num a => DynFlags -> a -> a
+ GHC.Stg.Syntax: AlgAlt :: TyCon -> AltType
+ GHC.Stg.Syntax: CodeGen :: StgPass
+ GHC.Stg.Syntax: LiftLams :: StgPass
+ GHC.Stg.Syntax: MultiValAlt :: Int -> AltType
+ GHC.Stg.Syntax: PolyAlt :: AltType
+ GHC.Stg.Syntax: PrimAlt :: PrimRep -> AltType
+ GHC.Stg.Syntax: ReEntrant :: UpdateFlag
+ GHC.Stg.Syntax: SingleEntry :: UpdateFlag
+ GHC.Stg.Syntax: StgApp :: Id -> [StgArg] -> GenStgExpr pass
+ GHC.Stg.Syntax: StgCase :: GenStgExpr pass -> BinderP pass -> AltType -> [GenStgAlt pass] -> GenStgExpr pass
+ GHC.Stg.Syntax: StgConApp :: DataCon -> [StgArg] -> [Type] -> GenStgExpr pass
+ GHC.Stg.Syntax: StgFCallOp :: ForeignCall -> Type -> StgOp
+ GHC.Stg.Syntax: StgLam :: NonEmpty (BinderP pass) -> StgExpr -> GenStgExpr pass
+ GHC.Stg.Syntax: StgLet :: XLet pass -> GenStgBinding pass -> GenStgExpr pass -> GenStgExpr pass
+ GHC.Stg.Syntax: StgLetNoEscape :: XLetNoEscape pass -> GenStgBinding pass -> GenStgExpr pass -> GenStgExpr pass
+ GHC.Stg.Syntax: StgLit :: Literal -> GenStgExpr pass
+ GHC.Stg.Syntax: StgLitArg :: Literal -> StgArg
+ GHC.Stg.Syntax: StgNonRec :: BinderP pass -> GenStgRhs pass -> GenStgBinding pass
+ GHC.Stg.Syntax: StgOpApp :: StgOp -> [StgArg] -> Type -> GenStgExpr pass
+ GHC.Stg.Syntax: StgPrimCallOp :: PrimCall -> StgOp
+ GHC.Stg.Syntax: StgPrimOp :: PrimOp -> StgOp
+ GHC.Stg.Syntax: StgRec :: [(BinderP pass, GenStgRhs pass)] -> GenStgBinding pass
+ GHC.Stg.Syntax: StgRhsClosure :: XRhsClosure pass -> CostCentreStack -> !UpdateFlag -> [BinderP pass] -> GenStgExpr pass -> GenStgRhs pass
+ GHC.Stg.Syntax: StgRhsCon :: CostCentreStack -> DataCon -> [StgArg] -> GenStgRhs pass
+ GHC.Stg.Syntax: StgTick :: Tickish Id -> GenStgExpr pass -> GenStgExpr pass
+ GHC.Stg.Syntax: StgTopLifted :: GenStgBinding pass -> GenStgTopBinding pass
+ GHC.Stg.Syntax: StgTopStringLit :: Id -> ByteString -> GenStgTopBinding pass
+ GHC.Stg.Syntax: StgVarArg :: Id -> StgArg
+ GHC.Stg.Syntax: Updatable :: UpdateFlag
+ GHC.Stg.Syntax: Vanilla :: StgPass
+ GHC.Stg.Syntax: data AltType
+ GHC.Stg.Syntax: data GenStgBinding pass
+ GHC.Stg.Syntax: data GenStgExpr pass
+ GHC.Stg.Syntax: data GenStgRhs pass
+ GHC.Stg.Syntax: data GenStgTopBinding pass
+ GHC.Stg.Syntax: data NoExtFieldSilent
+ GHC.Stg.Syntax: data StgArg
+ GHC.Stg.Syntax: data StgOp
+ GHC.Stg.Syntax: data StgPass
+ GHC.Stg.Syntax: data UpdateFlag
+ GHC.Stg.Syntax: instance Data.Data.Data GHC.Stg.Syntax.NoExtFieldSilent
+ GHC.Stg.Syntax: instance GHC.Classes.Eq GHC.Stg.Syntax.NoExtFieldSilent
+ GHC.Stg.Syntax: instance GHC.Classes.Ord GHC.Stg.Syntax.NoExtFieldSilent
+ GHC.Stg.Syntax: instance GHC.Stg.Syntax.OutputablePass pass => Outputable.Outputable (GHC.Stg.Syntax.GenStgBinding pass)
+ GHC.Stg.Syntax: instance GHC.Stg.Syntax.OutputablePass pass => Outputable.Outputable (GHC.Stg.Syntax.GenStgExpr pass)
+ GHC.Stg.Syntax: instance GHC.Stg.Syntax.OutputablePass pass => Outputable.Outputable (GHC.Stg.Syntax.GenStgRhs pass)
+ GHC.Stg.Syntax: instance GHC.Stg.Syntax.OutputablePass pass => Outputable.Outputable (GHC.Stg.Syntax.GenStgTopBinding pass)
+ GHC.Stg.Syntax: instance Outputable.Outputable GHC.Stg.Syntax.AltType
+ GHC.Stg.Syntax: instance Outputable.Outputable GHC.Stg.Syntax.NoExtFieldSilent
+ GHC.Stg.Syntax: instance Outputable.Outputable GHC.Stg.Syntax.StgArg
+ GHC.Stg.Syntax: instance Outputable.Outputable GHC.Stg.Syntax.UpdateFlag
+ GHC.Stg.Syntax: isDllConApp :: DynFlags -> Module -> DataCon -> [StgArg] -> Bool
+ GHC.Stg.Syntax: isUpdatable :: UpdateFlag -> Bool
+ GHC.Stg.Syntax: noExtFieldSilent :: NoExtFieldSilent
+ GHC.Stg.Syntax: pprGenStgTopBindings :: OutputablePass pass => [GenStgTopBinding pass] -> SDoc
+ GHC.Stg.Syntax: pprStgBinding :: StgBinding -> SDoc
+ GHC.Stg.Syntax: pprStgTopBindings :: [StgTopBinding] -> SDoc
+ GHC.Stg.Syntax: stgArgHasCafRefs :: StgArg -> Bool
+ GHC.Stg.Syntax: stgArgType :: StgArg -> Type
+ GHC.Stg.Syntax: stgCaseBndrInScope :: AltType -> Bool -> Bool
+ GHC.Stg.Syntax: stgRhsArity :: StgRhs -> Int
+ GHC.Stg.Syntax: stripStgTicksTop :: (Tickish Id -> Bool) -> GenStgExpr p -> ([Tickish Id], GenStgExpr p)
+ GHC.Stg.Syntax: stripStgTicksTopE :: (Tickish Id -> Bool) -> GenStgExpr p -> GenStgExpr p
+ GHC.Stg.Syntax: topStgBindHasCafRefs :: GenStgTopBinding pass -> Bool
+ GHC.Stg.Syntax: type CgStgAlt = GenStgAlt 'CodeGen
+ GHC.Stg.Syntax: type CgStgBinding = GenStgBinding 'CodeGen
+ GHC.Stg.Syntax: type CgStgExpr = GenStgExpr 'CodeGen
+ GHC.Stg.Syntax: type CgStgRhs = GenStgRhs 'CodeGen
+ GHC.Stg.Syntax: type CgStgTopBinding = GenStgTopBinding 'CodeGen
+ GHC.Stg.Syntax: type GenStgAlt pass = (AltCon, [BinderP pass], GenStgExpr pass)
+ GHC.Stg.Syntax: type InStgAlt = StgAlt
+ GHC.Stg.Syntax: type InStgArg = StgArg
+ GHC.Stg.Syntax: type InStgBinding = StgBinding
+ GHC.Stg.Syntax: type InStgExpr = StgExpr
+ GHC.Stg.Syntax: type InStgRhs = StgRhs
+ GHC.Stg.Syntax: type InStgTopBinding = StgTopBinding
+ GHC.Stg.Syntax: type LlStgAlt = GenStgAlt 'LiftLams
+ GHC.Stg.Syntax: type LlStgBinding = GenStgBinding 'LiftLams
+ GHC.Stg.Syntax: type LlStgExpr = GenStgExpr 'LiftLams
+ GHC.Stg.Syntax: type LlStgRhs = GenStgRhs 'LiftLams
+ GHC.Stg.Syntax: type LlStgTopBinding = GenStgTopBinding 'LiftLams
+ GHC.Stg.Syntax: type OutStgAlt = StgAlt
+ GHC.Stg.Syntax: type OutStgArg = StgArg
+ GHC.Stg.Syntax: type OutStgBinding = StgBinding
+ GHC.Stg.Syntax: type OutStgExpr = StgExpr
+ GHC.Stg.Syntax: type OutStgRhs = StgRhs
+ GHC.Stg.Syntax: type OutStgTopBinding = StgTopBinding
+ GHC.Stg.Syntax: type OutputablePass pass = (Outputable (XLet pass), Outputable (XLetNoEscape pass), Outputable (XRhsClosure pass), OutputableBndr (BinderP pass))
+ GHC.Stg.Syntax: type StgAlt = GenStgAlt 'Vanilla
+ GHC.Stg.Syntax: type StgBinding = GenStgBinding 'Vanilla
+ GHC.Stg.Syntax: type StgExpr = GenStgExpr 'Vanilla
+ GHC.Stg.Syntax: type StgRhs = GenStgRhs 'Vanilla
+ GHC.Stg.Syntax: type StgTopBinding = GenStgTopBinding 'Vanilla
+ GHC.Stg.Syntax: type family XLetNoEscape (pass :: StgPass)
+ Hooks: cmmToRawCmmHook :: Hooks -> Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroup () -> IO (Stream IO RawCmmGroup ()))
+ Hooks: stgToCmmHook :: Hooks -> Maybe (DynFlags -> Module -> [TyCon] -> CollectedCCs -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ())
+ HscTypes: instance HscTypes.MonadThings m => HscTypes.MonadThings (Control.Monad.Trans.Reader.ReaderT s m)
+ Language.Haskell.TH: class Monad m => Quote m
+ Language.Haskell.TH: type BangType = (Bang, Type)
+ Language.Haskell.TH: type VarBangType = (Name, Bang, Type)
+ Language.Haskell.TH.Lib.Internal: type Decs = [Dec]
+ Language.Haskell.TH.Syntax: class Monad m => Quote m
+ Language.Haskell.TH.Syntax: instance Language.Haskell.TH.Syntax.Quote Language.Haskell.TH.Syntax.Q
+ Lexer: lexerDbg :: Bool -> (Located Token -> P a) -> P a
+ OccName: delTidyOccEnvList :: TidyOccEnv -> [FastString] -> TidyOccEnv
+ Outputable: instance Outputable.Outputable a => Outputable.Outputable (GHC.Base.NonEmpty a)
+ Outputable: itsOrTheir :: [a] -> SDoc
+ Packages: PackageDatabase :: FilePath -> [UnitInfo] -> PackageDatabase
+ Packages: [packageDatabasePath] :: PackageDatabase -> FilePath
+ Packages: [packageDatabaseUnits] :: PackageDatabase -> [UnitInfo]
+ Packages: data PackageDatabase
+ Packages: data UnitInfoMap
+ Packages: getUnitInfoMap :: DynFlags -> UnitInfoMap
+ Packages: listUnitInfoMap :: DynFlags -> [UnitInfo]
+ Packages: lookupUnit :: DynFlags -> UnitId -> Maybe UnitInfo
+ Packages: lookupUnit' :: Bool -> UnitInfoMap -> UnitId -> Maybe UnitInfo
+ Packages: readPackageDatabase :: DynFlags -> FilePath -> IO PackageDatabase
+ Packages: readPackageDatabases :: DynFlags -> IO [PackageDatabase]
+ Packages: resolvePackageDatabase :: DynFlags -> PkgDbRef -> IO (Maybe FilePath)
+ Reg: RealRegPair :: {-# UNPACK #-} !RegNo -> {-# UNPACK #-} !RegNo -> RealReg
+ Reg: RealRegSingle :: {-# UNPACK #-} !RegNo -> RealReg
+ Reg: RegReal :: !RealReg -> Reg
+ Reg: RegVirtual :: !VirtualReg -> Reg
+ Reg: VirtualRegD :: {-# UNPACK #-} !Unique -> VirtualReg
+ Reg: VirtualRegF :: {-# UNPACK #-} !Unique -> VirtualReg
+ Reg: VirtualRegHi :: {-# UNPACK #-} !Unique -> VirtualReg
+ Reg: VirtualRegI :: {-# UNPACK #-} !Unique -> VirtualReg
+ Reg: classOfVirtualReg :: VirtualReg -> RegClass
+ Reg: data RealReg
+ Reg: data Reg
+ Reg: data VirtualReg
+ Reg: getHiVRegFromLo :: Reg -> Reg
+ Reg: getHiVirtualRegFromLo :: VirtualReg -> VirtualReg
+ Reg: instance GHC.Classes.Eq Reg.RealReg
+ Reg: instance GHC.Classes.Eq Reg.Reg
+ Reg: instance GHC.Classes.Eq Reg.VirtualReg
+ Reg: instance GHC.Classes.Ord Reg.RealReg
+ Reg: instance GHC.Classes.Ord Reg.Reg
+ Reg: instance GHC.Classes.Ord Reg.VirtualReg
+ Reg: instance GHC.Show.Show Reg.RealReg
+ Reg: instance GHC.Show.Show Reg.VirtualReg
+ Reg: instance Outputable.Outputable Reg.RealReg
+ Reg: instance Outputable.Outputable Reg.Reg
+ Reg: instance Outputable.Outputable Reg.VirtualReg
+ Reg: instance Unique.Uniquable Reg.RealReg
+ Reg: instance Unique.Uniquable Reg.Reg
+ Reg: instance Unique.Uniquable Reg.VirtualReg
+ Reg: isRealReg :: Reg -> Bool
+ Reg: isVirtualReg :: Reg -> Bool
+ Reg: liftPatchFnToRegReg :: (VirtualReg -> RealReg) -> Reg -> Reg
+ Reg: realRegsAlias :: RealReg -> RealReg -> Bool
+ Reg: regNosOfRealReg :: RealReg -> [RegNo]
+ Reg: regPair :: RegNo -> RegNo -> Reg
+ Reg: regSingle :: RegNo -> Reg
+ Reg: renameVirtualReg :: Unique -> VirtualReg -> VirtualReg
+ Reg: takeRealReg :: Reg -> Maybe RealReg
+ Reg: takeVirtualReg :: Reg -> Maybe VirtualReg
+ Reg: type RegNo = Int
+ RegClass: RcDouble :: RegClass
+ RegClass: RcFloat :: RegClass
+ RegClass: RcInteger :: RegClass
+ RegClass: data RegClass
+ RegClass: instance GHC.Classes.Eq RegClass.RegClass
+ RegClass: instance Outputable.Outputable RegClass.RegClass
+ RegClass: instance Unique.Uniquable RegClass.RegClass
+ Settings: sGlobalPackageDatabasePath :: Settings -> FilePath
+ Stream: Stream :: m (Either b (a, Stream m a b)) -> Stream m a b
+ Stream: [runStream] :: Stream m a b -> m (Either b (a, Stream m a b))
+ Stream: collect :: Monad m => Stream m a () -> m [a]
+ Stream: collect_ :: Monad m => Stream m a r -> m ([a], r)
+ Stream: consume :: Monad m => Stream m a b -> (a -> m ()) -> m b
+ Stream: fromList :: Monad m => [a] -> Stream m a ()
+ Stream: instance GHC.Base.Monad f => GHC.Base.Functor (Stream.Stream f a)
+ Stream: instance GHC.Base.Monad m => GHC.Base.Applicative (Stream.Stream m a)
+ Stream: instance GHC.Base.Monad m => GHC.Base.Monad (Stream.Stream m a)
+ Stream: liftIO :: IO a -> Stream IO b a
+ Stream: map :: Monad m => (a -> b) -> Stream m a x -> Stream m b x
+ Stream: mapAccumL :: Monad m => (c -> a -> m (c, b)) -> c -> Stream m a () -> Stream m b c
+ Stream: mapAccumL_ :: Monad m => (c -> a -> m (c, b)) -> c -> Stream m a r -> Stream m b (c, r)
+ Stream: mapM :: Monad m => (a -> m b) -> Stream m a x -> Stream m b x
+ Stream: newtype Stream m a b
+ Stream: yield :: Monad m => a -> Stream m a ()
+ TcEvidence: QuoteWrapper :: EvVar -> Type -> QuoteWrapper
+ TcEvidence: applyQuoteWrapper :: QuoteWrapper -> HsWrapper
+ TcEvidence: data QuoteWrapper
+ TcEvidence: instance Data.Data.Data TcEvidence.QuoteWrapper
+ TcEvidence: quoteWrapperTyVarTy :: QuoteWrapper -> Type
+ TcOrigin: BracketOrigin :: CtOrigin
+ TyCoPpr: pprTidiedType :: Type -> SDoc
+ UnitInfo: ComponentId :: FastString -> ComponentId
+ UnitInfo: InstalledPackageInfo :: instunitid -> compid -> [(modulename, mod)] -> srcpkgid -> srcpkgname -> Version -> Maybe srcpkgname -> String -> [instunitid] -> [(instunitid, String)] -> [FilePath] -> [String] -> [String] -> [String] -> [FilePath] -> [FilePath] -> [String] -> [FilePath] -> [String] -> [String] -> [String] -> [FilePath] -> [FilePath] -> [FilePath] -> [(modulename, Maybe mod)] -> [modulename] -> Bool -> Bool -> Bool -> InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod
+ UnitInfo: PackageName :: FastString -> PackageName
+ UnitInfo: SourcePackageId :: FastString -> SourcePackageId
+ UnitInfo: Version :: [Int] -> [String] -> Version
+ UnitInfo: [abiDepends] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [(instunitid, String)]
+ UnitInfo: [abiHash] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> String
+ UnitInfo: [ccOptions] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
+ UnitInfo: [componentId] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> compid
+ UnitInfo: [depends] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [instunitid]
+ UnitInfo: [exposedModules] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [(modulename, Maybe mod)]
+ UnitInfo: [exposed] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> Bool
+ UnitInfo: [extraGHCiLibraries] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
+ UnitInfo: [extraLibraries] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
+ UnitInfo: [frameworkDirs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
+ UnitInfo: [frameworks] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
+ UnitInfo: [haddockHTMLs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
+ UnitInfo: [haddockInterfaces] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
+ UnitInfo: [hiddenModules] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [modulename]
+ UnitInfo: [hsLibraries] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
+ UnitInfo: [importDirs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
+ UnitInfo: [includeDirs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
+ UnitInfo: [includes] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
+ UnitInfo: [indefinite] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> Bool
+ UnitInfo: [instantiatedWith] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [(modulename, mod)]
+ UnitInfo: [ldOptions] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [String]
+ UnitInfo: [libraryDirs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
+ UnitInfo: [libraryDynDirs] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> [FilePath]
+ UnitInfo: [packageName] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> srcpkgname
+ UnitInfo: [packageVersion] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> Version
+ UnitInfo: [sourceLibName] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> Maybe srcpkgname
+ UnitInfo: [sourcePackageId] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> srcpkgid
+ UnitInfo: [trusted] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> Bool
+ UnitInfo: [unitId] :: InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod -> instunitid
+ UnitInfo: [versionBranch] :: Version -> [Int]
+ UnitInfo: [versionTags] :: Version -> [String]
+ UnitInfo: data InstalledPackageInfo compid srcpkgid srcpkgname instunitid unitid modulename mod
+ UnitInfo: data Version
+ UnitInfo: defaultUnitInfo :: UnitInfo
+ UnitInfo: definiteUnitInfoId :: UnitInfo -> Maybe DefUnitId
+ UnitInfo: expandedUnitInfoId :: UnitInfo -> UnitId
+ UnitInfo: installedUnitInfoId :: UnitInfo -> InstalledUnitId
+ UnitInfo: instance GHC.Classes.Eq UnitInfo.PackageName
+ UnitInfo: instance GHC.Classes.Eq UnitInfo.SourcePackageId
+ UnitInfo: instance GHC.Classes.Ord UnitInfo.PackageName
+ UnitInfo: instance GHC.Classes.Ord UnitInfo.SourcePackageId
+ UnitInfo: instance GHC.PackageDb.BinaryStringRep UnitInfo.PackageName
+ UnitInfo: instance GHC.PackageDb.BinaryStringRep UnitInfo.SourcePackageId
+ UnitInfo: instance Outputable.Outputable UnitInfo.PackageName
+ UnitInfo: instance Outputable.Outputable UnitInfo.SourcePackageId
+ UnitInfo: instance Unique.Uniquable UnitInfo.PackageName
+ UnitInfo: instance Unique.Uniquable UnitInfo.SourcePackageId
+ UnitInfo: newtype ComponentId
+ UnitInfo: newtype PackageName
+ UnitInfo: newtype SourcePackageId
+ UnitInfo: packageConfigId :: UnitInfo -> UnitId
+ UnitInfo: packageNameString :: UnitInfo -> String
+ UnitInfo: pprUnitInfo :: UnitInfo -> SDoc
+ UnitInfo: sourcePackageIdString :: UnitInfo -> String
+ UnitInfo: type UnitInfo = InstalledPackageInfo ComponentId SourcePackageId PackageName InstalledUnitId UnitId ModuleName Module
+ VarEnv: delTidyEnvList :: TidyEnv -> [Var] -> TidyEnv
- BkpSyn: DeclD :: HscSource -> Located ModuleName -> Maybe (Located (HsModule GhcPs)) -> HsUnitDecl n
+ BkpSyn: DeclD :: HscSource -> Located ModuleName -> Maybe (Located HsModule) -> HsUnitDecl n
- DynFlags: DynFlags :: GhcMode -> GhcLink -> HscTarget -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> PlatformConstants -> [(String, String)] -> IntegerLibrary -> LlvmConfig -> Int -> Int -> Int -> Int -> Int -> Maybe String -> Maybe String -> [Int] -> Maybe Int -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> Maybe Int -> Maybe Int -> Int -> Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> Module -> Maybe String -> IntWithInf -> IntWithInf -> InstalledUnitId -> Maybe ComponentId -> Maybe [(ModuleName, Module)] -> [Way] -> String -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> IORef Bool -> String -> String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> Maybe FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [LoadedPlugin] -> [StaticPlugin] -> Hooks -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> Maybe [(FilePath, [PackageConfig])] -> PackageState -> IORef FilesToClean -> IORef (Map FilePath FilePath) -> IORef Int -> IORef (Set FilePath) -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> Int -> Int -> Int -> Int -> Float -> Int -> Bool -> Int -> Int -> LogAction -> DumpAction -> TraceAction -> FlushOut -> FlushErr -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> Maybe String -> IORef (ModuleEnv Int) -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> IORef (Maybe LinkerInfo) -> IORef (Maybe CompilerInfo) -> Int -> Int -> Int -> Bool -> Maybe Int -> Int -> Int -> CfgWeights -> DynFlags
+ DynFlags: DynFlags :: GhcMode -> GhcLink -> HscTarget -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> PlatformConstants -> [(String, String)] -> IntegerLibrary -> LlvmConfig -> Int -> Int -> Int -> Int -> Int -> Maybe String -> Maybe String -> [Int] -> Maybe Int -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> Maybe Int -> Maybe Int -> Int -> Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> Module -> Maybe String -> IntWithInf -> IntWithInf -> InstalledUnitId -> Maybe ComponentId -> Maybe [(ModuleName, Module)] -> [Way] -> String -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> IORef Bool -> String -> String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> Maybe FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [LoadedPlugin] -> [StaticPlugin] -> Hooks -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> Maybe [PackageDatabase] -> PackageState -> IORef FilesToClean -> IORef (Map FilePath FilePath) -> IORef Int -> IORef (Set FilePath) -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> Int -> Int -> Int -> Int -> Float -> Int -> Bool -> Int -> Int -> LogAction -> DumpAction -> TraceAction -> FlushOut -> FlushErr -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> Maybe String -> IORef (ModuleEnv Int) -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> IORef (Maybe LinkerInfo) -> IORef (Maybe CompilerInfo) -> Int -> Int -> Int -> Bool -> Maybe Int -> Int -> Int -> CfgWeights -> DynFlags
- DynFlags: PackageDB :: PkgConfRef -> PackageDBFlag
+ DynFlags: PackageDB :: PkgDbRef -> PackageDBFlag
- DynFlags: [pkgDatabase] :: DynFlags -> Maybe [(FilePath, [PackageConfig])]
+ DynFlags: [pkgDatabase] :: DynFlags -> Maybe [PackageDatabase]
- GHC.Hs: HsModule :: Maybe (Located ModuleName) -> Maybe (Located [LIE pass]) -> [LImportDecl pass] -> [LHsDecl pass] -> Maybe (Located WarningTxt) -> Maybe LHsDocString -> HsModule pass
+ GHC.Hs: HsModule :: Maybe (Located ModuleName) -> Maybe (Located [LIE GhcPs]) -> [LImportDecl GhcPs] -> [LHsDecl GhcPs] -> Maybe (Located WarningTxt) -> Maybe LHsDocString -> HsModule
- GHC.Hs: [hsmodDecls] :: HsModule pass -> [LHsDecl pass]
+ GHC.Hs: [hsmodDecls] :: HsModule -> [LHsDecl GhcPs]
- GHC.Hs: [hsmodDeprecMessage] :: HsModule pass -> Maybe (Located WarningTxt)
+ GHC.Hs: [hsmodDeprecMessage] :: HsModule -> Maybe (Located WarningTxt)
- GHC.Hs: [hsmodExports] :: HsModule pass -> Maybe (Located [LIE pass])
+ GHC.Hs: [hsmodExports] :: HsModule -> Maybe (Located [LIE GhcPs])
- GHC.Hs: [hsmodHaddockModHeader] :: HsModule pass -> Maybe LHsDocString
+ GHC.Hs: [hsmodHaddockModHeader] :: HsModule -> Maybe LHsDocString
- GHC.Hs: [hsmodImports] :: HsModule pass -> [LImportDecl pass]
+ GHC.Hs: [hsmodImports] :: HsModule -> [LImportDecl GhcPs]
- GHC.Hs: [hsmodName] :: HsModule pass -> Maybe (Located ModuleName)
+ GHC.Hs: [hsmodName] :: HsModule -> Maybe (Located ModuleName)
- GHC.Hs: data HsModule pass
+ GHC.Hs: data HsModule
- GHC.Hs.Expr: HsTcBracketOut :: XTcBracketOut p -> HsBracket GhcRn -> [PendingTcSplice] -> HsExpr p
+ GHC.Hs.Expr: HsTcBracketOut :: XTcBracketOut p -> Maybe QuoteWrapper -> HsBracket GhcRn -> [PendingTcSplice] -> HsExpr p
- GHC.HsToCore.PmCheck.Types: VI :: !Type -> ![(PmAltCon, [Id])] -> ![PmAltCon] -> !PossibleMatches -> VarInfo
+ GHC.HsToCore.PmCheck.Types: VI :: !Type -> ![(PmAltCon, [TyVar], [Id])] -> ![PmAltCon] -> !PossibleMatches -> VarInfo
- GHC.HsToCore.PmCheck.Types: [vi_pos] :: VarInfo -> ![(PmAltCon, [Id])]
+ GHC.HsToCore.PmCheck.Types: [vi_pos] :: VarInfo -> ![(PmAltCon, [TyVar], [Id])]
- HscTypes: HsParsedModule :: Located (HsModule GhcPs) -> [FilePath] -> ApiAnns -> HsParsedModule
+ HscTypes: HsParsedModule :: Located HsModule -> [FilePath] -> ApiAnns -> HsParsedModule
- HscTypes: [hpm_module] :: HsParsedModule -> Located (HsModule GhcPs)
+ HscTypes: [hpm_module] :: HsParsedModule -> Located HsModule
- Language.Haskell.TH: newName :: String -> Q Name
+ Language.Haskell.TH: newName :: Quote m => String -> m Name
- Language.Haskell.TH.Lib: anyclassStrategy :: DerivStrategyQ
+ Language.Haskell.TH.Lib: anyclassStrategy :: Quote m => m DerivStrategy
- Language.Haskell.TH.Lib: appE :: ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: appE :: Quote m => m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib: appKindT :: TypeQ -> KindQ -> TypeQ
+ Language.Haskell.TH.Lib: appKindT :: Quote m => m Type -> m Kind -> m Type
- Language.Haskell.TH.Lib: appT :: TypeQ -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib: appT :: Quote m => m Type -> m Type -> m Type
- Language.Haskell.TH.Lib: appTypeE :: ExpQ -> TypeQ -> ExpQ
+ Language.Haskell.TH.Lib: appTypeE :: Quote m => m Exp -> m Type -> m Exp
- Language.Haskell.TH.Lib: appsE :: [ExpQ] -> ExpQ
+ Language.Haskell.TH.Lib: appsE :: Quote m => [m Exp] -> m Exp
- Language.Haskell.TH.Lib: arithSeqE :: RangeQ -> ExpQ
+ Language.Haskell.TH.Lib: arithSeqE :: Quote m => m Range -> m Exp
- Language.Haskell.TH.Lib: arrowT :: TypeQ
+ Language.Haskell.TH.Lib: arrowT :: Quote m => m Type
- Language.Haskell.TH.Lib: asP :: Name -> PatQ -> PatQ
+ Language.Haskell.TH.Lib: asP :: Quote m => Name -> m Pat -> m Pat
- Language.Haskell.TH.Lib: bang :: SourceUnpackednessQ -> SourceStrictnessQ -> BangQ
+ Language.Haskell.TH.Lib: bang :: Quote m => m SourceUnpackedness -> m SourceStrictness -> m Bang
- Language.Haskell.TH.Lib: bangP :: PatQ -> PatQ
+ Language.Haskell.TH.Lib: bangP :: Quote m => m Pat -> m Pat
- Language.Haskell.TH.Lib: bangType :: BangQ -> TypeQ -> BangTypeQ
+ Language.Haskell.TH.Lib: bangType :: Quote m => m Bang -> m Type -> m BangType
- Language.Haskell.TH.Lib: bindS :: PatQ -> ExpQ -> StmtQ
+ Language.Haskell.TH.Lib: bindS :: Quote m => m Pat -> m Exp -> m Stmt
- Language.Haskell.TH.Lib: caseE :: ExpQ -> [MatchQ] -> ExpQ
+ Language.Haskell.TH.Lib: caseE :: Quote m => m Exp -> [m Match] -> m Exp
- Language.Haskell.TH.Lib: classD :: CxtQ -> Name -> [TyVarBndr] -> [FunDep] -> [DecQ] -> DecQ
+ Language.Haskell.TH.Lib: classD :: Quote m => m Cxt -> Name -> [TyVarBndr] -> [FunDep] -> [m Dec] -> m Dec
- Language.Haskell.TH.Lib: classP :: Name -> [Q Type] -> Q Pred
+ Language.Haskell.TH.Lib: classP :: Quote m => Name -> [m Type] -> m Pred
- Language.Haskell.TH.Lib: clause :: [PatQ] -> BodyQ -> [DecQ] -> ClauseQ
+ Language.Haskell.TH.Lib: clause :: Quote m => [m Pat] -> m Body -> [m Dec] -> m Clause
- Language.Haskell.TH.Lib: closedTypeFamilyD :: Name -> [TyVarBndr] -> FamilyResultSig -> Maybe InjectivityAnn -> [TySynEqnQ] -> DecQ
+ Language.Haskell.TH.Lib: closedTypeFamilyD :: Quote m => Name -> [TyVarBndr] -> FamilyResultSig -> Maybe InjectivityAnn -> [m TySynEqn] -> m Dec
- Language.Haskell.TH.Lib: compE :: [StmtQ] -> ExpQ
+ Language.Haskell.TH.Lib: compE :: Quote m => [m Stmt] -> m Exp
- Language.Haskell.TH.Lib: conE :: Name -> ExpQ
+ Language.Haskell.TH.Lib: conE :: Quote m => Name -> m Exp
- Language.Haskell.TH.Lib: conP :: Name -> [PatQ] -> PatQ
+ Language.Haskell.TH.Lib: conP :: Quote m => Name -> [m Pat] -> m Pat
- Language.Haskell.TH.Lib: conT :: Name -> TypeQ
+ Language.Haskell.TH.Lib: conT :: Quote m => Name -> m Type
- Language.Haskell.TH.Lib: condE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: condE :: Quote m => m Exp -> m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib: cxt :: [PredQ] -> CxtQ
+ Language.Haskell.TH.Lib: cxt :: Quote m => [m Pred] -> m Cxt
- Language.Haskell.TH.Lib: dataD :: CxtQ -> Name -> [TyVarBndr] -> Maybe Kind -> [ConQ] -> [DerivClauseQ] -> DecQ
+ Language.Haskell.TH.Lib: dataD :: Quote m => m Cxt -> Name -> [TyVarBndr] -> Maybe Kind -> [m Con] -> [m DerivClause] -> m Dec
- Language.Haskell.TH.Lib: dataFamilyD :: Name -> [TyVarBndr] -> Maybe Kind -> DecQ
+ Language.Haskell.TH.Lib: dataFamilyD :: Quote m => Name -> [TyVarBndr] -> Maybe Kind -> m Dec
- Language.Haskell.TH.Lib: dataInstD :: CxtQ -> Name -> [TypeQ] -> Maybe Kind -> [ConQ] -> [DerivClauseQ] -> DecQ
+ Language.Haskell.TH.Lib: dataInstD :: Quote m => m Cxt -> Name -> [m Type] -> Maybe Kind -> [m Con] -> [m DerivClause] -> m Dec
- Language.Haskell.TH.Lib: defaultSigD :: Name -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib: defaultSigD :: Quote m => Name -> m Type -> m Dec
- Language.Haskell.TH.Lib: derivClause :: Maybe DerivStrategy -> [PredQ] -> DerivClauseQ
+ Language.Haskell.TH.Lib: derivClause :: Quote m => Maybe DerivStrategy -> [m Pred] -> m DerivClause
- Language.Haskell.TH.Lib: doE :: [StmtQ] -> ExpQ
+ Language.Haskell.TH.Lib: doE :: Quote m => [m Stmt] -> m Exp
- Language.Haskell.TH.Lib: dyn :: String -> ExpQ
+ Language.Haskell.TH.Lib: dyn :: Quote m => String -> m Exp
- Language.Haskell.TH.Lib: equalP :: TypeQ -> TypeQ -> PredQ
+ Language.Haskell.TH.Lib: equalP :: Quote m => m Type -> m Type -> m Pred
- Language.Haskell.TH.Lib: equalityT :: TypeQ
+ Language.Haskell.TH.Lib: equalityT :: Quote m => m Type
- Language.Haskell.TH.Lib: explBidir :: [ClauseQ] -> PatSynDirQ
+ Language.Haskell.TH.Lib: explBidir :: Quote m => [m Clause] -> m PatSynDir
- Language.Haskell.TH.Lib: fieldExp :: Name -> ExpQ -> Q (Name, Exp)
+ Language.Haskell.TH.Lib: fieldExp :: Quote m => Name -> m Exp -> m (Name, Exp)
- Language.Haskell.TH.Lib: fieldPat :: Name -> PatQ -> FieldPatQ
+ Language.Haskell.TH.Lib: fieldPat :: Quote m => Name -> m Pat -> m FieldPat
- Language.Haskell.TH.Lib: forImpD :: Callconv -> Safety -> String -> Name -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib: forImpD :: Quote m => Callconv -> Safety -> String -> Name -> m Type -> m Dec
- Language.Haskell.TH.Lib: forallC :: [TyVarBndr] -> CxtQ -> ConQ -> ConQ
+ Language.Haskell.TH.Lib: forallC :: Quote m => [TyVarBndr] -> m Cxt -> m Con -> m Con
- Language.Haskell.TH.Lib: forallT :: [TyVarBndr] -> CxtQ -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib: forallT :: Quote m => [TyVarBndr] -> m Cxt -> m Type -> m Type
- Language.Haskell.TH.Lib: forallVisT :: [TyVarBndrQ] -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib: forallVisT :: Quote m => [m TyVarBndr] -> m Type -> m Type
- Language.Haskell.TH.Lib: fromE :: ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: fromE :: Quote m => m Exp -> m Exp
- Language.Haskell.TH.Lib: fromR :: ExpQ -> RangeQ
+ Language.Haskell.TH.Lib: fromR :: Quote m => m Exp -> m Range
- Language.Haskell.TH.Lib: fromThenE :: ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: fromThenE :: Quote m => m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib: fromThenR :: ExpQ -> ExpQ -> RangeQ
+ Language.Haskell.TH.Lib: fromThenR :: Quote m => m Exp -> m Exp -> m Range
- Language.Haskell.TH.Lib: fromThenToE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: fromThenToE :: Quote m => m Exp -> m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib: fromThenToR :: ExpQ -> ExpQ -> ExpQ -> RangeQ
+ Language.Haskell.TH.Lib: fromThenToR :: Quote m => m Exp -> m Exp -> m Exp -> m Range
- Language.Haskell.TH.Lib: fromToE :: ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: fromToE :: Quote m => m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib: fromToR :: ExpQ -> ExpQ -> RangeQ
+ Language.Haskell.TH.Lib: fromToR :: Quote m => m Exp -> m Exp -> m Range
- Language.Haskell.TH.Lib: funD :: Name -> [ClauseQ] -> DecQ
+ Language.Haskell.TH.Lib: funD :: Quote m => Name -> [m Clause] -> m Dec
- Language.Haskell.TH.Lib: gadtC :: [Name] -> [StrictTypeQ] -> TypeQ -> ConQ
+ Language.Haskell.TH.Lib: gadtC :: Quote m => [Name] -> [m StrictType] -> m Type -> m Con
- Language.Haskell.TH.Lib: guardedB :: [Q (Guard, Exp)] -> BodyQ
+ Language.Haskell.TH.Lib: guardedB :: Quote m => [m (Guard, Exp)] -> m Body
- Language.Haskell.TH.Lib: implBidir :: PatSynDirQ
+ Language.Haskell.TH.Lib: implBidir :: Quote m => m PatSynDir
- Language.Haskell.TH.Lib: implicitParamBindD :: String -> ExpQ -> DecQ
+ Language.Haskell.TH.Lib: implicitParamBindD :: Quote m => String -> m Exp -> m Dec
- Language.Haskell.TH.Lib: implicitParamT :: String -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib: implicitParamT :: Quote m => String -> m Type -> m Type
- Language.Haskell.TH.Lib: implicitParamVarE :: String -> ExpQ
+ Language.Haskell.TH.Lib: implicitParamVarE :: Quote m => String -> m Exp
- Language.Haskell.TH.Lib: infixApp :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: infixApp :: Quote m => m Exp -> m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib: infixC :: Q (Bang, Type) -> Name -> Q (Bang, Type) -> ConQ
+ Language.Haskell.TH.Lib: infixC :: Quote m => m (Bang, Type) -> Name -> m (Bang, Type) -> m Con
- Language.Haskell.TH.Lib: infixE :: Maybe ExpQ -> ExpQ -> Maybe ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: infixE :: Quote m => Maybe (m Exp) -> m Exp -> Maybe (m Exp) -> m Exp
- Language.Haskell.TH.Lib: infixLD :: Int -> Name -> DecQ
+ Language.Haskell.TH.Lib: infixLD :: Quote m => Int -> Name -> m Dec
- Language.Haskell.TH.Lib: infixND :: Int -> Name -> DecQ
+ Language.Haskell.TH.Lib: infixND :: Quote m => Int -> Name -> m Dec
- Language.Haskell.TH.Lib: infixP :: PatQ -> Name -> PatQ -> PatQ
+ Language.Haskell.TH.Lib: infixP :: Quote m => m Pat -> Name -> m Pat -> m Pat
- Language.Haskell.TH.Lib: infixPatSyn :: Name -> Name -> PatSynArgsQ
+ Language.Haskell.TH.Lib: infixPatSyn :: Quote m => Name -> Name -> m PatSynArgs
- Language.Haskell.TH.Lib: infixRD :: Int -> Name -> DecQ
+ Language.Haskell.TH.Lib: infixRD :: Quote m => Int -> Name -> m Dec
- Language.Haskell.TH.Lib: infixT :: TypeQ -> Name -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib: infixT :: Quote m => m Type -> Name -> m Type -> m Type
- Language.Haskell.TH.Lib: instanceD :: CxtQ -> TypeQ -> [DecQ] -> DecQ
+ Language.Haskell.TH.Lib: instanceD :: Quote m => m Cxt -> m Type -> [m Dec] -> m Dec
- Language.Haskell.TH.Lib: instanceWithOverlapD :: Maybe Overlap -> CxtQ -> TypeQ -> [DecQ] -> DecQ
+ Language.Haskell.TH.Lib: instanceWithOverlapD :: Quote m => Maybe Overlap -> m Cxt -> m Type -> [m Dec] -> m Dec
- Language.Haskell.TH.Lib: isStrict :: Q Strict
+ Language.Haskell.TH.Lib: isStrict :: Quote m => m Strict
- Language.Haskell.TH.Lib: kiSigD :: Name -> KindQ -> DecQ
+ Language.Haskell.TH.Lib: kiSigD :: Quote m => Name -> m Kind -> m Dec
- Language.Haskell.TH.Lib: labelE :: String -> ExpQ
+ Language.Haskell.TH.Lib: labelE :: Quote m => String -> m Exp
- Language.Haskell.TH.Lib: lam1E :: PatQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: lam1E :: Quote m => m Pat -> m Exp -> m Exp
- Language.Haskell.TH.Lib: lamCaseE :: [MatchQ] -> ExpQ
+ Language.Haskell.TH.Lib: lamCaseE :: Quote m => [m Match] -> m Exp
- Language.Haskell.TH.Lib: lamE :: [PatQ] -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: lamE :: Quote m => [m Pat] -> m Exp -> m Exp
- Language.Haskell.TH.Lib: letE :: [DecQ] -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: letE :: Quote m => [m Dec] -> m Exp -> m Exp
- Language.Haskell.TH.Lib: letS :: [DecQ] -> StmtQ
+ Language.Haskell.TH.Lib: letS :: Quote m => [m Dec] -> m Stmt
- Language.Haskell.TH.Lib: listE :: [ExpQ] -> ExpQ
+ Language.Haskell.TH.Lib: listE :: Quote m => [m Exp] -> m Exp
- Language.Haskell.TH.Lib: listP :: [PatQ] -> PatQ
+ Language.Haskell.TH.Lib: listP :: Quote m => [m Pat] -> m Pat
- Language.Haskell.TH.Lib: listT :: TypeQ
+ Language.Haskell.TH.Lib: listT :: Quote m => m Type
- Language.Haskell.TH.Lib: litE :: Lit -> ExpQ
+ Language.Haskell.TH.Lib: litE :: Quote m => Lit -> m Exp
- Language.Haskell.TH.Lib: litP :: Lit -> PatQ
+ Language.Haskell.TH.Lib: litP :: Quote m => Lit -> m Pat
- Language.Haskell.TH.Lib: litT :: TyLitQ -> TypeQ
+ Language.Haskell.TH.Lib: litT :: Quote m => m TyLit -> m Type
- Language.Haskell.TH.Lib: match :: PatQ -> BodyQ -> [DecQ] -> MatchQ
+ Language.Haskell.TH.Lib: match :: Quote m => m Pat -> m Body -> [m Dec] -> m Match
- Language.Haskell.TH.Lib: mdoE :: [StmtQ] -> ExpQ
+ Language.Haskell.TH.Lib: mdoE :: Quote m => [m Stmt] -> m Exp
- Language.Haskell.TH.Lib: multiIfE :: [Q (Guard, Exp)] -> ExpQ
+ Language.Haskell.TH.Lib: multiIfE :: Quote m => [m (Guard, Exp)] -> m Exp
- Language.Haskell.TH.Lib: newtypeD :: CxtQ -> Name -> [TyVarBndr] -> Maybe Kind -> ConQ -> [DerivClauseQ] -> DecQ
+ Language.Haskell.TH.Lib: newtypeD :: Quote m => m Cxt -> Name -> [TyVarBndr] -> Maybe Kind -> m Con -> [m DerivClause] -> m Dec
- Language.Haskell.TH.Lib: newtypeInstD :: CxtQ -> Name -> [TypeQ] -> Maybe Kind -> ConQ -> [DerivClauseQ] -> DecQ
+ Language.Haskell.TH.Lib: newtypeInstD :: Quote m => m Cxt -> Name -> [m Type] -> Maybe Kind -> m Con -> [m DerivClause] -> m Dec
- Language.Haskell.TH.Lib: newtypeStrategy :: DerivStrategyQ
+ Language.Haskell.TH.Lib: newtypeStrategy :: Quote m => m DerivStrategy
- Language.Haskell.TH.Lib: noBindS :: ExpQ -> StmtQ
+ Language.Haskell.TH.Lib: noBindS :: Quote m => m Exp -> m Stmt
- Language.Haskell.TH.Lib: noSourceStrictness :: SourceStrictnessQ
+ Language.Haskell.TH.Lib: noSourceStrictness :: Quote m => m SourceStrictness
- Language.Haskell.TH.Lib: noSourceUnpackedness :: SourceUnpackednessQ
+ Language.Haskell.TH.Lib: noSourceUnpackedness :: Quote m => m SourceUnpackedness
- Language.Haskell.TH.Lib: normalB :: ExpQ -> BodyQ
+ Language.Haskell.TH.Lib: normalB :: Quote m => m Exp -> m Body
- Language.Haskell.TH.Lib: normalC :: Name -> [BangTypeQ] -> ConQ
+ Language.Haskell.TH.Lib: normalC :: Quote m => Name -> [m BangType] -> m Con
- Language.Haskell.TH.Lib: normalG :: ExpQ -> GuardQ
+ Language.Haskell.TH.Lib: normalG :: Quote m => m Exp -> m Guard
- Language.Haskell.TH.Lib: normalGE :: ExpQ -> ExpQ -> Q (Guard, Exp)
+ Language.Haskell.TH.Lib: normalGE :: Quote m => m Exp -> m Exp -> m (Guard, Exp)
- Language.Haskell.TH.Lib: notStrict :: Q Strict
+ Language.Haskell.TH.Lib: notStrict :: Quote m => m Strict
- Language.Haskell.TH.Lib: numTyLit :: Integer -> TyLitQ
+ Language.Haskell.TH.Lib: numTyLit :: Quote m => Integer -> m TyLit
- Language.Haskell.TH.Lib: openTypeFamilyD :: Name -> [TyVarBndr] -> FamilyResultSig -> Maybe InjectivityAnn -> DecQ
+ Language.Haskell.TH.Lib: openTypeFamilyD :: Quote m => Name -> [TyVarBndr] -> FamilyResultSig -> Maybe InjectivityAnn -> m Dec
- Language.Haskell.TH.Lib: parS :: [[StmtQ]] -> StmtQ
+ Language.Haskell.TH.Lib: parS :: Quote m => [[m Stmt]] -> m Stmt
- Language.Haskell.TH.Lib: parensE :: ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: parensE :: Quote m => m Exp -> m Exp
- Language.Haskell.TH.Lib: parensP :: PatQ -> PatQ
+ Language.Haskell.TH.Lib: parensP :: Quote m => m Pat -> m Pat
- Language.Haskell.TH.Lib: parensT :: TypeQ -> TypeQ
+ Language.Haskell.TH.Lib: parensT :: Quote m => m Type -> m Type
- Language.Haskell.TH.Lib: patG :: [StmtQ] -> GuardQ
+ Language.Haskell.TH.Lib: patG :: Quote m => [m Stmt] -> m Guard
- Language.Haskell.TH.Lib: patGE :: [StmtQ] -> ExpQ -> Q (Guard, Exp)
+ Language.Haskell.TH.Lib: patGE :: Quote m => [m Stmt] -> m Exp -> m (Guard, Exp)
- Language.Haskell.TH.Lib: patSynD :: Name -> PatSynArgsQ -> PatSynDirQ -> PatQ -> DecQ
+ Language.Haskell.TH.Lib: patSynD :: Quote m => Name -> m PatSynArgs -> m PatSynDir -> m Pat -> m Dec
- Language.Haskell.TH.Lib: patSynSigD :: Name -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib: patSynSigD :: Quote m => Name -> m Type -> m Dec
- Language.Haskell.TH.Lib: pragAnnD :: AnnTarget -> ExpQ -> DecQ
+ Language.Haskell.TH.Lib: pragAnnD :: Quote m => AnnTarget -> m Exp -> m Dec
- Language.Haskell.TH.Lib: pragCompleteD :: [Name] -> Maybe Name -> DecQ
+ Language.Haskell.TH.Lib: pragCompleteD :: Quote m => [Name] -> Maybe Name -> m Dec
- Language.Haskell.TH.Lib: pragInlD :: Name -> Inline -> RuleMatch -> Phases -> DecQ
+ Language.Haskell.TH.Lib: pragInlD :: Quote m => Name -> Inline -> RuleMatch -> Phases -> m Dec
- Language.Haskell.TH.Lib: pragLineD :: Int -> String -> DecQ
+ Language.Haskell.TH.Lib: pragLineD :: Quote m => Int -> String -> m Dec
- Language.Haskell.TH.Lib: pragRuleD :: String -> [RuleBndrQ] -> ExpQ -> ExpQ -> Phases -> DecQ
+ Language.Haskell.TH.Lib: pragRuleD :: Quote m => String -> [m RuleBndr] -> m Exp -> m Exp -> Phases -> m Dec
- Language.Haskell.TH.Lib: pragSpecD :: Name -> TypeQ -> Phases -> DecQ
+ Language.Haskell.TH.Lib: pragSpecD :: Quote m => Name -> m Type -> Phases -> m Dec
- Language.Haskell.TH.Lib: pragSpecInlD :: Name -> TypeQ -> Inline -> Phases -> DecQ
+ Language.Haskell.TH.Lib: pragSpecInlD :: Quote m => Name -> m Type -> Inline -> Phases -> m Dec
- Language.Haskell.TH.Lib: pragSpecInstD :: TypeQ -> DecQ
+ Language.Haskell.TH.Lib: pragSpecInstD :: Quote m => m Type -> m Dec
- Language.Haskell.TH.Lib: prefixPatSyn :: [Name] -> PatSynArgsQ
+ Language.Haskell.TH.Lib: prefixPatSyn :: Quote m => [Name] -> m PatSynArgs
- Language.Haskell.TH.Lib: promotedConsT :: TypeQ
+ Language.Haskell.TH.Lib: promotedConsT :: Quote m => m Type
- Language.Haskell.TH.Lib: promotedNilT :: TypeQ
+ Language.Haskell.TH.Lib: promotedNilT :: Quote m => m Type
- Language.Haskell.TH.Lib: promotedT :: Name -> TypeQ
+ Language.Haskell.TH.Lib: promotedT :: Quote m => Name -> m Type
- Language.Haskell.TH.Lib: promotedTupleT :: Int -> TypeQ
+ Language.Haskell.TH.Lib: promotedTupleT :: Quote m => Int -> m Type
- Language.Haskell.TH.Lib: recC :: Name -> [VarBangTypeQ] -> ConQ
+ Language.Haskell.TH.Lib: recC :: Quote m => Name -> [m VarBangType] -> m Con
- Language.Haskell.TH.Lib: recConE :: Name -> [Q (Name, Exp)] -> ExpQ
+ Language.Haskell.TH.Lib: recConE :: Quote m => Name -> [m (Name, Exp)] -> m Exp
- Language.Haskell.TH.Lib: recGadtC :: [Name] -> [VarStrictTypeQ] -> TypeQ -> ConQ
+ Language.Haskell.TH.Lib: recGadtC :: Quote m => [Name] -> [m VarStrictType] -> m Type -> m Con
- Language.Haskell.TH.Lib: recP :: Name -> [FieldPatQ] -> PatQ
+ Language.Haskell.TH.Lib: recP :: Quote m => Name -> [m FieldPat] -> m Pat
- Language.Haskell.TH.Lib: recS :: [StmtQ] -> StmtQ
+ Language.Haskell.TH.Lib: recS :: Quote m => [m Stmt] -> m Stmt
- Language.Haskell.TH.Lib: recUpdE :: ExpQ -> [Q (Name, Exp)] -> ExpQ
+ Language.Haskell.TH.Lib: recUpdE :: Quote m => m Exp -> [m (Name, Exp)] -> m Exp
- Language.Haskell.TH.Lib: recordPatSyn :: [Name] -> PatSynArgsQ
+ Language.Haskell.TH.Lib: recordPatSyn :: Quote m => [Name] -> m PatSynArgs
- Language.Haskell.TH.Lib: roleAnnotD :: Name -> [Role] -> DecQ
+ Language.Haskell.TH.Lib: roleAnnotD :: Quote m => Name -> [Role] -> m Dec
- Language.Haskell.TH.Lib: ruleVar :: Name -> RuleBndrQ
+ Language.Haskell.TH.Lib: ruleVar :: Quote m => Name -> m RuleBndr
- Language.Haskell.TH.Lib: sectionL :: ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: sectionL :: Quote m => m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib: sectionR :: ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: sectionR :: Quote m => m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib: sigD :: Name -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib: sigD :: Quote m => Name -> m Type -> m Dec
- Language.Haskell.TH.Lib: sigE :: ExpQ -> TypeQ -> ExpQ
+ Language.Haskell.TH.Lib: sigE :: Quote m => m Exp -> m Type -> m Exp
- Language.Haskell.TH.Lib: sigP :: PatQ -> TypeQ -> PatQ
+ Language.Haskell.TH.Lib: sigP :: Quote m => m Pat -> m Type -> m Pat
- Language.Haskell.TH.Lib: sigT :: TypeQ -> Kind -> TypeQ
+ Language.Haskell.TH.Lib: sigT :: Quote m => m Type -> Kind -> m Type
- Language.Haskell.TH.Lib: sourceLazy :: SourceStrictnessQ
+ Language.Haskell.TH.Lib: sourceLazy :: Quote m => m SourceStrictness
- Language.Haskell.TH.Lib: sourceNoUnpack :: SourceUnpackednessQ
+ Language.Haskell.TH.Lib: sourceNoUnpack :: Quote m => m SourceUnpackedness
- Language.Haskell.TH.Lib: sourceStrict :: SourceStrictnessQ
+ Language.Haskell.TH.Lib: sourceStrict :: Quote m => m SourceStrictness
- Language.Haskell.TH.Lib: sourceUnpack :: SourceUnpackednessQ
+ Language.Haskell.TH.Lib: sourceUnpack :: Quote m => m SourceUnpackedness
- Language.Haskell.TH.Lib: standaloneDerivD :: CxtQ -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib: standaloneDerivD :: Quote m => m Cxt -> m Type -> m Dec
- Language.Haskell.TH.Lib: standaloneDerivWithStrategyD :: Maybe DerivStrategy -> CxtQ -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib: standaloneDerivWithStrategyD :: Quote m => Maybe DerivStrategy -> m Cxt -> m Type -> m Dec
- Language.Haskell.TH.Lib: staticE :: ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: staticE :: Quote m => m Exp -> m Exp
- Language.Haskell.TH.Lib: stockStrategy :: DerivStrategyQ
+ Language.Haskell.TH.Lib: stockStrategy :: Quote m => m DerivStrategy
- Language.Haskell.TH.Lib: strTyLit :: String -> TyLitQ
+ Language.Haskell.TH.Lib: strTyLit :: Quote m => String -> m TyLit
- Language.Haskell.TH.Lib: strictType :: Q Strict -> TypeQ -> StrictTypeQ
+ Language.Haskell.TH.Lib: strictType :: Quote m => m Strict -> m Type -> m StrictType
- Language.Haskell.TH.Lib: stringE :: String -> ExpQ
+ Language.Haskell.TH.Lib: stringE :: Quote m => String -> m Exp
- Language.Haskell.TH.Lib: tildeP :: PatQ -> PatQ
+ Language.Haskell.TH.Lib: tildeP :: Quote m => m Pat -> m Pat
- Language.Haskell.TH.Lib: tupE :: [ExpQ] -> ExpQ
+ Language.Haskell.TH.Lib: tupE :: Quote m => [m Exp] -> m Exp
- Language.Haskell.TH.Lib: tupP :: [PatQ] -> PatQ
+ Language.Haskell.TH.Lib: tupP :: Quote m => [m Pat] -> m Pat
- Language.Haskell.TH.Lib: tupleT :: Int -> TypeQ
+ Language.Haskell.TH.Lib: tupleT :: Quote m => Int -> m Type
- Language.Haskell.TH.Lib: tySynD :: Name -> [TyVarBndr] -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib: tySynD :: Quote m => Name -> [TyVarBndr] -> m Type -> m Dec
- Language.Haskell.TH.Lib: tySynEqn :: Maybe [TyVarBndr] -> TypeQ -> TypeQ -> TySynEqnQ
+ Language.Haskell.TH.Lib: tySynEqn :: Quote m => Maybe [TyVarBndr] -> m Type -> m Type -> m TySynEqn
- Language.Haskell.TH.Lib: tySynInstD :: TySynEqnQ -> DecQ
+ Language.Haskell.TH.Lib: tySynInstD :: Quote m => m TySynEqn -> m Dec
- Language.Haskell.TH.Lib: typedRuleVar :: Name -> TypeQ -> RuleBndrQ
+ Language.Haskell.TH.Lib: typedRuleVar :: Quote m => Name -> m Type -> m RuleBndr
- Language.Haskell.TH.Lib: uInfixE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib: uInfixE :: Quote m => m Exp -> m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib: uInfixP :: PatQ -> Name -> PatQ -> PatQ
+ Language.Haskell.TH.Lib: uInfixP :: Quote m => m Pat -> Name -> m Pat -> m Pat
- Language.Haskell.TH.Lib: uInfixT :: TypeQ -> Name -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib: uInfixT :: Quote m => m Type -> Name -> m Type -> m Type
- Language.Haskell.TH.Lib: unboundVarE :: Name -> ExpQ
+ Language.Haskell.TH.Lib: unboundVarE :: Quote m => Name -> m Exp
- Language.Haskell.TH.Lib: unboxedSumE :: ExpQ -> SumAlt -> SumArity -> ExpQ
+ Language.Haskell.TH.Lib: unboxedSumE :: Quote m => m Exp -> SumAlt -> SumArity -> m Exp
- Language.Haskell.TH.Lib: unboxedSumP :: PatQ -> SumAlt -> SumArity -> PatQ
+ Language.Haskell.TH.Lib: unboxedSumP :: Quote m => m Pat -> SumAlt -> SumArity -> m Pat
- Language.Haskell.TH.Lib: unboxedSumT :: SumArity -> TypeQ
+ Language.Haskell.TH.Lib: unboxedSumT :: Quote m => SumArity -> m Type
- Language.Haskell.TH.Lib: unboxedTupE :: [ExpQ] -> ExpQ
+ Language.Haskell.TH.Lib: unboxedTupE :: Quote m => [m Exp] -> m Exp
- Language.Haskell.TH.Lib: unboxedTupP :: [PatQ] -> PatQ
+ Language.Haskell.TH.Lib: unboxedTupP :: Quote m => [m Pat] -> m Pat
- Language.Haskell.TH.Lib: unboxedTupleT :: Int -> TypeQ
+ Language.Haskell.TH.Lib: unboxedTupleT :: Quote m => Int -> m Type
- Language.Haskell.TH.Lib: unidir :: PatSynDirQ
+ Language.Haskell.TH.Lib: unidir :: Quote m => m PatSynDir
- Language.Haskell.TH.Lib: unpacked :: Q Strict
+ Language.Haskell.TH.Lib: unpacked :: Quote m => m Strict
- Language.Haskell.TH.Lib: valD :: PatQ -> BodyQ -> [DecQ] -> DecQ
+ Language.Haskell.TH.Lib: valD :: Quote m => m Pat -> m Body -> [m Dec] -> m Dec
- Language.Haskell.TH.Lib: varBangType :: Name -> BangTypeQ -> VarBangTypeQ
+ Language.Haskell.TH.Lib: varBangType :: Quote m => Name -> m BangType -> m VarBangType
- Language.Haskell.TH.Lib: varE :: Name -> ExpQ
+ Language.Haskell.TH.Lib: varE :: Quote m => Name -> m Exp
- Language.Haskell.TH.Lib: varP :: Name -> PatQ
+ Language.Haskell.TH.Lib: varP :: Quote m => Name -> m Pat
- Language.Haskell.TH.Lib: varStrictType :: Name -> StrictTypeQ -> VarStrictTypeQ
+ Language.Haskell.TH.Lib: varStrictType :: Quote m => Name -> m StrictType -> m VarStrictType
- Language.Haskell.TH.Lib: varT :: Name -> TypeQ
+ Language.Haskell.TH.Lib: varT :: Quote m => Name -> m Type
- Language.Haskell.TH.Lib: viaStrategy :: TypeQ -> DerivStrategyQ
+ Language.Haskell.TH.Lib: viaStrategy :: Quote m => m Type -> m DerivStrategy
- Language.Haskell.TH.Lib: viewP :: ExpQ -> PatQ -> PatQ
+ Language.Haskell.TH.Lib: viewP :: Quote m => m Exp -> m Pat -> m Pat
- Language.Haskell.TH.Lib: wildCardT :: TypeQ
+ Language.Haskell.TH.Lib: wildCardT :: Quote m => m Type
- Language.Haskell.TH.Lib: wildP :: PatQ
+ Language.Haskell.TH.Lib: wildP :: Quote m => m Pat
- Language.Haskell.TH.Lib.Internal: anyclassStrategy :: DerivStrategyQ
+ Language.Haskell.TH.Lib.Internal: anyclassStrategy :: Quote m => m DerivStrategy
- Language.Haskell.TH.Lib.Internal: appE :: ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: appE :: Quote m => m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: appKindT :: TypeQ -> KindQ -> TypeQ
+ Language.Haskell.TH.Lib.Internal: appKindT :: Quote m => m Type -> m Kind -> m Type
- Language.Haskell.TH.Lib.Internal: appT :: TypeQ -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib.Internal: appT :: Quote m => m Type -> m Type -> m Type
- Language.Haskell.TH.Lib.Internal: appTypeE :: ExpQ -> TypeQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: appTypeE :: Quote m => m Exp -> m Type -> m Exp
- Language.Haskell.TH.Lib.Internal: appsE :: [ExpQ] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: appsE :: Quote m => [m Exp] -> m Exp
- Language.Haskell.TH.Lib.Internal: arithSeqE :: RangeQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: arithSeqE :: Quote m => m Range -> m Exp
- Language.Haskell.TH.Lib.Internal: arrowT :: TypeQ
+ Language.Haskell.TH.Lib.Internal: arrowT :: Quote m => m Type
- Language.Haskell.TH.Lib.Internal: asP :: Name -> PatQ -> PatQ
+ Language.Haskell.TH.Lib.Internal: asP :: Quote m => Name -> m Pat -> m Pat
- Language.Haskell.TH.Lib.Internal: bang :: SourceUnpackednessQ -> SourceStrictnessQ -> BangQ
+ Language.Haskell.TH.Lib.Internal: bang :: Quote m => m SourceUnpackedness -> m SourceStrictness -> m Bang
- Language.Haskell.TH.Lib.Internal: bangP :: PatQ -> PatQ
+ Language.Haskell.TH.Lib.Internal: bangP :: Quote m => m Pat -> m Pat
- Language.Haskell.TH.Lib.Internal: bangType :: BangQ -> TypeQ -> BangTypeQ
+ Language.Haskell.TH.Lib.Internal: bangType :: Quote m => m Bang -> m Type -> m BangType
- Language.Haskell.TH.Lib.Internal: bindS :: PatQ -> ExpQ -> StmtQ
+ Language.Haskell.TH.Lib.Internal: bindS :: Quote m => m Pat -> m Exp -> m Stmt
- Language.Haskell.TH.Lib.Internal: caseE :: ExpQ -> [MatchQ] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: caseE :: Quote m => m Exp -> [m Match] -> m Exp
- Language.Haskell.TH.Lib.Internal: classD :: CxtQ -> Name -> [TyVarBndrQ] -> [FunDep] -> [DecQ] -> DecQ
+ Language.Haskell.TH.Lib.Internal: classD :: Quote m => m Cxt -> Name -> [m TyVarBndr] -> [FunDep] -> [m Dec] -> m Dec
- Language.Haskell.TH.Lib.Internal: classP :: Name -> [Q Type] -> Q Pred
+ Language.Haskell.TH.Lib.Internal: classP :: Quote m => Name -> [m Type] -> m Pred
- Language.Haskell.TH.Lib.Internal: clause :: [PatQ] -> BodyQ -> [DecQ] -> ClauseQ
+ Language.Haskell.TH.Lib.Internal: clause :: Quote m => [m Pat] -> m Body -> [m Dec] -> m Clause
- Language.Haskell.TH.Lib.Internal: closedTypeFamilyD :: Name -> [TyVarBndrQ] -> FamilyResultSigQ -> Maybe InjectivityAnn -> [TySynEqnQ] -> DecQ
+ Language.Haskell.TH.Lib.Internal: closedTypeFamilyD :: Quote m => Name -> [m TyVarBndr] -> m FamilyResultSig -> Maybe InjectivityAnn -> [m TySynEqn] -> m Dec
- Language.Haskell.TH.Lib.Internal: compE :: [StmtQ] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: compE :: Quote m => [m Stmt] -> m Exp
- Language.Haskell.TH.Lib.Internal: conE :: Name -> ExpQ
+ Language.Haskell.TH.Lib.Internal: conE :: Quote m => Name -> m Exp
- Language.Haskell.TH.Lib.Internal: conP :: Name -> [PatQ] -> PatQ
+ Language.Haskell.TH.Lib.Internal: conP :: Quote m => Name -> [m Pat] -> m Pat
- Language.Haskell.TH.Lib.Internal: conT :: Name -> TypeQ
+ Language.Haskell.TH.Lib.Internal: conT :: Quote m => Name -> m Type
- Language.Haskell.TH.Lib.Internal: condE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: condE :: Quote m => m Exp -> m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: constraintK :: KindQ
+ Language.Haskell.TH.Lib.Internal: constraintK :: Quote m => m Kind
- Language.Haskell.TH.Lib.Internal: cxt :: [PredQ] -> CxtQ
+ Language.Haskell.TH.Lib.Internal: cxt :: Quote m => [m Pred] -> m Cxt
- Language.Haskell.TH.Lib.Internal: dataD :: CxtQ -> Name -> [TyVarBndrQ] -> Maybe KindQ -> [ConQ] -> [DerivClauseQ] -> DecQ
+ Language.Haskell.TH.Lib.Internal: dataD :: Quote m => m Cxt -> Name -> [m TyVarBndr] -> Maybe (m Kind) -> [m Con] -> [m DerivClause] -> m Dec
- Language.Haskell.TH.Lib.Internal: dataFamilyD :: Name -> [TyVarBndrQ] -> Maybe KindQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: dataFamilyD :: Quote m => Name -> [m TyVarBndr] -> Maybe (m Kind) -> m Dec
- Language.Haskell.TH.Lib.Internal: dataInstD :: CxtQ -> Maybe [TyVarBndrQ] -> TypeQ -> Maybe KindQ -> [ConQ] -> [DerivClauseQ] -> DecQ
+ Language.Haskell.TH.Lib.Internal: dataInstD :: Quote m => m Cxt -> Maybe [m TyVarBndr] -> m Type -> Maybe (m Kind) -> [m Con] -> [m DerivClause] -> m Dec
- Language.Haskell.TH.Lib.Internal: defaultSigD :: Name -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: defaultSigD :: Quote m => Name -> m Type -> m Dec
- Language.Haskell.TH.Lib.Internal: derivClause :: Maybe DerivStrategyQ -> [PredQ] -> DerivClauseQ
+ Language.Haskell.TH.Lib.Internal: derivClause :: Quote m => Maybe (m DerivStrategy) -> [m Pred] -> m DerivClause
- Language.Haskell.TH.Lib.Internal: doE :: [StmtQ] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: doE :: Quote m => [m Stmt] -> m Exp
- Language.Haskell.TH.Lib.Internal: dyn :: String -> ExpQ
+ Language.Haskell.TH.Lib.Internal: dyn :: Quote m => String -> m Exp
- Language.Haskell.TH.Lib.Internal: equalP :: TypeQ -> TypeQ -> PredQ
+ Language.Haskell.TH.Lib.Internal: equalP :: Quote m => m Type -> m Type -> m Pred
- Language.Haskell.TH.Lib.Internal: equalityT :: TypeQ
+ Language.Haskell.TH.Lib.Internal: equalityT :: Quote m => m Type
- Language.Haskell.TH.Lib.Internal: explBidir :: [ClauseQ] -> PatSynDirQ
+ Language.Haskell.TH.Lib.Internal: explBidir :: Quote m => [m Clause] -> m PatSynDir
- Language.Haskell.TH.Lib.Internal: fieldExp :: Name -> ExpQ -> Q (Name, Exp)
+ Language.Haskell.TH.Lib.Internal: fieldExp :: Quote m => Name -> m Exp -> m (Name, Exp)
- Language.Haskell.TH.Lib.Internal: fieldPat :: Name -> PatQ -> FieldPatQ
+ Language.Haskell.TH.Lib.Internal: fieldPat :: Quote m => Name -> m Pat -> m FieldPat
- Language.Haskell.TH.Lib.Internal: forImpD :: Callconv -> Safety -> String -> Name -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: forImpD :: Quote m => Callconv -> Safety -> String -> Name -> m Type -> m Dec
- Language.Haskell.TH.Lib.Internal: forallC :: [TyVarBndrQ] -> CxtQ -> ConQ -> ConQ
+ Language.Haskell.TH.Lib.Internal: forallC :: Quote m => [m TyVarBndr] -> m Cxt -> m Con -> m Con
- Language.Haskell.TH.Lib.Internal: forallT :: [TyVarBndrQ] -> CxtQ -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib.Internal: forallT :: Quote m => [m TyVarBndr] -> m Cxt -> m Type -> m Type
- Language.Haskell.TH.Lib.Internal: forallVisT :: [TyVarBndrQ] -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib.Internal: forallVisT :: Quote m => [m TyVarBndr] -> m Type -> m Type
- Language.Haskell.TH.Lib.Internal: fromE :: ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: fromE :: Quote m => m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: fromR :: ExpQ -> RangeQ
+ Language.Haskell.TH.Lib.Internal: fromR :: Quote m => m Exp -> m Range
- Language.Haskell.TH.Lib.Internal: fromThenE :: ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: fromThenE :: Quote m => m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: fromThenR :: ExpQ -> ExpQ -> RangeQ
+ Language.Haskell.TH.Lib.Internal: fromThenR :: Quote m => m Exp -> m Exp -> m Range
- Language.Haskell.TH.Lib.Internal: fromThenToE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: fromThenToE :: Quote m => m Exp -> m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: fromThenToR :: ExpQ -> ExpQ -> ExpQ -> RangeQ
+ Language.Haskell.TH.Lib.Internal: fromThenToR :: Quote m => m Exp -> m Exp -> m Exp -> m Range
- Language.Haskell.TH.Lib.Internal: fromToE :: ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: fromToE :: Quote m => m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: fromToR :: ExpQ -> ExpQ -> RangeQ
+ Language.Haskell.TH.Lib.Internal: fromToR :: Quote m => m Exp -> m Exp -> m Range
- Language.Haskell.TH.Lib.Internal: funD :: Name -> [ClauseQ] -> DecQ
+ Language.Haskell.TH.Lib.Internal: funD :: Quote m => Name -> [m Clause] -> m Dec
- Language.Haskell.TH.Lib.Internal: gadtC :: [Name] -> [StrictTypeQ] -> TypeQ -> ConQ
+ Language.Haskell.TH.Lib.Internal: gadtC :: Quote m => [Name] -> [m StrictType] -> m Type -> m Con
- Language.Haskell.TH.Lib.Internal: guardedB :: [Q (Guard, Exp)] -> BodyQ
+ Language.Haskell.TH.Lib.Internal: guardedB :: Quote m => [m (Guard, Exp)] -> m Body
- Language.Haskell.TH.Lib.Internal: implBidir :: PatSynDirQ
+ Language.Haskell.TH.Lib.Internal: implBidir :: Quote m => m PatSynDir
- Language.Haskell.TH.Lib.Internal: implicitParamBindD :: String -> ExpQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: implicitParamBindD :: Quote m => String -> m Exp -> m Dec
- Language.Haskell.TH.Lib.Internal: implicitParamT :: String -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib.Internal: implicitParamT :: Quote m => String -> m Type -> m Type
- Language.Haskell.TH.Lib.Internal: implicitParamVarE :: String -> ExpQ
+ Language.Haskell.TH.Lib.Internal: implicitParamVarE :: Quote m => String -> m Exp
- Language.Haskell.TH.Lib.Internal: infixApp :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: infixApp :: Quote m => m Exp -> m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: infixC :: Q (Bang, Type) -> Name -> Q (Bang, Type) -> ConQ
+ Language.Haskell.TH.Lib.Internal: infixC :: Quote m => m (Bang, Type) -> Name -> m (Bang, Type) -> m Con
- Language.Haskell.TH.Lib.Internal: infixE :: Maybe ExpQ -> ExpQ -> Maybe ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: infixE :: Quote m => Maybe (m Exp) -> m Exp -> Maybe (m Exp) -> m Exp
- Language.Haskell.TH.Lib.Internal: infixLD :: Int -> Name -> DecQ
+ Language.Haskell.TH.Lib.Internal: infixLD :: Quote m => Int -> Name -> m Dec
- Language.Haskell.TH.Lib.Internal: infixND :: Int -> Name -> DecQ
+ Language.Haskell.TH.Lib.Internal: infixND :: Quote m => Int -> Name -> m Dec
- Language.Haskell.TH.Lib.Internal: infixP :: PatQ -> Name -> PatQ -> PatQ
+ Language.Haskell.TH.Lib.Internal: infixP :: Quote m => m Pat -> Name -> m Pat -> m Pat
- Language.Haskell.TH.Lib.Internal: infixPatSyn :: Name -> Name -> PatSynArgsQ
+ Language.Haskell.TH.Lib.Internal: infixPatSyn :: Quote m => Name -> Name -> m PatSynArgs
- Language.Haskell.TH.Lib.Internal: infixRD :: Int -> Name -> DecQ
+ Language.Haskell.TH.Lib.Internal: infixRD :: Quote m => Int -> Name -> m Dec
- Language.Haskell.TH.Lib.Internal: infixT :: TypeQ -> Name -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib.Internal: infixT :: Quote m => m Type -> Name -> m Type -> m Type
- Language.Haskell.TH.Lib.Internal: instanceD :: CxtQ -> TypeQ -> [DecQ] -> DecQ
+ Language.Haskell.TH.Lib.Internal: instanceD :: Quote m => m Cxt -> m Type -> [m Dec] -> m Dec
- Language.Haskell.TH.Lib.Internal: instanceWithOverlapD :: Maybe Overlap -> CxtQ -> TypeQ -> [DecQ] -> DecQ
+ Language.Haskell.TH.Lib.Internal: instanceWithOverlapD :: Quote m => Maybe Overlap -> m Cxt -> m Type -> [m Dec] -> m Dec
- Language.Haskell.TH.Lib.Internal: isStrict :: Q Strict
+ Language.Haskell.TH.Lib.Internal: isStrict :: Quote m => m Strict
- Language.Haskell.TH.Lib.Internal: kiSigD :: Name -> KindQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: kiSigD :: Quote m => Name -> m Kind -> m Dec
- Language.Haskell.TH.Lib.Internal: kindSig :: KindQ -> FamilyResultSigQ
+ Language.Haskell.TH.Lib.Internal: kindSig :: Quote m => m Kind -> m FamilyResultSig
- Language.Haskell.TH.Lib.Internal: kindedTV :: Name -> KindQ -> TyVarBndrQ
+ Language.Haskell.TH.Lib.Internal: kindedTV :: Quote m => Name -> m Kind -> m TyVarBndr
- Language.Haskell.TH.Lib.Internal: labelE :: String -> ExpQ
+ Language.Haskell.TH.Lib.Internal: labelE :: Quote m => String -> m Exp
- Language.Haskell.TH.Lib.Internal: lam1E :: PatQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: lam1E :: Quote m => m Pat -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: lamCaseE :: [MatchQ] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: lamCaseE :: Quote m => [m Match] -> m Exp
- Language.Haskell.TH.Lib.Internal: lamE :: [PatQ] -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: lamE :: Quote m => [m Pat] -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: letE :: [DecQ] -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: letE :: Quote m => [m Dec] -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: letS :: [DecQ] -> StmtQ
+ Language.Haskell.TH.Lib.Internal: letS :: Quote m => [m Dec] -> m Stmt
- Language.Haskell.TH.Lib.Internal: listE :: [ExpQ] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: listE :: Quote m => [m Exp] -> m Exp
- Language.Haskell.TH.Lib.Internal: listP :: [PatQ] -> PatQ
+ Language.Haskell.TH.Lib.Internal: listP :: Quote m => [m Pat] -> m Pat
- Language.Haskell.TH.Lib.Internal: listT :: TypeQ
+ Language.Haskell.TH.Lib.Internal: listT :: Quote m => m Type
- Language.Haskell.TH.Lib.Internal: litE :: Lit -> ExpQ
+ Language.Haskell.TH.Lib.Internal: litE :: Quote m => Lit -> m Exp
- Language.Haskell.TH.Lib.Internal: litP :: Lit -> PatQ
+ Language.Haskell.TH.Lib.Internal: litP :: Quote m => Lit -> m Pat
- Language.Haskell.TH.Lib.Internal: litT :: TyLitQ -> TypeQ
+ Language.Haskell.TH.Lib.Internal: litT :: Quote m => m TyLit -> m Type
- Language.Haskell.TH.Lib.Internal: match :: PatQ -> BodyQ -> [DecQ] -> MatchQ
+ Language.Haskell.TH.Lib.Internal: match :: Quote m => m Pat -> m Body -> [m Dec] -> m Match
- Language.Haskell.TH.Lib.Internal: mdoE :: [StmtQ] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: mdoE :: Quote m => [m Stmt] -> m Exp
- Language.Haskell.TH.Lib.Internal: multiIfE :: [Q (Guard, Exp)] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: multiIfE :: Quote m => [m (Guard, Exp)] -> m Exp
- Language.Haskell.TH.Lib.Internal: newtypeD :: CxtQ -> Name -> [TyVarBndrQ] -> Maybe KindQ -> ConQ -> [DerivClauseQ] -> DecQ
+ Language.Haskell.TH.Lib.Internal: newtypeD :: Quote m => m Cxt -> Name -> [m TyVarBndr] -> Maybe (m Kind) -> m Con -> [m DerivClause] -> m Dec
- Language.Haskell.TH.Lib.Internal: newtypeInstD :: CxtQ -> Maybe [TyVarBndrQ] -> TypeQ -> Maybe KindQ -> ConQ -> [DerivClauseQ] -> DecQ
+ Language.Haskell.TH.Lib.Internal: newtypeInstD :: Quote m => m Cxt -> Maybe [m TyVarBndr] -> m Type -> Maybe (m Kind) -> m Con -> [m DerivClause] -> m Dec
- Language.Haskell.TH.Lib.Internal: newtypeStrategy :: DerivStrategyQ
+ Language.Haskell.TH.Lib.Internal: newtypeStrategy :: Quote m => m DerivStrategy
- Language.Haskell.TH.Lib.Internal: noBindS :: ExpQ -> StmtQ
+ Language.Haskell.TH.Lib.Internal: noBindS :: Quote m => m Exp -> m Stmt
- Language.Haskell.TH.Lib.Internal: noSig :: FamilyResultSigQ
+ Language.Haskell.TH.Lib.Internal: noSig :: Quote m => m FamilyResultSig
- Language.Haskell.TH.Lib.Internal: noSourceStrictness :: SourceStrictnessQ
+ Language.Haskell.TH.Lib.Internal: noSourceStrictness :: Quote m => m SourceStrictness
- Language.Haskell.TH.Lib.Internal: noSourceUnpackedness :: SourceUnpackednessQ
+ Language.Haskell.TH.Lib.Internal: noSourceUnpackedness :: Quote m => m SourceUnpackedness
- Language.Haskell.TH.Lib.Internal: normalB :: ExpQ -> BodyQ
+ Language.Haskell.TH.Lib.Internal: normalB :: Quote m => m Exp -> m Body
- Language.Haskell.TH.Lib.Internal: normalC :: Name -> [BangTypeQ] -> ConQ
+ Language.Haskell.TH.Lib.Internal: normalC :: Quote m => Name -> [m BangType] -> m Con
- Language.Haskell.TH.Lib.Internal: normalG :: ExpQ -> GuardQ
+ Language.Haskell.TH.Lib.Internal: normalG :: Quote m => m Exp -> m Guard
- Language.Haskell.TH.Lib.Internal: normalGE :: ExpQ -> ExpQ -> Q (Guard, Exp)
+ Language.Haskell.TH.Lib.Internal: normalGE :: Quote m => m Exp -> m Exp -> m (Guard, Exp)
- Language.Haskell.TH.Lib.Internal: notStrict :: Q Strict
+ Language.Haskell.TH.Lib.Internal: notStrict :: Quote m => m Strict
- Language.Haskell.TH.Lib.Internal: numTyLit :: Integer -> TyLitQ
+ Language.Haskell.TH.Lib.Internal: numTyLit :: Quote m => Integer -> m TyLit
- Language.Haskell.TH.Lib.Internal: openTypeFamilyD :: Name -> [TyVarBndrQ] -> FamilyResultSigQ -> Maybe InjectivityAnn -> DecQ
+ Language.Haskell.TH.Lib.Internal: openTypeFamilyD :: Quote m => Name -> [m TyVarBndr] -> m FamilyResultSig -> Maybe InjectivityAnn -> m Dec
- Language.Haskell.TH.Lib.Internal: parS :: [[StmtQ]] -> StmtQ
+ Language.Haskell.TH.Lib.Internal: parS :: Quote m => [[m Stmt]] -> m Stmt
- Language.Haskell.TH.Lib.Internal: parensE :: ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: parensE :: Quote m => m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: parensP :: PatQ -> PatQ
+ Language.Haskell.TH.Lib.Internal: parensP :: Quote m => m Pat -> m Pat
- Language.Haskell.TH.Lib.Internal: parensT :: TypeQ -> TypeQ
+ Language.Haskell.TH.Lib.Internal: parensT :: Quote m => m Type -> m Type
- Language.Haskell.TH.Lib.Internal: patG :: [StmtQ] -> GuardQ
+ Language.Haskell.TH.Lib.Internal: patG :: Quote m => [m Stmt] -> m Guard
- Language.Haskell.TH.Lib.Internal: patGE :: [StmtQ] -> ExpQ -> Q (Guard, Exp)
+ Language.Haskell.TH.Lib.Internal: patGE :: Quote m => [m Stmt] -> m Exp -> m (Guard, Exp)
- Language.Haskell.TH.Lib.Internal: patSynD :: Name -> PatSynArgsQ -> PatSynDirQ -> PatQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: patSynD :: Quote m => Name -> m PatSynArgs -> m PatSynDir -> m Pat -> m Dec
- Language.Haskell.TH.Lib.Internal: patSynSigD :: Name -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: patSynSigD :: Quote m => Name -> m Type -> m Dec
- Language.Haskell.TH.Lib.Internal: plainTV :: Name -> TyVarBndrQ
+ Language.Haskell.TH.Lib.Internal: plainTV :: Quote m => Name -> m TyVarBndr
- Language.Haskell.TH.Lib.Internal: pragAnnD :: AnnTarget -> ExpQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: pragAnnD :: Quote m => AnnTarget -> m Exp -> m Dec
- Language.Haskell.TH.Lib.Internal: pragCompleteD :: [Name] -> Maybe Name -> DecQ
+ Language.Haskell.TH.Lib.Internal: pragCompleteD :: Quote m => [Name] -> Maybe Name -> m Dec
- Language.Haskell.TH.Lib.Internal: pragInlD :: Name -> Inline -> RuleMatch -> Phases -> DecQ
+ Language.Haskell.TH.Lib.Internal: pragInlD :: Quote m => Name -> Inline -> RuleMatch -> Phases -> m Dec
- Language.Haskell.TH.Lib.Internal: pragLineD :: Int -> String -> DecQ
+ Language.Haskell.TH.Lib.Internal: pragLineD :: Quote m => Int -> String -> m Dec
- Language.Haskell.TH.Lib.Internal: pragRuleD :: String -> Maybe [TyVarBndrQ] -> [RuleBndrQ] -> ExpQ -> ExpQ -> Phases -> DecQ
+ Language.Haskell.TH.Lib.Internal: pragRuleD :: Quote m => String -> Maybe [m TyVarBndr] -> [m RuleBndr] -> m Exp -> m Exp -> Phases -> m Dec
- Language.Haskell.TH.Lib.Internal: pragSpecD :: Name -> TypeQ -> Phases -> DecQ
+ Language.Haskell.TH.Lib.Internal: pragSpecD :: Quote m => Name -> m Type -> Phases -> m Dec
- Language.Haskell.TH.Lib.Internal: pragSpecInlD :: Name -> TypeQ -> Inline -> Phases -> DecQ
+ Language.Haskell.TH.Lib.Internal: pragSpecInlD :: Quote m => Name -> m Type -> Inline -> Phases -> m Dec
- Language.Haskell.TH.Lib.Internal: pragSpecInstD :: TypeQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: pragSpecInstD :: Quote m => m Type -> m Dec
- Language.Haskell.TH.Lib.Internal: prefixPatSyn :: [Name] -> PatSynArgsQ
+ Language.Haskell.TH.Lib.Internal: prefixPatSyn :: Quote m => [Name] -> m PatSynArgs
- Language.Haskell.TH.Lib.Internal: promotedConsT :: TypeQ
+ Language.Haskell.TH.Lib.Internal: promotedConsT :: Quote m => m Type
- Language.Haskell.TH.Lib.Internal: promotedNilT :: TypeQ
+ Language.Haskell.TH.Lib.Internal: promotedNilT :: Quote m => m Type
- Language.Haskell.TH.Lib.Internal: promotedT :: Name -> TypeQ
+ Language.Haskell.TH.Lib.Internal: promotedT :: Quote m => Name -> m Type
- Language.Haskell.TH.Lib.Internal: promotedTupleT :: Int -> TypeQ
+ Language.Haskell.TH.Lib.Internal: promotedTupleT :: Quote m => Int -> m Type
- Language.Haskell.TH.Lib.Internal: recC :: Name -> [VarBangTypeQ] -> ConQ
+ Language.Haskell.TH.Lib.Internal: recC :: Quote m => Name -> [m VarBangType] -> m Con
- Language.Haskell.TH.Lib.Internal: recConE :: Name -> [Q (Name, Exp)] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: recConE :: Quote m => Name -> [m (Name, Exp)] -> m Exp
- Language.Haskell.TH.Lib.Internal: recGadtC :: [Name] -> [VarStrictTypeQ] -> TypeQ -> ConQ
+ Language.Haskell.TH.Lib.Internal: recGadtC :: Quote m => [Name] -> [m VarStrictType] -> m Type -> m Con
- Language.Haskell.TH.Lib.Internal: recP :: Name -> [FieldPatQ] -> PatQ
+ Language.Haskell.TH.Lib.Internal: recP :: Quote m => Name -> [m FieldPat] -> m Pat
- Language.Haskell.TH.Lib.Internal: recS :: [StmtQ] -> StmtQ
+ Language.Haskell.TH.Lib.Internal: recS :: Quote m => [m Stmt] -> m Stmt
- Language.Haskell.TH.Lib.Internal: recUpdE :: ExpQ -> [Q (Name, Exp)] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: recUpdE :: Quote m => m Exp -> [m (Name, Exp)] -> m Exp
- Language.Haskell.TH.Lib.Internal: recordPatSyn :: [Name] -> PatSynArgsQ
+ Language.Haskell.TH.Lib.Internal: recordPatSyn :: Quote m => [Name] -> m PatSynArgs
- Language.Haskell.TH.Lib.Internal: roleAnnotD :: Name -> [Role] -> DecQ
+ Language.Haskell.TH.Lib.Internal: roleAnnotD :: Quote m => Name -> [Role] -> m Dec
- Language.Haskell.TH.Lib.Internal: ruleVar :: Name -> RuleBndrQ
+ Language.Haskell.TH.Lib.Internal: ruleVar :: Quote m => Name -> m RuleBndr
- Language.Haskell.TH.Lib.Internal: sectionL :: ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: sectionL :: Quote m => m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: sectionR :: ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: sectionR :: Quote m => m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: sigD :: Name -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: sigD :: Quote m => Name -> m Type -> m Dec
- Language.Haskell.TH.Lib.Internal: sigE :: ExpQ -> TypeQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: sigE :: Quote m => m Exp -> m Type -> m Exp
- Language.Haskell.TH.Lib.Internal: sigP :: PatQ -> TypeQ -> PatQ
+ Language.Haskell.TH.Lib.Internal: sigP :: Quote m => m Pat -> m Type -> m Pat
- Language.Haskell.TH.Lib.Internal: sigT :: TypeQ -> KindQ -> TypeQ
+ Language.Haskell.TH.Lib.Internal: sigT :: Quote m => m Type -> m Kind -> m Type
- Language.Haskell.TH.Lib.Internal: sourceLazy :: SourceStrictnessQ
+ Language.Haskell.TH.Lib.Internal: sourceLazy :: Quote m => m SourceStrictness
- Language.Haskell.TH.Lib.Internal: sourceNoUnpack :: SourceUnpackednessQ
+ Language.Haskell.TH.Lib.Internal: sourceNoUnpack :: Quote m => m SourceUnpackedness
- Language.Haskell.TH.Lib.Internal: sourceStrict :: SourceStrictnessQ
+ Language.Haskell.TH.Lib.Internal: sourceStrict :: Quote m => m SourceStrictness
- Language.Haskell.TH.Lib.Internal: sourceUnpack :: SourceUnpackednessQ
+ Language.Haskell.TH.Lib.Internal: sourceUnpack :: Quote m => m SourceUnpackedness
- Language.Haskell.TH.Lib.Internal: standaloneDerivD :: CxtQ -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: standaloneDerivD :: Quote m => m Cxt -> m Type -> m Dec
- Language.Haskell.TH.Lib.Internal: standaloneDerivWithStrategyD :: Maybe DerivStrategyQ -> CxtQ -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: standaloneDerivWithStrategyD :: Quote m => Maybe (m DerivStrategy) -> m Cxt -> m Type -> m Dec
- Language.Haskell.TH.Lib.Internal: starK :: KindQ
+ Language.Haskell.TH.Lib.Internal: starK :: Quote m => m Kind
- Language.Haskell.TH.Lib.Internal: staticE :: ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: staticE :: Quote m => m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: stockStrategy :: DerivStrategyQ
+ Language.Haskell.TH.Lib.Internal: stockStrategy :: Quote m => m DerivStrategy
- Language.Haskell.TH.Lib.Internal: strTyLit :: String -> TyLitQ
+ Language.Haskell.TH.Lib.Internal: strTyLit :: Quote m => String -> m TyLit
- Language.Haskell.TH.Lib.Internal: strictType :: Q Strict -> TypeQ -> StrictTypeQ
+ Language.Haskell.TH.Lib.Internal: strictType :: Quote m => m Strict -> m Type -> m StrictType
- Language.Haskell.TH.Lib.Internal: stringE :: String -> ExpQ
+ Language.Haskell.TH.Lib.Internal: stringE :: Quote m => String -> m Exp
- Language.Haskell.TH.Lib.Internal: tildeP :: PatQ -> PatQ
+ Language.Haskell.TH.Lib.Internal: tildeP :: Quote m => m Pat -> m Pat
- Language.Haskell.TH.Lib.Internal: tupE :: [Maybe ExpQ] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: tupE :: Quote m => [Maybe (m Exp)] -> m Exp
- Language.Haskell.TH.Lib.Internal: tupP :: [PatQ] -> PatQ
+ Language.Haskell.TH.Lib.Internal: tupP :: Quote m => [m Pat] -> m Pat
- Language.Haskell.TH.Lib.Internal: tupleT :: Int -> TypeQ
+ Language.Haskell.TH.Lib.Internal: tupleT :: Quote m => Int -> m Type
- Language.Haskell.TH.Lib.Internal: tySynD :: Name -> [TyVarBndrQ] -> TypeQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: tySynD :: Quote m => Name -> [m TyVarBndr] -> m Type -> m Dec
- Language.Haskell.TH.Lib.Internal: tySynEqn :: Maybe [TyVarBndrQ] -> TypeQ -> TypeQ -> TySynEqnQ
+ Language.Haskell.TH.Lib.Internal: tySynEqn :: Quote m => Maybe [m TyVarBndr] -> m Type -> m Type -> m TySynEqn
- Language.Haskell.TH.Lib.Internal: tySynInstD :: TySynEqnQ -> DecQ
+ Language.Haskell.TH.Lib.Internal: tySynInstD :: Quote m => m TySynEqn -> m Dec
- Language.Haskell.TH.Lib.Internal: tyVarSig :: TyVarBndrQ -> FamilyResultSigQ
+ Language.Haskell.TH.Lib.Internal: tyVarSig :: Quote m => m TyVarBndr -> m FamilyResultSig
- Language.Haskell.TH.Lib.Internal: typedRuleVar :: Name -> TypeQ -> RuleBndrQ
+ Language.Haskell.TH.Lib.Internal: typedRuleVar :: Quote m => Name -> m Type -> m RuleBndr
- Language.Haskell.TH.Lib.Internal: uInfixE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
+ Language.Haskell.TH.Lib.Internal: uInfixE :: Quote m => m Exp -> m Exp -> m Exp -> m Exp
- Language.Haskell.TH.Lib.Internal: uInfixP :: PatQ -> Name -> PatQ -> PatQ
+ Language.Haskell.TH.Lib.Internal: uInfixP :: Quote m => m Pat -> Name -> m Pat -> m Pat
- Language.Haskell.TH.Lib.Internal: uInfixT :: TypeQ -> Name -> TypeQ -> TypeQ
+ Language.Haskell.TH.Lib.Internal: uInfixT :: Quote m => m Type -> Name -> m Type -> m Type
- Language.Haskell.TH.Lib.Internal: unboundVarE :: Name -> ExpQ
+ Language.Haskell.TH.Lib.Internal: unboundVarE :: Quote m => Name -> m Exp
- Language.Haskell.TH.Lib.Internal: unboxedSumE :: ExpQ -> SumAlt -> SumArity -> ExpQ
+ Language.Haskell.TH.Lib.Internal: unboxedSumE :: Quote m => m Exp -> SumAlt -> SumArity -> m Exp
- Language.Haskell.TH.Lib.Internal: unboxedSumP :: PatQ -> SumAlt -> SumArity -> PatQ
+ Language.Haskell.TH.Lib.Internal: unboxedSumP :: Quote m => m Pat -> SumAlt -> SumArity -> m Pat
- Language.Haskell.TH.Lib.Internal: unboxedSumT :: SumArity -> TypeQ
+ Language.Haskell.TH.Lib.Internal: unboxedSumT :: Quote m => SumArity -> m Type
- Language.Haskell.TH.Lib.Internal: unboxedTupE :: [Maybe ExpQ] -> ExpQ
+ Language.Haskell.TH.Lib.Internal: unboxedTupE :: Quote m => [Maybe (m Exp)] -> m Exp
- Language.Haskell.TH.Lib.Internal: unboxedTupP :: [PatQ] -> PatQ
+ Language.Haskell.TH.Lib.Internal: unboxedTupP :: Quote m => [m Pat] -> m Pat
- Language.Haskell.TH.Lib.Internal: unboxedTupleT :: Int -> TypeQ
+ Language.Haskell.TH.Lib.Internal: unboxedTupleT :: Quote m => Int -> m Type
- Language.Haskell.TH.Lib.Internal: unidir :: PatSynDirQ
+ Language.Haskell.TH.Lib.Internal: unidir :: Quote m => m PatSynDir
- Language.Haskell.TH.Lib.Internal: unpacked :: Q Strict
+ Language.Haskell.TH.Lib.Internal: unpacked :: Quote m => m Strict
- Language.Haskell.TH.Lib.Internal: valD :: PatQ -> BodyQ -> [DecQ] -> DecQ
+ Language.Haskell.TH.Lib.Internal: valD :: Quote m => m Pat -> m Body -> [m Dec] -> m Dec
- Language.Haskell.TH.Lib.Internal: varBangType :: Name -> BangTypeQ -> VarBangTypeQ
+ Language.Haskell.TH.Lib.Internal: varBangType :: Quote m => Name -> m BangType -> m VarBangType
- Language.Haskell.TH.Lib.Internal: varE :: Name -> ExpQ
+ Language.Haskell.TH.Lib.Internal: varE :: Quote m => Name -> m Exp
- Language.Haskell.TH.Lib.Internal: varP :: Name -> PatQ
+ Language.Haskell.TH.Lib.Internal: varP :: Quote m => Name -> m Pat
- Language.Haskell.TH.Lib.Internal: varStrictType :: Name -> StrictTypeQ -> VarStrictTypeQ
+ Language.Haskell.TH.Lib.Internal: varStrictType :: Quote m => Name -> m StrictType -> m VarStrictType
- Language.Haskell.TH.Lib.Internal: varT :: Name -> TypeQ
+ Language.Haskell.TH.Lib.Internal: varT :: Quote m => Name -> m Type
- Language.Haskell.TH.Lib.Internal: viaStrategy :: TypeQ -> DerivStrategyQ
+ Language.Haskell.TH.Lib.Internal: viaStrategy :: Quote m => m Type -> m DerivStrategy
- Language.Haskell.TH.Lib.Internal: viewP :: ExpQ -> PatQ -> PatQ
+ Language.Haskell.TH.Lib.Internal: viewP :: Quote m => m Exp -> m Pat -> m Pat
- Language.Haskell.TH.Lib.Internal: wildCardT :: TypeQ
+ Language.Haskell.TH.Lib.Internal: wildCardT :: Quote m => m Type
- Language.Haskell.TH.Lib.Internal: wildP :: PatQ
+ Language.Haskell.TH.Lib.Internal: wildP :: Quote m => m Pat
- Language.Haskell.TH.Syntax: lift :: (Lift t, r ~ 'LiftedRep) => t -> Q Exp
+ Language.Haskell.TH.Syntax: lift :: (Lift t, r ~ 'LiftedRep, Quote m) => t -> m Exp
- Language.Haskell.TH.Syntax: liftString :: String -> Q Exp
+ Language.Haskell.TH.Syntax: liftString :: Quote m => String -> m Exp
- Language.Haskell.TH.Syntax: liftTyped :: Lift t => t -> Q (TExp t)
+ Language.Haskell.TH.Syntax: liftTyped :: (Lift t, Quote m) => t -> m (TExp t)
- Language.Haskell.TH.Syntax: newName :: String -> Q Name
+ Language.Haskell.TH.Syntax: newName :: Quote m => String -> m Name
- Language.Haskell.TH.Syntax: sequenceQ :: [Q a] -> Q [a]
+ Language.Haskell.TH.Syntax: sequenceQ :: forall m. Monad m => forall a. [m a] -> m [a]
- Language.Haskell.TH.Syntax: unTypeQ :: forall (r :: RuntimeRep) (a :: TYPE r). Q (TExp a) -> Q Exp
+ Language.Haskell.TH.Syntax: unTypeQ :: forall (r :: RuntimeRep) (a :: TYPE r) m. Quote m => m (TExp a) -> m Exp
- Language.Haskell.TH.Syntax: unsafeTExpCoerce :: forall (r :: RuntimeRep) (a :: TYPE r). Q Exp -> Q (TExp a)
+ Language.Haskell.TH.Syntax: unsafeTExpCoerce :: forall (r :: RuntimeRep) (a :: TYPE r) m. Quote m => m Exp -> m (TExp a)
- Module: renameHoleModule' :: PackageConfigMap -> ShHoleSubst -> Module -> Module
+ Module: renameHoleModule' :: UnitInfoMap -> ShHoleSubst -> Module -> Module
- Module: renameHoleUnitId' :: PackageConfigMap -> ShHoleSubst -> UnitId -> UnitId
+ Module: renameHoleUnitId' :: UnitInfoMap -> ShHoleSubst -> UnitId -> UnitId
- Packages: LookupFound :: Module -> PackageConfig -> LookupResult
+ Packages: LookupFound :: Module -> UnitInfo -> LookupResult
- Packages: ModOrigin :: Maybe Bool -> [PackageConfig] -> [PackageConfig] -> Bool -> ModuleOrigin
+ Packages: ModOrigin :: Maybe Bool -> [UnitInfo] -> [UnitInfo] -> Bool -> ModuleOrigin
- Packages: [fromExposedReexport] :: ModuleOrigin -> [PackageConfig]
+ Packages: [fromExposedReexport] :: ModuleOrigin -> [UnitInfo]
- Packages: [fromHiddenReexport] :: ModuleOrigin -> [PackageConfig]
+ Packages: [fromHiddenReexport] :: ModuleOrigin -> [UnitInfo]
- Packages: collectArchives :: DynFlags -> PackageConfig -> IO [FilePath]
+ Packages: collectArchives :: DynFlags -> UnitInfo -> IO [FilePath]
- Packages: collectIncludeDirs :: [PackageConfig] -> [FilePath]
+ Packages: collectIncludeDirs :: [UnitInfo] -> [FilePath]
- Packages: collectLibraryPaths :: DynFlags -> [PackageConfig] -> [FilePath]
+ Packages: collectLibraryPaths :: DynFlags -> [UnitInfo] -> [FilePath]
- Packages: collectLinkOpts :: DynFlags -> [PackageConfig] -> ([String], [String], [String])
+ Packages: collectLinkOpts :: DynFlags -> [UnitInfo] -> ([String], [String], [String])
- Packages: getInstalledPackageDetails :: HasDebugCallStack => DynFlags -> InstalledUnitId -> PackageConfig
+ Packages: getInstalledPackageDetails :: HasDebugCallStack => DynFlags -> InstalledUnitId -> UnitInfo
- Packages: getPackageConfRefs :: DynFlags -> IO [PkgConfRef]
+ Packages: getPackageConfRefs :: DynFlags -> IO [PkgDbRef]
- Packages: getPackageDetails :: HasDebugCallStack => DynFlags -> UnitId -> PackageConfig
+ Packages: getPackageDetails :: HasDebugCallStack => DynFlags -> UnitId -> UnitInfo
- Packages: getPreloadPackagesAnd :: DynFlags -> [PreloadUnitId] -> IO [PackageConfig]
+ Packages: getPreloadPackagesAnd :: DynFlags -> [PreloadUnitId] -> IO [UnitInfo]
- Packages: improveUnitId :: PackageConfigMap -> UnitId -> UnitId
+ Packages: improveUnitId :: UnitInfoMap -> UnitId -> UnitId
- Packages: lookupInstalledPackage :: DynFlags -> InstalledUnitId -> Maybe PackageConfig
+ Packages: lookupInstalledPackage :: DynFlags -> InstalledUnitId -> Maybe UnitInfo
- Packages: lookupModuleInAllPackages :: DynFlags -> ModuleName -> [(Module, PackageConfig)]
+ Packages: lookupModuleInAllPackages :: DynFlags -> ModuleName -> [(Module, UnitInfo)]
- Packages: packageHsLibs :: DynFlags -> PackageConfig -> [String]
+ Packages: packageHsLibs :: DynFlags -> UnitInfo -> [String]
- Packages: pprModuleMap :: ModuleToPkgConfAll -> SDoc
+ Packages: pprModuleMap :: ModuleNameProvidersMap -> SDoc
- Packages: searchPackageId :: DynFlags -> SourcePackageId -> [PackageConfig]
+ Packages: searchPackageId :: DynFlags -> SourcePackageId -> [UnitInfo]
- Parser: parseHeader :: P (Located (HsModule GhcPs))
+ Parser: parseHeader :: P (Located HsModule)
- Parser: parseModule :: P (Located (HsModule GhcPs))
+ Parser: parseModule :: P (Located HsModule)
- Parser: parseSignature :: P (Located (HsModule GhcPs))
+ Parser: parseSignature :: P (Located HsModule)
- TcRnTypes: TcPending :: TcRef [PendingTcSplice] -> TcRef WantedConstraints -> PendingStuff
+ TcRnTypes: TcPending :: TcRef [PendingTcSplice] -> TcRef WantedConstraints -> QuoteWrapper -> PendingStuff
Files
- compiler/GHC/Cmm.hs +231/−0
- compiler/GHC/Cmm/BlockId.hs +46/−0
- compiler/GHC/Cmm/BlockId.hs-boot +8/−0
- compiler/GHC/Cmm/CLabel.hs +1571/−0
- compiler/GHC/Cmm/Dataflow/Block.hs +329/−0
- compiler/GHC/Cmm/Dataflow/Collections.hs +177/−0
- compiler/GHC/Cmm/Dataflow/Graph.hs +186/−0
- compiler/GHC/Cmm/Dataflow/Label.hs +142/−0
- compiler/GHC/Cmm/Expr.hs +619/−0
- compiler/GHC/Cmm/MachOp.hs +666/−0
- compiler/GHC/Cmm/Node.hs +726/−0
- compiler/GHC/Cmm/Switch.hs +503/−0
- compiler/GHC/Cmm/Type.hs +432/−0
- compiler/GHC/CoreToIface.hs +685/−0
- compiler/GHC/CoreToIface.hs-boot +18/−0
- compiler/GHC/Hs.hs +7/−9
- compiler/GHC/Hs/Binds.hs +2/−2
- compiler/GHC/Hs/Decls.hs +69/−20
- compiler/GHC/Hs/Expr.hs +14/−10
- compiler/GHC/Hs/Pat.hs +2/−2
- compiler/GHC/Hs/Types.hs +36/−54
- compiler/GHC/Hs/Utils.hs +5/−3
- compiler/GHC/HsToCore/PmCheck/Types.hs +2/−2
- compiler/GHC/Iface/Syntax.hs +2593/−0
- compiler/GHC/Iface/Type.hs +2060/−0
- compiler/GHC/Iface/Type.hs-boot +16/−0
- compiler/GHC/Platform/ARM.hs +10/−0
- compiler/GHC/Platform/ARM64.hs +10/−0
- compiler/GHC/Platform/NoRegs.hs +9/−0
- compiler/GHC/Platform/PPC.hs +10/−0
- compiler/GHC/Platform/Regs.hs +113/−0
- compiler/GHC/Platform/S390X.hs +10/−0
- compiler/GHC/Platform/SPARC.hs +10/−0
- compiler/GHC/Platform/X86.hs +10/−0
- compiler/GHC/Platform/X86_64.hs +10/−0
- compiler/GHC/Runtime/Layout.hs +563/−0
- compiler/GHC/Stg/Syntax.hs +871/−0
- compiler/backpack/BkpSyn.hs +2/−2
- compiler/basicTypes/Avail.hs +2/−2
- compiler/basicTypes/BasicTypes.hs +7/−6
- compiler/basicTypes/DataCon.hs +1/−1
- compiler/basicTypes/Demand.hs +6/−5
- compiler/basicTypes/Id.hs +1/−1
- compiler/basicTypes/IdInfo.hs +5/−3
- compiler/basicTypes/Literal.hs +5/−4
- compiler/basicTypes/MkId.hs +8/−6
- compiler/basicTypes/Module.hs +10/−10
- compiler/basicTypes/Name.hs +5/−4
- compiler/basicTypes/NameCache.hs +1/−1
- compiler/basicTypes/OccName.hs +8/−5
- compiler/basicTypes/RdrName.hs +10/−10
- compiler/basicTypes/Unique.hs +3/−3
- compiler/basicTypes/Var.hs +2/−0
- compiler/basicTypes/VarEnv.hs +8/−1
- compiler/basicTypes/VarSet.hs +1/−1
- compiler/cmm/CmmType.hs +0/−439
- compiler/coreSyn/CoreArity.hs +31/−16
- compiler/coreSyn/CoreFVs.hs +1/−1
- compiler/coreSyn/CoreOpt.hs +2/−2
- compiler/coreSyn/CoreSubst.hs +2/−1
- compiler/coreSyn/CoreSyn.hs +12/−10
- compiler/coreSyn/CoreTidy.hs +4/−3
- compiler/coreSyn/CoreUnfold.hs +9/−7
- compiler/coreSyn/CoreUtils.hs +6/−6
- compiler/coreSyn/MkCore.hs +3/−1
- compiler/coreSyn/PprCore.hs +4/−4
- compiler/iface/IfaceSyn.hs +0/−2593
- compiler/iface/IfaceType.hs +0/−2060
- compiler/iface/IfaceType.hs-boot +0/−15
- compiler/iface/ToIface.hs +0/−684
- compiler/iface/ToIface.hs-boot +0/−18
- compiler/main/DynFlags.hs +59/−47
- compiler/main/FileSettings.hs +6/−6
- compiler/main/HeaderInfo.hs +2/−1
- compiler/main/Hooks.hs +14/−0
- compiler/main/HscTypes.hs +20/−13
- compiler/main/PackageConfig.hs +0/−154
- compiler/main/PackageConfig.hs-boot +0/−7
- compiler/main/Packages.hs +236/−362
- compiler/main/Packages.hs-boot +4/−3
- compiler/main/Plugins.hs +2/−2
- compiler/main/Settings.hs +3/−3
- compiler/main/UnitInfo.hs +154/−0
- compiler/nativeGen/Reg.hs +241/−0
- compiler/nativeGen/RegClass.hs +32/−0
- compiler/parser/HaddockUtils.hs +1/−0
- compiler/parser/RdrHsSyn.hs +1/−1
- compiler/prelude/PrelNames.hs +8/−7
- compiler/prelude/PrelRules.hs +3/−3
- compiler/prelude/PrimOp.hs +3/−3
- compiler/prelude/TysPrim.hs +2/−1
- compiler/prelude/TysWiredIn.hs +6/−4
- compiler/simplCore/CoreMonad.hs +3/−1
- compiler/simplCore/OccurAnal.hs +10/−8
- compiler/specialise/Rules.hs +3/−3
- compiler/typecheck/Constraint.hs +7/−5
- compiler/typecheck/TcEvidence.hs +31/−6
- compiler/typecheck/TcOrigin.hs +6/−1
- compiler/typecheck/TcRnTypes.hs +36/−25
- compiler/typecheck/TcType.hs +6/−5
- compiler/types/Class.hs +1/−1
- compiler/types/Coercion.hs +4/−4
- compiler/types/FamInstEnv.hs +6/−4
- compiler/types/InstEnv.hs +3/−3
- compiler/types/OptCoercion.hs +1/−1
- compiler/types/TyCoFVs.hs +2/−2
- compiler/types/TyCoPpr.hs +12/−7
- compiler/types/TyCoRep.hs +3/−3
- compiler/types/TyCoSubst.hs +2/−1
- compiler/types/TyCoTidy.hs +5/−5
- compiler/types/TyCon.hs +4/−4
- compiler/types/Type.hs +7/−6
- compiler/utils/Binary.hs +2/−2
- compiler/utils/Digraph.hs +1/−1
- compiler/utils/FastString.hs +2/−2
- compiler/utils/Fingerprint.hs +1/−0
- compiler/utils/Outputable.hs +16/−2
- compiler/utils/Stream.hs +135/−0
- compiler/utils/Util.hs +8/−6
- ghc-lib-parser.cabal +33/−8
- ghc-lib/stage0/compiler/build/Lexer.hs +10/−3
- ghc-lib/stage0/compiler/build/Parser.hs +7/−7
- ghc-lib/stage0/lib/ghcautoconf.h +1/−1
- ghc-lib/stage0/lib/ghcversion.h +1/−1
- ghc-lib/stage0/lib/llvm-passes +1/−1
- ghc-lib/stage0/lib/settings +1/−1
- ghc-lib/stage0/libraries/ghc-boot/build/GHC/Version.hs +4/−4
- includes/CodeGen.Platform.hs +1/−1
- libraries/ghc-boot/GHC/PackageDb.hs +2/−2
- libraries/template-haskell/Language/Haskell/TH.hs +2/−2
- libraries/template-haskell/Language/Haskell/TH/Lib.hs +39/−39
- libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs +371/−367
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs +70/−50
+ compiler/GHC/Cmm.hs view
@@ -0,0 +1,231 @@+-- Cmm representations using Hoopl's Graph CmmNode e x.+{-# LANGUAGE GADTs #-}++module GHC.Cmm (+ -- * Cmm top-level datatypes+ CmmProgram, CmmGroup, GenCmmGroup,+ CmmDecl, GenCmmDecl(..),+ CmmGraph, GenCmmGraph(..),+ CmmBlock,+ RawCmmDecl, RawCmmGroup,+ Section(..), SectionType(..), CmmStatics(..), CmmStatic(..),+ isSecConstant,++ -- ** Blocks containing lists+ GenBasicBlock(..), blockId,+ ListGraph(..), pprBBlock,++ -- * Info Tables+ CmmTopInfo(..), CmmStackInfo(..), CmmInfoTable(..), topInfoTable,+ ClosureTypeInfo(..),+ ProfilingInfo(..), ConstrDescription,++ -- * Statements, expressions and types+ module GHC.Cmm.Node,+ module GHC.Cmm.Expr,+ ) where++import GhcPrelude++import Id+import CostCentre+import GHC.Cmm.CLabel+import GHC.Cmm.BlockId+import GHC.Cmm.Node+import GHC.Runtime.Layout+import GHC.Cmm.Expr+import GHC.Cmm.Dataflow.Block+import GHC.Cmm.Dataflow.Collections+import GHC.Cmm.Dataflow.Graph+import GHC.Cmm.Dataflow.Label+import Outputable+import Data.ByteString (ByteString)++-----------------------------------------------------------------------------+-- Cmm, GenCmm+-----------------------------------------------------------------------------++-- A CmmProgram is a list of CmmGroups+-- A CmmGroup is a list of top-level declarations++-- When object-splitting is on, each group is compiled into a separate+-- .o file. So typically we put closely related stuff in a CmmGroup.+-- Section-splitting follows suit and makes one .text subsection for each+-- CmmGroup.++type CmmProgram = [CmmGroup]++type GenCmmGroup d h g = [GenCmmDecl d h g]+type CmmGroup = GenCmmGroup CmmStatics CmmTopInfo CmmGraph+type RawCmmGroup = GenCmmGroup CmmStatics (LabelMap CmmStatics) CmmGraph++-----------------------------------------------------------------------------+-- CmmDecl, GenCmmDecl+-----------------------------------------------------------------------------++-- GenCmmDecl is abstracted over+-- d, the type of static data elements in CmmData+-- h, the static info preceding the code of a CmmProc+-- g, the control-flow graph of a CmmProc+--+-- We expect there to be two main instances of this type:+-- (a) C--, i.e. populated with various C-- constructs+-- (b) Native code, populated with data/instructions++-- | A top-level chunk, abstracted over the type of the contents of+-- the basic blocks (Cmm or instructions are the likely instantiations).+data GenCmmDecl d h g+ = CmmProc -- A procedure+ h -- Extra header such as the info table+ CLabel -- Entry label+ [GlobalReg] -- Registers live on entry. Note that the set of live+ -- registers will be correct in generated C-- code, but+ -- not in hand-written C-- code. However,+ -- splitAtProcPoints calculates correct liveness+ -- information for CmmProcs.+ g -- Control-flow graph for the procedure's code++ | CmmData -- Static data+ Section+ d++type CmmDecl = GenCmmDecl CmmStatics CmmTopInfo CmmGraph++type RawCmmDecl+ = GenCmmDecl+ CmmStatics+ (LabelMap CmmStatics)+ CmmGraph++-----------------------------------------------------------------------------+-- Graphs+-----------------------------------------------------------------------------++type CmmGraph = GenCmmGraph CmmNode+data GenCmmGraph n = CmmGraph { g_entry :: BlockId, g_graph :: Graph n C C }+type CmmBlock = Block CmmNode C C++-----------------------------------------------------------------------------+-- Info Tables+-----------------------------------------------------------------------------++-- | CmmTopInfo is attached to each CmmDecl (see defn of CmmGroup), and contains+-- the extra info (beyond the executable code) that belongs to that CmmDecl.+data CmmTopInfo = TopInfo { info_tbls :: LabelMap CmmInfoTable+ , stack_info :: CmmStackInfo }++topInfoTable :: GenCmmDecl a CmmTopInfo (GenCmmGraph n) -> Maybe CmmInfoTable+topInfoTable (CmmProc infos _ _ g) = mapLookup (g_entry g) (info_tbls infos)+topInfoTable _ = Nothing++data CmmStackInfo+ = StackInfo {+ arg_space :: ByteOff,+ -- number of bytes of arguments on the stack on entry to the+ -- the proc. This is filled in by GHC.StgToCmm.codeGen, and+ -- used by the stack allocator later.+ updfr_space :: Maybe ByteOff,+ -- XXX: this never contains anything useful, but it should.+ -- See comment in GHC.Cmm.LayoutStack.+ do_layout :: Bool+ -- Do automatic stack layout for this proc. This is+ -- True for all code generated by the code generator,+ -- but is occasionally False for hand-written Cmm where+ -- we want to do the stack manipulation manually.+ }++-- | Info table as a haskell data type+data CmmInfoTable+ = CmmInfoTable {+ cit_lbl :: CLabel, -- Info table label+ cit_rep :: SMRep,+ cit_prof :: ProfilingInfo,+ cit_srt :: Maybe CLabel, -- empty, or a closure address+ cit_clo :: Maybe (Id, CostCentreStack)+ -- Just (id,ccs) <=> build a static closure later+ -- Nothing <=> don't build a static closure+ --+ -- Static closures for FUNs and THUNKs are *not* generated by+ -- the code generator, because we might want to add SRT+ -- entries to them later (for FUNs at least; THUNKs are+ -- treated the same for consistency). See Note [SRTs] in+ -- GHC.Cmm.Info.Build, in particular the [FUN] optimisation.+ --+ -- This is strictly speaking not a part of the info table that+ -- will be finally generated, but it's the only convenient+ -- place to convey this information from the code generator to+ -- where we build the static closures in+ -- GHC.Cmm.Info.Build.doSRTs.+ }++data ProfilingInfo+ = NoProfilingInfo+ | ProfilingInfo ByteString ByteString -- closure_type, closure_desc++-----------------------------------------------------------------------------+-- Static Data+-----------------------------------------------------------------------------++data SectionType+ = Text+ | Data+ | ReadOnlyData+ | RelocatableReadOnlyData+ | UninitialisedData+ | ReadOnlyData16 -- .rodata.cst16 on x86_64, 16-byte aligned+ | CString+ | OtherSection String+ deriving (Show)++-- | Should a data in this section be considered constant+isSecConstant :: Section -> Bool+isSecConstant (Section t _) = case t of+ Text -> True+ ReadOnlyData -> True+ RelocatableReadOnlyData -> True+ ReadOnlyData16 -> True+ CString -> True+ Data -> False+ UninitialisedData -> False+ (OtherSection _) -> False++data Section = Section SectionType CLabel++data CmmStatic+ = CmmStaticLit CmmLit+ -- a literal value, size given by cmmLitRep of the literal.+ | CmmUninitialised Int+ -- uninitialised data, N bytes long+ | CmmString ByteString+ -- string of 8-bit values only, not zero terminated.++data CmmStatics+ = Statics+ CLabel -- Label of statics+ [CmmStatic] -- The static data itself++-- -----------------------------------------------------------------------------+-- Basic blocks consisting of lists++-- These are used by the LLVM and NCG backends, when populating Cmm+-- with lists of instructions.++data GenBasicBlock i = BasicBlock BlockId [i]++-- | The branch block id is that of the first block in+-- the branch, which is that branch's entry point+blockId :: GenBasicBlock i -> BlockId+blockId (BasicBlock blk_id _ ) = blk_id++newtype ListGraph i = ListGraph [GenBasicBlock i]++instance Outputable instr => Outputable (ListGraph instr) where+ ppr (ListGraph blocks) = vcat (map ppr blocks)++instance Outputable instr => Outputable (GenBasicBlock instr) where+ ppr = pprBBlock++pprBBlock :: Outputable stmt => GenBasicBlock stmt -> SDoc+pprBBlock (BasicBlock ident stmts) =+ hang (ppr ident <> colon) 4 (vcat (map ppr stmts))+
+ compiler/GHC/Cmm/BlockId.hs view
@@ -0,0 +1,46 @@+{-# LANGUAGE TypeSynonymInstances #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++{- BlockId module should probably go away completely, being superseded by Label -}+module GHC.Cmm.BlockId+ ( BlockId, mkBlockId -- ToDo: BlockId should be abstract, but it isn't yet+ , newBlockId+ , blockLbl, infoTblLbl+ ) where++import GhcPrelude++import GHC.Cmm.CLabel+import IdInfo+import Name+import Unique+import UniqSupply++import GHC.Cmm.Dataflow.Label (Label, mkHooplLabel)++----------------------------------------------------------------+--- Block Ids, their environments, and their sets++{- Note [Unique BlockId]+~~~~~~~~~~~~~~~~~~~~~~~~+Although a 'BlockId' is a local label, for reasons of implementation,+'BlockId's must be unique within an entire compilation unit. The reason+is that each local label is mapped to an assembly-language label, and in+most assembly languages allow, a label is visible throughout the entire+compilation unit in which it appears.+-}++type BlockId = Label++mkBlockId :: Unique -> BlockId+mkBlockId unique = mkHooplLabel $ getKey unique++newBlockId :: MonadUnique m => m BlockId+newBlockId = mkBlockId <$> getUniqueM++blockLbl :: BlockId -> CLabel+blockLbl label = mkLocalBlockLabel (getUnique label)++infoTblLbl :: BlockId -> CLabel+infoTblLbl label+ = mkBlockInfoTableLabel (mkFCallName (getUnique label) "block") NoCafRefs
+ compiler/GHC/Cmm/BlockId.hs-boot view
@@ -0,0 +1,8 @@+module GHC.Cmm.BlockId (BlockId, mkBlockId) where++import GHC.Cmm.Dataflow.Label (Label)+import Unique (Unique)++type BlockId = Label++mkBlockId :: Unique -> BlockId
+ compiler/GHC/Cmm/CLabel.hs view
@@ -0,0 +1,1571 @@+-----------------------------------------------------------------------------+--+-- Object-file symbols (called CLabel for histerical raisins).+--+-- (c) The University of Glasgow 2004-2006+--+-----------------------------------------------------------------------------++{-# LANGUAGE CPP #-}++module GHC.Cmm.CLabel (+ CLabel, -- abstract type+ ForeignLabelSource(..),+ pprDebugCLabel,++ mkClosureLabel,+ mkSRTLabel,+ mkInfoTableLabel,+ mkEntryLabel,+ mkRednCountsLabel,+ mkConInfoTableLabel,+ mkApEntryLabel,+ mkApInfoTableLabel,+ mkClosureTableLabel,+ mkBytesLabel,++ mkLocalBlockLabel,+ mkLocalClosureLabel,+ mkLocalInfoTableLabel,+ mkLocalClosureTableLabel,++ mkBlockInfoTableLabel,++ mkBitmapLabel,+ mkStringLitLabel,++ mkAsmTempLabel,+ mkAsmTempDerivedLabel,+ mkAsmTempEndLabel,+ mkAsmTempDieLabel,++ mkDirty_MUT_VAR_Label,+ mkNonmovingWriteBarrierEnabledLabel,+ mkUpdInfoLabel,+ mkBHUpdInfoLabel,+ mkIndStaticInfoLabel,+ mkMainCapabilityLabel,+ mkMAP_FROZEN_CLEAN_infoLabel,+ mkMAP_FROZEN_DIRTY_infoLabel,+ mkMAP_DIRTY_infoLabel,+ mkSMAP_FROZEN_CLEAN_infoLabel,+ mkSMAP_FROZEN_DIRTY_infoLabel,+ mkSMAP_DIRTY_infoLabel,+ mkBadAlignmentLabel,+ mkArrWords_infoLabel,+ mkSRTInfoLabel,++ mkTopTickyCtrLabel,+ mkCAFBlackHoleInfoTableLabel,+ mkRtsPrimOpLabel,+ mkRtsSlowFastTickyCtrLabel,++ mkSelectorInfoLabel,+ mkSelectorEntryLabel,++ mkCmmInfoLabel,+ mkCmmEntryLabel,+ mkCmmRetInfoLabel,+ mkCmmRetLabel,+ mkCmmCodeLabel,+ mkCmmDataLabel,+ mkCmmClosureLabel,++ mkRtsApFastLabel,++ mkPrimCallLabel,++ mkForeignLabel,+ addLabelSize,++ foreignLabelStdcallInfo,+ isBytesLabel,+ isForeignLabel,+ isSomeRODataLabel,+ isStaticClosureLabel,+ mkCCLabel, mkCCSLabel,++ DynamicLinkerLabelInfo(..),+ mkDynamicLinkerLabel,+ dynamicLinkerLabelInfo,++ mkPicBaseLabel,+ mkDeadStripPreventer,++ mkHpcTicksLabel,++ -- * Predicates+ hasCAF,+ needsCDecl, maybeLocalBlockLabel, externallyVisibleCLabel,+ isMathFun,+ isCFunctionLabel, isGcPtrLabel, labelDynamic,+ isLocalCLabel, mayRedirectTo,++ -- * Conversions+ toClosureLbl, toSlowEntryLbl, toEntryLbl, toInfoLbl, hasHaskellName,++ pprCLabel,+ isInfoTableLabel,+ isConInfoTableLabel+ ) where++#include "HsVersions.h"++import GhcPrelude++import IdInfo+import BasicTypes+import {-# SOURCE #-} GHC.Cmm.BlockId (BlockId, mkBlockId)+import Packages+import Module+import Name+import Unique+import PrimOp+import CostCentre+import Outputable+import FastString+import DynFlags+import GHC.Platform+import UniqSet+import Util+import PprCore ( {- instances -} )++-- -----------------------------------------------------------------------------+-- The CLabel type++{- |+ 'CLabel' is an abstract type that supports the following operations:++ - Pretty printing++ - In a C file, does it need to be declared before use? (i.e. is it+ guaranteed to be already in scope in the places we need to refer to it?)++ - If it needs to be declared, what type (code or data) should it be+ declared to have?++ - Is it visible outside this object file or not?++ - Is it "dynamic" (see details below)++ - Eq and Ord, so that we can make sets of CLabels (currently only+ used in outputting C as far as I can tell, to avoid generating+ more than one declaration for any given label).++ - Converting an info table label into an entry label.++ CLabel usage is a bit messy in GHC as they are used in a number of different+ contexts:++ - By the C-- AST to identify labels++ - By the unregisterised C code generator ("PprC") for naming functions (hence+ the name 'CLabel')++ - By the native and LLVM code generators to identify labels++ For extra fun, each of these uses a slightly different subset of constructors+ (e.g. 'AsmTempLabel' and 'AsmTempDerivedLabel' are used only in the NCG and+ LLVM backends).++ In general, we use 'IdLabel' to represent Haskell things early in the+ pipeline. However, later optimization passes will often represent blocks they+ create with 'LocalBlockLabel' where there is no obvious 'Name' to hang off the+ label.+-}++data CLabel+ = -- | A label related to the definition of a particular Id or Con in a .hs file.+ IdLabel+ Name+ CafInfo+ IdLabelInfo -- encodes the suffix of the label++ -- | A label from a .cmm file that is not associated with a .hs level Id.+ | CmmLabel+ UnitId -- what package the label belongs to.+ FastString -- identifier giving the prefix of the label+ CmmLabelInfo -- encodes the suffix of the label++ -- | A label with a baked-in \/ algorithmically generated name that definitely+ -- comes from the RTS. The code for it must compile into libHSrts.a \/ libHSrts.so+ -- If it doesn't have an algorithmically generated name then use a CmmLabel+ -- instead and give it an appropriate UnitId argument.+ | RtsLabel+ RtsLabelInfo++ -- | A label associated with a block. These aren't visible outside of the+ -- compilation unit in which they are defined. These are generally used to+ -- name blocks produced by Cmm-to-Cmm passes and the native code generator,+ -- where we don't have a 'Name' to associate the label to and therefore can't+ -- use 'IdLabel'.+ | LocalBlockLabel+ {-# UNPACK #-} !Unique++ -- | A 'C' (or otherwise foreign) label.+ --+ | ForeignLabel+ FastString -- name of the imported label.++ (Maybe Int) -- possible '@n' suffix for stdcall functions+ -- When generating C, the '@n' suffix is omitted, but when+ -- generating assembler we must add it to the label.++ ForeignLabelSource -- what package the foreign label is in.++ FunctionOrData++ -- | Local temporary label used for native (or LLVM) code generation; must not+ -- appear outside of these contexts. Use primarily for debug information+ | AsmTempLabel+ {-# UNPACK #-} !Unique++ -- | A label \"derived\" from another 'CLabel' by the addition of a suffix.+ -- Must not occur outside of the NCG or LLVM code generators.+ | AsmTempDerivedLabel+ CLabel+ FastString -- suffix++ | StringLitLabel+ {-# UNPACK #-} !Unique++ | CC_Label CostCentre+ | CCS_Label CostCentreStack+++ -- | These labels are generated and used inside the NCG only.+ -- They are special variants of a label used for dynamic linking+ -- see module PositionIndependentCode for details.+ | DynamicLinkerLabel DynamicLinkerLabelInfo CLabel++ -- | This label is generated and used inside the NCG only.+ -- It is used as a base for PIC calculations on some platforms.+ -- It takes the form of a local numeric assembler label '1'; and+ -- is pretty-printed as 1b, referring to the previous definition+ -- of 1: in the assembler source file.+ | PicBaseLabel++ -- | A label before an info table to prevent excessive dead-stripping on darwin+ | DeadStripPreventer CLabel+++ -- | Per-module table of tick locations+ | HpcTicksLabel Module++ -- | Static reference table+ | SRTLabel+ {-# UNPACK #-} !Unique++ -- | A bitmap (function or case return)+ | LargeBitmapLabel+ {-# UNPACK #-} !Unique++ deriving Eq++-- This is laborious, but necessary. We can't derive Ord because+-- Unique doesn't have an Ord instance. Note nonDetCmpUnique in the+-- implementation. See Note [No Ord for Unique]+-- This is non-deterministic but we do not currently support deterministic+-- code-generation. See Note [Unique Determinism and code generation]+instance Ord CLabel where+ compare (IdLabel a1 b1 c1) (IdLabel a2 b2 c2) =+ compare a1 a2 `thenCmp`+ compare b1 b2 `thenCmp`+ compare c1 c2+ compare (CmmLabel a1 b1 c1) (CmmLabel a2 b2 c2) =+ compare a1 a2 `thenCmp`+ compare b1 b2 `thenCmp`+ compare c1 c2+ compare (RtsLabel a1) (RtsLabel a2) = compare a1 a2+ compare (LocalBlockLabel u1) (LocalBlockLabel u2) = nonDetCmpUnique u1 u2+ compare (ForeignLabel a1 b1 c1 d1) (ForeignLabel a2 b2 c2 d2) =+ compare a1 a2 `thenCmp`+ compare b1 b2 `thenCmp`+ compare c1 c2 `thenCmp`+ compare d1 d2+ compare (AsmTempLabel u1) (AsmTempLabel u2) = nonDetCmpUnique u1 u2+ compare (AsmTempDerivedLabel a1 b1) (AsmTempDerivedLabel a2 b2) =+ compare a1 a2 `thenCmp`+ compare b1 b2+ compare (StringLitLabel u1) (StringLitLabel u2) =+ nonDetCmpUnique u1 u2+ compare (CC_Label a1) (CC_Label a2) =+ compare a1 a2+ compare (CCS_Label a1) (CCS_Label a2) =+ compare a1 a2+ compare (DynamicLinkerLabel a1 b1) (DynamicLinkerLabel a2 b2) =+ compare a1 a2 `thenCmp`+ compare b1 b2+ compare PicBaseLabel PicBaseLabel = EQ+ compare (DeadStripPreventer a1) (DeadStripPreventer a2) =+ compare a1 a2+ compare (HpcTicksLabel a1) (HpcTicksLabel a2) =+ compare a1 a2+ compare (SRTLabel u1) (SRTLabel u2) =+ nonDetCmpUnique u1 u2+ compare (LargeBitmapLabel u1) (LargeBitmapLabel u2) =+ nonDetCmpUnique u1 u2+ compare IdLabel{} _ = LT+ compare _ IdLabel{} = GT+ compare CmmLabel{} _ = LT+ compare _ CmmLabel{} = GT+ compare RtsLabel{} _ = LT+ compare _ RtsLabel{} = GT+ compare LocalBlockLabel{} _ = LT+ compare _ LocalBlockLabel{} = GT+ compare ForeignLabel{} _ = LT+ compare _ ForeignLabel{} = GT+ compare AsmTempLabel{} _ = LT+ compare _ AsmTempLabel{} = GT+ compare AsmTempDerivedLabel{} _ = LT+ compare _ AsmTempDerivedLabel{} = GT+ compare StringLitLabel{} _ = LT+ compare _ StringLitLabel{} = GT+ compare CC_Label{} _ = LT+ compare _ CC_Label{} = GT+ compare CCS_Label{} _ = LT+ compare _ CCS_Label{} = GT+ compare DynamicLinkerLabel{} _ = LT+ compare _ DynamicLinkerLabel{} = GT+ compare PicBaseLabel{} _ = LT+ compare _ PicBaseLabel{} = GT+ compare DeadStripPreventer{} _ = LT+ compare _ DeadStripPreventer{} = GT+ compare HpcTicksLabel{} _ = LT+ compare _ HpcTicksLabel{} = GT+ compare SRTLabel{} _ = LT+ compare _ SRTLabel{} = GT++-- | Record where a foreign label is stored.+data ForeignLabelSource++ -- | Label is in a named package+ = ForeignLabelInPackage UnitId++ -- | Label is in some external, system package that doesn't also+ -- contain compiled Haskell code, and is not associated with any .hi files.+ -- We don't have to worry about Haskell code being inlined from+ -- external packages. It is safe to treat the RTS package as "external".+ | ForeignLabelInExternalPackage++ -- | Label is in the package currently being compiled.+ -- This is only used for creating hacky tmp labels during code generation.+ -- Don't use it in any code that might be inlined across a package boundary+ -- (ie, core code) else the information will be wrong relative to the+ -- destination module.+ | ForeignLabelInThisPackage++ deriving (Eq, Ord)+++-- | For debugging problems with the CLabel representation.+-- We can't make a Show instance for CLabel because lots of its components don't have instances.+-- The regular Outputable instance only shows the label name, and not its other info.+--+pprDebugCLabel :: CLabel -> SDoc+pprDebugCLabel lbl+ = case lbl of+ IdLabel _ _ info-> ppr lbl <> (parens $ text "IdLabel"+ <> whenPprDebug (text ":" <> text (show info)))+ CmmLabel pkg _name _info+ -> ppr lbl <> (parens $ text "CmmLabel" <+> ppr pkg)++ RtsLabel{} -> ppr lbl <> (parens $ text "RtsLabel")++ ForeignLabel _name mSuffix src funOrData+ -> ppr lbl <> (parens $ text "ForeignLabel"+ <+> ppr mSuffix+ <+> ppr src+ <+> ppr funOrData)++ _ -> ppr lbl <> (parens $ text "other CLabel")+++data IdLabelInfo+ = Closure -- ^ Label for closure+ | InfoTable -- ^ Info tables for closures; always read-only+ | Entry -- ^ Entry point+ | Slow -- ^ Slow entry point++ | LocalInfoTable -- ^ Like InfoTable but not externally visible+ | LocalEntry -- ^ Like Entry but not externally visible++ | RednCounts -- ^ Label of place to keep Ticky-ticky info for this Id++ | ConEntry -- ^ Constructor entry point+ | ConInfoTable -- ^ Corresponding info table++ | ClosureTable -- ^ Table of closures for Enum tycons++ | Bytes -- ^ Content of a string literal. See+ -- Note [Bytes label].+ | BlockInfoTable -- ^ Like LocalInfoTable but for a proc-point block+ -- instead of a closure entry-point.+ -- See Note [Proc-point local block entry-point].++ deriving (Eq, Ord, Show)+++data RtsLabelInfo+ = RtsSelectorInfoTable Bool{-updatable-} Int{-offset-} -- ^ Selector thunks+ | RtsSelectorEntry Bool{-updatable-} Int{-offset-}++ | RtsApInfoTable Bool{-updatable-} Int{-arity-} -- ^ AP thunks+ | RtsApEntry Bool{-updatable-} Int{-arity-}++ | RtsPrimOp PrimOp+ | RtsApFast FastString -- ^ _fast versions of generic apply+ | RtsSlowFastTickyCtr String++ deriving (Eq, Ord)+ -- NOTE: Eq on PtrString compares the pointer only, so this isn't+ -- a real equality.+++-- | What type of Cmm label we're dealing with.+-- Determines the suffix appended to the name when a CLabel.CmmLabel+-- is pretty printed.+data CmmLabelInfo+ = CmmInfo -- ^ misc rts info tables, suffix _info+ | CmmEntry -- ^ misc rts entry points, suffix _entry+ | CmmRetInfo -- ^ misc rts ret info tables, suffix _info+ | CmmRet -- ^ misc rts return points, suffix _ret+ | CmmData -- ^ misc rts data bits, eg CHARLIKE_closure+ | CmmCode -- ^ misc rts code+ | CmmClosure -- ^ closures eg CHARLIKE_closure+ | CmmPrimCall -- ^ a prim call to some hand written Cmm code+ deriving (Eq, Ord)++data DynamicLinkerLabelInfo+ = CodeStub -- MachO: Lfoo$stub, ELF: foo@plt+ | SymbolPtr -- MachO: Lfoo$non_lazy_ptr, Windows: __imp_foo+ | GotSymbolPtr -- ELF: foo@got+ | GotSymbolOffset -- ELF: foo@gotoff++ deriving (Eq, Ord)+++-- -----------------------------------------------------------------------------+-- Constructing CLabels+-- -----------------------------------------------------------------------------++-- Constructing IdLabels+-- These are always local:++mkSRTLabel :: Unique -> CLabel+mkSRTLabel u = SRTLabel u++mkRednCountsLabel :: Name -> CLabel+mkRednCountsLabel name =+ IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE]++-- These have local & (possibly) external variants:+mkLocalClosureLabel :: Name -> CafInfo -> CLabel+mkLocalInfoTableLabel :: Name -> CafInfo -> CLabel+mkLocalClosureTableLabel :: Name -> CafInfo -> CLabel+mkLocalClosureLabel name c = IdLabel name c Closure+mkLocalInfoTableLabel name c = IdLabel name c LocalInfoTable+mkLocalClosureTableLabel name c = IdLabel name c ClosureTable++mkClosureLabel :: Name -> CafInfo -> CLabel+mkInfoTableLabel :: Name -> CafInfo -> CLabel+mkEntryLabel :: Name -> CafInfo -> CLabel+mkClosureTableLabel :: Name -> CafInfo -> CLabel+mkConInfoTableLabel :: Name -> CafInfo -> CLabel+mkBytesLabel :: Name -> CLabel+mkClosureLabel name c = IdLabel name c Closure+mkInfoTableLabel name c = IdLabel name c InfoTable+mkEntryLabel name c = IdLabel name c Entry+mkClosureTableLabel name c = IdLabel name c ClosureTable+mkConInfoTableLabel name c = IdLabel name c ConInfoTable+mkBytesLabel name = IdLabel name NoCafRefs Bytes++mkBlockInfoTableLabel :: Name -> CafInfo -> CLabel+mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable+ -- See Note [Proc-point local block entry-point].++-- Constructing Cmm Labels+mkDirty_MUT_VAR_Label,+ mkNonmovingWriteBarrierEnabledLabel,+ mkUpdInfoLabel,+ mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel,+ mkMAP_FROZEN_CLEAN_infoLabel, mkMAP_FROZEN_DIRTY_infoLabel,+ mkMAP_DIRTY_infoLabel,+ mkArrWords_infoLabel,+ mkTopTickyCtrLabel,+ mkCAFBlackHoleInfoTableLabel,+ mkSMAP_FROZEN_CLEAN_infoLabel, mkSMAP_FROZEN_DIRTY_infoLabel,+ mkSMAP_DIRTY_infoLabel, mkBadAlignmentLabel :: CLabel+mkDirty_MUT_VAR_Label = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction+mkNonmovingWriteBarrierEnabledLabel+ = CmmLabel rtsUnitId (fsLit "nonmoving_write_barrier_enabled") CmmData+mkUpdInfoLabel = CmmLabel rtsUnitId (fsLit "stg_upd_frame") CmmInfo+mkBHUpdInfoLabel = CmmLabel rtsUnitId (fsLit "stg_bh_upd_frame" ) CmmInfo+mkIndStaticInfoLabel = CmmLabel rtsUnitId (fsLit "stg_IND_STATIC") CmmInfo+mkMainCapabilityLabel = CmmLabel rtsUnitId (fsLit "MainCapability") CmmData+mkMAP_FROZEN_CLEAN_infoLabel = CmmLabel rtsUnitId (fsLit "stg_MUT_ARR_PTRS_FROZEN_CLEAN") CmmInfo+mkMAP_FROZEN_DIRTY_infoLabel = CmmLabel rtsUnitId (fsLit "stg_MUT_ARR_PTRS_FROZEN_DIRTY") CmmInfo+mkMAP_DIRTY_infoLabel = CmmLabel rtsUnitId (fsLit "stg_MUT_ARR_PTRS_DIRTY") CmmInfo+mkTopTickyCtrLabel = CmmLabel rtsUnitId (fsLit "top_ct") CmmData+mkCAFBlackHoleInfoTableLabel = CmmLabel rtsUnitId (fsLit "stg_CAF_BLACKHOLE") CmmInfo+mkArrWords_infoLabel = CmmLabel rtsUnitId (fsLit "stg_ARR_WORDS") CmmInfo+mkSMAP_FROZEN_CLEAN_infoLabel = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN_CLEAN") CmmInfo+mkSMAP_FROZEN_DIRTY_infoLabel = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN_DIRTY") CmmInfo+mkSMAP_DIRTY_infoLabel = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_DIRTY") CmmInfo+mkBadAlignmentLabel = CmmLabel rtsUnitId (fsLit "stg_badAlignment") CmmEntry++mkSRTInfoLabel :: Int -> CLabel+mkSRTInfoLabel n = CmmLabel rtsUnitId lbl CmmInfo+ where+ lbl =+ case n of+ 1 -> fsLit "stg_SRT_1"+ 2 -> fsLit "stg_SRT_2"+ 3 -> fsLit "stg_SRT_3"+ 4 -> fsLit "stg_SRT_4"+ 5 -> fsLit "stg_SRT_5"+ 6 -> fsLit "stg_SRT_6"+ 7 -> fsLit "stg_SRT_7"+ 8 -> fsLit "stg_SRT_8"+ 9 -> fsLit "stg_SRT_9"+ 10 -> fsLit "stg_SRT_10"+ 11 -> fsLit "stg_SRT_11"+ 12 -> fsLit "stg_SRT_12"+ 13 -> fsLit "stg_SRT_13"+ 14 -> fsLit "stg_SRT_14"+ 15 -> fsLit "stg_SRT_15"+ 16 -> fsLit "stg_SRT_16"+ _ -> panic "mkSRTInfoLabel"++-----+mkCmmInfoLabel, mkCmmEntryLabel, mkCmmRetInfoLabel, mkCmmRetLabel,+ mkCmmCodeLabel, mkCmmDataLabel, mkCmmClosureLabel+ :: UnitId -> FastString -> CLabel++mkCmmInfoLabel pkg str = CmmLabel pkg str CmmInfo+mkCmmEntryLabel pkg str = CmmLabel pkg str CmmEntry+mkCmmRetInfoLabel pkg str = CmmLabel pkg str CmmRetInfo+mkCmmRetLabel pkg str = CmmLabel pkg str CmmRet+mkCmmCodeLabel pkg str = CmmLabel pkg str CmmCode+mkCmmDataLabel pkg str = CmmLabel pkg str CmmData+mkCmmClosureLabel pkg str = CmmLabel pkg str CmmClosure++mkLocalBlockLabel :: Unique -> CLabel+mkLocalBlockLabel u = LocalBlockLabel u++-- Constructing RtsLabels+mkRtsPrimOpLabel :: PrimOp -> CLabel+mkRtsPrimOpLabel primop = RtsLabel (RtsPrimOp primop)++mkSelectorInfoLabel :: Bool -> Int -> CLabel+mkSelectorEntryLabel :: Bool -> Int -> CLabel+mkSelectorInfoLabel upd off = RtsLabel (RtsSelectorInfoTable upd off)+mkSelectorEntryLabel upd off = RtsLabel (RtsSelectorEntry upd off)++mkApInfoTableLabel :: Bool -> Int -> CLabel+mkApEntryLabel :: Bool -> Int -> CLabel+mkApInfoTableLabel upd off = RtsLabel (RtsApInfoTable upd off)+mkApEntryLabel upd off = RtsLabel (RtsApEntry upd off)+++-- A call to some primitive hand written Cmm code+mkPrimCallLabel :: PrimCall -> CLabel+mkPrimCallLabel (PrimCall str pkg)+ = CmmLabel pkg str CmmPrimCall+++-- Constructing ForeignLabels++-- | Make a foreign label+mkForeignLabel+ :: FastString -- name+ -> Maybe Int -- size prefix+ -> ForeignLabelSource -- what package it's in+ -> FunctionOrData+ -> CLabel++mkForeignLabel = ForeignLabel+++-- | Update the label size field in a ForeignLabel+addLabelSize :: CLabel -> Int -> CLabel+addLabelSize (ForeignLabel str _ src fod) sz+ = ForeignLabel str (Just sz) src fod+addLabelSize label _+ = label++-- | Whether label is a top-level string literal+isBytesLabel :: CLabel -> Bool+isBytesLabel (IdLabel _ _ Bytes) = True+isBytesLabel _lbl = False++-- | Whether label is a non-haskell label (defined in C code)+isForeignLabel :: CLabel -> Bool+isForeignLabel (ForeignLabel _ _ _ _) = True+isForeignLabel _lbl = False++-- | Whether label is a static closure label (can come from haskell or cmm)+isStaticClosureLabel :: CLabel -> Bool+-- Closure defined in haskell (.hs)+isStaticClosureLabel (IdLabel _ _ Closure) = True+-- Closure defined in cmm+isStaticClosureLabel (CmmLabel _ _ CmmClosure) = True+isStaticClosureLabel _lbl = False++-- | Whether label is a .rodata label+isSomeRODataLabel :: CLabel -> Bool+-- info table defined in haskell (.hs)+isSomeRODataLabel (IdLabel _ _ ClosureTable) = True+isSomeRODataLabel (IdLabel _ _ ConInfoTable) = True+isSomeRODataLabel (IdLabel _ _ InfoTable) = True+isSomeRODataLabel (IdLabel _ _ LocalInfoTable) = True+isSomeRODataLabel (IdLabel _ _ BlockInfoTable) = True+-- info table defined in cmm (.cmm)+isSomeRODataLabel (CmmLabel _ _ CmmInfo) = True+isSomeRODataLabel _lbl = False++-- | Whether label is points to some kind of info table+isInfoTableLabel :: CLabel -> Bool+isInfoTableLabel (IdLabel _ _ InfoTable) = True+isInfoTableLabel (IdLabel _ _ LocalInfoTable) = True+isInfoTableLabel (IdLabel _ _ ConInfoTable) = True+isInfoTableLabel (IdLabel _ _ BlockInfoTable) = True+isInfoTableLabel _ = False++-- | Whether label is points to constructor info table+isConInfoTableLabel :: CLabel -> Bool+isConInfoTableLabel (IdLabel _ _ ConInfoTable) = True+isConInfoTableLabel _ = False++-- | Get the label size field from a ForeignLabel+foreignLabelStdcallInfo :: CLabel -> Maybe Int+foreignLabelStdcallInfo (ForeignLabel _ info _ _) = info+foreignLabelStdcallInfo _lbl = Nothing+++-- Constructing Large*Labels+mkBitmapLabel :: Unique -> CLabel+mkBitmapLabel uniq = LargeBitmapLabel uniq++-- Constructing Cost Center Labels+mkCCLabel :: CostCentre -> CLabel+mkCCSLabel :: CostCentreStack -> CLabel+mkCCLabel cc = CC_Label cc+mkCCSLabel ccs = CCS_Label ccs++mkRtsApFastLabel :: FastString -> CLabel+mkRtsApFastLabel str = RtsLabel (RtsApFast str)++mkRtsSlowFastTickyCtrLabel :: String -> CLabel+mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat)+++-- Constructing Code Coverage Labels+mkHpcTicksLabel :: Module -> CLabel+mkHpcTicksLabel = HpcTicksLabel+++-- Constructing labels used for dynamic linking+mkDynamicLinkerLabel :: DynamicLinkerLabelInfo -> CLabel -> CLabel+mkDynamicLinkerLabel = DynamicLinkerLabel++dynamicLinkerLabelInfo :: CLabel -> Maybe (DynamicLinkerLabelInfo, CLabel)+dynamicLinkerLabelInfo (DynamicLinkerLabel info lbl) = Just (info, lbl)+dynamicLinkerLabelInfo _ = Nothing++mkPicBaseLabel :: CLabel+mkPicBaseLabel = PicBaseLabel+++-- Constructing miscellaneous other labels+mkDeadStripPreventer :: CLabel -> CLabel+mkDeadStripPreventer lbl = DeadStripPreventer lbl++mkStringLitLabel :: Unique -> CLabel+mkStringLitLabel = StringLitLabel++mkAsmTempLabel :: Uniquable a => a -> CLabel+mkAsmTempLabel a = AsmTempLabel (getUnique a)++mkAsmTempDerivedLabel :: CLabel -> FastString -> CLabel+mkAsmTempDerivedLabel = AsmTempDerivedLabel++mkAsmTempEndLabel :: CLabel -> CLabel+mkAsmTempEndLabel l = mkAsmTempDerivedLabel l (fsLit "_end")++-- | Construct a label for a DWARF Debug Information Entity (DIE)+-- describing another symbol.+mkAsmTempDieLabel :: CLabel -> CLabel+mkAsmTempDieLabel l = mkAsmTempDerivedLabel l (fsLit "_die")++-- -----------------------------------------------------------------------------+-- Convert between different kinds of label++toClosureLbl :: CLabel -> CLabel+toClosureLbl (IdLabel n c _) = IdLabel n c Closure+toClosureLbl (CmmLabel m str _) = CmmLabel m str CmmClosure+toClosureLbl l = pprPanic "toClosureLbl" (ppr l)++toSlowEntryLbl :: CLabel -> CLabel+toSlowEntryLbl (IdLabel n _ BlockInfoTable)+ = pprPanic "toSlowEntryLbl" (ppr n)+toSlowEntryLbl (IdLabel n c _) = IdLabel n c Slow+toSlowEntryLbl l = pprPanic "toSlowEntryLbl" (ppr l)++toEntryLbl :: CLabel -> CLabel+toEntryLbl (IdLabel n c LocalInfoTable) = IdLabel n c LocalEntry+toEntryLbl (IdLabel n c ConInfoTable) = IdLabel n c ConEntry+toEntryLbl (IdLabel n _ BlockInfoTable) = mkLocalBlockLabel (nameUnique n)+ -- See Note [Proc-point local block entry-point].+toEntryLbl (IdLabel n c _) = IdLabel n c Entry+toEntryLbl (CmmLabel m str CmmInfo) = CmmLabel m str CmmEntry+toEntryLbl (CmmLabel m str CmmRetInfo) = CmmLabel m str CmmRet+toEntryLbl l = pprPanic "toEntryLbl" (ppr l)++toInfoLbl :: CLabel -> CLabel+toInfoLbl (IdLabel n c LocalEntry) = IdLabel n c LocalInfoTable+toInfoLbl (IdLabel n c ConEntry) = IdLabel n c ConInfoTable+toInfoLbl (IdLabel n c _) = IdLabel n c InfoTable+toInfoLbl (CmmLabel m str CmmEntry) = CmmLabel m str CmmInfo+toInfoLbl (CmmLabel m str CmmRet) = CmmLabel m str CmmRetInfo+toInfoLbl l = pprPanic "CLabel.toInfoLbl" (ppr l)++hasHaskellName :: CLabel -> Maybe Name+hasHaskellName (IdLabel n _ _) = Just n+hasHaskellName _ = Nothing++-- -----------------------------------------------------------------------------+-- Does a CLabel's referent itself refer to a CAF?+hasCAF :: CLabel -> Bool+hasCAF (IdLabel _ _ RednCounts) = False -- Note [ticky for LNE]+hasCAF (IdLabel _ MayHaveCafRefs _) = True+hasCAF _ = False++-- Note [ticky for LNE]+-- ~~~~~~~~~~~~~~~~~~~~~++-- Until 14 Feb 2013, every ticky counter was associated with a+-- closure. Thus, ticky labels used IdLabel. It is odd that+-- GHC.Cmm.Info.Build.cafTransfers would consider such a ticky label+-- reason to add the name to the CAFEnv (and thus eventually the SRT),+-- but it was harmless because the ticky was only used if the closure+-- was also.+--+-- Since we now have ticky counters for LNEs, it is no longer the case+-- that every ticky counter has an actual closure. So I changed the+-- generation of ticky counters' CLabels to not result in their+-- associated id ending up in the SRT.+--+-- NB IdLabel is still appropriate for ticky ids (as opposed to+-- CmmLabel) because the LNE's counter is still related to an .hs Id,+-- that Id just isn't for a proper closure.++-- -----------------------------------------------------------------------------+-- Does a CLabel need declaring before use or not?+--+-- See wiki:commentary/compiler/backends/ppr-c#prototypes++needsCDecl :: CLabel -> Bool+ -- False <=> it's pre-declared; don't bother+ -- don't bother declaring Bitmap labels, we always make sure+ -- they are defined before use.+needsCDecl (SRTLabel _) = True+needsCDecl (LargeBitmapLabel _) = False+needsCDecl (IdLabel _ _ _) = True+needsCDecl (LocalBlockLabel _) = True++needsCDecl (StringLitLabel _) = False+needsCDecl (AsmTempLabel _) = False+needsCDecl (AsmTempDerivedLabel _ _) = False+needsCDecl (RtsLabel _) = False++needsCDecl (CmmLabel pkgId _ _)+ -- Prototypes for labels defined in the runtime system are imported+ -- into HC files via includes/Stg.h.+ | pkgId == rtsUnitId = False++ -- For other labels we inline one into the HC file directly.+ | otherwise = True++needsCDecl l@(ForeignLabel{}) = not (isMathFun l)+needsCDecl (CC_Label _) = True+needsCDecl (CCS_Label _) = True+needsCDecl (HpcTicksLabel _) = True+needsCDecl (DynamicLinkerLabel {}) = panic "needsCDecl DynamicLinkerLabel"+needsCDecl PicBaseLabel = panic "needsCDecl PicBaseLabel"+needsCDecl (DeadStripPreventer {}) = panic "needsCDecl DeadStripPreventer"++-- | If a label is a local block label then return just its 'BlockId', otherwise+-- 'Nothing'.+maybeLocalBlockLabel :: CLabel -> Maybe BlockId+maybeLocalBlockLabel (LocalBlockLabel uq) = Just $ mkBlockId uq+maybeLocalBlockLabel _ = Nothing+++-- | Check whether a label corresponds to a C function that has+-- a prototype in a system header somewhere, or is built-in+-- to the C compiler. For these labels we avoid generating our+-- own C prototypes.+isMathFun :: CLabel -> Bool+isMathFun (ForeignLabel fs _ _ _) = fs `elementOfUniqSet` math_funs+isMathFun _ = False++math_funs :: UniqSet FastString+math_funs = mkUniqSet [+ -- _ISOC99_SOURCE+ (fsLit "acos"), (fsLit "acosf"), (fsLit "acosh"),+ (fsLit "acoshf"), (fsLit "acoshl"), (fsLit "acosl"),+ (fsLit "asin"), (fsLit "asinf"), (fsLit "asinl"),+ (fsLit "asinh"), (fsLit "asinhf"), (fsLit "asinhl"),+ (fsLit "atan"), (fsLit "atanf"), (fsLit "atanl"),+ (fsLit "atan2"), (fsLit "atan2f"), (fsLit "atan2l"),+ (fsLit "atanh"), (fsLit "atanhf"), (fsLit "atanhl"),+ (fsLit "cbrt"), (fsLit "cbrtf"), (fsLit "cbrtl"),+ (fsLit "ceil"), (fsLit "ceilf"), (fsLit "ceill"),+ (fsLit "copysign"), (fsLit "copysignf"), (fsLit "copysignl"),+ (fsLit "cos"), (fsLit "cosf"), (fsLit "cosl"),+ (fsLit "cosh"), (fsLit "coshf"), (fsLit "coshl"),+ (fsLit "erf"), (fsLit "erff"), (fsLit "erfl"),+ (fsLit "erfc"), (fsLit "erfcf"), (fsLit "erfcl"),+ (fsLit "exp"), (fsLit "expf"), (fsLit "expl"),+ (fsLit "exp2"), (fsLit "exp2f"), (fsLit "exp2l"),+ (fsLit "expm1"), (fsLit "expm1f"), (fsLit "expm1l"),+ (fsLit "fabs"), (fsLit "fabsf"), (fsLit "fabsl"),+ (fsLit "fdim"), (fsLit "fdimf"), (fsLit "fdiml"),+ (fsLit "floor"), (fsLit "floorf"), (fsLit "floorl"),+ (fsLit "fma"), (fsLit "fmaf"), (fsLit "fmal"),+ (fsLit "fmax"), (fsLit "fmaxf"), (fsLit "fmaxl"),+ (fsLit "fmin"), (fsLit "fminf"), (fsLit "fminl"),+ (fsLit "fmod"), (fsLit "fmodf"), (fsLit "fmodl"),+ (fsLit "frexp"), (fsLit "frexpf"), (fsLit "frexpl"),+ (fsLit "hypot"), (fsLit "hypotf"), (fsLit "hypotl"),+ (fsLit "ilogb"), (fsLit "ilogbf"), (fsLit "ilogbl"),+ (fsLit "ldexp"), (fsLit "ldexpf"), (fsLit "ldexpl"),+ (fsLit "lgamma"), (fsLit "lgammaf"), (fsLit "lgammal"),+ (fsLit "llrint"), (fsLit "llrintf"), (fsLit "llrintl"),+ (fsLit "llround"), (fsLit "llroundf"), (fsLit "llroundl"),+ (fsLit "log"), (fsLit "logf"), (fsLit "logl"),+ (fsLit "log10l"), (fsLit "log10"), (fsLit "log10f"),+ (fsLit "log1pl"), (fsLit "log1p"), (fsLit "log1pf"),+ (fsLit "log2"), (fsLit "log2f"), (fsLit "log2l"),+ (fsLit "logb"), (fsLit "logbf"), (fsLit "logbl"),+ (fsLit "lrint"), (fsLit "lrintf"), (fsLit "lrintl"),+ (fsLit "lround"), (fsLit "lroundf"), (fsLit "lroundl"),+ (fsLit "modf"), (fsLit "modff"), (fsLit "modfl"),+ (fsLit "nan"), (fsLit "nanf"), (fsLit "nanl"),+ (fsLit "nearbyint"), (fsLit "nearbyintf"), (fsLit "nearbyintl"),+ (fsLit "nextafter"), (fsLit "nextafterf"), (fsLit "nextafterl"),+ (fsLit "nexttoward"), (fsLit "nexttowardf"), (fsLit "nexttowardl"),+ (fsLit "pow"), (fsLit "powf"), (fsLit "powl"),+ (fsLit "remainder"), (fsLit "remainderf"), (fsLit "remainderl"),+ (fsLit "remquo"), (fsLit "remquof"), (fsLit "remquol"),+ (fsLit "rint"), (fsLit "rintf"), (fsLit "rintl"),+ (fsLit "round"), (fsLit "roundf"), (fsLit "roundl"),+ (fsLit "scalbln"), (fsLit "scalblnf"), (fsLit "scalblnl"),+ (fsLit "scalbn"), (fsLit "scalbnf"), (fsLit "scalbnl"),+ (fsLit "sin"), (fsLit "sinf"), (fsLit "sinl"),+ (fsLit "sinh"), (fsLit "sinhf"), (fsLit "sinhl"),+ (fsLit "sqrt"), (fsLit "sqrtf"), (fsLit "sqrtl"),+ (fsLit "tan"), (fsLit "tanf"), (fsLit "tanl"),+ (fsLit "tanh"), (fsLit "tanhf"), (fsLit "tanhl"),+ (fsLit "tgamma"), (fsLit "tgammaf"), (fsLit "tgammal"),+ (fsLit "trunc"), (fsLit "truncf"), (fsLit "truncl"),+ -- ISO C 99 also defines these function-like macros in math.h:+ -- fpclassify, isfinite, isinf, isnormal, signbit, isgreater,+ -- isgreaterequal, isless, islessequal, islessgreater, isunordered++ -- additional symbols from _BSD_SOURCE+ (fsLit "drem"), (fsLit "dremf"), (fsLit "dreml"),+ (fsLit "finite"), (fsLit "finitef"), (fsLit "finitel"),+ (fsLit "gamma"), (fsLit "gammaf"), (fsLit "gammal"),+ (fsLit "isinf"), (fsLit "isinff"), (fsLit "isinfl"),+ (fsLit "isnan"), (fsLit "isnanf"), (fsLit "isnanl"),+ (fsLit "j0"), (fsLit "j0f"), (fsLit "j0l"),+ (fsLit "j1"), (fsLit "j1f"), (fsLit "j1l"),+ (fsLit "jn"), (fsLit "jnf"), (fsLit "jnl"),+ (fsLit "lgamma_r"), (fsLit "lgammaf_r"), (fsLit "lgammal_r"),+ (fsLit "scalb"), (fsLit "scalbf"), (fsLit "scalbl"),+ (fsLit "significand"), (fsLit "significandf"), (fsLit "significandl"),+ (fsLit "y0"), (fsLit "y0f"), (fsLit "y0l"),+ (fsLit "y1"), (fsLit "y1f"), (fsLit "y1l"),+ (fsLit "yn"), (fsLit "ynf"), (fsLit "ynl"),++ -- These functions are described in IEEE Std 754-2008 -+ -- Standard for Floating-Point Arithmetic and ISO/IEC TS 18661+ (fsLit "nextup"), (fsLit "nextupf"), (fsLit "nextupl"),+ (fsLit "nextdown"), (fsLit "nextdownf"), (fsLit "nextdownl")+ ]++-- -----------------------------------------------------------------------------+-- | Is a CLabel visible outside this object file or not?+-- From the point of view of the code generator, a name is+-- externally visible if it has to be declared as exported+-- in the .o file's symbol table; that is, made non-static.+externallyVisibleCLabel :: CLabel -> Bool -- not C "static"+externallyVisibleCLabel (StringLitLabel _) = False+externallyVisibleCLabel (AsmTempLabel _) = False+externallyVisibleCLabel (AsmTempDerivedLabel _ _)= False+externallyVisibleCLabel (RtsLabel _) = True+externallyVisibleCLabel (LocalBlockLabel _) = False+externallyVisibleCLabel (CmmLabel _ _ _) = True+externallyVisibleCLabel (ForeignLabel{}) = True+externallyVisibleCLabel (IdLabel name _ info) = isExternalName name && externallyVisibleIdLabel info+externallyVisibleCLabel (CC_Label _) = True+externallyVisibleCLabel (CCS_Label _) = True+externallyVisibleCLabel (DynamicLinkerLabel _ _) = False+externallyVisibleCLabel (HpcTicksLabel _) = True+externallyVisibleCLabel (LargeBitmapLabel _) = False+externallyVisibleCLabel (SRTLabel _) = False+externallyVisibleCLabel (PicBaseLabel {}) = panic "externallyVisibleCLabel PicBaseLabel"+externallyVisibleCLabel (DeadStripPreventer {}) = panic "externallyVisibleCLabel DeadStripPreventer"++externallyVisibleIdLabel :: IdLabelInfo -> Bool+externallyVisibleIdLabel LocalInfoTable = False+externallyVisibleIdLabel LocalEntry = False+externallyVisibleIdLabel BlockInfoTable = False+externallyVisibleIdLabel _ = True++-- -----------------------------------------------------------------------------+-- Finding the "type" of a CLabel++-- For generating correct types in label declarations:++data CLabelType+ = CodeLabel -- Address of some executable instructions+ | DataLabel -- Address of data, not a GC ptr+ | GcPtrLabel -- Address of a (presumably static) GC object++isCFunctionLabel :: CLabel -> Bool+isCFunctionLabel lbl = case labelType lbl of+ CodeLabel -> True+ _other -> False++isGcPtrLabel :: CLabel -> Bool+isGcPtrLabel lbl = case labelType lbl of+ GcPtrLabel -> True+ _other -> False+++-- | Work out the general type of data at the address of this label+-- whether it be code, data, or static GC object.+labelType :: CLabel -> CLabelType+labelType (IdLabel _ _ info) = idInfoLabelType info+labelType (CmmLabel _ _ CmmData) = DataLabel+labelType (CmmLabel _ _ CmmClosure) = GcPtrLabel+labelType (CmmLabel _ _ CmmCode) = CodeLabel+labelType (CmmLabel _ _ CmmInfo) = DataLabel+labelType (CmmLabel _ _ CmmEntry) = CodeLabel+labelType (CmmLabel _ _ CmmPrimCall) = CodeLabel+labelType (CmmLabel _ _ CmmRetInfo) = DataLabel+labelType (CmmLabel _ _ CmmRet) = CodeLabel+labelType (RtsLabel (RtsSelectorInfoTable _ _)) = DataLabel+labelType (RtsLabel (RtsApInfoTable _ _)) = DataLabel+labelType (RtsLabel (RtsApFast _)) = CodeLabel+labelType (RtsLabel _) = DataLabel+labelType (LocalBlockLabel _) = CodeLabel+labelType (SRTLabel _) = DataLabel+labelType (ForeignLabel _ _ _ IsFunction) = CodeLabel+labelType (ForeignLabel _ _ _ IsData) = DataLabel+labelType (AsmTempLabel _) = panic "labelType(AsmTempLabel)"+labelType (AsmTempDerivedLabel _ _) = panic "labelType(AsmTempDerivedLabel)"+labelType (StringLitLabel _) = DataLabel+labelType (CC_Label _) = DataLabel+labelType (CCS_Label _) = DataLabel+labelType (DynamicLinkerLabel _ _) = DataLabel -- Is this right?+labelType PicBaseLabel = DataLabel+labelType (DeadStripPreventer _) = DataLabel+labelType (HpcTicksLabel _) = DataLabel+labelType (LargeBitmapLabel _) = DataLabel++idInfoLabelType :: IdLabelInfo -> CLabelType+idInfoLabelType info =+ case info of+ InfoTable -> DataLabel+ LocalInfoTable -> DataLabel+ BlockInfoTable -> DataLabel+ Closure -> GcPtrLabel+ ConInfoTable -> DataLabel+ ClosureTable -> DataLabel+ RednCounts -> DataLabel+ Bytes -> DataLabel+ _ -> CodeLabel+++-- -----------------------------------------------------------------------------++-- | Is a 'CLabel' defined in the current module being compiled?+--+-- Sometimes we can optimise references within a compilation unit in ways that+-- we couldn't for inter-module references. This provides a conservative+-- estimate of whether a 'CLabel' lives in the current module.+isLocalCLabel :: Module -> CLabel -> Bool+isLocalCLabel this_mod lbl =+ case lbl of+ IdLabel name _ _+ | isInternalName name -> True+ | otherwise -> nameModule name == this_mod+ LocalBlockLabel _ -> True+ _ -> False++-- -----------------------------------------------------------------------------++-- | Does a 'CLabel' need dynamic linkage?+--+-- When referring to data in code, we need to know whether+-- that data resides in a DLL or not. [Win32 only.]+-- @labelDynamic@ returns @True@ if the label is located+-- in a DLL, be it a data reference or not.+labelDynamic :: DynFlags -> Module -> CLabel -> Bool+labelDynamic dflags this_mod lbl =+ case lbl of+ -- is the RTS in a DLL or not?+ RtsLabel _ ->+ externalDynamicRefs && (this_pkg /= rtsUnitId)++ IdLabel n _ _ ->+ isDllName dflags this_mod n++ -- When compiling in the "dyn" way, each package is to be linked into+ -- its own shared library.+ CmmLabel pkg _ _+ | os == OSMinGW32 ->+ externalDynamicRefs && (this_pkg /= pkg)+ | otherwise ->+ gopt Opt_ExternalDynamicRefs dflags++ LocalBlockLabel _ -> False++ ForeignLabel _ _ source _ ->+ if os == OSMinGW32+ then case source of+ -- Foreign label is in some un-named foreign package (or DLL).+ ForeignLabelInExternalPackage -> True++ -- Foreign label is linked into the same package as the+ -- source file currently being compiled.+ ForeignLabelInThisPackage -> False++ -- Foreign label is in some named package.+ -- When compiling in the "dyn" way, each package is to be+ -- linked into its own DLL.+ ForeignLabelInPackage pkgId ->+ externalDynamicRefs && (this_pkg /= pkgId)++ else -- On Mac OS X and on ELF platforms, false positives are OK,+ -- so we claim that all foreign imports come from dynamic+ -- libraries+ True++ CC_Label cc ->+ externalDynamicRefs && not (ccFromThisModule cc this_mod)++ -- CCS_Label always contains a CostCentre defined in the current module+ CCS_Label _ -> False++ HpcTicksLabel m ->+ externalDynamicRefs && this_mod /= m++ -- Note that DynamicLinkerLabels do NOT require dynamic linking themselves.+ _ -> False+ where+ externalDynamicRefs = gopt Opt_ExternalDynamicRefs dflags+ os = platformOS (targetPlatform dflags)+ this_pkg = moduleUnitId this_mod+++-----------------------------------------------------------------------------+-- Printing out CLabels.++{-+Convention:++ <name>_<type>++where <name> is <Module>_<name> for external names and <unique> for+internal names. <type> is one of the following:++ info Info table+ srt Static reference table+ entry Entry code (function, closure)+ slow Slow entry code (if any)+ ret Direct return address+ vtbl Vector table+ <n>_alt Case alternative (tag n)+ dflt Default case alternative+ btm Large bitmap vector+ closure Static closure+ con_entry Dynamic Constructor entry code+ con_info Dynamic Constructor info table+ static_entry Static Constructor entry code+ static_info Static Constructor info table+ sel_info Selector info table+ sel_entry Selector entry code+ cc Cost centre+ ccs Cost centre stack++Many of these distinctions are only for documentation reasons. For+example, _ret is only distinguished from _entry to make it easy to+tell whether a code fragment is a return point or a closure/function+entry.++Note [Closure and info labels]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+For a function 'foo, we have:+ foo_info : Points to the info table describing foo's closure+ (and entry code for foo with tables next to code)+ foo_closure : Static (no-free-var) closure only:+ points to the statically-allocated closure++For a data constructor (such as Just or Nothing), we have:+ Just_con_info: Info table for the data constructor itself+ the first word of a heap-allocated Just+ Just_info: Info table for the *worker function*, an+ ordinary Haskell function of arity 1 that+ allocates a (Just x) box:+ Just = \x -> Just x+ Just_closure: The closure for this worker++ Nothing_closure: a statically allocated closure for Nothing+ Nothing_static_info: info table for Nothing_closure++All these must be exported symbol, EXCEPT Just_info. We don't need to+export this because in other modules we either have+ * A reference to 'Just'; use Just_closure+ * A saturated call 'Just x'; allocate using Just_con_info+Not exporting these Just_info labels reduces the number of symbols+somewhat.++Note [Bytes label]+~~~~~~~~~~~~~~~~~~+For a top-level string literal 'foo', we have just one symbol 'foo_bytes', which+points to a static data block containing the content of the literal.++Note [Proc-point local block entry-points]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+A label for a proc-point local block entry-point has no "_entry" suffix. With+`infoTblLbl` we derive an info table label from a proc-point block ID. If+we convert such an info table label into an entry label we must produce+the label without an "_entry" suffix. So an info table label records+the fact that it was derived from a block ID in `IdLabelInfo` as+`BlockInfoTable`.++The info table label and the local block label are both local labels+and are not externally visible.+-}++instance Outputable CLabel where+ ppr c = sdocWithDynFlags $ \dynFlags -> pprCLabel dynFlags c++pprCLabel :: DynFlags -> CLabel -> SDoc++pprCLabel _ (LocalBlockLabel u)+ = tempLabelPrefixOrUnderscore <> pprUniqueAlways u++pprCLabel dynFlags (AsmTempLabel u)+ | not (platformUnregisterised $ targetPlatform dynFlags)+ = tempLabelPrefixOrUnderscore <> pprUniqueAlways u++pprCLabel dynFlags (AsmTempDerivedLabel l suf)+ | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags+ = ptext (asmTempLabelPrefix $ targetPlatform dynFlags)+ <> case l of AsmTempLabel u -> pprUniqueAlways u+ LocalBlockLabel u -> pprUniqueAlways u+ _other -> pprCLabel dynFlags l+ <> ftext suf++pprCLabel dynFlags (DynamicLinkerLabel info lbl)+ | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags+ = pprDynamicLinkerAsmLabel (targetPlatform dynFlags) info lbl++pprCLabel dynFlags PicBaseLabel+ | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags+ = text "1b"++pprCLabel dynFlags (DeadStripPreventer lbl)+ | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags+ =+ {-+ `lbl` can be temp one but we need to ensure that dsp label will stay+ in the final binary so we prepend non-temp prefix ("dsp_") and+ optional `_` (underscore) because this is how you mark non-temp symbols+ on some platforms (Darwin)+ -}+ maybe_underscore dynFlags $ text "dsp_"+ <> pprCLabel dynFlags lbl <> text "_dsp"++pprCLabel dynFlags (StringLitLabel u)+ | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags+ = pprUniqueAlways u <> ptext (sLit "_str")++pprCLabel dynFlags lbl+ = getPprStyle $ \ sty ->+ if platformMisc_ghcWithNativeCodeGen (platformMisc dynFlags) && asmStyle sty+ then maybe_underscore dynFlags $ pprAsmCLbl (targetPlatform dynFlags) lbl+ else pprCLbl lbl++maybe_underscore :: DynFlags -> SDoc -> SDoc+maybe_underscore dynFlags doc =+ if platformMisc_leadingUnderscore $ platformMisc dynFlags+ then pp_cSEP <> doc+ else doc++pprAsmCLbl :: Platform -> CLabel -> SDoc+pprAsmCLbl platform (ForeignLabel fs (Just sz) _ _)+ | platformOS platform == OSMinGW32+ -- In asm mode, we need to put the suffix on a stdcall ForeignLabel.+ -- (The C compiler does this itself).+ = ftext fs <> char '@' <> int sz+pprAsmCLbl _ lbl+ = pprCLbl lbl++pprCLbl :: CLabel -> SDoc+pprCLbl (StringLitLabel u)+ = pprUniqueAlways u <> text "_str"++pprCLbl (SRTLabel u)+ = tempLabelPrefixOrUnderscore <> pprUniqueAlways u <> pp_cSEP <> text "srt"++pprCLbl (LargeBitmapLabel u) =+ tempLabelPrefixOrUnderscore+ <> char 'b' <> pprUniqueAlways u <> pp_cSEP <> text "btm"+-- Some bitsmaps for tuple constructors have a numeric tag (e.g. '7')+-- until that gets resolved we'll just force them to start+-- with a letter so the label will be legal assembly code.+++pprCLbl (CmmLabel _ str CmmCode) = ftext str+pprCLbl (CmmLabel _ str CmmData) = ftext str+pprCLbl (CmmLabel _ str CmmPrimCall) = ftext str++pprCLbl (LocalBlockLabel u) =+ tempLabelPrefixOrUnderscore <> text "blk_" <> pprUniqueAlways u++pprCLbl (RtsLabel (RtsApFast str)) = ftext str <> text "_fast"++pprCLbl (RtsLabel (RtsSelectorInfoTable upd_reqd offset))+ = sdocWithDynFlags $ \dflags ->+ ASSERT(offset >= 0 && offset <= mAX_SPEC_SELECTEE_SIZE dflags)+ hcat [text "stg_sel_", text (show offset),+ ptext (if upd_reqd+ then (sLit "_upd_info")+ else (sLit "_noupd_info"))+ ]++pprCLbl (RtsLabel (RtsSelectorEntry upd_reqd offset))+ = sdocWithDynFlags $ \dflags ->+ ASSERT(offset >= 0 && offset <= mAX_SPEC_SELECTEE_SIZE dflags)+ hcat [text "stg_sel_", text (show offset),+ ptext (if upd_reqd+ then (sLit "_upd_entry")+ else (sLit "_noupd_entry"))+ ]++pprCLbl (RtsLabel (RtsApInfoTable upd_reqd arity))+ = sdocWithDynFlags $ \dflags ->+ ASSERT(arity > 0 && arity <= mAX_SPEC_AP_SIZE dflags)+ hcat [text "stg_ap_", text (show arity),+ ptext (if upd_reqd+ then (sLit "_upd_info")+ else (sLit "_noupd_info"))+ ]++pprCLbl (RtsLabel (RtsApEntry upd_reqd arity))+ = sdocWithDynFlags $ \dflags ->+ ASSERT(arity > 0 && arity <= mAX_SPEC_AP_SIZE dflags)+ hcat [text "stg_ap_", text (show arity),+ ptext (if upd_reqd+ then (sLit "_upd_entry")+ else (sLit "_noupd_entry"))+ ]++pprCLbl (CmmLabel _ fs CmmInfo)+ = ftext fs <> text "_info"++pprCLbl (CmmLabel _ fs CmmEntry)+ = ftext fs <> text "_entry"++pprCLbl (CmmLabel _ fs CmmRetInfo)+ = ftext fs <> text "_info"++pprCLbl (CmmLabel _ fs CmmRet)+ = ftext fs <> text "_ret"++pprCLbl (CmmLabel _ fs CmmClosure)+ = ftext fs <> text "_closure"++pprCLbl (RtsLabel (RtsPrimOp primop))+ = text "stg_" <> ppr primop++pprCLbl (RtsLabel (RtsSlowFastTickyCtr pat))+ = text "SLOW_CALL_fast_" <> text pat <> ptext (sLit "_ctr")++pprCLbl (ForeignLabel str _ _ _)+ = ftext str++pprCLbl (IdLabel name _cafs flavor) =+ internalNamePrefix name <> ppr name <> ppIdFlavor flavor++pprCLbl (CC_Label cc) = ppr cc+pprCLbl (CCS_Label ccs) = ppr ccs++pprCLbl (HpcTicksLabel mod)+ = text "_hpc_tickboxes_" <> ppr mod <> ptext (sLit "_hpc")++pprCLbl (AsmTempLabel {}) = panic "pprCLbl AsmTempLabel"+pprCLbl (AsmTempDerivedLabel {})= panic "pprCLbl AsmTempDerivedLabel"+pprCLbl (DynamicLinkerLabel {}) = panic "pprCLbl DynamicLinkerLabel"+pprCLbl (PicBaseLabel {}) = panic "pprCLbl PicBaseLabel"+pprCLbl (DeadStripPreventer {}) = panic "pprCLbl DeadStripPreventer"++ppIdFlavor :: IdLabelInfo -> SDoc+ppIdFlavor x = pp_cSEP <> text+ (case x of+ Closure -> "closure"+ InfoTable -> "info"+ LocalInfoTable -> "info"+ Entry -> "entry"+ LocalEntry -> "entry"+ Slow -> "slow"+ RednCounts -> "ct"+ ConEntry -> "con_entry"+ ConInfoTable -> "con_info"+ ClosureTable -> "closure_tbl"+ Bytes -> "bytes"+ BlockInfoTable -> "info"+ )+++pp_cSEP :: SDoc+pp_cSEP = char '_'+++instance Outputable ForeignLabelSource where+ ppr fs+ = case fs of+ ForeignLabelInPackage pkgId -> parens $ text "package: " <> ppr pkgId+ ForeignLabelInThisPackage -> parens $ text "this package"+ ForeignLabelInExternalPackage -> parens $ text "external package"++internalNamePrefix :: Name -> SDoc+internalNamePrefix name = getPprStyle $ \ sty ->+ if asmStyle sty && isRandomGenerated then+ sdocWithPlatform $ \platform ->+ ptext (asmTempLabelPrefix platform)+ else+ empty+ where+ isRandomGenerated = not $ isExternalName name++tempLabelPrefixOrUnderscore :: SDoc+tempLabelPrefixOrUnderscore = sdocWithPlatform $ \platform ->+ getPprStyle $ \ sty ->+ if asmStyle sty then+ ptext (asmTempLabelPrefix platform)+ else+ char '_'++-- -----------------------------------------------------------------------------+-- Machine-dependent knowledge about labels.++asmTempLabelPrefix :: Platform -> PtrString -- for formatting labels+asmTempLabelPrefix platform = case platformOS platform of+ OSDarwin -> sLit "L"+ OSAIX -> sLit "__L" -- follow IBM XL C's convention+ _ -> sLit ".L"++pprDynamicLinkerAsmLabel :: Platform -> DynamicLinkerLabelInfo -> CLabel -> SDoc+pprDynamicLinkerAsmLabel platform dllInfo lbl =+ case platformOS platform of+ OSDarwin+ | platformArch platform == ArchX86_64 ->+ case dllInfo of+ CodeStub -> char 'L' <> ppr lbl <> text "$stub"+ SymbolPtr -> char 'L' <> ppr lbl <> text "$non_lazy_ptr"+ GotSymbolPtr -> ppr lbl <> text "@GOTPCREL"+ GotSymbolOffset -> ppr lbl+ | otherwise ->+ case dllInfo of+ CodeStub -> char 'L' <> ppr lbl <> text "$stub"+ SymbolPtr -> char 'L' <> ppr lbl <> text "$non_lazy_ptr"+ _ -> panic "pprDynamicLinkerAsmLabel"++ OSAIX ->+ case dllInfo of+ SymbolPtr -> text "LC.." <> ppr lbl -- GCC's naming convention+ _ -> panic "pprDynamicLinkerAsmLabel"++ _ | osElfTarget (platformOS platform) -> elfLabel++ OSMinGW32 ->+ case dllInfo of+ SymbolPtr -> text "__imp_" <> ppr lbl+ _ -> panic "pprDynamicLinkerAsmLabel"++ _ -> panic "pprDynamicLinkerAsmLabel"+ where+ elfLabel+ | platformArch platform == ArchPPC+ = case dllInfo of+ CodeStub -> -- See Note [.LCTOC1 in PPC PIC code]+ ppr lbl <> text "+32768@plt"+ SymbolPtr -> text ".LC_" <> ppr lbl+ _ -> panic "pprDynamicLinkerAsmLabel"++ | platformArch platform == ArchX86_64+ = case dllInfo of+ CodeStub -> ppr lbl <> text "@plt"+ GotSymbolPtr -> ppr lbl <> text "@gotpcrel"+ GotSymbolOffset -> ppr lbl+ SymbolPtr -> text ".LC_" <> ppr lbl++ | platformArch platform == ArchPPC_64 ELF_V1+ || platformArch platform == ArchPPC_64 ELF_V2+ = case dllInfo of+ GotSymbolPtr -> text ".LC_" <> ppr lbl+ <> text "@toc"+ GotSymbolOffset -> ppr lbl+ SymbolPtr -> text ".LC_" <> ppr lbl+ _ -> panic "pprDynamicLinkerAsmLabel"++ | otherwise+ = case dllInfo of+ CodeStub -> ppr lbl <> text "@plt"+ SymbolPtr -> text ".LC_" <> ppr lbl+ GotSymbolPtr -> ppr lbl <> text "@got"+ GotSymbolOffset -> ppr lbl <> text "@gotoff"++-- Figure out whether `symbol` may serve as an alias+-- to `target` within one compilation unit.+--+-- This is true if any of these holds:+-- * `target` is a module-internal haskell name.+-- * `target` is an exported name, but comes from the same+-- module as `symbol`+--+-- These are sufficient conditions for establishing e.g. a+-- GNU assembly alias ('.equiv' directive). Sadly, there is+-- no such thing as an alias to an imported symbol (conf.+-- http://blog.omega-prime.co.uk/2011/07/06/the-sad-state-of-symbol-aliases/)+-- See note [emit-time elimination of static indirections].+--+-- Precondition is that both labels represent the+-- same semantic value.++mayRedirectTo :: CLabel -> CLabel -> Bool+mayRedirectTo symbol target+ | Just nam <- haskellName+ , staticClosureLabel+ , isExternalName nam+ , Just mod <- nameModule_maybe nam+ , Just anam <- hasHaskellName symbol+ , Just amod <- nameModule_maybe anam+ = amod == mod++ | Just nam <- haskellName+ , staticClosureLabel+ , isInternalName nam+ = True++ | otherwise = False+ where staticClosureLabel = isStaticClosureLabel target+ haskellName = hasHaskellName target+++{-+Note [emit-time elimination of static indirections]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+As described in #15155, certain static values are representationally+equivalent, e.g. 'cast'ed values (when created by 'newtype' wrappers).++ newtype A = A Int+ {-# NOINLINE a #-}+ a = A 42++a1_rYB :: Int+[GblId, Caf=NoCafRefs, Unf=OtherCon []]+a1_rYB = GHC.Types.I# 42#++a [InlPrag=NOINLINE] :: A+[GblId, Unf=OtherCon []]+a = a1_rYB `cast` (Sym (T15155.N:A[0]) :: Int ~R# A)++Formerly we created static indirections for these (IND_STATIC), which+consist of a statically allocated forwarding closure that contains+the (possibly tagged) indirectee. (See CMM/assembly below.)+This approach is suboptimal for two reasons:+ (a) they occupy extra space,+ (b) they need to be entered in order to obtain the indirectee,+ thus they cannot be tagged.++Fortunately there is a common case where static indirections can be+eliminated while emitting assembly (native or LLVM), viz. when the+indirectee is in the same module (object file) as the symbol that+points to it. In this case an assembly-level identification can+be created ('.equiv' directive), and as such the same object will+be assigned two names in the symbol table. Any of the identified+symbols can be referenced by a tagged pointer.++Currently the 'mayRedirectTo' predicate will+give a clue whether a label can be equated with another, already+emitted, label (which can in turn be an alias). The general mechanics+is that we identify data (IND_STATIC closures) that are amenable+to aliasing while pretty-printing of assembly output, and emit the+'.equiv' directive instead of static data in such a case.++Here is a sketch how the output is massaged:++ Consider+newtype A = A Int+{-# NOINLINE a #-}+a = A 42 -- I# 42# is the indirectee+ -- 'a' is exported++ results in STG++a1_rXq :: GHC.Types.Int+[GblId, Caf=NoCafRefs, Unf=OtherCon []] =+ CCS_DONT_CARE GHC.Types.I#! [42#];++T15155.a [InlPrag=NOINLINE] :: T15155.A+[GblId, Unf=OtherCon []] =+ CAF_ccs \ u [] a1_rXq;++ and CMM++[section ""data" . a1_rXq_closure" {+ a1_rXq_closure:+ const GHC.Types.I#_con_info;+ const 42;+ }]++[section ""data" . T15155.a_closure" {+ T15155.a_closure:+ const stg_IND_STATIC_info;+ const a1_rXq_closure+1;+ const 0;+ const 0;+ }]++The emitted assembly is++#### INDIRECTEE+a1_rXq_closure: -- module local haskell value+ .quad GHC.Types.I#_con_info -- an Int+ .quad 42++#### BEFORE+.globl T15155.a_closure -- exported newtype wrapped value+T15155.a_closure:+ .quad stg_IND_STATIC_info -- the closure info+ .quad a1_rXq_closure+1 -- indirectee ('+1' being the tag)+ .quad 0+ .quad 0++#### AFTER+.globl T15155.a_closure -- exported newtype wrapped value+.equiv a1_rXq_closure,T15155.a_closure -- both are shared++The transformation is performed because+ T15155.a_closure `mayRedirectTo` a1_rXq_closure+1+returns True.+-}
+ compiler/GHC/Cmm/Dataflow/Block.hs view
@@ -0,0 +1,329 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeFamilies #-}+module GHC.Cmm.Dataflow.Block+ ( Extensibility (..)+ , O+ , C+ , MaybeO(..)+ , IndexedCO+ , Block(..)+ , blockAppend+ , blockCons+ , blockFromList+ , blockJoin+ , blockJoinHead+ , blockJoinTail+ , blockSnoc+ , blockSplit+ , blockSplitHead+ , blockSplitTail+ , blockToList+ , emptyBlock+ , firstNode+ , foldBlockNodesB+ , foldBlockNodesB3+ , foldBlockNodesF+ , isEmptyBlock+ , lastNode+ , mapBlock+ , mapBlock'+ , mapBlock3'+ , replaceFirstNode+ , replaceLastNode+ ) where++import GhcPrelude++-- -----------------------------------------------------------------------------+-- Shapes: Open and Closed++-- | Used at the type level to indicate "open" vs "closed" structure.+data Extensibility+ -- | An "open" structure with a unique, unnamed control-flow edge flowing in+ -- or out. "Fallthrough" and concatenation are permitted at an open point.+ = Open+ -- | A "closed" structure which supports control transfer only through the use+ -- of named labels---no "fallthrough" is permitted. The number of control-flow+ -- edges is unconstrained.+ | Closed++type O = 'Open+type C = 'Closed++-- | Either type indexed by closed/open using type families+type family IndexedCO (ex :: Extensibility) (a :: k) (b :: k) :: k+type instance IndexedCO C a _b = a+type instance IndexedCO O _a b = b++-- | Maybe type indexed by open/closed+data MaybeO ex t where+ JustO :: t -> MaybeO O t+ NothingO :: MaybeO C t++-- | Maybe type indexed by closed/open+data MaybeC ex t where+ JustC :: t -> MaybeC C t+ NothingC :: MaybeC O t++deriving instance Functor (MaybeO ex)+deriving instance Functor (MaybeC ex)++-- -----------------------------------------------------------------------------+-- The Block type++-- | A sequence of nodes. May be any of four shapes (O/O, O/C, C/O, C/C).+-- Open at the entry means single entry, mutatis mutandis for exit.+-- A closed/closed block is a /basic/ block and can't be extended further.+-- Clients should avoid manipulating blocks and should stick to either nodes+-- or graphs.+data Block n e x where+ BlockCO :: n C O -> Block n O O -> Block n C O+ BlockCC :: n C O -> Block n O O -> n O C -> Block n C C+ BlockOC :: Block n O O -> n O C -> Block n O C++ BNil :: Block n O O+ BMiddle :: n O O -> Block n O O+ BCat :: Block n O O -> Block n O O -> Block n O O+ BSnoc :: Block n O O -> n O O -> Block n O O+ BCons :: n O O -> Block n O O -> Block n O O+++-- -----------------------------------------------------------------------------+-- Simple operations on Blocks++-- Predicates++isEmptyBlock :: Block n e x -> Bool+isEmptyBlock BNil = True+isEmptyBlock (BCat l r) = isEmptyBlock l && isEmptyBlock r+isEmptyBlock _ = False+++-- Building++emptyBlock :: Block n O O+emptyBlock = BNil++blockCons :: n O O -> Block n O x -> Block n O x+blockCons n b = case b of+ BlockOC b l -> (BlockOC $! (n `blockCons` b)) l+ BNil{} -> BMiddle n+ BMiddle{} -> n `BCons` b+ BCat{} -> n `BCons` b+ BSnoc{} -> n `BCons` b+ BCons{} -> n `BCons` b++blockSnoc :: Block n e O -> n O O -> Block n e O+blockSnoc b n = case b of+ BlockCO f b -> BlockCO f $! (b `blockSnoc` n)+ BNil{} -> BMiddle n+ BMiddle{} -> b `BSnoc` n+ BCat{} -> b `BSnoc` n+ BSnoc{} -> b `BSnoc` n+ BCons{} -> b `BSnoc` n++blockJoinHead :: n C O -> Block n O x -> Block n C x+blockJoinHead f (BlockOC b l) = BlockCC f b l+blockJoinHead f b = BlockCO f BNil `cat` b++blockJoinTail :: Block n e O -> n O C -> Block n e C+blockJoinTail (BlockCO f b) t = BlockCC f b t+blockJoinTail b t = b `cat` BlockOC BNil t++blockJoin :: n C O -> Block n O O -> n O C -> Block n C C+blockJoin f b t = BlockCC f b t++blockAppend :: Block n e O -> Block n O x -> Block n e x+blockAppend = cat+++-- Taking apart++firstNode :: Block n C x -> n C O+firstNode (BlockCO n _) = n+firstNode (BlockCC n _ _) = n++lastNode :: Block n x C -> n O C+lastNode (BlockOC _ n) = n+lastNode (BlockCC _ _ n) = n++blockSplitHead :: Block n C x -> (n C O, Block n O x)+blockSplitHead (BlockCO n b) = (n, b)+blockSplitHead (BlockCC n b t) = (n, BlockOC b t)++blockSplitTail :: Block n e C -> (Block n e O, n O C)+blockSplitTail (BlockOC b n) = (b, n)+blockSplitTail (BlockCC f b t) = (BlockCO f b, t)++-- | Split a closed block into its entry node, open middle block, and+-- exit node.+blockSplit :: Block n C C -> (n C O, Block n O O, n O C)+blockSplit (BlockCC f b t) = (f, b, t)++blockToList :: Block n O O -> [n O O]+blockToList b = go b []+ where go :: Block n O O -> [n O O] -> [n O O]+ go BNil r = r+ go (BMiddle n) r = n : r+ go (BCat b1 b2) r = go b1 $! go b2 r+ go (BSnoc b1 n) r = go b1 (n:r)+ go (BCons n b1) r = n : go b1 r++blockFromList :: [n O O] -> Block n O O+blockFromList = foldr BCons BNil++-- Modifying++replaceFirstNode :: Block n C x -> n C O -> Block n C x+replaceFirstNode (BlockCO _ b) f = BlockCO f b+replaceFirstNode (BlockCC _ b n) f = BlockCC f b n++replaceLastNode :: Block n x C -> n O C -> Block n x C+replaceLastNode (BlockOC b _) n = BlockOC b n+replaceLastNode (BlockCC l b _) n = BlockCC l b n++-- -----------------------------------------------------------------------------+-- General concatenation++cat :: Block n e O -> Block n O x -> Block n e x+cat x y = case x of+ BNil -> y++ BlockCO l b1 -> case y of+ BlockOC b2 n -> (BlockCC l $! (b1 `cat` b2)) n+ BNil -> x+ BMiddle _ -> BlockCO l $! (b1 `cat` y)+ BCat{} -> BlockCO l $! (b1 `cat` y)+ BSnoc{} -> BlockCO l $! (b1 `cat` y)+ BCons{} -> BlockCO l $! (b1 `cat` y)++ BMiddle n -> case y of+ BlockOC b2 n2 -> (BlockOC $! (x `cat` b2)) n2+ BNil -> x+ BMiddle{} -> BCons n y+ BCat{} -> BCons n y+ BSnoc{} -> BCons n y+ BCons{} -> BCons n y++ BCat{} -> case y of+ BlockOC b3 n2 -> (BlockOC $! (x `cat` b3)) n2+ BNil -> x+ BMiddle n -> BSnoc x n+ BCat{} -> BCat x y+ BSnoc{} -> BCat x y+ BCons{} -> BCat x y++ BSnoc{} -> case y of+ BlockOC b2 n2 -> (BlockOC $! (x `cat` b2)) n2+ BNil -> x+ BMiddle n -> BSnoc x n+ BCat{} -> BCat x y+ BSnoc{} -> BCat x y+ BCons{} -> BCat x y+++ BCons{} -> case y of+ BlockOC b2 n2 -> (BlockOC $! (x `cat` b2)) n2+ BNil -> x+ BMiddle n -> BSnoc x n+ BCat{} -> BCat x y+ BSnoc{} -> BCat x y+ BCons{} -> BCat x y+++-- -----------------------------------------------------------------------------+-- Mapping++-- | map a function over the nodes of a 'Block'+mapBlock :: (forall e x. n e x -> n' e x) -> Block n e x -> Block n' e x+mapBlock f (BlockCO n b ) = BlockCO (f n) (mapBlock f b)+mapBlock f (BlockOC b n) = BlockOC (mapBlock f b) (f n)+mapBlock f (BlockCC n b m) = BlockCC (f n) (mapBlock f b) (f m)+mapBlock _ BNil = BNil+mapBlock f (BMiddle n) = BMiddle (f n)+mapBlock f (BCat b1 b2) = BCat (mapBlock f b1) (mapBlock f b2)+mapBlock f (BSnoc b n) = BSnoc (mapBlock f b) (f n)+mapBlock f (BCons n b) = BCons (f n) (mapBlock f b)++-- | A strict 'mapBlock'+mapBlock' :: (forall e x. n e x -> n' e x) -> (Block n e x -> Block n' e x)+mapBlock' f = mapBlock3' (f, f, f)++-- | map over a block, with different functions to apply to first nodes,+-- middle nodes and last nodes respectively. The map is strict.+--+mapBlock3' :: forall n n' e x .+ ( n C O -> n' C O+ , n O O -> n' O O,+ n O C -> n' O C)+ -> Block n e x -> Block n' e x+mapBlock3' (f, m, l) b = go b+ where go :: forall e x . Block n e x -> Block n' e x+ go (BlockOC b y) = (BlockOC $! go b) $! l y+ go (BlockCO x b) = (BlockCO $! f x) $! (go b)+ go (BlockCC x b y) = ((BlockCC $! f x) $! go b) $! (l y)+ go BNil = BNil+ go (BMiddle n) = BMiddle $! m n+ go (BCat x y) = (BCat $! go x) $! (go y)+ go (BSnoc x n) = (BSnoc $! go x) $! (m n)+ go (BCons n x) = (BCons $! m n) $! (go x)++-- -----------------------------------------------------------------------------+-- Folding+++-- | Fold a function over every node in a block, forward or backward.+-- The fold function must be polymorphic in the shape of the nodes.+foldBlockNodesF3 :: forall n a b c .+ ( n C O -> a -> b+ , n O O -> b -> b+ , n O C -> b -> c)+ -> (forall e x . Block n e x -> IndexedCO e a b -> IndexedCO x c b)+foldBlockNodesF :: forall n a .+ (forall e x . n e x -> a -> a)+ -> (forall e x . Block n e x -> IndexedCO e a a -> IndexedCO x a a)+foldBlockNodesB3 :: forall n a b c .+ ( n C O -> b -> c+ , n O O -> b -> b+ , n O C -> a -> b)+ -> (forall e x . Block n e x -> IndexedCO x a b -> IndexedCO e c b)+foldBlockNodesB :: forall n a .+ (forall e x . n e x -> a -> a)+ -> (forall e x . Block n e x -> IndexedCO x a a -> IndexedCO e a a)++foldBlockNodesF3 (ff, fm, fl) = block+ where block :: forall e x . Block n e x -> IndexedCO e a b -> IndexedCO x c b+ block (BlockCO f b ) = ff f `cat` block b+ block (BlockCC f b l) = ff f `cat` block b `cat` fl l+ block (BlockOC b l) = block b `cat` fl l+ block BNil = id+ block (BMiddle node) = fm node+ block (b1 `BCat` b2) = block b1 `cat` block b2+ block (b1 `BSnoc` n) = block b1 `cat` fm n+ block (n `BCons` b2) = fm n `cat` block b2+ cat :: forall a b c. (a -> b) -> (b -> c) -> a -> c+ cat f f' = f' . f++foldBlockNodesF f = foldBlockNodesF3 (f, f, f)++foldBlockNodesB3 (ff, fm, fl) = block+ where block :: forall e x . Block n e x -> IndexedCO x a b -> IndexedCO e c b+ block (BlockCO f b ) = ff f `cat` block b+ block (BlockCC f b l) = ff f `cat` block b `cat` fl l+ block (BlockOC b l) = block b `cat` fl l+ block BNil = id+ block (BMiddle node) = fm node+ block (b1 `BCat` b2) = block b1 `cat` block b2+ block (b1 `BSnoc` n) = block b1 `cat` fm n+ block (n `BCons` b2) = fm n `cat` block b2+ cat :: forall a b c. (b -> c) -> (a -> b) -> a -> c+ cat f f' = f . f'++foldBlockNodesB f = foldBlockNodesB3 (f, f, f)+
+ compiler/GHC/Cmm/Dataflow/Collections.hs view
@@ -0,0 +1,177 @@+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++module GHC.Cmm.Dataflow.Collections+ ( IsSet(..)+ , setInsertList, setDeleteList, setUnions+ , IsMap(..)+ , mapInsertList, mapDeleteList, mapUnions+ , UniqueMap, UniqueSet+ ) where++import GhcPrelude++import qualified Data.IntMap.Strict as M+import qualified Data.IntSet as S++import Data.List (foldl1')++class IsSet set where+ type ElemOf set++ setNull :: set -> Bool+ setSize :: set -> Int+ setMember :: ElemOf set -> set -> Bool++ setEmpty :: set+ setSingleton :: ElemOf set -> set+ setInsert :: ElemOf set -> set -> set+ setDelete :: ElemOf set -> set -> set++ setUnion :: set -> set -> set+ setDifference :: set -> set -> set+ setIntersection :: set -> set -> set+ setIsSubsetOf :: set -> set -> Bool+ setFilter :: (ElemOf set -> Bool) -> set -> set++ setFoldl :: (b -> ElemOf set -> b) -> b -> set -> b+ setFoldr :: (ElemOf set -> b -> b) -> b -> set -> b++ setElems :: set -> [ElemOf set]+ setFromList :: [ElemOf set] -> set++-- Helper functions for IsSet class+setInsertList :: IsSet set => [ElemOf set] -> set -> set+setInsertList keys set = foldl' (flip setInsert) set keys++setDeleteList :: IsSet set => [ElemOf set] -> set -> set+setDeleteList keys set = foldl' (flip setDelete) set keys++setUnions :: IsSet set => [set] -> set+setUnions [] = setEmpty+setUnions sets = foldl1' setUnion sets+++class IsMap map where+ type KeyOf map++ mapNull :: map a -> Bool+ mapSize :: map a -> Int+ mapMember :: KeyOf map -> map a -> Bool+ mapLookup :: KeyOf map -> map a -> Maybe a+ mapFindWithDefault :: a -> KeyOf map -> map a -> a++ mapEmpty :: map a+ mapSingleton :: KeyOf map -> a -> map a+ mapInsert :: KeyOf map -> a -> map a -> map a+ mapInsertWith :: (a -> a -> a) -> KeyOf map -> a -> map a -> map a+ mapDelete :: KeyOf map -> map a -> map a+ mapAlter :: (Maybe a -> Maybe a) -> KeyOf map -> map a -> map a+ mapAdjust :: (a -> a) -> KeyOf map -> map a -> map a++ mapUnion :: map a -> map a -> map a+ mapUnionWithKey :: (KeyOf map -> a -> a -> a) -> map a -> map a -> map a+ mapDifference :: map a -> map a -> map a+ mapIntersection :: map a -> map a -> map a+ mapIsSubmapOf :: Eq a => map a -> map a -> Bool++ mapMap :: (a -> b) -> map a -> map b+ mapMapWithKey :: (KeyOf map -> a -> b) -> map a -> map b+ mapFoldl :: (b -> a -> b) -> b -> map a -> b+ mapFoldr :: (a -> b -> b) -> b -> map a -> b+ mapFoldlWithKey :: (b -> KeyOf map -> a -> b) -> b -> map a -> b+ mapFoldMapWithKey :: Monoid m => (KeyOf map -> a -> m) -> map a -> m+ mapFilter :: (a -> Bool) -> map a -> map a+ mapFilterWithKey :: (KeyOf map -> a -> Bool) -> map a -> map a+++ mapElems :: map a -> [a]+ mapKeys :: map a -> [KeyOf map]+ mapToList :: map a -> [(KeyOf map, a)]+ mapFromList :: [(KeyOf map, a)] -> map a+ mapFromListWith :: (a -> a -> a) -> [(KeyOf map,a)] -> map a++-- Helper functions for IsMap class+mapInsertList :: IsMap map => [(KeyOf map, a)] -> map a -> map a+mapInsertList assocs map = foldl' (flip (uncurry mapInsert)) map assocs++mapDeleteList :: IsMap map => [KeyOf map] -> map a -> map a+mapDeleteList keys map = foldl' (flip mapDelete) map keys++mapUnions :: IsMap map => [map a] -> map a+mapUnions [] = mapEmpty+mapUnions maps = foldl1' mapUnion maps++-----------------------------------------------------------------------------+-- Basic instances+-----------------------------------------------------------------------------++newtype UniqueSet = US S.IntSet deriving (Eq, Ord, Show, Semigroup, Monoid)++instance IsSet UniqueSet where+ type ElemOf UniqueSet = Int++ setNull (US s) = S.null s+ setSize (US s) = S.size s+ setMember k (US s) = S.member k s++ setEmpty = US S.empty+ setSingleton k = US (S.singleton k)+ setInsert k (US s) = US (S.insert k s)+ setDelete k (US s) = US (S.delete k s)++ setUnion (US x) (US y) = US (S.union x y)+ setDifference (US x) (US y) = US (S.difference x y)+ setIntersection (US x) (US y) = US (S.intersection x y)+ setIsSubsetOf (US x) (US y) = S.isSubsetOf x y+ setFilter f (US s) = US (S.filter f s)++ setFoldl k z (US s) = S.foldl' k z s+ setFoldr k z (US s) = S.foldr k z s++ setElems (US s) = S.elems s+ setFromList ks = US (S.fromList ks)++newtype UniqueMap v = UM (M.IntMap v)+ deriving (Eq, Ord, Show, Functor, Foldable, Traversable)++instance IsMap UniqueMap where+ type KeyOf UniqueMap = Int++ mapNull (UM m) = M.null m+ mapSize (UM m) = M.size m+ mapMember k (UM m) = M.member k m+ mapLookup k (UM m) = M.lookup k m+ mapFindWithDefault def k (UM m) = M.findWithDefault def k m++ mapEmpty = UM M.empty+ mapSingleton k v = UM (M.singleton k v)+ mapInsert k v (UM m) = UM (M.insert k v m)+ mapInsertWith f k v (UM m) = UM (M.insertWith f k v m)+ mapDelete k (UM m) = UM (M.delete k m)+ mapAlter f k (UM m) = UM (M.alter f k m)+ mapAdjust f k (UM m) = UM (M.adjust f k m)++ mapUnion (UM x) (UM y) = UM (M.union x y)+ mapUnionWithKey f (UM x) (UM y) = UM (M.unionWithKey f x y)+ mapDifference (UM x) (UM y) = UM (M.difference x y)+ mapIntersection (UM x) (UM y) = UM (M.intersection x y)+ mapIsSubmapOf (UM x) (UM y) = M.isSubmapOf x y++ mapMap f (UM m) = UM (M.map f m)+ mapMapWithKey f (UM m) = UM (M.mapWithKey f m)+ mapFoldl k z (UM m) = M.foldl' k z m+ mapFoldr k z (UM m) = M.foldr k z m+ mapFoldlWithKey k z (UM m) = M.foldlWithKey' k z m+ mapFoldMapWithKey f (UM m) = M.foldMapWithKey f m+ mapFilter f (UM m) = UM (M.filter f m)+ mapFilterWithKey f (UM m) = UM (M.filterWithKey f m)++ mapElems (UM m) = M.elems m+ mapKeys (UM m) = M.keys m+ mapToList (UM m) = M.toList m+ mapFromList assocs = UM (M.fromList assocs)+ mapFromListWith f assocs = UM (M.fromListWith f assocs)
+ compiler/GHC/Cmm/Dataflow/Graph.hs view
@@ -0,0 +1,186 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+module GHC.Cmm.Dataflow.Graph+ ( Body+ , Graph+ , Graph'(..)+ , NonLocal(..)+ , addBlock+ , bodyList+ , emptyBody+ , labelsDefined+ , mapGraph+ , mapGraphBlocks+ , revPostorderFrom+ ) where+++import GhcPrelude+import Util++import GHC.Cmm.Dataflow.Label+import GHC.Cmm.Dataflow.Block+import GHC.Cmm.Dataflow.Collections++-- | A (possibly empty) collection of closed/closed blocks+type Body n = LabelMap (Block n C C)++-- | @Body@ abstracted over @block@+type Body' block (n :: Extensibility -> Extensibility -> *) = LabelMap (block n C C)++-------------------------------+-- | Gives access to the anchor points for+-- nonlocal edges as well as the edges themselves+class NonLocal thing where+ entryLabel :: thing C x -> Label -- ^ The label of a first node or block+ successors :: thing e C -> [Label] -- ^ Gives control-flow successors++instance NonLocal n => NonLocal (Block n) where+ entryLabel (BlockCO f _) = entryLabel f+ entryLabel (BlockCC f _ _) = entryLabel f++ successors (BlockOC _ n) = successors n+ successors (BlockCC _ _ n) = successors n+++emptyBody :: Body' block n+emptyBody = mapEmpty++bodyList :: Body' block n -> [(Label,block n C C)]+bodyList body = mapToList body++addBlock+ :: (NonLocal block, HasDebugCallStack)+ => block C C -> LabelMap (block C C) -> LabelMap (block C C)+addBlock block body = mapAlter add lbl body+ where+ lbl = entryLabel block+ add Nothing = Just block+ add _ = error $ "duplicate label " ++ show lbl ++ " in graph"+++-- ---------------------------------------------------------------------------+-- Graph++-- | A control-flow graph, which may take any of four shapes (O/O,+-- O/C, C/O, C/C). A graph open at the entry has a single,+-- distinguished, anonymous entry point; if a graph is closed at the+-- entry, its entry point(s) are supplied by a context.+type Graph = Graph' Block++-- | @Graph'@ is abstracted over the block type, so that we can build+-- graphs of annotated blocks for example (Compiler.Hoopl.Dataflow+-- needs this).+data Graph' block (n :: Extensibility -> Extensibility -> *) e x where+ GNil :: Graph' block n O O+ GUnit :: block n O O -> Graph' block n O O+ GMany :: MaybeO e (block n O C)+ -> Body' block n+ -> MaybeO x (block n C O)+ -> Graph' block n e x+++-- -----------------------------------------------------------------------------+-- Mapping over graphs++-- | Maps over all nodes in a graph.+mapGraph :: (forall e x. n e x -> n' e x) -> Graph n e x -> Graph n' e x+mapGraph f = mapGraphBlocks (mapBlock f)++-- | Function 'mapGraphBlocks' enables a change of representation of blocks,+-- nodes, or both. It lifts a polymorphic block transform into a polymorphic+-- graph transform. When the block representation stabilizes, a similar+-- function should be provided for blocks.+mapGraphBlocks :: forall block n block' n' e x .+ (forall e x . block n e x -> block' n' e x)+ -> (Graph' block n e x -> Graph' block' n' e x)++mapGraphBlocks f = map+ where map :: Graph' block n e x -> Graph' block' n' e x+ map GNil = GNil+ map (GUnit b) = GUnit (f b)+ map (GMany e b x) = GMany (fmap f e) (mapMap f b) (fmap f x)++-- -----------------------------------------------------------------------------+-- Extracting Labels from graphs++labelsDefined :: forall block n e x . NonLocal (block n) => Graph' block n e x+ -> LabelSet+labelsDefined GNil = setEmpty+labelsDefined (GUnit{}) = setEmpty+labelsDefined (GMany _ body x) = mapFoldlWithKey addEntry (exitLabel x) body+ where addEntry :: forall a. LabelSet -> ElemOf LabelSet -> a -> LabelSet+ addEntry labels label _ = setInsert label labels+ exitLabel :: MaybeO x (block n C O) -> LabelSet+ exitLabel NothingO = setEmpty+ exitLabel (JustO b) = setSingleton (entryLabel b)+++----------------------------------------------------------------++-- | Returns a list of blocks reachable from the provided Labels in the reverse+-- postorder.+--+-- This is the most important traversal over this data structure. It drops+-- unreachable code and puts blocks in an order that is good for solving forward+-- dataflow problems quickly. The reverse order is good for solving backward+-- dataflow problems quickly. The forward order is also reasonably good for+-- emitting instructions, except that it will not usually exploit Forrest+-- Baskett's trick of eliminating the unconditional branch from a loop. For+-- that you would need a more serious analysis, probably based on dominators, to+-- identify loop headers.+--+-- For forward analyses we want reverse postorder visitation, consider:+-- @+-- A -> [B,C]+-- B -> D+-- C -> D+-- @+-- Postorder: [D, C, B, A] (or [D, B, C, A])+-- Reverse postorder: [A, B, C, D] (or [A, C, B, D])+-- This matters for, e.g., forward analysis, because we want to analyze *both*+-- B and C before we analyze D.+revPostorderFrom+ :: forall block. (NonLocal block)+ => LabelMap (block C C) -> Label -> [block C C]+revPostorderFrom graph start = go start_worklist setEmpty []+ where+ start_worklist = lookup_for_descend start Nil++ -- To compute the postorder we need to "visit" a block (mark as done)+ -- *after* visiting all its successors. So we need to know whether we+ -- already processed all successors of each block (and @NonLocal@ allows+ -- arbitrary many successors). So we use an explicit stack with an extra bit+ -- of information:+ -- * @ConsTodo@ means to explore the block if it wasn't visited before+ -- * @ConsMark@ means that all successors were already done and we can add+ -- the block to the result.+ --+ -- NOTE: We add blocks to the result list in postorder, but we *prepend*+ -- them (i.e., we use @(:)@), which means that the final list is in reverse+ -- postorder.+ go :: DfsStack (block C C) -> LabelSet -> [block C C] -> [block C C]+ go Nil !_ !result = result+ go (ConsMark block rest) !wip_or_done !result =+ go rest wip_or_done (block : result)+ go (ConsTodo block rest) !wip_or_done !result+ | entryLabel block `setMember` wip_or_done = go rest wip_or_done result+ | otherwise =+ let new_worklist =+ foldr lookup_for_descend+ (ConsMark block rest)+ (successors block)+ in go new_worklist (setInsert (entryLabel block) wip_or_done) result++ lookup_for_descend :: Label -> DfsStack (block C C) -> DfsStack (block C C)+ lookup_for_descend label wl+ | Just b <- mapLookup label graph = ConsTodo b wl+ | otherwise =+ error $ "Label that doesn't have a block?! " ++ show label++data DfsStack a = ConsTodo a (DfsStack a) | ConsMark a (DfsStack a) | Nil
+ compiler/GHC/Cmm/Dataflow/Label.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++module GHC.Cmm.Dataflow.Label+ ( Label+ , LabelMap+ , LabelSet+ , FactBase+ , lookupFact+ , mkHooplLabel+ ) where++import GhcPrelude++import Outputable++-- TODO: This should really just use GHC's Unique and Uniq{Set,FM}+import GHC.Cmm.Dataflow.Collections++import Unique (Uniquable(..))+import TrieMap+++-----------------------------------------------------------------------------+-- Label+-----------------------------------------------------------------------------++newtype Label = Label { lblToUnique :: Int }+ deriving (Eq, Ord)++mkHooplLabel :: Int -> Label+mkHooplLabel = Label++instance Show Label where+ show (Label n) = "L" ++ show n++instance Uniquable Label where+ getUnique label = getUnique (lblToUnique label)++instance Outputable Label where+ ppr label = ppr (getUnique label)++-----------------------------------------------------------------------------+-- LabelSet++newtype LabelSet = LS UniqueSet deriving (Eq, Ord, Show, Monoid, Semigroup)++instance IsSet LabelSet where+ type ElemOf LabelSet = Label++ setNull (LS s) = setNull s+ setSize (LS s) = setSize s+ setMember (Label k) (LS s) = setMember k s++ setEmpty = LS setEmpty+ setSingleton (Label k) = LS (setSingleton k)+ setInsert (Label k) (LS s) = LS (setInsert k s)+ setDelete (Label k) (LS s) = LS (setDelete k s)++ setUnion (LS x) (LS y) = LS (setUnion x y)+ setDifference (LS x) (LS y) = LS (setDifference x y)+ setIntersection (LS x) (LS y) = LS (setIntersection x y)+ setIsSubsetOf (LS x) (LS y) = setIsSubsetOf x y+ setFilter f (LS s) = LS (setFilter (f . mkHooplLabel) s)+ setFoldl k z (LS s) = setFoldl (\a v -> k a (mkHooplLabel v)) z s+ setFoldr k z (LS s) = setFoldr (\v a -> k (mkHooplLabel v) a) z s++ setElems (LS s) = map mkHooplLabel (setElems s)+ setFromList ks = LS (setFromList (map lblToUnique ks))++-----------------------------------------------------------------------------+-- LabelMap++newtype LabelMap v = LM (UniqueMap v)+ deriving (Eq, Ord, Show, Functor, Foldable, Traversable)++instance IsMap LabelMap where+ type KeyOf LabelMap = Label++ mapNull (LM m) = mapNull m+ mapSize (LM m) = mapSize m+ mapMember (Label k) (LM m) = mapMember k m+ mapLookup (Label k) (LM m) = mapLookup k m+ mapFindWithDefault def (Label k) (LM m) = mapFindWithDefault def k m++ mapEmpty = LM mapEmpty+ mapSingleton (Label k) v = LM (mapSingleton k v)+ mapInsert (Label k) v (LM m) = LM (mapInsert k v m)+ mapInsertWith f (Label k) v (LM m) = LM (mapInsertWith f k v m)+ mapDelete (Label k) (LM m) = LM (mapDelete k m)+ mapAlter f (Label k) (LM m) = LM (mapAlter f k m)+ mapAdjust f (Label k) (LM m) = LM (mapAdjust f k m)++ mapUnion (LM x) (LM y) = LM (mapUnion x y)+ mapUnionWithKey f (LM x) (LM y) = LM (mapUnionWithKey (f . mkHooplLabel) x y)+ mapDifference (LM x) (LM y) = LM (mapDifference x y)+ mapIntersection (LM x) (LM y) = LM (mapIntersection x y)+ mapIsSubmapOf (LM x) (LM y) = mapIsSubmapOf x y++ mapMap f (LM m) = LM (mapMap f m)+ mapMapWithKey f (LM m) = LM (mapMapWithKey (f . mkHooplLabel) m)+ mapFoldl k z (LM m) = mapFoldl k z m+ mapFoldr k z (LM m) = mapFoldr k z m+ mapFoldlWithKey k z (LM m) =+ mapFoldlWithKey (\a v -> k a (mkHooplLabel v)) z m+ mapFoldMapWithKey f (LM m) = mapFoldMapWithKey (\k v -> f (mkHooplLabel k) v) m+ mapFilter f (LM m) = LM (mapFilter f m)+ mapFilterWithKey f (LM m) = LM (mapFilterWithKey (f . mkHooplLabel) m)++ mapElems (LM m) = mapElems m+ mapKeys (LM m) = map mkHooplLabel (mapKeys m)+ mapToList (LM m) = [(mkHooplLabel k, v) | (k, v) <- mapToList m]+ mapFromList assocs = LM (mapFromList [(lblToUnique k, v) | (k, v) <- assocs])+ mapFromListWith f assocs = LM (mapFromListWith f [(lblToUnique k, v) | (k, v) <- assocs])++-----------------------------------------------------------------------------+-- Instances++instance Outputable LabelSet where+ ppr = ppr . setElems++instance Outputable a => Outputable (LabelMap a) where+ ppr = ppr . mapToList++instance TrieMap LabelMap where+ type Key LabelMap = Label+ emptyTM = mapEmpty+ lookupTM k m = mapLookup k m+ alterTM k f m = mapAlter f k m+ foldTM k m z = mapFoldr k z m+ mapTM f m = mapMap f m++-----------------------------------------------------------------------------+-- FactBase++type FactBase f = LabelMap f++lookupFact :: Label -> FactBase f -> Maybe f+lookupFact = mapLookup
+ compiler/GHC/Cmm/Expr.hs view
@@ -0,0 +1,619 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}++module GHC.Cmm.Expr+ ( CmmExpr(..), cmmExprType, cmmExprWidth, cmmExprAlignment, maybeInvertCmmExpr+ , CmmReg(..), cmmRegType, cmmRegWidth+ , CmmLit(..), cmmLitType+ , LocalReg(..), localRegType+ , GlobalReg(..), isArgReg, globalRegType+ , spReg, hpReg, spLimReg, hpLimReg, nodeReg+ , currentTSOReg, currentNurseryReg, hpAllocReg, cccsReg+ , node, baseReg+ , VGcPtr(..)++ , DefinerOfRegs, UserOfRegs+ , foldRegsDefd, foldRegsUsed+ , foldLocalRegsDefd, foldLocalRegsUsed++ , RegSet, LocalRegSet, GlobalRegSet+ , emptyRegSet, elemRegSet, extendRegSet, deleteFromRegSet, mkRegSet+ , plusRegSet, minusRegSet, timesRegSet, sizeRegSet, nullRegSet+ , regSetToList++ , Area(..)+ , module GHC.Cmm.MachOp+ , module GHC.Cmm.Type+ )+where++import GhcPrelude++import GHC.Cmm.BlockId+import GHC.Cmm.CLabel+import GHC.Cmm.MachOp+import GHC.Cmm.Type+import DynFlags+import Outputable (panic)+import Unique++import Data.Set (Set)+import qualified Data.Set as Set++import BasicTypes (Alignment, mkAlignment, alignmentOf)++-----------------------------------------------------------------------------+-- CmmExpr+-- An expression. Expressions have no side effects.+-----------------------------------------------------------------------------++data CmmExpr+ = CmmLit CmmLit -- Literal+ | CmmLoad !CmmExpr !CmmType -- Read memory location+ | CmmReg !CmmReg -- Contents of register+ | CmmMachOp MachOp [CmmExpr] -- Machine operation (+, -, *, etc.)+ | CmmStackSlot Area {-# UNPACK #-} !Int+ -- addressing expression of a stack slot+ -- See Note [CmmStackSlot aliasing]+ | CmmRegOff !CmmReg Int+ -- CmmRegOff reg i+ -- ** is shorthand only, meaning **+ -- CmmMachOp (MO_Add rep) [x, CmmLit (CmmInt (fromIntegral i) rep)]+ -- where rep = typeWidth (cmmRegType reg)++instance Eq CmmExpr where -- Equality ignores the types+ CmmLit l1 == CmmLit l2 = l1==l2+ CmmLoad e1 _ == CmmLoad e2 _ = e1==e2+ CmmReg r1 == CmmReg r2 = r1==r2+ CmmRegOff r1 i1 == CmmRegOff r2 i2 = r1==r2 && i1==i2+ CmmMachOp op1 es1 == CmmMachOp op2 es2 = op1==op2 && es1==es2+ CmmStackSlot a1 i1 == CmmStackSlot a2 i2 = a1==a2 && i1==i2+ _e1 == _e2 = False++data CmmReg+ = CmmLocal {-# UNPACK #-} !LocalReg+ | CmmGlobal GlobalReg+ deriving( Eq, Ord )++-- | A stack area is either the stack slot where a variable is spilled+-- or the stack space where function arguments and results are passed.+data Area+ = Old -- See Note [Old Area]+ | Young {-# UNPACK #-} !BlockId -- Invariant: must be a continuation BlockId+ -- See Note [Continuation BlockId] in GHC.Cmm.Node.+ deriving (Eq, Ord)++{- Note [Old Area]+~~~~~~~~~~~~~~~~~~+There is a single call area 'Old', allocated at the extreme old+end of the stack frame (ie just younger than the return address)+which holds:+ * incoming (overflow) parameters,+ * outgoing (overflow) parameter to tail calls,+ * outgoing (overflow) result values+ * the update frame (if any)++Its size is the max of all these requirements. On entry, the stack+pointer will point to the youngest incoming parameter, which is not+necessarily at the young end of the Old area.++End of note -}+++{- Note [CmmStackSlot aliasing]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When do two CmmStackSlots alias?++ - T[old+N] aliases with U[young(L)+M] for all T, U, L, N and M+ - T[old+N] aliases with U[old+M] only if the areas actually overlap++Or more informally, different Areas may overlap with each other.++An alternative semantics, that we previously had, was that different+Areas do not overlap. The problem that lead to redefining the+semantics of stack areas is described below.++e.g. if we had++ x = Sp[old + 8]+ y = Sp[old + 16]++ Sp[young(L) + 8] = L+ Sp[young(L) + 16] = y+ Sp[young(L) + 24] = x+ call f() returns to L++if areas semantically do not overlap, then we might optimise this to++ Sp[young(L) + 8] = L+ Sp[young(L) + 16] = Sp[old + 8]+ Sp[young(L) + 24] = Sp[old + 16]+ call f() returns to L++and now young(L) cannot be allocated at the same place as old, and we+are doomed to use more stack.++ - old+8 conflicts with young(L)+8+ - old+16 conflicts with young(L)+16 and young(L)+8++so young(L)+8 == old+24 and we get++ Sp[-8] = L+ Sp[-16] = Sp[8]+ Sp[-24] = Sp[0]+ Sp -= 24+ call f() returns to L++However, if areas are defined to be "possibly overlapping" in the+semantics, then we cannot commute any loads/stores of old with+young(L), and we will be able to re-use both old+8 and old+16 for+young(L).++ x = Sp[8]+ y = Sp[0]++ Sp[8] = L+ Sp[0] = y+ Sp[-8] = x+ Sp = Sp - 8+ call f() returns to L++Now, the assignments of y go away,++ x = Sp[8]+ Sp[8] = L+ Sp[-8] = x+ Sp = Sp - 8+ call f() returns to L+-}++data CmmLit+ = CmmInt !Integer Width+ -- Interpretation: the 2's complement representation of the value+ -- is truncated to the specified size. This is easier than trying+ -- to keep the value within range, because we don't know whether+ -- it will be used as a signed or unsigned value (the CmmType doesn't+ -- distinguish between signed & unsigned).+ | CmmFloat Rational Width+ | CmmVec [CmmLit] -- Vector literal+ | CmmLabel CLabel -- Address of label+ | CmmLabelOff CLabel Int -- Address of label + byte offset++ -- Due to limitations in the C backend, the following+ -- MUST ONLY be used inside the info table indicated by label2+ -- (label2 must be the info label), and label1 must be an+ -- SRT, a slow entrypoint or a large bitmap (see the Mangler)+ -- Don't use it at all unless tablesNextToCode.+ -- It is also used inside the NCG during when generating+ -- position-independent code.+ | CmmLabelDiffOff CLabel CLabel Int Width -- label1 - label2 + offset+ -- In an expression, the width just has the effect of MO_SS_Conv+ -- from wordWidth to the desired width.+ --+ -- In a static literal, the supported Widths depend on the+ -- architecture: wordWidth is supported on all+ -- architectures. Additionally W32 is supported on x86_64 when+ -- using the small memory model.++ | CmmBlock {-# UNPACK #-} !BlockId -- Code label+ -- Invariant: must be a continuation BlockId+ -- See Note [Continuation BlockId] in GHC.Cmm.Node.++ | CmmHighStackMark -- A late-bound constant that stands for the max+ -- #bytes of stack space used during a procedure.+ -- During the stack-layout pass, CmmHighStackMark+ -- is replaced by a CmmInt for the actual number+ -- of bytes used+ deriving Eq++cmmExprType :: DynFlags -> CmmExpr -> CmmType+cmmExprType dflags (CmmLit lit) = cmmLitType dflags lit+cmmExprType _ (CmmLoad _ rep) = rep+cmmExprType dflags (CmmReg reg) = cmmRegType dflags reg+cmmExprType dflags (CmmMachOp op args) = machOpResultType dflags op (map (cmmExprType dflags) args)+cmmExprType dflags (CmmRegOff reg _) = cmmRegType dflags reg+cmmExprType dflags (CmmStackSlot _ _) = bWord dflags -- an address+-- Careful though: what is stored at the stack slot may be bigger than+-- an address++cmmLitType :: DynFlags -> CmmLit -> CmmType+cmmLitType _ (CmmInt _ width) = cmmBits width+cmmLitType _ (CmmFloat _ width) = cmmFloat width+cmmLitType _ (CmmVec []) = panic "cmmLitType: CmmVec []"+cmmLitType cflags (CmmVec (l:ls)) = let ty = cmmLitType cflags l+ in if all (`cmmEqType` ty) (map (cmmLitType cflags) ls)+ then cmmVec (1+length ls) ty+ else panic "cmmLitType: CmmVec"+cmmLitType dflags (CmmLabel lbl) = cmmLabelType dflags lbl+cmmLitType dflags (CmmLabelOff lbl _) = cmmLabelType dflags lbl+cmmLitType _ (CmmLabelDiffOff _ _ _ width) = cmmBits width+cmmLitType dflags (CmmBlock _) = bWord dflags+cmmLitType dflags (CmmHighStackMark) = bWord dflags++cmmLabelType :: DynFlags -> CLabel -> CmmType+cmmLabelType dflags lbl+ | isGcPtrLabel lbl = gcWord dflags+ | otherwise = bWord dflags++cmmExprWidth :: DynFlags -> CmmExpr -> Width+cmmExprWidth dflags e = typeWidth (cmmExprType dflags e)++-- | Returns an alignment in bytes of a CmmExpr when it's a statically+-- known integer constant, otherwise returns an alignment of 1 byte.+-- The caller is responsible for using with a sensible CmmExpr+-- argument.+cmmExprAlignment :: CmmExpr -> Alignment+cmmExprAlignment (CmmLit (CmmInt intOff _)) = alignmentOf (fromInteger intOff)+cmmExprAlignment _ = mkAlignment 1+--------+--- Negation for conditional branches++maybeInvertCmmExpr :: CmmExpr -> Maybe CmmExpr+maybeInvertCmmExpr (CmmMachOp op args) = do op' <- maybeInvertComparison op+ return (CmmMachOp op' args)+maybeInvertCmmExpr _ = Nothing++-----------------------------------------------------------------------------+-- Local registers+-----------------------------------------------------------------------------++data LocalReg+ = LocalReg {-# UNPACK #-} !Unique CmmType+ -- ^ Parameters:+ -- 1. Identifier+ -- 2. Type++instance Eq LocalReg where+ (LocalReg u1 _) == (LocalReg u2 _) = u1 == u2++-- This is non-deterministic but we do not currently support deterministic+-- code-generation. See Note [Unique Determinism and code generation]+-- See Note [No Ord for Unique]+instance Ord LocalReg where+ compare (LocalReg u1 _) (LocalReg u2 _) = nonDetCmpUnique u1 u2++instance Uniquable LocalReg where+ getUnique (LocalReg uniq _) = uniq++cmmRegType :: DynFlags -> CmmReg -> CmmType+cmmRegType _ (CmmLocal reg) = localRegType reg+cmmRegType dflags (CmmGlobal reg) = globalRegType dflags reg++cmmRegWidth :: DynFlags -> CmmReg -> Width+cmmRegWidth dflags = typeWidth . cmmRegType dflags++localRegType :: LocalReg -> CmmType+localRegType (LocalReg _ rep) = rep++-----------------------------------------------------------------------------+-- Register-use information for expressions and other types+-----------------------------------------------------------------------------++-- | Sets of registers++-- These are used for dataflow facts, and a common operation is taking+-- the union of two RegSets and then asking whether the union is the+-- same as one of the inputs. UniqSet isn't good here, because+-- sizeUniqSet is O(n) whereas Set.size is O(1), so we use ordinary+-- Sets.++type RegSet r = Set r+type LocalRegSet = RegSet LocalReg+type GlobalRegSet = RegSet GlobalReg++emptyRegSet :: RegSet r+nullRegSet :: RegSet r -> Bool+elemRegSet :: Ord r => r -> RegSet r -> Bool+extendRegSet :: Ord r => RegSet r -> r -> RegSet r+deleteFromRegSet :: Ord r => RegSet r -> r -> RegSet r+mkRegSet :: Ord r => [r] -> RegSet r+minusRegSet, plusRegSet, timesRegSet :: Ord r => RegSet r -> RegSet r -> RegSet r+sizeRegSet :: RegSet r -> Int+regSetToList :: RegSet r -> [r]++emptyRegSet = Set.empty+nullRegSet = Set.null+elemRegSet = Set.member+extendRegSet = flip Set.insert+deleteFromRegSet = flip Set.delete+mkRegSet = Set.fromList+minusRegSet = Set.difference+plusRegSet = Set.union+timesRegSet = Set.intersection+sizeRegSet = Set.size+regSetToList = Set.toList++class Ord r => UserOfRegs r a where+ foldRegsUsed :: DynFlags -> (b -> r -> b) -> b -> a -> b++foldLocalRegsUsed :: UserOfRegs LocalReg a+ => DynFlags -> (b -> LocalReg -> b) -> b -> a -> b+foldLocalRegsUsed = foldRegsUsed++class Ord r => DefinerOfRegs r a where+ foldRegsDefd :: DynFlags -> (b -> r -> b) -> b -> a -> b++foldLocalRegsDefd :: DefinerOfRegs LocalReg a+ => DynFlags -> (b -> LocalReg -> b) -> b -> a -> b+foldLocalRegsDefd = foldRegsDefd++instance UserOfRegs LocalReg CmmReg where+ foldRegsUsed _ f z (CmmLocal reg) = f z reg+ foldRegsUsed _ _ z (CmmGlobal _) = z++instance DefinerOfRegs LocalReg CmmReg where+ foldRegsDefd _ f z (CmmLocal reg) = f z reg+ foldRegsDefd _ _ z (CmmGlobal _) = z++instance UserOfRegs GlobalReg CmmReg where+ foldRegsUsed _ _ z (CmmLocal _) = z+ foldRegsUsed _ f z (CmmGlobal reg) = f z reg++instance DefinerOfRegs GlobalReg CmmReg where+ foldRegsDefd _ _ z (CmmLocal _) = z+ foldRegsDefd _ f z (CmmGlobal reg) = f z reg++instance Ord r => UserOfRegs r r where+ foldRegsUsed _ f z r = f z r++instance Ord r => DefinerOfRegs r r where+ foldRegsDefd _ f z r = f z r++instance (Ord r, UserOfRegs r CmmReg) => UserOfRegs r CmmExpr where+ -- The (Ord r) in the context is necessary here+ -- See Note [Recursive superclasses] in TcInstDcls+ foldRegsUsed dflags f !z e = expr z e+ where expr z (CmmLit _) = z+ expr z (CmmLoad addr _) = foldRegsUsed dflags f z addr+ expr z (CmmReg r) = foldRegsUsed dflags f z r+ expr z (CmmMachOp _ exprs) = foldRegsUsed dflags f z exprs+ expr z (CmmRegOff r _) = foldRegsUsed dflags f z r+ expr z (CmmStackSlot _ _) = z++instance UserOfRegs r a => UserOfRegs r [a] where+ foldRegsUsed dflags f set as = foldl' (foldRegsUsed dflags f) set as+ {-# INLINABLE foldRegsUsed #-}++instance DefinerOfRegs r a => DefinerOfRegs r [a] where+ foldRegsDefd dflags f set as = foldl' (foldRegsDefd dflags f) set as+ {-# INLINABLE foldRegsDefd #-}++-----------------------------------------------------------------------------+-- Global STG registers+-----------------------------------------------------------------------------++data VGcPtr = VGcPtr | VNonGcPtr deriving( Eq, Show )++-----------------------------------------------------------------------------+-- Global STG registers+-----------------------------------------------------------------------------+{-+Note [Overlapping global registers]++The backend might not faithfully implement the abstraction of the STG+machine with independent registers for different values of type+GlobalReg. Specifically, certain pairs of registers (r1, r2) may+overlap in the sense that a store to r1 invalidates the value in r2,+and vice versa.++Currently this occurs only on the x86_64 architecture where FloatReg n+and DoubleReg n are assigned the same microarchitectural register, in+order to allow functions to receive more Float# or Double# arguments+in registers (as opposed to on the stack).++There are no specific rules about which registers might overlap with+which other registers, but presumably it's safe to assume that nothing+will overlap with special registers like Sp or BaseReg.++Use GHC.Cmm.Utils.regsOverlap to determine whether two GlobalRegs overlap+on a particular platform. The instance Eq GlobalReg is syntactic+equality of STG registers and does not take overlap into+account. However it is still used in UserOfRegs/DefinerOfRegs and+there are likely still bugs there, beware!+-}++data GlobalReg+ -- Argument and return registers+ = VanillaReg -- pointers, unboxed ints and chars+ {-# UNPACK #-} !Int -- its number+ VGcPtr++ | FloatReg -- single-precision floating-point registers+ {-# UNPACK #-} !Int -- its number++ | DoubleReg -- double-precision floating-point registers+ {-# UNPACK #-} !Int -- its number++ | LongReg -- long int registers (64-bit, really)+ {-# UNPACK #-} !Int -- its number++ | XmmReg -- 128-bit SIMD vector register+ {-# UNPACK #-} !Int -- its number++ | YmmReg -- 256-bit SIMD vector register+ {-# UNPACK #-} !Int -- its number++ | ZmmReg -- 512-bit SIMD vector register+ {-# UNPACK #-} !Int -- its number++ -- STG registers+ | Sp -- Stack ptr; points to last occupied stack location.+ | SpLim -- Stack limit+ | Hp -- Heap ptr; points to last occupied heap location.+ | HpLim -- Heap limit register+ | CCCS -- Current cost-centre stack+ | CurrentTSO -- pointer to current thread's TSO+ | CurrentNursery -- pointer to allocation area+ | HpAlloc -- allocation count for heap check failure++ -- We keep the address of some commonly-called+ -- functions in the register table, to keep code+ -- size down:+ | EagerBlackholeInfo -- stg_EAGER_BLACKHOLE_info+ | GCEnter1 -- stg_gc_enter_1+ | GCFun -- stg_gc_fun++ -- Base offset for the register table, used for accessing registers+ -- which do not have real registers assigned to them. This register+ -- will only appear after we have expanded GlobalReg into memory accesses+ -- (where necessary) in the native code generator.+ | BaseReg++ -- The register used by the platform for the C stack pointer. This is+ -- a break in the STG abstraction used exclusively to setup stack unwinding+ -- information.+ | MachSp++ -- The is a dummy register used to indicate to the stack unwinder where+ -- a routine would return to.+ | UnwindReturnReg++ -- Base Register for PIC (position-independent code) calculations+ -- Only used inside the native code generator. It's exact meaning differs+ -- from platform to platform (see module PositionIndependentCode).+ | PicBaseReg++ deriving( Show )++instance Eq GlobalReg where+ VanillaReg i _ == VanillaReg j _ = i==j -- Ignore type when seeking clashes+ FloatReg i == FloatReg j = i==j+ DoubleReg i == DoubleReg j = i==j+ LongReg i == LongReg j = i==j+ -- NOTE: XMM, YMM, ZMM registers actually are the same registers+ -- at least with respect to store at YMM i and then read from XMM i+ -- and similarly for ZMM etc.+ XmmReg i == XmmReg j = i==j+ YmmReg i == YmmReg j = i==j+ ZmmReg i == ZmmReg j = i==j+ Sp == Sp = True+ SpLim == SpLim = True+ Hp == Hp = True+ HpLim == HpLim = True+ CCCS == CCCS = True+ CurrentTSO == CurrentTSO = True+ CurrentNursery == CurrentNursery = True+ HpAlloc == HpAlloc = True+ EagerBlackholeInfo == EagerBlackholeInfo = True+ GCEnter1 == GCEnter1 = True+ GCFun == GCFun = True+ BaseReg == BaseReg = True+ MachSp == MachSp = True+ UnwindReturnReg == UnwindReturnReg = True+ PicBaseReg == PicBaseReg = True+ _r1 == _r2 = False++instance Ord GlobalReg where+ compare (VanillaReg i _) (VanillaReg j _) = compare i j+ -- Ignore type when seeking clashes+ compare (FloatReg i) (FloatReg j) = compare i j+ compare (DoubleReg i) (DoubleReg j) = compare i j+ compare (LongReg i) (LongReg j) = compare i j+ compare (XmmReg i) (XmmReg j) = compare i j+ compare (YmmReg i) (YmmReg j) = compare i j+ compare (ZmmReg i) (ZmmReg j) = compare i j+ compare Sp Sp = EQ+ compare SpLim SpLim = EQ+ compare Hp Hp = EQ+ compare HpLim HpLim = EQ+ compare CCCS CCCS = EQ+ compare CurrentTSO CurrentTSO = EQ+ compare CurrentNursery CurrentNursery = EQ+ compare HpAlloc HpAlloc = EQ+ compare EagerBlackholeInfo EagerBlackholeInfo = EQ+ compare GCEnter1 GCEnter1 = EQ+ compare GCFun GCFun = EQ+ compare BaseReg BaseReg = EQ+ compare MachSp MachSp = EQ+ compare UnwindReturnReg UnwindReturnReg = EQ+ compare PicBaseReg PicBaseReg = EQ+ compare (VanillaReg _ _) _ = LT+ compare _ (VanillaReg _ _) = GT+ compare (FloatReg _) _ = LT+ compare _ (FloatReg _) = GT+ compare (DoubleReg _) _ = LT+ compare _ (DoubleReg _) = GT+ compare (LongReg _) _ = LT+ compare _ (LongReg _) = GT+ compare (XmmReg _) _ = LT+ compare _ (XmmReg _) = GT+ compare (YmmReg _) _ = LT+ compare _ (YmmReg _) = GT+ compare (ZmmReg _) _ = LT+ compare _ (ZmmReg _) = GT+ compare Sp _ = LT+ compare _ Sp = GT+ compare SpLim _ = LT+ compare _ SpLim = GT+ compare Hp _ = LT+ compare _ Hp = GT+ compare HpLim _ = LT+ compare _ HpLim = GT+ compare CCCS _ = LT+ compare _ CCCS = GT+ compare CurrentTSO _ = LT+ compare _ CurrentTSO = GT+ compare CurrentNursery _ = LT+ compare _ CurrentNursery = GT+ compare HpAlloc _ = LT+ compare _ HpAlloc = GT+ compare GCEnter1 _ = LT+ compare _ GCEnter1 = GT+ compare GCFun _ = LT+ compare _ GCFun = GT+ compare BaseReg _ = LT+ compare _ BaseReg = GT+ compare MachSp _ = LT+ compare _ MachSp = GT+ compare UnwindReturnReg _ = LT+ compare _ UnwindReturnReg = GT+ compare EagerBlackholeInfo _ = LT+ compare _ EagerBlackholeInfo = GT++-- convenient aliases+baseReg, spReg, hpReg, spLimReg, hpLimReg, nodeReg,+ currentTSOReg, currentNurseryReg, hpAllocReg, cccsReg :: CmmReg+baseReg = CmmGlobal BaseReg+spReg = CmmGlobal Sp+hpReg = CmmGlobal Hp+hpLimReg = CmmGlobal HpLim+spLimReg = CmmGlobal SpLim+nodeReg = CmmGlobal node+currentTSOReg = CmmGlobal CurrentTSO+currentNurseryReg = CmmGlobal CurrentNursery+hpAllocReg = CmmGlobal HpAlloc+cccsReg = CmmGlobal CCCS++node :: GlobalReg+node = VanillaReg 1 VGcPtr++globalRegType :: DynFlags -> GlobalReg -> CmmType+globalRegType dflags (VanillaReg _ VGcPtr) = gcWord dflags+globalRegType dflags (VanillaReg _ VNonGcPtr) = bWord dflags+globalRegType _ (FloatReg _) = cmmFloat W32+globalRegType _ (DoubleReg _) = cmmFloat W64+globalRegType _ (LongReg _) = cmmBits W64+-- TODO: improve the internal model of SIMD/vectorized registers+-- the right design SHOULd improve handling of float and double code too.+-- see remarks in "NOTE [SIMD Design for the future]"" in GHC.StgToCmm.Prim+globalRegType _ (XmmReg _) = cmmVec 4 (cmmBits W32)+globalRegType _ (YmmReg _) = cmmVec 8 (cmmBits W32)+globalRegType _ (ZmmReg _) = cmmVec 16 (cmmBits W32)++globalRegType dflags Hp = gcWord dflags+ -- The initialiser for all+ -- dynamically allocated closures+globalRegType dflags _ = bWord dflags++isArgReg :: GlobalReg -> Bool+isArgReg (VanillaReg {}) = True+isArgReg (FloatReg {}) = True+isArgReg (DoubleReg {}) = True+isArgReg (LongReg {}) = True+isArgReg (XmmReg {}) = True+isArgReg (YmmReg {}) = True+isArgReg (ZmmReg {}) = True+isArgReg _ = False
+ compiler/GHC/Cmm/MachOp.hs view
@@ -0,0 +1,666 @@+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}++module GHC.Cmm.MachOp+ ( MachOp(..)+ , pprMachOp, isCommutableMachOp, isAssociativeMachOp+ , isComparisonMachOp, maybeIntComparison, machOpResultType+ , machOpArgReps, maybeInvertComparison, isFloatComparison++ -- MachOp builders+ , mo_wordAdd, mo_wordSub, mo_wordEq, mo_wordNe,mo_wordMul, mo_wordSQuot+ , mo_wordSRem, mo_wordSNeg, mo_wordUQuot, mo_wordURem+ , mo_wordSGe, mo_wordSLe, mo_wordSGt, mo_wordSLt, mo_wordUGe+ , mo_wordULe, mo_wordUGt, mo_wordULt+ , mo_wordAnd, mo_wordOr, mo_wordXor, mo_wordNot+ , mo_wordShl, mo_wordSShr, mo_wordUShr+ , mo_u_8To32, mo_s_8To32, mo_u_16To32, mo_s_16To32+ , mo_u_8ToWord, mo_s_8ToWord, mo_u_16ToWord, mo_s_16ToWord+ , mo_u_32ToWord, mo_s_32ToWord+ , mo_32To8, mo_32To16, mo_WordTo8, mo_WordTo16, mo_WordTo32, mo_WordTo64++ -- CallishMachOp+ , CallishMachOp(..), callishMachOpHints+ , pprCallishMachOp+ , machOpMemcpyishAlign++ -- Atomic read-modify-write+ , AtomicMachOp(..)+ )+where++import GhcPrelude++import GHC.Cmm.Type+import Outputable+import DynFlags++-----------------------------------------------------------------------------+-- MachOp+-----------------------------------------------------------------------------++{- |+Machine-level primops; ones which we can reasonably delegate to the+native code generators to handle.++Most operations are parameterised by the 'Width' that they operate on.+Some operations have separate signed and unsigned versions, and float+and integer versions.+-}++data MachOp+ -- Integer operations (insensitive to signed/unsigned)+ = MO_Add Width+ | MO_Sub Width+ | MO_Eq Width+ | MO_Ne Width+ | MO_Mul Width -- low word of multiply++ -- Signed multiply/divide+ | MO_S_MulMayOflo Width -- nonzero if signed multiply overflows+ | MO_S_Quot Width -- signed / (same semantics as IntQuotOp)+ | MO_S_Rem Width -- signed % (same semantics as IntRemOp)+ | MO_S_Neg Width -- unary -++ -- Unsigned multiply/divide+ | MO_U_MulMayOflo Width -- nonzero if unsigned multiply overflows+ | MO_U_Quot Width -- unsigned / (same semantics as WordQuotOp)+ | MO_U_Rem Width -- unsigned % (same semantics as WordRemOp)++ -- Signed comparisons+ | MO_S_Ge Width+ | MO_S_Le Width+ | MO_S_Gt Width+ | MO_S_Lt Width++ -- Unsigned comparisons+ | MO_U_Ge Width+ | MO_U_Le Width+ | MO_U_Gt Width+ | MO_U_Lt Width++ -- Floating point arithmetic+ | MO_F_Add Width+ | MO_F_Sub Width+ | MO_F_Neg Width -- unary -+ | MO_F_Mul Width+ | MO_F_Quot Width++ -- Floating point comparison+ | MO_F_Eq Width+ | MO_F_Ne Width+ | MO_F_Ge Width+ | MO_F_Le Width+ | MO_F_Gt Width+ | MO_F_Lt Width++ -- Bitwise operations. Not all of these may be supported+ -- at all sizes, and only integral Widths are valid.+ | MO_And Width+ | MO_Or Width+ | MO_Xor Width+ | MO_Not Width+ | MO_Shl Width+ | MO_U_Shr Width -- unsigned shift right+ | MO_S_Shr Width -- signed shift right++ -- Conversions. Some of these will be NOPs.+ -- Floating-point conversions use the signed variant.+ | MO_SF_Conv Width Width -- Signed int -> Float+ | MO_FS_Conv Width Width -- Float -> Signed int+ | MO_SS_Conv Width Width -- Signed int -> Signed int+ | MO_UU_Conv Width Width -- unsigned int -> unsigned int+ | MO_XX_Conv Width Width -- int -> int; puts no requirements on the+ -- contents of upper bits when extending;+ -- narrowing is simply truncation; the only+ -- expectation is that we can recover the+ -- original value by applying the opposite+ -- MO_XX_Conv, e.g.,+ -- MO_XX_CONV W64 W8 (MO_XX_CONV W8 W64 x)+ -- is equivalent to just x.+ | MO_FF_Conv Width Width -- Float -> Float++ -- Vector element insertion and extraction operations+ | MO_V_Insert Length Width -- Insert scalar into vector+ | MO_V_Extract Length Width -- Extract scalar from vector++ -- Integer vector operations+ | MO_V_Add Length Width+ | MO_V_Sub Length Width+ | MO_V_Mul Length Width++ -- Signed vector multiply/divide+ | MO_VS_Quot Length Width+ | MO_VS_Rem Length Width+ | MO_VS_Neg Length Width++ -- Unsigned vector multiply/divide+ | MO_VU_Quot Length Width+ | MO_VU_Rem Length Width++ -- Floating point vector element insertion and extraction operations+ | MO_VF_Insert Length Width -- Insert scalar into vector+ | MO_VF_Extract Length Width -- Extract scalar from vector++ -- Floating point vector operations+ | MO_VF_Add Length Width+ | MO_VF_Sub Length Width+ | MO_VF_Neg Length Width -- unary negation+ | MO_VF_Mul Length Width+ | MO_VF_Quot Length Width++ -- Alignment check (for -falignment-sanitisation)+ | MO_AlignmentCheck Int Width+ deriving (Eq, Show)++pprMachOp :: MachOp -> SDoc+pprMachOp mo = text (show mo)++++-- -----------------------------------------------------------------------------+-- Some common MachReps++-- A 'wordRep' is a machine word on the target architecture+-- Specifically, it is the size of an Int#, Word#, Addr#+-- and the unit of allocation on the stack and the heap+-- Any pointer is also guaranteed to be a wordRep.++mo_wordAdd, mo_wordSub, mo_wordEq, mo_wordNe,mo_wordMul, mo_wordSQuot+ , mo_wordSRem, mo_wordSNeg, mo_wordUQuot, mo_wordURem+ , mo_wordSGe, mo_wordSLe, mo_wordSGt, mo_wordSLt, mo_wordUGe+ , mo_wordULe, mo_wordUGt, mo_wordULt+ , mo_wordAnd, mo_wordOr, mo_wordXor, mo_wordNot, mo_wordShl, mo_wordSShr, mo_wordUShr+ , mo_u_8ToWord, mo_s_8ToWord, mo_u_16ToWord, mo_s_16ToWord, mo_u_32ToWord, mo_s_32ToWord+ , mo_WordTo8, mo_WordTo16, mo_WordTo32, mo_WordTo64+ :: DynFlags -> MachOp++mo_u_8To32, mo_s_8To32, mo_u_16To32, mo_s_16To32+ , mo_32To8, mo_32To16+ :: MachOp++mo_wordAdd dflags = MO_Add (wordWidth dflags)+mo_wordSub dflags = MO_Sub (wordWidth dflags)+mo_wordEq dflags = MO_Eq (wordWidth dflags)+mo_wordNe dflags = MO_Ne (wordWidth dflags)+mo_wordMul dflags = MO_Mul (wordWidth dflags)+mo_wordSQuot dflags = MO_S_Quot (wordWidth dflags)+mo_wordSRem dflags = MO_S_Rem (wordWidth dflags)+mo_wordSNeg dflags = MO_S_Neg (wordWidth dflags)+mo_wordUQuot dflags = MO_U_Quot (wordWidth dflags)+mo_wordURem dflags = MO_U_Rem (wordWidth dflags)++mo_wordSGe dflags = MO_S_Ge (wordWidth dflags)+mo_wordSLe dflags = MO_S_Le (wordWidth dflags)+mo_wordSGt dflags = MO_S_Gt (wordWidth dflags)+mo_wordSLt dflags = MO_S_Lt (wordWidth dflags)++mo_wordUGe dflags = MO_U_Ge (wordWidth dflags)+mo_wordULe dflags = MO_U_Le (wordWidth dflags)+mo_wordUGt dflags = MO_U_Gt (wordWidth dflags)+mo_wordULt dflags = MO_U_Lt (wordWidth dflags)++mo_wordAnd dflags = MO_And (wordWidth dflags)+mo_wordOr dflags = MO_Or (wordWidth dflags)+mo_wordXor dflags = MO_Xor (wordWidth dflags)+mo_wordNot dflags = MO_Not (wordWidth dflags)+mo_wordShl dflags = MO_Shl (wordWidth dflags)+mo_wordSShr dflags = MO_S_Shr (wordWidth dflags)+mo_wordUShr dflags = MO_U_Shr (wordWidth dflags)++mo_u_8To32 = MO_UU_Conv W8 W32+mo_s_8To32 = MO_SS_Conv W8 W32+mo_u_16To32 = MO_UU_Conv W16 W32+mo_s_16To32 = MO_SS_Conv W16 W32++mo_u_8ToWord dflags = MO_UU_Conv W8 (wordWidth dflags)+mo_s_8ToWord dflags = MO_SS_Conv W8 (wordWidth dflags)+mo_u_16ToWord dflags = MO_UU_Conv W16 (wordWidth dflags)+mo_s_16ToWord dflags = MO_SS_Conv W16 (wordWidth dflags)+mo_s_32ToWord dflags = MO_SS_Conv W32 (wordWidth dflags)+mo_u_32ToWord dflags = MO_UU_Conv W32 (wordWidth dflags)++mo_WordTo8 dflags = MO_UU_Conv (wordWidth dflags) W8+mo_WordTo16 dflags = MO_UU_Conv (wordWidth dflags) W16+mo_WordTo32 dflags = MO_UU_Conv (wordWidth dflags) W32+mo_WordTo64 dflags = MO_UU_Conv (wordWidth dflags) W64++mo_32To8 = MO_UU_Conv W32 W8+mo_32To16 = MO_UU_Conv W32 W16+++-- ----------------------------------------------------------------------------+-- isCommutableMachOp++{- |+Returns 'True' if the MachOp has commutable arguments. This is used+in the platform-independent Cmm optimisations.++If in doubt, return 'False'. This generates worse code on the+native routes, but is otherwise harmless.+-}+isCommutableMachOp :: MachOp -> Bool+isCommutableMachOp mop =+ case mop of+ MO_Add _ -> True+ MO_Eq _ -> True+ MO_Ne _ -> True+ MO_Mul _ -> True+ MO_S_MulMayOflo _ -> True+ MO_U_MulMayOflo _ -> True+ MO_And _ -> True+ MO_Or _ -> True+ MO_Xor _ -> True+ MO_F_Add _ -> True+ MO_F_Mul _ -> True+ _other -> False++-- ----------------------------------------------------------------------------+-- isAssociativeMachOp++{- |+Returns 'True' if the MachOp is associative (i.e. @(x+y)+z == x+(y+z)@)+This is used in the platform-independent Cmm optimisations.++If in doubt, return 'False'. This generates worse code on the+native routes, but is otherwise harmless.+-}+isAssociativeMachOp :: MachOp -> Bool+isAssociativeMachOp mop =+ case mop of+ MO_Add {} -> True -- NB: does not include+ MO_Mul {} -> True -- floatint point!+ MO_And {} -> True+ MO_Or {} -> True+ MO_Xor {} -> True+ _other -> False+++-- ----------------------------------------------------------------------------+-- isComparisonMachOp++{- |+Returns 'True' if the MachOp is a comparison.++If in doubt, return False. This generates worse code on the+native routes, but is otherwise harmless.+-}+isComparisonMachOp :: MachOp -> Bool+isComparisonMachOp mop =+ case mop of+ MO_Eq _ -> True+ MO_Ne _ -> True+ MO_S_Ge _ -> True+ MO_S_Le _ -> True+ MO_S_Gt _ -> True+ MO_S_Lt _ -> True+ MO_U_Ge _ -> True+ MO_U_Le _ -> True+ MO_U_Gt _ -> True+ MO_U_Lt _ -> True+ MO_F_Eq {} -> True+ MO_F_Ne {} -> True+ MO_F_Ge {} -> True+ MO_F_Le {} -> True+ MO_F_Gt {} -> True+ MO_F_Lt {} -> True+ _other -> False++{- |+Returns @Just w@ if the operation is an integer comparison with width+@w@, or @Nothing@ otherwise.+-}+maybeIntComparison :: MachOp -> Maybe Width+maybeIntComparison mop =+ case mop of+ MO_Eq w -> Just w+ MO_Ne w -> Just w+ MO_S_Ge w -> Just w+ MO_S_Le w -> Just w+ MO_S_Gt w -> Just w+ MO_S_Lt w -> Just w+ MO_U_Ge w -> Just w+ MO_U_Le w -> Just w+ MO_U_Gt w -> Just w+ MO_U_Lt w -> Just w+ _ -> Nothing++isFloatComparison :: MachOp -> Bool+isFloatComparison mop =+ case mop of+ MO_F_Eq {} -> True+ MO_F_Ne {} -> True+ MO_F_Ge {} -> True+ MO_F_Le {} -> True+ MO_F_Gt {} -> True+ MO_F_Lt {} -> True+ _other -> False++-- -----------------------------------------------------------------------------+-- Inverting conditions++-- Sometimes it's useful to be able to invert the sense of a+-- condition. Not all conditional tests are invertible: in+-- particular, floating point conditionals cannot be inverted, because+-- there exist floating-point values which return False for both senses+-- of a condition (eg. !(NaN > NaN) && !(NaN /<= NaN)).++maybeInvertComparison :: MachOp -> Maybe MachOp+maybeInvertComparison op+ = case op of -- None of these Just cases include floating point+ MO_Eq r -> Just (MO_Ne r)+ MO_Ne r -> Just (MO_Eq r)+ MO_U_Lt r -> Just (MO_U_Ge r)+ MO_U_Gt r -> Just (MO_U_Le r)+ MO_U_Le r -> Just (MO_U_Gt r)+ MO_U_Ge r -> Just (MO_U_Lt r)+ MO_S_Lt r -> Just (MO_S_Ge r)+ MO_S_Gt r -> Just (MO_S_Le r)+ MO_S_Le r -> Just (MO_S_Gt r)+ MO_S_Ge r -> Just (MO_S_Lt r)+ _other -> Nothing++-- ----------------------------------------------------------------------------+-- machOpResultType++{- |+Returns the MachRep of the result of a MachOp.+-}+machOpResultType :: DynFlags -> MachOp -> [CmmType] -> CmmType+machOpResultType dflags mop tys =+ case mop of+ MO_Add {} -> ty1 -- Preserve GC-ptr-hood+ MO_Sub {} -> ty1 -- of first arg+ MO_Mul r -> cmmBits r+ MO_S_MulMayOflo r -> cmmBits r+ MO_S_Quot r -> cmmBits r+ MO_S_Rem r -> cmmBits r+ MO_S_Neg r -> cmmBits r+ MO_U_MulMayOflo r -> cmmBits r+ MO_U_Quot r -> cmmBits r+ MO_U_Rem r -> cmmBits r++ MO_Eq {} -> comparisonResultRep dflags+ MO_Ne {} -> comparisonResultRep dflags+ MO_S_Ge {} -> comparisonResultRep dflags+ MO_S_Le {} -> comparisonResultRep dflags+ MO_S_Gt {} -> comparisonResultRep dflags+ MO_S_Lt {} -> comparisonResultRep dflags++ MO_U_Ge {} -> comparisonResultRep dflags+ MO_U_Le {} -> comparisonResultRep dflags+ MO_U_Gt {} -> comparisonResultRep dflags+ MO_U_Lt {} -> comparisonResultRep dflags++ MO_F_Add r -> cmmFloat r+ MO_F_Sub r -> cmmFloat r+ MO_F_Mul r -> cmmFloat r+ MO_F_Quot r -> cmmFloat r+ MO_F_Neg r -> cmmFloat r+ MO_F_Eq {} -> comparisonResultRep dflags+ MO_F_Ne {} -> comparisonResultRep dflags+ MO_F_Ge {} -> comparisonResultRep dflags+ MO_F_Le {} -> comparisonResultRep dflags+ MO_F_Gt {} -> comparisonResultRep dflags+ MO_F_Lt {} -> comparisonResultRep dflags++ MO_And {} -> ty1 -- Used for pointer masking+ MO_Or {} -> ty1+ MO_Xor {} -> ty1+ MO_Not r -> cmmBits r+ MO_Shl r -> cmmBits r+ MO_U_Shr r -> cmmBits r+ MO_S_Shr r -> cmmBits r++ MO_SS_Conv _ to -> cmmBits to+ MO_UU_Conv _ to -> cmmBits to+ MO_XX_Conv _ to -> cmmBits to+ MO_FS_Conv _ to -> cmmBits to+ MO_SF_Conv _ to -> cmmFloat to+ MO_FF_Conv _ to -> cmmFloat to++ MO_V_Insert l w -> cmmVec l (cmmBits w)+ MO_V_Extract _ w -> cmmBits w++ MO_V_Add l w -> cmmVec l (cmmBits w)+ MO_V_Sub l w -> cmmVec l (cmmBits w)+ MO_V_Mul l w -> cmmVec l (cmmBits w)++ MO_VS_Quot l w -> cmmVec l (cmmBits w)+ MO_VS_Rem l w -> cmmVec l (cmmBits w)+ MO_VS_Neg l w -> cmmVec l (cmmBits w)++ MO_VU_Quot l w -> cmmVec l (cmmBits w)+ MO_VU_Rem l w -> cmmVec l (cmmBits w)++ MO_VF_Insert l w -> cmmVec l (cmmFloat w)+ MO_VF_Extract _ w -> cmmFloat w++ MO_VF_Add l w -> cmmVec l (cmmFloat w)+ MO_VF_Sub l w -> cmmVec l (cmmFloat w)+ MO_VF_Mul l w -> cmmVec l (cmmFloat w)+ MO_VF_Quot l w -> cmmVec l (cmmFloat w)+ MO_VF_Neg l w -> cmmVec l (cmmFloat w)++ MO_AlignmentCheck _ _ -> ty1+ where+ (ty1:_) = tys++comparisonResultRep :: DynFlags -> CmmType+comparisonResultRep = bWord -- is it?+++-- -----------------------------------------------------------------------------+-- machOpArgReps++-- | This function is used for debugging only: we can check whether an+-- application of a MachOp is "type-correct" by checking that the MachReps of+-- its arguments are the same as the MachOp expects. This is used when+-- linting a CmmExpr.++machOpArgReps :: DynFlags -> MachOp -> [Width]+machOpArgReps dflags op =+ case op of+ MO_Add r -> [r,r]+ MO_Sub r -> [r,r]+ MO_Eq r -> [r,r]+ MO_Ne r -> [r,r]+ MO_Mul r -> [r,r]+ MO_S_MulMayOflo r -> [r,r]+ MO_S_Quot r -> [r,r]+ MO_S_Rem r -> [r,r]+ MO_S_Neg r -> [r]+ MO_U_MulMayOflo r -> [r,r]+ MO_U_Quot r -> [r,r]+ MO_U_Rem r -> [r,r]++ MO_S_Ge r -> [r,r]+ MO_S_Le r -> [r,r]+ MO_S_Gt r -> [r,r]+ MO_S_Lt r -> [r,r]++ MO_U_Ge r -> [r,r]+ MO_U_Le r -> [r,r]+ MO_U_Gt r -> [r,r]+ MO_U_Lt r -> [r,r]++ MO_F_Add r -> [r,r]+ MO_F_Sub r -> [r,r]+ MO_F_Mul r -> [r,r]+ MO_F_Quot r -> [r,r]+ MO_F_Neg r -> [r]+ MO_F_Eq r -> [r,r]+ MO_F_Ne r -> [r,r]+ MO_F_Ge r -> [r,r]+ MO_F_Le r -> [r,r]+ MO_F_Gt r -> [r,r]+ MO_F_Lt r -> [r,r]++ MO_And r -> [r,r]+ MO_Or r -> [r,r]+ MO_Xor r -> [r,r]+ MO_Not r -> [r]+ MO_Shl r -> [r, wordWidth dflags]+ MO_U_Shr r -> [r, wordWidth dflags]+ MO_S_Shr r -> [r, wordWidth dflags]++ MO_SS_Conv from _ -> [from]+ MO_UU_Conv from _ -> [from]+ MO_XX_Conv from _ -> [from]+ MO_SF_Conv from _ -> [from]+ MO_FS_Conv from _ -> [from]+ MO_FF_Conv from _ -> [from]++ MO_V_Insert l r -> [typeWidth (vec l (cmmBits r)),r,wordWidth dflags]+ MO_V_Extract l r -> [typeWidth (vec l (cmmBits r)),wordWidth dflags]++ MO_V_Add _ r -> [r,r]+ MO_V_Sub _ r -> [r,r]+ MO_V_Mul _ r -> [r,r]++ MO_VS_Quot _ r -> [r,r]+ MO_VS_Rem _ r -> [r,r]+ MO_VS_Neg _ r -> [r]++ MO_VU_Quot _ r -> [r,r]+ MO_VU_Rem _ r -> [r,r]++ MO_VF_Insert l r -> [typeWidth (vec l (cmmFloat r)),r,wordWidth dflags]+ MO_VF_Extract l r -> [typeWidth (vec l (cmmFloat r)),wordWidth dflags]++ MO_VF_Add _ r -> [r,r]+ MO_VF_Sub _ r -> [r,r]+ MO_VF_Mul _ r -> [r,r]+ MO_VF_Quot _ r -> [r,r]+ MO_VF_Neg _ r -> [r]++ MO_AlignmentCheck _ r -> [r]++-----------------------------------------------------------------------------+-- CallishMachOp+-----------------------------------------------------------------------------++-- CallishMachOps tend to be implemented by foreign calls in some backends,+-- so we separate them out. In Cmm, these can only occur in a+-- statement position, in contrast to an ordinary MachOp which can occur+-- anywhere in an expression.+data CallishMachOp+ = MO_F64_Pwr+ | MO_F64_Sin+ | MO_F64_Cos+ | MO_F64_Tan+ | MO_F64_Sinh+ | MO_F64_Cosh+ | MO_F64_Tanh+ | MO_F64_Asin+ | MO_F64_Acos+ | MO_F64_Atan+ | MO_F64_Asinh+ | MO_F64_Acosh+ | MO_F64_Atanh+ | MO_F64_Log+ | MO_F64_Log1P+ | MO_F64_Exp+ | MO_F64_ExpM1+ | MO_F64_Fabs+ | MO_F64_Sqrt+ | MO_F32_Pwr+ | MO_F32_Sin+ | MO_F32_Cos+ | MO_F32_Tan+ | MO_F32_Sinh+ | MO_F32_Cosh+ | MO_F32_Tanh+ | MO_F32_Asin+ | MO_F32_Acos+ | MO_F32_Atan+ | MO_F32_Asinh+ | MO_F32_Acosh+ | MO_F32_Atanh+ | MO_F32_Log+ | MO_F32_Log1P+ | MO_F32_Exp+ | MO_F32_ExpM1+ | MO_F32_Fabs+ | MO_F32_Sqrt++ | MO_UF_Conv Width++ | MO_S_Mul2 Width+ | MO_S_QuotRem Width+ | MO_U_QuotRem Width+ | MO_U_QuotRem2 Width+ | MO_Add2 Width+ | MO_AddWordC Width+ | MO_SubWordC Width+ | MO_AddIntC Width+ | MO_SubIntC Width+ | MO_U_Mul2 Width++ | MO_ReadBarrier+ | MO_WriteBarrier+ | MO_Touch -- Keep variables live (when using interior pointers)++ -- Prefetch+ | MO_Prefetch_Data Int -- Prefetch hint. May change program performance but not+ -- program behavior.+ -- the Int can be 0-3. Needs to be known at compile time+ -- to interact with code generation correctly.+ -- TODO: add support for prefetch WRITES,+ -- currently only exposes prefetch reads, which+ -- would the majority of use cases in ghc anyways+++ -- These three MachOps are parameterised by the known alignment+ -- of the destination and source (for memcpy/memmove) pointers.+ -- This information may be used for optimisation in backends.+ | MO_Memcpy Int+ | MO_Memset Int+ | MO_Memmove Int+ | MO_Memcmp Int++ | MO_PopCnt Width+ | MO_Pdep Width+ | MO_Pext Width+ | MO_Clz Width+ | MO_Ctz Width++ | MO_BSwap Width+ | MO_BRev Width++ -- Atomic read-modify-write.+ | MO_AtomicRMW Width AtomicMachOp+ | MO_AtomicRead Width+ | MO_AtomicWrite Width+ | MO_Cmpxchg Width+ deriving (Eq, Show)++-- | The operation to perform atomically.+data AtomicMachOp =+ AMO_Add+ | AMO_Sub+ | AMO_And+ | AMO_Nand+ | AMO_Or+ | AMO_Xor+ deriving (Eq, Show)++pprCallishMachOp :: CallishMachOp -> SDoc+pprCallishMachOp mo = text (show mo)++callishMachOpHints :: CallishMachOp -> ([ForeignHint], [ForeignHint])+callishMachOpHints op = case op of+ MO_Memcpy _ -> ([], [AddrHint,AddrHint,NoHint])+ MO_Memset _ -> ([], [AddrHint,NoHint,NoHint])+ MO_Memmove _ -> ([], [AddrHint,AddrHint,NoHint])+ MO_Memcmp _ -> ([], [AddrHint, AddrHint, NoHint])+ _ -> ([],[])+ -- empty lists indicate NoHint++-- | The alignment of a 'memcpy'-ish operation.+machOpMemcpyishAlign :: CallishMachOp -> Maybe Int+machOpMemcpyishAlign op = case op of+ MO_Memcpy align -> Just align+ MO_Memset align -> Just align+ MO_Memmove align -> Just align+ MO_Memcmp align -> Just align+ _ -> Nothing
+ compiler/GHC/Cmm/Node.hs view
@@ -0,0 +1,726 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE ExplicitForAll #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}++{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}++-- CmmNode type for representation using Hoopl graphs.++module GHC.Cmm.Node (+ CmmNode(..), CmmFormal, CmmActual, CmmTickish,+ UpdFrameOffset, Convention(..),+ ForeignConvention(..), ForeignTarget(..), foreignTargetHints,+ CmmReturnInfo(..),+ mapExp, mapExpDeep, wrapRecExp, foldExp, foldExpDeep, wrapRecExpf,+ mapExpM, mapExpDeepM, wrapRecExpM, mapSuccessors, mapCollectSuccessors,++ -- * Tick scopes+ CmmTickScope(..), isTickSubScope, combineTickScopes,+ ) where++import GhcPrelude hiding (succ)++import GHC.Platform.Regs+import GHC.Cmm.Expr+import GHC.Cmm.Switch+import DynFlags+import FastString+import ForeignCall+import Outputable+import GHC.Runtime.Layout+import CoreSyn (Tickish)+import qualified Unique as U++import GHC.Cmm.Dataflow.Block+import GHC.Cmm.Dataflow.Graph+import GHC.Cmm.Dataflow.Collections+import GHC.Cmm.Dataflow.Label+import Data.Maybe+import Data.List (tails,sortBy)+import Unique (nonDetCmpUnique)+import Util+++------------------------+-- CmmNode++#define ULabel {-# UNPACK #-} !Label++data CmmNode e x where+ CmmEntry :: ULabel -> CmmTickScope -> CmmNode C O++ CmmComment :: FastString -> CmmNode O O++ -- Tick annotation, covering Cmm code in our tick scope. We only+ -- expect non-code @Tickish@ at this point (e.g. @SourceNote@).+ -- See Note [CmmTick scoping details]+ CmmTick :: !CmmTickish -> CmmNode O O++ -- Unwind pseudo-instruction, encoding stack unwinding+ -- instructions for a debugger. This describes how to reconstruct+ -- the "old" value of a register if we want to navigate the stack+ -- up one frame. Having unwind information for @Sp@ will allow the+ -- debugger to "walk" the stack.+ --+ -- See Note [What is this unwinding business?] in Debug+ CmmUnwind :: [(GlobalReg, Maybe CmmExpr)] -> CmmNode O O++ CmmAssign :: !CmmReg -> !CmmExpr -> CmmNode O O+ -- Assign to register++ CmmStore :: !CmmExpr -> !CmmExpr -> CmmNode O O+ -- Assign to memory location. Size is+ -- given by cmmExprType of the rhs.++ CmmUnsafeForeignCall :: -- An unsafe foreign call;+ -- see Note [Foreign calls]+ -- Like a "fat machine instruction"; can occur+ -- in the middle of a block+ ForeignTarget -> -- call target+ [CmmFormal] -> -- zero or more results+ [CmmActual] -> -- zero or more arguments+ CmmNode O O+ -- Semantics: clobbers any GlobalRegs for which callerSaves r == True+ -- See Note [Unsafe foreign calls clobber caller-save registers]+ --+ -- Invariant: the arguments and the ForeignTarget must not+ -- mention any registers for which GHC.Platform.callerSaves+ -- is True. See Note [Register Parameter Passing].++ CmmBranch :: ULabel -> CmmNode O C+ -- Goto another block in the same procedure++ CmmCondBranch :: { -- conditional branch+ cml_pred :: CmmExpr,+ cml_true, cml_false :: ULabel,+ cml_likely :: Maybe Bool -- likely result of the conditional,+ -- if known+ } -> CmmNode O C++ CmmSwitch+ :: CmmExpr -- Scrutinee, of some integral type+ -> SwitchTargets -- Cases. See [Note SwitchTargets]+ -> CmmNode O C++ CmmCall :: { -- A native call or tail call+ cml_target :: CmmExpr, -- never a CmmPrim to a CallishMachOp!++ cml_cont :: Maybe Label,+ -- Label of continuation (Nothing for return or tail call)+ --+ -- Note [Continuation BlockIds]: these BlockIds are called+ -- Continuation BlockIds, and are the only BlockIds that can+ -- occur in CmmExprs, namely as (CmmLit (CmmBlock b)) or+ -- (CmmStackSlot (Young b) _).++ cml_args_regs :: [GlobalReg],+ -- The argument GlobalRegs (Rx, Fx, Dx, Lx) that are passed+ -- to the call. This is essential information for the+ -- native code generator's register allocator; without+ -- knowing which GlobalRegs are live it has to assume that+ -- they are all live. This list should only include+ -- GlobalRegs that are mapped to real machine registers on+ -- the target platform.++ cml_args :: ByteOff,+ -- Byte offset, from the *old* end of the Area associated with+ -- the Label (if cml_cont = Nothing, then Old area), of+ -- youngest outgoing arg. Set the stack pointer to this before+ -- transferring control.+ -- (NB: an update frame might also have been stored in the Old+ -- area, but it'll be in an older part than the args.)++ cml_ret_args :: ByteOff,+ -- For calls *only*, the byte offset for youngest returned value+ -- This is really needed at the *return* point rather than here+ -- at the call, but in practice it's convenient to record it here.++ cml_ret_off :: ByteOff+ -- For calls *only*, the byte offset of the base of the frame that+ -- must be described by the info table for the return point.+ -- The older words are an update frames, which have their own+ -- info-table and layout information++ -- From a liveness point of view, the stack words older than+ -- cml_ret_off are treated as live, even if the sequel of+ -- the call goes into a loop.+ } -> CmmNode O C++ CmmForeignCall :: { -- A safe foreign call; see Note [Foreign calls]+ -- Always the last node of a block+ tgt :: ForeignTarget, -- call target and convention+ res :: [CmmFormal], -- zero or more results+ args :: [CmmActual], -- zero or more arguments; see Note [Register parameter passing]+ succ :: ULabel, -- Label of continuation+ ret_args :: ByteOff, -- same as cml_ret_args+ ret_off :: ByteOff, -- same as cml_ret_off+ intrbl:: Bool -- whether or not the call is interruptible+ } -> CmmNode O C++{- Note [Foreign calls]+~~~~~~~~~~~~~~~~~~~~~~~+A CmmUnsafeForeignCall is used for *unsafe* foreign calls;+a CmmForeignCall call is used for *safe* foreign calls.++Unsafe ones are mostly easy: think of them as a "fat machine+instruction". In particular, they do *not* kill all live registers,+just the registers they return to (there was a bit of code in GHC that+conservatively assumed otherwise.) However, see [Register parameter passing].++Safe ones are trickier. A safe foreign call+ r = f(x)+ultimately expands to+ push "return address" -- Never used to return to;+ -- just points an info table+ save registers into TSO+ call suspendThread+ r = f(x) -- Make the call+ call resumeThread+ restore registers+ pop "return address"+We cannot "lower" a safe foreign call to this sequence of Cmms, because+after we've saved Sp all the Cmm optimiser's assumptions are broken.++Note that a safe foreign call needs an info table.++So Safe Foreign Calls must remain as last nodes until the stack is+made manifest in GHC.Cmm.LayoutStack, where they are lowered into the above+sequence.+-}++{- Note [Unsafe foreign calls clobber caller-save registers]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A foreign call is defined to clobber any GlobalRegs that are mapped to+caller-saves machine registers (according to the prevailing C ABI).+GHC.StgToCmm.Utils.callerSaves tells you which GlobalRegs are caller-saves.++This is a design choice that makes it easier to generate code later.+We could instead choose to say that foreign calls do *not* clobber+caller-saves regs, but then we would have to figure out which regs+were live across the call later and insert some saves/restores.++Furthermore when we generate code we never have any GlobalRegs live+across a call, because they are always copied-in to LocalRegs and+copied-out again before making a call/jump. So all we have to do is+avoid any code motion that would make a caller-saves GlobalReg live+across a foreign call during subsequent optimisations.+-}++{- Note [Register parameter passing]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+On certain architectures, some registers are utilized for parameter+passing in the C calling convention. For example, in x86-64 Linux+convention, rdi, rsi, rdx and rcx (as well as r8 and r9) may be used for+argument passing. These are registers R3-R6, which our generated+code may also be using; as a result, it's necessary to save these+values before doing a foreign call. This is done during initial+code generation in callerSaveVolatileRegs in GHC.StgToCmm.Utils. However,+one result of doing this is that the contents of these registers+may mysteriously change if referenced inside the arguments. This+is dangerous, so you'll need to disable inlining much in the same+way is done in GHC.Cmm.Opt currently. We should fix this!+-}++---------------------------------------------+-- Eq instance of CmmNode++deriving instance Eq (CmmNode e x)++----------------------------------------------+-- Hoopl instances of CmmNode++instance NonLocal CmmNode where+ entryLabel (CmmEntry l _) = l++ successors (CmmBranch l) = [l]+ successors (CmmCondBranch {cml_true=t, cml_false=f}) = [f, t] -- meets layout constraint+ successors (CmmSwitch _ ids) = switchTargetsToList ids+ successors (CmmCall {cml_cont=l}) = maybeToList l+ successors (CmmForeignCall {succ=l}) = [l]+++--------------------------------------------------+-- Various helper types++type CmmActual = CmmExpr+type CmmFormal = LocalReg++type UpdFrameOffset = ByteOff++-- | A convention maps a list of values (function arguments or return+-- values) to registers or stack locations.+data Convention+ = NativeDirectCall+ -- ^ top-level Haskell functions use @NativeDirectCall@, which+ -- maps arguments to registers starting with R2, according to+ -- how many registers are available on the platform. This+ -- convention ignores R1, because for a top-level function call+ -- the function closure is implicit, and doesn't need to be passed.+ | NativeNodeCall+ -- ^ non-top-level Haskell functions, which pass the address of+ -- the function closure in R1 (regardless of whether R1 is a+ -- real register or not), and the rest of the arguments in+ -- registers or on the stack.+ | NativeReturn+ -- ^ a native return. The convention for returns depends on+ -- how many values are returned: for just one value returned,+ -- the appropriate register is used (R1, F1, etc.). regardless+ -- of whether it is a real register or not. For multiple+ -- values returned, they are mapped to registers or the stack.+ | Slow+ -- ^ Slow entry points: all args pushed on the stack+ | GC+ -- ^ Entry to the garbage collector: uses the node reg!+ -- (TODO: I don't think we need this --SDM)+ deriving( Eq )++data ForeignConvention+ = ForeignConvention+ CCallConv -- Which foreign-call convention+ [ForeignHint] -- Extra info about the args+ [ForeignHint] -- Extra info about the result+ CmmReturnInfo+ deriving Eq++data CmmReturnInfo+ = CmmMayReturn+ | CmmNeverReturns+ deriving ( Eq )++data ForeignTarget -- The target of a foreign call+ = ForeignTarget -- A foreign procedure+ CmmExpr -- Its address+ ForeignConvention -- Its calling convention+ | PrimTarget -- A possibly-side-effecting machine operation+ CallishMachOp -- Which one+ deriving Eq++foreignTargetHints :: ForeignTarget -> ([ForeignHint], [ForeignHint])+foreignTargetHints target+ = ( res_hints ++ repeat NoHint+ , arg_hints ++ repeat NoHint )+ where+ (res_hints, arg_hints) =+ case target of+ PrimTarget op -> callishMachOpHints op+ ForeignTarget _ (ForeignConvention _ arg_hints res_hints _) ->+ (res_hints, arg_hints)++--------------------------------------------------+-- Instances of register and slot users / definers++instance UserOfRegs LocalReg (CmmNode e x) where+ foldRegsUsed dflags f !z n = case n of+ CmmAssign _ expr -> fold f z expr+ CmmStore addr rval -> fold f (fold f z addr) rval+ CmmUnsafeForeignCall t _ args -> fold f (fold f z t) args+ CmmCondBranch expr _ _ _ -> fold f z expr+ CmmSwitch expr _ -> fold f z expr+ CmmCall {cml_target=tgt} -> fold f z tgt+ CmmForeignCall {tgt=tgt, args=args} -> fold f (fold f z tgt) args+ _ -> z+ where fold :: forall a b. UserOfRegs LocalReg a+ => (b -> LocalReg -> b) -> b -> a -> b+ fold f z n = foldRegsUsed dflags f z n++instance UserOfRegs GlobalReg (CmmNode e x) where+ foldRegsUsed dflags f !z n = case n of+ CmmAssign _ expr -> fold f z expr+ CmmStore addr rval -> fold f (fold f z addr) rval+ CmmUnsafeForeignCall t _ args -> fold f (fold f z t) args+ CmmCondBranch expr _ _ _ -> fold f z expr+ CmmSwitch expr _ -> fold f z expr+ CmmCall {cml_target=tgt, cml_args_regs=args} -> fold f (fold f z args) tgt+ CmmForeignCall {tgt=tgt, args=args} -> fold f (fold f z tgt) args+ _ -> z+ where fold :: forall a b. UserOfRegs GlobalReg a+ => (b -> GlobalReg -> b) -> b -> a -> b+ fold f z n = foldRegsUsed dflags f z n++instance (Ord r, UserOfRegs r CmmReg) => UserOfRegs r ForeignTarget where+ -- The (Ord r) in the context is necessary here+ -- See Note [Recursive superclasses] in TcInstDcls+ foldRegsUsed _ _ !z (PrimTarget _) = z+ foldRegsUsed dflags f !z (ForeignTarget e _) = foldRegsUsed dflags f z e++instance DefinerOfRegs LocalReg (CmmNode e x) where+ foldRegsDefd dflags f !z n = case n of+ CmmAssign lhs _ -> fold f z lhs+ CmmUnsafeForeignCall _ fs _ -> fold f z fs+ CmmForeignCall {res=res} -> fold f z res+ _ -> z+ where fold :: forall a b. DefinerOfRegs LocalReg a+ => (b -> LocalReg -> b) -> b -> a -> b+ fold f z n = foldRegsDefd dflags f z n++instance DefinerOfRegs GlobalReg (CmmNode e x) where+ foldRegsDefd dflags f !z n = case n of+ CmmAssign lhs _ -> fold f z lhs+ CmmUnsafeForeignCall tgt _ _ -> fold f z (foreignTargetRegs tgt)+ CmmCall {} -> fold f z activeRegs+ CmmForeignCall {} -> fold f z activeRegs+ -- See Note [Safe foreign calls clobber STG registers]+ _ -> z+ where fold :: forall a b. DefinerOfRegs GlobalReg a+ => (b -> GlobalReg -> b) -> b -> a -> b+ fold f z n = foldRegsDefd dflags f z n++ platform = targetPlatform dflags+ activeRegs = activeStgRegs platform+ activeCallerSavesRegs = filter (callerSaves platform) activeRegs++ foreignTargetRegs (ForeignTarget _ (ForeignConvention _ _ _ CmmNeverReturns)) = []+ foreignTargetRegs _ = activeCallerSavesRegs++-- Note [Safe foreign calls clobber STG registers]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+--+-- During stack layout phase every safe foreign call is expanded into a block+-- that contains unsafe foreign call (instead of safe foreign call) and ends+-- with a normal call (See Note [Foreign calls]). This means that we must+-- treat safe foreign call as if it was a normal call (because eventually it+-- will be). This is important if we try to run sinking pass before stack+-- layout phase. Consider this example of what might go wrong (this is cmm+-- code from stablename001 test). Here is code after common block elimination+-- (before stack layout):+--+-- c1q6:+-- _s1pf::P64 = R1;+-- _c1q8::I64 = performMajorGC;+-- I64[(young<c1q9> + 8)] = c1q9;+-- foreign call "ccall" arg hints: [] result hints: [] (_c1q8::I64)(...)+-- returns to c1q9 args: ([]) ress: ([])ret_args: 8ret_off: 8;+-- c1q9:+-- I64[(young<c1qb> + 8)] = c1qb;+-- R1 = _s1pc::P64;+-- call stg_makeStableName#(R1) returns to c1qb, args: 8, res: 8, upd: 8;+--+-- If we run sinking pass now (still before stack layout) we will get this:+--+-- c1q6:+-- I64[(young<c1q9> + 8)] = c1q9;+-- foreign call "ccall" arg hints: [] result hints: [] performMajorGC(...)+-- returns to c1q9 args: ([]) ress: ([])ret_args: 8ret_off: 8;+-- c1q9:+-- I64[(young<c1qb> + 8)] = c1qb;+-- _s1pf::P64 = R1; <------ _s1pf sunk past safe foreign call+-- R1 = _s1pc::P64;+-- call stg_makeStableName#(R1) returns to c1qb, args: 8, res: 8, upd: 8;+--+-- Notice that _s1pf was sunk past a foreign call. When we run stack layout+-- safe call to performMajorGC will be turned into:+--+-- c1q6:+-- _s1pc::P64 = P64[Sp + 8];+-- I64[Sp - 8] = c1q9;+-- Sp = Sp - 8;+-- I64[I64[CurrentTSO + 24] + 16] = Sp;+-- P64[CurrentNursery + 8] = Hp + 8;+-- (_u1qI::I64) = call "ccall" arg hints: [PtrHint,]+-- result hints: [PtrHint] suspendThread(BaseReg, 0);+-- call "ccall" arg hints: [] result hints: [] performMajorGC();+-- (_u1qJ::I64) = call "ccall" arg hints: [PtrHint]+-- result hints: [PtrHint] resumeThread(_u1qI::I64);+-- BaseReg = _u1qJ::I64;+-- _u1qK::P64 = CurrentTSO;+-- _u1qL::P64 = I64[_u1qK::P64 + 24];+-- Sp = I64[_u1qL::P64 + 16];+-- SpLim = _u1qL::P64 + 192;+-- HpAlloc = 0;+-- Hp = I64[CurrentNursery + 8] - 8;+-- HpLim = I64[CurrentNursery] + (%MO_SS_Conv_W32_W64(I32[CurrentNursery + 48]) * 4096 - 1);+-- call (I64[Sp])() returns to c1q9, args: 8, res: 8, upd: 8;+-- c1q9:+-- I64[(young<c1qb> + 8)] = c1qb;+-- _s1pf::P64 = R1; <------ INCORRECT!+-- R1 = _s1pc::P64;+-- call stg_makeStableName#(R1) returns to c1qb, args: 8, res: 8, upd: 8;+--+-- Notice that c1q6 now ends with a call. Sinking _s1pf::P64 = R1 past that+-- call is clearly incorrect. This is what would happen if we assumed that+-- safe foreign call has the same semantics as unsafe foreign call. To prevent+-- this we need to treat safe foreign call as if was normal call.++-----------------------------------+-- mapping Expr in GHC.Cmm.Node++mapForeignTarget :: (CmmExpr -> CmmExpr) -> ForeignTarget -> ForeignTarget+mapForeignTarget exp (ForeignTarget e c) = ForeignTarget (exp e) c+mapForeignTarget _ m@(PrimTarget _) = m++wrapRecExp :: (CmmExpr -> CmmExpr) -> CmmExpr -> CmmExpr+-- Take a transformer on expressions and apply it recursively.+-- (wrapRecExp f e) first recursively applies itself to sub-expressions of e+-- then uses f to rewrite the resulting expression+wrapRecExp f (CmmMachOp op es) = f (CmmMachOp op $ map (wrapRecExp f) es)+wrapRecExp f (CmmLoad addr ty) = f (CmmLoad (wrapRecExp f addr) ty)+wrapRecExp f e = f e++mapExp :: (CmmExpr -> CmmExpr) -> CmmNode e x -> CmmNode e x+mapExp _ f@(CmmEntry{}) = f+mapExp _ m@(CmmComment _) = m+mapExp _ m@(CmmTick _) = m+mapExp f (CmmUnwind regs) = CmmUnwind (map (fmap (fmap f)) regs)+mapExp f (CmmAssign r e) = CmmAssign r (f e)+mapExp f (CmmStore addr e) = CmmStore (f addr) (f e)+mapExp f (CmmUnsafeForeignCall tgt fs as) = CmmUnsafeForeignCall (mapForeignTarget f tgt) fs (map f as)+mapExp _ l@(CmmBranch _) = l+mapExp f (CmmCondBranch e ti fi l) = CmmCondBranch (f e) ti fi l+mapExp f (CmmSwitch e ids) = CmmSwitch (f e) ids+mapExp f n@CmmCall {cml_target=tgt} = n{cml_target = f tgt}+mapExp f (CmmForeignCall tgt fs as succ ret_args updfr intrbl) = CmmForeignCall (mapForeignTarget f tgt) fs (map f as) succ ret_args updfr intrbl++mapExpDeep :: (CmmExpr -> CmmExpr) -> CmmNode e x -> CmmNode e x+mapExpDeep f = mapExp $ wrapRecExp f++------------------------------------------------------------------------+-- mapping Expr in GHC.Cmm.Node, but not performing allocation if no changes++mapForeignTargetM :: (CmmExpr -> Maybe CmmExpr) -> ForeignTarget -> Maybe ForeignTarget+mapForeignTargetM f (ForeignTarget e c) = (\x -> ForeignTarget x c) `fmap` f e+mapForeignTargetM _ (PrimTarget _) = Nothing++wrapRecExpM :: (CmmExpr -> Maybe CmmExpr) -> (CmmExpr -> Maybe CmmExpr)+-- (wrapRecExpM f e) first recursively applies itself to sub-expressions of e+-- then gives f a chance to rewrite the resulting expression+wrapRecExpM f n@(CmmMachOp op es) = maybe (f n) (f . CmmMachOp op) (mapListM (wrapRecExpM f) es)+wrapRecExpM f n@(CmmLoad addr ty) = maybe (f n) (f . flip CmmLoad ty) (wrapRecExpM f addr)+wrapRecExpM f e = f e++mapExpM :: (CmmExpr -> Maybe CmmExpr) -> CmmNode e x -> Maybe (CmmNode e x)+mapExpM _ (CmmEntry{}) = Nothing+mapExpM _ (CmmComment _) = Nothing+mapExpM _ (CmmTick _) = Nothing+mapExpM f (CmmUnwind regs) = CmmUnwind `fmap` mapM (\(r,e) -> mapM f e >>= \e' -> pure (r,e')) regs+mapExpM f (CmmAssign r e) = CmmAssign r `fmap` f e+mapExpM f (CmmStore addr e) = (\[addr', e'] -> CmmStore addr' e') `fmap` mapListM f [addr, e]+mapExpM _ (CmmBranch _) = Nothing+mapExpM f (CmmCondBranch e ti fi l) = (\x -> CmmCondBranch x ti fi l) `fmap` f e+mapExpM f (CmmSwitch e tbl) = (\x -> CmmSwitch x tbl) `fmap` f e+mapExpM f (CmmCall tgt mb_id r o i s) = (\x -> CmmCall x mb_id r o i s) `fmap` f tgt+mapExpM f (CmmUnsafeForeignCall tgt fs as)+ = case mapForeignTargetM f tgt of+ Just tgt' -> Just (CmmUnsafeForeignCall tgt' fs (mapListJ f as))+ Nothing -> (\xs -> CmmUnsafeForeignCall tgt fs xs) `fmap` mapListM f as+mapExpM f (CmmForeignCall tgt fs as succ ret_args updfr intrbl)+ = case mapForeignTargetM f tgt of+ Just tgt' -> Just (CmmForeignCall tgt' fs (mapListJ f as) succ ret_args updfr intrbl)+ Nothing -> (\xs -> CmmForeignCall tgt fs xs succ ret_args updfr intrbl) `fmap` mapListM f as++-- share as much as possible+mapListM :: (a -> Maybe a) -> [a] -> Maybe [a]+mapListM f xs = let (b, r) = mapListT f xs+ in if b then Just r else Nothing++mapListJ :: (a -> Maybe a) -> [a] -> [a]+mapListJ f xs = snd (mapListT f xs)++mapListT :: (a -> Maybe a) -> [a] -> (Bool, [a])+mapListT f xs = foldr g (False, []) (zip3 (tails xs) xs (map f xs))+ where g (_, y, Nothing) (True, ys) = (True, y:ys)+ g (_, _, Just y) (True, ys) = (True, y:ys)+ g (ys', _, Nothing) (False, _) = (False, ys')+ g (_, _, Just y) (False, ys) = (True, y:ys)++mapExpDeepM :: (CmmExpr -> Maybe CmmExpr) -> CmmNode e x -> Maybe (CmmNode e x)+mapExpDeepM f = mapExpM $ wrapRecExpM f++-----------------------------------+-- folding Expr in GHC.Cmm.Node++foldExpForeignTarget :: (CmmExpr -> z -> z) -> ForeignTarget -> z -> z+foldExpForeignTarget exp (ForeignTarget e _) z = exp e z+foldExpForeignTarget _ (PrimTarget _) z = z++-- Take a folder on expressions and apply it recursively.+-- Specifically (wrapRecExpf f e z) deals with CmmMachOp and CmmLoad+-- itself, delegating all the other CmmExpr forms to 'f'.+wrapRecExpf :: (CmmExpr -> z -> z) -> CmmExpr -> z -> z+wrapRecExpf f e@(CmmMachOp _ es) z = foldr (wrapRecExpf f) (f e z) es+wrapRecExpf f e@(CmmLoad addr _) z = wrapRecExpf f addr (f e z)+wrapRecExpf f e z = f e z++foldExp :: (CmmExpr -> z -> z) -> CmmNode e x -> z -> z+foldExp _ (CmmEntry {}) z = z+foldExp _ (CmmComment {}) z = z+foldExp _ (CmmTick {}) z = z+foldExp f (CmmUnwind xs) z = foldr (maybe id f) z (map snd xs)+foldExp f (CmmAssign _ e) z = f e z+foldExp f (CmmStore addr e) z = f addr $ f e z+foldExp f (CmmUnsafeForeignCall t _ as) z = foldr f (foldExpForeignTarget f t z) as+foldExp _ (CmmBranch _) z = z+foldExp f (CmmCondBranch e _ _ _) z = f e z+foldExp f (CmmSwitch e _) z = f e z+foldExp f (CmmCall {cml_target=tgt}) z = f tgt z+foldExp f (CmmForeignCall {tgt=tgt, args=args}) z = foldr f (foldExpForeignTarget f tgt z) args++foldExpDeep :: (CmmExpr -> z -> z) -> CmmNode e x -> z -> z+foldExpDeep f = foldExp (wrapRecExpf f)++-- -----------------------------------------------------------------------------++mapSuccessors :: (Label -> Label) -> CmmNode O C -> CmmNode O C+mapSuccessors f (CmmBranch bid) = CmmBranch (f bid)+mapSuccessors f (CmmCondBranch p y n l) = CmmCondBranch p (f y) (f n) l+mapSuccessors f (CmmSwitch e ids) = CmmSwitch e (mapSwitchTargets f ids)+mapSuccessors _ n = n++mapCollectSuccessors :: forall a. (Label -> (Label,a)) -> CmmNode O C+ -> (CmmNode O C, [a])+mapCollectSuccessors f (CmmBranch bid)+ = let (bid', acc) = f bid in (CmmBranch bid', [acc])+mapCollectSuccessors f (CmmCondBranch p y n l)+ = let (bidt, acct) = f y+ (bidf, accf) = f n+ in (CmmCondBranch p bidt bidf l, [accf, acct])+mapCollectSuccessors f (CmmSwitch e ids)+ = let lbls = switchTargetsToList ids :: [Label]+ lblMap = mapFromList $ zip lbls (map f lbls) :: LabelMap (Label, a)+ in ( CmmSwitch e+ (mapSwitchTargets+ (\l -> fst $ mapFindWithDefault (error "impossible") l lblMap) ids)+ , map snd (mapElems lblMap)+ )+mapCollectSuccessors _ n = (n, [])++-- -----------------------------------------------------------------------------++-- | Tickish in Cmm context (annotations only)+type CmmTickish = Tickish ()++-- | Tick scope identifier, allowing us to reason about what+-- annotations in a Cmm block should scope over. We especially take+-- care to allow optimisations to reorganise blocks without losing+-- tick association in the process.+data CmmTickScope+ = GlobalScope+ -- ^ The global scope is the "root" of the scope graph. Every+ -- scope is a sub-scope of the global scope. It doesn't make sense+ -- to add ticks to this scope. On the other hand, this means that+ -- setting this scope on a block means no ticks apply to it.++ | SubScope !U.Unique CmmTickScope+ -- ^ Constructs a new sub-scope to an existing scope. This allows+ -- us to translate Core-style scoping rules (see @tickishScoped@)+ -- into the Cmm world. Suppose the following code:+ --+ -- tick<1> case ... of+ -- A -> tick<2> ...+ -- B -> tick<3> ...+ --+ -- We want the top-level tick annotation to apply to blocks+ -- generated for the A and B alternatives. We can achieve that by+ -- generating tick<1> into a block with scope a, while the code+ -- for alternatives A and B gets generated into sub-scopes a/b and+ -- a/c respectively.++ | CombinedScope CmmTickScope CmmTickScope+ -- ^ A combined scope scopes over everything that the two given+ -- scopes cover. It is therefore a sub-scope of either scope. This+ -- is required for optimisations. Consider common block elimination:+ --+ -- A -> tick<2> case ... of+ -- C -> [common]+ -- B -> tick<3> case ... of+ -- D -> [common]+ --+ -- We will generate code for the C and D alternatives, and figure+ -- out afterwards that it's actually common code. Scoping rules+ -- dictate that the resulting common block needs to be covered by+ -- both tick<2> and tick<3>, therefore we need to construct a+ -- scope that is a child to *both* scope. Now we can do that - if+ -- we assign the scopes a/c and b/d to the common-ed up blocks,+ -- the new block could have a combined tick scope a/c+b/d, which+ -- both tick<2> and tick<3> apply to.++-- Note [CmmTick scoping details]:+--+-- The scope of a @CmmTick@ is given by the @CmmEntry@ node of the+-- same block. Note that as a result of this, optimisations making+-- tick scopes more specific can *reduce* the amount of code a tick+-- scopes over. Fixing this would require a separate @CmmTickScope@+-- field for @CmmTick@. Right now we do not do this simply because I+-- couldn't find an example where it actually mattered -- multiple+-- blocks within the same scope generally jump to each other, which+-- prevents common block elimination from happening in the first+-- place. But this is no strong reason, so if Cmm optimisations become+-- more involved in future this might have to be revisited.++-- | Output all scope paths.+scopeToPaths :: CmmTickScope -> [[U.Unique]]+scopeToPaths GlobalScope = [[]]+scopeToPaths (SubScope u s) = map (u:) (scopeToPaths s)+scopeToPaths (CombinedScope s1 s2) = scopeToPaths s1 ++ scopeToPaths s2++-- | Returns the head uniques of the scopes. This is based on the+-- assumption that the @Unique@ of @SubScope@ identifies the+-- underlying super-scope. Used for efficient equality and comparison,+-- see below.+scopeUniques :: CmmTickScope -> [U.Unique]+scopeUniques GlobalScope = []+scopeUniques (SubScope u _) = [u]+scopeUniques (CombinedScope s1 s2) = scopeUniques s1 ++ scopeUniques s2++-- Equality and order is based on the head uniques defined above. We+-- take care to short-cut the (extremely) common cases.+instance Eq CmmTickScope where+ GlobalScope == GlobalScope = True+ GlobalScope == _ = False+ _ == GlobalScope = False+ (SubScope u _) == (SubScope u' _) = u == u'+ (SubScope _ _) == _ = False+ _ == (SubScope _ _) = False+ scope == scope' =+ sortBy nonDetCmpUnique (scopeUniques scope) ==+ sortBy nonDetCmpUnique (scopeUniques scope')+ -- This is still deterministic because+ -- the order is the same for equal lists++-- This is non-deterministic but we do not currently support deterministic+-- code-generation. See Note [Unique Determinism and code generation]+-- See Note [No Ord for Unique]+instance Ord CmmTickScope where+ compare GlobalScope GlobalScope = EQ+ compare GlobalScope _ = LT+ compare _ GlobalScope = GT+ compare (SubScope u _) (SubScope u' _) = nonDetCmpUnique u u'+ compare scope scope' = cmpList nonDetCmpUnique+ (sortBy nonDetCmpUnique $ scopeUniques scope)+ (sortBy nonDetCmpUnique $ scopeUniques scope')++instance Outputable CmmTickScope where+ ppr GlobalScope = text "global"+ ppr (SubScope us GlobalScope)+ = ppr us+ ppr (SubScope us s) = ppr s <> char '/' <> ppr us+ ppr combined = parens $ hcat $ punctuate (char '+') $+ map (hcat . punctuate (char '/') . map ppr . reverse) $+ scopeToPaths combined++-- | Checks whether two tick scopes are sub-scopes of each other. True+-- if the two scopes are equal.+isTickSubScope :: CmmTickScope -> CmmTickScope -> Bool+isTickSubScope = cmp+ where cmp _ GlobalScope = True+ cmp GlobalScope _ = False+ cmp (CombinedScope s1 s2) s' = cmp s1 s' && cmp s2 s'+ cmp s (CombinedScope s1' s2') = cmp s s1' || cmp s s2'+ cmp (SubScope u s) s'@(SubScope u' _) = u == u' || cmp s s'++-- | Combine two tick scopes. The new scope should be sub-scope of+-- both parameters. We simplify automatically if one tick scope is a+-- sub-scope of the other already.+combineTickScopes :: CmmTickScope -> CmmTickScope -> CmmTickScope+combineTickScopes s1 s2+ | s1 `isTickSubScope` s2 = s1+ | s2 `isTickSubScope` s1 = s2+ | otherwise = CombinedScope s1 s2
+ compiler/GHC/Cmm/Switch.hs view
@@ -0,0 +1,503 @@+{-# LANGUAGE GADTs #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+module GHC.Cmm.Switch (+ SwitchTargets,+ mkSwitchTargets,+ switchTargetsCases, switchTargetsDefault, switchTargetsRange, switchTargetsSigned,+ mapSwitchTargets, switchTargetsToTable, switchTargetsFallThrough,+ switchTargetsToList, eqSwitchTargetWith,++ SwitchPlan(..),+ targetSupportsSwitch,+ createSwitchPlan,+ ) where++import GhcPrelude++import Outputable+import DynFlags+import GHC.Cmm.Dataflow.Label (Label)++import Data.Maybe+import Data.List (groupBy)+import Data.Function (on)+import qualified Data.Map as M++-- Note [Cmm Switches, the general plan]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+--+-- Compiling a high-level switch statement, as it comes out of a STG case+-- expression, for example, allows for a surprising amount of design decisions.+-- Therefore, we cleanly separated this from the Stg → Cmm transformation, as+-- well as from the actual code generation.+--+-- The overall plan is:+-- * The Stg → Cmm transformation creates a single `SwitchTargets` in+-- emitSwitch and emitCmmLitSwitch in GHC.StgToCmm.Utils.+-- At this stage, they are unsuitable for code generation.+-- * A dedicated Cmm transformation (GHC.Cmm.Switch.Implement) replaces these+-- switch statements with code that is suitable for code generation, i.e.+-- a nice balanced tree of decisions with dense jump tables in the leafs.+-- The actual planning of this tree is performed in pure code in createSwitchPlan+-- in this module. See Note [createSwitchPlan].+-- * The actual code generation will not do any further processing and+-- implement each CmmSwitch with a jump tables.+--+-- When compiling to LLVM or C, GHC.Cmm.Switch.Implement leaves the switch+-- statements alone, as we can turn a SwitchTargets value into a nice+-- switch-statement in LLVM resp. C, and leave the rest to the compiler.+--+-- See Note [GHC.Cmm.Switch vs. GHC.Cmm.Switch.Implement] why the two module are+-- separated.++-----------------------------------------------------------------------------+-- Note [Magic Constants in GHC.Cmm.Switch]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+--+-- There are a lot of heuristics here that depend on magic values where it is+-- hard to determine the "best" value (for whatever that means). These are the+-- magic values:++-- | Number of consecutive default values allowed in a jump table. If there are+-- more of them, the jump tables are split.+--+-- Currently 7, as it costs 7 words of additional code when a jump table is+-- split (at least on x64, determined experimentally).+maxJumpTableHole :: Integer+maxJumpTableHole = 7++-- | Minimum size of a jump table. If the number is smaller, the switch is+-- implemented using conditionals.+-- Currently 5, because an if-then-else tree of 4 values is nice and compact.+minJumpTableSize :: Int+minJumpTableSize = 5++-- | Minimum non-zero offset for a jump table. See Note [Jump Table Offset].+minJumpTableOffset :: Integer+minJumpTableOffset = 2+++-----------------------------------------------------------------------------+-- Switch Targets++-- Note [SwitchTargets]+-- ~~~~~~~~~~~~~~~~~~~~+--+-- The branches of a switch are stored in a SwitchTargets, which consists of an+-- (optional) default jump target, and a map from values to jump targets.+--+-- If the default jump target is absent, the behaviour of the switch outside the+-- values of the map is undefined.+--+-- We use an Integer for the keys the map so that it can be used in switches on+-- unsigned as well as signed integers.+--+-- The map may be empty (we prune out-of-range branches here, so it could be us+-- emptying it).+--+-- Before code generation, the table needs to be brought into a form where all+-- entries are non-negative, so that it can be compiled into a jump table.+-- See switchTargetsToTable.+++-- | A value of type SwitchTargets contains the alternatives for a 'CmmSwitch'+-- value, and knows whether the value is signed, the possible range, an+-- optional default value and a map from values to jump labels.+data SwitchTargets =+ SwitchTargets+ Bool -- Signed values+ (Integer, Integer) -- Range+ (Maybe Label) -- Default value+ (M.Map Integer Label) -- The branches+ deriving (Show, Eq)++-- | The smart constructor mkSwitchTargets normalises the map a bit:+-- * No entries outside the range+-- * No entries equal to the default+-- * No default if all elements have explicit values+mkSwitchTargets :: Bool -> (Integer, Integer) -> Maybe Label -> M.Map Integer Label -> SwitchTargets+mkSwitchTargets signed range@(lo,hi) mbdef ids+ = SwitchTargets signed range mbdef' ids'+ where+ ids' = dropDefault $ restrict ids+ mbdef' | defaultNeeded = mbdef+ | otherwise = Nothing++ -- Drop entries outside the range, if there is a range+ restrict = restrictMap (lo,hi)++ -- Drop entries that equal the default, if there is a default+ dropDefault | Just l <- mbdef = M.filter (/= l)+ | otherwise = id++ -- Check if the default is still needed+ defaultNeeded = fromIntegral (M.size ids') /= hi-lo+1+++-- | Changes all labels mentioned in the SwitchTargets value+mapSwitchTargets :: (Label -> Label) -> SwitchTargets -> SwitchTargets+mapSwitchTargets f (SwitchTargets signed range mbdef branches)+ = SwitchTargets signed range (fmap f mbdef) (fmap f branches)++-- | Returns the list of non-default branches of the SwitchTargets value+switchTargetsCases :: SwitchTargets -> [(Integer, Label)]+switchTargetsCases (SwitchTargets _ _ _ branches) = M.toList branches++-- | Return the default label of the SwitchTargets value+switchTargetsDefault :: SwitchTargets -> Maybe Label+switchTargetsDefault (SwitchTargets _ _ mbdef _) = mbdef++-- | Return the range of the SwitchTargets value+switchTargetsRange :: SwitchTargets -> (Integer, Integer)+switchTargetsRange (SwitchTargets _ range _ _) = range++-- | Return whether this is used for a signed value+switchTargetsSigned :: SwitchTargets -> Bool+switchTargetsSigned (SwitchTargets signed _ _ _) = signed++-- | switchTargetsToTable creates a dense jump table, usable for code generation.+--+-- Also returns an offset to add to the value; the list is 0-based on the+-- result of that addition.+--+-- The conversion from Integer to Int is a bit of a wart, as the actual+-- scrutinee might be an unsigned word, but it just works, due to wrap-around+-- arithmetic (as verified by the CmmSwitchTest test case).+switchTargetsToTable :: SwitchTargets -> (Int, [Maybe Label])+switchTargetsToTable (SwitchTargets _ (lo,hi) mbdef branches)+ = (fromIntegral (-start), [ labelFor i | i <- [start..hi] ])+ where+ labelFor i = case M.lookup i branches of Just l -> Just l+ Nothing -> mbdef+ start | lo >= 0 && lo < minJumpTableOffset = 0 -- See Note [Jump Table Offset]+ | otherwise = lo++-- Note [Jump Table Offset]+-- ~~~~~~~~~~~~~~~~~~~~~~~~+--+-- Usually, the code for a jump table starting at x will first subtract x from+-- the value, to avoid a large amount of empty entries. But if x is very small,+-- the extra entries are no worse than the subtraction in terms of code size, and+-- not having to do the subtraction is quicker.+--+-- I.e. instead of+-- _u20N:+-- leaq -1(%r14),%rax+-- jmp *_n20R(,%rax,8)+-- _n20R:+-- .quad _c20p+-- .quad _c20q+-- do+-- _u20N:+-- jmp *_n20Q(,%r14,8)+--+-- _n20Q:+-- .quad 0+-- .quad _c20p+-- .quad _c20q+-- .quad _c20r++-- | The list of all labels occurring in the SwitchTargets value.+switchTargetsToList :: SwitchTargets -> [Label]+switchTargetsToList (SwitchTargets _ _ mbdef branches)+ = maybeToList mbdef ++ M.elems branches++-- | Groups cases with equal targets, suitable for pretty-printing to a+-- c-like switch statement with fall-through semantics.+switchTargetsFallThrough :: SwitchTargets -> ([([Integer], Label)], Maybe Label)+switchTargetsFallThrough (SwitchTargets _ _ mbdef branches) = (groups, mbdef)+ where+ groups = map (\xs -> (map fst xs, snd (head xs))) $+ groupBy ((==) `on` snd) $+ M.toList branches++-- | Custom equality helper, needed for "GHC.Cmm.CommonBlockElim"+eqSwitchTargetWith :: (Label -> Label -> Bool) -> SwitchTargets -> SwitchTargets -> Bool+eqSwitchTargetWith eq (SwitchTargets signed1 range1 mbdef1 ids1) (SwitchTargets signed2 range2 mbdef2 ids2) =+ signed1 == signed2 && range1 == range2 && goMB mbdef1 mbdef2 && goList (M.toList ids1) (M.toList ids2)+ where+ goMB Nothing Nothing = True+ goMB (Just l1) (Just l2) = l1 `eq` l2+ goMB _ _ = False+ goList [] [] = True+ goList ((i1,l1):ls1) ((i2,l2):ls2) = i1 == i2 && l1 `eq` l2 && goList ls1 ls2+ goList _ _ = False++-----------------------------------------------------------------------------+-- Code generation for Switches+++-- | A SwitchPlan abstractly describes how a Switch statement ought to be+-- implemented. See Note [createSwitchPlan]+data SwitchPlan+ = Unconditionally Label+ | IfEqual Integer Label SwitchPlan+ | IfLT Bool Integer SwitchPlan SwitchPlan+ | JumpTable SwitchTargets+ deriving Show+--+-- Note [createSwitchPlan]+-- ~~~~~~~~~~~~~~~~~~~~~~~+--+-- A SwitchPlan describes how a Switch statement is to be broken down into+-- smaller pieces suitable for code generation.+--+-- createSwitchPlan creates such a switch plan, in these steps:+-- 1. It splits the switch statement at segments of non-default values that+-- are too large. See splitAtHoles and Note [Magic Constants in GHC.Cmm.Switch]+-- 2. Too small jump tables should be avoided, so we break up smaller pieces+-- in breakTooSmall.+-- 3. We fill in the segments between those pieces with a jump to the default+-- label (if there is one), returning a SeparatedList in mkFlatSwitchPlan+-- 4. We find and replace two less-than branches by a single equal-to-test in+-- findSingleValues+-- 5. The thus collected pieces are assembled to a balanced binary tree.++{-+ Note [Two alts + default]+ ~~~~~~~~~~~~~~~~~~~~~~~~~++Discussion and a bit more info at #14644++When dealing with a switch of the form:+switch(e) {+ case 1: goto l1;+ case 3000: goto l2;+ default: goto ldef;+}++If we treat it as a sparse jump table we would generate:++if (e > 3000) //Check if value is outside of the jump table.+ goto ldef;+else {+ if (e < 3000) { //Compare to upper value+ if(e != 1) //Compare to remaining value+ goto ldef;+ else+ goto l2;+ }+ else+ goto l1;+}++Instead we special case this to :++if (e==1) goto l1;+else if (e==3000) goto l2;+else goto l3;++This means we have:+* Less comparisons for: 1,<3000+* Unchanged for 3000+* One more for >3000++This improves code in a few ways:+* One comparison less means smaller code which helps with cache.+* It exchanges a taken jump for two jumps no taken in the >range case.+ Jumps not taken are cheaper (See Agner guides) making this about as fast.+* For all other cases the first range check is removed making it faster.++The end result is that the change is not measurably slower for the case+>3000 and faster for the other cases.++This makes running this kind of match in an inner loop cheaper by 10-20%+depending on the data.+In nofib this improves wheel-sieve1 by 4-9% depending on problem+size.++We could also add a second conditional jump after the comparison to+keep the range check like this:+ cmp 3000, rArgument+ jg <default>+ je <branch 2>+While this is fairly cheap it made no big difference for the >3000 case+and slowed down all other cases making it not worthwhile.+-}+++-- | Does the target support switch out of the box? Then leave this to the+-- target!+targetSupportsSwitch :: HscTarget -> Bool+targetSupportsSwitch HscC = True+targetSupportsSwitch HscLlvm = True+targetSupportsSwitch _ = False++-- | This function creates a SwitchPlan from a SwitchTargets value, breaking it+-- down into smaller pieces suitable for code generation.+createSwitchPlan :: SwitchTargets -> SwitchPlan+-- Lets do the common case of a singleton map quickly and efficiently (#10677)+createSwitchPlan (SwitchTargets _signed _range (Just defLabel) m)+ | [(x, l)] <- M.toList m+ = IfEqual x l (Unconditionally defLabel)+-- And another common case, matching "booleans"+createSwitchPlan (SwitchTargets _signed (lo,hi) Nothing m)+ | [(x1, l1), (_x2,l2)] <- M.toAscList m+ --Checking If |range| = 2 is enough if we have two unique literals+ , hi - lo == 1+ = IfEqual x1 l1 (Unconditionally l2)+-- See Note [Two alts + default]+createSwitchPlan (SwitchTargets _signed _range (Just defLabel) m)+ | [(x1, l1), (x2,l2)] <- M.toAscList m+ = IfEqual x1 l1 (IfEqual x2 l2 (Unconditionally defLabel))+createSwitchPlan (SwitchTargets signed range mbdef m) =+ -- pprTrace "createSwitchPlan" (text (show ids) $$ text (show (range,m)) $$ text (show pieces) $$ text (show flatPlan) $$ text (show plan)) $+ plan+ where+ pieces = concatMap breakTooSmall $ splitAtHoles maxJumpTableHole m+ flatPlan = findSingleValues $ mkFlatSwitchPlan signed mbdef range pieces+ plan = buildTree signed $ flatPlan+++---+--- Step 1: Splitting at large holes+---+splitAtHoles :: Integer -> M.Map Integer a -> [M.Map Integer a]+splitAtHoles _ m | M.null m = []+splitAtHoles holeSize m = map (\range -> restrictMap range m) nonHoles+ where+ holes = filter (\(l,h) -> h - l > holeSize) $ zip (M.keys m) (tail (M.keys m))+ nonHoles = reassocTuples lo holes hi++ (lo,_) = M.findMin m+ (hi,_) = M.findMax m++---+--- Step 2: Avoid small jump tables+---+-- We do not want jump tables below a certain size. This breaks them up+-- (into singleton maps, for now).+breakTooSmall :: M.Map Integer a -> [M.Map Integer a]+breakTooSmall m+ | M.size m > minJumpTableSize = [m]+ | otherwise = [M.singleton k v | (k,v) <- M.toList m]++---+--- Step 3: Fill in the blanks+---++-- | A FlatSwitchPlan is a list of SwitchPlans, with an integer inbetween every+-- two entries, dividing the range.+-- So if we have (abusing list syntax) [plan1,n,plan2], then we use plan1 if+-- the expression is < n, and plan2 otherwise.++type FlatSwitchPlan = SeparatedList Integer SwitchPlan++mkFlatSwitchPlan :: Bool -> Maybe Label -> (Integer, Integer) -> [M.Map Integer Label] -> FlatSwitchPlan++-- If we have no default (i.e. undefined where there is no entry), we can+-- branch at the minimum of each map+mkFlatSwitchPlan _ Nothing _ [] = pprPanic "mkFlatSwitchPlan with nothing left to do" empty+mkFlatSwitchPlan signed Nothing _ (m:ms)+ = (mkLeafPlan signed Nothing m , [ (fst (M.findMin m'), mkLeafPlan signed Nothing m') | m' <- ms ])++-- If we have a default, we have to interleave segments that jump+-- to the default between the maps+mkFlatSwitchPlan signed (Just l) r ms = let ((_,p1):ps) = go r ms in (p1, ps)+ where+ go (lo,hi) []+ | lo > hi = []+ | otherwise = [(lo, Unconditionally l)]+ go (lo,hi) (m:ms)+ | lo < min+ = (lo, Unconditionally l) : go (min,hi) (m:ms)+ | lo == min+ = (lo, mkLeafPlan signed (Just l) m) : go (max+1,hi) ms+ | otherwise+ = pprPanic "mkFlatSwitchPlan" (integer lo <+> integer min)+ where+ min = fst (M.findMin m)+ max = fst (M.findMax m)+++mkLeafPlan :: Bool -> Maybe Label -> M.Map Integer Label -> SwitchPlan+mkLeafPlan signed mbdef m+ | [(_,l)] <- M.toList m -- singleton map+ = Unconditionally l+ | otherwise+ = JumpTable $ mkSwitchTargets signed (min,max) mbdef m+ where+ min = fst (M.findMin m)+ max = fst (M.findMax m)++---+--- Step 4: Reduce the number of branches using ==+---++-- A sequence of three unconditional jumps, with the outer two pointing to the+-- same value and the bounds off by exactly one can be improved+findSingleValues :: FlatSwitchPlan -> FlatSwitchPlan+findSingleValues (Unconditionally l, (i, Unconditionally l2) : (i', Unconditionally l3) : xs)+ | l == l3 && i + 1 == i'+ = findSingleValues (IfEqual i l2 (Unconditionally l), xs)+findSingleValues (p, (i,p'):xs)+ = (p,i) `consSL` findSingleValues (p', xs)+findSingleValues (p, [])+ = (p, [])++---+--- Step 5: Actually build the tree+---++-- Build a balanced tree from a separated list+buildTree :: Bool -> FlatSwitchPlan -> SwitchPlan+buildTree _ (p,[]) = p+buildTree signed sl = IfLT signed m (buildTree signed sl1) (buildTree signed sl2)+ where+ (sl1, m, sl2) = divideSL sl++++--+-- Utility data type: Non-empty lists with extra markers in between each+-- element:+--++type SeparatedList b a = (a, [(b,a)])++consSL :: (a, b) -> SeparatedList b a -> SeparatedList b a+consSL (a, b) (a', xs) = (a, (b,a'):xs)++divideSL :: SeparatedList b a -> (SeparatedList b a, b, SeparatedList b a)+divideSL (_,[]) = error "divideSL: Singleton SeparatedList"+divideSL (p,xs) = ((p, xs1), m, (p', xs2))+ where+ (xs1, (m,p'):xs2) = splitAt (length xs `div` 2) xs++--+-- Other Utilities+--++restrictMap :: (Integer,Integer) -> M.Map Integer b -> M.Map Integer b+restrictMap (lo,hi) m = mid+ where (_, mid_hi) = M.split (lo-1) m+ (mid, _) = M.split (hi+1) mid_hi++-- for example: reassocTuples a [(b,c),(d,e)] f == [(a,b),(c,d),(e,f)]+reassocTuples :: a -> [(a,a)] -> a -> [(a,a)]+reassocTuples initial [] last+ = [(initial,last)]+reassocTuples initial ((a,b):tuples) last+ = (initial,a) : reassocTuples b tuples last++-- Note [GHC.Cmm.Switch vs. GHC.Cmm.Switch.Implement]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- I (Joachim) separated the two somewhat closely related modules+--+-- - GHC.Cmm.Switch, which provides the CmmSwitchTargets type and contains the strategy+-- for implementing a Cmm switch (createSwitchPlan), and+-- - GHC.Cmm.Switch.Implement, which contains the actual Cmm graph modification,+--+-- for these reasons:+--+-- * GHC.Cmm.Switch is very low in the dependency tree, i.e. does not depend on any+-- GHC specific modules at all (with the exception of Output and+-- GHC.Cmm.Dataflow (Literal)).+-- * GHC.Cmm.Switch.Implement is the Cmm transformation and hence very high in+-- the dependency tree.+-- * GHC.Cmm.Switch provides the CmmSwitchTargets data type, which is abstract, but+-- used in GHC.Cmm.Node.+-- * Because GHC.Cmm.Switch is low in the dependency tree, the separation allows+-- for more parallelism when building GHC.+-- * The interaction between the modules is very explicit and easy to+-- understand, due to the small and simple interface.
+ compiler/GHC/Cmm/Type.hs view
@@ -0,0 +1,432 @@+module GHC.Cmm.Type+ ( CmmType -- Abstract+ , b8, b16, b32, b64, b128, b256, b512, f32, f64, bWord, bHalfWord, gcWord+ , cInt+ , cmmBits, cmmFloat+ , typeWidth, cmmEqType, cmmEqType_ignoring_ptrhood+ , isFloatType, isGcPtrType, isBitsType+ , isWord32, isWord64, isFloat64, isFloat32++ , Width(..)+ , widthInBits, widthInBytes, widthInLog, widthFromBytes+ , wordWidth, halfWordWidth, cIntWidth+ , halfWordMask+ , narrowU, narrowS+ , rEP_CostCentreStack_mem_alloc+ , rEP_CostCentreStack_scc_count+ , rEP_StgEntCounter_allocs+ , rEP_StgEntCounter_allocd++ , ForeignHint(..)++ , Length+ , vec, vec2, vec4, vec8, vec16+ , vec2f64, vec2b64, vec4f32, vec4b32, vec8b16, vec16b8+ , cmmVec+ , vecLength, vecElemType+ , isVecType+ )+where+++import GhcPrelude++import DynFlags+import FastString+import Outputable++import Data.Word+import Data.Int++-----------------------------------------------------------------------------+-- CmmType+-----------------------------------------------------------------------------++ -- NOTE: CmmType is an abstract type, not exported from this+ -- module so you can easily change its representation+ --+ -- However Width is exported in a concrete way,+ -- and is used extensively in pattern-matching++data CmmType -- The important one!+ = CmmType CmmCat Width++data CmmCat -- "Category" (not exported)+ = GcPtrCat -- GC pointer+ | BitsCat -- Non-pointer+ | FloatCat -- Float+ | VecCat Length CmmCat -- Vector+ deriving( Eq )+ -- See Note [Signed vs unsigned] at the end++instance Outputable CmmType where+ ppr (CmmType cat wid) = ppr cat <> ppr (widthInBits wid)++instance Outputable CmmCat where+ ppr FloatCat = text "F"+ ppr GcPtrCat = text "P"+ ppr BitsCat = text "I"+ ppr (VecCat n cat) = ppr cat <> text "x" <> ppr n <> text "V"++-- Why is CmmType stratified? For native code generation,+-- most of the time you just want to know what sort of register+-- to put the thing in, and for this you need to know how+-- many bits thing has, and whether it goes in a floating-point+-- register. By contrast, the distinction between GcPtr and+-- GcNonPtr is of interest to only a few parts of the code generator.++-------- Equality on CmmType --------------+-- CmmType is *not* an instance of Eq; sometimes we care about the+-- Gc/NonGc distinction, and sometimes we don't+-- So we use an explicit function to force you to think about it+cmmEqType :: CmmType -> CmmType -> Bool -- Exact equality+cmmEqType (CmmType c1 w1) (CmmType c2 w2) = c1==c2 && w1==w2++cmmEqType_ignoring_ptrhood :: CmmType -> CmmType -> Bool+ -- This equality is temporary; used in CmmLint+ -- but the RTS files are not yet well-typed wrt pointers+cmmEqType_ignoring_ptrhood (CmmType c1 w1) (CmmType c2 w2)+ = c1 `weak_eq` c2 && w1==w2+ where+ weak_eq :: CmmCat -> CmmCat -> Bool+ FloatCat `weak_eq` FloatCat = True+ FloatCat `weak_eq` _other = False+ _other `weak_eq` FloatCat = False+ (VecCat l1 cat1) `weak_eq` (VecCat l2 cat2) = l1 == l2+ && cat1 `weak_eq` cat2+ (VecCat {}) `weak_eq` _other = False+ _other `weak_eq` (VecCat {}) = False+ _word1 `weak_eq` _word2 = True -- Ignores GcPtr++--- Simple operations on CmmType -----+typeWidth :: CmmType -> Width+typeWidth (CmmType _ w) = w++cmmBits, cmmFloat :: Width -> CmmType+cmmBits = CmmType BitsCat+cmmFloat = CmmType FloatCat++-------- Common CmmTypes ------------+-- Floats and words of specific widths+b8, b16, b32, b64, b128, b256, b512, f32, f64 :: CmmType+b8 = cmmBits W8+b16 = cmmBits W16+b32 = cmmBits W32+b64 = cmmBits W64+b128 = cmmBits W128+b256 = cmmBits W256+b512 = cmmBits W512+f32 = cmmFloat W32+f64 = cmmFloat W64++-- CmmTypes of native word widths+bWord :: DynFlags -> CmmType+bWord dflags = cmmBits (wordWidth dflags)++bHalfWord :: DynFlags -> CmmType+bHalfWord dflags = cmmBits (halfWordWidth dflags)++gcWord :: DynFlags -> CmmType+gcWord dflags = CmmType GcPtrCat (wordWidth dflags)++cInt :: DynFlags -> CmmType+cInt dflags = cmmBits (cIntWidth dflags)++------------ Predicates ----------------+isFloatType, isGcPtrType, isBitsType :: CmmType -> Bool+isFloatType (CmmType FloatCat _) = True+isFloatType _other = False++isGcPtrType (CmmType GcPtrCat _) = True+isGcPtrType _other = False++isBitsType (CmmType BitsCat _) = True+isBitsType _ = False++isWord32, isWord64, isFloat32, isFloat64 :: CmmType -> Bool+-- isWord64 is true of 64-bit non-floats (both gc-ptrs and otherwise)+-- isFloat32 and 64 are obvious++isWord64 (CmmType BitsCat W64) = True+isWord64 (CmmType GcPtrCat W64) = True+isWord64 _other = False++isWord32 (CmmType BitsCat W32) = True+isWord32 (CmmType GcPtrCat W32) = True+isWord32 _other = False++isFloat32 (CmmType FloatCat W32) = True+isFloat32 _other = False++isFloat64 (CmmType FloatCat W64) = True+isFloat64 _other = False++-----------------------------------------------------------------------------+-- Width+-----------------------------------------------------------------------------++data Width = W8 | W16 | W32 | W64+ | W128+ | W256+ | W512+ deriving (Eq, Ord, Show)++instance Outputable Width where+ ppr rep = ptext (mrStr rep)++mrStr :: Width -> PtrString+mrStr = sLit . show+++-------- Common Widths ------------+wordWidth :: DynFlags -> Width+wordWidth dflags+ | wORD_SIZE dflags == 4 = W32+ | wORD_SIZE dflags == 8 = W64+ | otherwise = panic "MachOp.wordRep: Unknown word size"++halfWordWidth :: DynFlags -> Width+halfWordWidth dflags+ | wORD_SIZE dflags == 4 = W16+ | wORD_SIZE dflags == 8 = W32+ | otherwise = panic "MachOp.halfWordRep: Unknown word size"++halfWordMask :: DynFlags -> Integer+halfWordMask dflags+ | wORD_SIZE dflags == 4 = 0xFFFF+ | wORD_SIZE dflags == 8 = 0xFFFFFFFF+ | otherwise = panic "MachOp.halfWordMask: Unknown word size"++-- cIntRep is the Width for a C-language 'int'+cIntWidth :: DynFlags -> Width+cIntWidth dflags = case cINT_SIZE dflags of+ 4 -> W32+ 8 -> W64+ s -> panic ("cIntWidth: Unknown cINT_SIZE: " ++ show s)++widthInBits :: Width -> Int+widthInBits W8 = 8+widthInBits W16 = 16+widthInBits W32 = 32+widthInBits W64 = 64+widthInBits W128 = 128+widthInBits W256 = 256+widthInBits W512 = 512+++widthInBytes :: Width -> Int+widthInBytes W8 = 1+widthInBytes W16 = 2+widthInBytes W32 = 4+widthInBytes W64 = 8+widthInBytes W128 = 16+widthInBytes W256 = 32+widthInBytes W512 = 64+++widthFromBytes :: Int -> Width+widthFromBytes 1 = W8+widthFromBytes 2 = W16+widthFromBytes 4 = W32+widthFromBytes 8 = W64+widthFromBytes 16 = W128+widthFromBytes 32 = W256+widthFromBytes 64 = W512++widthFromBytes n = pprPanic "no width for given number of bytes" (ppr n)++-- log_2 of the width in bytes, useful for generating shifts.+widthInLog :: Width -> Int+widthInLog W8 = 0+widthInLog W16 = 1+widthInLog W32 = 2+widthInLog W64 = 3+widthInLog W128 = 4+widthInLog W256 = 5+widthInLog W512 = 6+++-- widening / narrowing++narrowU :: Width -> Integer -> Integer+narrowU W8 x = fromIntegral (fromIntegral x :: Word8)+narrowU W16 x = fromIntegral (fromIntegral x :: Word16)+narrowU W32 x = fromIntegral (fromIntegral x :: Word32)+narrowU W64 x = fromIntegral (fromIntegral x :: Word64)+narrowU _ _ = panic "narrowTo"++narrowS :: Width -> Integer -> Integer+narrowS W8 x = fromIntegral (fromIntegral x :: Int8)+narrowS W16 x = fromIntegral (fromIntegral x :: Int16)+narrowS W32 x = fromIntegral (fromIntegral x :: Int32)+narrowS W64 x = fromIntegral (fromIntegral x :: Int64)+narrowS _ _ = panic "narrowTo"++-----------------------------------------------------------------------------+-- SIMD+-----------------------------------------------------------------------------++type Length = Int++vec :: Length -> CmmType -> CmmType+vec l (CmmType cat w) = CmmType (VecCat l cat) vecw+ where+ vecw :: Width+ vecw = widthFromBytes (l*widthInBytes w)++vec2, vec4, vec8, vec16 :: CmmType -> CmmType+vec2 = vec 2+vec4 = vec 4+vec8 = vec 8+vec16 = vec 16++vec2f64, vec2b64, vec4f32, vec4b32, vec8b16, vec16b8 :: CmmType+vec2f64 = vec 2 f64+vec2b64 = vec 2 b64+vec4f32 = vec 4 f32+vec4b32 = vec 4 b32+vec8b16 = vec 8 b16+vec16b8 = vec 16 b8++cmmVec :: Int -> CmmType -> CmmType+cmmVec n (CmmType cat w) =+ CmmType (VecCat n cat) (widthFromBytes (n*widthInBytes w))++vecLength :: CmmType -> Length+vecLength (CmmType (VecCat l _) _) = l+vecLength _ = panic "vecLength: not a vector"++vecElemType :: CmmType -> CmmType+vecElemType (CmmType (VecCat l cat) w) = CmmType cat scalw+ where+ scalw :: Width+ scalw = widthFromBytes (widthInBytes w `div` l)+vecElemType _ = panic "vecElemType: not a vector"++isVecType :: CmmType -> Bool+isVecType (CmmType (VecCat {}) _) = True+isVecType _ = False++-------------------------------------------------------------------------+-- Hints++-- Hints are extra type information we attach to the arguments and+-- results of a foreign call, where more type information is sometimes+-- needed by the ABI to make the correct kind of call.++data ForeignHint+ = NoHint | AddrHint | SignedHint+ deriving( Eq )+ -- Used to give extra per-argument or per-result+ -- information needed by foreign calling conventions++-------------------------------------------------------------------------++-- These don't really belong here, but I don't know where is best to+-- put them.++rEP_CostCentreStack_mem_alloc :: DynFlags -> CmmType+rEP_CostCentreStack_mem_alloc dflags+ = cmmBits (widthFromBytes (pc_REP_CostCentreStack_mem_alloc pc))+ where pc = platformConstants dflags++rEP_CostCentreStack_scc_count :: DynFlags -> CmmType+rEP_CostCentreStack_scc_count dflags+ = cmmBits (widthFromBytes (pc_REP_CostCentreStack_scc_count pc))+ where pc = platformConstants dflags++rEP_StgEntCounter_allocs :: DynFlags -> CmmType+rEP_StgEntCounter_allocs dflags+ = cmmBits (widthFromBytes (pc_REP_StgEntCounter_allocs pc))+ where pc = platformConstants dflags++rEP_StgEntCounter_allocd :: DynFlags -> CmmType+rEP_StgEntCounter_allocd dflags+ = cmmBits (widthFromBytes (pc_REP_StgEntCounter_allocd pc))+ where pc = platformConstants dflags++-------------------------------------------------------------------------+{- Note [Signed vs unsigned]+ ~~~~~~~~~~~~~~~~~~~~~~~~~+Should a CmmType include a signed vs. unsigned distinction?++This is very much like a "hint" in C-- terminology: it isn't necessary+in order to generate correct code, but it might be useful in that the+compiler can generate better code if it has access to higher-level+hints about data. This is important at call boundaries, because the+definition of a function is not visible at all of its call sites, so+the compiler cannot infer the hints.++Here in Cmm, we're taking a slightly different approach. We include+the int vs. float hint in the CmmType, because (a) the majority of+platforms have a strong distinction between float and int registers,+and (b) we don't want to do any heavyweight hint-inference in the+native code backend in order to get good code. We're treating the+hint more like a type: our Cmm is always completely consistent with+respect to hints. All coercions between float and int are explicit.++What about the signed vs. unsigned hint? This information might be+useful if we want to keep sub-word-sized values in word-size+registers, which we must do if we only have word-sized registers.++On such a system, there are two straightforward conventions for+representing sub-word-sized values:++(a) Leave the upper bits undefined. Comparison operations must+ sign- or zero-extend both operands before comparing them,+ depending on whether the comparison is signed or unsigned.++(b) Always keep the values sign- or zero-extended as appropriate.+ Arithmetic operations must narrow the result to the appropriate+ size.++A clever compiler might not use either (a) or (b) exclusively, instead+it would attempt to minimize the coercions by analysis: the same kind+of analysis that propagates hints around. In Cmm we don't want to+have to do this, so we plump for having richer types and keeping the+type information consistent.++If signed/unsigned hints are missing from CmmType, then the only+choice we have is (a), because we don't know whether the result of an+operation should be sign- or zero-extended.++Many architectures have extending load operations, which work well+with (b). To make use of them with (a), you need to know whether the+value is going to be sign- or zero-extended by an enclosing comparison+(for example), which involves knowing above the context. This is+doable but more complex.++Further complicating the issue is foreign calls: a foreign calling+convention can specify that signed 8-bit quantities are passed as+sign-extended 32 bit quantities, for example (this is the case on the+PowerPC). So we *do* need sign information on foreign call arguments.++Pros for adding signed vs. unsigned to CmmType:++ - It would let us use convention (b) above, and get easier+ code generation for extending loads.++ - Less information required on foreign calls.++ - MachOp type would be simpler++Cons:++ - More complexity++ - What is the CmmType for a VanillaReg? Currently it is+ always wordRep, but now we have to decide whether it is+ signed or unsigned. The same VanillaReg can thus have+ different CmmType in different parts of the program.++ - Extra coercions cluttering up expressions.++Currently for GHC, the foreign call point is moot, because we do our+own promotion of sub-word-sized values to word-sized values. The Int8+type is represented by an Int# which is kept sign-extended at all times+(this is slightly naughty, because we're making assumptions about the+C calling convention rather early on in the compiler). However, given+this, the cons outweigh the pros.++-}+
+ compiler/GHC/CoreToIface.hs view
@@ -0,0 +1,685 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE Strict #-} -- See Note [Avoiding space leaks in toIface*]++-- | Functions for converting Core things to interface file things.+module GHC.CoreToIface+ ( -- * Binders+ toIfaceTvBndr+ , toIfaceTvBndrs+ , toIfaceIdBndr+ , toIfaceBndr+ , toIfaceForAllBndr+ , toIfaceTyCoVarBinders+ , toIfaceTyVar+ -- * Types+ , toIfaceType, toIfaceTypeX+ , toIfaceKind+ , toIfaceTcArgs+ , toIfaceTyCon+ , toIfaceTyCon_name+ , toIfaceTyLit+ -- * Tidying types+ , tidyToIfaceType+ , tidyToIfaceContext+ , tidyToIfaceTcArgs+ -- * Coercions+ , toIfaceCoercion, toIfaceCoercionX+ -- * Pattern synonyms+ , patSynToIfaceDecl+ -- * Expressions+ , toIfaceExpr+ , toIfaceBang+ , toIfaceSrcBang+ , toIfaceLetBndr+ , toIfaceIdDetails+ , toIfaceIdInfo+ , toIfUnfolding+ , toIfaceOneShot+ , toIfaceTickish+ , toIfaceBind+ , toIfaceAlt+ , toIfaceCon+ , toIfaceApp+ , toIfaceVar+ ) where++#include "HsVersions.h"++import GhcPrelude++import GHC.Iface.Syntax+import DataCon+import Id+import IdInfo+import CoreSyn+import TyCon hiding ( pprPromotionQuote )+import CoAxiom+import TysPrim ( eqPrimTyCon, eqReprPrimTyCon )+import TysWiredIn ( heqTyCon )+import MkId ( noinlineIdName )+import PrelNames+import Name+import BasicTypes+import Type+import PatSyn+import Outputable+import FastString+import Util+import Var+import VarEnv+import VarSet+import TyCoRep+import TyCoTidy ( tidyCo )+import Demand ( isTopSig )++import Data.Maybe ( catMaybes )++{- Note [Avoiding space leaks in toIface*]+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Building a interface file depends on the output of the simplifier.+If we build these lazily this would mean keeping the Core AST alive+much longer than necessary causing a space "leak".++This happens for example when we only write the interface file to disk+after code gen has run, in which case we might carry megabytes of core+AST in the heap which is no longer needed.++We avoid this in two ways.+* First we use -XStrict in GHC.CoreToIface which avoids many thunks+ to begin with.+* Second we define NFData instance for Iface syntax and use them to+ force any remaining thunks.++-XStrict is not sufficient as patterns of the form `f (g x)` would still+result in a thunk being allocated for `g x`.++NFData is sufficient for the space leak, but using -XStrict reduces allocation+by ~0.1% when compiling with -O. (nofib/spectral/simple, T10370).+It's essentially free performance hence we use -XStrict on top of NFData.++MR !1633 on gitlab, has more discussion on the topic.+-}++----------------+toIfaceTvBndr :: TyVar -> IfaceTvBndr+toIfaceTvBndr = toIfaceTvBndrX emptyVarSet++toIfaceTvBndrX :: VarSet -> TyVar -> IfaceTvBndr+toIfaceTvBndrX fr tyvar = ( occNameFS (getOccName tyvar)+ , toIfaceTypeX fr (tyVarKind tyvar)+ )++toIfaceTvBndrs :: [TyVar] -> [IfaceTvBndr]+toIfaceTvBndrs = map toIfaceTvBndr++toIfaceIdBndr :: Id -> IfaceIdBndr+toIfaceIdBndr = toIfaceIdBndrX emptyVarSet++toIfaceIdBndrX :: VarSet -> CoVar -> IfaceIdBndr+toIfaceIdBndrX fr covar = ( occNameFS (getOccName covar)+ , toIfaceTypeX fr (varType covar)+ )++toIfaceBndr :: Var -> IfaceBndr+toIfaceBndr var+ | isId var = IfaceIdBndr (toIfaceIdBndr var)+ | otherwise = IfaceTvBndr (toIfaceTvBndr var)++toIfaceBndrX :: VarSet -> Var -> IfaceBndr+toIfaceBndrX fr var+ | isId var = IfaceIdBndr (toIfaceIdBndrX fr var)+ | otherwise = IfaceTvBndr (toIfaceTvBndrX fr var)++toIfaceTyCoVarBinder :: VarBndr Var vis -> VarBndr IfaceBndr vis+toIfaceTyCoVarBinder (Bndr tv vis) = Bndr (toIfaceBndr tv) vis++toIfaceTyCoVarBinders :: [VarBndr Var vis] -> [VarBndr IfaceBndr vis]+toIfaceTyCoVarBinders = map toIfaceTyCoVarBinder++{-+************************************************************************+* *+ Conversion from Type to IfaceType+* *+************************************************************************+-}++toIfaceKind :: Type -> IfaceType+toIfaceKind = toIfaceType++---------------------+toIfaceType :: Type -> IfaceType+toIfaceType = toIfaceTypeX emptyVarSet++toIfaceTypeX :: VarSet -> Type -> IfaceType+-- (toIfaceTypeX free ty)+-- translates the tyvars in 'free' as IfaceFreeTyVars+--+-- Synonyms are retained in the interface type+toIfaceTypeX fr (TyVarTy tv) -- See Note [TcTyVars in IfaceType] in GHC.Iface.Type+ | tv `elemVarSet` fr = IfaceFreeTyVar tv+ | otherwise = IfaceTyVar (toIfaceTyVar tv)+toIfaceTypeX fr ty@(AppTy {}) =+ -- Flatten as many argument AppTys as possible, then turn them into an+ -- IfaceAppArgs list.+ -- See Note [Suppressing invisible arguments] in GHC.Iface.Type.+ let (head, args) = splitAppTys ty+ in IfaceAppTy (toIfaceTypeX fr head) (toIfaceAppTyArgsX fr head args)+toIfaceTypeX _ (LitTy n) = IfaceLitTy (toIfaceTyLit n)+toIfaceTypeX fr (ForAllTy b t) = IfaceForAllTy (toIfaceForAllBndrX fr b)+ (toIfaceTypeX (fr `delVarSet` binderVar b) t)+toIfaceTypeX fr (FunTy { ft_arg = t1, ft_res = t2, ft_af = af })+ = IfaceFunTy af (toIfaceTypeX fr t1) (toIfaceTypeX fr t2)+toIfaceTypeX fr (CastTy ty co) = IfaceCastTy (toIfaceTypeX fr ty) (toIfaceCoercionX fr co)+toIfaceTypeX fr (CoercionTy co) = IfaceCoercionTy (toIfaceCoercionX fr co)++toIfaceTypeX fr (TyConApp tc tys)+ -- tuples+ | Just sort <- tyConTuple_maybe tc+ , n_tys == arity+ = IfaceTupleTy sort NotPromoted (toIfaceTcArgsX fr tc tys)++ | Just dc <- isPromotedDataCon_maybe tc+ , isTupleDataCon dc+ , n_tys == 2*arity+ = IfaceTupleTy BoxedTuple IsPromoted (toIfaceTcArgsX fr tc (drop arity tys))++ | tc `elem` [ eqPrimTyCon, eqReprPrimTyCon, heqTyCon ]+ , (k1:k2:_) <- tys+ = let info = IfaceTyConInfo NotPromoted sort+ sort | k1 `eqType` k2 = IfaceEqualityTyCon+ | otherwise = IfaceNormalTyCon+ in IfaceTyConApp (IfaceTyCon (tyConName tc) info) (toIfaceTcArgsX fr tc tys)++ -- other applications+ | otherwise+ = IfaceTyConApp (toIfaceTyCon tc) (toIfaceTcArgsX fr tc tys)+ where+ arity = tyConArity tc+ n_tys = length tys++toIfaceTyVar :: TyVar -> FastString+toIfaceTyVar = occNameFS . getOccName++toIfaceCoVar :: CoVar -> FastString+toIfaceCoVar = occNameFS . getOccName++toIfaceForAllBndr :: TyCoVarBinder -> IfaceForAllBndr+toIfaceForAllBndr = toIfaceForAllBndrX emptyVarSet++toIfaceForAllBndrX :: VarSet -> TyCoVarBinder -> IfaceForAllBndr+toIfaceForAllBndrX fr (Bndr v vis) = Bndr (toIfaceBndrX fr v) vis++----------------+toIfaceTyCon :: TyCon -> IfaceTyCon+toIfaceTyCon tc+ = IfaceTyCon tc_name info+ where+ tc_name = tyConName tc+ info = IfaceTyConInfo promoted sort+ promoted | isPromotedDataCon tc = IsPromoted+ | otherwise = NotPromoted++ tupleSort :: TyCon -> Maybe IfaceTyConSort+ tupleSort tc' =+ case tyConTuple_maybe tc' of+ Just UnboxedTuple -> let arity = tyConArity tc' `div` 2+ in Just $ IfaceTupleTyCon arity UnboxedTuple+ Just sort -> let arity = tyConArity tc'+ in Just $ IfaceTupleTyCon arity sort+ Nothing -> Nothing++ sort+ | Just tsort <- tupleSort tc = tsort++ | Just dcon <- isPromotedDataCon_maybe tc+ , let tc' = dataConTyCon dcon+ , Just tsort <- tupleSort tc' = tsort++ | isUnboxedSumTyCon tc+ , Just cons <- isDataSumTyCon_maybe tc = IfaceSumTyCon (length cons)++ | otherwise = IfaceNormalTyCon+++toIfaceTyCon_name :: Name -> IfaceTyCon+toIfaceTyCon_name n = IfaceTyCon n info+ where info = IfaceTyConInfo NotPromoted IfaceNormalTyCon+ -- Used for the "rough-match" tycon stuff,+ -- where pretty-printing is not an issue++toIfaceTyLit :: TyLit -> IfaceTyLit+toIfaceTyLit (NumTyLit x) = IfaceNumTyLit x+toIfaceTyLit (StrTyLit x) = IfaceStrTyLit x++----------------+toIfaceCoercion :: Coercion -> IfaceCoercion+toIfaceCoercion = toIfaceCoercionX emptyVarSet++toIfaceCoercionX :: VarSet -> Coercion -> IfaceCoercion+-- (toIfaceCoercionX free ty)+-- translates the tyvars in 'free' as IfaceFreeTyVars+toIfaceCoercionX fr co+ = go co+ where+ go_mco MRefl = IfaceMRefl+ go_mco (MCo co) = IfaceMCo $ go co++ go (Refl ty) = IfaceReflCo (toIfaceTypeX fr ty)+ go (GRefl r ty mco) = IfaceGReflCo r (toIfaceTypeX fr ty) (go_mco mco)+ go (CoVarCo cv)+ -- See [TcTyVars in IfaceType] in GHC.Iface.Type+ | cv `elemVarSet` fr = IfaceFreeCoVar cv+ | otherwise = IfaceCoVarCo (toIfaceCoVar cv)+ go (HoleCo h) = IfaceHoleCo (coHoleCoVar h)++ go (AppCo co1 co2) = IfaceAppCo (go co1) (go co2)+ go (SymCo co) = IfaceSymCo (go co)+ go (TransCo co1 co2) = IfaceTransCo (go co1) (go co2)+ go (NthCo _r d co) = IfaceNthCo d (go co)+ go (LRCo lr co) = IfaceLRCo lr (go co)+ go (InstCo co arg) = IfaceInstCo (go co) (go arg)+ go (KindCo c) = IfaceKindCo (go c)+ go (SubCo co) = IfaceSubCo (go co)+ go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (coaxrName co) (map go cs)+ go (AxiomInstCo c i cs) = IfaceAxiomInstCo (coAxiomName c) i (map go cs)+ go (UnivCo p r t1 t2) = IfaceUnivCo (go_prov p) r+ (toIfaceTypeX fr t1)+ (toIfaceTypeX fr t2)+ go (TyConAppCo r tc cos)+ | tc `hasKey` funTyConKey+ , [_,_,_,_] <- cos = pprPanic "toIfaceCoercion" (ppr co)+ | otherwise = IfaceTyConAppCo r (toIfaceTyCon tc) (map go cos)+ go (FunCo r co1 co2) = IfaceFunCo r (go co1) (go co2)++ go (ForAllCo tv k co) = IfaceForAllCo (toIfaceBndr tv)+ (toIfaceCoercionX fr' k)+ (toIfaceCoercionX fr' co)+ where+ fr' = fr `delVarSet` tv++ go_prov :: UnivCoProvenance -> IfaceUnivCoProv+ go_prov UnsafeCoerceProv = IfaceUnsafeCoerceProv+ go_prov (PhantomProv co) = IfacePhantomProv (go co)+ go_prov (ProofIrrelProv co) = IfaceProofIrrelProv (go co)+ go_prov (PluginProv str) = IfacePluginProv str++toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs+toIfaceTcArgs = toIfaceTcArgsX emptyVarSet++toIfaceTcArgsX :: VarSet -> TyCon -> [Type] -> IfaceAppArgs+toIfaceTcArgsX fr tc ty_args = toIfaceAppArgsX fr (tyConKind tc) ty_args++toIfaceAppTyArgsX :: VarSet -> Type -> [Type] -> IfaceAppArgs+toIfaceAppTyArgsX fr ty ty_args = toIfaceAppArgsX fr (typeKind ty) ty_args++toIfaceAppArgsX :: VarSet -> Kind -> [Type] -> IfaceAppArgs+-- See Note [Suppressing invisible arguments] in GHC.Iface.Type+-- We produce a result list of args describing visibility+-- The awkward case is+-- T :: forall k. * -> k+-- And consider+-- T (forall j. blah) * blib+-- Is 'blib' visible? It depends on the visibility flag on j,+-- so we have to substitute for k. Annoying!+toIfaceAppArgsX fr kind ty_args+ = go (mkEmptyTCvSubst in_scope) kind ty_args+ where+ in_scope = mkInScopeSet (tyCoVarsOfTypes ty_args)++ go _ _ [] = IA_Nil+ go env ty ts+ | Just ty' <- coreView ty+ = go env ty' ts+ go env (ForAllTy (Bndr tv vis) res) (t:ts)+ = IA_Arg t' vis ts'+ where+ t' = toIfaceTypeX fr t+ ts' = go (extendTCvSubst env tv t) res ts++ go env (FunTy { ft_af = af, ft_res = res }) (t:ts)+ = IA_Arg (toIfaceTypeX fr t) argf (go env res ts)+ where+ argf = case af of+ VisArg -> Required+ InvisArg -> Inferred+ -- It's rare for a kind to have a constraint argument, but+ -- it can happen. See Note [AnonTCB InvisArg] in TyCon.++ go env ty ts@(t1:ts1)+ | not (isEmptyTCvSubst env)+ = go (zapTCvSubst env) (substTy env ty) ts+ -- See Note [Care with kind instantiation] in Type.hs++ | otherwise+ = -- There's a kind error in the type we are trying to print+ -- e.g. kind = k, ty_args = [Int]+ -- This is probably a compiler bug, so we print a trace and+ -- carry on as if it were FunTy. Without the test for+ -- isEmptyTCvSubst we'd get an infinite loop (#15473)+ WARN( True, ppr kind $$ ppr ty_args )+ IA_Arg (toIfaceTypeX fr t1) Required (go env ty ts1)++tidyToIfaceType :: TidyEnv -> Type -> IfaceType+tidyToIfaceType env ty = toIfaceType (tidyType env ty)++tidyToIfaceTcArgs :: TidyEnv -> TyCon -> [Type] -> IfaceAppArgs+tidyToIfaceTcArgs env tc tys = toIfaceTcArgs tc (tidyTypes env tys)++tidyToIfaceContext :: TidyEnv -> ThetaType -> IfaceContext+tidyToIfaceContext env theta = map (tidyToIfaceType env) theta++{-+************************************************************************+* *+ Conversion of pattern synonyms+* *+************************************************************************+-}++patSynToIfaceDecl :: PatSyn -> IfaceDecl+patSynToIfaceDecl ps+ = IfacePatSyn { ifName = getName $ ps+ , ifPatMatcher = to_if_pr (patSynMatcher ps)+ , ifPatBuilder = fmap to_if_pr (patSynBuilder ps)+ , ifPatIsInfix = patSynIsInfix ps+ , ifPatUnivBndrs = map toIfaceForAllBndr univ_bndrs'+ , ifPatExBndrs = map toIfaceForAllBndr ex_bndrs'+ , ifPatProvCtxt = tidyToIfaceContext env2 prov_theta+ , ifPatReqCtxt = tidyToIfaceContext env2 req_theta+ , ifPatArgs = map (tidyToIfaceType env2) args+ , ifPatTy = tidyToIfaceType env2 rhs_ty+ , ifFieldLabels = (patSynFieldLabels ps)+ }+ where+ (_univ_tvs, req_theta, _ex_tvs, prov_theta, args, rhs_ty) = patSynSig ps+ univ_bndrs = patSynUnivTyVarBinders ps+ ex_bndrs = patSynExTyVarBinders ps+ (env1, univ_bndrs') = tidyTyCoVarBinders emptyTidyEnv univ_bndrs+ (env2, ex_bndrs') = tidyTyCoVarBinders env1 ex_bndrs+ to_if_pr (id, needs_dummy) = (idName id, needs_dummy)++{-+************************************************************************+* *+ Conversion of other things+* *+************************************************************************+-}++toIfaceBang :: TidyEnv -> HsImplBang -> IfaceBang+toIfaceBang _ HsLazy = IfNoBang+toIfaceBang _ (HsUnpack Nothing) = IfUnpack+toIfaceBang env (HsUnpack (Just co)) = IfUnpackCo (toIfaceCoercion (tidyCo env co))+toIfaceBang _ HsStrict = IfStrict++toIfaceSrcBang :: HsSrcBang -> IfaceSrcBang+toIfaceSrcBang (HsSrcBang _ unpk bang) = IfSrcBang unpk bang++toIfaceLetBndr :: Id -> IfaceLetBndr+toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id))+ (toIfaceType (idType id))+ (toIfaceIdInfo (idInfo id))+ (toIfaceJoinInfo (isJoinId_maybe id))+ -- Put into the interface file any IdInfo that CoreTidy.tidyLetBndr+ -- has left on the Id. See Note [IdInfo on nested let-bindings] in GHC.Iface.Syntax++toIfaceIdDetails :: IdDetails -> IfaceIdDetails+toIfaceIdDetails VanillaId = IfVanillaId+toIfaceIdDetails (DFunId {}) = IfDFunId+toIfaceIdDetails (RecSelId { sel_naughty = n+ , sel_tycon = tc }) =+ let iface = case tc of+ RecSelData ty_con -> Left (toIfaceTyCon ty_con)+ RecSelPatSyn pat_syn -> Right (patSynToIfaceDecl pat_syn)+ in IfRecSelId iface n++ -- The remaining cases are all "implicit Ids" which don't+ -- appear in interface files at all+toIfaceIdDetails other = pprTrace "toIfaceIdDetails" (ppr other)+ IfVanillaId -- Unexpected; the other++toIfaceIdInfo :: IdInfo -> IfaceIdInfo+toIfaceIdInfo id_info+ = case catMaybes [arity_hsinfo, caf_hsinfo, strict_hsinfo,+ inline_hsinfo, unfold_hsinfo, levity_hsinfo] of+ [] -> NoInfo+ infos -> HasInfo infos+ -- NB: strictness and arity must appear in the list before unfolding+ -- See GHC.IfaceToCore.tcUnfolding+ where+ ------------ Arity --------------+ arity_info = arityInfo id_info+ arity_hsinfo | arity_info == 0 = Nothing+ | otherwise = Just (HsArity arity_info)++ ------------ Caf Info --------------+ caf_info = cafInfo id_info+ caf_hsinfo = case caf_info of+ NoCafRefs -> Just HsNoCafRefs+ _other -> Nothing++ ------------ Strictness --------------+ -- No point in explicitly exporting TopSig+ sig_info = strictnessInfo id_info+ strict_hsinfo | not (isTopSig sig_info) = Just (HsStrictness sig_info)+ | otherwise = Nothing++ ------------ Unfolding --------------+ unfold_hsinfo = toIfUnfolding loop_breaker (unfoldingInfo id_info)+ loop_breaker = isStrongLoopBreaker (occInfo id_info)++ ------------ Inline prag --------------+ inline_prag = inlinePragInfo id_info+ inline_hsinfo | isDefaultInlinePragma inline_prag = Nothing+ | otherwise = Just (HsInline inline_prag)++ ------------ Levity polymorphism ----------+ levity_hsinfo | isNeverLevPolyIdInfo id_info = Just HsLevity+ | otherwise = Nothing++toIfaceJoinInfo :: Maybe JoinArity -> IfaceJoinInfo+toIfaceJoinInfo (Just ar) = IfaceJoinPoint ar+toIfaceJoinInfo Nothing = IfaceNotJoinPoint++--------------------------+toIfUnfolding :: Bool -> Unfolding -> Maybe IfaceInfoItem+toIfUnfolding lb (CoreUnfolding { uf_tmpl = rhs+ , uf_src = src+ , uf_guidance = guidance })+ = Just $ HsUnfold lb $+ case src of+ InlineStable+ -> case guidance of+ UnfWhen {ug_arity = arity, ug_unsat_ok = unsat_ok, ug_boring_ok = boring_ok }+ -> IfInlineRule arity unsat_ok boring_ok if_rhs+ _other -> IfCoreUnfold True if_rhs+ InlineCompulsory -> IfCompulsory if_rhs+ InlineRhs -> IfCoreUnfold False if_rhs+ -- Yes, even if guidance is UnfNever, expose the unfolding+ -- If we didn't want to expose the unfolding, GHC.Iface.Tidy would+ -- have stuck in NoUnfolding. For supercompilation we want+ -- to see that unfolding!+ where+ if_rhs = toIfaceExpr rhs++toIfUnfolding lb (DFunUnfolding { df_bndrs = bndrs, df_args = args })+ = Just (HsUnfold lb (IfDFunUnfold (map toIfaceBndr bndrs) (map toIfaceExpr args)))+ -- No need to serialise the data constructor;+ -- we can recover it from the type of the dfun++toIfUnfolding _ (OtherCon {}) = Nothing+ -- The binding site of an Id doesn't have OtherCon, except perhaps+ -- where we have called zapUnfolding; and that evald'ness info is+ -- not needed by importing modules++toIfUnfolding _ BootUnfolding = Nothing+ -- Can't happen; we only have BootUnfolding for imported binders++toIfUnfolding _ NoUnfolding = Nothing++{-+************************************************************************+* *+ Conversion of expressions+* *+************************************************************************+-}++toIfaceExpr :: CoreExpr -> IfaceExpr+toIfaceExpr (Var v) = toIfaceVar v+toIfaceExpr (Lit l) = IfaceLit l+toIfaceExpr (Type ty) = IfaceType (toIfaceType ty)+toIfaceExpr (Coercion co) = IfaceCo (toIfaceCoercion co)+toIfaceExpr (Lam x b) = IfaceLam (toIfaceBndr x, toIfaceOneShot x) (toIfaceExpr b)+toIfaceExpr (App f a) = toIfaceApp f [a]+toIfaceExpr (Case s x ty as)+ | null as = IfaceECase (toIfaceExpr s) (toIfaceType ty)+ | otherwise = IfaceCase (toIfaceExpr s) (getOccFS x) (map toIfaceAlt as)+toIfaceExpr (Let b e) = IfaceLet (toIfaceBind b) (toIfaceExpr e)+toIfaceExpr (Cast e co) = IfaceCast (toIfaceExpr e) (toIfaceCoercion co)+toIfaceExpr (Tick t e)+ | Just t' <- toIfaceTickish t = IfaceTick t' (toIfaceExpr e)+ | otherwise = toIfaceExpr e++toIfaceOneShot :: Id -> IfaceOneShot+toIfaceOneShot id | isId id+ , OneShotLam <- oneShotInfo (idInfo id)+ = IfaceOneShot+ | otherwise+ = IfaceNoOneShot++---------------------+toIfaceTickish :: Tickish Id -> Maybe IfaceTickish+toIfaceTickish (ProfNote cc tick push) = Just (IfaceSCC cc tick push)+toIfaceTickish (HpcTick modl ix) = Just (IfaceHpcTick modl ix)+toIfaceTickish (SourceNote src names) = Just (IfaceSource src names)+toIfaceTickish (Breakpoint {}) = Nothing+ -- Ignore breakpoints, since they are relevant only to GHCi, and+ -- should not be serialised (#8333)++---------------------+toIfaceBind :: Bind Id -> IfaceBinding+toIfaceBind (NonRec b r) = IfaceNonRec (toIfaceLetBndr b) (toIfaceExpr r)+toIfaceBind (Rec prs) = IfaceRec [(toIfaceLetBndr b, toIfaceExpr r) | (b,r) <- prs]++---------------------+toIfaceAlt :: (AltCon, [Var], CoreExpr)+ -> (IfaceConAlt, [FastString], IfaceExpr)+toIfaceAlt (c,bs,r) = (toIfaceCon c, map getOccFS bs, toIfaceExpr r)++---------------------+toIfaceCon :: AltCon -> IfaceConAlt+toIfaceCon (DataAlt dc) = IfaceDataAlt (getName dc)+toIfaceCon (LitAlt l) = IfaceLitAlt l+toIfaceCon DEFAULT = IfaceDefault++---------------------+toIfaceApp :: Expr CoreBndr -> [Arg CoreBndr] -> IfaceExpr+toIfaceApp (App f a) as = toIfaceApp f (a:as)+toIfaceApp (Var v) as+ = case isDataConWorkId_maybe v of+ -- We convert the *worker* for tuples into IfaceTuples+ Just dc | saturated+ , Just tup_sort <- tyConTuple_maybe tc+ -> IfaceTuple tup_sort tup_args+ where+ val_args = dropWhile isTypeArg as+ saturated = val_args `lengthIs` idArity v+ tup_args = map toIfaceExpr val_args+ tc = dataConTyCon dc++ _ -> mkIfaceApps (toIfaceVar v) as++toIfaceApp e as = mkIfaceApps (toIfaceExpr e) as++mkIfaceApps :: IfaceExpr -> [CoreExpr] -> IfaceExpr+mkIfaceApps f as = foldl' (\f a -> IfaceApp f (toIfaceExpr a)) f as++---------------------+toIfaceVar :: Id -> IfaceExpr+toIfaceVar v+ | isBootUnfolding (idUnfolding v)+ = -- See Note [Inlining and hs-boot files]+ IfaceApp (IfaceApp (IfaceExt noinlineIdName)+ (IfaceType (toIfaceType (idType v))))+ (IfaceExt name) -- don't use mkIfaceApps, or infinite loop++ | Just fcall <- isFCallId_maybe v = IfaceFCall fcall (toIfaceType (idType v))+ -- Foreign calls have special syntax++ | isExternalName name = IfaceExt name+ | otherwise = IfaceLcl (getOccFS name)+ where name = idName v+++{- Note [Inlining and hs-boot files]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider this example (#10083, #12789):++ ---------- RSR.hs-boot ------------+ module RSR where+ data RSR+ eqRSR :: RSR -> RSR -> Bool++ ---------- SR.hs ------------+ module SR where+ import {-# SOURCE #-} RSR+ data SR = MkSR RSR+ eqSR (MkSR r1) (MkSR r2) = eqRSR r1 r2++ ---------- RSR.hs ------------+ module RSR where+ import SR+ data RSR = MkRSR SR -- deriving( Eq )+ eqRSR (MkRSR s1) (MkRSR s2) = (eqSR s1 s2)+ foo x y = not (eqRSR x y)++When compiling RSR we get this code++ RSR.eqRSR :: RSR -> RSR -> Bool+ RSR.eqRSR = \ (ds1 :: RSR.RSR) (ds2 :: RSR.RSR) ->+ case ds1 of _ { RSR.MkRSR s1 ->+ case ds2 of _ { RSR.MkRSR s2 ->+ SR.eqSR s1 s2 }}++ RSR.foo :: RSR -> RSR -> Bool+ RSR.foo = \ (x :: RSR) (y :: RSR) -> not (RSR.eqRSR x y)++Now, when optimising foo:+ Inline eqRSR (small, non-rec)+ Inline eqSR (small, non-rec)+but the result of inlining eqSR from SR is another call to eqRSR, so+everything repeats. Neither eqSR nor eqRSR are (apparently) loop+breakers.++Solution: in the unfolding of eqSR in SR.hi, replace `eqRSR` in SR+with `noinline eqRSR`, so that eqRSR doesn't get inlined. This means+that when GHC inlines `eqSR`, it will not also inline `eqRSR`, exactly+as would have been the case if `foo` had been defined in SR.hs (and+marked as a loop-breaker).++But how do we arrange for this to happen? There are two ingredients:++ 1. When we serialize out unfoldings to IfaceExprs (toIfaceVar),+ for every variable reference we see if we are referring to an+ 'Id' that came from an hs-boot file. If so, we add a `noinline`+ to the reference.++ 2. But how do we know if a reference came from an hs-boot file+ or not? We could record this directly in the 'IdInfo', but+ actually we deduce this by looking at the unfolding: 'Id's+ that come from boot files are given a special unfolding+ (upon typechecking) 'BootUnfolding' which say that there is+ no unfolding, and the reason is because the 'Id' came from+ a boot file.++Here is a solution that doesn't work: when compiling RSR,+add a NOINLINE pragma to every function exported by the boot-file+for RSR (if it exists). Doing so makes the bootstrapped GHC itself+slower by 8% overall (on #9872a-d, and T1969: the reason+is that these NOINLINE'd functions now can't be profitably inlined+outside of the hs-boot loop.++-}
+ compiler/GHC/CoreToIface.hs-boot view
@@ -0,0 +1,18 @@+module GHC.CoreToIface where++import {-# SOURCE #-} TyCoRep ( Type, TyLit, Coercion )+import {-# SOURCE #-} GHC.Iface.Type( IfaceType, IfaceTyCon, IfaceForAllBndr+ , IfaceCoercion, IfaceTyLit, IfaceAppArgs )+import Var ( TyCoVarBinder )+import VarEnv ( TidyEnv )+import TyCon ( TyCon )+import VarSet( VarSet )++-- For TyCoRep+toIfaceTypeX :: VarSet -> Type -> IfaceType+toIfaceTyLit :: TyLit -> IfaceTyLit+toIfaceForAllBndr :: TyCoVarBinder -> IfaceForAllBndr+toIfaceTyCon :: TyCon -> IfaceTyCon+toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs+toIfaceCoercionX :: VarSet -> Coercion -> IfaceCoercion+tidyToIfaceTcArgs :: TidyEnv -> TyCon -> [Type] -> IfaceAppArgs
compiler/GHC/Hs.hs view
@@ -64,12 +64,12 @@ -- | Haskell Module -- -- All we actually declare here is the top-level structure for a module.-data HsModule pass+data HsModule = HsModule { hsmodName :: Maybe (Located ModuleName), -- ^ @Nothing@: \"module X where\" is omitted (in which case the next -- field is Nothing too)- hsmodExports :: Maybe (Located [LIE pass]),+ hsmodExports :: Maybe (Located [LIE GhcPs]), -- ^ Export list -- -- - @Nothing@: export list omitted, so export everything@@ -83,11 +83,11 @@ -- ,'ApiAnnotation.AnnClose' -- For details on above see note [Api annotations] in ApiAnnotation- hsmodImports :: [LImportDecl pass],+ hsmodImports :: [LImportDecl GhcPs], -- ^ We snaffle interesting stuff out of the imported interfaces early -- on, adding that info to TyDecls/etc; so this list is often empty, -- downstream.- hsmodDecls :: [LHsDecl pass],+ hsmodDecls :: [LHsDecl GhcPs], -- ^ Type, class, value, and interface signature decls hsmodDeprecMessage :: Maybe (Located WarningTxt), -- ^ reason\/explanation for warning/deprecation of this module@@ -114,12 +114,10 @@ -- hsmodImports,hsmodDecls if this style is used. -- For details on above see note [Api annotations] in ApiAnnotation--- deriving instance (DataIdLR name name) => Data (HsModule name)-deriving instance Data (HsModule GhcPs)-deriving instance Data (HsModule GhcRn)-deriving instance Data (HsModule GhcTc) -instance (OutputableBndrId p) => Outputable (HsModule (GhcPass p)) where+deriving instance Data HsModule++instance Outputable HsModule where ppr (HsModule Nothing _ imports decls _ mbDoc) = pp_mb mbDoc $$ pp_nonnull imports
compiler/GHC/Hs/Binds.hs view
@@ -345,7 +345,7 @@ -- -- See Note [AbsBinds] --- | Abtraction Bindings Export+-- | Abstraction Bindings Export data ABExport p = ABE { abe_ext :: XABE p , abe_poly :: IdP p -- ^ Any INLINE pragma is attached to this Id@@ -562,7 +562,7 @@ undef = /\ a. \ (d:HasCallStack) -> error a d "undef" The abs_sig field supports this direct desugaring, with no local-let-bining. When abs_sig = True+let-binding. When abs_sig = True * the abs_binds is single FunBind
compiler/GHC/Hs/Decls.hs view
@@ -13,6 +13,8 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE TypeFamilies #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+ -- | Abstract syntax of global declarations. -- -- Definitions for: @SynDecl@ and @ConDecl@, @ClassDecl@,@@ -84,7 +86,8 @@ resultVariableName, -- * Grouping- HsGroup(..), emptyRdrGroup, emptyRnGroup, appendGroups, hsGroupInstDecls+ HsGroup(..), emptyRdrGroup, emptyRnGroup, appendGroups, hsGroupInstDecls,+ hsGroupTopLevelFixitySigs, ) where @@ -167,19 +170,50 @@ type instance XRoleAnnotD (GhcPass _) = NoExtField type instance XXHsDecl (GhcPass _) = NoExtCon --- NB: all top-level fixity decls are contained EITHER--- EITHER SigDs--- OR in the ClassDecls in TyClDs------ The former covers--- a) data constructors--- b) class methods (but they can be also done in the--- signatures of class decls)--- c) imported functions (that have an IfacSig)--- d) top level decls------ The latter is for class methods only+{-+Note [Top-level fixity signatures in an HsGroup]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+An `HsGroup p` stores every top-level fixity declarations in one of two places: +1. hs_fixds :: [LFixitySig p]++ This stores fixity signatures for top-level declarations (e.g., functions,+ data constructors, classes, type families, etc.) as well as fixity+ signatures for class methods written outside of the class, as in this+ example:++ infixl 4 `m1`+ class C1 a where+ m1 :: a -> a -> a++2. hs_tyclds :: [TyClGroup p]++ Each type class can be found in a TyClDecl inside a TyClGroup, and that+ TyClDecl stores the fixity signatures for its methods written inside of the+ class, as in this example:++ class C2 a where+ infixl 4 `m2`+ m2 :: a -> a -> a++The story for fixity signatures for class methods is made slightly complicated+by the fact that they can appear both inside and outside of the class itself,+and both forms of fixity signatures are considered top-level. This matters+in `GHC.Rename.Source.rnSrcDecls`, which must create a fixity environment out+of all top-level fixity signatures before doing anything else. Therefore,+`rnSrcDecls` must be aware of both (1) and (2) above. The+`hsGroupTopLevelFixitySigs` function is responsible for collecting this+information from an `HsGroup`.++One might wonder why we even bother separating top-level fixity signatures+into two places at all. That is, why not just take the fixity signatures+from `hs_tyclds` and put them into `hs_fixds` so that they are all in one+location? This ends up causing problems for `DsMeta.repTopDs`, which translates+each fixity signature in `hs_fixds` and `hs_tyclds` into a Template Haskell+`Dec`. If there are any duplicate signatures between the two fields, this will+result in an error (#17608).+-}+ -- | Haskell Group -- -- A 'HsDecl' is categorised into a 'HsGroup' before being@@ -199,8 +233,10 @@ hs_derivds :: [LDerivDecl p], hs_fixds :: [LFixitySig p],- -- Snaffled out of both top-level fixity signatures,- -- and those in class declarations+ -- A list of fixity signatures defined for top-level+ -- declarations and class methods (defined outside of the class+ -- itself).+ -- See Note [Top-level fixity signatures in an HsGroup] hs_defds :: [LDefaultDecl p], hs_fords :: [LForeignDecl p],@@ -232,6 +268,19 @@ hs_splcds = [], hs_docs = [] } +-- | The fixity signatures for each top-level declaration and class method+-- in an 'HsGroup'.+-- See Note [Top-level fixity signatures in an HsGroup]+hsGroupTopLevelFixitySigs :: HsGroup (GhcPass p) -> [LFixitySig (GhcPass p)]+hsGroupTopLevelFixitySigs (HsGroup{ hs_fixds = fixds, hs_tyclds = tyclds }) =+ fixds ++ cls_fixds+ where+ cls_fixds = [ L loc sig+ | L _ ClassDecl{tcdSigs = sigs} <- tyClGroupTyClDecls tyclds+ , L loc (FixSig _ sig) <- sigs+ ]+hsGroupTopLevelFixitySigs (XHsGroup nec) = noExtCon nec+ appendGroups :: HsGroup (GhcPass p) -> HsGroup (GhcPass p) -> HsGroup (GhcPass p) appendGroups@@ -383,7 +432,7 @@ (See RnHiFiles.getSysBinders) - When typechecking the decl, we build the implicit TyCons and Ids.- When doing so we look them up in the name cache (RnEnv.lookupSysName),+ When doing so we look them up in the name cache (GHC.Rename.Env.lookupSysName), to ensure correct module and provenance is set These are the two places that we have to conjure up the magic derived@@ -907,8 +956,8 @@ depend on group_tyclds, or on earlier TyClGroups, but not on later ones. -See Note [Dependency analsis of type, class, and instance decls]-in RnSource for more info.+See Note [Dependency analysis of type, class, and instance decls]+in GHC.Rename.Source for more info. -} -- | Type or Class Group@@ -1189,7 +1238,7 @@ -- For @data T a where { T1 :: T a }@ -- the 'LConDecls' all have 'ConDeclGADT'. - dd_derivs :: HsDeriving pass -- ^ Optional 'deriving' claues+ dd_derivs :: HsDeriving pass -- ^ Optional 'deriving' clause -- For details on above see note [Api annotations] in ApiAnnotation }@@ -1412,7 +1461,7 @@ con_args = PrefixCon [] con_res_ty = a :*: (b -> (a :*: (b -> (a :+: b)))) - - In the renamer (RnSource.rnConDecl), we unravel it afer+ - In the renamer (GHC.Rename.Source.rnConDecl), we unravel it after operator fixities are sorted. So we generate. So we end up with con_args = PrefixCon [ a :*: b, a :*: b ]
compiler/GHC/Hs/Expr.hs view
@@ -15,6 +15,8 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+ -- | Abstract Haskell syntax for expressions. module GHC.Hs.Expr where @@ -179,7 +181,7 @@ make fully-instantiated piece of evidence at every use site. The Cmd way is Less Cool because * The renamer has to predict which methods are needed.- See the tedious RnExpr.methodNamesCmd.+ See the tedious GHC.Rename.Expr.methodNamesCmd. * The desugarer has to know the polymorphic type of the instantiated method. This is checked by Inst.tcSyntaxName, but is less flexible@@ -451,6 +453,8 @@ | HsTcBracketOut (XTcBracketOut p)+ (Maybe QuoteWrapper) -- The wrapper to apply type and dictionary argument+ -- to the quote. (HsBracket GhcRn) -- Output of the type checker is the *original* -- renamed expression, plus [PendingTcSplice] -- _typechecked_ splices to be@@ -1006,8 +1010,8 @@ ppr_expr (HsBracket _ b) = pprHsBracket b ppr_expr (HsRnBracketOut _ e []) = ppr e ppr_expr (HsRnBracketOut _ e ps) = ppr e $$ text "pending(rn)" <+> ppr ps-ppr_expr (HsTcBracketOut _ e []) = ppr e-ppr_expr (HsTcBracketOut _ e ps) = ppr e $$ text "pending(tc)" <+> ppr ps+ppr_expr (HsTcBracketOut _ _wrap e []) = ppr e+ppr_expr (HsTcBracketOut _ _wrap e ps) = ppr e $$ text "pending(tc)" <+> ppr ps ppr_expr (HsProc _ pat (L _ (HsCmdTop _ cmd))) = hsep [text "proc", ppr pat, ptext (sLit "->"), ppr cmd]@@ -1748,7 +1752,7 @@ -- For details on above see note [Api annotations] in ApiAnnotation data StmtLR idL idR body -- body should always be (LHs**** idR) = LastStmt -- Always the last Stmt in ListComp, MonadComp,- -- and (after the renamer, see RnExpr.checkLastStmt) DoExpr, MDoExpr+ -- and (after the renamer, see GHC.Rename.Expr.checkLastStmt) DoExpr, MDoExpr -- Not used for GhciStmtCtxt, PatGuard, which scope over other stuff (XLastStmt idL idR body) body@@ -1776,7 +1780,7 @@ -- appropriate applicative expression by the desugarer, but it is intended -- to be invisible in error messages. --- -- For full details, see Note [ApplicativeDo] in RnExpr+ -- For full details, see Note [ApplicativeDo] in GHC.Rename.Expr -- | ApplicativeStmt (XApplicativeStmt idL idR body) -- Post typecheck, Type of the body@@ -2297,7 +2301,7 @@ -- AZ:TODO: use XSplice instead of HsSpliced | HsSpliced -- See Note [Delaying modFinalizers in untyped splices] in- -- RnSplice.+ -- GHC.Rename.Splice. -- This is the result of splicing a splice. It is produced by -- the renamer and consumed by the typechecker. It lives only -- between the two.@@ -2333,7 +2337,7 @@ -- | Finalizers produced by a splice with -- 'Language.Haskell.TH.Syntax.addModFinalizer' ----- See Note [Delaying modFinalizers in untyped splices] in RnSplice. For how+-- See Note [Delaying modFinalizers in untyped splices] in GHC.Rename.Splice. For how -- this is used. -- newtype ThModFinalizers = ThModFinalizers [ForeignRef (TH.Q ())]@@ -2421,11 +2425,11 @@ UntypedExpSplice is also used for * quasi-quotes, where the pending expression expands to $(quoter "...blah...")- (see RnSplice.makePending, HsQuasiQuote case)+ (see GHC.Rename.Splice.makePending, HsQuasiQuote case) * cross-stage lifting, where the pending expression expands to $(lift x)- (see RnSplice.checkCrossStageLifting)+ (see GHC.Rename.Splice.checkCrossStageLifting) * Pending pattern splices (UntypedPatSplice), e.g., [| \$(f x) -> x |]@@ -2572,7 +2576,7 @@ | FromThenTo (LHsExpr id) (LHsExpr id) (LHsExpr id)--- AZ: Sould ArithSeqInfo have a TTG extension?+-- AZ: Should ArithSeqInfo have a TTG extension? instance OutputableBndrId p => Outputable (ArithSeqInfo (GhcPass p)) where
compiler/GHC/Hs/Pat.hs view
@@ -245,7 +245,7 @@ -- a new hs-boot file. Not worth it. (SyntaxExpr p) -- (>=) function, of type t1->t2->Bool- (SyntaxExpr p) -- Name of '-' (see RnEnv.lookupSyntaxName)+ (SyntaxExpr p) -- Name of '-' (see GHC.Rename.Env.lookupSyntaxName) -- ^ n+k pattern ------------ Pattern type signatures ---------------@@ -686,7 +686,7 @@ -- Specifically on a ConPatIn, which is what it sees for a -- (LPat Name) in the renamer, it doesn't know the size of the -- constructor family, so it returns False. Result: only--- tuple patterns are considered irrefuable at the renamer stage.+-- tuple patterns are considered irrefutable at the renamer stage. -- -- But if it returns True, the pattern is definitely irrefutable isIrrefutableHsPat
compiler/GHC/Hs/Types.hs view
@@ -56,8 +56,7 @@ hsLTyVarName, hsLTyVarNames, hsLTyVarLocName, hsExplicitLTyVarNames, splitLHsInstDeclTy, getLHsInstDeclHead, getLHsInstDeclClass_maybe, splitLHsPatSynTy,- splitLHsForAllTy, splitLHsForAllTyInvis,- splitLHsQualTy, splitLHsSigmaTy, splitLHsSigmaTyInvis,+ splitLHsForAllTyInvis, splitLHsQualTy, splitLHsSigmaTyInvis, splitHsFunType, hsTyGetAppHead_maybe, mkHsOpTy, mkHsAppTy, mkHsAppTys, mkHsAppKindTy, ignoreParens, hsSigType, hsSigWcType,@@ -92,7 +91,7 @@ import Outputable import FastString import Maybes( isJust )-import Util ( count, debugIsOn )+import Util ( count ) import Data.Data hiding ( Fixity, Prefix, Infix ) @@ -144,7 +143,7 @@ renamer can decorate it with the variables bound by the pattern ('a' in the first example, 'k' in the second), assuming that neither of them is in scope already-See also Note [Kind and type-variable binders] in RnTypes+See also Note [Kind and type-variable binders] in GHC.Rename.Types Note [HsType binders] ~~~~~~~~~~~~~~~~~~~~~@@ -265,7 +264,7 @@ preserve their existing left-to-right ordering. Implicitly bound variables are collected by the extract- family of functions-(extractHsTysRdrTyVars, extractHsTyVarBndrsKVs, etc.) in RnTypes.+(extractHsTysRdrTyVars, extractHsTyVarBndrsKVs, etc.) in GHC.Rename.Types. These functions thus promise to keep left-to-right ordering. Look for pointers to this note to see the places where the action happens. @@ -368,7 +367,7 @@ -- Implicitly-bound kind & type vars -- Order is important; see -- Note [Ordering of implicit variables]- -- in RnTypes+ -- in GHC.Rename.Types , hsib_body :: thing -- Main payload (type or list of types) }@@ -602,7 +601,8 @@ | HsParTy (XParTy pass) (LHsType pass) -- See Note [Parens in HsSyn] in GHC.Hs.Expr- -- Parenthesis preserved for the precedence re-arrangement in RnTypes+ -- Parenthesis preserved for the precedence re-arrangement in+ -- GHC.Rename.Types -- It's important that a * (b + c) doesn't get rearranged to (a*b) + c! -- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen' @'('@, -- 'ApiAnnotation.AnnClose' @')'@@@ -673,7 +673,7 @@ | HsExplicitListTy -- A promoted explicit list (XExplicitListTy pass)- PromotionFlag -- whether explcitly promoted, for pretty printer+ PromotionFlag -- whether explicitly promoted, for pretty printer [LHsType pass] -- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen' @"'["@, -- 'ApiAnnotation.AnnClose' @']'@@@ -774,7 +774,7 @@ Qualified currently behaves exactly as Implicit, but it is deprecated to use it for implicit quantification. In this case, GHC 7.10 gives a warning; see-Note [Context quantification] in RnTypes, and #4426.+Note [Context quantification] in GHC.Rename.Types, and #4426. In GHC 8.0, Qualified will no longer bind variables and this will become an error. @@ -887,7 +887,7 @@ -- For details on above see note [Api annotations] in ApiAnnotation -- | Constructor Declaration Field-data ConDeclField pass -- Record fields have Haddoc docs on them+data ConDeclField pass -- Record fields have Haddock docs on them = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField passs]@@ -957,16 +957,15 @@ hsWcScopedTvs :: LHsSigWcType GhcRn -> [Name] -- Get the lexically-scoped type variables of a HsSigType -- - the explicitly-given forall'd type variables--- - the named wildcars; see Note [Scoping of named wildcards]+-- - the named wildcards; see Note [Scoping of named wildcards] -- because they scope in the same way hsWcScopedTvs sig_ty | HsWC { hswc_ext = nwcs, hswc_body = sig_ty1 } <- sig_ty , HsIB { hsib_ext = vars , hsib_body = sig_ty2 } <- sig_ty1 = case sig_ty2 of- L _ (HsForAllTy { hst_fvf = vis_flag+ L _ (HsForAllTy { hst_fvf = ForallInvis -- See Note [hsScopedTvs vis_flag] , hst_bndrs = tvs }) ->- ASSERT( vis_flag == ForallInvis ) -- See Note [hsScopedTvs vis_flag] vars ++ nwcs ++ hsLTyVarNames tvs _ -> nwcs hsWcScopedTvs (HsWC _ (XHsImplicitBndrs nec)) = noExtCon nec@@ -977,10 +976,9 @@ hsScopedTvs sig_ty | HsIB { hsib_ext = vars , hsib_body = sig_ty2 } <- sig_ty- , L _ (HsForAllTy { hst_fvf = vis_flag+ , L _ (HsForAllTy { hst_fvf = ForallInvis -- See Note [hsScopedTvs vis_flag] , hst_bndrs = tvs }) <- sig_ty2- = ASSERT( vis_flag == ForallInvis ) -- See Note [hsScopedTvs vis_flag]- vars ++ hsLTyVarNames tvs+ = vars ++ hsLTyVarNames tvs | otherwise = [] @@ -1026,17 +1024,23 @@ > vfn :: forall x y -> tau(x,y) > vfn x y = \a b -> ... -- bad! -At the moment, GHC does not support visible 'forall' in terms, so we simply cement-our assumptions with an assert:+We cement this design by pattern-matching on ForallInvis in hsScopedTvs: - hsScopedTvs (HsForAllTy { hst_fvf = vis_flag, ... }) =- ASSERT( vis_flag == ForallInvis )- ...+ hsScopedTvs (HsForAllTy { hst_fvf = ForallInvis, ... }) = ... -In the future, this assert can be safely turned into a pattern match to support-visible forall in terms:+At the moment, GHC does not support visible 'forall' in terms. Nevertheless,+it is still possible to write erroneous programs that use visible 'forall's in+terms, such as this example: - hsScopedTvs (HsForAllTy { hst_fvf = ForallInvis, ... }) = ...+ x :: forall a -> a -> a+ x = x++If we do not pattern-match on ForallInvis in hsScopedTvs, then `a` would+erroneously be brought into scope over the body of `x` when renaming it.+Although the typechecker would later reject this (see `TcValidity.vdqAllowed`),+it is still possible for this to wreak havoc in the renamer before it gets to+that point (see #17687 for an example of this).+Bottom line: nip problems in the bud by matching on ForallInvis from the start. -} ---------------------@@ -1232,21 +1236,9 @@ (provs, ty4) = splitLHsQualTy ty3 -- | Decompose a sigma type (of the form @forall <tvs>. context => body@)--- into its constituent parts.------ Note that this function looks through parentheses, so it will work on types--- such as @(forall a. <...>)@. The downside to this is that it is not--- generally possible to take the returned types and reconstruct the original--- type (parentheses and all) from them.-splitLHsSigmaTy :: LHsType pass- -> ([LHsTyVarBndr pass], LHsContext pass, LHsType pass)-splitLHsSigmaTy ty- | (tvs, ty1) <- splitLHsForAllTy ty- , (ctxt, ty2) <- splitLHsQualTy ty1- = (tvs, ctxt, ty2)---- | Like 'splitLHsSigmaTy', but only splits type variable binders that were--- quantified invisibly (e.g., @forall a.@, with a dot).+-- into its constituent parts. Note that only /invisible/ @forall@s+-- (i.e., @forall a.@, with a dot) are split apart; /visible/ @forall@s+-- (i.e., @forall a ->@, with an arrow) are left untouched. -- -- This function is used to split apart certain types, such as instance -- declaration types, which disallow visible @forall@s. For instance, if GHC@@ -1264,20 +1256,10 @@ , (ctxt, ty2) <- splitLHsQualTy ty1 = (tvs, ctxt, ty2) --- | Decompose a type of the form @forall <tvs>. body@) into its constituent--- parts.------ Note that this function looks through parentheses, so it will work on types--- such as @(forall a. <...>)@. The downside to this is that it is not--- generally possible to take the returned types and reconstruct the original--- type (parentheses and all) from them.-splitLHsForAllTy :: LHsType pass -> ([LHsTyVarBndr pass], LHsType pass)-splitLHsForAllTy (L _ (HsParTy _ ty)) = splitLHsForAllTy ty-splitLHsForAllTy (L _ (HsForAllTy { hst_bndrs = tvs, hst_body = body })) = (tvs, body)-splitLHsForAllTy body = ([], body)---- | Like 'splitLHsForAllTy', but only splits type variable binders that--- were quantified invisibly (e.g., @forall a.@, with a dot).+-- | Decompose a type of the form @forall <tvs>. body@ into its constituent+-- parts. Note that only /invisible/ @forall@s+-- (i.e., @forall a.@, with a dot) are split apart; /visible/ @forall@s+-- (i.e., @forall a ->@, with an arrow) are left untouched. -- -- This function is used to split apart certain types, such as instance -- declaration types, which disallow visible @forall@s. For instance, if GHC@@ -1686,7 +1668,7 @@ maybeAddSpace :: [LHsType pass] -> SDoc -> SDoc -- See Note [Printing promoted type constructors]--- in IfaceType. This code implements the same+-- in GHC.Iface.Type. This code implements the same -- logic for printing HsType maybeAddSpace tys doc | (ty : _) <- tys
compiler/GHC/Hs/Utils.hs view
@@ -25,6 +25,8 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+ module GHC.Hs.Utils( -- * Terms mkHsPar, mkHsApp, mkHsAppType, mkHsAppTypes, mkHsCaseAlt,@@ -239,7 +241,7 @@ ------------------------------- -- These are the bits of syntax that contain rebindable names--- See RnEnv.lookupSyntaxName+-- See GHC.Rename.Env.lookupSyntaxName mkHsIntegral :: IntegralLit -> HsOverLit GhcPs mkHsFractional :: FractionalLit -> HsOverLit GhcPs@@ -551,7 +553,7 @@ -- #big_tuples# -- -- GHCs built in tuples can only go up to 'mAX_TUPLE_SIZE' in arity, but--- we might concievably want to build such a massive tuple as part of the+-- we might conceivably want to build such a massive tuple as part of the -- output of a desugaring stage (notably that for list comprehensions). -- -- We call tuples above this size \"big tuples\", and emulate them by@@ -566,7 +568,7 @@ -- and 'mkTupleCase' functions to do all your work with tuples you should be -- fine, and not have to worry about the arity limitation at all. --- | Lifts a \"small\" constructor into a \"big\" constructor by recursive decompositon+-- | Lifts a \"small\" constructor into a \"big\" constructor by recursive decomposition mkChunkified :: ([a] -> a) -- ^ \"Small\" constructor function, of maximum input arity 'mAX_TUPLE_SIZE' -> [a] -- ^ Possible \"big\" list of things to construct from -> a -- ^ Constructed thing made possible by recursive decomposition
compiler/GHC/HsToCore/PmCheck/Types.hs view
@@ -465,7 +465,7 @@ -- ^ The type of the variable. Important for rejecting possible GADT -- constructors or incompatible pattern synonyms (@Just42 :: Maybe Int@). - , vi_pos :: ![(PmAltCon, [Id])]+ , vi_pos :: ![(PmAltCon, [TyVar], [Id])] -- ^ Positive info: 'PmAltCon' apps it is (i.e. @x ~ [Just y, PatSyn z]@), all -- at the same time (i.e. conjunctive). We need a list because of nested -- pattern matches involving pattern synonym@@ -531,7 +531,7 @@ initDelta = MkDelta initTyState initTmState instance Outputable Delta where- ppr delta = vcat [+ ppr delta = hang (text "Delta") 2 $ vcat [ -- intentionally formatted this way enable the dev to comment in only -- the info she needs ppr (delta_tm_st delta),
+ compiler/GHC/Iface/Syntax.hs view
@@ -0,0 +1,2593 @@+{-+(c) The University of Glasgow 2006+(c) The GRASP/AQUA Project, Glasgow University, 1993-1998+-}++{-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-}++module GHC.Iface.Syntax (+ module GHC.Iface.Type,++ IfaceDecl(..), IfaceFamTyConFlav(..), IfaceClassOp(..), IfaceAT(..),+ IfaceConDecl(..), IfaceConDecls(..), IfaceEqSpec,+ IfaceExpr(..), IfaceAlt, IfaceLetBndr(..), IfaceJoinInfo(..),+ IfaceBinding(..), IfaceConAlt(..),+ IfaceIdInfo(..), IfaceIdDetails(..), IfaceUnfolding(..),+ IfaceInfoItem(..), IfaceRule(..), IfaceAnnotation(..), IfaceAnnTarget,+ IfaceClsInst(..), IfaceFamInst(..), IfaceTickish(..),+ IfaceClassBody(..),+ IfaceBang(..),+ IfaceSrcBang(..), SrcUnpackedness(..), SrcStrictness(..),+ IfaceAxBranch(..),+ IfaceTyConParent(..),+ IfaceCompleteMatch(..),++ -- * Binding names+ IfaceTopBndr,+ putIfaceTopBndr, getIfaceTopBndr,++ -- Misc+ ifaceDeclImplicitBndrs, visibleIfConDecls,+ ifaceDeclFingerprints,++ -- Free Names+ freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst,++ -- Pretty printing+ pprIfaceExpr,+ pprIfaceDecl,+ AltPpr(..), ShowSub(..), ShowHowMuch(..), showToIface, showToHeader+ ) where++#include "HsVersions.h"++import GhcPrelude++import GHC.Iface.Type+import BinFingerprint+import CoreSyn( IsOrphan, isOrphan )+import DynFlags( gopt, GeneralFlag (Opt_PrintAxiomIncomps) )+import Demand+import Class+import FieldLabel+import NameSet+import CoAxiom ( BranchIndex )+import Name+import CostCentre+import Literal+import ForeignCall+import Annotations( AnnPayload, AnnTarget )+import BasicTypes+import Outputable+import Module+import SrcLoc+import Fingerprint+import Binary+import BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue )+import Var( VarBndr(..), binderVar )+import TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag )+import Util( dropList, filterByList, notNull, unzipWith, debugIsOn )+import DataCon (SrcStrictness(..), SrcUnpackedness(..))+import Lexeme (isLexSym)+import TysWiredIn ( constraintKindTyConName )+import Util (seqList)++import Control.Monad+import System.IO.Unsafe+import Control.DeepSeq++infixl 3 &&&++{-+************************************************************************+* *+ Declarations+* *+************************************************************************+-}++-- | A binding top-level 'Name' in an interface file (e.g. the name of an+-- 'IfaceDecl').+type IfaceTopBndr = Name+ -- It's convenient to have a Name in the Iface syntax, although in each+ -- case the namespace is implied by the context. However, having a+ -- Name makes things like ifaceDeclImplicitBndrs and ifaceDeclFingerprints+ -- very convenient. Moreover, having the key of the binder means that+ -- we can encode known-key things cleverly in the symbol table. See Note+ -- [Symbol table representation of Names]+ --+ -- We don't serialise the namespace onto the disk though; rather we+ -- drop it when serialising and add it back in when deserialising.++getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr+getIfaceTopBndr bh = get bh++putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO ()+putIfaceTopBndr bh name =+ case getUserData bh of+ UserData{ ud_put_binding_name = put_binding_name } ->+ --pprTrace "putIfaceTopBndr" (ppr name) $+ put_binding_name bh name++data IfaceDecl+ = IfaceId { ifName :: IfaceTopBndr,+ ifType :: IfaceType,+ ifIdDetails :: IfaceIdDetails,+ ifIdInfo :: IfaceIdInfo }++ | IfaceData { ifName :: IfaceTopBndr, -- Type constructor+ ifBinders :: [IfaceTyConBinder],+ ifResKind :: IfaceType, -- Result kind of type constructor+ ifCType :: Maybe CType, -- C type for CAPI FFI+ ifRoles :: [Role], -- Roles+ ifCtxt :: IfaceContext, -- The "stupid theta"+ ifCons :: IfaceConDecls, -- Includes new/data/data family info+ ifGadtSyntax :: Bool, -- True <=> declared using+ -- GADT syntax+ ifParent :: IfaceTyConParent -- The axiom, for a newtype,+ -- or data/newtype family instance+ }++ | IfaceSynonym { ifName :: IfaceTopBndr, -- Type constructor+ ifRoles :: [Role], -- Roles+ ifBinders :: [IfaceTyConBinder],+ ifResKind :: IfaceKind, -- Kind of the *result*+ ifSynRhs :: IfaceType }++ | IfaceFamily { ifName :: IfaceTopBndr, -- Type constructor+ ifResVar :: Maybe IfLclName, -- Result variable name, used+ -- only for pretty-printing+ -- with --show-iface+ ifBinders :: [IfaceTyConBinder],+ ifResKind :: IfaceKind, -- Kind of the *tycon*+ ifFamFlav :: IfaceFamTyConFlav,+ ifFamInj :: Injectivity } -- injectivity information++ | IfaceClass { ifName :: IfaceTopBndr, -- Name of the class TyCon+ ifRoles :: [Role], -- Roles+ ifBinders :: [IfaceTyConBinder],+ ifFDs :: [FunDep IfLclName], -- Functional dependencies+ ifBody :: IfaceClassBody -- Methods, superclasses, ATs+ }++ | IfaceAxiom { ifName :: IfaceTopBndr, -- Axiom name+ ifTyCon :: IfaceTyCon, -- LHS TyCon+ ifRole :: Role, -- Role of axiom+ ifAxBranches :: [IfaceAxBranch] -- Branches+ }++ | IfacePatSyn { ifName :: IfaceTopBndr, -- Name of the pattern synonym+ ifPatIsInfix :: Bool,+ ifPatMatcher :: (IfExtName, Bool),+ ifPatBuilder :: Maybe (IfExtName, Bool),+ -- Everything below is redundant,+ -- but needed to implement pprIfaceDecl+ ifPatUnivBndrs :: [IfaceForAllBndr],+ ifPatExBndrs :: [IfaceForAllBndr],+ ifPatProvCtxt :: IfaceContext,+ ifPatReqCtxt :: IfaceContext,+ ifPatArgs :: [IfaceType],+ ifPatTy :: IfaceType,+ ifFieldLabels :: [FieldLabel] }++-- See also 'ClassBody'+data IfaceClassBody+ -- Abstract classes don't specify their body; they only occur in @hs-boot@ and+ -- @hsig@ files.+ = IfAbstractClass+ | IfConcreteClass {+ ifClassCtxt :: IfaceContext, -- Super classes+ ifATs :: [IfaceAT], -- Associated type families+ ifSigs :: [IfaceClassOp], -- Method signatures+ ifMinDef :: BooleanFormula IfLclName -- Minimal complete definition+ }++data IfaceTyConParent+ = IfNoParent+ | IfDataInstance+ IfExtName -- Axiom name+ IfaceTyCon -- Family TyCon (pretty-printing only, not used in GHC.IfaceToCore)+ -- see Note [Pretty printing via Iface syntax] in PprTyThing+ IfaceAppArgs -- Arguments of the family TyCon++data IfaceFamTyConFlav+ = IfaceDataFamilyTyCon -- Data family+ | IfaceOpenSynFamilyTyCon+ | IfaceClosedSynFamilyTyCon (Maybe (IfExtName, [IfaceAxBranch]))+ -- ^ Name of associated axiom and branches for pretty printing purposes,+ -- or 'Nothing' for an empty closed family without an axiom+ -- See Note [Pretty printing via Iface syntax] in PprTyThing+ | IfaceAbstractClosedSynFamilyTyCon+ | IfaceBuiltInSynFamTyCon -- for pretty printing purposes only++data IfaceClassOp+ = IfaceClassOp IfaceTopBndr+ IfaceType -- Class op type+ (Maybe (DefMethSpec IfaceType)) -- Default method+ -- The types of both the class op itself,+ -- and the default method, are *not* quantified+ -- over the class variables++data IfaceAT = IfaceAT -- See Class.ClassATItem+ IfaceDecl -- The associated type declaration+ (Maybe IfaceType) -- Default associated type instance, if any+++-- This is just like CoAxBranch+data IfaceAxBranch = IfaceAxBranch { ifaxbTyVars :: [IfaceTvBndr]+ , ifaxbEtaTyVars :: [IfaceTvBndr]+ , ifaxbCoVars :: [IfaceIdBndr]+ , ifaxbLHS :: IfaceAppArgs+ , ifaxbRoles :: [Role]+ , ifaxbRHS :: IfaceType+ , ifaxbIncomps :: [BranchIndex] }+ -- See Note [Storing compatibility] in CoAxiom++data IfaceConDecls+ = IfAbstractTyCon -- c.f TyCon.AbstractTyCon+ | IfDataTyCon [IfaceConDecl] -- Data type decls+ | IfNewTyCon IfaceConDecl -- Newtype decls++-- For IfDataTyCon and IfNewTyCon we store:+-- * the data constructor(s);+-- The field labels are stored individually in the IfaceConDecl+-- (there is some redundancy here, because a field label may occur+-- in multiple IfaceConDecls and represent the same field label)++data IfaceConDecl+ = IfCon {+ ifConName :: IfaceTopBndr, -- Constructor name+ ifConWrapper :: Bool, -- True <=> has a wrapper+ ifConInfix :: Bool, -- True <=> declared infix++ -- The universal type variables are precisely those+ -- of the type constructor of this data constructor+ -- This is *easy* to guarantee when creating the IfCon+ -- but it's not so easy for the original TyCon/DataCon+ -- So this guarantee holds for IfaceConDecl, but *not* for DataCon++ ifConExTCvs :: [IfaceBndr], -- Existential ty/covars+ ifConUserTvBinders :: [IfaceForAllBndr],+ -- The tyvars, in the order the user wrote them+ -- INVARIANT: the set of tyvars in ifConUserTvBinders is exactly the+ -- set of tyvars (*not* covars) of ifConExTCvs, unioned+ -- with the set of ifBinders (from the parent IfaceDecl)+ -- whose tyvars do not appear in ifConEqSpec+ -- See Note [DataCon user type variable binders] in DataCon+ ifConEqSpec :: IfaceEqSpec, -- Equality constraints+ ifConCtxt :: IfaceContext, -- Non-stupid context+ ifConArgTys :: [IfaceType], -- Arg types+ ifConFields :: [FieldLabel], -- ...ditto... (field labels)+ ifConStricts :: [IfaceBang],+ -- Empty (meaning all lazy),+ -- or 1-1 corresp with arg tys+ -- See Note [Bangs on imported data constructors] in MkId+ ifConSrcStricts :: [IfaceSrcBang] } -- empty meaning no src stricts++type IfaceEqSpec = [(IfLclName,IfaceType)]++-- | This corresponds to an HsImplBang; that is, the final+-- implementation decision about the data constructor arg+data IfaceBang+ = IfNoBang | IfStrict | IfUnpack | IfUnpackCo IfaceCoercion++-- | This corresponds to HsSrcBang+data IfaceSrcBang+ = IfSrcBang SrcUnpackedness SrcStrictness++data IfaceClsInst+ = IfaceClsInst { ifInstCls :: IfExtName, -- See comments with+ ifInstTys :: [Maybe IfaceTyCon], -- the defn of ClsInst+ ifDFun :: IfExtName, -- The dfun+ ifOFlag :: OverlapFlag, -- Overlap flag+ ifInstOrph :: IsOrphan } -- See Note [Orphans] in InstEnv+ -- There's always a separate IfaceDecl for the DFun, which gives+ -- its IdInfo with its full type and version number.+ -- The instance declarations taken together have a version number,+ -- and we don't want that to wobble gratuitously+ -- If this instance decl is *used*, we'll record a usage on the dfun;+ -- and if the head does not change it won't be used if it wasn't before++-- The ifFamInstTys field of IfaceFamInst contains a list of the rough+-- match types+data IfaceFamInst+ = IfaceFamInst { ifFamInstFam :: IfExtName -- Family name+ , ifFamInstTys :: [Maybe IfaceTyCon] -- See above+ , ifFamInstAxiom :: IfExtName -- The axiom+ , ifFamInstOrph :: IsOrphan -- Just like IfaceClsInst+ }++data IfaceRule+ = IfaceRule {+ ifRuleName :: RuleName,+ ifActivation :: Activation,+ ifRuleBndrs :: [IfaceBndr], -- Tyvars and term vars+ ifRuleHead :: IfExtName, -- Head of lhs+ ifRuleArgs :: [IfaceExpr], -- Args of LHS+ ifRuleRhs :: IfaceExpr,+ ifRuleAuto :: Bool,+ ifRuleOrph :: IsOrphan -- Just like IfaceClsInst+ }++data IfaceAnnotation+ = IfaceAnnotation {+ ifAnnotatedTarget :: IfaceAnnTarget,+ ifAnnotatedValue :: AnnPayload+ }++type IfaceAnnTarget = AnnTarget OccName++data IfaceCompleteMatch = IfaceCompleteMatch [IfExtName] IfExtName++instance Outputable IfaceCompleteMatch where+ ppr (IfaceCompleteMatch cls ty) = text "COMPLETE" <> colon <+> ppr cls+ <+> dcolon <+> ppr ty+++++-- Here's a tricky case:+-- * Compile with -O module A, and B which imports A.f+-- * Change function f in A, and recompile without -O+-- * When we read in old A.hi we read in its IdInfo (as a thunk)+-- (In earlier GHCs we used to drop IdInfo immediately on reading,+-- but we do not do that now. Instead it's discarded when the+-- ModIface is read into the various decl pools.)+-- * The version comparison sees that new (=NoInfo) differs from old (=HasInfo *)+-- and so gives a new version.++data IfaceIdInfo+ = NoInfo -- When writing interface file without -O+ | HasInfo [IfaceInfoItem] -- Has info, and here it is++data IfaceInfoItem+ = HsArity Arity+ | HsStrictness StrictSig+ | HsInline InlinePragma+ | HsUnfold Bool -- True <=> isStrongLoopBreaker is true+ IfaceUnfolding -- See Note [Expose recursive functions]+ | HsNoCafRefs+ | HsLevity -- Present <=> never levity polymorphic++-- NB: Specialisations and rules come in separately and are+-- only later attached to the Id. Partial reason: some are orphans.++data IfaceUnfolding+ = IfCoreUnfold Bool IfaceExpr -- True <=> INLINABLE, False <=> regular unfolding+ -- Possibly could eliminate the Bool here, the information+ -- is also in the InlinePragma.++ | IfCompulsory IfaceExpr -- Only used for default methods, in fact++ | IfInlineRule Arity -- INLINE pragmas+ Bool -- OK to inline even if *un*-saturated+ Bool -- OK to inline even if context is boring+ IfaceExpr++ | IfDFunUnfold [IfaceBndr] [IfaceExpr]+++-- We only serialise the IdDetails of top-level Ids, and even then+-- we only need a very limited selection. Notably, none of the+-- implicit ones are needed here, because they are not put it+-- interface files++data IfaceIdDetails+ = IfVanillaId+ | IfRecSelId (Either IfaceTyCon IfaceDecl) Bool+ | IfDFunId++{-+Note [Versioning of instances]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+See [https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/recompilation-avoidance#instances]+++************************************************************************+* *+ Functions over declarations+* *+************************************************************************+-}++visibleIfConDecls :: IfaceConDecls -> [IfaceConDecl]+visibleIfConDecls IfAbstractTyCon = []+visibleIfConDecls (IfDataTyCon cs) = cs+visibleIfConDecls (IfNewTyCon c) = [c]++ifaceDeclImplicitBndrs :: IfaceDecl -> [OccName]+-- *Excludes* the 'main' name, but *includes* the implicitly-bound names+-- Deeply revolting, because it has to predict what gets bound,+-- especially the question of whether there's a wrapper for a datacon+-- See Note [Implicit TyThings] in HscTypes++-- N.B. the set of names returned here *must* match the set of+-- TyThings returned by HscTypes.implicitTyThings, in the sense that+-- TyThing.getOccName should define a bijection between the two lists.+-- This invariant is used in GHC.Iface.Load.loadDecl (see note [Tricky iface loop])+-- The order of the list does not matter.++ifaceDeclImplicitBndrs (IfaceData {ifName = tc_name, ifCons = cons })+ = case cons of+ IfAbstractTyCon -> []+ IfNewTyCon cd -> mkNewTyCoOcc (occName tc_name) : ifaceConDeclImplicitBndrs cd+ IfDataTyCon cds -> concatMap ifaceConDeclImplicitBndrs cds++ifaceDeclImplicitBndrs (IfaceClass { ifBody = IfAbstractClass })+ = []++ifaceDeclImplicitBndrs (IfaceClass { ifName = cls_tc_name+ , ifBody = IfConcreteClass {+ ifClassCtxt = sc_ctxt,+ ifSigs = sigs,+ ifATs = ats+ }})+ = -- (possibly) newtype coercion+ co_occs +++ -- data constructor (DataCon namespace)+ -- data worker (Id namespace)+ -- no wrapper (class dictionaries never have a wrapper)+ [dc_occ, dcww_occ] +++ -- associated types+ [occName (ifName at) | IfaceAT at _ <- ats ] +++ -- superclass selectors+ [mkSuperDictSelOcc n cls_tc_occ | n <- [1..n_ctxt]] +++ -- operation selectors+ [occName op | IfaceClassOp op _ _ <- sigs]+ where+ cls_tc_occ = occName cls_tc_name+ n_ctxt = length sc_ctxt+ n_sigs = length sigs+ co_occs | is_newtype = [mkNewTyCoOcc cls_tc_occ]+ | otherwise = []+ dcww_occ = mkDataConWorkerOcc dc_occ+ dc_occ = mkClassDataConOcc cls_tc_occ+ is_newtype = n_sigs + n_ctxt == 1 -- Sigh (keep this synced with buildClass)++ifaceDeclImplicitBndrs _ = []++ifaceConDeclImplicitBndrs :: IfaceConDecl -> [OccName]+ifaceConDeclImplicitBndrs (IfCon {+ ifConWrapper = has_wrapper, ifConName = con_name })+ = [occName con_name, work_occ] ++ wrap_occs+ where+ con_occ = occName con_name+ work_occ = mkDataConWorkerOcc con_occ -- Id namespace+ wrap_occs | has_wrapper = [mkDataConWrapperOcc con_occ] -- Id namespace+ | otherwise = []++-- -----------------------------------------------------------------------------+-- The fingerprints of an IfaceDecl++ -- We better give each name bound by the declaration a+ -- different fingerprint! So we calculate the fingerprint of+ -- each binder by combining the fingerprint of the whole+ -- declaration with the name of the binder. (#5614, #7215)+ifaceDeclFingerprints :: Fingerprint -> IfaceDecl -> [(OccName,Fingerprint)]+ifaceDeclFingerprints hash decl+ = (getOccName decl, hash) :+ [ (occ, computeFingerprint' (hash,occ))+ | occ <- ifaceDeclImplicitBndrs decl ]+ where+ computeFingerprint' =+ unsafeDupablePerformIO+ . computeFingerprint (panic "ifaceDeclFingerprints")++{-+************************************************************************+* *+ Expressions+* *+************************************************************************+-}++data IfaceExpr+ = IfaceLcl IfLclName+ | IfaceExt IfExtName+ | IfaceType IfaceType+ | IfaceCo IfaceCoercion+ | IfaceTuple TupleSort [IfaceExpr] -- Saturated; type arguments omitted+ | IfaceLam IfaceLamBndr IfaceExpr+ | IfaceApp IfaceExpr IfaceExpr+ | IfaceCase IfaceExpr IfLclName [IfaceAlt]+ | IfaceECase IfaceExpr IfaceType -- See Note [Empty case alternatives]+ | IfaceLet IfaceBinding IfaceExpr+ | IfaceCast IfaceExpr IfaceCoercion+ | IfaceLit Literal+ | IfaceFCall ForeignCall IfaceType+ | IfaceTick IfaceTickish IfaceExpr -- from Tick tickish E++data IfaceTickish+ = IfaceHpcTick Module Int -- from HpcTick x+ | IfaceSCC CostCentre Bool Bool -- from ProfNote+ | IfaceSource RealSrcSpan String -- from SourceNote+ -- no breakpoints: we never export these into interface files++type IfaceAlt = (IfaceConAlt, [IfLclName], IfaceExpr)+ -- Note: IfLclName, not IfaceBndr (and same with the case binder)+ -- We reconstruct the kind/type of the thing from the context+ -- thus saving bulk in interface files++data IfaceConAlt = IfaceDefault+ | IfaceDataAlt IfExtName+ | IfaceLitAlt Literal++data IfaceBinding+ = IfaceNonRec IfaceLetBndr IfaceExpr+ | IfaceRec [(IfaceLetBndr, IfaceExpr)]++-- IfaceLetBndr is like IfaceIdBndr, but has IdInfo too+-- It's used for *non-top-level* let/rec binders+-- See Note [IdInfo on nested let-bindings]+data IfaceLetBndr = IfLetBndr IfLclName IfaceType IfaceIdInfo IfaceJoinInfo++data IfaceJoinInfo = IfaceNotJoinPoint+ | IfaceJoinPoint JoinArity++{-+Note [Empty case alternatives]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In Iface syntax an IfaceCase does not record the types of the alternatives,+unlike Core syntax Case. But we need this type if the alternatives are empty.+Hence IfaceECase. See Note [Empty case alternatives] in CoreSyn.++Note [Expose recursive functions]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+For supercompilation we want to put *all* unfoldings in the interface+file, even for functions that are recursive (or big). So we need to+know when an unfolding belongs to a loop-breaker so that we can refrain+from inlining it (except during supercompilation).++Note [IdInfo on nested let-bindings]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Occasionally we want to preserve IdInfo on nested let bindings. The one+that came up was a NOINLINE pragma on a let-binding inside an INLINE+function. The user (Duncan Coutts) really wanted the NOINLINE control+to cross the separate compilation boundary.++In general we retain all info that is left by CoreTidy.tidyLetBndr, since+that is what is seen by importing module with --make++Note [Displaying axiom incompatibilities]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+With -fprint-axiom-incomps we display which closed type family equations+are incompatible with which. This information is sometimes necessary+because GHC doesn't try equations in order: any equation can be used when+all preceding equations that are incompatible with it do not apply.++For example, the last "a && a = a" equation in Data.Type.Bool.&& is+actually compatible with all previous equations, and can reduce at any+time.++This is displayed as:+Prelude> :i Data.Type.Equality.==+type family (==) (a :: k) (b :: k) :: Bool+ where+ {- #0 -} (==) (f a) (g b) = (f == g) && (a == b)+ {- #1 -} (==) a a = 'True+ -- incompatible with: #0+ {- #2 -} (==) _1 _2 = 'False+ -- incompatible with: #1, #0+The comment after an equation refers to all previous equations (0-indexed)+that are incompatible with it.++************************************************************************+* *+ Printing IfaceDecl+* *+************************************************************************+-}++pprAxBranch :: SDoc -> BranchIndex -> IfaceAxBranch -> SDoc+-- The TyCon might be local (just an OccName), or this might+-- be a branch for an imported TyCon, so it would be an ExtName+-- So it's easier to take an SDoc here+--+-- This function is used+-- to print interface files,+-- in debug messages+-- in :info F for GHCi, which goes via toConToIfaceDecl on the family tycon+-- For user error messages we use Coercion.pprCoAxiom and friends+pprAxBranch pp_tc idx (IfaceAxBranch { ifaxbTyVars = tvs+ , ifaxbCoVars = _cvs+ , ifaxbLHS = pat_tys+ , ifaxbRHS = rhs+ , ifaxbIncomps = incomps })+ = ASSERT2( null _cvs, pp_tc $$ ppr _cvs )+ hang ppr_binders 2 (hang pp_lhs 2 (equals <+> ppr rhs))+ $+$+ nest 4 maybe_incomps+ where+ -- See Note [Printing foralls in type family instances] in GHC.Iface.Type+ ppr_binders = maybe_index <+>+ pprUserIfaceForAll (map (mkIfaceForAllTvBndr Specified) tvs)+ pp_lhs = hang pp_tc 2 (pprParendIfaceAppArgs pat_tys)++ -- See Note [Displaying axiom incompatibilities]+ maybe_index+ = sdocWithDynFlags $ \dflags ->+ ppWhen (gopt Opt_PrintAxiomIncomps dflags) $+ text "{-" <+> (text "#" <> ppr idx) <+> text "-}"+ maybe_incomps+ = sdocWithDynFlags $ \dflags ->+ ppWhen (gopt Opt_PrintAxiomIncomps dflags && notNull incomps) $+ text "--" <+> text "incompatible with:"+ <+> pprWithCommas (\incomp -> text "#" <> ppr incomp) incomps++instance Outputable IfaceAnnotation where+ ppr (IfaceAnnotation target value) = ppr target <+> colon <+> ppr value++instance NamedThing IfaceClassOp where+ getName (IfaceClassOp n _ _) = n++instance HasOccName IfaceClassOp where+ occName = getOccName++instance NamedThing IfaceConDecl where+ getName = ifConName++instance HasOccName IfaceConDecl where+ occName = getOccName++instance NamedThing IfaceDecl where+ getName = ifName++instance HasOccName IfaceDecl where+ occName = getOccName++instance Outputable IfaceDecl where+ ppr = pprIfaceDecl showToIface++{-+Note [Minimal complete definition] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The minimal complete definition should only be included if a complete+class definition is shown. Since the minimal complete definition is+anonymous we can't reuse the same mechanism that is used for the+filtering of method signatures. Instead we just check if anything at all is+filtered and hide it in that case.+-}++data ShowSub+ = ShowSub+ { ss_how_much :: ShowHowMuch+ , ss_forall :: ShowForAllFlag }++-- See Note [Printing IfaceDecl binders]+-- The alternative pretty printer referred to in the note.+newtype AltPpr = AltPpr (Maybe (OccName -> SDoc))++data ShowHowMuch+ = ShowHeader AltPpr -- ^Header information only, not rhs+ | ShowSome [OccName] AltPpr+ -- ^ Show only some sub-components. Specifically,+ --+ -- [@[]@] Print all sub-components.+ -- [@(n:ns)@] Print sub-component @n@ with @ShowSub = ns@;+ -- elide other sub-components to @...@+ -- May 14: the list is max 1 element long at the moment+ | ShowIface+ -- ^Everything including GHC-internal information (used in --show-iface)++{-+Note [Printing IfaceDecl binders]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The binders in an IfaceDecl are just OccNames, so we don't know what module they+come from. But when we pretty-print a TyThing by converting to an IfaceDecl+(see PprTyThing), the TyThing may come from some other module so we really need+the module qualifier. We solve this by passing in a pretty-printer for the+binders.++When printing an interface file (--show-iface), we want to print+everything unqualified, so we can just print the OccName directly.+-}++instance Outputable ShowHowMuch where+ ppr (ShowHeader _) = text "ShowHeader"+ ppr ShowIface = text "ShowIface"+ ppr (ShowSome occs _) = text "ShowSome" <+> ppr occs++showToHeader :: ShowSub+showToHeader = ShowSub { ss_how_much = ShowHeader $ AltPpr Nothing+ , ss_forall = ShowForAllWhen }++showToIface :: ShowSub+showToIface = ShowSub { ss_how_much = ShowIface+ , ss_forall = ShowForAllWhen }++ppShowIface :: ShowSub -> SDoc -> SDoc+ppShowIface (ShowSub { ss_how_much = ShowIface }) doc = doc+ppShowIface _ _ = Outputable.empty++-- show if all sub-components or the complete interface is shown+ppShowAllSubs :: ShowSub -> SDoc -> SDoc -- Note [Minimal complete definition]+ppShowAllSubs (ShowSub { ss_how_much = ShowSome [] _ }) doc = doc+ppShowAllSubs (ShowSub { ss_how_much = ShowIface }) doc = doc+ppShowAllSubs _ _ = Outputable.empty++ppShowRhs :: ShowSub -> SDoc -> SDoc+ppShowRhs (ShowSub { ss_how_much = ShowHeader _ }) _ = Outputable.empty+ppShowRhs _ doc = doc++showSub :: HasOccName n => ShowSub -> n -> Bool+showSub (ShowSub { ss_how_much = ShowHeader _ }) _ = False+showSub (ShowSub { ss_how_much = ShowSome (n:_) _ }) thing = n == occName thing+showSub (ShowSub { ss_how_much = _ }) _ = True++ppr_trim :: [Maybe SDoc] -> [SDoc]+-- Collapse a group of Nothings to a single "..."+ppr_trim xs+ = snd (foldr go (False, []) xs)+ where+ go (Just doc) (_, so_far) = (False, doc : so_far)+ go Nothing (True, so_far) = (True, so_far)+ go Nothing (False, so_far) = (True, text "..." : so_far)++isIfaceDataInstance :: IfaceTyConParent -> Bool+isIfaceDataInstance IfNoParent = False+isIfaceDataInstance _ = True++pprClassRoles :: ShowSub -> IfaceTopBndr -> [IfaceTyConBinder] -> [Role] -> SDoc+pprClassRoles ss clas binders roles =+ pprRoles (== Nominal)+ (pprPrefixIfDeclBndr (ss_how_much ss) (occName clas))+ binders+ roles++pprClassStandaloneKindSig :: ShowSub -> IfaceTopBndr -> IfaceKind -> SDoc+pprClassStandaloneKindSig ss clas =+ pprStandaloneKindSig (pprPrefixIfDeclBndr (ss_how_much ss) (occName clas))++constraintIfaceKind :: IfaceKind+constraintIfaceKind =+ IfaceTyConApp (IfaceTyCon constraintKindTyConName (IfaceTyConInfo NotPromoted IfaceNormalTyCon)) IA_Nil++pprIfaceDecl :: ShowSub -> IfaceDecl -> SDoc+-- NB: pprIfaceDecl is also used for pretty-printing TyThings in GHCi+-- See Note [Pretty-printing TyThings] in PprTyThing+pprIfaceDecl ss (IfaceData { ifName = tycon, ifCType = ctype,+ ifCtxt = context, ifResKind = kind,+ ifRoles = roles, ifCons = condecls,+ ifParent = parent,+ ifGadtSyntax = gadt,+ ifBinders = binders })++ | gadt = vcat [ pp_roles+ , pp_ki_sig+ , pp_nd <+> pp_lhs <+> pp_kind <+> pp_where+ , nest 2 (vcat pp_cons)+ , nest 2 $ ppShowIface ss pp_extra ]+ | otherwise = vcat [ pp_roles+ , pp_ki_sig+ , hang (pp_nd <+> pp_lhs) 2 (add_bars pp_cons)+ , nest 2 $ ppShowIface ss pp_extra ]+ where+ is_data_instance = isIfaceDataInstance parent+ -- See Note [Printing foralls in type family instances] in GHC.Iface.Type+ pp_data_inst_forall :: SDoc+ pp_data_inst_forall = pprUserIfaceForAll forall_bndrs++ forall_bndrs :: [IfaceForAllBndr]+ forall_bndrs = [Bndr (binderVar tc_bndr) Specified | tc_bndr <- binders]++ cons = visibleIfConDecls condecls+ pp_where = ppWhen (gadt && not (null cons)) $ text "where"+ pp_cons = ppr_trim (map show_con cons) :: [SDoc]+ pp_kind = ppUnless (if ki_sig_printable+ then isIfaceTauType kind+ -- Even in the presence of a standalone kind signature, a non-tau+ -- result kind annotation cannot be discarded as it determines the arity.+ -- See Note [Arity inference in kcDeclHeader_sig] in TcHsType+ else isIfaceLiftedTypeKind kind)+ (dcolon <+> ppr kind)++ pp_lhs = case parent of+ IfNoParent -> pprIfaceDeclHead suppress_bndr_sig context ss tycon binders+ IfDataInstance{}+ -> text "instance" <+> pp_data_inst_forall+ <+> pprIfaceTyConParent parent++ pp_roles+ | is_data_instance = empty+ | otherwise = pprRoles (== Representational) name_doc binders roles+ -- Don't display roles for data family instances (yet)+ -- See discussion on #8672.++ ki_sig_printable =+ -- If we print a standalone kind signature for a data instance, we leak+ -- the internal constructor name:+ --+ -- type T15827.R:Dka :: forall k. k -> *+ -- data instance forall k (a :: k). D a = MkD (Proxy a)+ --+ -- This T15827.R:Dka is a compiler-generated type constructor for the+ -- data instance.+ not is_data_instance++ pp_ki_sig = ppWhen ki_sig_printable $+ pprStandaloneKindSig name_doc (mkIfaceTyConKind binders kind)++ -- See Note [Suppressing binder signatures] in GHC.Iface.Type+ suppress_bndr_sig = SuppressBndrSig ki_sig_printable++ name_doc = pprPrefixIfDeclBndr (ss_how_much ss) (occName tycon)++ add_bars [] = Outputable.empty+ add_bars (c:cs) = sep ((equals <+> c) : map (vbar <+>) cs)++ ok_con dc = showSub ss dc || any (showSub ss . flSelector) (ifConFields dc)++ show_con dc+ | ok_con dc = Just $ pprIfaceConDecl ss gadt tycon binders parent dc+ | otherwise = Nothing++ pp_nd = case condecls of+ IfAbstractTyCon{} -> text "data"+ IfDataTyCon{} -> text "data"+ IfNewTyCon{} -> text "newtype"++ pp_extra = vcat [pprCType ctype]++pprIfaceDecl ss (IfaceClass { ifName = clas+ , ifRoles = roles+ , ifFDs = fds+ , ifBinders = binders+ , ifBody = IfAbstractClass })+ = vcat [ pprClassRoles ss clas binders roles+ , pprClassStandaloneKindSig ss clas (mkIfaceTyConKind binders constraintIfaceKind)+ , text "class" <+> pprIfaceDeclHead suppress_bndr_sig [] ss clas binders <+> pprFundeps fds ]+ where+ -- See Note [Suppressing binder signatures] in GHC.Iface.Type+ suppress_bndr_sig = SuppressBndrSig True++pprIfaceDecl ss (IfaceClass { ifName = clas+ , ifRoles = roles+ , ifFDs = fds+ , ifBinders = binders+ , ifBody = IfConcreteClass {+ ifATs = ats,+ ifSigs = sigs,+ ifClassCtxt = context,+ ifMinDef = minDef+ }})+ = vcat [ pprClassRoles ss clas binders roles+ , pprClassStandaloneKindSig ss clas (mkIfaceTyConKind binders constraintIfaceKind)+ , text "class" <+> pprIfaceDeclHead suppress_bndr_sig context ss clas binders <+> pprFundeps fds <+> pp_where+ , nest 2 (vcat [ vcat asocs, vcat dsigs+ , ppShowAllSubs ss (pprMinDef minDef)])]+ where+ pp_where = ppShowRhs ss $ ppUnless (null sigs && null ats) (text "where")++ asocs = ppr_trim $ map maybeShowAssoc ats+ dsigs = ppr_trim $ map maybeShowSig sigs++ maybeShowAssoc :: IfaceAT -> Maybe SDoc+ maybeShowAssoc asc@(IfaceAT d _)+ | showSub ss d = Just $ pprIfaceAT ss asc+ | otherwise = Nothing++ maybeShowSig :: IfaceClassOp -> Maybe SDoc+ maybeShowSig sg+ | showSub ss sg = Just $ pprIfaceClassOp ss sg+ | otherwise = Nothing++ pprMinDef :: BooleanFormula IfLclName -> SDoc+ pprMinDef minDef = ppUnless (isTrue minDef) $ -- hide empty definitions+ text "{-# MINIMAL" <+>+ pprBooleanFormula+ (\_ def -> cparen (isLexSym def) (ppr def)) 0 minDef <+>+ text "#-}"++ -- See Note [Suppressing binder signatures] in GHC.Iface.Type+ suppress_bndr_sig = SuppressBndrSig True++pprIfaceDecl ss (IfaceSynonym { ifName = tc+ , ifBinders = binders+ , ifSynRhs = mono_ty+ , ifResKind = res_kind})+ = vcat [ pprStandaloneKindSig name_doc (mkIfaceTyConKind binders res_kind)+ , hang (text "type" <+> pprIfaceDeclHead suppress_bndr_sig [] ss tc binders <+> equals)+ 2 (sep [ pprIfaceForAll tvs, pprIfaceContextArr theta, ppr tau+ , ppUnless (isIfaceLiftedTypeKind res_kind) (dcolon <+> ppr res_kind) ])+ ]+ where+ (tvs, theta, tau) = splitIfaceSigmaTy mono_ty+ name_doc = pprPrefixIfDeclBndr (ss_how_much ss) (occName tc)++ -- See Note [Suppressing binder signatures] in GHC.Iface.Type+ suppress_bndr_sig = SuppressBndrSig True++pprIfaceDecl ss (IfaceFamily { ifName = tycon+ , ifFamFlav = rhs, ifBinders = binders+ , ifResKind = res_kind+ , ifResVar = res_var, ifFamInj = inj })+ | IfaceDataFamilyTyCon <- rhs+ = vcat [ pprStandaloneKindSig name_doc (mkIfaceTyConKind binders res_kind)+ , text "data family" <+> pprIfaceDeclHead suppress_bndr_sig [] ss tycon binders+ ]++ | otherwise+ = vcat [ pprStandaloneKindSig name_doc (mkIfaceTyConKind binders res_kind)+ , hang (text "type family"+ <+> pprIfaceDeclHead suppress_bndr_sig [] ss tycon binders+ <+> ppShowRhs ss (pp_where rhs))+ 2 (pp_inj res_var inj <+> ppShowRhs ss (pp_rhs rhs))+ $$+ nest 2 (ppShowRhs ss (pp_branches rhs))+ ]+ where+ name_doc = pprPrefixIfDeclBndr (ss_how_much ss) (occName tycon)++ pp_where (IfaceClosedSynFamilyTyCon {}) = text "where"+ pp_where _ = empty++ pp_inj Nothing _ = empty+ pp_inj (Just res) inj+ | Injective injectivity <- inj = hsep [ equals, ppr res+ , pp_inj_cond res injectivity]+ | otherwise = hsep [ equals, ppr res ]++ pp_inj_cond res inj = case filterByList inj binders of+ [] -> empty+ tvs -> hsep [vbar, ppr res, text "->", interppSP (map ifTyConBinderName tvs)]++ pp_rhs IfaceDataFamilyTyCon+ = ppShowIface ss (text "data")+ pp_rhs IfaceOpenSynFamilyTyCon+ = ppShowIface ss (text "open")+ pp_rhs IfaceAbstractClosedSynFamilyTyCon+ = ppShowIface ss (text "closed, abstract")+ pp_rhs (IfaceClosedSynFamilyTyCon {})+ = empty -- see pp_branches+ pp_rhs IfaceBuiltInSynFamTyCon+ = ppShowIface ss (text "built-in")++ pp_branches (IfaceClosedSynFamilyTyCon (Just (ax, brs)))+ = vcat (unzipWith (pprAxBranch+ (pprPrefixIfDeclBndr+ (ss_how_much ss)+ (occName tycon))+ ) $ zip [0..] brs)+ $$ ppShowIface ss (text "axiom" <+> ppr ax)+ pp_branches _ = Outputable.empty++ -- See Note [Suppressing binder signatures] in GHC.Iface.Type+ suppress_bndr_sig = SuppressBndrSig True++pprIfaceDecl _ (IfacePatSyn { ifName = name,+ ifPatUnivBndrs = univ_bndrs, ifPatExBndrs = ex_bndrs,+ ifPatProvCtxt = prov_ctxt, ifPatReqCtxt = req_ctxt,+ ifPatArgs = arg_tys,+ ifPatTy = pat_ty} )+ = sdocWithDynFlags mk_msg+ where+ mk_msg dflags+ = hang (text "pattern" <+> pprPrefixOcc name)+ 2 (dcolon <+> sep [univ_msg+ , pprIfaceContextArr req_ctxt+ , ppWhen insert_empty_ctxt $ parens empty <+> darrow+ , ex_msg+ , pprIfaceContextArr prov_ctxt+ , pprIfaceType $ foldr (IfaceFunTy VisArg) pat_ty arg_tys ])+ where+ univ_msg = pprUserIfaceForAll univ_bndrs+ ex_msg = pprUserIfaceForAll ex_bndrs++ insert_empty_ctxt = null req_ctxt+ && not (null prov_ctxt && isEmpty dflags ex_msg)++pprIfaceDecl ss (IfaceId { ifName = var, ifType = ty,+ ifIdDetails = details, ifIdInfo = info })+ = vcat [ hang (pprPrefixIfDeclBndr (ss_how_much ss) (occName var) <+> dcolon)+ 2 (pprIfaceSigmaType (ss_forall ss) ty)+ , ppShowIface ss (ppr details)+ , ppShowIface ss (ppr info) ]++pprIfaceDecl _ (IfaceAxiom { ifName = name, ifTyCon = tycon+ , ifAxBranches = branches })+ = hang (text "axiom" <+> ppr name <+> dcolon)+ 2 (vcat $ unzipWith (pprAxBranch (ppr tycon)) $ zip [0..] branches)++pprCType :: Maybe CType -> SDoc+pprCType Nothing = Outputable.empty+pprCType (Just cType) = text "C type:" <+> ppr cType++-- if, for each role, suppress_if role is True, then suppress the role+-- output+pprRoles :: (Role -> Bool) -> SDoc -> [IfaceTyConBinder]+ -> [Role] -> SDoc+pprRoles suppress_if tyCon bndrs roles+ = sdocWithDynFlags $ \dflags ->+ let froles = suppressIfaceInvisibles dflags bndrs roles+ in ppUnless (all suppress_if froles || null froles) $+ text "type role" <+> tyCon <+> hsep (map ppr froles)++pprStandaloneKindSig :: SDoc -> IfaceType -> SDoc+pprStandaloneKindSig tyCon ty = text "type" <+> tyCon <+> text "::" <+> ppr ty++pprInfixIfDeclBndr :: ShowHowMuch -> OccName -> SDoc+pprInfixIfDeclBndr (ShowSome _ (AltPpr (Just ppr_bndr))) name+ = pprInfixVar (isSymOcc name) (ppr_bndr name)+pprInfixIfDeclBndr _ name+ = pprInfixVar (isSymOcc name) (ppr name)++pprPrefixIfDeclBndr :: ShowHowMuch -> OccName -> SDoc+pprPrefixIfDeclBndr (ShowHeader (AltPpr (Just ppr_bndr))) name+ = parenSymOcc name (ppr_bndr name)+pprPrefixIfDeclBndr (ShowSome _ (AltPpr (Just ppr_bndr))) name+ = parenSymOcc name (ppr_bndr name)+pprPrefixIfDeclBndr _ name+ = parenSymOcc name (ppr name)++instance Outputable IfaceClassOp where+ ppr = pprIfaceClassOp showToIface++pprIfaceClassOp :: ShowSub -> IfaceClassOp -> SDoc+pprIfaceClassOp ss (IfaceClassOp n ty dm)+ = pp_sig n ty $$ generic_dm+ where+ generic_dm | Just (GenericDM dm_ty) <- dm+ = text "default" <+> pp_sig n dm_ty+ | otherwise+ = empty+ pp_sig n ty+ = pprPrefixIfDeclBndr (ss_how_much ss) (occName n)+ <+> dcolon+ <+> pprIfaceSigmaType ShowForAllWhen ty++instance Outputable IfaceAT where+ ppr = pprIfaceAT showToIface++pprIfaceAT :: ShowSub -> IfaceAT -> SDoc+pprIfaceAT ss (IfaceAT d mb_def)+ = vcat [ pprIfaceDecl ss d+ , case mb_def of+ Nothing -> Outputable.empty+ Just rhs -> nest 2 $+ text "Default:" <+> ppr rhs ]++instance Outputable IfaceTyConParent where+ ppr p = pprIfaceTyConParent p++pprIfaceTyConParent :: IfaceTyConParent -> SDoc+pprIfaceTyConParent IfNoParent+ = Outputable.empty+pprIfaceTyConParent (IfDataInstance _ tc tys)+ = pprIfaceTypeApp topPrec tc tys++pprIfaceDeclHead :: SuppressBndrSig+ -> IfaceContext -> ShowSub -> Name+ -> [IfaceTyConBinder] -- of the tycon, for invisible-suppression+ -> SDoc+pprIfaceDeclHead suppress_sig context ss tc_occ bndrs+ = sdocWithDynFlags $ \ dflags ->+ sep [ pprIfaceContextArr context+ , pprPrefixIfDeclBndr (ss_how_much ss) (occName tc_occ)+ <+> pprIfaceTyConBinders suppress_sig+ (suppressIfaceInvisibles dflags bndrs bndrs) ]++pprIfaceConDecl :: ShowSub -> Bool+ -> IfaceTopBndr+ -> [IfaceTyConBinder]+ -> IfaceTyConParent+ -> IfaceConDecl -> SDoc+pprIfaceConDecl ss gadt_style tycon tc_binders parent+ (IfCon { ifConName = name, ifConInfix = is_infix,+ ifConUserTvBinders = user_tvbs,+ ifConEqSpec = eq_spec, ifConCtxt = ctxt, ifConArgTys = arg_tys,+ ifConStricts = stricts, ifConFields = fields })+ | gadt_style = pp_prefix_con <+> dcolon <+> ppr_gadt_ty+ | otherwise = ppr_ex_quant pp_h98_con+ where+ pp_h98_con+ | not (null fields) = pp_prefix_con <+> pp_field_args+ | is_infix+ , [ty1, ty2] <- pp_args+ = sep [ ty1+ , pprInfixIfDeclBndr how_much (occName name)+ , ty2]+ | otherwise = pp_prefix_con <+> sep pp_args++ how_much = ss_how_much ss+ tys_w_strs :: [(IfaceBang, IfaceType)]+ tys_w_strs = zip stricts arg_tys+ pp_prefix_con = pprPrefixIfDeclBndr how_much (occName name)++ -- If we're pretty-printing a H98-style declaration with existential+ -- quantification, then user_tvbs will always consist of the universal+ -- tyvar binders followed by the existential tyvar binders. So to recover+ -- the visibilities of the existential tyvar binders, we can simply drop+ -- the universal tyvar binders from user_tvbs.+ ex_tvbs = dropList tc_binders user_tvbs+ ppr_ex_quant = pprIfaceForAllPartMust ex_tvbs ctxt+ pp_gadt_res_ty = mk_user_con_res_ty eq_spec+ ppr_gadt_ty = pprIfaceForAllPart user_tvbs ctxt pp_tau++ -- A bit gruesome this, but we can't form the full con_tau, and ppr it,+ -- 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)+ [] -> panic "pp_con_taus"+ | otherwise+ = sep [pp_field_args, arrow <+> pp_gadt_res_ty]++ ppr_bang IfNoBang = whenPprDebug $ char '_'+ ppr_bang IfStrict = char '!'+ ppr_bang IfUnpack = text "{-# UNPACK #-}"+ ppr_bang (IfUnpackCo co) = text "! {-# UNPACK #-}" <>+ pprParendIfaceCoercion co++ pprFieldArgTy, pprArgTy :: (IfaceBang, IfaceType) -> SDoc+ -- If using record syntax, the only reason one would need to parenthesize+ -- a compound field type is if it's preceded by a bang pattern.+ pprFieldArgTy (bang, ty) = ppr_arg_ty (bang_prec bang) bang ty+ -- If not using record syntax, a compound field type might need to be+ -- parenthesized if one of the following holds:+ --+ -- 1. We're using Haskell98 syntax.+ -- 2. The field type is preceded with a bang pattern.+ pprArgTy (bang, ty) = ppr_arg_ty (max gadt_prec (bang_prec bang)) bang ty++ ppr_arg_ty :: PprPrec -> IfaceBang -> IfaceType -> SDoc+ ppr_arg_ty prec bang ty = ppr_bang bang <> pprPrecIfaceType prec ty++ -- If we're displaying the fields GADT-style, e.g.,+ --+ -- data Foo a where+ -- MkFoo :: (Int -> Int) -> Maybe a -> Foo+ --+ -- Then we use `funPrec`, since that will ensure `Int -> Int` gets the+ -- parentheses that it requires, but simple compound types like `Maybe a`+ -- (which don't require parentheses in a function argument position) won't+ -- get them, assuming that there are no bang patterns (see bang_prec).+ --+ -- If we're displaying the fields Haskell98-style, e.g.,+ --+ -- data Foo a = MkFoo (Int -> Int) (Maybe a)+ --+ -- Then not only must we parenthesize `Int -> Int`, we must also+ -- parenthesize compound fields like (Maybe a). Therefore, we pick+ -- `appPrec`, which has higher precedence than `funPrec`.+ gadt_prec :: PprPrec+ gadt_prec+ | gadt_style = funPrec+ | otherwise = appPrec++ -- The presence of bang patterns or UNPACK annotations requires+ -- surrounding the type with parentheses, if needed (#13699)+ bang_prec :: IfaceBang -> PprPrec+ bang_prec IfNoBang = topPrec+ bang_prec IfStrict = appPrec+ bang_prec IfUnpack = appPrec+ bang_prec IfUnpackCo{} = appPrec++ pp_args :: [SDoc] -- No records, e.g., ` Maybe a -> Int -> ...` or+ -- `!(Maybe a) -> !Int -> ...`+ pp_args = map pprArgTy tys_w_strs++ pp_field_args :: SDoc -- Records, e.g., { x :: Maybe a, y :: Int } or+ -- { x :: !(Maybe a), y :: !Int }+ pp_field_args = braces $ sep $ punctuate comma $ ppr_trim $+ zipWith maybe_show_label fields tys_w_strs++ maybe_show_label :: FieldLabel -> (IfaceBang, IfaceType) -> Maybe SDoc+ maybe_show_label lbl bty+ | showSub ss sel = Just (pprPrefixIfDeclBndr how_much occ+ <+> dcolon <+> pprFieldArgTy bty)+ | otherwise = Nothing+ where+ sel = flSelector lbl+ occ = mkVarOccFS (flLabel lbl)++ mk_user_con_res_ty :: IfaceEqSpec -> SDoc+ -- See Note [Result type of a data family GADT]+ mk_user_con_res_ty eq_spec+ | IfDataInstance _ tc tys <- parent+ = pprIfaceType (IfaceTyConApp tc (substIfaceAppArgs gadt_subst tys))+ | otherwise+ = ppr_tc_app gadt_subst+ where+ gadt_subst = mkIfaceTySubst eq_spec++ -- When pretty-printing a GADT return type, we:+ --+ -- 1. Take the data tycon binders, extract their variable names and+ -- visibilities, and construct suitable arguments from them. (This is+ -- the role of mk_tc_app_args.)+ -- 2. Apply the GADT substitution constructed from the eq_spec.+ -- (See Note [Result type of a data family GADT].)+ -- 3. Pretty-print the data type constructor applied to its arguments.+ -- This process will omit any invisible arguments, such as coercion+ -- variables, if necessary. (See Note+ -- [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in TyCoRep.)+ ppr_tc_app gadt_subst =+ pprPrefixIfDeclBndr how_much (occName tycon)+ <+> pprParendIfaceAppArgs+ (substIfaceAppArgs gadt_subst (mk_tc_app_args tc_binders))++ mk_tc_app_args :: [IfaceTyConBinder] -> IfaceAppArgs+ mk_tc_app_args [] = IA_Nil+ mk_tc_app_args (Bndr bndr vis:tc_bndrs) =+ IA_Arg (IfaceTyVar (ifaceBndrName bndr)) (tyConBndrVisArgFlag vis)+ (mk_tc_app_args tc_bndrs)++instance Outputable IfaceRule where+ ppr (IfaceRule { ifRuleName = name, ifActivation = act, ifRuleBndrs = bndrs,+ ifRuleHead = fn, ifRuleArgs = args, ifRuleRhs = rhs,+ ifRuleOrph = orph })+ = sep [ hsep [ pprRuleName name+ , if isOrphan orph then text "[orphan]" else Outputable.empty+ , ppr act+ , pp_foralls ]+ , nest 2 (sep [ppr fn <+> sep (map pprParendIfaceExpr args),+ text "=" <+> ppr rhs]) ]+ where+ pp_foralls = ppUnless (null bndrs) $ forAllLit <+> pprIfaceBndrs bndrs <> dot++instance Outputable IfaceClsInst where+ ppr (IfaceClsInst { ifDFun = dfun_id, ifOFlag = flag+ , ifInstCls = cls, ifInstTys = mb_tcs+ , ifInstOrph = orph })+ = hang (text "instance" <+> ppr flag+ <+> (if isOrphan orph then text "[orphan]" else Outputable.empty)+ <+> ppr cls <+> brackets (pprWithCommas ppr_rough mb_tcs))+ 2 (equals <+> ppr dfun_id)++instance Outputable IfaceFamInst where+ ppr (IfaceFamInst { ifFamInstFam = fam, ifFamInstTys = mb_tcs+ , ifFamInstAxiom = tycon_ax, ifFamInstOrph = orph })+ = hang (text "family instance"+ <+> (if isOrphan orph then text "[orphan]" else Outputable.empty)+ <+> ppr fam <+> pprWithCommas (brackets . ppr_rough) mb_tcs)+ 2 (equals <+> ppr tycon_ax)++ppr_rough :: Maybe IfaceTyCon -> SDoc+ppr_rough Nothing = dot+ppr_rough (Just tc) = ppr tc++{-+Note [Result type of a data family GADT]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider+ data family T a+ data instance T (p,q) where+ T1 :: T (Int, Maybe c)+ T2 :: T (Bool, q)++The IfaceDecl actually looks like++ data TPr p q where+ T1 :: forall p q. forall c. (p~Int,q~Maybe c) => TPr p q+ T2 :: forall p q. (p~Bool) => TPr p q++To reconstruct the result types for T1 and T2 that we+want to pretty print, we substitute the eq-spec+[p->Int, q->Maybe c] in the arg pattern (p,q) to give+ T (Int, Maybe c)+Remember that in IfaceSyn, the TyCon and DataCon share the same+universal type variables.++----------------------------- Printing IfaceExpr ------------------------------------+-}++instance Outputable IfaceExpr where+ ppr e = pprIfaceExpr noParens e++noParens :: SDoc -> SDoc+noParens pp = pp++pprParendIfaceExpr :: IfaceExpr -> SDoc+pprParendIfaceExpr = pprIfaceExpr parens++-- | Pretty Print an IfaceExpre+--+-- The first argument should be a function that adds parens in context that need+-- an atomic value (e.g. function args)+pprIfaceExpr :: (SDoc -> SDoc) -> IfaceExpr -> SDoc++pprIfaceExpr _ (IfaceLcl v) = ppr v+pprIfaceExpr _ (IfaceExt v) = ppr v+pprIfaceExpr _ (IfaceLit l) = ppr l+pprIfaceExpr _ (IfaceFCall cc ty) = braces (ppr cc <+> ppr ty)+pprIfaceExpr _ (IfaceType ty) = char '@' <> pprParendIfaceType ty+pprIfaceExpr _ (IfaceCo co) = text "@~" <> pprParendIfaceCoercion co++pprIfaceExpr add_par app@(IfaceApp _ _) = add_par (pprIfaceApp app [])+pprIfaceExpr _ (IfaceTuple c as) = tupleParens c (pprWithCommas ppr as)++pprIfaceExpr add_par i@(IfaceLam _ _)+ = add_par (sep [char '\\' <+> sep (map pprIfaceLamBndr bndrs) <+> arrow,+ pprIfaceExpr noParens body])+ where+ (bndrs,body) = collect [] i+ collect bs (IfaceLam b e) = collect (b:bs) e+ collect bs e = (reverse bs, e)++pprIfaceExpr add_par (IfaceECase scrut ty)+ = add_par (sep [ text "case" <+> pprIfaceExpr noParens scrut+ , text "ret_ty" <+> pprParendIfaceType ty+ , text "of {}" ])++pprIfaceExpr add_par (IfaceCase scrut bndr [(con, bs, rhs)])+ = add_par (sep [text "case"+ <+> pprIfaceExpr noParens scrut <+> text "of"+ <+> ppr bndr <+> char '{' <+> ppr_con_bs con bs <+> arrow,+ pprIfaceExpr noParens rhs <+> char '}'])++pprIfaceExpr add_par (IfaceCase scrut bndr alts)+ = add_par (sep [text "case"+ <+> pprIfaceExpr noParens scrut <+> text "of"+ <+> ppr bndr <+> char '{',+ nest 2 (sep (map ppr_alt alts)) <+> char '}'])++pprIfaceExpr _ (IfaceCast expr co)+ = sep [pprParendIfaceExpr expr,+ nest 2 (text "`cast`"),+ pprParendIfaceCoercion co]++pprIfaceExpr add_par (IfaceLet (IfaceNonRec b rhs) body)+ = add_par (sep [text "let {",+ nest 2 (ppr_bind (b, rhs)),+ text "} in",+ pprIfaceExpr noParens body])++pprIfaceExpr add_par (IfaceLet (IfaceRec pairs) body)+ = add_par (sep [text "letrec {",+ nest 2 (sep (map ppr_bind pairs)),+ text "} in",+ pprIfaceExpr noParens body])++pprIfaceExpr add_par (IfaceTick tickish e)+ = add_par (pprIfaceTickish tickish <+> pprIfaceExpr noParens e)++ppr_alt :: (IfaceConAlt, [IfLclName], IfaceExpr) -> SDoc+ppr_alt (con, bs, rhs) = sep [ppr_con_bs con bs,+ arrow <+> pprIfaceExpr noParens rhs]++ppr_con_bs :: IfaceConAlt -> [IfLclName] -> SDoc+ppr_con_bs con bs = ppr con <+> hsep (map ppr bs)++ppr_bind :: (IfaceLetBndr, IfaceExpr) -> SDoc+ppr_bind (IfLetBndr b ty info ji, rhs)+ = sep [hang (ppr b <+> dcolon <+> ppr ty) 2 (ppr ji <+> ppr info),+ equals <+> pprIfaceExpr noParens rhs]++------------------+pprIfaceTickish :: IfaceTickish -> SDoc+pprIfaceTickish (IfaceHpcTick m ix)+ = braces (text "tick" <+> ppr m <+> ppr ix)+pprIfaceTickish (IfaceSCC cc tick scope)+ = braces (pprCostCentreCore cc <+> ppr tick <+> ppr scope)+pprIfaceTickish (IfaceSource src _names)+ = braces (pprUserRealSpan True src)++------------------+pprIfaceApp :: IfaceExpr -> [SDoc] -> SDoc+pprIfaceApp (IfaceApp fun arg) args = pprIfaceApp fun $+ nest 2 (pprParendIfaceExpr arg) : args+pprIfaceApp fun args = sep (pprParendIfaceExpr fun : args)++------------------+instance Outputable IfaceConAlt where+ ppr IfaceDefault = text "DEFAULT"+ ppr (IfaceLitAlt l) = ppr l+ ppr (IfaceDataAlt d) = ppr d++------------------+instance Outputable IfaceIdDetails where+ ppr IfVanillaId = Outputable.empty+ ppr (IfRecSelId tc b) = text "RecSel" <+> ppr tc+ <+> if b+ then text "<naughty>"+ else Outputable.empty+ ppr IfDFunId = text "DFunId"++instance Outputable IfaceIdInfo where+ ppr NoInfo = Outputable.empty+ ppr (HasInfo is) = text "{-" <+> pprWithCommas ppr is+ <+> text "-}"++instance Outputable IfaceInfoItem where+ ppr (HsUnfold lb unf) = text "Unfolding"+ <> ppWhen lb (text "(loop-breaker)")+ <> colon <+> ppr unf+ ppr (HsInline prag) = text "Inline:" <+> ppr prag+ ppr (HsArity arity) = text "Arity:" <+> int arity+ ppr (HsStrictness str) = text "Strictness:" <+> pprIfaceStrictSig str+ ppr HsNoCafRefs = text "HasNoCafRefs"+ ppr HsLevity = text "Never levity-polymorphic"++instance Outputable IfaceJoinInfo where+ ppr IfaceNotJoinPoint = empty+ ppr (IfaceJoinPoint ar) = angleBrackets (text "join" <+> ppr ar)++instance Outputable IfaceUnfolding where+ ppr (IfCompulsory e) = text "<compulsory>" <+> parens (ppr e)+ ppr (IfCoreUnfold s e) = (if s+ then text "<stable>"+ else Outputable.empty)+ <+> parens (ppr e)+ ppr (IfInlineRule a uok bok e) = sep [text "InlineRule"+ <+> ppr (a,uok,bok),+ pprParendIfaceExpr e]+ ppr (IfDFunUnfold bs es) = hang (text "DFun:" <+> sep (map ppr bs) <> dot)+ 2 (sep (map pprParendIfaceExpr es))++{-+************************************************************************+* *+ Finding the Names in Iface syntax+* *+************************************************************************++This is used for dependency analysis in GHC.Iface.Utils, so that we+fingerprint a declaration before the things that depend on it. It+is specific to interface-file fingerprinting in the sense that we+don't collect *all* Names: for example, the DFun of an instance is+recorded textually rather than by its fingerprint when+fingerprinting the instance, so DFuns are not dependencies.+-}++freeNamesIfDecl :: IfaceDecl -> NameSet+freeNamesIfDecl (IfaceId { ifType = t, ifIdDetails = d, ifIdInfo = i})+ = freeNamesIfType t &&&+ freeNamesIfIdInfo i &&&+ freeNamesIfIdDetails d++freeNamesIfDecl (IfaceData { ifBinders = bndrs, ifResKind = res_k+ , ifParent = p, ifCtxt = ctxt, ifCons = cons })+ = freeNamesIfVarBndrs bndrs &&&+ freeNamesIfType res_k &&&+ freeNamesIfaceTyConParent p &&&+ freeNamesIfContext ctxt &&&+ freeNamesIfConDecls cons++freeNamesIfDecl (IfaceSynonym { ifBinders = bndrs, ifResKind = res_k+ , ifSynRhs = rhs })+ = freeNamesIfVarBndrs bndrs &&&+ freeNamesIfKind res_k &&&+ freeNamesIfType rhs++freeNamesIfDecl (IfaceFamily { ifBinders = bndrs, ifResKind = res_k+ , ifFamFlav = flav })+ = freeNamesIfVarBndrs bndrs &&&+ freeNamesIfKind res_k &&&+ freeNamesIfFamFlav flav++freeNamesIfDecl (IfaceClass{ ifBinders = bndrs, ifBody = cls_body })+ = freeNamesIfVarBndrs bndrs &&&+ freeNamesIfClassBody cls_body++freeNamesIfDecl (IfaceAxiom { ifTyCon = tc, ifAxBranches = branches })+ = freeNamesIfTc tc &&&+ fnList freeNamesIfAxBranch branches++freeNamesIfDecl (IfacePatSyn { ifPatMatcher = (matcher, _)+ , ifPatBuilder = mb_builder+ , ifPatUnivBndrs = univ_bndrs+ , ifPatExBndrs = ex_bndrs+ , ifPatProvCtxt = prov_ctxt+ , ifPatReqCtxt = req_ctxt+ , ifPatArgs = args+ , ifPatTy = pat_ty+ , ifFieldLabels = lbls })+ = unitNameSet matcher &&&+ maybe emptyNameSet (unitNameSet . fst) mb_builder &&&+ freeNamesIfVarBndrs univ_bndrs &&&+ freeNamesIfVarBndrs ex_bndrs &&&+ freeNamesIfContext prov_ctxt &&&+ freeNamesIfContext req_ctxt &&&+ fnList freeNamesIfType args &&&+ freeNamesIfType pat_ty &&&+ mkNameSet (map flSelector lbls)++freeNamesIfClassBody :: IfaceClassBody -> NameSet+freeNamesIfClassBody IfAbstractClass+ = emptyNameSet+freeNamesIfClassBody (IfConcreteClass{ ifClassCtxt = ctxt, ifATs = ats, ifSigs = sigs })+ = freeNamesIfContext ctxt &&&+ fnList freeNamesIfAT ats &&&+ fnList freeNamesIfClsSig sigs++freeNamesIfAxBranch :: IfaceAxBranch -> NameSet+freeNamesIfAxBranch (IfaceAxBranch { ifaxbTyVars = tyvars+ , ifaxbCoVars = covars+ , ifaxbLHS = lhs+ , ifaxbRHS = rhs })+ = fnList freeNamesIfTvBndr tyvars &&&+ fnList freeNamesIfIdBndr covars &&&+ freeNamesIfAppArgs lhs &&&+ freeNamesIfType rhs++freeNamesIfIdDetails :: IfaceIdDetails -> NameSet+freeNamesIfIdDetails (IfRecSelId tc _) =+ either freeNamesIfTc freeNamesIfDecl tc+freeNamesIfIdDetails _ = emptyNameSet++-- All other changes are handled via the version info on the tycon+freeNamesIfFamFlav :: IfaceFamTyConFlav -> NameSet+freeNamesIfFamFlav IfaceOpenSynFamilyTyCon = emptyNameSet+freeNamesIfFamFlav IfaceDataFamilyTyCon = emptyNameSet+freeNamesIfFamFlav (IfaceClosedSynFamilyTyCon (Just (ax, br)))+ = unitNameSet ax &&& fnList freeNamesIfAxBranch br+freeNamesIfFamFlav (IfaceClosedSynFamilyTyCon Nothing) = emptyNameSet+freeNamesIfFamFlav IfaceAbstractClosedSynFamilyTyCon = emptyNameSet+freeNamesIfFamFlav IfaceBuiltInSynFamTyCon = emptyNameSet++freeNamesIfContext :: IfaceContext -> NameSet+freeNamesIfContext = fnList freeNamesIfType++freeNamesIfAT :: IfaceAT -> NameSet+freeNamesIfAT (IfaceAT decl mb_def)+ = freeNamesIfDecl decl &&&+ case mb_def of+ Nothing -> emptyNameSet+ Just rhs -> freeNamesIfType rhs++freeNamesIfClsSig :: IfaceClassOp -> NameSet+freeNamesIfClsSig (IfaceClassOp _n ty dm) = freeNamesIfType ty &&& freeNamesDM dm++freeNamesDM :: Maybe (DefMethSpec IfaceType) -> NameSet+freeNamesDM (Just (GenericDM ty)) = freeNamesIfType ty+freeNamesDM _ = emptyNameSet++freeNamesIfConDecls :: IfaceConDecls -> NameSet+freeNamesIfConDecls (IfDataTyCon c) = fnList freeNamesIfConDecl c+freeNamesIfConDecls (IfNewTyCon c) = freeNamesIfConDecl c+freeNamesIfConDecls _ = emptyNameSet++freeNamesIfConDecl :: IfaceConDecl -> NameSet+freeNamesIfConDecl (IfCon { ifConExTCvs = ex_tvs, ifConCtxt = ctxt+ , ifConArgTys = arg_tys+ , ifConFields = flds+ , ifConEqSpec = eq_spec+ , ifConStricts = bangs })+ = fnList freeNamesIfBndr ex_tvs &&&+ freeNamesIfContext ctxt &&&+ fnList freeNamesIfType arg_tys &&&+ mkNameSet (map flSelector flds) &&&+ fnList freeNamesIfType (map snd eq_spec) &&& -- equality constraints+ fnList freeNamesIfBang bangs++freeNamesIfBang :: IfaceBang -> NameSet+freeNamesIfBang (IfUnpackCo co) = freeNamesIfCoercion co+freeNamesIfBang _ = emptyNameSet++freeNamesIfKind :: IfaceType -> NameSet+freeNamesIfKind = freeNamesIfType++freeNamesIfAppArgs :: IfaceAppArgs -> NameSet+freeNamesIfAppArgs (IA_Arg t _ ts) = freeNamesIfType t &&& freeNamesIfAppArgs ts+freeNamesIfAppArgs IA_Nil = emptyNameSet++freeNamesIfType :: IfaceType -> NameSet+freeNamesIfType (IfaceFreeTyVar _) = emptyNameSet+freeNamesIfType (IfaceTyVar _) = emptyNameSet+freeNamesIfType (IfaceAppTy s t) = freeNamesIfType s &&& freeNamesIfAppArgs t+freeNamesIfType (IfaceTyConApp tc ts) = freeNamesIfTc tc &&& freeNamesIfAppArgs ts+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 (IfaceCastTy t c) = freeNamesIfType t &&& freeNamesIfCoercion c+freeNamesIfType (IfaceCoercionTy c) = freeNamesIfCoercion c++freeNamesIfMCoercion :: IfaceMCoercion -> NameSet+freeNamesIfMCoercion IfaceMRefl = emptyNameSet+freeNamesIfMCoercion (IfaceMCo co) = freeNamesIfCoercion co++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 (IfaceTyConAppCo _ tc cos)+ = freeNamesIfTc tc &&& fnList freeNamesIfCoercion cos+freeNamesIfCoercion (IfaceAppCo c1 c2)+ = freeNamesIfCoercion c1 &&& freeNamesIfCoercion c2+freeNamesIfCoercion (IfaceForAllCo _ kind_co co)+ = freeNamesIfCoercion kind_co &&& freeNamesIfCoercion co+freeNamesIfCoercion (IfaceFreeCoVar _) = emptyNameSet+freeNamesIfCoercion (IfaceCoVarCo _) = emptyNameSet+freeNamesIfCoercion (IfaceHoleCo _) = emptyNameSet+freeNamesIfCoercion (IfaceAxiomInstCo ax _ cos)+ = unitNameSet ax &&& fnList freeNamesIfCoercion cos+freeNamesIfCoercion (IfaceUnivCo p _ t1 t2)+ = freeNamesIfProv p &&& freeNamesIfType t1 &&& freeNamesIfType t2+freeNamesIfCoercion (IfaceSymCo c)+ = freeNamesIfCoercion c+freeNamesIfCoercion (IfaceTransCo c1 c2)+ = freeNamesIfCoercion c1 &&& freeNamesIfCoercion c2+freeNamesIfCoercion (IfaceNthCo _ co)+ = freeNamesIfCoercion co+freeNamesIfCoercion (IfaceLRCo _ co)+ = freeNamesIfCoercion co+freeNamesIfCoercion (IfaceInstCo co co2)+ = freeNamesIfCoercion co &&& freeNamesIfCoercion co2+freeNamesIfCoercion (IfaceKindCo c)+ = freeNamesIfCoercion c+freeNamesIfCoercion (IfaceSubCo co)+ = freeNamesIfCoercion co+freeNamesIfCoercion (IfaceAxiomRuleCo _ax cos)+ -- the axiom is just a string, so we don't count it as a name.+ = fnList freeNamesIfCoercion cos++freeNamesIfProv :: IfaceUnivCoProv -> NameSet+freeNamesIfProv IfaceUnsafeCoerceProv = emptyNameSet+freeNamesIfProv (IfacePhantomProv co) = freeNamesIfCoercion co+freeNamesIfProv (IfaceProofIrrelProv co) = freeNamesIfCoercion co+freeNamesIfProv (IfacePluginProv _) = emptyNameSet++freeNamesIfVarBndr :: VarBndr IfaceBndr vis -> NameSet+freeNamesIfVarBndr (Bndr bndr _) = freeNamesIfBndr bndr++freeNamesIfVarBndrs :: [VarBndr IfaceBndr vis] -> NameSet+freeNamesIfVarBndrs = fnList freeNamesIfVarBndr++freeNamesIfBndr :: IfaceBndr -> NameSet+freeNamesIfBndr (IfaceIdBndr b) = freeNamesIfIdBndr b+freeNamesIfBndr (IfaceTvBndr b) = freeNamesIfTvBndr b++freeNamesIfBndrs :: [IfaceBndr] -> NameSet+freeNamesIfBndrs = fnList freeNamesIfBndr++freeNamesIfLetBndr :: IfaceLetBndr -> NameSet+-- Remember IfaceLetBndr is used only for *nested* bindings+-- The IdInfo can contain an unfolding (in the case of+-- local INLINE pragmas), so look there too+freeNamesIfLetBndr (IfLetBndr _name ty info _ji) = freeNamesIfType ty+ &&& freeNamesIfIdInfo info++freeNamesIfTvBndr :: IfaceTvBndr -> NameSet+freeNamesIfTvBndr (_fs,k) = freeNamesIfKind k+ -- kinds can have Names inside, because of promotion++freeNamesIfIdBndr :: IfaceIdBndr -> NameSet+freeNamesIfIdBndr (_fs,k) = freeNamesIfKind k++freeNamesIfIdInfo :: IfaceIdInfo -> NameSet+freeNamesIfIdInfo NoInfo = emptyNameSet+freeNamesIfIdInfo (HasInfo i) = fnList freeNamesItem i++freeNamesItem :: IfaceInfoItem -> NameSet+freeNamesItem (HsUnfold _ u) = freeNamesIfUnfold u+freeNamesItem _ = emptyNameSet++freeNamesIfUnfold :: IfaceUnfolding -> NameSet+freeNamesIfUnfold (IfCoreUnfold _ e) = freeNamesIfExpr e+freeNamesIfUnfold (IfCompulsory e) = freeNamesIfExpr e+freeNamesIfUnfold (IfInlineRule _ _ _ e) = freeNamesIfExpr e+freeNamesIfUnfold (IfDFunUnfold bs es) = freeNamesIfBndrs bs &&& fnList freeNamesIfExpr es++freeNamesIfExpr :: IfaceExpr -> NameSet+freeNamesIfExpr (IfaceExt v) = unitNameSet v+freeNamesIfExpr (IfaceFCall _ ty) = freeNamesIfType ty+freeNamesIfExpr (IfaceType ty) = freeNamesIfType ty+freeNamesIfExpr (IfaceCo co) = freeNamesIfCoercion co+freeNamesIfExpr (IfaceTuple _ as) = fnList freeNamesIfExpr as+freeNamesIfExpr (IfaceLam (b,_) body) = freeNamesIfBndr b &&& freeNamesIfExpr body+freeNamesIfExpr (IfaceApp f a) = freeNamesIfExpr f &&& freeNamesIfExpr a+freeNamesIfExpr (IfaceCast e co) = freeNamesIfExpr e &&& freeNamesIfCoercion co+freeNamesIfExpr (IfaceTick _ e) = freeNamesIfExpr e+freeNamesIfExpr (IfaceECase e ty) = freeNamesIfExpr e &&& freeNamesIfType ty+freeNamesIfExpr (IfaceCase s _ alts)+ = freeNamesIfExpr s &&& fnList fn_alt alts &&& fn_cons alts+ where+ fn_alt (_con,_bs,r) = freeNamesIfExpr r++ -- Depend on the data constructors. Just one will do!+ -- Note [Tracking data constructors]+ fn_cons [] = emptyNameSet+ fn_cons ((IfaceDefault ,_,_) : xs) = fn_cons xs+ fn_cons ((IfaceDataAlt con,_,_) : _ ) = unitNameSet con+ fn_cons (_ : _ ) = emptyNameSet++freeNamesIfExpr (IfaceLet (IfaceNonRec bndr rhs) body)+ = freeNamesIfLetBndr bndr &&& freeNamesIfExpr rhs &&& freeNamesIfExpr body++freeNamesIfExpr (IfaceLet (IfaceRec as) x)+ = fnList fn_pair as &&& freeNamesIfExpr x+ where+ fn_pair (bndr, rhs) = freeNamesIfLetBndr bndr &&& freeNamesIfExpr rhs++freeNamesIfExpr _ = emptyNameSet++freeNamesIfTc :: IfaceTyCon -> NameSet+freeNamesIfTc tc = unitNameSet (ifaceTyConName tc)+-- ToDo: shouldn't we include IfaceIntTc & co.?++freeNamesIfRule :: IfaceRule -> NameSet+freeNamesIfRule (IfaceRule { ifRuleBndrs = bs, ifRuleHead = f+ , ifRuleArgs = es, ifRuleRhs = rhs })+ = unitNameSet f &&&+ fnList freeNamesIfBndr bs &&&+ fnList freeNamesIfExpr es &&&+ freeNamesIfExpr rhs++freeNamesIfFamInst :: IfaceFamInst -> NameSet+freeNamesIfFamInst (IfaceFamInst { ifFamInstFam = famName+ , ifFamInstAxiom = axName })+ = unitNameSet famName &&&+ unitNameSet axName++freeNamesIfaceTyConParent :: IfaceTyConParent -> NameSet+freeNamesIfaceTyConParent IfNoParent = emptyNameSet+freeNamesIfaceTyConParent (IfDataInstance ax tc tys)+ = unitNameSet ax &&& freeNamesIfTc tc &&& freeNamesIfAppArgs tys++-- helpers+(&&&) :: NameSet -> NameSet -> NameSet+(&&&) = unionNameSet++fnList :: (a -> NameSet) -> [a] -> NameSet+fnList f = foldr (&&&) emptyNameSet . map f++{-+Note [Tracking data constructors]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In a case expression+ case e of { C a -> ...; ... }+You might think that we don't need to include the datacon C+in the free names, because its type will probably show up in+the free names of 'e'. But in rare circumstances this may+not happen. Here's the one that bit me:++ module DynFlags where+ import {-# SOURCE #-} Packages( PackageState )+ data DynFlags = DF ... PackageState ...++ module Packages where+ import DynFlags+ data PackageState = PS ...+ lookupModule (df :: DynFlags)+ = case df of+ DF ...p... -> case p of+ PS ... -> ...++Now, lookupModule depends on DynFlags, but the transitive dependency+on the *locally-defined* type PackageState is not visible. We need+to take account of the use of the data constructor PS in the pattern match.+++************************************************************************+* *+ Binary instances+* *+************************************************************************++Note that there is a bit of subtlety here when we encode names. While+IfaceTopBndrs is really just a synonym for Name, we need to take care to+encode them with {get,put}IfaceTopBndr. The difference becomes important when+we go to fingerprint an IfaceDecl. See Note [Fingerprinting IfaceDecls] for+details.++-}++instance Binary IfaceDecl where+ put_ bh (IfaceId name ty details idinfo) = do+ putByte bh 0+ putIfaceTopBndr bh name+ lazyPut bh (ty, details, idinfo)+ -- See Note [Lazy deserialization of IfaceId]++ put_ bh (IfaceData a1 a2 a3 a4 a5 a6 a7 a8 a9) = do+ putByte bh 2+ putIfaceTopBndr bh a1+ put_ bh a2+ put_ bh a3+ put_ bh a4+ put_ bh a5+ put_ bh a6+ put_ bh a7+ put_ bh a8+ put_ bh a9++ put_ bh (IfaceSynonym a1 a2 a3 a4 a5) = do+ putByte bh 3+ putIfaceTopBndr bh a1+ put_ bh a2+ put_ bh a3+ put_ bh a4+ put_ bh a5++ put_ bh (IfaceFamily a1 a2 a3 a4 a5 a6) = do+ putByte bh 4+ putIfaceTopBndr bh a1+ put_ bh a2+ put_ bh a3+ put_ bh a4+ put_ bh a5+ put_ bh a6++ -- NB: Written in a funny way to avoid an interface change+ put_ bh (IfaceClass {+ ifName = a2,+ ifRoles = a3,+ ifBinders = a4,+ ifFDs = a5,+ ifBody = IfConcreteClass {+ ifClassCtxt = a1,+ ifATs = a6,+ ifSigs = a7,+ ifMinDef = a8+ }}) = do+ putByte bh 5+ put_ bh a1+ putIfaceTopBndr bh a2+ put_ bh a3+ put_ bh a4+ put_ bh a5+ put_ bh a6+ put_ bh a7+ put_ bh a8++ put_ bh (IfaceAxiom a1 a2 a3 a4) = do+ putByte bh 6+ putIfaceTopBndr bh a1+ put_ bh a2+ put_ bh a3+ put_ bh a4++ put_ bh (IfacePatSyn a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = do+ putByte bh 7+ putIfaceTopBndr bh a1+ put_ bh a2+ put_ bh a3+ put_ bh a4+ put_ bh a5+ put_ bh a6+ put_ bh a7+ put_ bh a8+ put_ bh a9+ put_ bh a10+ put_ bh a11++ put_ bh (IfaceClass {+ ifName = a1,+ ifRoles = a2,+ ifBinders = a3,+ ifFDs = a4,+ ifBody = IfAbstractClass }) = do+ putByte bh 8+ putIfaceTopBndr bh a1+ put_ bh a2+ put_ bh a3+ put_ bh a4++ get bh = do+ h <- getByte bh+ case h of+ 0 -> do name <- get bh+ ~(ty, details, idinfo) <- lazyGet bh+ -- See Note [Lazy deserialization of IfaceId]+ return (IfaceId name ty details idinfo)+ 1 -> error "Binary.get(TyClDecl): ForeignType"+ 2 -> do a1 <- getIfaceTopBndr bh+ a2 <- get bh+ a3 <- get bh+ a4 <- get bh+ a5 <- get bh+ a6 <- get bh+ a7 <- get bh+ a8 <- get bh+ a9 <- get bh+ return (IfaceData a1 a2 a3 a4 a5 a6 a7 a8 a9)+ 3 -> do a1 <- getIfaceTopBndr bh+ a2 <- get bh+ a3 <- get bh+ a4 <- get bh+ a5 <- get bh+ return (IfaceSynonym a1 a2 a3 a4 a5)+ 4 -> do a1 <- getIfaceTopBndr bh+ a2 <- get bh+ a3 <- get bh+ a4 <- get bh+ a5 <- get bh+ a6 <- get bh+ return (IfaceFamily a1 a2 a3 a4 a5 a6)+ 5 -> do a1 <- get bh+ a2 <- getIfaceTopBndr bh+ a3 <- get bh+ a4 <- get bh+ a5 <- get bh+ a6 <- get bh+ a7 <- get bh+ a8 <- get bh+ return (IfaceClass {+ ifName = a2,+ ifRoles = a3,+ ifBinders = a4,+ ifFDs = a5,+ ifBody = IfConcreteClass {+ ifClassCtxt = a1,+ ifATs = a6,+ ifSigs = a7,+ ifMinDef = a8+ }})+ 6 -> do a1 <- getIfaceTopBndr bh+ a2 <- get bh+ a3 <- get bh+ a4 <- get bh+ return (IfaceAxiom a1 a2 a3 a4)+ 7 -> do a1 <- getIfaceTopBndr bh+ a2 <- get bh+ a3 <- get bh+ a4 <- get bh+ a5 <- get bh+ a6 <- get bh+ a7 <- get bh+ a8 <- get bh+ a9 <- get bh+ a10 <- get bh+ a11 <- get bh+ return (IfacePatSyn a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11)+ 8 -> do a1 <- getIfaceTopBndr bh+ a2 <- get bh+ a3 <- get bh+ a4 <- get bh+ return (IfaceClass {+ ifName = a1,+ ifRoles = a2,+ ifBinders = a3,+ ifFDs = a4,+ ifBody = IfAbstractClass })+ _ -> panic (unwords ["Unknown IfaceDecl tag:", show h])++{- Note [Lazy deserialization of IfaceId]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The use of lazyPut and lazyGet in the IfaceId Binary instance is+purely for performance reasons, to avoid deserializing details about+identifiers that will never be used. It's not involved in tying the+knot in the type checker. It saved ~1% of the total build time of GHC.++When we read an interface file, we extend the PTE, a mapping of Names+to TyThings, with the declarations we have read. The extension of the+PTE is strict in the Names, but not in the TyThings themselves.+GHC.Iface.Load.loadDecl calculates the list of (Name, TyThing) bindings to+add to the PTE. For an IfaceId, there's just one binding to add; and+the ty, details, and idinfo fields of an IfaceId are used only in the+TyThing. So by reading those fields lazily we may be able to save the+work of ever having to deserialize them (into IfaceType, etc.).++For IfaceData and IfaceClass, loadDecl creates extra implicit bindings+(the constructors and field selectors of the data declaration, or the+methods of the class), whose Names depend on more than just the Name+of the type constructor or class itself. So deserializing them lazily+would be more involved. Similar comments apply to the other+constructors of IfaceDecl with the additional point that they probably+represent a small proportion of all declarations.+-}++instance Binary IfaceFamTyConFlav where+ put_ bh IfaceDataFamilyTyCon = putByte bh 0+ put_ bh IfaceOpenSynFamilyTyCon = putByte bh 1+ put_ bh (IfaceClosedSynFamilyTyCon mb) = putByte bh 2 >> put_ bh mb+ put_ bh IfaceAbstractClosedSynFamilyTyCon = putByte bh 3+ put_ _ IfaceBuiltInSynFamTyCon+ = pprPanic "Cannot serialize IfaceBuiltInSynFamTyCon, used for pretty-printing only" Outputable.empty++ get bh = do { h <- getByte bh+ ; case h of+ 0 -> return IfaceDataFamilyTyCon+ 1 -> return IfaceOpenSynFamilyTyCon+ 2 -> do { mb <- get bh+ ; return (IfaceClosedSynFamilyTyCon mb) }+ 3 -> return IfaceAbstractClosedSynFamilyTyCon+ _ -> pprPanic "Binary.get(IfaceFamTyConFlav): Invalid tag"+ (ppr (fromIntegral h :: Int)) }++instance Binary IfaceClassOp where+ put_ bh (IfaceClassOp n ty def) = do+ putIfaceTopBndr bh n+ put_ bh ty+ put_ bh def+ get bh = do+ n <- getIfaceTopBndr bh+ ty <- get bh+ def <- get bh+ return (IfaceClassOp n ty def)++instance Binary IfaceAT where+ put_ bh (IfaceAT dec defs) = do+ put_ bh dec+ put_ bh defs+ get bh = do+ dec <- get bh+ defs <- get bh+ return (IfaceAT dec defs)++instance Binary IfaceAxBranch where+ put_ bh (IfaceAxBranch a1 a2 a3 a4 a5 a6 a7) = do+ put_ bh a1+ put_ bh a2+ put_ bh a3+ put_ bh a4+ put_ bh a5+ put_ bh a6+ put_ bh a7+ get bh = do+ a1 <- get bh+ a2 <- get bh+ a3 <- get bh+ a4 <- get bh+ a5 <- get bh+ a6 <- get bh+ a7 <- get bh+ return (IfaceAxBranch a1 a2 a3 a4 a5 a6 a7)++instance Binary IfaceConDecls where+ put_ bh IfAbstractTyCon = putByte bh 0+ put_ bh (IfDataTyCon cs) = putByte bh 1 >> put_ bh cs+ put_ bh (IfNewTyCon c) = putByte bh 2 >> put_ bh c+ get bh = do+ h <- getByte bh+ case h of+ 0 -> return IfAbstractTyCon+ 1 -> liftM IfDataTyCon (get bh)+ 2 -> liftM IfNewTyCon (get bh)+ _ -> error "Binary(IfaceConDecls).get: Invalid IfaceConDecls"++instance Binary IfaceConDecl where+ put_ bh (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = do+ putIfaceTopBndr bh a1+ put_ bh a2+ put_ bh a3+ put_ bh a4+ put_ bh a5+ put_ bh a6+ put_ bh a7+ put_ bh a8+ put_ bh (length a9)+ mapM_ (put_ bh) a9+ put_ bh a10+ put_ bh a11+ get bh = do+ a1 <- getIfaceTopBndr bh+ a2 <- get bh+ a3 <- get bh+ a4 <- get bh+ a5 <- get bh+ a6 <- get bh+ a7 <- get bh+ a8 <- get bh+ n_fields <- get bh+ a9 <- replicateM n_fields (get bh)+ a10 <- get bh+ a11 <- get bh+ return (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11)++instance Binary IfaceBang where+ put_ bh IfNoBang = putByte bh 0+ put_ bh IfStrict = putByte bh 1+ put_ bh IfUnpack = putByte bh 2+ put_ bh (IfUnpackCo co) = putByte bh 3 >> put_ bh co++ get bh = do+ h <- getByte bh+ case h of+ 0 -> do return IfNoBang+ 1 -> do return IfStrict+ 2 -> do return IfUnpack+ _ -> do { a <- get bh; return (IfUnpackCo a) }++instance Binary IfaceSrcBang where+ put_ bh (IfSrcBang a1 a2) =+ do put_ bh a1+ put_ bh a2++ get bh =+ do a1 <- get bh+ a2 <- get bh+ return (IfSrcBang a1 a2)++instance Binary IfaceClsInst where+ put_ bh (IfaceClsInst cls tys dfun flag orph) = do+ put_ bh cls+ put_ bh tys+ put_ bh dfun+ put_ bh flag+ put_ bh orph+ get bh = do+ cls <- get bh+ tys <- get bh+ dfun <- get bh+ flag <- get bh+ orph <- get bh+ return (IfaceClsInst cls tys dfun flag orph)++instance Binary IfaceFamInst where+ put_ bh (IfaceFamInst fam tys name orph) = do+ put_ bh fam+ put_ bh tys+ put_ bh name+ put_ bh orph+ get bh = do+ fam <- get bh+ tys <- get bh+ name <- get bh+ orph <- get bh+ return (IfaceFamInst fam tys name orph)++instance Binary IfaceRule where+ put_ bh (IfaceRule a1 a2 a3 a4 a5 a6 a7 a8) = do+ put_ bh a1+ put_ bh a2+ put_ bh a3+ put_ bh a4+ put_ bh a5+ put_ bh a6+ put_ bh a7+ put_ bh a8+ get bh = do+ a1 <- get bh+ a2 <- get bh+ a3 <- get bh+ a4 <- get bh+ a5 <- get bh+ a6 <- get bh+ a7 <- get bh+ a8 <- get bh+ return (IfaceRule a1 a2 a3 a4 a5 a6 a7 a8)++instance Binary IfaceAnnotation where+ put_ bh (IfaceAnnotation a1 a2) = do+ put_ bh a1+ put_ bh a2+ get bh = do+ a1 <- get bh+ a2 <- get bh+ return (IfaceAnnotation a1 a2)++instance Binary IfaceIdDetails where+ put_ bh IfVanillaId = putByte bh 0+ put_ bh (IfRecSelId a b) = putByte bh 1 >> put_ bh a >> put_ bh b+ put_ bh IfDFunId = putByte bh 2+ get bh = do+ h <- getByte bh+ case h of+ 0 -> return IfVanillaId+ 1 -> do { a <- get bh; b <- get bh; return (IfRecSelId a b) }+ _ -> return IfDFunId++instance Binary IfaceIdInfo where+ put_ bh NoInfo = putByte bh 0+ put_ bh (HasInfo i) = putByte bh 1 >> lazyPut bh i -- NB lazyPut++ get bh = do+ h <- getByte bh+ case h of+ 0 -> return NoInfo+ _ -> liftM HasInfo $ lazyGet bh -- NB lazyGet++instance Binary IfaceInfoItem where+ put_ bh (HsArity aa) = putByte bh 0 >> put_ bh aa+ put_ bh (HsStrictness ab) = putByte bh 1 >> put_ bh ab+ put_ bh (HsUnfold lb ad) = putByte bh 2 >> put_ bh lb >> put_ bh ad+ put_ bh (HsInline ad) = putByte bh 3 >> put_ bh ad+ put_ bh HsNoCafRefs = putByte bh 4+ put_ bh HsLevity = putByte bh 5+ get bh = do+ h <- getByte bh+ case h of+ 0 -> liftM HsArity $ get bh+ 1 -> liftM HsStrictness $ get bh+ 2 -> do lb <- get bh+ ad <- get bh+ return (HsUnfold lb ad)+ 3 -> liftM HsInline $ get bh+ 4 -> return HsNoCafRefs+ _ -> return HsLevity++instance Binary IfaceUnfolding where+ put_ bh (IfCoreUnfold s e) = do+ putByte bh 0+ put_ bh s+ put_ bh e+ put_ bh (IfInlineRule a b c d) = do+ putByte bh 1+ put_ bh a+ put_ bh b+ put_ bh c+ put_ bh d+ put_ bh (IfDFunUnfold as bs) = do+ putByte bh 2+ put_ bh as+ put_ bh bs+ put_ bh (IfCompulsory e) = do+ putByte bh 3+ put_ bh e+ get bh = do+ h <- getByte bh+ case h of+ 0 -> do s <- get bh+ e <- get bh+ return (IfCoreUnfold s e)+ 1 -> do a <- get bh+ b <- get bh+ c <- get bh+ d <- get bh+ return (IfInlineRule a b c d)+ 2 -> do as <- get bh+ bs <- get bh+ return (IfDFunUnfold as bs)+ _ -> do e <- get bh+ return (IfCompulsory e)+++instance Binary IfaceExpr where+ put_ bh (IfaceLcl aa) = do+ putByte bh 0+ put_ bh aa+ put_ bh (IfaceType ab) = do+ putByte bh 1+ put_ bh ab+ put_ bh (IfaceCo ab) = do+ putByte bh 2+ put_ bh ab+ put_ bh (IfaceTuple ac ad) = do+ putByte bh 3+ put_ bh ac+ put_ bh ad+ put_ bh (IfaceLam (ae, os) af) = do+ putByte bh 4+ put_ bh ae+ put_ bh os+ put_ bh af+ put_ bh (IfaceApp ag ah) = do+ putByte bh 5+ put_ bh ag+ put_ bh ah+ put_ bh (IfaceCase ai aj ak) = do+ putByte bh 6+ put_ bh ai+ put_ bh aj+ put_ bh ak+ put_ bh (IfaceLet al am) = do+ putByte bh 7+ put_ bh al+ put_ bh am+ put_ bh (IfaceTick an ao) = do+ putByte bh 8+ put_ bh an+ put_ bh ao+ put_ bh (IfaceLit ap) = do+ putByte bh 9+ put_ bh ap+ put_ bh (IfaceFCall as at) = do+ putByte bh 10+ put_ bh as+ put_ bh at+ put_ bh (IfaceExt aa) = do+ putByte bh 11+ put_ bh aa+ put_ bh (IfaceCast ie ico) = do+ putByte bh 12+ put_ bh ie+ put_ bh ico+ put_ bh (IfaceECase a b) = do+ putByte bh 13+ put_ bh a+ put_ bh b+ get bh = do+ h <- getByte bh+ case h of+ 0 -> do aa <- get bh+ return (IfaceLcl aa)+ 1 -> do ab <- get bh+ return (IfaceType ab)+ 2 -> do ab <- get bh+ return (IfaceCo ab)+ 3 -> do ac <- get bh+ ad <- get bh+ return (IfaceTuple ac ad)+ 4 -> do ae <- get bh+ os <- get bh+ af <- get bh+ return (IfaceLam (ae, os) af)+ 5 -> do ag <- get bh+ ah <- get bh+ return (IfaceApp ag ah)+ 6 -> do ai <- get bh+ aj <- get bh+ ak <- get bh+ return (IfaceCase ai aj ak)+ 7 -> do al <- get bh+ am <- get bh+ return (IfaceLet al am)+ 8 -> do an <- get bh+ ao <- get bh+ return (IfaceTick an ao)+ 9 -> do ap <- get bh+ return (IfaceLit ap)+ 10 -> do as <- get bh+ at <- get bh+ return (IfaceFCall as at)+ 11 -> do aa <- get bh+ return (IfaceExt aa)+ 12 -> do ie <- get bh+ ico <- get bh+ return (IfaceCast ie ico)+ 13 -> do a <- get bh+ b <- get bh+ return (IfaceECase a b)+ _ -> panic ("get IfaceExpr " ++ show h)++instance Binary IfaceTickish where+ put_ bh (IfaceHpcTick m ix) = do+ putByte bh 0+ put_ bh m+ put_ bh ix+ put_ bh (IfaceSCC cc tick push) = do+ putByte bh 1+ put_ bh cc+ put_ bh tick+ put_ bh push+ put_ bh (IfaceSource src name) = do+ putByte bh 2+ put_ bh (srcSpanFile src)+ put_ bh (srcSpanStartLine src)+ put_ bh (srcSpanStartCol src)+ put_ bh (srcSpanEndLine src)+ put_ bh (srcSpanEndCol src)+ put_ bh name++ get bh = do+ h <- getByte bh+ case h of+ 0 -> do m <- get bh+ ix <- get bh+ return (IfaceHpcTick m ix)+ 1 -> do cc <- get bh+ tick <- get bh+ push <- get bh+ return (IfaceSCC cc tick push)+ 2 -> do file <- get bh+ sl <- get bh+ sc <- get bh+ el <- get bh+ ec <- get bh+ let start = mkRealSrcLoc file sl sc+ end = mkRealSrcLoc file el ec+ name <- get bh+ return (IfaceSource (mkRealSrcSpan start end) name)+ _ -> panic ("get IfaceTickish " ++ show h)++instance Binary IfaceConAlt where+ put_ bh IfaceDefault = putByte bh 0+ put_ bh (IfaceDataAlt aa) = putByte bh 1 >> put_ bh aa+ put_ bh (IfaceLitAlt ac) = putByte bh 2 >> put_ bh ac+ get bh = do+ h <- getByte bh+ case h of+ 0 -> return IfaceDefault+ 1 -> liftM IfaceDataAlt $ get bh+ _ -> liftM IfaceLitAlt $ get bh++instance Binary IfaceBinding where+ put_ bh (IfaceNonRec aa ab) = putByte bh 0 >> put_ bh aa >> put_ bh ab+ put_ bh (IfaceRec ac) = putByte bh 1 >> put_ bh ac+ get bh = do+ h <- getByte bh+ case h of+ 0 -> do { aa <- get bh; ab <- get bh; return (IfaceNonRec aa ab) }+ _ -> do { ac <- get bh; return (IfaceRec ac) }++instance Binary IfaceLetBndr where+ put_ bh (IfLetBndr a b c d) = do+ put_ bh a+ put_ bh b+ put_ bh c+ put_ bh d+ get bh = do a <- get bh+ b <- get bh+ c <- get bh+ d <- get bh+ return (IfLetBndr a b c d)++instance Binary IfaceJoinInfo where+ put_ bh IfaceNotJoinPoint = putByte bh 0+ put_ bh (IfaceJoinPoint ar) = do+ putByte bh 1+ put_ bh ar+ get bh = do+ h <- getByte bh+ case h of+ 0 -> return IfaceNotJoinPoint+ _ -> liftM IfaceJoinPoint $ get bh++instance Binary IfaceTyConParent where+ put_ bh IfNoParent = putByte bh 0+ put_ bh (IfDataInstance ax pr ty) = do+ putByte bh 1+ put_ bh ax+ put_ bh pr+ put_ bh ty+ get bh = do+ h <- getByte bh+ case h of+ 0 -> return IfNoParent+ _ -> do+ ax <- get bh+ pr <- get bh+ ty <- get bh+ return $ IfDataInstance ax pr ty++instance Binary IfaceCompleteMatch where+ put_ bh (IfaceCompleteMatch cs ts) = put_ bh cs >> put_ bh ts+ get bh = IfaceCompleteMatch <$> get bh <*> get bh+++{-+************************************************************************+* *+ NFData instances+ See Note [Avoiding space leaks in toIface*] in GHC.CoreToIface+* *+************************************************************************+-}++instance NFData IfaceDecl where+ rnf = \case+ IfaceId f1 f2 f3 f4 ->+ rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4++ IfaceData f1 f2 f3 f4 f5 f6 f7 f8 f9 ->+ f1 `seq` seqList f2 `seq` f3 `seq` f4 `seq` f5 `seq`+ rnf f6 `seq` rnf f7 `seq` rnf f8 `seq` rnf f9++ IfaceSynonym f1 f2 f3 f4 f5 ->+ rnf f1 `seq` f2 `seq` seqList f3 `seq` rnf f4 `seq` rnf f5++ IfaceFamily f1 f2 f3 f4 f5 f6 ->+ rnf f1 `seq` rnf f2 `seq` seqList f3 `seq` rnf f4 `seq` rnf f5 `seq` f6 `seq` ()++ IfaceClass f1 f2 f3 f4 f5 ->+ rnf f1 `seq` f2 `seq` seqList f3 `seq` rnf f4 `seq` rnf f5++ IfaceAxiom nm tycon role ax ->+ rnf nm `seq`+ rnf tycon `seq`+ role `seq`+ rnf ax++ IfacePatSyn f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 ->+ rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` f5 `seq` f6 `seq`+ rnf f7 `seq` rnf f8 `seq` rnf f9 `seq` rnf f10 `seq` f11 `seq` ()++instance NFData IfaceAxBranch where+ rnf (IfaceAxBranch f1 f2 f3 f4 f5 f6 f7) =+ rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` f5 `seq` rnf f6 `seq` rnf f7++instance NFData IfaceClassBody where+ rnf = \case+ IfAbstractClass -> ()+ IfConcreteClass f1 f2 f3 f4 -> rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` f4 `seq` ()++instance NFData IfaceAT where+ rnf (IfaceAT f1 f2) = rnf f1 `seq` rnf f2++instance NFData IfaceClassOp where+ rnf (IfaceClassOp f1 f2 f3) = rnf f1 `seq` rnf f2 `seq` f3 `seq` ()++instance NFData IfaceTyConParent where+ rnf = \case+ IfNoParent -> ()+ IfDataInstance f1 f2 f3 -> rnf f1 `seq` rnf f2 `seq` rnf f3++instance NFData IfaceConDecls where+ rnf = \case+ IfAbstractTyCon -> ()+ IfDataTyCon f1 -> rnf f1+ IfNewTyCon f1 -> rnf f1++instance NFData IfaceConDecl where+ rnf (IfCon f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11) =+ rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` f5 `seq` rnf f6 `seq`+ rnf f7 `seq` rnf f8 `seq` f9 `seq` rnf f10 `seq` rnf f11++instance NFData IfaceSrcBang where+ rnf (IfSrcBang f1 f2) = f1 `seq` f2 `seq` ()++instance NFData IfaceBang where+ rnf x = x `seq` ()++instance NFData IfaceIdDetails where+ rnf = \case+ IfVanillaId -> ()+ IfRecSelId (Left tycon) b -> rnf tycon `seq` rnf b+ IfRecSelId (Right decl) b -> rnf decl `seq` rnf b+ IfDFunId -> ()++instance NFData IfaceIdInfo where+ rnf = \case+ NoInfo -> ()+ HasInfo f1 -> rnf f1++instance NFData IfaceInfoItem where+ rnf = \case+ HsArity a -> rnf a+ HsStrictness str -> seqStrictSig str+ HsInline p -> p `seq` () -- TODO: seq further?+ HsUnfold b unf -> rnf b `seq` rnf unf+ HsNoCafRefs -> ()+ HsLevity -> ()++instance NFData IfaceUnfolding where+ rnf = \case+ IfCoreUnfold inlinable expr ->+ rnf inlinable `seq` rnf expr+ IfCompulsory expr ->+ rnf expr+ IfInlineRule arity b1 b2 e ->+ rnf arity `seq` rnf b1 `seq` rnf b2 `seq` rnf e+ IfDFunUnfold bndrs exprs ->+ rnf bndrs `seq` rnf exprs++instance NFData IfaceExpr where+ rnf = \case+ IfaceLcl nm -> rnf nm+ IfaceExt nm -> rnf nm+ IfaceType ty -> rnf ty+ IfaceCo co -> rnf co+ IfaceTuple sort exprs -> sort `seq` rnf exprs+ IfaceLam bndr expr -> rnf bndr `seq` rnf expr+ IfaceApp e1 e2 -> rnf e1 `seq` rnf e2+ IfaceCase e nm alts -> rnf e `seq` nm `seq` rnf alts+ IfaceECase e ty -> rnf e `seq` rnf ty+ IfaceLet bind e -> rnf bind `seq` rnf e+ IfaceCast e co -> rnf e `seq` rnf co+ IfaceLit l -> l `seq` () -- FIXME+ IfaceFCall fc ty -> fc `seq` rnf ty+ IfaceTick tick e -> rnf tick `seq` rnf e++instance NFData IfaceBinding where+ rnf = \case+ IfaceNonRec bndr e -> rnf bndr `seq` rnf e+ IfaceRec binds -> rnf binds++instance NFData IfaceLetBndr where+ rnf (IfLetBndr nm ty id_info join_info) =+ rnf nm `seq` rnf ty `seq` rnf id_info `seq` rnf join_info++instance NFData IfaceFamTyConFlav where+ rnf = \case+ IfaceDataFamilyTyCon -> ()+ IfaceOpenSynFamilyTyCon -> ()+ IfaceClosedSynFamilyTyCon f1 -> rnf f1+ IfaceAbstractClosedSynFamilyTyCon -> ()+ IfaceBuiltInSynFamTyCon -> ()++instance NFData IfaceJoinInfo where+ rnf x = x `seq` ()++instance NFData IfaceTickish where+ rnf = \case+ IfaceHpcTick m i -> rnf m `seq` rnf i+ IfaceSCC cc b1 b2 -> cc `seq` rnf b1 `seq` rnf b2+ IfaceSource src str -> src `seq` rnf str++instance NFData IfaceConAlt where+ rnf = \case+ IfaceDefault -> ()+ IfaceDataAlt nm -> rnf nm+ IfaceLitAlt lit -> lit `seq` ()++instance NFData IfaceCompleteMatch where+ rnf (IfaceCompleteMatch f1 f2) = rnf f1 `seq` rnf f2++instance NFData IfaceRule where+ rnf (IfaceRule f1 f2 f3 f4 f5 f6 f7 f8) =+ rnf f1 `seq` f2 `seq` rnf f3 `seq` rnf f4 `seq` rnf f5 `seq` rnf f6 `seq` rnf f7 `seq` f8 `seq` ()++instance NFData IfaceFamInst where+ rnf (IfaceFamInst f1 f2 f3 f4) =+ rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` f4 `seq` ()++instance NFData IfaceClsInst where+ rnf (IfaceClsInst f1 f2 f3 f4 f5) =+ f1 `seq` rnf f2 `seq` rnf f3 `seq` f4 `seq` f5 `seq` ()++instance NFData IfaceAnnotation where+ rnf (IfaceAnnotation f1 f2) = f1 `seq` f2 `seq` ()
+ compiler/GHC/Iface/Type.hs view
@@ -0,0 +1,2060 @@+{-+(c) The University of Glasgow 2006+(c) The GRASP/AQUA Project, Glasgow University, 1993-1998+++This module defines interface types and binders+-}++{-# LANGUAGE CPP, FlexibleInstances, BangPatterns #-}+{-# LANGUAGE MultiWayIf #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE LambdaCase #-}+ -- FlexibleInstances for Binary (DefMethSpec IfaceType)++module GHC.Iface.Type (+ IfExtName, IfLclName,++ IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..),+ IfaceMCoercion(..),+ IfaceUnivCoProv(..),+ IfaceTyCon(..), IfaceTyConInfo(..), IfaceTyConSort(..),+ IfaceTyLit(..), IfaceAppArgs(..),+ IfaceContext, IfaceBndr(..), IfaceOneShot(..), IfaceLamBndr,+ IfaceTvBndr, IfaceIdBndr, IfaceTyConBinder,+ IfaceForAllBndr, ArgFlag(..), AnonArgFlag(..),+ ForallVisFlag(..), ShowForAllFlag(..),+ mkIfaceForAllTvBndr,+ mkIfaceTyConKind,++ ifForAllBndrVar, ifForAllBndrName, ifaceBndrName,+ ifTyConBinderVar, ifTyConBinderName,++ -- Equality testing+ isIfaceLiftedTypeKind,++ -- Conversion from IfaceAppArgs to IfaceTypes/ArgFlags+ appArgsIfaceTypes, appArgsIfaceTypesArgFlags,++ -- Printing+ SuppressBndrSig(..),+ UseBndrParens(..),+ pprIfaceType, pprParendIfaceType, pprPrecIfaceType,+ pprIfaceContext, pprIfaceContextArr,+ pprIfaceIdBndr, pprIfaceLamBndr, pprIfaceTvBndr, pprIfaceTyConBinders,+ pprIfaceBndrs, pprIfaceAppArgs, pprParendIfaceAppArgs,+ pprIfaceForAllPart, pprIfaceForAllPartMust, pprIfaceForAll,+ pprIfaceSigmaType, pprIfaceTyLit,+ pprIfaceCoercion, pprParendIfaceCoercion,+ splitIfaceSigmaTy, pprIfaceTypeApp, pprUserIfaceForAll,+ pprIfaceCoTcApp, pprTyTcApp, pprIfacePrefixApp,+ isIfaceTauType,++ suppressIfaceInvisibles,+ stripIfaceInvisVars,+ stripInvisArgs,++ mkIfaceTySubst, substIfaceTyVar, substIfaceAppArgs, inDomIfaceTySubst+ ) where++#include "HsVersions.h"++import GhcPrelude++import {-# SOURCE #-} TysWiredIn ( coercibleTyCon, heqTyCon+ , liftedRepDataConTyCon, tupleTyConName )+import {-# SOURCE #-} Type ( isRuntimeRepTy )++import DynFlags+import TyCon hiding ( pprPromotionQuote )+import CoAxiom+import Var+import PrelNames+import Name+import BasicTypes+import Binary+import Outputable+import FastString+import FastStringEnv+import Util++import Data.Maybe( isJust )+import qualified Data.Semigroup as Semi+import Control.DeepSeq++{-+************************************************************************+* *+ Local (nested) binders+* *+************************************************************************+-}++type IfLclName = FastString -- A local name in iface syntax++type IfExtName = Name -- An External or WiredIn Name can appear in Iface syntax+ -- (However Internal or System Names never should)++data IfaceBndr -- Local (non-top-level) binders+ = IfaceIdBndr {-# UNPACK #-} !IfaceIdBndr+ | IfaceTvBndr {-# UNPACK #-} !IfaceTvBndr++type IfaceIdBndr = (IfLclName, IfaceType)+type IfaceTvBndr = (IfLclName, IfaceKind)++ifaceTvBndrName :: IfaceTvBndr -> IfLclName+ifaceTvBndrName (n,_) = n++ifaceIdBndrName :: IfaceIdBndr -> IfLclName+ifaceIdBndrName (n,_) = n++ifaceBndrName :: IfaceBndr -> IfLclName+ifaceBndrName (IfaceTvBndr bndr) = ifaceTvBndrName bndr+ifaceBndrName (IfaceIdBndr bndr) = ifaceIdBndrName bndr++ifaceBndrType :: IfaceBndr -> IfaceType+ifaceBndrType (IfaceIdBndr (_, t)) = t+ifaceBndrType (IfaceTvBndr (_, t)) = t++type IfaceLamBndr = (IfaceBndr, IfaceOneShot)++data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy+ = IfaceNoOneShot -- and Note [The oneShot function] in MkId+ | IfaceOneShot+++{-+%************************************************************************+%* *+ IfaceType+%* *+%************************************************************************+-}++-------------------------------+type IfaceKind = IfaceType++-- | A kind of universal type, used for types and kinds.+--+-- Any time a 'Type' is pretty-printed, it is first converted to an 'IfaceType'+-- before being printed. See Note [Pretty printing via Iface syntax] in PprTyThing+data IfaceType+ = IfaceFreeTyVar TyVar -- See Note [Free tyvars in IfaceType]+ | IfaceTyVar IfLclName -- Type/coercion variable only, not tycon+ | IfaceLitTy IfaceTyLit+ | IfaceAppTy IfaceType IfaceAppArgs+ -- See Note [Suppressing invisible arguments] for+ -- an explanation of why the second field isn't+ -- IfaceType, analogous to AppTy.+ | IfaceFunTy AnonArgFlag IfaceType IfaceType+ | IfaceForAllTy IfaceForAllBndr IfaceType+ | IfaceTyConApp IfaceTyCon IfaceAppArgs -- Not necessarily saturated+ -- Includes newtypes, synonyms, tuples+ | IfaceCastTy IfaceType IfaceCoercion+ | IfaceCoercionTy IfaceCoercion++ | IfaceTupleTy -- Saturated tuples (unsaturated ones use IfaceTyConApp)+ TupleSort -- What sort of tuple?+ PromotionFlag -- A bit like IfaceTyCon+ IfaceAppArgs -- arity = length args+ -- For promoted data cons, the kind args are omitted++type IfacePredType = IfaceType+type IfaceContext = [IfacePredType]++data IfaceTyLit+ = IfaceNumTyLit Integer+ | IfaceStrTyLit FastString+ deriving (Eq)++type IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis+type IfaceForAllBndr = VarBndr IfaceBndr ArgFlag++-- | Make an 'IfaceForAllBndr' from an 'IfaceTvBndr'.+mkIfaceForAllTvBndr :: ArgFlag -> IfaceTvBndr -> IfaceForAllBndr+mkIfaceForAllTvBndr vis var = Bndr (IfaceTvBndr var) vis++-- | Build the 'tyConKind' from the binders and the result kind.+-- Keep in sync with 'mkTyConKind' in types/TyCon.+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 (NamedTCB vis)) k = IfaceForAllTy (Bndr tv vis) k++-- | Stores the arguments in a type application as a list.+-- See @Note [Suppressing invisible arguments]@.+data IfaceAppArgs+ = IA_Nil+ | IA_Arg IfaceType -- The type argument++ ArgFlag -- The argument's visibility. We store this here so+ -- that we can:+ --+ -- 1. Avoid pretty-printing invisible (i.e., specified+ -- or inferred) arguments when+ -- -fprint-explicit-kinds isn't enabled, or+ -- 2. When -fprint-explicit-kinds *is*, enabled, print+ -- specified arguments in @(...) and inferred+ -- arguments in @{...}.++ IfaceAppArgs -- The rest of the arguments++instance Semi.Semigroup IfaceAppArgs where+ IA_Nil <> xs = xs+ IA_Arg ty argf rest <> xs = IA_Arg ty argf (rest Semi.<> xs)++instance Monoid IfaceAppArgs where+ mempty = IA_Nil+ mappend = (Semi.<>)++-- Encodes type constructors, kind constructors,+-- coercion constructors, the lot.+-- We have to tag them in order to pretty print them+-- properly.+data IfaceTyCon = IfaceTyCon { ifaceTyConName :: IfExtName+ , ifaceTyConInfo :: IfaceTyConInfo }+ deriving (Eq)++-- | The various types of TyCons which have special, built-in syntax.+data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon++ | IfaceTupleTyCon !Arity !TupleSort+ -- ^ e.g. @(a, b, c)@ or @(#a, b, c#)@.+ -- The arity is the tuple width, not the tycon arity+ -- (which is twice the width in the case of unboxed+ -- tuples).++ | IfaceSumTyCon !Arity+ -- ^ e.g. @(a | b | c)@++ | IfaceEqualityTyCon+ -- ^ A heterogeneous equality TyCon+ -- (i.e. eqPrimTyCon, eqReprPrimTyCon, heqTyCon)+ -- that is actually being applied to two types+ -- of the same kind. This affects pretty-printing+ -- only: see Note [Equality predicates in IfaceType]+ deriving (Eq)++{- Note [Free tyvars in IfaceType]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Nowadays (since Nov 16, 2016) we pretty-print a Type by converting to+an IfaceType and pretty printing that. This eliminates a lot of+pretty-print duplication, and it matches what we do with pretty-+printing TyThings. See Note [Pretty printing via Iface syntax] in PprTyThing.++It works fine for closed types, but when printing debug traces (e.g.+when using -ddump-tc-trace) we print a lot of /open/ types. These+types are full of TcTyVars, and it's absolutely crucial to print them+in their full glory, with their unique, TcTyVarDetails etc.++So we simply embed a TyVar in IfaceType with the IfaceFreeTyVar constructor.+Note that:++* We never expect to serialise an IfaceFreeTyVar into an interface file, nor+ to deserialise one. IfaceFreeTyVar is used only in the "convert to IfaceType+ and then pretty-print" pipeline.++We do the same for covars, naturally.++Note [Equality predicates in IfaceType]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+GHC has several varieties of type equality (see Note [The equality types story]+in TysPrim for details). In an effort to avoid confusing users, we suppress+the differences during pretty printing unless certain flags are enabled.+Here is how each equality predicate* is printed in homogeneous and+heterogeneous contexts, depending on which combination of the+-fprint-explicit-kinds and -fprint-equality-relations flags is used:++--------------------------------------------------------------------------------------------+| Predicate | Neither flag | -fprint-explicit-kinds |+|-------------------------------|----------------------------|-----------------------------|+| a ~ b (homogeneous) | a ~ b | (a :: Type) ~ (b :: Type) |+| a ~~ b, homogeneously | a ~ b | (a :: Type) ~ (b :: Type) |+| a ~~ b, heterogeneously | a ~~ c | (a :: Type) ~~ (c :: k) |+| a ~# b, homogeneously | a ~ b | (a :: Type) ~ (b :: Type) |+| a ~# b, heterogeneously | a ~~ c | (a :: Type) ~~ (c :: k) |+| Coercible a b (homogeneous) | Coercible a b | Coercible @Type a b |+| a ~R# b, homogeneously | Coercible a b | Coercible @Type a b |+| a ~R# b, heterogeneously | a ~R# b | (a :: Type) ~R# (c :: k) |+|-------------------------------|----------------------------|-----------------------------|+| Predicate | -fprint-equality-relations | Both flags |+|-------------------------------|----------------------------|-----------------------------|+| a ~ b (homogeneous) | a ~ b | (a :: Type) ~ (b :: Type) |+| a ~~ b, homogeneously | a ~~ b | (a :: Type) ~~ (b :: Type) |+| a ~~ b, heterogeneously | a ~~ c | (a :: Type) ~~ (c :: k) |+| a ~# b, homogeneously | a ~# b | (a :: Type) ~# (b :: Type) |+| a ~# b, heterogeneously | a ~# c | (a :: Type) ~# (c :: k) |+| Coercible a b (homogeneous) | Coercible a b | Coercible @Type a b |+| a ~R# b, homogeneously | a ~R# b | (a :: Type) ~R# (b :: Type) |+| a ~R# b, heterogeneously | a ~R# b | (a :: Type) ~R# (c :: k) |+--------------------------------------------------------------------------------------------++(* There is no heterogeneous, representational, lifted equality counterpart+to (~~). There could be, but there seems to be no use for it.)++This table adheres to the following rules:++A. With -fprint-equality-relations, print the true equality relation.+B. Without -fprint-equality-relations:+ i. If the equality is representational and homogeneous, use Coercible.+ ii. Otherwise, if the equality is representational, use ~R#.+ iii. If the equality is nominal and homogeneous, use ~.+ iv. Otherwise, if the equality is nominal, use ~~.+C. With -fprint-explicit-kinds, print kinds on both sides of an infix operator,+ as above; or print the kind with Coercible.+D. Without -fprint-explicit-kinds, don't print kinds.++A hetero-kinded equality is used homogeneously when it is applied to two+identical kinds. Unfortunately, determining this from an IfaceType isn't+possible since we can't see through type synonyms. Consequently, we need to+record whether this particular application is homogeneous in IfaceTyConSort+for the purposes of pretty-printing.++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 :: PromotionFlag+ , ifaceTyConSort :: IfaceTyConSort }+ deriving (Eq)++data IfaceMCoercion+ = IfaceMRefl+ | IfaceMCo IfaceCoercion++data IfaceCoercion+ = IfaceReflCo IfaceType+ | IfaceGReflCo Role IfaceType (IfaceMCoercion)+ | IfaceFunCo Role IfaceCoercion IfaceCoercion+ | IfaceTyConAppCo Role IfaceTyCon [IfaceCoercion]+ | IfaceAppCo IfaceCoercion IfaceCoercion+ | IfaceForAllCo IfaceBndr IfaceCoercion IfaceCoercion+ | IfaceCoVarCo IfLclName+ | IfaceAxiomInstCo IfExtName BranchIndex [IfaceCoercion]+ | IfaceAxiomRuleCo IfLclName [IfaceCoercion]+ -- There are only a fixed number of CoAxiomRules, so it suffices+ -- to use an IfaceLclName to distinguish them.+ -- See Note [Adding built-in type families] in TcTypeNats+ | IfaceUnivCo IfaceUnivCoProv Role IfaceType IfaceType+ | IfaceSymCo IfaceCoercion+ | IfaceTransCo IfaceCoercion IfaceCoercion+ | IfaceNthCo Int IfaceCoercion+ | IfaceLRCo LeftOrRight IfaceCoercion+ | IfaceInstCo IfaceCoercion IfaceCoercion+ | IfaceKindCo IfaceCoercion+ | IfaceSubCo IfaceCoercion+ | IfaceFreeCoVar CoVar -- See Note [Free tyvars in IfaceType]+ | IfaceHoleCo CoVar -- ^ See Note [Holes in IfaceCoercion]++data IfaceUnivCoProv+ = IfaceUnsafeCoerceProv+ | IfacePhantomProv IfaceCoercion+ | IfaceProofIrrelProv IfaceCoercion+ | IfacePluginProv String++{- Note [Holes in IfaceCoercion]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When typechecking fails the typechecker will produce a HoleCo to stand+in place of the unproven assertion. While we generally don't want to+let these unproven assertions leak into interface files, we still need+to be able to pretty-print them as we use IfaceType's pretty-printer+to render Types. For this reason IfaceCoercion has a IfaceHoleCo+constructor; however, we fails when asked to serialize to a+IfaceHoleCo to ensure that they don't end up in an interface file.+++%************************************************************************+%* *+ Functions over IFaceTypes+* *+************************************************************************+-}++ifaceTyConHasKey :: IfaceTyCon -> Unique -> Bool+ifaceTyConHasKey tc key = ifaceTyConName tc `hasKey` key++isIfaceLiftedTypeKind :: IfaceKind -> Bool+isIfaceLiftedTypeKind (IfaceTyConApp tc IA_Nil)+ = isLiftedTypeKindTyConName (ifaceTyConName tc)+isIfaceLiftedTypeKind (IfaceTyConApp tc+ (IA_Arg (IfaceTyConApp ptr_rep_lifted IA_Nil)+ Required IA_Nil))+ = tc `ifaceTyConHasKey` tYPETyConKey+ && ptr_rep_lifted `ifaceTyConHasKey` liftedRepDataConKey+isIfaceLiftedTypeKind _ = False++splitIfaceSigmaTy :: IfaceType -> ([IfaceForAllBndr], [IfacePredType], IfaceType)+-- Mainly for printing purposes+--+-- Here we split nested IfaceSigmaTy properly.+--+-- @+-- forall t. T t => forall m a b. M m => (a -> m b) -> t a -> m (t b)+-- @+--+-- If you called @splitIfaceSigmaTy@ on this type:+--+-- @+-- ([t, m, a, b], [T t, M m], (a -> m b) -> t a -> m (t b))+-- @+splitIfaceSigmaTy ty+ = case (bndrs, theta) of+ ([], []) -> (bndrs, theta, tau)+ _ -> let (bndrs', theta', tau') = splitIfaceSigmaTy tau+ in (bndrs ++ bndrs', theta ++ theta', tau')+ where+ (bndrs, rho) = split_foralls ty+ (theta, tau) = split_rho rho++ split_foralls (IfaceForAllTy bndr ty)+ = case split_foralls ty of { (bndrs, rho) -> (bndr:bndrs, rho) }+ split_foralls rho = ([], rho)++ split_rho (IfaceFunTy InvisArg ty1 ty2)+ = case split_rho ty2 of { (ps, tau) -> (ty1:ps, tau) }+ split_rho tau = ([], tau)++suppressIfaceInvisibles :: DynFlags -> [IfaceTyConBinder] -> [a] -> [a]+suppressIfaceInvisibles dflags tys xs+ | gopt Opt_PrintExplicitKinds dflags = xs+ | otherwise = suppress tys xs+ where+ suppress _ [] = []+ suppress [] a = a+ suppress (k:ks) (x:xs)+ | isInvisibleTyConBinder k = suppress ks xs+ | otherwise = x : suppress ks xs++stripIfaceInvisVars :: DynFlags -> [IfaceTyConBinder] -> [IfaceTyConBinder]+stripIfaceInvisVars dflags tyvars+ | gopt Opt_PrintExplicitKinds dflags = tyvars+ | otherwise = filterOut isInvisibleTyConBinder tyvars++-- | Extract an 'IfaceBndr' from an 'IfaceForAllBndr'.+ifForAllBndrVar :: IfaceForAllBndr -> IfaceBndr+ifForAllBndrVar = binderVar++-- | Extract the variable name from an 'IfaceForAllBndr'.+ifForAllBndrName :: IfaceForAllBndr -> IfLclName+ifForAllBndrName fab = ifaceBndrName (ifForAllBndrVar fab)++-- | Extract an 'IfaceBndr' from an 'IfaceTyConBinder'.+ifTyConBinderVar :: IfaceTyConBinder -> IfaceBndr+ifTyConBinderVar = binderVar++-- | Extract the variable name from an 'IfaceTyConBinder'.+ifTyConBinderName :: IfaceTyConBinder -> IfLclName+ifTyConBinderName tcb = ifaceBndrName (ifTyConBinderVar tcb)++ifTypeIsVarFree :: IfaceType -> Bool+-- Returns True if the type definitely has no variables at all+-- Just used to control pretty printing+ifTypeIsVarFree ty = go ty+ where+ go (IfaceTyVar {}) = False+ go (IfaceFreeTyVar {}) = False+ go (IfaceAppTy fun args) = go fun && go_args args+ go (IfaceFunTy _ arg res) = go arg && go res+ go (IfaceForAllTy {}) = False+ go (IfaceTyConApp _ args) = go_args args+ go (IfaceTupleTy _ _ args) = go_args args+ go (IfaceLitTy _) = True+ go (IfaceCastTy {}) = False -- Safe+ go (IfaceCoercionTy {}) = False -- Safe++ go_args IA_Nil = True+ go_args (IA_Arg arg _ args) = go arg && go_args args++{- Note [Substitution on IfaceType]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Substitutions on IfaceType are done only during pretty-printing to+construct the result type of a GADT, and does not deal with binders+(eg IfaceForAll), so it doesn't need fancy capture stuff. -}++type IfaceTySubst = FastStringEnv IfaceType -- Note [Substitution on IfaceType]++mkIfaceTySubst :: [(IfLclName,IfaceType)] -> IfaceTySubst+-- See Note [Substitution on IfaceType]+mkIfaceTySubst eq_spec = mkFsEnv eq_spec++inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool+-- See Note [Substitution on IfaceType]+inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst fs)++substIfaceType :: IfaceTySubst -> IfaceType -> IfaceType+-- See Note [Substitution on IfaceType]+substIfaceType env ty+ = go ty+ where+ 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 ty@(IfaceLitTy {}) = ty+ go (IfaceTyConApp tc tys) = IfaceTyConApp tc (substIfaceAppArgs env tys)+ go (IfaceTupleTy s i tys) = IfaceTupleTy s i (substIfaceAppArgs env tys)+ go (IfaceForAllTy {}) = pprPanic "substIfaceType" (ppr ty)+ go (IfaceCastTy ty co) = IfaceCastTy (go ty) (go_co co)+ go (IfaceCoercionTy co) = IfaceCoercionTy (go_co co)++ go_mco IfaceMRefl = IfaceMRefl+ go_mco (IfaceMCo co) = IfaceMCo $ go_co co++ 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 (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)+ go_co (IfaceFreeCoVar cv) = IfaceFreeCoVar cv+ go_co (IfaceCoVarCo cv) = IfaceCoVarCo cv+ go_co (IfaceHoleCo cv) = IfaceHoleCo cv+ go_co (IfaceAxiomInstCo a i cos) = IfaceAxiomInstCo a i (go_cos cos)+ go_co (IfaceUnivCo prov r t1 t2) = IfaceUnivCo (go_prov prov) r (go t1) (go t2)+ go_co (IfaceSymCo co) = IfaceSymCo (go_co co)+ go_co (IfaceTransCo co1 co2) = IfaceTransCo (go_co co1) (go_co co2)+ go_co (IfaceNthCo n co) = IfaceNthCo n (go_co co)+ go_co (IfaceLRCo lr co) = IfaceLRCo lr (go_co co)+ go_co (IfaceInstCo c1 c2) = IfaceInstCo (go_co c1) (go_co c2)+ go_co (IfaceKindCo co) = IfaceKindCo (go_co co)+ go_co (IfaceSubCo co) = IfaceSubCo (go_co co)+ go_co (IfaceAxiomRuleCo n cos) = IfaceAxiomRuleCo n (go_cos cos)++ go_cos = map go_co++ go_prov IfaceUnsafeCoerceProv = IfaceUnsafeCoerceProv+ go_prov (IfacePhantomProv co) = IfacePhantomProv (go_co co)+ go_prov (IfaceProofIrrelProv co) = IfaceProofIrrelProv (go_co co)+ go_prov (IfacePluginProv str) = IfacePluginProv str++substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs+substIfaceAppArgs env args+ = go args+ where+ go IA_Nil = IA_Nil+ go (IA_Arg ty arg tys) = IA_Arg (substIfaceType env ty) arg (go tys)++substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType+substIfaceTyVar env tv+ | Just ty <- lookupFsEnv env tv = ty+ | otherwise = IfaceTyVar tv+++{-+************************************************************************+* *+ Functions over IfaceAppArgs+* *+************************************************************************+-}++stripInvisArgs :: DynFlags -> IfaceAppArgs -> IfaceAppArgs+stripInvisArgs dflags tys+ | gopt Opt_PrintExplicitKinds dflags = tys+ | otherwise = suppress_invis tys+ where+ suppress_invis c+ = case c of+ IA_Nil -> IA_Nil+ IA_Arg t argf ts+ | isVisibleArgFlag argf+ -> IA_Arg t argf $ suppress_invis ts+ -- Keep recursing through the remainder of the arguments, as it's+ -- possible that there are remaining invisible ones.+ -- See the "In type declarations" section of Note [VarBndrs,+ -- TyCoVarBinders, TyConBinders, and visibility] in TyCoRep.+ | otherwise+ -> suppress_invis ts++appArgsIfaceTypes :: IfaceAppArgs -> [IfaceType]+appArgsIfaceTypes IA_Nil = []+appArgsIfaceTypes (IA_Arg t _ ts) = t : appArgsIfaceTypes ts++appArgsIfaceTypesArgFlags :: IfaceAppArgs -> [(IfaceType, ArgFlag)]+appArgsIfaceTypesArgFlags IA_Nil = []+appArgsIfaceTypesArgFlags (IA_Arg t a ts)+ = (t, a) : appArgsIfaceTypesArgFlags ts++ifaceVisAppArgsLength :: IfaceAppArgs -> Int+ifaceVisAppArgsLength = go 0+ where+ go !n IA_Nil = n+ go n (IA_Arg _ argf rest)+ | isVisibleArgFlag argf = go (n+1) rest+ | otherwise = go n rest++{-+Note [Suppressing invisible arguments]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We use the IfaceAppArgs data type to specify which of the arguments to a type+should be displayed when pretty-printing, under the control of+-fprint-explicit-kinds.+See also Type.filterOutInvisibleTypes.+For example, given++ T :: forall k. (k->*) -> k -> * -- Ordinary kind polymorphism+ 'Just :: forall k. k -> 'Maybe k -- Promoted++we want++ T * Tree Int prints as T Tree Int+ 'Just * prints as Just *++For type constructors (IfaceTyConApp), IfaceAppArgs is a quite natural fit,+since the corresponding Core constructor:++ data Type+ = ...+ | TyConApp TyCon [Type]++Already puts all of its arguments into a list. So when converting a Type to an+IfaceType (see toIfaceAppArgsX in GHC.Core.ToIface), we simply use the kind of+the TyCon (which is cached) to guide the process of converting the argument+Types into an IfaceAppArgs list.++We also want this behavior for IfaceAppTy, since given:++ data Proxy (a :: k)+ f :: forall (t :: forall a. a -> Type). Proxy Type (t Bool True)++We want to print the return type as `Proxy (t True)` without the use of+-fprint-explicit-kinds (#15330). Accomplishing this is trickier than in the+tycon case, because the corresponding Core constructor for IfaceAppTy:++ data Type+ = ...+ | AppTy Type Type++Only stores one argument at a time. Therefore, when converting an AppTy to an+IfaceAppTy (in toIfaceTypeX in GHC.CoreToIface), we:++1. Flatten the chain of AppTys down as much as possible+2. Use typeKind to determine the function Type's kind+3. Use this kind to guide the process of converting the argument Types into an+ IfaceAppArgs list.++By flattening the arguments like this, we obtain two benefits:++(a) We can reuse the same machinery to pretty-print IfaceTyConApp arguments as+ we do IfaceTyApp arguments, which means that we only need to implement the+ logic to filter out invisible arguments once.+(b) Unlike for tycons, finding the kind of a type in general (through typeKind)+ is not a constant-time operation, so by flattening the arguments first, we+ decrease the number of times we have to call typeKind.++Note [Pretty-printing invisible arguments]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Note [Suppressing invisible arguments] is all about how to avoid printing+invisible arguments when the -fprint-explicit-kinds flag is disables. Well,+what about when it's enabled? Then we can and should print invisible kind+arguments, and this Note explains how we do it.++As two running examples, consider the following code:++ {-# LANGUAGE PolyKinds #-}+ data T1 a+ data T2 (a :: k)++When displaying these types (with -fprint-explicit-kinds on), we could just+do the following:++ T1 k a+ T2 k a++That certainly gets the job done. But it lacks a crucial piece of information:+is the `k` argument inferred or specified? To communicate this, we use visible+kind application syntax to distinguish the two cases:++ T1 @{k} a+ T2 @k a++Here, @{k} indicates that `k` is an inferred argument, and @k indicates that+`k` is a specified argument. (See+Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in TyCoRep for+a lengthier explanation on what "inferred" and "specified" mean.)++************************************************************************+* *+ Pretty-printing+* *+************************************************************************+-}++if_print_coercions :: SDoc -- ^ if printing coercions+ -> SDoc -- ^ otherwise+ -> SDoc+if_print_coercions yes no+ = sdocWithDynFlags $ \dflags ->+ getPprStyle $ \style ->+ if gopt Opt_PrintExplicitCoercions dflags+ || dumpStyle style || debugStyle style+ then yes+ else no++pprIfaceInfixApp :: PprPrec -> SDoc -> SDoc -> SDoc -> SDoc+pprIfaceInfixApp ctxt_prec pp_tc pp_ty1 pp_ty2+ = maybeParen ctxt_prec opPrec $+ sep [pp_ty1, pp_tc <+> pp_ty2]++pprIfacePrefixApp :: PprPrec -> SDoc -> [SDoc] -> SDoc+pprIfacePrefixApp ctxt_prec pp_fun pp_tys+ | null pp_tys = pp_fun+ | otherwise = maybeParen ctxt_prec appPrec $+ hang pp_fun 2 (sep pp_tys)++isIfaceTauType :: IfaceType -> Bool+isIfaceTauType (IfaceForAllTy _ _) = False+isIfaceTauType (IfaceFunTy InvisArg _ _) = False+isIfaceTauType _ = True++-- ----------------------------- Printing binders ------------------------------------++instance Outputable IfaceBndr where+ ppr (IfaceIdBndr bndr) = pprIfaceIdBndr bndr+ ppr (IfaceTvBndr bndr) = char '@' <> pprIfaceTvBndr bndr (SuppressBndrSig False)+ (UseBndrParens False)++pprIfaceBndrs :: [IfaceBndr] -> SDoc+pprIfaceBndrs bs = sep (map ppr bs)++pprIfaceLamBndr :: IfaceLamBndr -> SDoc+pprIfaceLamBndr (b, IfaceNoOneShot) = ppr b+pprIfaceLamBndr (b, IfaceOneShot) = ppr b <> text "[OneShot]"++pprIfaceIdBndr :: IfaceIdBndr -> SDoc+pprIfaceIdBndr (name, ty) = parens (ppr name <+> dcolon <+> ppr ty)++{- Note [Suppressing binder signatures]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When printing the binders in a 'forall', we want to keep the kind annotations:++ forall (a :: k). blah+ ^^^^+ good++On the other hand, when we print the binders of a data declaration in :info,+the kind information would be redundant due to the standalone kind signature:++ type F :: Symbol -> Type+ type F (s :: Symbol) = blah+ ^^^^^^^^^+ redundant++Here we'd like to omit the kind annotation:++ type F :: Symbol -> Type+ type F s = blah+-}++-- | Do we want to suppress kind annotations on binders?+-- See Note [Suppressing binder signatures]+newtype SuppressBndrSig = SuppressBndrSig Bool++newtype UseBndrParens = UseBndrParens Bool++pprIfaceTvBndr :: IfaceTvBndr -> SuppressBndrSig -> UseBndrParens -> SDoc+pprIfaceTvBndr (tv, ki) (SuppressBndrSig suppress_sig) (UseBndrParens use_parens)+ | suppress_sig = ppr tv+ | isIfaceLiftedTypeKind ki = ppr tv+ | otherwise = maybe_parens (ppr tv <+> dcolon <+> ppr ki)+ where+ maybe_parens | use_parens = parens+ | otherwise = id++pprIfaceTyConBinders :: SuppressBndrSig -> [IfaceTyConBinder] -> SDoc+pprIfaceTyConBinders suppress_sig = sep . map go+ where+ go :: IfaceTyConBinder -> SDoc+ go (Bndr (IfaceIdBndr bndr) _) = pprIfaceIdBndr bndr+ go (Bndr (IfaceTvBndr bndr) vis) =+ -- See Note [Pretty-printing invisible arguments]+ case vis of+ AnonTCB VisArg -> ppr_bndr (UseBndrParens True)+ AnonTCB InvisArg -> char '@' <> braces (ppr_bndr (UseBndrParens False))+ -- The above case is rare. (See Note [AnonTCB InvisArg] in TyCon.)+ -- Should we print these differently?+ NamedTCB Required -> ppr_bndr (UseBndrParens True)+ NamedTCB Specified -> char '@' <> ppr_bndr (UseBndrParens True)+ NamedTCB Inferred -> char '@' <> braces (ppr_bndr (UseBndrParens False))+ where+ ppr_bndr = pprIfaceTvBndr bndr suppress_sig++instance Binary IfaceBndr where+ put_ bh (IfaceIdBndr aa) = do+ putByte bh 0+ put_ bh aa+ put_ bh (IfaceTvBndr ab) = do+ putByte bh 1+ put_ bh ab+ get bh = do+ h <- getByte bh+ case h of+ 0 -> do aa <- get bh+ return (IfaceIdBndr aa)+ _ -> do ab <- get bh+ return (IfaceTvBndr ab)++instance Binary IfaceOneShot where+ put_ bh IfaceNoOneShot = do+ putByte bh 0+ put_ bh IfaceOneShot = do+ putByte bh 1+ get bh = do+ h <- getByte bh+ case h of+ 0 -> do return IfaceNoOneShot+ _ -> do return IfaceOneShot++-- ----------------------------- Printing IfaceType ------------------------------------++---------------------------------+instance Outputable IfaceType where+ ppr ty = pprIfaceType ty++pprIfaceType, pprParendIfaceType :: IfaceType -> SDoc+pprIfaceType = pprPrecIfaceType topPrec+pprParendIfaceType = pprPrecIfaceType appPrec++pprPrecIfaceType :: PprPrec -> IfaceType -> SDoc+-- We still need `eliminateRuntimeRep`, since the `pprPrecIfaceType` maybe+-- called from other places, besides `:type` and `:info`.+pprPrecIfaceType prec ty = eliminateRuntimeRep (ppr_ty prec) ty++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 _ (IfaceFreeTyVar tyvar) = ppr tyvar -- This is the main reason for IfaceFreeTyVar!+ppr_ty _ (IfaceTyVar tyvar) = ppr tyvar -- See Note [TcTyVars in IfaceType]+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+ = -- 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)]+ 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_ty ctxt_prec (IfaceAppTy t ts)+ = if_print_coercions+ ppr_app_ty+ ppr_app_ty_no_casts+ where+ ppr_app_ty =+ sdocWithDynFlags $ \dflags ->+ pprIfacePrefixApp ctxt_prec+ (ppr_ty funPrec t)+ (map (ppr_app_arg appPrec) (tys_wo_kinds dflags))++ tys_wo_kinds dflags = appArgsIfaceTypesArgFlags $ stripInvisArgs dflags ts++ -- Strip any casts from the head of the application+ ppr_app_ty_no_casts =+ case t of+ IfaceCastTy head _ -> ppr_ty ctxt_prec (mk_app_tys head ts)+ _ -> ppr_app_ty++ mk_app_tys :: IfaceType -> IfaceAppArgs -> IfaceType+ mk_app_tys (IfaceTyConApp tc tys1) tys2 =+ IfaceTyConApp tc (tys1 `mappend` tys2)+ mk_app_tys t1 tys2 = IfaceAppTy t1 tys2++ppr_ty ctxt_prec (IfaceCastTy ty co)+ = if_print_coercions+ (parens (ppr_ty topPrec ty <+> text "|>" <+> ppr co))+ (ppr_ty ctxt_prec ty)++ppr_ty ctxt_prec (IfaceCoercionTy co)+ = if_print_coercions+ (ppr_co ctxt_prec co)+ (text "<>")++{- Note [Defaulting RuntimeRep variables]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+RuntimeRep variables are considered by many (most?) users to be little+more than syntactic noise. When the notion was introduced there was a+significant and understandable push-back from those with pedagogy in+mind, which argued that RuntimeRep variables would throw a wrench into+nearly any teach approach since they appear in even the lowly ($)+function's type,++ ($) :: forall (w :: RuntimeRep) a (b :: TYPE w). (a -> b) -> a -> b++which is significantly less readable than its non RuntimeRep-polymorphic type of++ ($) :: (a -> b) -> a -> b++Moreover, unboxed types don't appear all that often in run-of-the-mill+Haskell programs, so it makes little sense to make all users pay this+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)++This applies to /quantified/ variables like 'w' above. What about+variables that are /free/ in the type being printed, which certainly+happens in error messages. Suppose (#16074) we are reporting a+mismatch between two skolems+ (a :: RuntimeRep) ~ (b :: RuntimeRep)+We certainly don't want to say "Can't match LiftedRep ~ LiftedRep"!++But if we are printing the type+ (forall (a :: Type r). blah+we do want to turn that (free) r into LiftedRep, so it prints as+ (forall a. blah)++Conclusion: keep track of whether we we are in the kind of a+binder; ohly if so, convert free RuntimeRep variables to LiftedRep.+-}++-- | Default 'RuntimeRep' variables to 'LiftedPtr'. e.g.+--+-- @+-- ($) :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r).+-- (a -> b) -> a -> b+-- @+--+-- turns in to,+--+-- @ ($) :: forall a (b :: *). (a -> b) -> a -> b @+--+-- 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+ where+ go :: Bool -- True <=> Inside the kind of a binder+ -> FastStringEnv () -- Set of enclosing forall-ed RuntimeRep variables+ -> IfaceType -- (replace them with LiftedRep)+ -> IfaceType+ go ink subs (IfaceForAllTy (Bndr (IfaceTvBndr (var, var_kind)) argf) ty)+ | isRuntimeRep var_kind+ , isInvisibleArgFlag argf -- Don't default *visible* quantification+ -- or we get the mess in #13963+ = let subs' = extendFsEnv subs var ()+ -- Record that we should replace it with LiftedRep,+ -- and recurse, discarding the forall+ in go ink subs' 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 in_kind _ ty@(IfaceFreeTyVar tv)+ -- See Note [Defaulting RuntimeRep variables], about free vars+ | in_kind && Type.isRuntimeRepTy (tyVarKind tv)+ = IfaceTyConApp liftedRep IA_Nil+ | otherwise+ = ty++ go ink subs (IfaceTyConApp tc tc_args)+ = IfaceTyConApp tc (go_args ink subs tc_args)++ 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 (IfaceAppTy t ts)+ = IfaceAppTy (go ink subs t) (go_args ink subs ts)++ go ink subs (IfaceCastTy x co)+ = IfaceCastTy (go ink subs x) co++ 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 subs (Bndr (IfaceTvBndr (n, t)) argf)+ = Bndr (IfaceTvBndr (n, go True subs t)) argf++ go_args :: Bool -> FastStringEnv () -> 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+ = sdocWithDynFlags $ \dflags ->+ getPprStyle $ \sty ->+ if userStyle sty && not (gopt Opt_PrintExplicitRuntimeReps dflags)+ then f (defaultRuntimeRepVars ty)+ else f ty++instance Outputable IfaceAppArgs where+ ppr tca = pprIfaceAppArgs tca++pprIfaceAppArgs, pprParendIfaceAppArgs :: IfaceAppArgs -> SDoc+pprIfaceAppArgs = ppr_app_args topPrec+pprParendIfaceAppArgs = ppr_app_args appPrec++ppr_app_args :: PprPrec -> IfaceAppArgs -> SDoc+ppr_app_args ctx_prec = go+ where+ go :: IfaceAppArgs -> SDoc+ go IA_Nil = empty+ go (IA_Arg t argf ts) = ppr_app_arg ctx_prec (t, argf) <+> go ts++-- See Note [Pretty-printing invisible arguments]+ppr_app_arg :: PprPrec -> (IfaceType, ArgFlag) -> SDoc+ppr_app_arg ctx_prec (t, argf) =+ sdocWithDynFlags $ \dflags ->+ let print_kinds = gopt Opt_PrintExplicitKinds dflags+ in case argf of+ Required -> ppr_ty ctx_prec t+ Specified | print_kinds+ -> char '@' <> ppr_ty appPrec t+ Inferred | print_kinds+ -> char '@' <> braces (ppr_ty topPrec t)+ _ -> empty++-------------------+pprIfaceForAllPart :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc+pprIfaceForAllPart tvs ctxt sdoc+ = ppr_iface_forall_part ShowForAllWhen tvs ctxt sdoc++-- | Like 'pprIfaceForAllPart', but always uses an explicit @forall@.+pprIfaceForAllPartMust :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc+pprIfaceForAllPartMust tvs ctxt sdoc+ = ppr_iface_forall_part ShowForAllMust tvs ctxt sdoc++pprIfaceForAllCoPart :: [(IfLclName, IfaceCoercion)] -> SDoc -> SDoc+pprIfaceForAllCoPart tvs sdoc+ = sep [ pprIfaceForAllCo tvs, sdoc ]++ppr_iface_forall_part :: ShowForAllFlag+ -> [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc+ppr_iface_forall_part show_forall tvs ctxt sdoc+ = sep [ case show_forall of+ ShowForAllMust -> pprIfaceForAll tvs+ ShowForAllWhen -> pprUserIfaceForAll tvs+ , pprIfaceContextArr ctxt+ , sdoc]++-- | Render the "forall ... ." or "forall ... ->" bit of a type.+pprIfaceForAll :: [IfaceForAllBndr] -> SDoc+pprIfaceForAll [] = empty+pprIfaceForAll bndrs@(Bndr _ vis : _)+ = sep [ add_separator (forAllLit <+> fsep docs)+ , pprIfaceForAll bndrs' ]+ where+ (bndrs', docs) = ppr_itv_bndrs bndrs vis++ add_separator stuff = case vis of+ Required -> stuff <+> arrow+ _inv -> stuff <> dot+++-- | Render the ... in @(forall ... .)@ or @(forall ... ->)@.+-- Returns both the list of not-yet-rendered binders and the doc.+-- No anonymous binders here!+ppr_itv_bndrs :: [IfaceForAllBndr]+ -> ArgFlag -- ^ visibility of the first binder in the list+ -> ([IfaceForAllBndr], [SDoc])+ppr_itv_bndrs all_bndrs@(bndr@(Bndr _ vis) : bndrs) vis1+ | vis `sameVis` vis1 = let (bndrs', doc) = ppr_itv_bndrs bndrs vis1 in+ (bndrs', pprIfaceForAllBndr bndr : doc)+ | otherwise = (all_bndrs, [])+ppr_itv_bndrs [] _ = ([], [])++pprIfaceForAllCo :: [(IfLclName, IfaceCoercion)] -> SDoc+pprIfaceForAllCo [] = empty+pprIfaceForAllCo tvs = text "forall" <+> pprIfaceForAllCoBndrs tvs <> dot++pprIfaceForAllCoBndrs :: [(IfLclName, IfaceCoercion)] -> SDoc+pprIfaceForAllCoBndrs bndrs = hsep $ map pprIfaceForAllCoBndr bndrs++pprIfaceForAllBndr :: IfaceForAllBndr -> SDoc+pprIfaceForAllBndr bndr =+ case bndr of+ Bndr (IfaceTvBndr tv) Inferred ->+ sdocWithDynFlags $ \dflags ->+ if gopt Opt_PrintExplicitForalls dflags+ then braces $ pprIfaceTvBndr tv suppress_sig (UseBndrParens False)+ else pprIfaceTvBndr tv suppress_sig (UseBndrParens True)+ Bndr (IfaceTvBndr tv) _ ->+ pprIfaceTvBndr tv suppress_sig (UseBndrParens True)+ Bndr (IfaceIdBndr idv) _ -> pprIfaceIdBndr idv+ where+ -- See Note [Suppressing binder signatures]+ suppress_sig = SuppressBndrSig False++pprIfaceForAllCoBndr :: (IfLclName, IfaceCoercion) -> SDoc+pprIfaceForAllCoBndr (tv, kind_co)+ = parens (ppr tv <+> dcolon <+> pprIfaceCoercion kind_co)++-- | Show forall flag+--+-- Unconditionally show the forall quantifier with ('ShowForAllMust')+-- or when ('ShowForAllWhen') the names used are free in the binder+-- or when compiling with -fprint-explicit-foralls.+data ShowForAllFlag = ShowForAllMust | ShowForAllWhen++pprIfaceSigmaType :: ShowForAllFlag -> IfaceType -> SDoc+pprIfaceSigmaType show_forall ty+ = eliminateRuntimeRep ppr_fn ty+ where+ ppr_fn iface_ty =+ let (tvs, theta, tau) = splitIfaceSigmaTy iface_ty+ in ppr_iface_forall_part show_forall tvs theta (ppr tau)++pprUserIfaceForAll :: [IfaceForAllBndr] -> SDoc+pprUserIfaceForAll tvs+ = sdocWithDynFlags $ \dflags ->+ -- See Note [When to print foralls] in this module.+ ppWhen (any tv_has_kind_var tvs+ || any tv_is_required tvs+ || gopt Opt_PrintExplicitForalls dflags) $+ pprIfaceForAll tvs+ where+ tv_has_kind_var (Bndr (IfaceTvBndr (_,kind)) _)+ = not (ifTypeIsVarFree kind)+ tv_has_kind_var _ = False++ tv_is_required = isVisibleArgFlag . binderArgFlag++{-+Note [When to print foralls]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We opt to explicitly pretty-print `forall`s if any of the following+criteria are met:++1. -fprint-explicit-foralls is on.++2. A bound type variable has a polymorphic kind. E.g.,++ forall k (a::k). Proxy a -> Proxy a++ Since a's kind mentions a variable k, we print the foralls.++3. A bound type variable is a visible argument (#14238).+ Suppose we are printing the kind of:++ T :: forall k -> k -> Type++ The "forall k ->" notation means that this kind argument is required.+ That is, it must be supplied at uses of T. E.g.,++ f :: T (Type->Type) Monad -> Int++ So we print an explicit "T :: forall k -> k -> Type",+ because omitting it and printing "T :: k -> Type" would be+ utterly misleading.++ See Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility]+ in TyCoRep.++N.B. Until now (Aug 2018) we didn't check anything for coercion variables.++Note [Printing foralls in type family instances]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We use the same criteria as in Note [When to print foralls] to determine+whether a type family instance should be pretty-printed with an explicit+`forall`. Example:++ type family Foo (a :: k) :: k where+ Foo Maybe = []+ Foo (a :: Type) = Int+ Foo a = a++Without -fprint-explicit-foralls enabled, this will be pretty-printed as:++type family Foo (a :: k) :: k where+ Foo Maybe = []+ Foo a = Int+ forall k (a :: k). Foo a = a++Note that only the third equation has an explicit forall, since it has a type+variable with a non-Type kind. (If -fprint-explicit-foralls were enabled, then+the second equation would be preceded with `forall a.`.)++There is one tricky point in the implementation: what visibility+do we give the type variables in a type family instance? Type family instances+only store type *variables*, not type variable *binders*, and only the latter+has visibility information. We opt to default the visibility of each of these+type variables to Specified because users can't ever instantiate these+variables manually, so the choice of visibility is only relevant to+pretty-printing. (This is why the `k` in `forall k (a :: k). ...` above is+printed the way it is, even though it wasn't written explicitly in the+original source code.)++We adopt the same strategy for data family instances. Example:++ data family DF (a :: k)+ data instance DF '[a, b] = DFList++That data family instance is pretty-printed as:++ data instance forall j (a :: j) (b :: j). DF '[a, b] = DFList++This is despite that the representation tycon for this data instance (call it+$DF:List) actually has different visibilities for its binders.+However, the visibilities of these binders are utterly irrelevant to the+programmer, who cares only about the specificity of variables in `DF`'s type,+not $DF:List's type. Therefore, we opt to pretty-print all variables in data+family instances as Specified.++Note [Printing promoted type constructors]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider this GHCi session (#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+ IsPromoted -> (space <>)+ _ -> id+pprSpaceIfPromotedTyCon _+ = id++-- See equivalent function in TyCoRep.hs+pprIfaceTyList :: PprPrec -> IfaceType -> IfaceType -> SDoc+-- Given a type-level list (t1 ': t2), see if we can print+-- it in list notation [t1, ...].+-- Precondition: Opt_PrintExplicitKinds is off+pprIfaceTyList ctxt_prec ty1 ty2+ = case gather ty2 of+ (arg_tys, Nothing)+ -> char '\'' <> brackets (pprSpaceIfPromotedTyCon ty1 (fsep+ (punctuate comma (map (ppr_ty topPrec) (ty1:arg_tys)))))+ (arg_tys, Just tl)+ -> maybeParen ctxt_prec funPrec $ hang (ppr_ty funPrec ty1)+ 2 (fsep [ colon <+> ppr_ty funPrec ty | ty <- arg_tys ++ [tl]])+ where+ gather :: IfaceType -> ([IfaceType], Maybe IfaceType)+ -- (gather ty) = (tys, Nothing) means ty is a list [t1, .., tn]+ -- = (tys, Just tl) means ty is of form t1:t2:...tn:tl+ gather (IfaceTyConApp tc tys)+ | tc `ifaceTyConHasKey` consDataConKey+ , IA_Arg _ argf (IA_Arg ty1 Required (IA_Arg ty2 Required IA_Nil)) <- tys+ , isInvisibleArgFlag argf+ , (args, tl) <- gather ty2+ = (ty1:args, tl)+ | tc `ifaceTyConHasKey` nilDataConKey+ = ([], Nothing)+ gather ty = ([], Just ty)++pprIfaceTypeApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc+pprIfaceTypeApp prec tc args = pprTyTcApp prec tc args++pprTyTcApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc+pprTyTcApp ctxt_prec tc tys =+ sdocWithDynFlags $ \dflags ->+ getPprStyle $ \style ->+ pprTyTcApp' ctxt_prec tc tys dflags style++pprTyTcApp' :: PprPrec -> IfaceTyCon -> IfaceAppArgs+ -> DynFlags -> PprStyle -> SDoc+pprTyTcApp' ctxt_prec tc tys dflags style+ | ifaceTyConName tc `hasKey` ipClassKey+ , IA_Arg (IfaceLitTy (IfaceStrTyLit n))+ Required (IA_Arg ty Required IA_Nil) <- tys+ = maybeParen ctxt_prec funPrec+ $ char '?' <> ftext n <> text "::" <> ppr_ty topPrec ty++ | IfaceTupleTyCon arity sort <- ifaceTyConSort info+ , not (debugStyle style)+ , arity == ifaceVisAppArgsLength tys+ = pprTuple ctxt_prec sort (ifaceTyConIsPromoted info) tys++ | IfaceSumTyCon arity <- ifaceTyConSort info+ = pprSum arity (ifaceTyConIsPromoted info) tys++ | tc `ifaceTyConHasKey` consDataConKey+ , not (gopt Opt_PrintExplicitKinds dflags)+ , IA_Arg _ argf (IA_Arg ty1 Required (IA_Arg ty2 Required IA_Nil)) <- tys+ , isInvisibleArgFlag argf+ = pprIfaceTyList ctxt_prec ty1 ty2++ | tc `ifaceTyConHasKey` tYPETyConKey+ , IA_Arg (IfaceTyConApp rep IA_Nil) Required IA_Nil <- tys+ , rep `ifaceTyConHasKey` liftedRepDataConKey+ = ppr_kind_type ctxt_prec++ | otherwise+ = getPprDebug $ \dbg ->+ if | not dbg && tc `ifaceTyConHasKey` errorMessageTypeErrorFamKey+ -- Suppress detail unless you _really_ want to see+ -> text "(TypeError ...)"++ | Just doc <- ppr_equality ctxt_prec tc (appArgsIfaceTypes tys)+ -> doc++ | otherwise+ -> ppr_iface_tc_app ppr_app_arg ctxt_prec tc tys_wo_kinds+ where+ info = ifaceTyConInfo tc+ tys_wo_kinds = appArgsIfaceTypesArgFlags $ stripInvisArgs dflags tys++ppr_kind_type :: PprPrec -> SDoc+ppr_kind_type ctxt_prec =+ sdocWithDynFlags $ \dflags ->+ if useStarIsType dflags+ then maybeParen ctxt_prec starPrec $+ unicodeSyntax (char '★') (char '*')+ else text "Type"++-- | Pretty-print a type-level equality.+-- Returns (Just doc) if the argument is a /saturated/ application+-- of eqTyCon (~)+-- eqPrimTyCon (~#)+-- eqReprPrimTyCon (~R#)+-- heqTyCon (~~)+--+-- See Note [Equality predicates in IfaceType]+-- and Note [The equality types story] in TysPrim+ppr_equality :: PprPrec -> IfaceTyCon -> [IfaceType] -> Maybe SDoc+ppr_equality ctxt_prec tc args+ | hetero_eq_tc+ , [k1, k2, t1, t2] <- args+ = Just $ print_equality (k1, k2, t1, t2)++ | hom_eq_tc+ , [k, t1, t2] <- args+ = Just $ print_equality (k, k, t1, t2)++ | otherwise+ = Nothing+ where+ homogeneous = tc_name `hasKey` eqTyConKey -- (~)+ || hetero_tc_used_homogeneously+ where+ hetero_tc_used_homogeneously+ = case ifaceTyConSort $ ifaceTyConInfo tc of+ IfaceEqualityTyCon -> True+ _other -> False+ -- True <=> a heterogeneous equality whose arguments+ -- are (in this case) of the same kind++ tc_name = ifaceTyConName tc+ pp = ppr_ty+ hom_eq_tc = tc_name `hasKey` eqTyConKey -- (~)+ hetero_eq_tc = tc_name `hasKey` eqPrimTyConKey -- (~#)+ || tc_name `hasKey` eqReprPrimTyConKey -- (~R#)+ || tc_name `hasKey` heqTyConKey -- (~~)+ nominal_eq_tc = tc_name `hasKey` heqTyConKey -- (~~)+ || tc_name `hasKey` eqPrimTyConKey -- (~#)+ print_equality args =+ sdocWithDynFlags $ \dflags ->+ getPprStyle $ \style ->+ print_equality' args style dflags++ print_equality' (ki1, ki2, ty1, ty2) style dflags+ | -- If -fprint-equality-relations is on, just print the original TyCon+ print_eqs+ = ppr_infix_eq (ppr tc)++ | -- Homogeneous use of heterogeneous equality (ty1 ~~ ty2)+ -- or unlifted equality (ty1 ~# ty2)+ nominal_eq_tc, homogeneous+ = ppr_infix_eq (text "~")++ | -- Heterogeneous use of unlifted equality (ty1 ~# ty2)+ not homogeneous+ = ppr_infix_eq (ppr heqTyCon)++ | -- Homogeneous use of representational unlifted equality (ty1 ~R# ty2)+ tc_name `hasKey` eqReprPrimTyConKey, homogeneous+ = let ki | print_kinds = [pp appPrec ki1]+ | otherwise = []+ in pprIfacePrefixApp ctxt_prec (ppr coercibleTyCon)+ (ki ++ [pp appPrec ty1, pp appPrec ty2])++ -- The other cases work as you'd expect+ | otherwise+ = ppr_infix_eq (ppr tc)+ where+ ppr_infix_eq :: SDoc -> SDoc+ ppr_infix_eq eq_op = pprIfaceInfixApp ctxt_prec eq_op+ (pp_ty_ki ty1 ki1) (pp_ty_ki ty2 ki2)+ where+ pp_ty_ki ty ki+ | print_kinds+ = parens (pp topPrec ty <+> dcolon <+> pp opPrec ki)+ | otherwise+ = pp opPrec ty++ print_kinds = gopt Opt_PrintExplicitKinds dflags+ print_eqs = gopt Opt_PrintEqualityRelations dflags ||+ dumpStyle style || debugStyle style+++pprIfaceCoTcApp :: PprPrec -> IfaceTyCon -> [IfaceCoercion] -> SDoc+pprIfaceCoTcApp ctxt_prec tc tys =+ ppr_iface_tc_app (\prec (co, _) -> ppr_co prec co) ctxt_prec tc+ (map (, Required) tys)+ -- We are trying to re-use ppr_iface_tc_app here, which requires its+ -- arguments to be accompanied by visibilities. But visibility is+ -- irrelevant when printing coercions, so just default everything to+ -- Required.++-- | Pretty-prints an application of a type constructor to some arguments+-- (whose visibilities are known). This is polymorphic (over @a@) since we use+-- this function to pretty-print two different things:+--+-- 1. Types (from `pprTyTcApp'`)+--+-- 2. Coercions (from 'pprIfaceCoTcApp')+ppr_iface_tc_app :: (PprPrec -> (a, ArgFlag) -> SDoc)+ -> PprPrec -> IfaceTyCon -> [(a, ArgFlag)] -> SDoc+ppr_iface_tc_app pp _ tc [ty]+ | tc `ifaceTyConHasKey` listTyConKey = pprPromotionQuote tc <> brackets (pp topPrec ty)++ppr_iface_tc_app pp ctxt_prec tc tys+ | tc `ifaceTyConHasKey` liftedTypeKindTyConKey+ = ppr_kind_type ctxt_prec++ | not (isSymOcc (nameOccName (ifaceTyConName tc)))+ = pprIfacePrefixApp ctxt_prec (ppr tc) (map (pp appPrec) tys)++ | [ ty1@(_, Required)+ , ty2@(_, Required) ] <- tys+ -- Infix, two visible arguments (we know nothing of precedence though).+ -- Don't apply this special case if one of the arguments is invisible,+ -- lest we print something like (@LiftedRep -> @LiftedRep) (#15941).+ = pprIfaceInfixApp ctxt_prec (ppr tc)+ (pp opPrec ty1) (pp opPrec ty2)++ | otherwise+ = pprIfacePrefixApp ctxt_prec (parens (ppr tc)) (map (pp appPrec) tys)++pprSum :: Arity -> PromotionFlag -> IfaceAppArgs -> SDoc+pprSum _arity is_promoted args+ = -- drop the RuntimeRep vars.+ -- See Note [Unboxed tuple RuntimeRep vars] in TyCon+ let tys = appArgsIfaceTypes args+ args' = drop (length tys `div` 2) tys+ in pprPromotionQuoteI is_promoted+ <> sumParens (pprWithBars (ppr_ty topPrec) args')++pprTuple :: PprPrec -> TupleSort -> PromotionFlag -> IfaceAppArgs -> SDoc+pprTuple ctxt_prec sort promoted args =+ case promoted of+ IsPromoted+ -> let tys = appArgsIfaceTypes args+ args' = drop (length tys `div` 2) tys+ spaceIfPromoted = case args' of+ arg0:_ -> pprSpaceIfPromotedTyCon arg0+ _ -> id+ in ppr_tuple_app args' $+ pprPromotionQuoteI IsPromoted <>+ tupleParens sort (spaceIfPromoted (pprWithCommas pprIfaceType args'))++ NotPromoted+ | ConstraintTuple <- sort+ , IA_Nil <- args+ -> maybeParen ctxt_prec sigPrec $+ text "() :: Constraint"++ | otherwise+ -> -- drop the RuntimeRep vars.+ -- See Note [Unboxed tuple RuntimeRep vars] in TyCon+ let tys = appArgsIfaceTypes args+ args' = case sort of+ UnboxedTuple -> drop (length tys `div` 2) tys+ _ -> tys+ in+ ppr_tuple_app args' $+ pprPromotionQuoteI promoted <>+ tupleParens sort (pprWithCommas pprIfaceType args')+ where+ ppr_tuple_app :: [IfaceType] -> SDoc -> SDoc+ ppr_tuple_app args_wo_runtime_reps ppr_args_w_parens+ -- Special-case unary boxed tuples so that they are pretty-printed as+ -- `Unit x`, not `(x)`+ | [_] <- args_wo_runtime_reps+ , BoxedTuple <- sort+ = let unit_tc_info = IfaceTyConInfo promoted IfaceNormalTyCon+ unit_tc = IfaceTyCon (tupleTyConName sort 1) unit_tc_info in+ pprPrecIfaceType ctxt_prec $ IfaceTyConApp unit_tc args+ | otherwise+ = ppr_args_w_parens++pprIfaceTyLit :: IfaceTyLit -> SDoc+pprIfaceTyLit (IfaceNumTyLit n) = integer n+pprIfaceTyLit (IfaceStrTyLit n) = text (show n)++pprIfaceCoercion, pprParendIfaceCoercion :: IfaceCoercion -> SDoc+pprIfaceCoercion = ppr_co topPrec+pprParendIfaceCoercion = ppr_co appPrec++ppr_co :: PprPrec -> IfaceCoercion -> SDoc+ppr_co _ (IfaceReflCo ty) = angleBrackets (ppr ty) <> ppr_role Nominal+ppr_co _ (IfaceGReflCo r ty IfaceMRefl)+ = angleBrackets (ppr ty) <> ppr_role r+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)+ = maybeParen ctxt_prec funPrec $+ sep (ppr_co funPrec co1 : ppr_fun_tail 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_co _ (IfaceTyConAppCo r tc cos)+ = parens (pprIfaceCoTcApp topPrec tc cos) <> ppr_role r+ppr_co ctxt_prec (IfaceAppCo co1 co2)+ = maybeParen ctxt_prec appPrec $+ ppr_co funPrec co1 <+> pprParendIfaceCoercion co2+ppr_co ctxt_prec co@(IfaceForAllCo {})+ = maybeParen ctxt_prec funPrec $+ pprIfaceForAllCoPart tvs (pprIfaceCoercion inner_co)+ where+ (tvs, inner_co) = split_co co++ 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')+ = let (tvs, co'') = split_co co' in ((name,kind_co):tvs,co'')+ split_co co' = ([], co')++-- Why these three? See Note [TcTyVars in IfaceType]+ppr_co _ (IfaceFreeCoVar covar) = ppr covar+ppr_co _ (IfaceCoVarCo covar) = ppr covar+ppr_co _ (IfaceHoleCo covar) = braces (ppr covar)++ppr_co ctxt_prec (IfaceUnivCo IfaceUnsafeCoerceProv r ty1 ty2)+ = maybeParen ctxt_prec appPrec $+ text "UnsafeCo" <+> ppr r <+>+ pprParendIfaceType ty1 <+> pprParendIfaceType ty2++ppr_co _ (IfaceUnivCo prov role ty1 ty2)+ = text "Univ" <> (parens $+ sep [ ppr role <+> pprIfaceUnivCoProv prov+ , dcolon <+> ppr ty1 <> comma <+> ppr ty2 ])++ppr_co ctxt_prec (IfaceInstCo co ty)+ = maybeParen ctxt_prec appPrec $+ text "Inst" <+> pprParendIfaceCoercion co+ <+> pprParendIfaceCoercion ty++ppr_co ctxt_prec (IfaceAxiomRuleCo tc cos)+ = maybeParen ctxt_prec appPrec $ ppr tc <+> parens (interpp'SP cos)++ppr_co ctxt_prec (IfaceAxiomInstCo n i cos)+ = ppr_special_co ctxt_prec (ppr n <> brackets (ppr i)) cos+ppr_co ctxt_prec (IfaceSymCo co)+ = ppr_special_co ctxt_prec (text "Sym") [co]+ppr_co ctxt_prec (IfaceTransCo co1 co2)+ = maybeParen ctxt_prec opPrec $+ ppr_co opPrec co1 <+> semi <+> ppr_co opPrec co2+ppr_co ctxt_prec (IfaceNthCo d co)+ = ppr_special_co ctxt_prec (text "Nth:" <> int d) [co]+ppr_co ctxt_prec (IfaceLRCo lr co)+ = ppr_special_co ctxt_prec (ppr lr) [co]+ppr_co ctxt_prec (IfaceSubCo co)+ = ppr_special_co ctxt_prec (text "Sub") [co]+ppr_co ctxt_prec (IfaceKindCo co)+ = ppr_special_co ctxt_prec (text "Kind") [co]++ppr_special_co :: PprPrec -> SDoc -> [IfaceCoercion] -> SDoc+ppr_special_co ctxt_prec doc cos+ = maybeParen ctxt_prec appPrec+ (sep [doc, nest 4 (sep (map pprParendIfaceCoercion cos))])++ppr_role :: Role -> SDoc+ppr_role r = underscore <> pp_role+ where pp_role = case r of+ Nominal -> char 'N'+ Representational -> char 'R'+ Phantom -> char 'P'++------------------+pprIfaceUnivCoProv :: IfaceUnivCoProv -> SDoc+pprIfaceUnivCoProv IfaceUnsafeCoerceProv+ = text "unsafe"+pprIfaceUnivCoProv (IfacePhantomProv co)+ = text "phantom" <+> pprParendIfaceCoercion co+pprIfaceUnivCoProv (IfaceProofIrrelProv co)+ = text "irrel" <+> pprParendIfaceCoercion co+pprIfaceUnivCoProv (IfacePluginProv s)+ = text "plugin" <+> doubleQuotes (text s)++-------------------+instance Outputable IfaceTyCon where+ ppr tc = pprPromotionQuote tc <> ppr (ifaceTyConName tc)++pprPromotionQuote :: IfaceTyCon -> SDoc+pprPromotionQuote tc =+ pprPromotionQuoteI $ ifaceTyConIsPromoted $ ifaceTyConInfo tc++pprPromotionQuoteI :: PromotionFlag -> SDoc+pprPromotionQuoteI NotPromoted = empty+pprPromotionQuoteI IsPromoted = char '\''++instance Outputable IfaceCoercion where+ ppr = pprIfaceCoercion++instance Binary IfaceTyCon where+ put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i++ get bh = do n <- get bh+ i <- get bh+ return (IfaceTyCon n i)++instance Binary IfaceTyConSort where+ put_ bh IfaceNormalTyCon = putByte bh 0+ put_ bh (IfaceTupleTyCon arity sort) = putByte bh 1 >> put_ bh arity >> put_ bh sort+ put_ bh (IfaceSumTyCon arity) = putByte bh 2 >> put_ bh arity+ put_ bh IfaceEqualityTyCon = putByte bh 3++ get bh = do+ n <- getByte bh+ case n of+ 0 -> return IfaceNormalTyCon+ 1 -> IfaceTupleTyCon <$> get bh <*> get bh+ 2 -> IfaceSumTyCon <$> get bh+ _ -> return IfaceEqualityTyCon++instance Binary IfaceTyConInfo where+ put_ bh (IfaceTyConInfo i s) = put_ bh i >> put_ bh s++ get bh = IfaceTyConInfo <$> get bh <*> get bh++instance Outputable IfaceTyLit where+ ppr = pprIfaceTyLit++instance Binary IfaceTyLit where+ put_ bh (IfaceNumTyLit n) = putByte bh 1 >> put_ bh n+ put_ bh (IfaceStrTyLit n) = putByte bh 2 >> put_ bh n++ get bh =+ do tag <- getByte bh+ case tag of+ 1 -> do { n <- get bh+ ; return (IfaceNumTyLit n) }+ 2 -> do { n <- get bh+ ; return (IfaceStrTyLit n) }+ _ -> panic ("get IfaceTyLit " ++ show tag)++instance Binary IfaceAppArgs where+ put_ bh tk =+ case tk of+ IA_Arg t a ts -> putByte bh 0 >> put_ bh t >> put_ bh a >> put_ bh ts+ IA_Nil -> putByte bh 1++ get bh =+ do c <- getByte bh+ case c of+ 0 -> do+ t <- get bh+ a <- get bh+ ts <- get bh+ return $! IA_Arg t a ts+ 1 -> return IA_Nil+ _ -> panic ("get IfaceAppArgs " ++ show c)++-------------------++-- Some notes about printing contexts+--+-- In the event that we are printing a singleton context (e.g. @Eq a@) we can+-- omit parentheses. However, we must take care to set the precedence correctly+-- to opPrec, since something like @a :~: b@ must be parenthesized (see+-- #9658).+--+-- When printing a larger context we use 'fsep' instead of 'sep' so that+-- the context doesn't get displayed as a giant column. Rather than,+-- instance (Eq a,+-- Eq b,+-- Eq c,+-- Eq d,+-- Eq e,+-- Eq f,+-- Eq g,+-- Eq h,+-- Eq i,+-- Eq j,+-- Eq k,+-- Eq l) =>+-- Eq (a, b, c, d, e, f, g, h, i, j, k, l)+--+-- we want+--+-- instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i,+-- Eq j, Eq k, Eq l) =>+-- Eq (a, b, c, d, e, f, g, h, i, j, k, l)++++-- | Prints "(C a, D b) =>", including the arrow.+-- Used when we want to print a context in a type, so we+-- use 'funPrec' to decide whether to parenthesise a singleton+-- predicate; e.g. Num a => a -> a+pprIfaceContextArr :: [IfacePredType] -> SDoc+pprIfaceContextArr [] = empty+pprIfaceContextArr [pred] = ppr_ty funPrec pred <+> darrow+pprIfaceContextArr preds = ppr_parend_preds preds <+> darrow++-- | Prints a context or @()@ if empty+-- You give it the context precedence+pprIfaceContext :: PprPrec -> [IfacePredType] -> SDoc+pprIfaceContext _ [] = text "()"+pprIfaceContext prec [pred] = ppr_ty prec pred+pprIfaceContext _ preds = ppr_parend_preds preds++ppr_parend_preds :: [IfacePredType] -> SDoc+ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds)))++instance Binary IfaceType where+ put_ _ (IfaceFreeTyVar tv)+ = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv)++ put_ bh (IfaceForAllTy aa ab) = do+ putByte bh 0+ put_ bh aa+ put_ bh ab+ put_ bh (IfaceTyVar ad) = do+ putByte bh 1+ put_ bh ad+ put_ bh (IfaceAppTy ae af) = do+ putByte bh 2+ put_ bh ae+ put_ bh af+ put_ bh (IfaceFunTy af ag ah) = do+ putByte bh 3+ put_ bh af+ put_ bh ag+ put_ bh ah+ put_ bh (IfaceTyConApp tc tys)+ = do { putByte bh 5; put_ bh tc; put_ bh tys }+ put_ bh (IfaceCastTy a b)+ = do { putByte bh 6; put_ bh a; put_ bh b }+ put_ bh (IfaceCoercionTy a)+ = do { putByte bh 7; put_ bh a }+ put_ bh (IfaceTupleTy s i tys)+ = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys }+ put_ bh (IfaceLitTy n)+ = do { putByte bh 9; put_ bh n }++ get bh = do+ h <- getByte bh+ case h of+ 0 -> do aa <- get bh+ ab <- get bh+ return (IfaceForAllTy aa ab)+ 1 -> do ad <- get bh+ return (IfaceTyVar ad)+ 2 -> do ae <- get bh+ af <- get bh+ return (IfaceAppTy ae af)+ 3 -> do af <- get bh+ ag <- get bh+ ah <- get bh+ return (IfaceFunTy af ag ah)+ 5 -> do { tc <- get bh; tys <- get bh+ ; return (IfaceTyConApp tc tys) }+ 6 -> do { a <- get bh; b <- get bh+ ; return (IfaceCastTy a b) }+ 7 -> do { a <- get bh+ ; return (IfaceCoercionTy a) }++ 8 -> do { s <- get bh; i <- get bh; tys <- get bh+ ; return (IfaceTupleTy s i tys) }+ _ -> do n <- get bh+ return (IfaceLitTy n)++instance Binary IfaceMCoercion where+ put_ bh IfaceMRefl = do+ putByte bh 1+ put_ bh (IfaceMCo co) = do+ putByte bh 2+ put_ bh co++ get bh = do+ tag <- getByte bh+ case tag of+ 1 -> return IfaceMRefl+ 2 -> do a <- get bh+ return $ IfaceMCo a+ _ -> panic ("get IfaceMCoercion " ++ show tag)++instance Binary IfaceCoercion where+ put_ bh (IfaceReflCo a) = do+ putByte bh 1+ put_ bh a+ put_ bh (IfaceGReflCo a b c) = do+ putByte bh 2+ put_ bh a+ put_ bh b+ put_ bh c+ put_ bh (IfaceFunCo a b c) = do+ putByte bh 3+ put_ bh a+ put_ bh b+ put_ bh c+ put_ bh (IfaceTyConAppCo a b c) = do+ putByte bh 4+ put_ bh a+ put_ bh b+ put_ bh c+ put_ bh (IfaceAppCo a b) = do+ putByte bh 5+ put_ bh a+ put_ bh b+ put_ bh (IfaceForAllCo a b c) = do+ putByte bh 6+ put_ bh a+ put_ bh b+ put_ bh c+ put_ bh (IfaceCoVarCo a) = do+ putByte bh 7+ put_ bh a+ put_ bh (IfaceAxiomInstCo a b c) = do+ putByte bh 8+ put_ bh a+ put_ bh b+ put_ bh c+ put_ bh (IfaceUnivCo a b c d) = do+ putByte bh 9+ put_ bh a+ put_ bh b+ put_ bh c+ put_ bh d+ put_ bh (IfaceSymCo a) = do+ putByte bh 10+ put_ bh a+ put_ bh (IfaceTransCo a b) = do+ putByte bh 11+ put_ bh a+ put_ bh b+ put_ bh (IfaceNthCo a b) = do+ putByte bh 12+ put_ bh a+ put_ bh b+ put_ bh (IfaceLRCo a b) = do+ putByte bh 13+ put_ bh a+ put_ bh b+ put_ bh (IfaceInstCo a b) = do+ putByte bh 14+ put_ bh a+ put_ bh b+ put_ bh (IfaceKindCo a) = do+ putByte bh 15+ put_ bh a+ put_ bh (IfaceSubCo a) = do+ putByte bh 16+ put_ bh a+ put_ bh (IfaceAxiomRuleCo a b) = do+ putByte bh 17+ put_ bh a+ put_ bh b+ put_ _ (IfaceFreeCoVar cv)+ = pprPanic "Can't serialise IfaceFreeCoVar" (ppr cv)+ put_ _ (IfaceHoleCo cv)+ = pprPanic "Can't serialise IfaceHoleCo" (ppr cv)+ -- See Note [Holes in IfaceCoercion]++ get bh = do+ tag <- getByte bh+ case tag of+ 1 -> do a <- get bh+ return $ IfaceReflCo a+ 2 -> do a <- get bh+ b <- get bh+ c <- get bh+ return $ IfaceGReflCo a b c+ 3 -> do a <- get bh+ b <- get bh+ c <- get bh+ return $ IfaceFunCo a b c+ 4 -> do a <- get bh+ b <- get bh+ c <- get bh+ return $ IfaceTyConAppCo a b c+ 5 -> do a <- get bh+ b <- get bh+ return $ IfaceAppCo a b+ 6 -> do a <- get bh+ b <- get bh+ c <- get bh+ return $ IfaceForAllCo a b c+ 7 -> do a <- get bh+ return $ IfaceCoVarCo a+ 8 -> do a <- get bh+ b <- get bh+ c <- get bh+ return $ IfaceAxiomInstCo a b c+ 9 -> do a <- get bh+ b <- get bh+ c <- get bh+ d <- get bh+ return $ IfaceUnivCo a b c d+ 10-> do a <- get bh+ return $ IfaceSymCo a+ 11-> do a <- get bh+ b <- get bh+ return $ IfaceTransCo a b+ 12-> do a <- get bh+ b <- get bh+ return $ IfaceNthCo a b+ 13-> do a <- get bh+ b <- get bh+ return $ IfaceLRCo a b+ 14-> do a <- get bh+ b <- get bh+ return $ IfaceInstCo a b+ 15-> do a <- get bh+ return $ IfaceKindCo a+ 16-> do a <- get bh+ return $ IfaceSubCo a+ 17-> do a <- get bh+ b <- get bh+ return $ IfaceAxiomRuleCo a b+ _ -> panic ("get IfaceCoercion " ++ show tag)++instance Binary IfaceUnivCoProv where+ put_ bh IfaceUnsafeCoerceProv = putByte bh 1+ put_ bh (IfacePhantomProv a) = do+ putByte bh 2+ put_ bh a+ put_ bh (IfaceProofIrrelProv a) = do+ putByte bh 3+ put_ bh a+ put_ bh (IfacePluginProv a) = do+ putByte bh 4+ put_ bh a++ get bh = do+ tag <- getByte bh+ case tag of+ 1 -> return $ IfaceUnsafeCoerceProv+ 2 -> do a <- get bh+ return $ IfacePhantomProv a+ 3 -> do a <- get bh+ return $ IfaceProofIrrelProv a+ 4 -> do a <- get bh+ return $ IfacePluginProv a+ _ -> panic ("get IfaceUnivCoProv " ++ show tag)+++instance Binary (DefMethSpec IfaceType) where+ put_ bh VanillaDM = putByte bh 0+ put_ bh (GenericDM t) = putByte bh 1 >> put_ bh t+ get bh = do+ h <- getByte bh+ case h of+ 0 -> return VanillaDM+ _ -> do { t <- get bh; return (GenericDM t) }++instance NFData IfaceType where+ rnf = \case+ IfaceFreeTyVar f1 -> f1 `seq` ()+ 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+ IfaceForAllTy f1 f2 -> f1 `seq` rnf f2+ IfaceTyConApp f1 f2 -> rnf f1 `seq` rnf f2+ IfaceCastTy f1 f2 -> rnf f1 `seq` rnf f2+ IfaceCoercionTy f1 -> rnf f1+ IfaceTupleTy f1 f2 f3 -> f1 `seq` f2 `seq` rnf f3++instance NFData IfaceTyLit where+ rnf = \case+ IfaceNumTyLit f1 -> rnf f1+ IfaceStrTyLit f1 -> rnf f1++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+ 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+ IfaceCoVarCo f1 -> rnf f1+ IfaceAxiomInstCo f1 f2 f3 -> rnf f1 `seq` rnf f2 `seq` rnf f3+ IfaceAxiomRuleCo f1 f2 -> rnf f1 `seq` rnf f2+ IfaceUnivCo f1 f2 f3 f4 -> rnf f1 `seq` f2 `seq` rnf f3 `seq` rnf f4+ IfaceSymCo f1 -> rnf f1+ IfaceTransCo f1 f2 -> rnf f1 `seq` rnf f2+ IfaceNthCo f1 f2 -> rnf f1 `seq` rnf f2+ IfaceLRCo f1 f2 -> f1 `seq` rnf f2+ IfaceInstCo f1 f2 -> rnf f1 `seq` rnf f2+ IfaceKindCo f1 -> rnf f1+ IfaceSubCo f1 -> rnf f1+ IfaceFreeCoVar f1 -> f1 `seq` ()+ IfaceHoleCo f1 -> f1 `seq` ()++instance NFData IfaceUnivCoProv where+ rnf x = seq x ()++instance NFData IfaceMCoercion where+ rnf x = seq x ()++instance NFData IfaceOneShot where+ rnf x = seq x ()++instance NFData IfaceTyConSort where+ rnf = \case+ IfaceNormalTyCon -> ()+ IfaceTupleTyCon arity sort -> rnf arity `seq` sort `seq` ()+ IfaceSumTyCon arity -> rnf arity+ IfaceEqualityTyCon -> ()++instance NFData IfaceTyConInfo where+ rnf (IfaceTyConInfo f s) = f `seq` rnf s++instance NFData IfaceTyCon where+ rnf (IfaceTyCon nm info) = rnf nm `seq` rnf info++instance NFData IfaceBndr where+ rnf = \case+ IfaceIdBndr id_bndr -> rnf id_bndr+ IfaceTvBndr tv_bndr -> rnf tv_bndr++instance NFData IfaceAppArgs where+ rnf = \case+ IA_Nil -> ()+ IA_Arg f1 f2 f3 -> rnf f1 `seq` f2 `seq` rnf f3
+ compiler/GHC/Iface/Type.hs-boot view
@@ -0,0 +1,16 @@+module GHC.Iface.Type+ ( IfaceType, IfaceTyCon, IfaceForAllBndr+ , IfaceCoercion, IfaceTyLit, IfaceAppArgs+ )+where++import Var (VarBndr, ArgFlag)++data IfaceAppArgs++data IfaceType+data IfaceTyCon+data IfaceTyLit+data IfaceCoercion+data IfaceBndr+type IfaceForAllBndr = VarBndr IfaceBndr ArgFlag
+ compiler/GHC/Platform/ARM.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE CPP #-}++module GHC.Platform.ARM where++import GhcPrelude++#define MACHREGS_NO_REGS 0+#define MACHREGS_arm 1+#include "../../../includes/CodeGen.Platform.hs"+
+ compiler/GHC/Platform/ARM64.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE CPP #-}++module GHC.Platform.ARM64 where++import GhcPrelude++#define MACHREGS_NO_REGS 0+#define MACHREGS_aarch64 1+#include "../../../includes/CodeGen.Platform.hs"+
+ compiler/GHC/Platform/NoRegs.hs view
@@ -0,0 +1,9 @@+{-# LANGUAGE CPP #-}++module GHC.Platform.NoRegs where++import GhcPrelude++#define MACHREGS_NO_REGS 1+#include "../../../includes/CodeGen.Platform.hs"+
+ compiler/GHC/Platform/PPC.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE CPP #-}++module GHC.Platform.PPC where++import GhcPrelude++#define MACHREGS_NO_REGS 0+#define MACHREGS_powerpc 1+#include "../../../includes/CodeGen.Platform.hs"+
+ compiler/GHC/Platform/Regs.hs view
@@ -0,0 +1,113 @@++module GHC.Platform.Regs+ (callerSaves, activeStgRegs, haveRegBase, globalRegMaybe, freeReg)+ where++import GhcPrelude++import GHC.Cmm.Expr+import GHC.Platform+import Reg++import qualified GHC.Platform.ARM as ARM+import qualified GHC.Platform.ARM64 as ARM64+import qualified GHC.Platform.PPC as PPC+import qualified GHC.Platform.S390X as S390X+import qualified GHC.Platform.SPARC as SPARC+import qualified GHC.Platform.X86 as X86+import qualified GHC.Platform.X86_64 as X86_64+import qualified GHC.Platform.NoRegs as NoRegs++-- | Returns 'True' if this global register is stored in a caller-saves+-- machine register.++callerSaves :: Platform -> GlobalReg -> Bool+callerSaves platform+ | platformUnregisterised platform = NoRegs.callerSaves+ | otherwise+ = case platformArch platform of+ ArchX86 -> X86.callerSaves+ ArchX86_64 -> X86_64.callerSaves+ ArchS390X -> S390X.callerSaves+ ArchSPARC -> SPARC.callerSaves+ ArchARM {} -> ARM.callerSaves+ ArchARM64 -> ARM64.callerSaves+ arch+ | arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->+ PPC.callerSaves++ | otherwise -> NoRegs.callerSaves++-- | Here is where the STG register map is defined for each target arch.+-- The order matters (for the llvm backend anyway)! We must make sure to+-- maintain the order here with the order used in the LLVM calling conventions.+-- Note that also, this isn't all registers, just the ones that are currently+-- possibly mapped to real registers.+activeStgRegs :: Platform -> [GlobalReg]+activeStgRegs platform+ | platformUnregisterised platform = NoRegs.activeStgRegs+ | otherwise+ = case platformArch platform of+ ArchX86 -> X86.activeStgRegs+ ArchX86_64 -> X86_64.activeStgRegs+ ArchS390X -> S390X.activeStgRegs+ ArchSPARC -> SPARC.activeStgRegs+ ArchARM {} -> ARM.activeStgRegs+ ArchARM64 -> ARM64.activeStgRegs+ arch+ | arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->+ PPC.activeStgRegs++ | otherwise -> NoRegs.activeStgRegs++haveRegBase :: Platform -> Bool+haveRegBase platform+ | platformUnregisterised platform = NoRegs.haveRegBase+ | otherwise+ = case platformArch platform of+ ArchX86 -> X86.haveRegBase+ ArchX86_64 -> X86_64.haveRegBase+ ArchS390X -> S390X.haveRegBase+ ArchSPARC -> SPARC.haveRegBase+ ArchARM {} -> ARM.haveRegBase+ ArchARM64 -> ARM64.haveRegBase+ arch+ | arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->+ PPC.haveRegBase++ | otherwise -> NoRegs.haveRegBase++globalRegMaybe :: Platform -> GlobalReg -> Maybe RealReg+globalRegMaybe platform+ | platformUnregisterised platform = NoRegs.globalRegMaybe+ | otherwise+ = case platformArch platform of+ ArchX86 -> X86.globalRegMaybe+ ArchX86_64 -> X86_64.globalRegMaybe+ ArchS390X -> S390X.globalRegMaybe+ ArchSPARC -> SPARC.globalRegMaybe+ ArchARM {} -> ARM.globalRegMaybe+ ArchARM64 -> ARM64.globalRegMaybe+ arch+ | arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->+ PPC.globalRegMaybe++ | otherwise -> NoRegs.globalRegMaybe++freeReg :: Platform -> RegNo -> Bool+freeReg platform+ | platformUnregisterised platform = NoRegs.freeReg+ | otherwise+ = case platformArch platform of+ ArchX86 -> X86.freeReg+ ArchX86_64 -> X86_64.freeReg+ ArchS390X -> S390X.freeReg+ ArchSPARC -> SPARC.freeReg+ ArchARM {} -> ARM.freeReg+ ArchARM64 -> ARM64.freeReg+ arch+ | arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] ->+ PPC.freeReg++ | otherwise -> NoRegs.freeReg+
+ compiler/GHC/Platform/S390X.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE CPP #-}++module GHC.Platform.S390X where++import GhcPrelude++#define MACHREGS_NO_REGS 0+#define MACHREGS_s390x 1+#include "../../../includes/CodeGen.Platform.hs"+
+ compiler/GHC/Platform/SPARC.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE CPP #-}++module GHC.Platform.SPARC where++import GhcPrelude++#define MACHREGS_NO_REGS 0+#define MACHREGS_sparc 1+#include "../../../includes/CodeGen.Platform.hs"+
+ compiler/GHC/Platform/X86.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE CPP #-}++module GHC.Platform.X86 where++import GhcPrelude++#define MACHREGS_NO_REGS 0+#define MACHREGS_i386 1+#include "../../../includes/CodeGen.Platform.hs"+
+ compiler/GHC/Platform/X86_64.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE CPP #-}++module GHC.Platform.X86_64 where++import GhcPrelude++#define MACHREGS_NO_REGS 0+#define MACHREGS_x86_64 1+#include "../../../includes/CodeGen.Platform.hs"+
+ compiler/GHC/Runtime/Layout.hs view
@@ -0,0 +1,563 @@+-- (c) The University of Glasgow 2006+-- (c) The GRASP/AQUA Project, Glasgow University, 1992-1998+--+-- Storage manager representation of closures++{-# LANGUAGE CPP,GeneralizedNewtypeDeriving #-}++module GHC.Runtime.Layout (+ -- * Words and bytes+ WordOff, ByteOff,+ wordsToBytes, bytesToWordsRoundUp,+ roundUpToWords, roundUpTo,++ StgWord, fromStgWord, toStgWord,+ StgHalfWord, fromStgHalfWord, toStgHalfWord,+ halfWordSize, halfWordSizeInBits,++ -- * Closure representation+ SMRep(..), -- CmmInfo sees the rep; no one else does+ IsStatic,+ ClosureTypeInfo(..), ArgDescr(..), Liveness,+ ConstrDescription,++ -- ** Construction+ mkHeapRep, blackHoleRep, indStaticRep, mkStackRep, mkRTSRep, arrPtrsRep,+ smallArrPtrsRep, arrWordsRep,++ -- ** Predicates+ isStaticRep, isConRep, isThunkRep, isFunRep, isStaticNoCafCon,+ isStackRep,++ -- ** Size-related things+ heapClosureSizeW,+ fixedHdrSizeW, arrWordsHdrSize, arrWordsHdrSizeW, arrPtrsHdrSize,+ arrPtrsHdrSizeW, profHdrSize, thunkHdrSize, nonHdrSize, nonHdrSizeW,+ smallArrPtrsHdrSize, smallArrPtrsHdrSizeW, hdrSize, hdrSizeW,+ fixedHdrSize,++ -- ** RTS closure types+ rtsClosureType, rET_SMALL, rET_BIG,+ aRG_GEN, aRG_GEN_BIG,++ -- ** Arrays+ card, cardRoundUp, cardTableSizeB, cardTableSizeW+ ) where++import GhcPrelude++import BasicTypes( ConTagZ )+import DynFlags+import Outputable+import GHC.Platform+import FastString++import Data.Word+import Data.Bits+import Data.ByteString (ByteString)++{-+************************************************************************+* *+ Words and bytes+* *+************************************************************************+-}++-- | Word offset, or word count+type WordOff = Int++-- | Byte offset, or byte count+type ByteOff = Int++-- | Round up the given byte count to the next byte count that's a+-- multiple of the machine's word size.+roundUpToWords :: DynFlags -> ByteOff -> ByteOff+roundUpToWords dflags n = roundUpTo n (wORD_SIZE dflags)++-- | Round up @base@ to a multiple of @size@.+roundUpTo :: ByteOff -> ByteOff -> ByteOff+roundUpTo base size = (base + (size - 1)) .&. (complement (size - 1))++-- | Convert the given number of words to a number of bytes.+--+-- This function morally has type @WordOff -> ByteOff@, but uses @Num+-- a@ to allow for overloading.+wordsToBytes :: Num a => DynFlags -> a -> a+wordsToBytes dflags n = fromIntegral (wORD_SIZE dflags) * n+{-# SPECIALIZE wordsToBytes :: DynFlags -> Int -> Int #-}+{-# SPECIALIZE wordsToBytes :: DynFlags -> Word -> Word #-}+{-# SPECIALIZE wordsToBytes :: DynFlags -> Integer -> Integer #-}++-- | First round the given byte count up to a multiple of the+-- machine's word size and then convert the result to words.+bytesToWordsRoundUp :: DynFlags -> ByteOff -> WordOff+bytesToWordsRoundUp dflags n = (n + word_size - 1) `quot` word_size+ where word_size = wORD_SIZE dflags+-- StgWord is a type representing an StgWord on the target platform.+-- A Word64 is large enough to hold a Word for either a 32bit or 64bit platform+newtype StgWord = StgWord Word64+ deriving (Eq, Bits)++fromStgWord :: StgWord -> Integer+fromStgWord (StgWord i) = toInteger i++toStgWord :: DynFlags -> Integer -> StgWord+toStgWord dflags i+ = case platformWordSize (targetPlatform dflags) of+ -- These conversions mean that things like toStgWord (-1)+ -- do the right thing+ PW4 -> StgWord (fromIntegral (fromInteger i :: Word32))+ PW8 -> StgWord (fromInteger i)++instance Outputable StgWord where+ ppr (StgWord i) = integer (toInteger i)++--++-- A Word32 is large enough to hold half a Word for either a 32bit or+-- 64bit platform+newtype StgHalfWord = StgHalfWord Word32+ deriving Eq++fromStgHalfWord :: StgHalfWord -> Integer+fromStgHalfWord (StgHalfWord w) = toInteger w++toStgHalfWord :: DynFlags -> Integer -> StgHalfWord+toStgHalfWord dflags i+ = case platformWordSize (targetPlatform dflags) of+ -- These conversions mean that things like toStgHalfWord (-1)+ -- do the right thing+ PW4 -> StgHalfWord (fromIntegral (fromInteger i :: Word16))+ PW8 -> StgHalfWord (fromInteger i :: Word32)++instance Outputable StgHalfWord where+ ppr (StgHalfWord w) = integer (toInteger w)++-- | Half word size in bytes+halfWordSize :: DynFlags -> ByteOff+halfWordSize dflags = platformWordSizeInBytes (targetPlatform dflags) `div` 2++halfWordSizeInBits :: DynFlags -> Int+halfWordSizeInBits dflags = platformWordSizeInBits (targetPlatform dflags) `div` 2++{-+************************************************************************+* *+\subsubsection[SMRep-datatype]{@SMRep@---storage manager representation}+* *+************************************************************************+-}++-- | A description of the layout of a closure. Corresponds directly+-- to the closure types in includes/rts/storage/ClosureTypes.h.+data SMRep+ = HeapRep -- GC routines consult sizes in info tbl+ IsStatic+ !WordOff -- # ptr words+ !WordOff -- # non-ptr words INCLUDING SLOP (see mkHeapRep below)+ ClosureTypeInfo -- type-specific info++ | ArrayPtrsRep+ !WordOff -- # ptr words+ !WordOff -- # card table words++ | SmallArrayPtrsRep+ !WordOff -- # ptr words++ | ArrayWordsRep+ !WordOff -- # bytes expressed in words, rounded up++ | StackRep -- Stack frame (RET_SMALL or RET_BIG)+ Liveness++ | RTSRep -- The RTS needs to declare info tables with specific+ Int -- type tags, so this form lets us override the default+ SMRep -- tag for an SMRep.++-- | True <=> This is a static closure. Affects how we garbage-collect it.+-- Static closure have an extra static link field at the end.+-- Constructors do not have a static variant; see Note [static constructors]+type IsStatic = Bool++-- From an SMRep you can get to the closure type defined in+-- includes/rts/storage/ClosureTypes.h. Described by the function+-- rtsClosureType below.++data ClosureTypeInfo+ = Constr ConTagZ ConstrDescription+ | Fun FunArity ArgDescr+ | Thunk+ | ThunkSelector SelectorOffset+ | BlackHole+ | IndStatic++type ConstrDescription = ByteString -- result of dataConIdentity+type FunArity = Int+type SelectorOffset = Int++-------------------------+-- We represent liveness bitmaps as a Bitmap (whose internal+-- representation really is a bitmap). These are pinned onto case return+-- vectors to indicate the state of the stack for the garbage collector.+--+-- In the compiled program, liveness bitmaps that fit inside a single+-- word (StgWord) are stored as a single word, while larger bitmaps are+-- stored as a pointer to an array of words.++type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead+ -- False <=> ptr++-------------------------+-- An ArgDescr describes the argument pattern of a function++data ArgDescr+ = ArgSpec -- Fits one of the standard patterns+ !Int -- RTS type identifier ARG_P, ARG_N, ...++ | ArgGen -- General case+ Liveness -- Details about the arguments+++-----------------------------------------------------------------------------+-- Construction++mkHeapRep :: DynFlags -> IsStatic -> WordOff -> WordOff -> ClosureTypeInfo+ -> SMRep+mkHeapRep dflags is_static ptr_wds nonptr_wds cl_type_info+ = HeapRep is_static+ ptr_wds+ (nonptr_wds + slop_wds)+ cl_type_info+ where+ slop_wds+ | is_static = 0+ | otherwise = max 0 (minClosureSize dflags - (hdr_size + payload_size))++ hdr_size = closureTypeHdrSize dflags cl_type_info+ payload_size = ptr_wds + nonptr_wds++mkRTSRep :: Int -> SMRep -> SMRep+mkRTSRep = RTSRep++mkStackRep :: [Bool] -> SMRep+mkStackRep liveness = StackRep liveness++blackHoleRep :: SMRep+blackHoleRep = HeapRep False 0 0 BlackHole++indStaticRep :: SMRep+indStaticRep = HeapRep True 1 0 IndStatic++arrPtrsRep :: DynFlags -> WordOff -> SMRep+arrPtrsRep dflags elems = ArrayPtrsRep elems (cardTableSizeW dflags elems)++smallArrPtrsRep :: WordOff -> SMRep+smallArrPtrsRep elems = SmallArrayPtrsRep elems++arrWordsRep :: DynFlags -> ByteOff -> SMRep+arrWordsRep dflags bytes = ArrayWordsRep (bytesToWordsRoundUp dflags bytes)++-----------------------------------------------------------------------------+-- Predicates++isStaticRep :: SMRep -> IsStatic+isStaticRep (HeapRep is_static _ _ _) = is_static+isStaticRep (RTSRep _ rep) = isStaticRep rep+isStaticRep _ = False++isStackRep :: SMRep -> Bool+isStackRep StackRep{} = True+isStackRep (RTSRep _ rep) = isStackRep rep+isStackRep _ = False++isConRep :: SMRep -> Bool+isConRep (HeapRep _ _ _ Constr{}) = True+isConRep _ = False++isThunkRep :: SMRep -> Bool+isThunkRep (HeapRep _ _ _ Thunk) = True+isThunkRep (HeapRep _ _ _ ThunkSelector{}) = True+isThunkRep (HeapRep _ _ _ BlackHole) = True+isThunkRep (HeapRep _ _ _ IndStatic) = True+isThunkRep _ = False++isFunRep :: SMRep -> Bool+isFunRep (HeapRep _ _ _ Fun{}) = True+isFunRep _ = False++isStaticNoCafCon :: SMRep -> Bool+-- This should line up exactly with CONSTR_NOCAF below+-- See Note [Static NoCaf constructors]+isStaticNoCafCon (HeapRep _ 0 _ Constr{}) = True+isStaticNoCafCon _ = False+++-----------------------------------------------------------------------------+-- Size-related things++fixedHdrSize :: DynFlags -> ByteOff+fixedHdrSize dflags = wordsToBytes dflags (fixedHdrSizeW dflags)++-- | Size of a closure header (StgHeader in includes/rts/storage/Closures.h)+fixedHdrSizeW :: DynFlags -> WordOff+fixedHdrSizeW dflags = sTD_HDR_SIZE dflags + profHdrSize dflags++-- | Size of the profiling part of a closure header+-- (StgProfHeader in includes/rts/storage/Closures.h)+profHdrSize :: DynFlags -> WordOff+profHdrSize dflags+ | gopt Opt_SccProfilingOn dflags = pROF_HDR_SIZE dflags+ | otherwise = 0++-- | The garbage collector requires that every closure is at least as+-- big as this.+minClosureSize :: DynFlags -> WordOff+minClosureSize dflags = fixedHdrSizeW dflags + mIN_PAYLOAD_SIZE dflags++arrWordsHdrSize :: DynFlags -> ByteOff+arrWordsHdrSize dflags+ = fixedHdrSize dflags + sIZEOF_StgArrBytes_NoHdr dflags++arrWordsHdrSizeW :: DynFlags -> WordOff+arrWordsHdrSizeW dflags =+ fixedHdrSizeW dflags ++ (sIZEOF_StgArrBytes_NoHdr dflags `quot` wORD_SIZE dflags)++arrPtrsHdrSize :: DynFlags -> ByteOff+arrPtrsHdrSize dflags+ = fixedHdrSize dflags + sIZEOF_StgMutArrPtrs_NoHdr dflags++arrPtrsHdrSizeW :: DynFlags -> WordOff+arrPtrsHdrSizeW dflags =+ fixedHdrSizeW dflags ++ (sIZEOF_StgMutArrPtrs_NoHdr dflags `quot` wORD_SIZE dflags)++smallArrPtrsHdrSize :: DynFlags -> ByteOff+smallArrPtrsHdrSize dflags+ = fixedHdrSize dflags + sIZEOF_StgSmallMutArrPtrs_NoHdr dflags++smallArrPtrsHdrSizeW :: DynFlags -> WordOff+smallArrPtrsHdrSizeW dflags =+ fixedHdrSizeW dflags ++ (sIZEOF_StgSmallMutArrPtrs_NoHdr dflags `quot` wORD_SIZE dflags)++-- Thunks have an extra header word on SMP, so the update doesn't+-- splat the payload.+thunkHdrSize :: DynFlags -> WordOff+thunkHdrSize dflags = fixedHdrSizeW dflags + smp_hdr+ where smp_hdr = sIZEOF_StgSMPThunkHeader dflags `quot` wORD_SIZE dflags++hdrSize :: DynFlags -> SMRep -> ByteOff+hdrSize dflags rep = wordsToBytes dflags (hdrSizeW dflags rep)++hdrSizeW :: DynFlags -> SMRep -> WordOff+hdrSizeW dflags (HeapRep _ _ _ ty) = closureTypeHdrSize dflags ty+hdrSizeW dflags (ArrayPtrsRep _ _) = arrPtrsHdrSizeW dflags+hdrSizeW dflags (SmallArrayPtrsRep _) = smallArrPtrsHdrSizeW dflags+hdrSizeW dflags (ArrayWordsRep _) = arrWordsHdrSizeW dflags+hdrSizeW _ _ = panic "SMRep.hdrSizeW"++nonHdrSize :: DynFlags -> SMRep -> ByteOff+nonHdrSize dflags rep = wordsToBytes dflags (nonHdrSizeW rep)++nonHdrSizeW :: SMRep -> WordOff+nonHdrSizeW (HeapRep _ p np _) = p + np+nonHdrSizeW (ArrayPtrsRep elems ct) = elems + ct+nonHdrSizeW (SmallArrayPtrsRep elems) = elems+nonHdrSizeW (ArrayWordsRep words) = words+nonHdrSizeW (StackRep bs) = length bs+nonHdrSizeW (RTSRep _ rep) = nonHdrSizeW rep++-- | The total size of the closure, in words.+heapClosureSizeW :: DynFlags -> SMRep -> WordOff+heapClosureSizeW dflags (HeapRep _ p np ty)+ = closureTypeHdrSize dflags ty + p + np+heapClosureSizeW dflags (ArrayPtrsRep elems ct)+ = arrPtrsHdrSizeW dflags + elems + ct+heapClosureSizeW dflags (SmallArrayPtrsRep elems)+ = smallArrPtrsHdrSizeW dflags + elems+heapClosureSizeW dflags (ArrayWordsRep words)+ = arrWordsHdrSizeW dflags + words+heapClosureSizeW _ _ = panic "SMRep.heapClosureSize"++closureTypeHdrSize :: DynFlags -> ClosureTypeInfo -> WordOff+closureTypeHdrSize dflags ty = case ty of+ Thunk -> thunkHdrSize dflags+ ThunkSelector{} -> thunkHdrSize dflags+ BlackHole -> thunkHdrSize dflags+ IndStatic -> thunkHdrSize dflags+ _ -> fixedHdrSizeW dflags+ -- All thunks use thunkHdrSize, even if they are non-updatable.+ -- this is because we don't have separate closure types for+ -- updatable vs. non-updatable thunks, so the GC can't tell the+ -- difference. If we ever have significant numbers of non-+ -- updatable thunks, it might be worth fixing this.++-- ---------------------------------------------------------------------------+-- Arrays++-- | The byte offset into the card table of the card for a given element+card :: DynFlags -> Int -> Int+card dflags i = i `shiftR` mUT_ARR_PTRS_CARD_BITS dflags++-- | Convert a number of elements to a number of cards, rounding up+cardRoundUp :: DynFlags -> Int -> Int+cardRoundUp dflags i =+ card dflags (i + ((1 `shiftL` mUT_ARR_PTRS_CARD_BITS dflags) - 1))++-- | The size of a card table, in bytes+cardTableSizeB :: DynFlags -> Int -> ByteOff+cardTableSizeB dflags elems = cardRoundUp dflags elems++-- | The size of a card table, in words+cardTableSizeW :: DynFlags -> Int -> WordOff+cardTableSizeW dflags elems =+ bytesToWordsRoundUp dflags (cardTableSizeB dflags elems)++-----------------------------------------------------------------------------+-- deriving the RTS closure type from an SMRep++#include "rts/storage/ClosureTypes.h"+#include "rts/storage/FunTypes.h"+-- Defines CONSTR, CONSTR_1_0 etc++-- | Derives the RTS closure type from an 'SMRep'+rtsClosureType :: SMRep -> Int+rtsClosureType rep+ = case rep of+ RTSRep ty _ -> ty++ -- See Note [static constructors]+ HeapRep _ 1 0 Constr{} -> CONSTR_1_0+ HeapRep _ 0 1 Constr{} -> CONSTR_0_1+ HeapRep _ 2 0 Constr{} -> CONSTR_2_0+ HeapRep _ 1 1 Constr{} -> CONSTR_1_1+ HeapRep _ 0 2 Constr{} -> CONSTR_0_2+ HeapRep _ 0 _ Constr{} -> CONSTR_NOCAF+ -- See Note [Static NoCaf constructors]+ HeapRep _ _ _ Constr{} -> CONSTR++ HeapRep False 1 0 Fun{} -> FUN_1_0+ HeapRep False 0 1 Fun{} -> FUN_0_1+ HeapRep False 2 0 Fun{} -> FUN_2_0+ HeapRep False 1 1 Fun{} -> FUN_1_1+ HeapRep False 0 2 Fun{} -> FUN_0_2+ HeapRep False _ _ Fun{} -> FUN++ HeapRep False 1 0 Thunk -> THUNK_1_0+ HeapRep False 0 1 Thunk -> THUNK_0_1+ HeapRep False 2 0 Thunk -> THUNK_2_0+ HeapRep False 1 1 Thunk -> THUNK_1_1+ HeapRep False 0 2 Thunk -> THUNK_0_2+ HeapRep False _ _ Thunk -> THUNK++ HeapRep False _ _ ThunkSelector{} -> THUNK_SELECTOR++ HeapRep True _ _ Fun{} -> FUN_STATIC+ HeapRep True _ _ Thunk -> THUNK_STATIC+ HeapRep False _ _ BlackHole -> BLACKHOLE+ HeapRep False _ _ IndStatic -> IND_STATIC++ _ -> panic "rtsClosureType"++-- We export these ones+rET_SMALL, rET_BIG, aRG_GEN, aRG_GEN_BIG :: Int+rET_SMALL = RET_SMALL+rET_BIG = RET_BIG+aRG_GEN = ARG_GEN+aRG_GEN_BIG = ARG_GEN_BIG++{-+Note [static constructors]+~~~~~~~~~~~~~~~~~~~~~~~~~~++We used to have a CONSTR_STATIC closure type, and each constructor had+two info tables: one with CONSTR (or CONSTR_1_0 etc.), and one with+CONSTR_STATIC.++This distinction was removed, because when copying a data structure+into a compact region, we must copy static constructors into the+compact region too. If we didn't do this, we would need to track the+references from the compact region out to the static constructors,+because they might (indirectly) refer to CAFs.++Since static constructors will be copied to the heap, if we wanted to+use different info tables for static and dynamic constructors, we+would have to switch the info pointer when copying the constructor+into the compact region, which means we would need an extra field of+the static info table to point to the dynamic one.++However, since the distinction between static and dynamic closure+types is never actually needed (other than for assertions), we can+just drop the distinction and use the same info table for both.++The GC *does* need to distinguish between static and dynamic closures,+but it does this using the HEAP_ALLOCED() macro which checks whether+the address of the closure resides within the dynamic heap.+HEAP_ALLOCED() doesn't read the closure's info table.++Note [Static NoCaf constructors]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+If we know that a top-level binding 'x' is not Caffy (ie no CAFs are+reachable from 'x'), then a statically allocated constructor (Just x)+is also not Caffy, and the garbage collector need not follow its+argument fields. Exploiting this would require two static info tables+for Just, for the two cases where the argument was Caffy or non-Caffy.++Currently we don't do this; instead we treat nullary constructors+as non-Caffy, and the others as potentially Caffy.+++************************************************************************+* *+ Pretty printing of SMRep and friends+* *+************************************************************************+-}++instance Outputable ClosureTypeInfo where+ ppr = pprTypeInfo++instance Outputable SMRep where+ ppr (HeapRep static ps nps tyinfo)+ = hang (header <+> lbrace) 2 (ppr tyinfo <+> rbrace)+ where+ header = text "HeapRep"+ <+> if static then text "static" else empty+ <+> pp_n "ptrs" ps <+> pp_n "nonptrs" nps+ pp_n :: String -> Int -> SDoc+ pp_n _ 0 = empty+ pp_n s n = int n <+> text s++ ppr (ArrayPtrsRep size _) = text "ArrayPtrsRep" <+> ppr size++ ppr (SmallArrayPtrsRep size) = text "SmallArrayPtrsRep" <+> ppr size++ ppr (ArrayWordsRep words) = text "ArrayWordsRep" <+> ppr words++ ppr (StackRep bs) = text "StackRep" <+> ppr bs++ ppr (RTSRep ty rep) = text "tag:" <> ppr ty <+> ppr rep++instance Outputable ArgDescr where+ ppr (ArgSpec n) = text "ArgSpec" <+> ppr n+ ppr (ArgGen ls) = text "ArgGen" <+> ppr ls++pprTypeInfo :: ClosureTypeInfo -> SDoc+pprTypeInfo (Constr tag descr)+ = text "Con" <+>+ braces (sep [ text "tag:" <+> ppr tag+ , text "descr:" <> text (show descr) ])++pprTypeInfo (Fun arity args)+ = text "Fun" <+>+ braces (sep [ text "arity:" <+> ppr arity+ , ptext (sLit ("fun_type:")) <+> ppr args ])++pprTypeInfo (ThunkSelector offset)+ = text "ThunkSel" <+> ppr offset++pprTypeInfo Thunk = text "Thunk"+pprTypeInfo BlackHole = text "BlackHole"+pprTypeInfo IndStatic = text "IndStatic"
+ compiler/GHC/Stg/Syntax.hs view
@@ -0,0 +1,871 @@+{-+(c) The GRASP/AQUA Project, Glasgow University, 1992-1998++Shared term graph (STG) syntax for spineless-tagless code generation+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++This data type represents programs just before code generation (conversion to+@Cmm@): basically, what we have is a stylised form of @CoreSyntax@, the style+being one that happens to be ideally suited to spineless tagless code+generation.+-}++{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds #-}++module GHC.Stg.Syntax (+ StgArg(..),++ GenStgTopBinding(..), GenStgBinding(..), GenStgExpr(..), GenStgRhs(..),+ GenStgAlt, AltType(..),++ StgPass(..), BinderP, XRhsClosure, XLet, XLetNoEscape,+ NoExtFieldSilent, noExtFieldSilent,+ OutputablePass,++ UpdateFlag(..), isUpdatable,++ -- a set of synonyms for the vanilla parameterisation+ StgTopBinding, StgBinding, StgExpr, StgRhs, StgAlt,++ -- a set of synonyms for the code gen parameterisation+ CgStgTopBinding, CgStgBinding, CgStgExpr, CgStgRhs, CgStgAlt,++ -- a set of synonyms for the lambda lifting parameterisation+ LlStgTopBinding, LlStgBinding, LlStgExpr, LlStgRhs, LlStgAlt,++ -- a set of synonyms to distinguish in- and out variants+ InStgArg, InStgTopBinding, InStgBinding, InStgExpr, InStgRhs, InStgAlt,+ OutStgArg, OutStgTopBinding, OutStgBinding, OutStgExpr, OutStgRhs, OutStgAlt,++ -- StgOp+ StgOp(..),++ -- utils+ topStgBindHasCafRefs, stgArgHasCafRefs, stgRhsArity,+ isDllConApp,+ stgArgType,+ stripStgTicksTop, stripStgTicksTopE,+ stgCaseBndrInScope,++ pprStgBinding, pprGenStgTopBindings, pprStgTopBindings+ ) where++#include "HsVersions.h"++import GhcPrelude++import CoreSyn ( AltCon, Tickish )+import CostCentre ( CostCentreStack )+import Data.ByteString ( ByteString )+import Data.Data ( Data )+import Data.List ( intersperse )+import DataCon+import DynFlags+import ForeignCall ( ForeignCall )+import Id+import IdInfo ( mayHaveCafRefs )+import VarSet+import Literal ( Literal, literalType )+import Module ( Module )+import Outputable+import Packages ( isDllName )+import GHC.Platform+import PprCore ( {- instances -} )+import PrimOp ( PrimOp, PrimCall )+import TyCon ( PrimRep(..), TyCon )+import Type ( Type )+import GHC.Types.RepType ( typePrimRep1 )+import Util++import Data.List.NonEmpty ( NonEmpty, toList )++{-+************************************************************************+* *+GenStgBinding+* *+************************************************************************++As usual, expressions are interesting; other things are boring. Here are the+boring things (except note the @GenStgRhs@), parameterised with respect to+binder and occurrence information (just as in @CoreSyn@):+-}++-- | A top-level binding.+data GenStgTopBinding pass+-- See Note [CoreSyn top-level string literals]+ = StgTopLifted (GenStgBinding pass)+ | StgTopStringLit Id ByteString++data GenStgBinding pass+ = StgNonRec (BinderP pass) (GenStgRhs pass)+ | StgRec [(BinderP pass, GenStgRhs pass)]++{-+************************************************************************+* *+StgArg+* *+************************************************************************+-}++data StgArg+ = StgVarArg Id+ | StgLitArg Literal++-- | Does this constructor application refer to anything in a different+-- *Windows* DLL?+-- If so, we can't allocate it statically+isDllConApp :: DynFlags -> Module -> DataCon -> [StgArg] -> Bool+isDllConApp dflags this_mod con args+ | platformOS (targetPlatform dflags) == OSMinGW32+ = isDllName dflags this_mod (dataConName con) || any is_dll_arg args+ | otherwise = False+ where+ -- NB: typePrimRep1 is legit because any free variables won't have+ -- unlifted type (there are no unlifted things at top level)+ is_dll_arg :: StgArg -> Bool+ is_dll_arg (StgVarArg v) = isAddrRep (typePrimRep1 (idType v))+ && isDllName dflags this_mod (idName v)+ is_dll_arg _ = False++-- True of machine addresses; these are the things that don't work across DLLs.+-- The key point here is that VoidRep comes out False, so that a top level+-- nullary GADT constructor is False for isDllConApp+--+-- data T a where+-- T1 :: T Int+--+-- gives+--+-- T1 :: forall a. (a~Int) -> T a+--+-- and hence the top-level binding+--+-- $WT1 :: T Int+-- $WT1 = T1 Int (Coercion (Refl Int))+--+-- The coercion argument here gets VoidRep+isAddrRep :: PrimRep -> Bool+isAddrRep AddrRep = True+isAddrRep LiftedRep = True+isAddrRep UnliftedRep = True+isAddrRep _ = False++-- | Type of an @StgArg@+--+-- Very half baked because we have lost the type arguments.+stgArgType :: StgArg -> Type+stgArgType (StgVarArg v) = idType v+stgArgType (StgLitArg lit) = literalType lit+++-- | Strip ticks of a given type from an STG expression.+stripStgTicksTop :: (Tickish Id -> Bool) -> GenStgExpr p -> ([Tickish Id], GenStgExpr p)+stripStgTicksTop p = go []+ where go ts (StgTick t e) | p t = go (t:ts) e+ go ts other = (reverse ts, other)++-- | Strip ticks of a given type from an STG expression returning only the expression.+stripStgTicksTopE :: (Tickish Id -> Bool) -> GenStgExpr p -> GenStgExpr p+stripStgTicksTopE p = go+ where go (StgTick t e) | p t = go e+ go other = other++-- | Given an alt type and whether the program is unarised, return whether the+-- case binder is in scope.+--+-- Case binders of unboxed tuple or unboxed sum type always dead after the+-- unariser has run. See Note [Post-unarisation invariants].+stgCaseBndrInScope :: AltType -> Bool {- ^ unarised? -} -> Bool+stgCaseBndrInScope alt_ty unarised =+ case alt_ty of+ AlgAlt _ -> True+ PrimAlt _ -> True+ MultiValAlt _ -> not unarised+ PolyAlt -> True++{-+************************************************************************+* *+STG expressions+* *+************************************************************************++The @GenStgExpr@ data type is parameterised on binder and occurrence info, as+before.++************************************************************************+* *+GenStgExpr+* *+************************************************************************++An application is of a function to a list of atoms (not expressions).+Operationally, we want to push the arguments on the stack and call the function.+(If the arguments were expressions, we would have to build their closures+first.)++There is no constructor for a lone variable; it would appear as @StgApp var []@.+-}++data GenStgExpr pass+ = StgApp+ Id -- function+ [StgArg] -- arguments; may be empty++{-+************************************************************************+* *+StgConApp and StgPrimApp --- saturated applications+* *+************************************************************************++There are specialised forms of application, for constructors, primitives, and+literals.+-}++ | StgLit Literal++ -- StgConApp is vital for returning unboxed tuples or sums+ -- which can't be let-bound+ | StgConApp DataCon+ [StgArg] -- Saturated+ [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise++ | StgOpApp StgOp -- Primitive op or foreign call+ [StgArg] -- Saturated.+ Type -- Result type+ -- We need to know this so that we can+ -- assign result registers++{-+************************************************************************+* *+StgLam+* *+************************************************************************++StgLam is used *only* during CoreToStg's work. Before CoreToStg has finished it+encodes (\x -> e) as (let f = \x -> e in f) TODO: Encode this via an extension+to GenStgExpr à la TTG.+-}++ | StgLam+ (NonEmpty (BinderP pass))+ StgExpr -- Body of lambda++{-+************************************************************************+* *+GenStgExpr: case-expressions+* *+************************************************************************++This has the same boxed/unboxed business as Core case expressions.+-}++ | StgCase+ (GenStgExpr pass) -- the thing to examine+ (BinderP pass) -- binds the result of evaluating the scrutinee+ AltType+ [GenStgAlt pass]+ -- The DEFAULT case is always *first*+ -- if it is there at all++{-+************************************************************************+* *+GenStgExpr: let(rec)-expressions+* *+************************************************************************++The various forms of let(rec)-expression encode most of the interesting things+we want to do.++- let-closure x = [free-vars] [args] expr in e++ is equivalent to++ let x = (\free-vars -> \args -> expr) free-vars++ @args@ may be empty (and is for most closures). It isn't under circumstances+ like this:++ let x = (\y -> y+z)++ This gets mangled to++ let-closure x = [z] [y] (y+z)++ The idea is that we compile code for @(y+z)@ in an environment in which @z@ is+ bound to an offset from Node, and `y` is bound to an offset from the stack+ pointer.++ (A let-closure is an @StgLet@ with a @StgRhsClosure@ RHS.)++- let-constructor x = Constructor [args] in e++ (A let-constructor is an @StgLet@ with a @StgRhsCon@ RHS.)++- Letrec-expressions are essentially the same deal as let-closure/+ let-constructor, so we use a common structure and distinguish between them+ with an @is_recursive@ boolean flag.++- let-unboxed u = <an arbitrary arithmetic expression in unboxed values> in e++ All the stuff on the RHS must be fully evaluated. No function calls either!++ (We've backed away from this toward case-expressions with suitably-magical+ alts ...)++- Advanced stuff here! Not to start with, but makes pattern matching generate+ more efficient code.++ let-escapes-not fail = expr+ in e'++ Here the idea is that @e'@ guarantees not to put @fail@ in a data structure,+ or pass it to another function. All @e'@ will ever do is tail-call @fail@.+ Rather than build a closure for @fail@, all we need do is to record the stack+ level at the moment of the @let-escapes-not@; then entering @fail@ is just a+ matter of adjusting the stack pointer back down to that point and entering the+ code for it.++ Another example:++ f x y = let z = huge-expression in+ if y==1 then z else+ if y==2 then z else+ 1++ (A let-escapes-not is an @StgLetNoEscape@.)++- We may eventually want:++ let-literal x = Literal in e++And so the code for let(rec)-things:+-}++ | StgLet+ (XLet pass)+ (GenStgBinding pass) -- right hand sides (see below)+ (GenStgExpr pass) -- body++ | StgLetNoEscape+ (XLetNoEscape pass)+ (GenStgBinding pass) -- right hand sides (see below)+ (GenStgExpr pass) -- body++{-+*************************************************************************+* *+GenStgExpr: hpc, scc and other debug annotations+* *+*************************************************************************++Finally for @hpc@ expressions we introduce a new STG construct.+-}++ | StgTick+ (Tickish Id)+ (GenStgExpr pass) -- sub expression++-- END of GenStgExpr++{-+************************************************************************+* *+STG right-hand sides+* *+************************************************************************++Here's the rest of the interesting stuff for @StgLet@s; the first flavour is for+closures:+-}++data GenStgRhs pass+ = StgRhsClosure+ (XRhsClosure pass) -- ^ Extension point for non-global free var+ -- list just before 'CodeGen'.+ CostCentreStack -- ^ CCS to be attached (default is CurrentCCS)+ !UpdateFlag -- ^ 'ReEntrant' | 'Updatable' | 'SingleEntry'+ [BinderP pass] -- ^ arguments; if empty, then not a function;+ -- as above, order is important.+ (GenStgExpr pass) -- ^ body++{-+An example may be in order. Consider:++ let t = \x -> \y -> ... x ... y ... p ... q in e++Pulling out the free vars and stylising somewhat, we get the equivalent:++ let t = (\[p,q] -> \[x,y] -> ... x ... y ... p ...q) p q++Stg-operationally, the @[x,y]@ are on the stack, the @[p,q]@ are offsets from+@Node@ into the closure, and the code ptr for the closure will be exactly that+in parentheses above.++The second flavour of right-hand-side is for constructors (simple but+important):+-}++ | StgRhsCon+ CostCentreStack -- CCS to be attached (default is CurrentCCS).+ -- Top-level (static) ones will end up with+ -- DontCareCCS, because we don't count static+ -- data in heap profiles, and we don't set CCCS+ -- from static closure.+ DataCon -- Constructor. Never an unboxed tuple or sum, as those+ -- are not allocated.+ [StgArg] -- Args++-- | Used as a data type index for the stgSyn AST+data StgPass+ = Vanilla+ | LiftLams+ | CodeGen++-- | Like 'GHC.Hs.Extension.NoExtField', but with an 'Outputable' instance that+-- returns 'empty'.+data NoExtFieldSilent = NoExtFieldSilent+ deriving (Data, Eq, Ord)++instance Outputable NoExtFieldSilent where+ ppr _ = empty++-- | Used when constructing a term with an unused extension point that should+-- not appear in pretty-printed output at all.+noExtFieldSilent :: NoExtFieldSilent+noExtFieldSilent = NoExtFieldSilent+-- TODO: Maybe move this to GHC.Hs.Extension? I'm not sure about the+-- implications on build time...++-- TODO: Do we really want to the extension point type families to have a closed+-- domain?+type family BinderP (pass :: StgPass)+type instance BinderP 'Vanilla = Id+type instance BinderP 'CodeGen = Id++type family XRhsClosure (pass :: StgPass)+type instance XRhsClosure 'Vanilla = NoExtFieldSilent+-- | Code gen needs to track non-global free vars+type instance XRhsClosure 'CodeGen = DIdSet++type family XLet (pass :: StgPass)+type instance XLet 'Vanilla = NoExtFieldSilent+type instance XLet 'CodeGen = NoExtFieldSilent++type family XLetNoEscape (pass :: StgPass)+type instance XLetNoEscape 'Vanilla = NoExtFieldSilent+type instance XLetNoEscape 'CodeGen = NoExtFieldSilent++stgRhsArity :: StgRhs -> Int+stgRhsArity (StgRhsClosure _ _ _ bndrs _)+ = ASSERT( all isId bndrs ) length bndrs+ -- The arity never includes type parameters, but they should have gone by now+stgRhsArity (StgRhsCon _ _ _) = 0++-- Note [CAF consistency]+-- ~~~~~~~~~~~~~~~~~~~~~~+--+-- `topStgBindHasCafRefs` is only used by an assert (`consistentCafInfo` in+-- `CoreToStg`) to make sure CAF-ness predicted by `GHC.Iface.Tidy` is consistent with+-- reality.+--+-- Specifically, if the RHS mentions any Id that itself is marked+-- `MayHaveCafRefs`; or if the binding is a top-level updateable thunk; then the+-- `Id` for the binding should be marked `MayHaveCafRefs`. The potential trouble+-- is that `GHC.Iface.Tidy` computed the CAF info on the `Id` but some transformations+-- have taken place since then.++topStgBindHasCafRefs :: GenStgTopBinding pass -> Bool+topStgBindHasCafRefs (StgTopLifted (StgNonRec _ rhs))+ = topRhsHasCafRefs rhs+topStgBindHasCafRefs (StgTopLifted (StgRec binds))+ = any topRhsHasCafRefs (map snd binds)+topStgBindHasCafRefs StgTopStringLit{}+ = False++topRhsHasCafRefs :: GenStgRhs pass -> Bool+topRhsHasCafRefs (StgRhsClosure _ _ upd _ body)+ = -- See Note [CAF consistency]+ isUpdatable upd || exprHasCafRefs body+topRhsHasCafRefs (StgRhsCon _ _ args)+ = any stgArgHasCafRefs args++exprHasCafRefs :: GenStgExpr pass -> Bool+exprHasCafRefs (StgApp f args)+ = stgIdHasCafRefs f || any stgArgHasCafRefs args+exprHasCafRefs StgLit{}+ = False+exprHasCafRefs (StgConApp _ args _)+ = any stgArgHasCafRefs args+exprHasCafRefs (StgOpApp _ args _)+ = any stgArgHasCafRefs args+exprHasCafRefs (StgLam _ body)+ = exprHasCafRefs body+exprHasCafRefs (StgCase scrt _ _ alts)+ = exprHasCafRefs scrt || any altHasCafRefs alts+exprHasCafRefs (StgLet _ bind body)+ = bindHasCafRefs bind || exprHasCafRefs body+exprHasCafRefs (StgLetNoEscape _ bind body)+ = bindHasCafRefs bind || exprHasCafRefs body+exprHasCafRefs (StgTick _ expr)+ = exprHasCafRefs expr++bindHasCafRefs :: GenStgBinding pass -> Bool+bindHasCafRefs (StgNonRec _ rhs)+ = rhsHasCafRefs rhs+bindHasCafRefs (StgRec binds)+ = any rhsHasCafRefs (map snd binds)++rhsHasCafRefs :: GenStgRhs pass -> Bool+rhsHasCafRefs (StgRhsClosure _ _ _ _ body)+ = exprHasCafRefs body+rhsHasCafRefs (StgRhsCon _ _ args)+ = any stgArgHasCafRefs args++altHasCafRefs :: GenStgAlt pass -> Bool+altHasCafRefs (_, _, rhs) = exprHasCafRefs rhs++stgArgHasCafRefs :: StgArg -> Bool+stgArgHasCafRefs (StgVarArg id)+ = stgIdHasCafRefs id+stgArgHasCafRefs _+ = False++stgIdHasCafRefs :: Id -> Bool+stgIdHasCafRefs id =+ -- We are looking for occurrences of an Id that is bound at top level, and may+ -- have CAF refs. At this point (after GHC.Iface.Tidy) top-level Ids (whether+ -- imported or defined in this module) are GlobalIds, so the test is easy.+ isGlobalId id && mayHaveCafRefs (idCafInfo id)++{-+************************************************************************+* *+STG case alternatives+* *+************************************************************************++Very like in @CoreSyntax@ (except no type-world stuff).++The type constructor is guaranteed not to be abstract; that is, we can see its+representation. This is important because the code generator uses it to+determine return conventions etc. But it's not trivial where there's a module+loop involved, because some versions of a type constructor might not have all+the constructors visible. So mkStgAlgAlts (in CoreToStg) ensures that it gets+the TyCon from the constructors or literals (which are guaranteed to have the+Real McCoy) rather than from the scrutinee type.+-}++type GenStgAlt pass+ = (AltCon, -- alts: data constructor,+ [BinderP pass], -- constructor's parameters,+ GenStgExpr pass) -- ...right-hand side.++data AltType+ = PolyAlt -- Polymorphic (a lifted type variable)+ | MultiValAlt Int -- Multi value of this arity (unboxed tuple or sum)+ -- the arity could indeed be 1 for unary unboxed tuple+ -- or enum-like unboxed sums+ | AlgAlt TyCon -- Algebraic data type; the AltCons will be DataAlts+ | PrimAlt PrimRep -- Primitive data type; the AltCons (if any) will be LitAlts++{-+************************************************************************+* *+The Plain STG parameterisation+* *+************************************************************************++This happens to be the only one we use at the moment.+-}++type StgTopBinding = GenStgTopBinding 'Vanilla+type StgBinding = GenStgBinding 'Vanilla+type StgExpr = GenStgExpr 'Vanilla+type StgRhs = GenStgRhs 'Vanilla+type StgAlt = GenStgAlt 'Vanilla++type LlStgTopBinding = GenStgTopBinding 'LiftLams+type LlStgBinding = GenStgBinding 'LiftLams+type LlStgExpr = GenStgExpr 'LiftLams+type LlStgRhs = GenStgRhs 'LiftLams+type LlStgAlt = GenStgAlt 'LiftLams++type CgStgTopBinding = GenStgTopBinding 'CodeGen+type CgStgBinding = GenStgBinding 'CodeGen+type CgStgExpr = GenStgExpr 'CodeGen+type CgStgRhs = GenStgRhs 'CodeGen+type CgStgAlt = GenStgAlt 'CodeGen++{- Many passes apply a substitution, and it's very handy to have type+ synonyms to remind us whether or not the substitution has been applied.+ See CoreSyn for precedence in Core land+-}++type InStgTopBinding = StgTopBinding+type InStgBinding = StgBinding+type InStgArg = StgArg+type InStgExpr = StgExpr+type InStgRhs = StgRhs+type InStgAlt = StgAlt+type OutStgTopBinding = StgTopBinding+type OutStgBinding = StgBinding+type OutStgArg = StgArg+type OutStgExpr = StgExpr+type OutStgRhs = StgRhs+type OutStgAlt = StgAlt++{-++************************************************************************+* *+UpdateFlag+* *+************************************************************************++This is also used in @LambdaFormInfo@ in the @ClosureInfo@ module.++A @ReEntrant@ closure may be entered multiple times, but should not be updated+or blackholed. An @Updatable@ closure should be updated after evaluation (and+may be blackholed during evaluation). A @SingleEntry@ closure will only be+entered once, and so need not be updated but may safely be blackholed.+-}++data UpdateFlag = ReEntrant | Updatable | SingleEntry++instance Outputable UpdateFlag where+ ppr u = char $ case u of+ ReEntrant -> 'r'+ Updatable -> 'u'+ SingleEntry -> 's'++isUpdatable :: UpdateFlag -> Bool+isUpdatable ReEntrant = False+isUpdatable SingleEntry = False+isUpdatable Updatable = True++{-+************************************************************************+* *+StgOp+* *+************************************************************************++An StgOp allows us to group together PrimOps and ForeignCalls. It's quite useful+to move these around together, notably in StgOpApp and COpStmt.+-}++data StgOp+ = StgPrimOp PrimOp++ | StgPrimCallOp PrimCall++ | StgFCallOp ForeignCall Type+ -- The Type, which is obtained from the foreign import declaration+ -- itself, is needed by the stg-to-cmm pass to determine the offset to+ -- apply to unlifted boxed arguments in GHC.StgToCmm.Foreign. See Note+ -- [Unlifted boxed arguments to foreign calls]++{-+************************************************************************+* *+Pretty-printing+* *+************************************************************************++Robin Popplestone asked for semi-colon separators on STG binds; here's hoping he+likes terminators instead... Ditto for case alternatives.+-}++type OutputablePass pass =+ ( Outputable (XLet pass)+ , Outputable (XLetNoEscape pass)+ , Outputable (XRhsClosure pass)+ , OutputableBndr (BinderP pass)+ )++pprGenStgTopBinding+ :: OutputablePass pass => GenStgTopBinding pass -> SDoc+pprGenStgTopBinding (StgTopStringLit bndr str)+ = hang (hsep [pprBndr LetBind bndr, equals])+ 4 (pprHsBytes str <> semi)+pprGenStgTopBinding (StgTopLifted bind)+ = pprGenStgBinding bind++pprGenStgBinding+ :: OutputablePass pass => GenStgBinding pass -> SDoc++pprGenStgBinding (StgNonRec bndr rhs)+ = hang (hsep [pprBndr LetBind bndr, equals])+ 4 (ppr rhs <> semi)++pprGenStgBinding (StgRec pairs)+ = vcat [ text "Rec {"+ , vcat (intersperse blankLine (map ppr_bind pairs))+ , text "end Rec }" ]+ where+ ppr_bind (bndr, expr)+ = hang (hsep [pprBndr LetBind bndr, equals])+ 4 (ppr expr <> semi)++pprGenStgTopBindings+ :: (OutputablePass pass) => [GenStgTopBinding pass] -> SDoc+pprGenStgTopBindings binds+ = vcat $ intersperse blankLine (map pprGenStgTopBinding binds)++pprStgBinding :: StgBinding -> SDoc+pprStgBinding = pprGenStgBinding++pprStgTopBindings :: [StgTopBinding] -> SDoc+pprStgTopBindings = pprGenStgTopBindings++instance Outputable StgArg where+ ppr = pprStgArg++instance OutputablePass pass => Outputable (GenStgTopBinding pass) where+ ppr = pprGenStgTopBinding++instance OutputablePass pass => Outputable (GenStgBinding pass) where+ ppr = pprGenStgBinding++instance OutputablePass pass => Outputable (GenStgExpr pass) where+ ppr = pprStgExpr++instance OutputablePass pass => Outputable (GenStgRhs pass) where+ ppr rhs = pprStgRhs rhs++pprStgArg :: StgArg -> SDoc+pprStgArg (StgVarArg var) = ppr var+pprStgArg (StgLitArg con) = ppr con++pprStgExpr :: OutputablePass pass => GenStgExpr pass -> SDoc+-- special case+pprStgExpr (StgLit lit) = ppr lit++-- general case+pprStgExpr (StgApp func args)+ = hang (ppr func) 4 (sep (map (ppr) args))++pprStgExpr (StgConApp con args _)+ = hsep [ ppr con, brackets (interppSP args) ]++pprStgExpr (StgOpApp op args _)+ = hsep [ pprStgOp op, brackets (interppSP args)]++pprStgExpr (StgLam bndrs body)+ = sep [ char '\\' <+> ppr_list (map (pprBndr LambdaBind) (toList bndrs))+ <+> text "->",+ pprStgExpr body ]+ where ppr_list = brackets . fsep . punctuate comma++-- special case: let v = <very specific thing>+-- in+-- let ...+-- in+-- ...+--+-- Very special! Suspicious! (SLPJ)++{-+pprStgExpr (StgLet srt (StgNonRec bndr (StgRhsClosure cc bi free_vars upd_flag args rhs))+ expr@(StgLet _ _))+ = ($$)+ (hang (hcat [text "let { ", ppr bndr, ptext (sLit " = "),+ ppr cc,+ pp_binder_info bi,+ text " [", whenPprDebug (interppSP free_vars), ptext (sLit "] \\"),+ ppr upd_flag, text " [",+ interppSP args, char ']'])+ 8 (sep [hsep [ppr rhs, text "} in"]]))+ (ppr expr)+-}++-- special case: let ... in let ...++pprStgExpr (StgLet ext bind expr@StgLet{})+ = ($$)+ (sep [hang (text "let" <+> ppr ext <+> text "{")+ 2 (hsep [pprGenStgBinding bind, text "} in"])])+ (ppr expr)++-- general case+pprStgExpr (StgLet ext bind expr)+ = sep [hang (text "let" <+> ppr ext <+> text "{") 2 (pprGenStgBinding bind),+ hang (text "} in ") 2 (ppr expr)]++pprStgExpr (StgLetNoEscape ext bind expr)+ = sep [hang (text "let-no-escape" <+> ppr ext <+> text "{")+ 2 (pprGenStgBinding bind),+ hang (text "} in ")+ 2 (ppr expr)]++pprStgExpr (StgTick tickish expr)+ = sdocWithDynFlags $ \dflags ->+ if gopt Opt_SuppressTicks dflags+ then pprStgExpr expr+ else sep [ ppr tickish, pprStgExpr expr ]+++-- Don't indent for a single case alternative.+pprStgExpr (StgCase expr bndr alt_type [alt])+ = sep [sep [text "case",+ nest 4 (hsep [pprStgExpr expr,+ whenPprDebug (dcolon <+> ppr alt_type)]),+ text "of", pprBndr CaseBind bndr, char '{'],+ pprStgAlt False alt,+ char '}']++pprStgExpr (StgCase expr bndr alt_type alts)+ = sep [sep [text "case",+ nest 4 (hsep [pprStgExpr expr,+ whenPprDebug (dcolon <+> ppr alt_type)]),+ text "of", pprBndr CaseBind bndr, char '{'],+ nest 2 (vcat (map (pprStgAlt True) alts)),+ char '}']+++pprStgAlt :: OutputablePass pass => Bool -> GenStgAlt pass -> SDoc+pprStgAlt indent (con, params, expr)+ | indent = hang altPattern 4 (ppr expr <> semi)+ | otherwise = sep [altPattern, ppr expr <> semi]+ where+ altPattern = (hsep [ppr con, sep (map (pprBndr CasePatBind) params), text "->"])+++pprStgOp :: StgOp -> SDoc+pprStgOp (StgPrimOp op) = ppr op+pprStgOp (StgPrimCallOp op)= ppr op+pprStgOp (StgFCallOp op _) = ppr op++instance Outputable AltType where+ ppr PolyAlt = text "Polymorphic"+ ppr (MultiValAlt n) = text "MultiAlt" <+> ppr n+ ppr (AlgAlt tc) = text "Alg" <+> ppr tc+ ppr (PrimAlt tc) = text "Prim" <+> ppr tc++pprStgRhs :: OutputablePass pass => GenStgRhs pass -> SDoc++pprStgRhs (StgRhsClosure ext cc upd_flag args body)+ = sdocWithDynFlags $ \dflags ->+ hang (hsep [if gopt Opt_SccProfilingOn dflags then ppr cc else empty,+ if not $ gopt Opt_SuppressStgExts dflags+ then ppr ext else empty,+ char '\\' <> ppr upd_flag, brackets (interppSP args)])+ 4 (ppr body)++pprStgRhs (StgRhsCon cc con args)+ = hcat [ ppr cc,+ space, ppr con, text "! ", brackets (interppSP args)]
compiler/backpack/BkpSyn.hs view
@@ -23,7 +23,7 @@ import SrcLoc import Outputable import Module-import PackageConfig+import UnitInfo {- ************************************************************************@@ -61,7 +61,7 @@ -- | A declaration in a package, e.g. a module or signature definition, -- or an include. data HsUnitDecl n- = DeclD HscSource (Located ModuleName) (Maybe (Located (HsModule GhcPs)))+ = DeclD HscSource (Located ModuleName) (Maybe (Located HsModule)) | IncludeD (IncludeDecl n) type LHsUnitDecl n = Located (HsUnitDecl n)
compiler/basicTypes/Avail.hs view
@@ -200,7 +200,7 @@ plusAvail :: AvailInfo -> AvailInfo -> AvailInfo plusAvail a1 a2 | debugIsOn && availName a1 /= availName a2- = pprPanic "RnEnv.plusAvail names differ" (hsep [ppr a1,ppr a2])+ = pprPanic "GHC.Rename.Env.plusAvail names differ" (hsep [ppr a1,ppr a2]) plusAvail a1@(Avail {}) (Avail {}) = a1 plusAvail (AvailTC _ [] []) a2@(AvailTC {}) = a2 plusAvail a1@(AvailTC {}) (AvailTC _ [] []) = a1@@ -218,7 +218,7 @@ = AvailTC n1 ss1 (fs1 `unionLists` fs2) plusAvail (AvailTC n1 [] fs1) (AvailTC _ ss2 fs2) = AvailTC n1 ss2 (fs1 `unionLists` fs2)-plusAvail a1 a2 = pprPanic "RnEnv.plusAvail" (hsep [ppr a1,ppr a2])+plusAvail a1 a2 = pprPanic "GHC.Rename.Env.plusAvail" (hsep [ppr a1,ppr a2]) -- | trims an 'AvailInfo' to keep only a single name trimAvail :: AvailInfo -> Name -> AvailInfo
compiler/basicTypes/BasicTypes.hs view
@@ -2,7 +2,7 @@ (c) The University of Glasgow 2006 (c) The GRASP/AQUA Project, Glasgow University, 1997-1998 -\section[BasicTypes]{Miscellanous types}+\section[BasicTypes]{Miscellaneous types} This module defines a miscellaneously collection of very simple types that@@ -15,6 +15,7 @@ -} {-# LANGUAGE DeriveDataTypeable #-}+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module BasicTypes( Version, bumpVersion, initialVersion,@@ -970,8 +971,8 @@ | NotInteresting deriving (Eq) --- | If there is any 'interesting' identifier occurance, then the--- aggregated occurance info of that identifier is considered interesting.+-- | If there is any 'interesting' identifier occurrence, then the+-- aggregated occurrence info of that identifier is considered interesting. instance Semi.Semigroup InterestingCxt where NotInteresting <> x = x IsInteresting <> _ = IsInteresting@@ -990,8 +991,8 @@ | NotInsideLam deriving (Eq) --- | If any occurance of an identifier is inside a lambda, then the--- occurance info of that identifier marks it as occuring inside a lambda+-- | If any occurrence of an identifier is inside a lambda, then the+-- occurrence info of that identifier marks it as occurring inside a lambda instance Semi.Semigroup InsideLam where NotInsideLam <> x = x IsInsideLam <> _ = IsInsideLam@@ -1003,7 +1004,7 @@ ----------------- data OneBranch = InOneBranch- -- ^ One syntactic occurance: Occurs in only one case branch+ -- ^ One syntactic occurrence: Occurs in only one case branch -- so no code-duplication issue to worry about | MultipleBranches deriving (Eq)
compiler/basicTypes/DataCon.hs view
@@ -366,7 +366,7 @@ dcExTyCoVars :: [TyCoVar], -- INVARIANT: the UnivTyVars and ExTyCoVars all have distinct OccNames- -- Reason: less confusing, and easier to generate IfaceSyn+ -- Reason: less confusing, and easier to generate Iface syntax -- The type/coercion vars in the order the user wrote them [c,y,x,b] -- INVARIANT: the set of tyvars in dcUserTyVarBinders is exactly the set
compiler/basicTypes/Demand.hs view
@@ -6,6 +6,7 @@ -} {-# LANGUAGE CPP, FlexibleInstances, TypeSynonymInstances, RecordWildCards #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Demand ( StrDmd, UseDmd(..), Count,@@ -526,7 +527,7 @@ point in w/w since the components of the pair are not used at all. So the solution is: don't aggressively collapse UProd [Used,Used] to-Used; intead leave it as-is. In effect we are using the UseDmd to do a+Used; instead leave it as-is. In effect we are using the UseDmd to do a little bit of boxity analysis. Not very nice. Note [Used should win]@@ -700,7 +701,7 @@ {- ************************************************************************ * *- Demand: combining stricness and usage+ Demand: Combining Strictness and Usage * * ************************************************************************ -}@@ -1089,7 +1090,7 @@ The CPR information, though, is valid after the number of arguments mentioned in the type is given. Therefore, when forgetting the demand on arguments, as in-dmdAnalRhs, this needs to be considere (via removeDmdTyArgs).+dmdAnalRhs, this needs to be considered (via removeDmdTyArgs). Consider b2 x y = x `seq` y `seq` error (show x)@@ -1128,7 +1129,7 @@ 3. combine the termination results, but 4. take CPR info from the first argument. -3 and 4 are implementd in bothDmdResult.+3 and 4 are implemented in bothDmdResult. -} -- Equality needed for fixpoints in DmdAnal@@ -1444,7 +1445,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If the variable is not mentioned in the environment of a demand type, its demand is taken to be a result demand of the type.- For the stricness component,+ For the strictness component, if the result demand is a Diverges, then we use HyperStr else we use Lazy For the usage component, we use Absent.
compiler/basicTypes/Id.hs view
@@ -387,7 +387,7 @@ In CoreTidy we must make all these LocalIds into GlobalIds, so that in importing modules (in --make mode) we treat them as properly global.-That is what is happening in, say tidy_insts in TidyPgm.+That is what is happening in, say tidy_insts in GHC.Iface.Tidy. ************************************************************************ * *
compiler/basicTypes/IdInfo.hs view
@@ -11,6 +11,8 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+ module IdInfo ( -- * The IdDetails type IdDetails(..), pprIdDetails, coVarDetails, isCoVarDetails,@@ -250,7 +252,7 @@ oneShotInfo :: OneShotInfo, -- ^ Info about a lambda-bound variable, if the 'Id' is one inlinePragInfo :: InlinePragma,- -- ^ Any inline pragma atached to the 'Id'+ -- ^ Any inline pragma attached to the 'Id' occInfo :: OccInfo, -- ^ How the 'Id' occurs in the program strictnessInfo :: StrictSig,@@ -409,7 +411,7 @@ a) they might be nested, in which case a global table won't work b) the RULE might mention free variables, which we use to keep things alive -In TidyPgm, when the LocalId becomes a GlobalId, its RULES are stripped off+In GHC.Iface.Tidy, when the LocalId becomes a GlobalId, its RULES are stripped off and put in the global list. -} @@ -425,7 +427,7 @@ -- ru_fn though. -- Note [Rule dependency info] in OccurAnal --- | Assume that no specilizations exist: always safe+-- | Assume that no specializations exist: always safe emptyRuleInfo :: RuleInfo emptyRuleInfo = RuleInfo [] emptyDVarSet
compiler/basicTypes/Literal.hs view
@@ -6,6 +6,7 @@ -} {-# LANGUAGE CPP, DeriveDataTypeable, ScopedTypeVariables #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Literal (@@ -177,14 +178,14 @@ They only get converted into real Core, mkInteger [c1, c2, .., cn]-during the CorePrep phase, although TidyPgm looks ahead at what the+during the CorePrep phase, although GHC.Iface.Tidy looks ahead at what the core will be, so that it can see whether it involves CAFs. When we initially build an Integer literal, notably when deserialising it from an interface file (see the Binary instance below), we don't have convenient access to the mkInteger Id. So we just use an error thunk, and fill in the real Id when we do tcIfaceLit-in TcIface.+in GHC.IfaceToCore. Note [Natural literals] ~~~~~~~~~~~~~~~~~~~~~~~@@ -831,7 +832,7 @@ * We define LitRubbish as a constructor in Literal.Literal -* It is given its polymoprhic type by Literal.literalType+* It is given its polymorphic type by Literal.literalType * WwLib.mk_absent_let introduces a LitRubbish for absent arguments of boxed, unlifted type.@@ -842,7 +843,7 @@ which the garbage collector can follow if it encounters it. We considered maintaining LitRubbish in STG, and lowering- it in the code genreators, but it seems simpler to do it+ it in the code generators, but it seems simpler to do it once and for all in CoreToSTG. In ByteCodeAsm we just lower it as a 0 literal, because
compiler/basicTypes/MkId.hs view
@@ -14,6 +14,8 @@ {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+ module MkId ( mkDictFunId, mkDictFunTy, mkDictSelId, mkDictSelRhs, @@ -362,8 +364,8 @@ as ephemeral as the newtype workers. In other words, give the wrappers compulsory unfoldings and no bindings. The compulsory unfolding is given in wrap_unf in mkDataConRep, and the lack of a binding happens in-TidyPgm.getTyConImplicitBinds, where we say that a newtype has no implicit-bindings.+GHC.Iface.Tidy.getTyConImplicitBinds, where we say that a newtype has no+implicit bindings. ************************************************************************ * *@@ -649,7 +651,7 @@ `setInlinePragInfo` wrap_prag `setUnfoldingInfo` wrap_unf `setStrictnessInfo` wrap_sig- -- We need to get the CAF info right here because TidyPgm+ -- We need to get the CAF info right here because GHC.Iface.Tidy -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane `setLevityInfoWithType` wrap_ty@@ -1178,7 +1180,7 @@ -- When unwrapping, we do *not* apply any family coercion, because this will -- be done via a CoPat by the type checker. We have to do it this way as -- computing the right type arguments for the coercion requires more than just--- a spliting operation (cf, TcPat.tcConPat).+-- a splitting operation (cf, TcPat.tcConPat). unwrapNewTypeBody :: TyCon -> [Type] -> CoreExpr -> CoreExpr unwrapNewTypeBody tycon args result_expr@@ -1496,7 +1498,7 @@ ~~~~~~~~~~~~~~~~~~ 'GHC.Prim.seq' is special in several ways. -a) Its fixity is set in LoadIface.ghcPrimIface+a) Its fixity is set in GHC.Iface.Load.ghcPrimIface b) It has quite a bit of desugaring magic. See DsUtils.hs Note [Desugaring seq (1)] and (2) and (3)@@ -1601,7 +1603,7 @@ 'noinline' needs to be wired-in because it gets inserted automatically when we serialize an expression to the interface format. See-Note [Inlining and hs-boot files] in ToIface+Note [Inlining and hs-boot files] in GHC.CoreToIface Note that noinline as currently implemented can hide some simplifications since it hides strictness from the demand analyser. Specifically, the demand analyser
compiler/basicTypes/Module.hs view
@@ -170,7 +170,7 @@ import System.FilePath import {-# SOURCE #-} DynFlags (DynFlags)-import {-# SOURCE #-} Packages (componentIdString, improveUnitId, PackageConfigMap, getPackageConfigMap, displayInstalledUnitId)+import {-# SOURCE #-} Packages (componentIdString, improveUnitId, UnitInfoMap, getUnitInfoMap, displayInstalledUnitId) -- Note [The identifier lexicon] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -642,7 +642,7 @@ -- p[H=impl:H]. If we *only* wrap in p[H=impl:H] -- IndefiniteUnitId, they won't compare equal; only -- after improvement will the equality hold.- improveUnitId (getPackageConfigMap dflags) $+ improveUnitId (getUnitInfoMap dflags) $ IndefiniteUnitId iuid data IndefModule = IndefModule {@@ -943,18 +943,18 @@ -- @p[A=<A>]:B@ maps to @p[A=q():A]:B@ with @A=q():A@; -- similarly, @<A>@ maps to @q():A@. renameHoleModule :: DynFlags -> ShHoleSubst -> Module -> Module-renameHoleModule dflags = renameHoleModule' (getPackageConfigMap dflags)+renameHoleModule dflags = renameHoleModule' (getUnitInfoMap dflags) -- | Substitutes holes in a 'UnitId', suitable for renaming when -- an include occurs; see Note [Representation of module/name variable]. -- -- @p[A=<A>]@ maps to @p[A=<B>]@ with @A=<B>@. renameHoleUnitId :: DynFlags -> ShHoleSubst -> UnitId -> UnitId-renameHoleUnitId dflags = renameHoleUnitId' (getPackageConfigMap dflags)+renameHoleUnitId dflags = renameHoleUnitId' (getUnitInfoMap dflags) --- | Like 'renameHoleModule', but requires only 'PackageConfigMap'+-- | Like 'renameHoleModule', but requires only 'UnitInfoMap' -- so it can be used by "Packages".-renameHoleModule' :: PackageConfigMap -> ShHoleSubst -> Module -> Module+renameHoleModule' :: UnitInfoMap -> ShHoleSubst -> Module -> Module renameHoleModule' pkg_map env m | not (isHoleModule m) = let uid = renameHoleUnitId' pkg_map env (moduleUnitId m)@@ -963,9 +963,9 @@ -- NB m = <Blah>, that's what's in scope. | otherwise = m --- | Like 'renameHoleUnitId, but requires only 'PackageConfigMap'+-- | Like 'renameHoleUnitId, but requires only 'UnitInfoMap' -- so it can be used by "Packages".-renameHoleUnitId' :: PackageConfigMap -> ShHoleSubst -> UnitId -> UnitId+renameHoleUnitId' :: UnitInfoMap -> ShHoleSubst -> UnitId -> UnitId renameHoleUnitId' pkg_map env uid = case uid of (IndefiniteUnitId@@ -975,7 +975,7 @@ -> if isNullUFM (intersectUFM_C const (udfmToUfm (getUniqDSet fh)) env) then uid -- Functorially apply the substitution to the instantiation,- -- then check the 'PackageConfigMap' to see if there is+ -- then check the 'UnitInfoMap' to see if there is -- a compiled version of this 'UnitId' we can improve to. -- See Note [UnitId to InstalledUnitId] improvement else improveUnitId pkg_map $@@ -1068,7 +1068,7 @@ However, for each invocation of GHC, only a single instance of each wired-in package will be recognised (the desired one is selected via-@-package@\/@-hide-package@), and GHC will internall pretend that it has the+@-package@\/@-hide-package@), and GHC will internally pretend that it has the *unversioned* 'UnitId', including in .hi files and object file symbols. Unselected versions of wired-in packages will be ignored, as will any other
compiler/basicTypes/Name.hs view
@@ -162,7 +162,7 @@ 2. In any invocation of GHC, an External Name for "M.x" has one and only one unique. This unique association is ensured via the Name Cache;- see Note [The Name Cache] in IfaceEnv.+ see Note [The Name Cache] in GHC.Iface.Env. 3. Things with a External name are given C static labels, so they finally appear in the .o file's symbol table. They appear in the symbol table@@ -367,7 +367,7 @@ -- | Create a name which definitely originates in the given module mkExternalName :: Unique -> Module -> OccName -> SrcSpan -> Name -- WATCH OUT! External Names should be in the Name Cache--- (see Note [The Name Cache] in IfaceEnv), so don't just call mkExternalName+-- (see Note [The Name Cache] in GHC.Iface.Env), so don't just call mkExternalName -- with some fresh unique without populating the Name Cache mkExternalName uniq mod occ loc = Name { n_uniq = uniq, n_sort = External mod,@@ -502,8 +502,9 @@ -} -- | Assumes that the 'Name' is a non-binding one. See--- 'IfaceSyn.putIfaceTopBndr' and 'IfaceSyn.getIfaceTopBndr' for serializing--- binding 'Name's. See 'UserData' for the rationale for this distinction.+-- 'GHC.Iface.Syntax.putIfaceTopBndr' and 'GHC.Iface.Syntax.getIfaceTopBndr' for+-- serializing binding 'Name's. See 'UserData' for the rationale for this+-- distinction. instance Binary Name where put_ bh name = case getUserData bh of
compiler/basicTypes/NameCache.hs view
@@ -51,7 +51,7 @@ Namely these names are encoded as by their Uniques. We know how to get from a Unique back to the Name which it represents via the mapping defined in the SumTupleUniques module. See Note [Symbol table representation of names]- in BinIface and for details.+ in GHC.Iface.Binary and for details. b. We don't include them in the Orig name cache but instead parse their OccNames (in isBuiltInOcc_maybe) to avoid bloating the name cache with
compiler/basicTypes/OccName.hs view
@@ -94,7 +94,7 @@ -- * Tidying up TidyOccEnv, emptyTidyOccEnv, initTidyOccEnv,- tidyOccName, avoidClashesOccEnv,+ tidyOccName, avoidClashesOccEnv, delTidyOccEnvList, -- FsEnv FastStringEnv, emptyFsEnv, lookupFsEnv, extendFsEnv, mkFsEnv@@ -207,7 +207,7 @@ -- demoteNameSpace lowers the NameSpace if possible. We can not know -- in advance, since a TvName can appear in an HsTyVar.--- See Note [Demotion] in RnEnv+-- See Note [Demotion] in GHC.Rename.Env demoteNameSpace :: NameSpace -> Maybe NameSpace demoteNameSpace VarName = Nothing demoteNameSpace DataName = Nothing@@ -582,7 +582,7 @@ mkOccNameFS occ_sp (concatFS $ sys_prefix : str) isDerivedOccName :: OccName -> Bool--- ^ Test for definitions internally generated by GHC. This predicte+-- ^ Test for definitions internally generated by GHC. This predicate -- is used to suppress printing of internal definitions in some debug prints isDerivedOccName occ = case occNameString occ of@@ -818,7 +818,7 @@ (id,id,id) :: (a2 -> a2, a1 -> a1, a -> a) -which is a bit unfortunate, as it unfairly renames only one of them. What we+which is a bit unfortunate, as it unfairly renames only two of them. What we would like to see is (id,id,id) :: (a3 -> a3, a2 -> a2, a1 -> a1)@@ -846,6 +846,9 @@ where add env (OccName _ fs) = addToUFM env fs 1 +delTidyOccEnvList :: TidyOccEnv -> [FastString] -> TidyOccEnv+delTidyOccEnvList = delListFromUFM+ -- see Note [Tidying multiple names at once] avoidClashesOccEnv :: TidyOccEnv -> [OccName] -> TidyOccEnv avoidClashesOccEnv env occs = go env emptyUFM occs@@ -893,7 +896,7 @@ ************************************************************************ * * Binary instance- Here rather than BinIface because OccName is abstract+ Here rather than in GHC.Iface.Binary because OccName is abstract * * ************************************************************************ -}
compiler/basicTypes/RdrName.hs view
@@ -24,7 +24,7 @@ module RdrName ( -- * The main type- RdrName(..), -- Constructors exported only to BinIface+ RdrName(..), -- Constructors exported only to GHC.Iface.Binary -- ** Construction mkRdrUnqual, mkRdrQual,@@ -280,7 +280,7 @@ instance OutputableBndr RdrName where pprBndr _ n- | isTvOcc (rdrNameOcc n) = char '@' <+> ppr n+ | isTvOcc (rdrNameOcc n) = char '@' <> ppr n | otherwise = ppr n pprInfixOcc rdr = pprInfixVar (isSymOcc (rdrNameOcc rdr)) (ppr rdr)@@ -344,7 +344,7 @@ -- (@let@, @where@, lambda, @case@). -- It is keyed by OccName, because we never use it for qualified names -- We keep the current mapping, *and* the set of all Names in scope--- Reason: see Note [Splicing Exact names] in RnEnv+-- Reason: see Note [Splicing Exact names] in GHC.Rename.Env data LocalRdrEnv = LRE { lre_env :: OccEnv Name , lre_in_scope :: NameSet } @@ -416,7 +416,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ With Template Haskell we can make local bindings that have Exact Names. Computing shadowing etc may use elemLocalRdrEnv (at least it certainly-does so in RnTpes.bindHsQTyVars), so for an Exact Name we must consult+does so in GHC.Rename.Types.bindHsQTyVars), so for an Exact Name we must consult the in-scope-name-set. @@ -444,7 +444,7 @@ -- INVARIANT 2: Imported provenance => Name is an ExternalName -- However LocalDefs can have an InternalName. This -- happens only when type-checking a [d| ... |] Template--- Haskell quotation; see this note in RnNames+-- Haskell quotation; see this note in GHC.Rename.Names -- Note [Top-level Names in Template Haskell decl quotes] -- -- INVARIANT 3: If the GlobalRdrEnv maps [occ -> gre], then@@ -452,7 +452,7 @@ -- -- NB: greOccName gre is usually the same as -- nameOccName (gre_name gre), but not always in the--- case of record seectors; see greOccName+-- case of record selectors; see greOccName -- | Global Reader Element --@@ -509,7 +509,7 @@ It is just possible to have *both* if there is a module loop: a Name is defined locally in A, and also brought into scope by importing a-module that SOURCE-imported A. Exapmle (#7672):+module that SOURCE-imported A. Example (#7672): A.hs-boot module A where data T@@ -928,7 +928,7 @@ -- it is in scope qualified an unqualified respectively -- -- Used only for the 'module M' item in export list;--- see RnNames.exports_from_avail+-- see GHC.Rename.Names.exports_from_avail pickGREsModExp mod gres = mapMaybe (pickBothGRE mod) gres pickBothGRE :: ModuleName -> GlobalRdrElt -> Maybe (GlobalRdrElt, GlobalRdrElt)@@ -1039,7 +1039,7 @@ 'T' to mean the newly-declared 'T', not an old one. * Nested Template Haskell declaration brackets- See Note [Top-level Names in Template Haskell decl quotes] in RnNames+ See Note [Top-level Names in Template Haskell decl quotes] in GHC.Rename.Names Consider a TH decl quote: module M where@@ -1234,7 +1234,7 @@ 3. After processing all the RdrNames, bleat about any import-items that are unused.- This is done in RnNames.warnUnusedImportDecls.+ This is done in GHC.Rename.Names.warnUnusedImportDecls. The function 'bestImport' returns the dominant import among the ImportSpecs it is given, implementing Step 2. We say import-item A
compiler/basicTypes/Unique.hs view
@@ -31,7 +31,7 @@ mkUniqueGrimily, -- Used in UniqSupply only! getKey, -- Used in Var, UniqFM, Name only!- mkUnique, unpkUnique, -- Used in BinIface only+ mkUnique, unpkUnique, -- Used in GHC.Iface.Binary only eqUnique, ltUnique, incrUnique, @@ -178,7 +178,7 @@ -- | The interface file symbol-table encoding assumes that known-key uniques fit -- in 30-bits; verify this. ----- See Note [Symbol table representation of names] in BinIface for details.+-- See Note [Symbol table representation of names] in GHC.Iface.Binary for details. isValidKnownKeyUnique :: Unique -> Bool isValidKnownKeyUnique u = case unpkUnique u of@@ -276,7 +276,7 @@ is controlled. See Module.ModuleEnv 3) Change the algorithm to use nonDetCmpUnique and document why it's still deterministic- 4) Use TrieMap as done in CmmCommonBlockElim.groupByLabel+ 4) Use TrieMap as done in GHC.Cmm.CommonBlockElim.groupByLabel -} instance Eq Unique where
compiler/basicTypes/Var.hs view
@@ -6,6 +6,8 @@ -} {-# LANGUAGE CPP, FlexibleContexts, MultiWayIf, FlexibleInstances, DeriveDataTypeable #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} -- | -- #name_types#
compiler/basicTypes/VarEnv.hs view
@@ -71,13 +71,14 @@ -- * TidyEnv and its operation TidyEnv,- emptyTidyEnv, mkEmptyTidyEnv+ emptyTidyEnv, mkEmptyTidyEnv, delTidyEnvList ) where import GhcPrelude import qualified Data.IntMap.Strict as IntMap -- TODO: Move this to UniqFM import OccName+import Name import Var import VarSet import UniqSet@@ -423,6 +424,12 @@ mkEmptyTidyEnv :: TidyOccEnv -> TidyEnv mkEmptyTidyEnv occ_env = (occ_env, emptyVarEnv)++delTidyEnvList :: TidyEnv -> [Var] -> TidyEnv+delTidyEnvList (occ_env, var_env) vs = (occ_env', var_env')+ where+ occ_env' = occ_env `delTidyOccEnvList` map (occNameFS . getOccName) vs+ var_env' = var_env `delVarEnvList` vs {- ************************************************************************
compiler/basicTypes/VarSet.hs view
@@ -319,7 +319,7 @@ extendDVarSetList :: DVarSet -> [Var] -> DVarSet extendDVarSetList = addListToUniqDSet --- | Convert a DVarSet to a VarSet by forgeting the order of insertion+-- | Convert a DVarSet to a VarSet by forgetting the order of insertion dVarSetToVarSet :: DVarSet -> VarSet dVarSetToVarSet = unsafeUFMToUniqSet . udfmToUfm . getUniqDSet
− compiler/cmm/CmmType.hs
@@ -1,439 +0,0 @@-module CmmType- ( CmmType -- Abstract- , b8, b16, b32, b64, b128, b256, b512, f32, f64, bWord, bHalfWord, gcWord- , cInt- , cmmBits, cmmFloat- , typeWidth, cmmEqType, cmmEqType_ignoring_ptrhood- , isFloatType, isGcPtrType, isBitsType- , isWord32, isWord64, isFloat64, isFloat32-- , Width(..)- , widthInBits, widthInBytes, widthInLog, widthFromBytes- , wordWidth, halfWordWidth, cIntWidth- , halfWordMask- , narrowU, narrowS- , rEP_CostCentreStack_mem_alloc- , rEP_CostCentreStack_scc_count- , rEP_StgEntCounter_allocs- , rEP_StgEntCounter_allocd-- , ForeignHint(..)-- , Length- , vec, vec2, vec4, vec8, vec16- , vec2f64, vec2b64, vec4f32, vec4b32, vec8b16, vec16b8- , cmmVec- , vecLength, vecElemType- , isVecType- )-where---import GhcPrelude--import DynFlags-import FastString-import Outputable--import Data.Word-import Data.Int---------------------------------------------------------------------------------- CmmType-------------------------------------------------------------------------------- -- NOTE: CmmType is an abstract type, not exported from this- -- module so you can easily change its representation- --- -- However Width is exported in a concrete way,- -- and is used extensively in pattern-matching--data CmmType -- The important one!- = CmmType CmmCat Width--data CmmCat -- "Category" (not exported)- = GcPtrCat -- GC pointer- | BitsCat -- Non-pointer- | FloatCat -- Float- | VecCat Length CmmCat -- Vector- deriving( Eq )- -- See Note [Signed vs unsigned] at the end--instance Outputable CmmType where- ppr (CmmType cat wid) = ppr cat <> ppr (widthInBits wid)--instance Outputable CmmCat where- ppr FloatCat = text "F"- ppr GcPtrCat = text "P"- ppr BitsCat = text "I"- ppr (VecCat n cat) = ppr cat <> text "x" <> ppr n <> text "V"---- Why is CmmType stratified? For native code generation,--- most of the time you just want to know what sort of register--- to put the thing in, and for this you need to know how--- many bits thing has, and whether it goes in a floating-point--- register. By contrast, the distinction between GcPtr and--- GcNonPtr is of interest to only a few parts of the code generator.---------- Equality on CmmType ----------------- CmmType is *not* an instance of Eq; sometimes we care about the--- Gc/NonGc distinction, and sometimes we don't--- So we use an explicit function to force you to think about it-cmmEqType :: CmmType -> CmmType -> Bool -- Exact equality-cmmEqType (CmmType c1 w1) (CmmType c2 w2) = c1==c2 && w1==w2--cmmEqType_ignoring_ptrhood :: CmmType -> CmmType -> Bool- -- This equality is temporary; used in CmmLint- -- but the RTS files are not yet well-typed wrt pointers-cmmEqType_ignoring_ptrhood (CmmType c1 w1) (CmmType c2 w2)- = c1 `weak_eq` c2 && w1==w2- where- weak_eq :: CmmCat -> CmmCat -> Bool- FloatCat `weak_eq` FloatCat = True- FloatCat `weak_eq` _other = False- _other `weak_eq` FloatCat = False- (VecCat l1 cat1) `weak_eq` (VecCat l2 cat2) = l1 == l2- && cat1 `weak_eq` cat2- (VecCat {}) `weak_eq` _other = False- _other `weak_eq` (VecCat {}) = False- _word1 `weak_eq` _word2 = True -- Ignores GcPtr----- Simple operations on CmmType ------typeWidth :: CmmType -> Width-typeWidth (CmmType _ w) = w--cmmBits, cmmFloat :: Width -> CmmType-cmmBits = CmmType BitsCat-cmmFloat = CmmType FloatCat---------- Common CmmTypes --------------- Floats and words of specific widths-b8, b16, b32, b64, b128, b256, b512, f32, f64 :: CmmType-b8 = cmmBits W8-b16 = cmmBits W16-b32 = cmmBits W32-b64 = cmmBits W64-b128 = cmmBits W128-b256 = cmmBits W256-b512 = cmmBits W512-f32 = cmmFloat W32-f64 = cmmFloat W64---- CmmTypes of native word widths-bWord :: DynFlags -> CmmType-bWord dflags = cmmBits (wordWidth dflags)--bHalfWord :: DynFlags -> CmmType-bHalfWord dflags = cmmBits (halfWordWidth dflags)--gcWord :: DynFlags -> CmmType-gcWord dflags = CmmType GcPtrCat (wordWidth dflags)--cInt :: DynFlags -> CmmType-cInt dflags = cmmBits (cIntWidth dflags)-------------- Predicates -----------------isFloatType, isGcPtrType, isBitsType :: CmmType -> Bool-isFloatType (CmmType FloatCat _) = True-isFloatType _other = False--isGcPtrType (CmmType GcPtrCat _) = True-isGcPtrType _other = False--isBitsType (CmmType BitsCat _) = True-isBitsType _ = False--isWord32, isWord64, isFloat32, isFloat64 :: CmmType -> Bool--- isWord64 is true of 64-bit non-floats (both gc-ptrs and otherwise)--- isFloat32 and 64 are obvious--isWord64 (CmmType BitsCat W64) = True-isWord64 (CmmType GcPtrCat W64) = True-isWord64 _other = False--isWord32 (CmmType BitsCat W32) = True-isWord32 (CmmType GcPtrCat W32) = True-isWord32 _other = False--isFloat32 (CmmType FloatCat W32) = True-isFloat32 _other = False--isFloat64 (CmmType FloatCat W64) = True-isFloat64 _other = False---------------------------------------------------------------------------------- Width--------------------------------------------------------------------------------data Width = W8 | W16 | W32 | W64- | W128- | W256- | W512- deriving (Eq, Ord, Show)--instance Outputable Width where- ppr rep = ptext (mrStr rep)--mrStr :: Width -> PtrString-mrStr W8 = sLit("W8")-mrStr W16 = sLit("W16")-mrStr W32 = sLit("W32")-mrStr W64 = sLit("W64")-mrStr W128 = sLit("W128")-mrStr W256 = sLit("W256")-mrStr W512 = sLit("W512")------------ Common Widths -------------wordWidth :: DynFlags -> Width-wordWidth dflags- | wORD_SIZE dflags == 4 = W32- | wORD_SIZE dflags == 8 = W64- | otherwise = panic "MachOp.wordRep: Unknown word size"--halfWordWidth :: DynFlags -> Width-halfWordWidth dflags- | wORD_SIZE dflags == 4 = W16- | wORD_SIZE dflags == 8 = W32- | otherwise = panic "MachOp.halfWordRep: Unknown word size"--halfWordMask :: DynFlags -> Integer-halfWordMask dflags- | wORD_SIZE dflags == 4 = 0xFFFF- | wORD_SIZE dflags == 8 = 0xFFFFFFFF- | otherwise = panic "MachOp.halfWordMask: Unknown word size"---- cIntRep is the Width for a C-language 'int'-cIntWidth :: DynFlags -> Width-cIntWidth dflags = case cINT_SIZE dflags of- 4 -> W32- 8 -> W64- s -> panic ("cIntWidth: Unknown cINT_SIZE: " ++ show s)--widthInBits :: Width -> Int-widthInBits W8 = 8-widthInBits W16 = 16-widthInBits W32 = 32-widthInBits W64 = 64-widthInBits W128 = 128-widthInBits W256 = 256-widthInBits W512 = 512---widthInBytes :: Width -> Int-widthInBytes W8 = 1-widthInBytes W16 = 2-widthInBytes W32 = 4-widthInBytes W64 = 8-widthInBytes W128 = 16-widthInBytes W256 = 32-widthInBytes W512 = 64---widthFromBytes :: Int -> Width-widthFromBytes 1 = W8-widthFromBytes 2 = W16-widthFromBytes 4 = W32-widthFromBytes 8 = W64-widthFromBytes 16 = W128-widthFromBytes 32 = W256-widthFromBytes 64 = W512--widthFromBytes n = pprPanic "no width for given number of bytes" (ppr n)---- log_2 of the width in bytes, useful for generating shifts.-widthInLog :: Width -> Int-widthInLog W8 = 0-widthInLog W16 = 1-widthInLog W32 = 2-widthInLog W64 = 3-widthInLog W128 = 4-widthInLog W256 = 5-widthInLog W512 = 6----- widening / narrowing--narrowU :: Width -> Integer -> Integer-narrowU W8 x = fromIntegral (fromIntegral x :: Word8)-narrowU W16 x = fromIntegral (fromIntegral x :: Word16)-narrowU W32 x = fromIntegral (fromIntegral x :: Word32)-narrowU W64 x = fromIntegral (fromIntegral x :: Word64)-narrowU _ _ = panic "narrowTo"--narrowS :: Width -> Integer -> Integer-narrowS W8 x = fromIntegral (fromIntegral x :: Int8)-narrowS W16 x = fromIntegral (fromIntegral x :: Int16)-narrowS W32 x = fromIntegral (fromIntegral x :: Int32)-narrowS W64 x = fromIntegral (fromIntegral x :: Int64)-narrowS _ _ = panic "narrowTo"---------------------------------------------------------------------------------- SIMD--------------------------------------------------------------------------------type Length = Int--vec :: Length -> CmmType -> CmmType-vec l (CmmType cat w) = CmmType (VecCat l cat) vecw- where- vecw :: Width- vecw = widthFromBytes (l*widthInBytes w)--vec2, vec4, vec8, vec16 :: CmmType -> CmmType-vec2 = vec 2-vec4 = vec 4-vec8 = vec 8-vec16 = vec 16--vec2f64, vec2b64, vec4f32, vec4b32, vec8b16, vec16b8 :: CmmType-vec2f64 = vec 2 f64-vec2b64 = vec 2 b64-vec4f32 = vec 4 f32-vec4b32 = vec 4 b32-vec8b16 = vec 8 b16-vec16b8 = vec 16 b8--cmmVec :: Int -> CmmType -> CmmType-cmmVec n (CmmType cat w) =- CmmType (VecCat n cat) (widthFromBytes (n*widthInBytes w))--vecLength :: CmmType -> Length-vecLength (CmmType (VecCat l _) _) = l-vecLength _ = panic "vecLength: not a vector"--vecElemType :: CmmType -> CmmType-vecElemType (CmmType (VecCat l cat) w) = CmmType cat scalw- where- scalw :: Width- scalw = widthFromBytes (widthInBytes w `div` l)-vecElemType _ = panic "vecElemType: not a vector"--isVecType :: CmmType -> Bool-isVecType (CmmType (VecCat {}) _) = True-isVecType _ = False------------------------------------------------------------------------------ Hints---- Hints are extra type information we attach to the arguments and--- results of a foreign call, where more type information is sometimes--- needed by the ABI to make the correct kind of call.--data ForeignHint- = NoHint | AddrHint | SignedHint- deriving( Eq )- -- Used to give extra per-argument or per-result- -- information needed by foreign calling conventions------------------------------------------------------------------------------- These don't really belong here, but I don't know where is best to--- put them.--rEP_CostCentreStack_mem_alloc :: DynFlags -> CmmType-rEP_CostCentreStack_mem_alloc dflags- = cmmBits (widthFromBytes (pc_REP_CostCentreStack_mem_alloc pc))- where pc = platformConstants dflags--rEP_CostCentreStack_scc_count :: DynFlags -> CmmType-rEP_CostCentreStack_scc_count dflags- = cmmBits (widthFromBytes (pc_REP_CostCentreStack_scc_count pc))- where pc = platformConstants dflags--rEP_StgEntCounter_allocs :: DynFlags -> CmmType-rEP_StgEntCounter_allocs dflags- = cmmBits (widthFromBytes (pc_REP_StgEntCounter_allocs pc))- where pc = platformConstants dflags--rEP_StgEntCounter_allocd :: DynFlags -> CmmType-rEP_StgEntCounter_allocd dflags- = cmmBits (widthFromBytes (pc_REP_StgEntCounter_allocd pc))- where pc = platformConstants dflags----------------------------------------------------------------------------{- Note [Signed vs unsigned]- ~~~~~~~~~~~~~~~~~~~~~~~~~-Should a CmmType include a signed vs. unsigned distinction?--This is very much like a "hint" in C-- terminology: it isn't necessary-in order to generate correct code, but it might be useful in that the-compiler can generate better code if it has access to higher-level-hints about data. This is important at call boundaries, because the-definition of a function is not visible at all of its call sites, so-the compiler cannot infer the hints.--Here in Cmm, we're taking a slightly different approach. We include-the int vs. float hint in the CmmType, because (a) the majority of-platforms have a strong distinction between float and int registers,-and (b) we don't want to do any heavyweight hint-inference in the-native code backend in order to get good code. We're treating the-hint more like a type: our Cmm is always completely consistent with-respect to hints. All coercions between float and int are explicit.--What about the signed vs. unsigned hint? This information might be-useful if we want to keep sub-word-sized values in word-size-registers, which we must do if we only have word-sized registers.--On such a system, there are two straightforward conventions for-representing sub-word-sized values:--(a) Leave the upper bits undefined. Comparison operations must- sign- or zero-extend both operands before comparing them,- depending on whether the comparison is signed or unsigned.--(b) Always keep the values sign- or zero-extended as appropriate.- Arithmetic operations must narrow the result to the appropriate- size.--A clever compiler might not use either (a) or (b) exclusively, instead-it would attempt to minimize the coercions by analysis: the same kind-of analysis that propagates hints around. In Cmm we don't want to-have to do this, so we plump for having richer types and keeping the-type information consistent.--If signed/unsigned hints are missing from CmmType, then the only-choice we have is (a), because we don't know whether the result of an-operation should be sign- or zero-extended.--Many architectures have extending load operations, which work well-with (b). To make use of them with (a), you need to know whether the-value is going to be sign- or zero-extended by an enclosing comparison-(for example), which involves knowing above the context. This is-doable but more complex.--Further complicating the issue is foreign calls: a foreign calling-convention can specify that signed 8-bit quantities are passed as-sign-extended 32 bit quantities, for example (this is the case on the-PowerPC). So we *do* need sign information on foreign call arguments.--Pros for adding signed vs. unsigned to CmmType:-- - It would let us use convention (b) above, and get easier- code generation for extending loads.-- - Less information required on foreign calls.-- - MachOp type would be simpler--Cons:-- - More complexity-- - What is the CmmType for a VanillaReg? Currently it is- always wordRep, but now we have to decide whether it is- signed or unsigned. The same VanillaReg can thus have- different CmmType in different parts of the program.-- - Extra coercions cluttering up expressions.--Currently for GHC, the foreign call point is moot, because we do our-own promotion of sub-word-sized values to word-sized values. The Int8-type is represented by an Int# which is kept sign-extended at all times-(this is slightly naughty, because we're making assumptions about the-C calling convention rather early on in the compiler). However, given-this, the cons outweigh the pros.---}-
compiler/coreSyn/CoreArity.hs view
@@ -8,6 +8,8 @@ {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+ -- | Arity and eta expansion module CoreArity ( manifestArity, joinRhsArity, exprArity, typeArity,@@ -174,13 +176,13 @@ can get "n" manifest lambdas to the top. Why is this important? Because- - In TidyPgm we use exprArity to fix the *final arity* of+ - In GHC.Iface.Tidy we use exprArity to fix the *final arity* of each top-level Id, and in - In CorePrep we use etaExpand on each rhs, so that the visible lambdas actually match that arity, which in turn means that the StgRhs has the right number of lambdas -An alternative would be to do the eta-expansion in TidyPgm, at least+An alternative would be to do the eta-expansion in GHC.Iface.Tidy, at least for top-level bindings, in which case we would not need the trim_arity in exprArity. That is a less local change, so I'm going to leave it for today! @@ -267,7 +269,7 @@ there is no work lost in duplicating the partial application (e x1 .. x(n-1)) -In the divegent case, no work is lost by duplicating because if the thing+In the divergent case, no work is lost by duplicating because if the thing is evaluated once, that's the end of the program. Or, to put it another way, in any context C@@ -356,7 +358,7 @@ HOWEVER, note that if you use coerce bogusly you can ge coerce Int negate And since negate has arity 2, you might try to eta expand. But you can't- decopose Int to a function type. Hence the final case in eta_expand.+ decompose Int to a function type. Hence the final case in eta_expand. Note [The state-transformer hack] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -855,7 +857,7 @@ expansion and the CorePrep invariants] in CorePrep. This means the eta-expander has to do a bit of on-the-fly-simplification but it's not too hard. The alernative, of relying on+simplification but it's not too hard. The alternative, of relying on a subsequent clean-up phase of the Simplifier to de-crapify the result, means you can't really use it in CorePrep, which is painful. @@ -938,7 +940,7 @@ etaExpand n orig_expr = go n orig_expr where- -- Strip off existing lambdas and casts+ -- Strip off existing lambdas and casts before handing off to mkEtaWW -- Note [Eta expansion and SCCs] go 0 expr = expr go n (Lam v body) | isTyVar v = Lam v (go n body)@@ -949,7 +951,7 @@ retick $ etaInfoAbs etas (etaInfoApp subst' sexpr etas) where in_scope = mkInScopeSet (exprFreeVars expr)- (in_scope', etas) = mkEtaWW n orig_expr in_scope (exprType expr)+ (in_scope', etas) = mkEtaWW n (ppr orig_expr) in_scope (exprType expr) subst' = mkEmptySubst in_scope' -- Find ticks behind type apps.@@ -1040,14 +1042,27 @@ etaInfoAppTy _ (EtaCo co : eis) = etaInfoAppTy (coercionRKind co) eis ---------------mkEtaWW :: Arity -> CoreExpr -> InScopeSet -> Type- -> (InScopeSet, [EtaInfo])- -- EtaInfo contains fresh variables,- -- not free in the incoming CoreExpr- -- Outgoing InScopeSet includes the EtaInfo vars- -- and the original free vars+-- | @mkEtaWW n _ fvs ty@ will compute the 'EtaInfo' necessary for eta-expanding+-- an expression @e :: ty@ to take @n@ value arguments, where @fvs@ are the+-- free variables of @e@.+--+-- Note that this function is entirely unconcerned about cost centres and other+-- semantically-irrelevant source annotations, so call sites must take care to+-- preserve that info. See Note [Eta expansion and SCCs].+mkEtaWW+ :: Arity+ -- ^ How many value arguments to eta-expand+ -> SDoc+ -- ^ The pretty-printed original expression, for warnings.+ -> InScopeSet+ -- ^ A super-set of the free vars of the expression to eta-expand.+ -> Type+ -> (InScopeSet, [EtaInfo])+ -- ^ The variables in 'EtaInfo' are fresh wrt. to the incoming 'InScopeSet'.+ -- The outgoing 'InScopeSet' extends the incoming 'InScopeSet' with the+ -- fresh variables in 'EtaInfo'. -mkEtaWW orig_n orig_expr in_scope orig_ty+mkEtaWW orig_n ppr_orig_expr in_scope orig_ty = go orig_n empty_subst orig_ty [] where empty_subst = mkEmptyTCvSubst in_scope@@ -1104,9 +1119,9 @@ | otherwise -- We have an expression of arity > 0, -- but its type isn't a function, or a binder -- is levity-polymorphic- = WARN( True, (ppr orig_n <+> ppr orig_ty) $$ ppr orig_expr )+ = WARN( True, (ppr orig_n <+> ppr orig_ty) $$ ppr_orig_expr ) (getTCvInScope subst, reverse eis)- -- This *can* legitmately happen:+ -- This *can* legitimately happen: -- e.g. coerce Int (\x. x) Essentially the programmer is -- playing fast and loose with types (Happy does this a lot). -- So we simply decline to eta-expand. Otherwise we'd end up
compiler/coreSyn/CoreFVs.hs view
@@ -496,7 +496,7 @@ ruleLhsFreeIdsList :: CoreRule -> [Var] -- ^ This finds all locally-defined free Ids on the left hand side of a rule--- and returns them as a determinisitcally ordered list+-- and returns them as a deterministically ordered list ruleLhsFreeIdsList = fvVarList . ruleLhsFVIds ruleLhsFVIds :: CoreRule -> FV
compiler/coreSyn/CoreOpt.hs view
@@ -833,7 +833,7 @@ we must parse it back into a FastString to split off the first character. That way we can treat unpackCString# and unpackCStringUtf8# in the same way. -We must also be caeful about+We must also be careful about lvl = "foo"# ...(unpackCString# lvl)... to ensure that we see through the let-binding for 'lvl'. Hence the@@ -1138,7 +1138,7 @@ Note [DFun arity check] ~~~~~~~~~~~~~~~~~~~~~~~-Here we check that the total number of supplied arguments (inclding+Here we check that the total number of supplied arguments (including type args) matches what the dfun is expecting. This may be *less* than the ordinary arity of the dfun: see Note [DFun unfoldings] in CoreSyn -}
compiler/coreSyn/CoreSubst.hs view
@@ -7,6 +7,7 @@ -} {-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module CoreSubst ( -- * Main data types Subst(..), -- Implementation exported for supercompiler's Renaming.hs only@@ -745,7 +746,7 @@ {- Note [Worker inlining] ~~~~~~~~~~~~~~~~~~~~~~-A worker can get sustituted away entirely.+A worker can get substituted away entirely. - it might be trivial - it might simply be very small We do not treat an InlWrapper as an 'occurrence' in the occurrence
compiler/coreSyn/CoreSyn.hs view
@@ -6,6 +6,8 @@ {-# LANGUAGE CPP, DeriveDataTypeable, FlexibleContexts #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE BangPatterns #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} -- | CoreSyn holds all the main data types for use by for the Glasgow Haskell Compiler midsection module CoreSyn (@@ -225,7 +227,7 @@ exprType (Case scrut bndr ty alts) = ty is better for at least three reasons: -* It works when there are no alternatives (see case invarant 1 above)+* It works when there are no alternatives (see case invariant 1 above) * It might be faster in deeply-nested situations. @@ -1042,7 +1044,7 @@ -- ==> -- tick<...> case foo of x -> bar --- -- While this is always leagl, we want to make a best effort to+ -- While this is always legal, we want to make a best effort to -- only make us of this where it exposes transformation -- opportunities. | SoftScope@@ -1262,8 +1264,8 @@ has two major consequences * A module that contains orphans is called an "orphan module". If- the module being compiled depends (transitively) on an oprhan- module M, then M.hi is read in regardless of whether M is oherwise+ the module being compiled depends (transitively) on an orphan+ module M, then M.hi is read in regardless of whether M is otherwise needed. This is to ensure that we don't miss any instance decls in M. But it's painful, because it means we need to keep track of all the orphan modules below us.@@ -1273,12 +1275,12 @@ mentions on the LHS. For example data T = T1 | T2 instance Eq T where ....- The instance (Eq T) is incorprated as part of T's fingerprint.+ The instance (Eq T) is incorporated as part of T's fingerprint. In contrast, orphans are all fingerprinted together in the mi_orph_hash field of the ModIface. - See MkIface.addFingerprints.+ See GHC.Iface.Utils.addFingerprints. Orphan-hood is computed * For class instances:@@ -1286,8 +1288,8 @@ (because it is needed during instance lookup) * For rules and family instances:- when we generate an IfaceRule (MkIface.coreRuleToIfaceRule)- or IfaceFamInst (MkIface.instanceToIfaceInst)+ when we generate an IfaceRule (GHC.Iface.Utils.coreRuleToIfaceRule)+ or IfaceFamInst (GHC.Iface.Utils.instanceToIfaceInst) -} {-@@ -1351,7 +1353,7 @@ ru_auto :: Bool, -- ^ @True@ <=> this rule is auto-generated -- (notably by Specialise or SpecConstr) -- @False@ <=> generated at the user's behest- -- See Note [Trimming auto-rules] in TidyPgm+ -- See Note [Trimming auto-rules] in GHC.Iface.Tidy -- for the sole purpose of this field. ru_origin :: !Module, -- ^ 'Module' the rule was defined in, used@@ -1447,7 +1449,7 @@ | BootUnfolding -- ^ We have no information about the unfolding, because -- this 'Id' came from an @hi-boot@ file.- -- See Note [Inlining and hs-boot files] in ToIface+ -- See Note [Inlining and hs-boot files] in GHC.CoreToIface -- for what this is used for. | OtherCon [AltCon] -- ^ It ain't one of these constructors.
compiler/coreSyn/CoreTidy.hs view
@@ -4,10 +4,11 @@ This module contains "tidying" code for *nested* expressions, bindings, rules.-The code for *top-level* bindings is in TidyPgm.+The code for *top-level* bindings is in GHC.Iface.Tidy. -} {-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module CoreTidy ( tidyExpr, tidyRules, tidyUnfolding ) where@@ -196,7 +197,7 @@ -- Don't attempt to recompute arity here; this is just tidying! -- Trying to do so led to #17294 --- -- Set inline-prag info so that we preseve it across+ -- Set inline-prag info so that we preserve it across -- separate compilation boundaries old_info = idInfo id new_info = vanillaIdInfo@@ -229,7 +230,7 @@ = seqIt $ unf { uf_tmpl = tidyExpr tidy_env unf_rhs } -- Preserves OccInfo -- This seqIt avoids a space leak: otherwise the uf_is_value, -- uf_is_conlike, ... fields may retain a reference to the- -- pre-tidied expression forever (ToIface doesn't look at them)+ -- pre-tidied expression forever (GHC.CoreToIface doesn't look at them) | otherwise = unf_from_rhs
compiler/coreSyn/CoreUnfold.hs view
@@ -17,6 +17,8 @@ {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+ module CoreUnfold ( Unfolding, UnfoldingGuidance, -- Abstract types @@ -226,13 +228,13 @@ {- INLINABLE f #-} Now if we specialise f, should the specialised version still have an INLINABLE pragma? If it does, we'll capture a specialised copy- of <big-rhs> as its unfolding, and that probaby won't inline. But+ of <big-rhs> as its unfolding, and that probably won't inline. But if we don't, the specialised version of <big-rhs> might be small enough to inline at a call site. This happens with Control.Monad.liftM3, and can cause a lot more allocation as a result (nofib n-body shows this). Moreover, keeping the INLINABLE thing isn't much help, because- the specialised function (probaby) isn't overloaded any more.+ the specialised function (probably) isn't overloaded any more. Conclusion: drop the INLINEALE pragma. In practice what this means is: if a stable unfolding has UnfoldingGuidance of UnfWhen,@@ -255,7 +257,7 @@ that is, applied to at least as many arguments as appear on the LHS of the Haskell source definition. -(This soure-code-derived arity is stored in the `ug_arity` field of+(This source-code-derived arity is stored in the `ug_arity` field of the `UnfoldingGuidance`.) In the example, x's ug_arity is 0, so we should inline it at every use@@ -362,14 +364,14 @@ But more generally, the simplifier is designed on the basis that it is looking at occurrence-analysed expressions, so better-ensure that they acutally are.+ensure that they actually are. We use occurAnalyseExpr_NoBinderSwap instead of occurAnalyseExpr; see Note [No binder swap in unfoldings]. Note [No binder swap in unfoldings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The binder swap can temporarily violate Core Lint, by assinging+The binder swap can temporarily violate Core Lint, by assigning a LocalId binding to a GlobalId. For example, if A.foo{r872} is a GlobalId with unique r872, then @@ -528,7 +530,7 @@ [25/5/11] All sizes are now multiplied by 10, except for primops (which have sizes like 1 or 4. This makes primops look fantastically-cheap, and seems to be almost unversally beneficial. Done partly as a+cheap, and seems to be almost universally beneficial. Done partly as a result of #4978. Note [Do not inline top-level bottoming functions]@@ -1612,5 +1614,5 @@ -- constructors; but we only want to invoke that large discount -- when there's a case continuation. -- Otherwise we, rather arbitrarily, threshold it. Yuk.- -- But we want to aovid inlining large functions that return+ -- But we want to avoid inlining large functions that return -- constructors into contexts that are simply "interesting"
compiler/coreSyn/CoreUtils.hs view
@@ -8,7 +8,7 @@ {-# LANGUAGE CPP #-} --- | Commonly useful utilites for manipulating the Core language+-- | Commonly useful utilities for manipulating the Core language module CoreUtils ( -- * Constructing expressions mkCast,@@ -552,7 +552,7 @@ Note [Binding coercions] ~~~~~~~~~~~~~~~~~~~~~~~~-Consider binding a CoVar, c = e. Then, we must atisfy+Consider binding a CoVar, c = e. Then, we must satisfy Note [CoreSyn type and coercion invariant] in CoreSyn, which allows only (Coercion co) on the RHS. @@ -609,7 +609,7 @@ Suppose that for some silly reason, x isn't substituted in the case expression. (Perhaps there's a NOINLINE on it, or profiling SCC stuff-gets in the way; cf #3118.) Then the full-lazines pass might produce+gets in the way; cf #3118.) Then the full-laziness pass might produce this x = Red@@ -1622,7 +1622,7 @@ ----------------------------- altsAreExhaustive :: [Alt b] -> Bool--- True <=> the case alternatives are definiely exhaustive+-- True <=> the case alternatives are definitely exhaustive -- False <=> they may or may not be altsAreExhaustive [] = False -- Should not happen@@ -2502,9 +2502,9 @@ -> (Name -> Bool) -- Which names are dynamic -> (LitNumType -> Integer -> Maybe CoreExpr) -- Desugaring for some literals (disgusting)- -- C.f. Note [Disgusting computation of CafRefs] in TidyPgm+ -- C.f. Note [Disgusting computation of CafRefs] in GHC.Iface.Tidy -> CoreExpr -> Bool--- It's called (i) in TidyPgm.hasCafRefs to decide if the rhs is, or+-- It's called (i) in GHC.Iface.Tidy.hasCafRefs to decide if the rhs is, or -- refers to, CAFs; (ii) in CoreToStg to decide whether to put an -- update flag on it and (iii) in DsExpr to decide how to expand -- list literals
compiler/coreSyn/MkCore.hs view
@@ -1,5 +1,7 @@ {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+ -- | Handy functions for creating much Core syntax module MkCore ( -- * Constructing normal syntax@@ -886,7 +888,7 @@ Yikes! That bogusly appears to evaluate the absentError! This is extremely tiresome. Another way to think of this is that, in-Core, it is an invariant that a strict data contructor, like MkT, must+Core, it is an invariant that a strict data constructor, like MkT, must be applied only to an argument in HNF. So (absentError "blah") had better be non-bottom.
compiler/coreSyn/PprCore.hs view
@@ -319,8 +319,8 @@ = sdocWithDynFlags $ \dflags -> if gopt Opt_SuppressTypeApplications dflags then empty- else text "@" <+> pprParendType ty-pprArg (Coercion co) = text "@~" <+> pprOptCo co+ else text "@" <> pprParendType ty+pprArg (Coercion co) = text "@~" <> pprOptCo co pprArg expr = pprParendExpr expr {-@@ -381,7 +381,7 @@ pprUntypedBinder :: Var -> SDoc pprUntypedBinder binder- | isTyVar binder = text "@" <+> ppr binder -- NB: don't print kind+ | isTyVar binder = text "@" <> ppr binder -- NB: don't print kind | otherwise = pprIdBndr binder pprTypedLamBinder :: BindingSite -> Bool -> Var -> SDoc@@ -431,7 +431,7 @@ pprKindedTyVarBndr :: TyVar -> SDoc -- Print a type variable binder with its kind (but not if *) pprKindedTyVarBndr tyvar- = text "@" <+> pprTyVar tyvar+ = text "@" <> pprTyVar tyvar -- pprIdBndr does *not* print the type -- When printing any Id binder in debug mode, we print its inline pragma and one-shot-ness
− compiler/iface/IfaceSyn.hs
@@ -1,2593 +0,0 @@-{--(c) The University of Glasgow 2006-(c) The GRASP/AQUA Project, Glasgow University, 1993-1998--}--{-# LANGUAGE CPP #-}-{-# LANGUAGE LambdaCase #-}--module IfaceSyn (- module IfaceType,-- IfaceDecl(..), IfaceFamTyConFlav(..), IfaceClassOp(..), IfaceAT(..),- IfaceConDecl(..), IfaceConDecls(..), IfaceEqSpec,- IfaceExpr(..), IfaceAlt, IfaceLetBndr(..), IfaceJoinInfo(..),- IfaceBinding(..), IfaceConAlt(..),- IfaceIdInfo(..), IfaceIdDetails(..), IfaceUnfolding(..),- IfaceInfoItem(..), IfaceRule(..), IfaceAnnotation(..), IfaceAnnTarget,- IfaceClsInst(..), IfaceFamInst(..), IfaceTickish(..),- IfaceClassBody(..),- IfaceBang(..),- IfaceSrcBang(..), SrcUnpackedness(..), SrcStrictness(..),- IfaceAxBranch(..),- IfaceTyConParent(..),- IfaceCompleteMatch(..),-- -- * Binding names- IfaceTopBndr,- putIfaceTopBndr, getIfaceTopBndr,-- -- Misc- ifaceDeclImplicitBndrs, visibleIfConDecls,- ifaceDeclFingerprints,-- -- Free Names- freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst,-- -- Pretty printing- pprIfaceExpr,- pprIfaceDecl,- AltPpr(..), ShowSub(..), ShowHowMuch(..), showToIface, showToHeader- ) where--#include "HsVersions.h"--import GhcPrelude--import IfaceType-import BinFingerprint-import CoreSyn( IsOrphan, isOrphan )-import DynFlags( gopt, GeneralFlag (Opt_PrintAxiomIncomps) )-import Demand-import Class-import FieldLabel-import NameSet-import CoAxiom ( BranchIndex )-import Name-import CostCentre-import Literal-import ForeignCall-import Annotations( AnnPayload, AnnTarget )-import BasicTypes-import Outputable-import Module-import SrcLoc-import Fingerprint-import Binary-import BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue )-import Var( VarBndr(..), binderVar )-import TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag )-import Util( dropList, filterByList, notNull, unzipWith, debugIsOn )-import DataCon (SrcStrictness(..), SrcUnpackedness(..))-import Lexeme (isLexSym)-import TysWiredIn ( constraintKindTyConName )-import Util (seqList)--import Control.Monad-import System.IO.Unsafe-import Control.DeepSeq--infixl 3 &&&--{--************************************************************************-* *- Declarations-* *-************************************************************************--}---- | A binding top-level 'Name' in an interface file (e.g. the name of an--- 'IfaceDecl').-type IfaceTopBndr = Name- -- It's convenient to have a Name in the IfaceSyn, although in each- -- case the namespace is implied by the context. However, having an- -- Name makes things like ifaceDeclImplicitBndrs and ifaceDeclFingerprints- -- very convenient. Moreover, having the key of the binder means that- -- we can encode known-key things cleverly in the symbol table. See Note- -- [Symbol table representation of Names]- --- -- We don't serialise the namespace onto the disk though; rather we- -- drop it when serialising and add it back in when deserialising.--getIfaceTopBndr :: BinHandle -> IO IfaceTopBndr-getIfaceTopBndr bh = get bh--putIfaceTopBndr :: BinHandle -> IfaceTopBndr -> IO ()-putIfaceTopBndr bh name =- case getUserData bh of- UserData{ ud_put_binding_name = put_binding_name } ->- --pprTrace "putIfaceTopBndr" (ppr name) $- put_binding_name bh name--data IfaceDecl- = IfaceId { ifName :: IfaceTopBndr,- ifType :: IfaceType,- ifIdDetails :: IfaceIdDetails,- ifIdInfo :: IfaceIdInfo }-- | IfaceData { ifName :: IfaceTopBndr, -- Type constructor- ifBinders :: [IfaceTyConBinder],- ifResKind :: IfaceType, -- Result kind of type constructor- ifCType :: Maybe CType, -- C type for CAPI FFI- ifRoles :: [Role], -- Roles- ifCtxt :: IfaceContext, -- The "stupid theta"- ifCons :: IfaceConDecls, -- Includes new/data/data family info- ifGadtSyntax :: Bool, -- True <=> declared using- -- GADT syntax- ifParent :: IfaceTyConParent -- The axiom, for a newtype,- -- or data/newtype family instance- }-- | IfaceSynonym { ifName :: IfaceTopBndr, -- Type constructor- ifRoles :: [Role], -- Roles- ifBinders :: [IfaceTyConBinder],- ifResKind :: IfaceKind, -- Kind of the *result*- ifSynRhs :: IfaceType }-- | IfaceFamily { ifName :: IfaceTopBndr, -- Type constructor- ifResVar :: Maybe IfLclName, -- Result variable name, used- -- only for pretty-printing- -- with --show-iface- ifBinders :: [IfaceTyConBinder],- ifResKind :: IfaceKind, -- Kind of the *tycon*- ifFamFlav :: IfaceFamTyConFlav,- ifFamInj :: Injectivity } -- injectivity information-- | IfaceClass { ifName :: IfaceTopBndr, -- Name of the class TyCon- ifRoles :: [Role], -- Roles- ifBinders :: [IfaceTyConBinder],- ifFDs :: [FunDep IfLclName], -- Functional dependencies- ifBody :: IfaceClassBody -- Methods, superclasses, ATs- }-- | IfaceAxiom { ifName :: IfaceTopBndr, -- Axiom name- ifTyCon :: IfaceTyCon, -- LHS TyCon- ifRole :: Role, -- Role of axiom- ifAxBranches :: [IfaceAxBranch] -- Branches- }-- | IfacePatSyn { ifName :: IfaceTopBndr, -- Name of the pattern synonym- ifPatIsInfix :: Bool,- ifPatMatcher :: (IfExtName, Bool),- ifPatBuilder :: Maybe (IfExtName, Bool),- -- Everything below is redundant,- -- but needed to implement pprIfaceDecl- ifPatUnivBndrs :: [IfaceForAllBndr],- ifPatExBndrs :: [IfaceForAllBndr],- ifPatProvCtxt :: IfaceContext,- ifPatReqCtxt :: IfaceContext,- ifPatArgs :: [IfaceType],- ifPatTy :: IfaceType,- ifFieldLabels :: [FieldLabel] }---- See also 'ClassBody'-data IfaceClassBody- -- Abstract classes don't specify their body; they only occur in @hs-boot@ and- -- @hsig@ files.- = IfAbstractClass- | IfConcreteClass {- ifClassCtxt :: IfaceContext, -- Super classes- ifATs :: [IfaceAT], -- Associated type families- ifSigs :: [IfaceClassOp], -- Method signatures- ifMinDef :: BooleanFormula IfLclName -- Minimal complete definition- }--data IfaceTyConParent- = IfNoParent- | IfDataInstance- IfExtName -- Axiom name- IfaceTyCon -- Family TyCon (pretty-printing only, not used in TcIface)- -- see Note [Pretty printing via IfaceSyn] in PprTyThing- IfaceAppArgs -- Arguments of the family TyCon--data IfaceFamTyConFlav- = IfaceDataFamilyTyCon -- Data family- | IfaceOpenSynFamilyTyCon- | IfaceClosedSynFamilyTyCon (Maybe (IfExtName, [IfaceAxBranch]))- -- ^ Name of associated axiom and branches for pretty printing purposes,- -- or 'Nothing' for an empty closed family without an axiom- -- See Note [Pretty printing via IfaceSyn] in PprTyThing- | IfaceAbstractClosedSynFamilyTyCon- | IfaceBuiltInSynFamTyCon -- for pretty printing purposes only--data IfaceClassOp- = IfaceClassOp IfaceTopBndr- IfaceType -- Class op type- (Maybe (DefMethSpec IfaceType)) -- Default method- -- The types of both the class op itself,- -- and the default method, are *not* quantified- -- over the class variables--data IfaceAT = IfaceAT -- See Class.ClassATItem- IfaceDecl -- The associated type declaration- (Maybe IfaceType) -- Default associated type instance, if any----- This is just like CoAxBranch-data IfaceAxBranch = IfaceAxBranch { ifaxbTyVars :: [IfaceTvBndr]- , ifaxbEtaTyVars :: [IfaceTvBndr]- , ifaxbCoVars :: [IfaceIdBndr]- , ifaxbLHS :: IfaceAppArgs- , ifaxbRoles :: [Role]- , ifaxbRHS :: IfaceType- , ifaxbIncomps :: [BranchIndex] }- -- See Note [Storing compatibility] in CoAxiom--data IfaceConDecls- = IfAbstractTyCon -- c.f TyCon.AbstractTyCon- | IfDataTyCon [IfaceConDecl] -- Data type decls- | IfNewTyCon IfaceConDecl -- Newtype decls---- For IfDataTyCon and IfNewTyCon we store:--- * the data constructor(s);--- The field labels are stored individually in the IfaceConDecl--- (there is some redundancy here, because a field label may occur--- in multiple IfaceConDecls and represent the same field label)--data IfaceConDecl- = IfCon {- ifConName :: IfaceTopBndr, -- Constructor name- ifConWrapper :: Bool, -- True <=> has a wrapper- ifConInfix :: Bool, -- True <=> declared infix-- -- The universal type variables are precisely those- -- of the type constructor of this data constructor- -- This is *easy* to guarantee when creating the IfCon- -- but it's not so easy for the original TyCon/DataCon- -- So this guarantee holds for IfaceConDecl, but *not* for DataCon-- ifConExTCvs :: [IfaceBndr], -- Existential ty/covars- ifConUserTvBinders :: [IfaceForAllBndr],- -- The tyvars, in the order the user wrote them- -- INVARIANT: the set of tyvars in ifConUserTvBinders is exactly the- -- set of tyvars (*not* covars) of ifConExTCvs, unioned- -- with the set of ifBinders (from the parent IfaceDecl)- -- whose tyvars do not appear in ifConEqSpec- -- See Note [DataCon user type variable binders] in DataCon- ifConEqSpec :: IfaceEqSpec, -- Equality constraints- ifConCtxt :: IfaceContext, -- Non-stupid context- ifConArgTys :: [IfaceType], -- Arg types- ifConFields :: [FieldLabel], -- ...ditto... (field labels)- ifConStricts :: [IfaceBang],- -- Empty (meaning all lazy),- -- or 1-1 corresp with arg tys- -- See Note [Bangs on imported data constructors] in MkId- ifConSrcStricts :: [IfaceSrcBang] } -- empty meaning no src stricts--type IfaceEqSpec = [(IfLclName,IfaceType)]---- | This corresponds to an HsImplBang; that is, the final--- implementation decision about the data constructor arg-data IfaceBang- = IfNoBang | IfStrict | IfUnpack | IfUnpackCo IfaceCoercion---- | This corresponds to HsSrcBang-data IfaceSrcBang- = IfSrcBang SrcUnpackedness SrcStrictness--data IfaceClsInst- = IfaceClsInst { ifInstCls :: IfExtName, -- See comments with- ifInstTys :: [Maybe IfaceTyCon], -- the defn of ClsInst- ifDFun :: IfExtName, -- The dfun- ifOFlag :: OverlapFlag, -- Overlap flag- ifInstOrph :: IsOrphan } -- See Note [Orphans] in InstEnv- -- There's always a separate IfaceDecl for the DFun, which gives- -- its IdInfo with its full type and version number.- -- The instance declarations taken together have a version number,- -- and we don't want that to wobble gratuitously- -- If this instance decl is *used*, we'll record a usage on the dfun;- -- and if the head does not change it won't be used if it wasn't before---- The ifFamInstTys field of IfaceFamInst contains a list of the rough--- match types-data IfaceFamInst- = IfaceFamInst { ifFamInstFam :: IfExtName -- Family name- , ifFamInstTys :: [Maybe IfaceTyCon] -- See above- , ifFamInstAxiom :: IfExtName -- The axiom- , ifFamInstOrph :: IsOrphan -- Just like IfaceClsInst- }--data IfaceRule- = IfaceRule {- ifRuleName :: RuleName,- ifActivation :: Activation,- ifRuleBndrs :: [IfaceBndr], -- Tyvars and term vars- ifRuleHead :: IfExtName, -- Head of lhs- ifRuleArgs :: [IfaceExpr], -- Args of LHS- ifRuleRhs :: IfaceExpr,- ifRuleAuto :: Bool,- ifRuleOrph :: IsOrphan -- Just like IfaceClsInst- }--data IfaceAnnotation- = IfaceAnnotation {- ifAnnotatedTarget :: IfaceAnnTarget,- ifAnnotatedValue :: AnnPayload- }--type IfaceAnnTarget = AnnTarget OccName--data IfaceCompleteMatch = IfaceCompleteMatch [IfExtName] IfExtName--instance Outputable IfaceCompleteMatch where- ppr (IfaceCompleteMatch cls ty) = text "COMPLETE" <> colon <+> ppr cls- <+> dcolon <+> ppr ty------- Here's a tricky case:--- * Compile with -O module A, and B which imports A.f--- * Change function f in A, and recompile without -O--- * When we read in old A.hi we read in its IdInfo (as a thunk)--- (In earlier GHCs we used to drop IdInfo immediately on reading,--- but we do not do that now. Instead it's discarded when the--- ModIface is read into the various decl pools.)--- * The version comparison sees that new (=NoInfo) differs from old (=HasInfo *)--- and so gives a new version.--data IfaceIdInfo- = NoInfo -- When writing interface file without -O- | HasInfo [IfaceInfoItem] -- Has info, and here it is--data IfaceInfoItem- = HsArity Arity- | HsStrictness StrictSig- | HsInline InlinePragma- | HsUnfold Bool -- True <=> isStrongLoopBreaker is true- IfaceUnfolding -- See Note [Expose recursive functions]- | HsNoCafRefs- | HsLevity -- Present <=> never levity polymorphic---- NB: Specialisations and rules come in separately and are--- only later attached to the Id. Partial reason: some are orphans.--data IfaceUnfolding- = IfCoreUnfold Bool IfaceExpr -- True <=> INLINABLE, False <=> regular unfolding- -- Possibly could eliminate the Bool here, the information- -- is also in the InlinePragma.-- | IfCompulsory IfaceExpr -- Only used for default methods, in fact-- | IfInlineRule Arity -- INLINE pragmas- Bool -- OK to inline even if *un*-saturated- Bool -- OK to inline even if context is boring- IfaceExpr-- | IfDFunUnfold [IfaceBndr] [IfaceExpr]----- We only serialise the IdDetails of top-level Ids, and even then--- we only need a very limited selection. Notably, none of the--- implicit ones are needed here, because they are not put it--- interface files--data IfaceIdDetails- = IfVanillaId- | IfRecSelId (Either IfaceTyCon IfaceDecl) Bool- | IfDFunId--{--Note [Versioning of instances]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-See [https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/recompilation-avoidance#instances]---************************************************************************-* *- Functions over declarations-* *-************************************************************************--}--visibleIfConDecls :: IfaceConDecls -> [IfaceConDecl]-visibleIfConDecls IfAbstractTyCon = []-visibleIfConDecls (IfDataTyCon cs) = cs-visibleIfConDecls (IfNewTyCon c) = [c]--ifaceDeclImplicitBndrs :: IfaceDecl -> [OccName]--- *Excludes* the 'main' name, but *includes* the implicitly-bound names--- Deeply revolting, because it has to predict what gets bound,--- especially the question of whether there's a wrapper for a datacon--- See Note [Implicit TyThings] in HscTypes---- N.B. the set of names returned here *must* match the set of--- TyThings returned by HscTypes.implicitTyThings, in the sense that--- TyThing.getOccName should define a bijection between the two lists.--- This invariant is used in LoadIface.loadDecl (see note [Tricky iface loop])--- The order of the list does not matter.--ifaceDeclImplicitBndrs (IfaceData {ifName = tc_name, ifCons = cons })- = case cons of- IfAbstractTyCon -> []- IfNewTyCon cd -> mkNewTyCoOcc (occName tc_name) : ifaceConDeclImplicitBndrs cd- IfDataTyCon cds -> concatMap ifaceConDeclImplicitBndrs cds--ifaceDeclImplicitBndrs (IfaceClass { ifBody = IfAbstractClass })- = []--ifaceDeclImplicitBndrs (IfaceClass { ifName = cls_tc_name- , ifBody = IfConcreteClass {- ifClassCtxt = sc_ctxt,- ifSigs = sigs,- ifATs = ats- }})- = -- (possibly) newtype coercion- co_occs ++- -- data constructor (DataCon namespace)- -- data worker (Id namespace)- -- no wrapper (class dictionaries never have a wrapper)- [dc_occ, dcww_occ] ++- -- associated types- [occName (ifName at) | IfaceAT at _ <- ats ] ++- -- superclass selectors- [mkSuperDictSelOcc n cls_tc_occ | n <- [1..n_ctxt]] ++- -- operation selectors- [occName op | IfaceClassOp op _ _ <- sigs]- where- cls_tc_occ = occName cls_tc_name- n_ctxt = length sc_ctxt- n_sigs = length sigs- co_occs | is_newtype = [mkNewTyCoOcc cls_tc_occ]- | otherwise = []- dcww_occ = mkDataConWorkerOcc dc_occ- dc_occ = mkClassDataConOcc cls_tc_occ- is_newtype = n_sigs + n_ctxt == 1 -- Sigh (keep this synced with buildClass)--ifaceDeclImplicitBndrs _ = []--ifaceConDeclImplicitBndrs :: IfaceConDecl -> [OccName]-ifaceConDeclImplicitBndrs (IfCon {- ifConWrapper = has_wrapper, ifConName = con_name })- = [occName con_name, work_occ] ++ wrap_occs- where- con_occ = occName con_name- work_occ = mkDataConWorkerOcc con_occ -- Id namespace- wrap_occs | has_wrapper = [mkDataConWrapperOcc con_occ] -- Id namespace- | otherwise = []---- -------------------------------------------------------------------------------- The fingerprints of an IfaceDecl-- -- We better give each name bound by the declaration a- -- different fingerprint! So we calculate the fingerprint of- -- each binder by combining the fingerprint of the whole- -- declaration with the name of the binder. (#5614, #7215)-ifaceDeclFingerprints :: Fingerprint -> IfaceDecl -> [(OccName,Fingerprint)]-ifaceDeclFingerprints hash decl- = (getOccName decl, hash) :- [ (occ, computeFingerprint' (hash,occ))- | occ <- ifaceDeclImplicitBndrs decl ]- where- computeFingerprint' =- unsafeDupablePerformIO- . computeFingerprint (panic "ifaceDeclFingerprints")--{--************************************************************************-* *- Expressions-* *-************************************************************************--}--data IfaceExpr- = IfaceLcl IfLclName- | IfaceExt IfExtName- | IfaceType IfaceType- | IfaceCo IfaceCoercion- | IfaceTuple TupleSort [IfaceExpr] -- Saturated; type arguments omitted- | IfaceLam IfaceLamBndr IfaceExpr- | IfaceApp IfaceExpr IfaceExpr- | IfaceCase IfaceExpr IfLclName [IfaceAlt]- | IfaceECase IfaceExpr IfaceType -- See Note [Empty case alternatives]- | IfaceLet IfaceBinding IfaceExpr- | IfaceCast IfaceExpr IfaceCoercion- | IfaceLit Literal- | IfaceFCall ForeignCall IfaceType- | IfaceTick IfaceTickish IfaceExpr -- from Tick tickish E--data IfaceTickish- = IfaceHpcTick Module Int -- from HpcTick x- | IfaceSCC CostCentre Bool Bool -- from ProfNote- | IfaceSource RealSrcSpan String -- from SourceNote- -- no breakpoints: we never export these into interface files--type IfaceAlt = (IfaceConAlt, [IfLclName], IfaceExpr)- -- Note: IfLclName, not IfaceBndr (and same with the case binder)- -- We reconstruct the kind/type of the thing from the context- -- thus saving bulk in interface files--data IfaceConAlt = IfaceDefault- | IfaceDataAlt IfExtName- | IfaceLitAlt Literal--data IfaceBinding- = IfaceNonRec IfaceLetBndr IfaceExpr- | IfaceRec [(IfaceLetBndr, IfaceExpr)]---- IfaceLetBndr is like IfaceIdBndr, but has IdInfo too--- It's used for *non-top-level* let/rec binders--- See Note [IdInfo on nested let-bindings]-data IfaceLetBndr = IfLetBndr IfLclName IfaceType IfaceIdInfo IfaceJoinInfo--data IfaceJoinInfo = IfaceNotJoinPoint- | IfaceJoinPoint JoinArity--{--Note [Empty case alternatives]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-In IfaceSyn an IfaceCase does not record the types of the alternatives,-unlike CorSyn Case. But we need this type if the alternatives are empty.-Hence IfaceECase. See Note [Empty case alternatives] in CoreSyn.--Note [Expose recursive functions]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-For supercompilation we want to put *all* unfoldings in the interface-file, even for functions that are recursive (or big). So we need to-know when an unfolding belongs to a loop-breaker so that we can refrain-from inlining it (except during supercompilation).--Note [IdInfo on nested let-bindings]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Occasionally we want to preserve IdInfo on nested let bindings. The one-that came up was a NOINLINE pragma on a let-binding inside an INLINE-function. The user (Duncan Coutts) really wanted the NOINLINE control-to cross the separate compilation boundary.--In general we retain all info that is left by CoreTidy.tidyLetBndr, since-that is what is seen by importing module with --make--Note [Displaying axiom incompatibilities]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-With -fprint-axiom-incomps we display which closed type family equations-are incompatible with which. This information is sometimes necessary-because GHC doesn't try equations in order: any equation can be used when-all preceding equations that are incompatible with it do not apply.--For example, the last "a && a = a" equation in Data.Type.Bool.&& is-actually compatible with all previous equations, and can reduce at any-time.--This is displayed as:-Prelude> :i Data.Type.Equality.==-type family (==) (a :: k) (b :: k) :: Bool- where- {- #0 -} (==) (f a) (g b) = (f == g) && (a == b)- {- #1 -} (==) a a = 'True- -- incompatible with: #0- {- #2 -} (==) _1 _2 = 'False- -- incompatible with: #1, #0-The comment after an equation refers to all previous equations (0-indexed)-that are incompatible with it.--************************************************************************-* *- Printing IfaceDecl-* *-************************************************************************--}--pprAxBranch :: SDoc -> BranchIndex -> IfaceAxBranch -> SDoc--- The TyCon might be local (just an OccName), or this might--- be a branch for an imported TyCon, so it would be an ExtName--- So it's easier to take an SDoc here------ This function is used--- to print interface files,--- in debug messages--- in :info F for GHCi, which goes via toConToIfaceDecl on the family tycon--- For user error messages we use Coercion.pprCoAxiom and friends-pprAxBranch pp_tc idx (IfaceAxBranch { ifaxbTyVars = tvs- , ifaxbCoVars = _cvs- , ifaxbLHS = pat_tys- , ifaxbRHS = rhs- , ifaxbIncomps = incomps })- = ASSERT2( null _cvs, pp_tc $$ ppr _cvs )- hang ppr_binders 2 (hang pp_lhs 2 (equals <+> ppr rhs))- $+$- nest 4 maybe_incomps- where- -- See Note [Printing foralls in type family instances] in IfaceType- ppr_binders = maybe_index <+>- pprUserIfaceForAll (map (mkIfaceForAllTvBndr Specified) tvs)- pp_lhs = hang pp_tc 2 (pprParendIfaceAppArgs pat_tys)-- -- See Note [Displaying axiom incompatibilities]- maybe_index- = sdocWithDynFlags $ \dflags ->- ppWhen (gopt Opt_PrintAxiomIncomps dflags) $- text "{-" <+> (text "#" <> ppr idx) <+> text "-}"- maybe_incomps- = sdocWithDynFlags $ \dflags ->- ppWhen (gopt Opt_PrintAxiomIncomps dflags && notNull incomps) $- text "--" <+> text "incompatible with:"- <+> pprWithCommas (\incomp -> text "#" <> ppr incomp) incomps--instance Outputable IfaceAnnotation where- ppr (IfaceAnnotation target value) = ppr target <+> colon <+> ppr value--instance NamedThing IfaceClassOp where- getName (IfaceClassOp n _ _) = n--instance HasOccName IfaceClassOp where- occName = getOccName--instance NamedThing IfaceConDecl where- getName = ifConName--instance HasOccName IfaceConDecl where- occName = getOccName--instance NamedThing IfaceDecl where- getName = ifName--instance HasOccName IfaceDecl where- occName = getOccName--instance Outputable IfaceDecl where- ppr = pprIfaceDecl showToIface--{--Note [Minimal complete definition] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The minimal complete definition should only be included if a complete-class definition is shown. Since the minimal complete definition is-anonymous we can't reuse the same mechanism that is used for the-filtering of method signatures. Instead we just check if anything at all is-filtered and hide it in that case.--}--data ShowSub- = ShowSub- { ss_how_much :: ShowHowMuch- , ss_forall :: ShowForAllFlag }---- See Note [Printing IfaceDecl binders]--- The alternative pretty printer referred to in the note.-newtype AltPpr = AltPpr (Maybe (OccName -> SDoc))--data ShowHowMuch- = ShowHeader AltPpr -- ^Header information only, not rhs- | ShowSome [OccName] AltPpr- -- ^ Show only some sub-components. Specifically,- --- -- [@[]@] Print all sub-components.- -- [@(n:ns)@] Print sub-component @n@ with @ShowSub = ns@;- -- elide other sub-components to @...@- -- May 14: the list is max 1 element long at the moment- | ShowIface- -- ^Everything including GHC-internal information (used in --show-iface)--{--Note [Printing IfaceDecl binders]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The binders in an IfaceDecl are just OccNames, so we don't know what module they-come from. But when we pretty-print a TyThing by converting to an IfaceDecl-(see PprTyThing), the TyThing may come from some other module so we really need-the module qualifier. We solve this by passing in a pretty-printer for the-binders.--When printing an interface file (--show-iface), we want to print-everything unqualified, so we can just print the OccName directly.--}--instance Outputable ShowHowMuch where- ppr (ShowHeader _) = text "ShowHeader"- ppr ShowIface = text "ShowIface"- ppr (ShowSome occs _) = text "ShowSome" <+> ppr occs--showToHeader :: ShowSub-showToHeader = ShowSub { ss_how_much = ShowHeader $ AltPpr Nothing- , ss_forall = ShowForAllWhen }--showToIface :: ShowSub-showToIface = ShowSub { ss_how_much = ShowIface- , ss_forall = ShowForAllWhen }--ppShowIface :: ShowSub -> SDoc -> SDoc-ppShowIface (ShowSub { ss_how_much = ShowIface }) doc = doc-ppShowIface _ _ = Outputable.empty---- show if all sub-components or the complete interface is shown-ppShowAllSubs :: ShowSub -> SDoc -> SDoc -- Note [Minimal complete definition]-ppShowAllSubs (ShowSub { ss_how_much = ShowSome [] _ }) doc = doc-ppShowAllSubs (ShowSub { ss_how_much = ShowIface }) doc = doc-ppShowAllSubs _ _ = Outputable.empty--ppShowRhs :: ShowSub -> SDoc -> SDoc-ppShowRhs (ShowSub { ss_how_much = ShowHeader _ }) _ = Outputable.empty-ppShowRhs _ doc = doc--showSub :: HasOccName n => ShowSub -> n -> Bool-showSub (ShowSub { ss_how_much = ShowHeader _ }) _ = False-showSub (ShowSub { ss_how_much = ShowSome (n:_) _ }) thing = n == occName thing-showSub (ShowSub { ss_how_much = _ }) _ = True--ppr_trim :: [Maybe SDoc] -> [SDoc]--- Collapse a group of Nothings to a single "..."-ppr_trim xs- = snd (foldr go (False, []) xs)- where- go (Just doc) (_, so_far) = (False, doc : so_far)- go Nothing (True, so_far) = (True, so_far)- go Nothing (False, so_far) = (True, text "..." : so_far)--isIfaceDataInstance :: IfaceTyConParent -> Bool-isIfaceDataInstance IfNoParent = False-isIfaceDataInstance _ = True--pprClassRoles :: ShowSub -> IfaceTopBndr -> [IfaceTyConBinder] -> [Role] -> SDoc-pprClassRoles ss clas binders roles =- pprRoles (== Nominal)- (pprPrefixIfDeclBndr (ss_how_much ss) (occName clas))- binders- roles--pprClassStandaloneKindSig :: ShowSub -> IfaceTopBndr -> IfaceKind -> SDoc-pprClassStandaloneKindSig ss clas =- pprStandaloneKindSig (pprPrefixIfDeclBndr (ss_how_much ss) (occName clas))--constraintIfaceKind :: IfaceKind-constraintIfaceKind =- IfaceTyConApp (IfaceTyCon constraintKindTyConName (IfaceTyConInfo NotPromoted IfaceNormalTyCon)) IA_Nil--pprIfaceDecl :: ShowSub -> IfaceDecl -> SDoc--- NB: pprIfaceDecl is also used for pretty-printing TyThings in GHCi--- See Note [Pretty-printing TyThings] in PprTyThing-pprIfaceDecl ss (IfaceData { ifName = tycon, ifCType = ctype,- ifCtxt = context, ifResKind = kind,- ifRoles = roles, ifCons = condecls,- ifParent = parent,- ifGadtSyntax = gadt,- ifBinders = binders })-- | gadt = vcat [ pp_roles- , pp_ki_sig- , pp_nd <+> pp_lhs <+> pp_kind <+> pp_where- , nest 2 (vcat pp_cons)- , nest 2 $ ppShowIface ss pp_extra ]- | otherwise = vcat [ pp_roles- , pp_ki_sig- , hang (pp_nd <+> pp_lhs) 2 (add_bars pp_cons)- , nest 2 $ ppShowIface ss pp_extra ]- where- is_data_instance = isIfaceDataInstance parent- -- See Note [Printing foralls in type family instances] in IfaceType- pp_data_inst_forall :: SDoc- pp_data_inst_forall = pprUserIfaceForAll forall_bndrs-- forall_bndrs :: [IfaceForAllBndr]- forall_bndrs = [Bndr (binderVar tc_bndr) Specified | tc_bndr <- binders]-- cons = visibleIfConDecls condecls- pp_where = ppWhen (gadt && not (null cons)) $ text "where"- pp_cons = ppr_trim (map show_con cons) :: [SDoc]- pp_kind = ppUnless (if ki_sig_printable- then isIfaceTauType kind- -- Even in the presence of a standalone kind signature, a non-tau- -- result kind annotation cannot be discarded as it determines the arity.- -- See Note [Arity inference in kcDeclHeader_sig] in TcHsType- else isIfaceLiftedTypeKind kind)- (dcolon <+> ppr kind)-- pp_lhs = case parent of- IfNoParent -> pprIfaceDeclHead suppress_bndr_sig context ss tycon binders- IfDataInstance{}- -> text "instance" <+> pp_data_inst_forall- <+> pprIfaceTyConParent parent-- pp_roles- | is_data_instance = empty- | otherwise = pprRoles (== Representational) name_doc binders roles- -- Don't display roles for data family instances (yet)- -- See discussion on #8672.-- ki_sig_printable =- -- If we print a standalone kind signature for a data instance, we leak- -- the internal constructor name:- --- -- type T15827.R:Dka :: forall k. k -> *- -- data instance forall k (a :: k). D a = MkD (Proxy a)- --- -- This T15827.R:Dka is a compiler-generated type constructor for the- -- data instance.- not is_data_instance-- pp_ki_sig = ppWhen ki_sig_printable $- pprStandaloneKindSig name_doc (mkIfaceTyConKind binders kind)-- -- See Note [Suppressing binder signatures] in IfaceType- suppress_bndr_sig = SuppressBndrSig ki_sig_printable-- name_doc = pprPrefixIfDeclBndr (ss_how_much ss) (occName tycon)-- add_bars [] = Outputable.empty- add_bars (c:cs) = sep ((equals <+> c) : map (vbar <+>) cs)-- ok_con dc = showSub ss dc || any (showSub ss . flSelector) (ifConFields dc)-- show_con dc- | ok_con dc = Just $ pprIfaceConDecl ss gadt tycon binders parent dc- | otherwise = Nothing-- pp_nd = case condecls of- IfAbstractTyCon{} -> text "data"- IfDataTyCon{} -> text "data"- IfNewTyCon{} -> text "newtype"-- pp_extra = vcat [pprCType ctype]--pprIfaceDecl ss (IfaceClass { ifName = clas- , ifRoles = roles- , ifFDs = fds- , ifBinders = binders- , ifBody = IfAbstractClass })- = vcat [ pprClassRoles ss clas binders roles- , pprClassStandaloneKindSig ss clas (mkIfaceTyConKind binders constraintIfaceKind)- , text "class" <+> pprIfaceDeclHead suppress_bndr_sig [] ss clas binders <+> pprFundeps fds ]- where- -- See Note [Suppressing binder signatures] in IfaceType- suppress_bndr_sig = SuppressBndrSig True--pprIfaceDecl ss (IfaceClass { ifName = clas- , ifRoles = roles- , ifFDs = fds- , ifBinders = binders- , ifBody = IfConcreteClass {- ifATs = ats,- ifSigs = sigs,- ifClassCtxt = context,- ifMinDef = minDef- }})- = vcat [ pprClassRoles ss clas binders roles- , pprClassStandaloneKindSig ss clas (mkIfaceTyConKind binders constraintIfaceKind)- , text "class" <+> pprIfaceDeclHead suppress_bndr_sig context ss clas binders <+> pprFundeps fds <+> pp_where- , nest 2 (vcat [ vcat asocs, vcat dsigs- , ppShowAllSubs ss (pprMinDef minDef)])]- where- pp_where = ppShowRhs ss $ ppUnless (null sigs && null ats) (text "where")-- asocs = ppr_trim $ map maybeShowAssoc ats- dsigs = ppr_trim $ map maybeShowSig sigs-- maybeShowAssoc :: IfaceAT -> Maybe SDoc- maybeShowAssoc asc@(IfaceAT d _)- | showSub ss d = Just $ pprIfaceAT ss asc- | otherwise = Nothing-- maybeShowSig :: IfaceClassOp -> Maybe SDoc- maybeShowSig sg- | showSub ss sg = Just $ pprIfaceClassOp ss sg- | otherwise = Nothing-- pprMinDef :: BooleanFormula IfLclName -> SDoc- pprMinDef minDef = ppUnless (isTrue minDef) $ -- hide empty definitions- text "{-# MINIMAL" <+>- pprBooleanFormula- (\_ def -> cparen (isLexSym def) (ppr def)) 0 minDef <+>- text "#-}"-- -- See Note [Suppressing binder signatures] in IfaceType- suppress_bndr_sig = SuppressBndrSig True--pprIfaceDecl ss (IfaceSynonym { ifName = tc- , ifBinders = binders- , ifSynRhs = mono_ty- , ifResKind = res_kind})- = vcat [ pprStandaloneKindSig name_doc (mkIfaceTyConKind binders res_kind)- , hang (text "type" <+> pprIfaceDeclHead suppress_bndr_sig [] ss tc binders <+> equals)- 2 (sep [ pprIfaceForAll tvs, pprIfaceContextArr theta, ppr tau- , ppUnless (isIfaceLiftedTypeKind res_kind) (dcolon <+> ppr res_kind) ])- ]- where- (tvs, theta, tau) = splitIfaceSigmaTy mono_ty- name_doc = pprPrefixIfDeclBndr (ss_how_much ss) (occName tc)-- -- See Note [Suppressing binder signatures] in IfaceType- suppress_bndr_sig = SuppressBndrSig True--pprIfaceDecl ss (IfaceFamily { ifName = tycon- , ifFamFlav = rhs, ifBinders = binders- , ifResKind = res_kind- , ifResVar = res_var, ifFamInj = inj })- | IfaceDataFamilyTyCon <- rhs- = vcat [ pprStandaloneKindSig name_doc (mkIfaceTyConKind binders res_kind)- , text "data family" <+> pprIfaceDeclHead suppress_bndr_sig [] ss tycon binders- ]-- | otherwise- = vcat [ pprStandaloneKindSig name_doc (mkIfaceTyConKind binders res_kind)- , hang (text "type family"- <+> pprIfaceDeclHead suppress_bndr_sig [] ss tycon binders- <+> ppShowRhs ss (pp_where rhs))- 2 (pp_inj res_var inj <+> ppShowRhs ss (pp_rhs rhs))- $$- nest 2 (ppShowRhs ss (pp_branches rhs))- ]- where- name_doc = pprPrefixIfDeclBndr (ss_how_much ss) (occName tycon)-- pp_where (IfaceClosedSynFamilyTyCon {}) = text "where"- pp_where _ = empty-- pp_inj Nothing _ = empty- pp_inj (Just res) inj- | Injective injectivity <- inj = hsep [ equals, ppr res- , pp_inj_cond res injectivity]- | otherwise = hsep [ equals, ppr res ]-- pp_inj_cond res inj = case filterByList inj binders of- [] -> empty- tvs -> hsep [vbar, ppr res, text "->", interppSP (map ifTyConBinderName tvs)]-- pp_rhs IfaceDataFamilyTyCon- = ppShowIface ss (text "data")- pp_rhs IfaceOpenSynFamilyTyCon- = ppShowIface ss (text "open")- pp_rhs IfaceAbstractClosedSynFamilyTyCon- = ppShowIface ss (text "closed, abstract")- pp_rhs (IfaceClosedSynFamilyTyCon {})- = empty -- see pp_branches- pp_rhs IfaceBuiltInSynFamTyCon- = ppShowIface ss (text "built-in")-- pp_branches (IfaceClosedSynFamilyTyCon (Just (ax, brs)))- = vcat (unzipWith (pprAxBranch- (pprPrefixIfDeclBndr- (ss_how_much ss)- (occName tycon))- ) $ zip [0..] brs)- $$ ppShowIface ss (text "axiom" <+> ppr ax)- pp_branches _ = Outputable.empty-- -- See Note [Suppressing binder signatures] in IfaceType- suppress_bndr_sig = SuppressBndrSig True--pprIfaceDecl _ (IfacePatSyn { ifName = name,- ifPatUnivBndrs = univ_bndrs, ifPatExBndrs = ex_bndrs,- ifPatProvCtxt = prov_ctxt, ifPatReqCtxt = req_ctxt,- ifPatArgs = arg_tys,- ifPatTy = pat_ty} )- = sdocWithDynFlags mk_msg- where- mk_msg dflags- = hang (text "pattern" <+> pprPrefixOcc name)- 2 (dcolon <+> sep [univ_msg- , pprIfaceContextArr req_ctxt- , ppWhen insert_empty_ctxt $ parens empty <+> darrow- , ex_msg- , pprIfaceContextArr prov_ctxt- , pprIfaceType $ foldr (IfaceFunTy VisArg) pat_ty arg_tys ])- where- univ_msg = pprUserIfaceForAll univ_bndrs- ex_msg = pprUserIfaceForAll ex_bndrs-- insert_empty_ctxt = null req_ctxt- && not (null prov_ctxt && isEmpty dflags ex_msg)--pprIfaceDecl ss (IfaceId { ifName = var, ifType = ty,- ifIdDetails = details, ifIdInfo = info })- = vcat [ hang (pprPrefixIfDeclBndr (ss_how_much ss) (occName var) <+> dcolon)- 2 (pprIfaceSigmaType (ss_forall ss) ty)- , ppShowIface ss (ppr details)- , ppShowIface ss (ppr info) ]--pprIfaceDecl _ (IfaceAxiom { ifName = name, ifTyCon = tycon- , ifAxBranches = branches })- = hang (text "axiom" <+> ppr name <+> dcolon)- 2 (vcat $ unzipWith (pprAxBranch (ppr tycon)) $ zip [0..] branches)--pprCType :: Maybe CType -> SDoc-pprCType Nothing = Outputable.empty-pprCType (Just cType) = text "C type:" <+> ppr cType---- if, for each role, suppress_if role is True, then suppress the role--- output-pprRoles :: (Role -> Bool) -> SDoc -> [IfaceTyConBinder]- -> [Role] -> SDoc-pprRoles suppress_if tyCon bndrs roles- = sdocWithDynFlags $ \dflags ->- let froles = suppressIfaceInvisibles dflags bndrs roles- in ppUnless (all suppress_if froles || null froles) $- text "type role" <+> tyCon <+> hsep (map ppr froles)--pprStandaloneKindSig :: SDoc -> IfaceType -> SDoc-pprStandaloneKindSig tyCon ty = text "type" <+> tyCon <+> text "::" <+> ppr ty--pprInfixIfDeclBndr :: ShowHowMuch -> OccName -> SDoc-pprInfixIfDeclBndr (ShowSome _ (AltPpr (Just ppr_bndr))) name- = pprInfixVar (isSymOcc name) (ppr_bndr name)-pprInfixIfDeclBndr _ name- = pprInfixVar (isSymOcc name) (ppr name)--pprPrefixIfDeclBndr :: ShowHowMuch -> OccName -> SDoc-pprPrefixIfDeclBndr (ShowHeader (AltPpr (Just ppr_bndr))) name- = parenSymOcc name (ppr_bndr name)-pprPrefixIfDeclBndr (ShowSome _ (AltPpr (Just ppr_bndr))) name- = parenSymOcc name (ppr_bndr name)-pprPrefixIfDeclBndr _ name- = parenSymOcc name (ppr name)--instance Outputable IfaceClassOp where- ppr = pprIfaceClassOp showToIface--pprIfaceClassOp :: ShowSub -> IfaceClassOp -> SDoc-pprIfaceClassOp ss (IfaceClassOp n ty dm)- = pp_sig n ty $$ generic_dm- where- generic_dm | Just (GenericDM dm_ty) <- dm- = text "default" <+> pp_sig n dm_ty- | otherwise- = empty- pp_sig n ty- = pprPrefixIfDeclBndr (ss_how_much ss) (occName n)- <+> dcolon- <+> pprIfaceSigmaType ShowForAllWhen ty--instance Outputable IfaceAT where- ppr = pprIfaceAT showToIface--pprIfaceAT :: ShowSub -> IfaceAT -> SDoc-pprIfaceAT ss (IfaceAT d mb_def)- = vcat [ pprIfaceDecl ss d- , case mb_def of- Nothing -> Outputable.empty- Just rhs -> nest 2 $- text "Default:" <+> ppr rhs ]--instance Outputable IfaceTyConParent where- ppr p = pprIfaceTyConParent p--pprIfaceTyConParent :: IfaceTyConParent -> SDoc-pprIfaceTyConParent IfNoParent- = Outputable.empty-pprIfaceTyConParent (IfDataInstance _ tc tys)- = pprIfaceTypeApp topPrec tc tys--pprIfaceDeclHead :: SuppressBndrSig- -> IfaceContext -> ShowSub -> Name- -> [IfaceTyConBinder] -- of the tycon, for invisible-suppression- -> SDoc-pprIfaceDeclHead suppress_sig context ss tc_occ bndrs- = sdocWithDynFlags $ \ dflags ->- sep [ pprIfaceContextArr context- , pprPrefixIfDeclBndr (ss_how_much ss) (occName tc_occ)- <+> pprIfaceTyConBinders suppress_sig- (suppressIfaceInvisibles dflags bndrs bndrs) ]--pprIfaceConDecl :: ShowSub -> Bool- -> IfaceTopBndr- -> [IfaceTyConBinder]- -> IfaceTyConParent- -> IfaceConDecl -> SDoc-pprIfaceConDecl ss gadt_style tycon tc_binders parent- (IfCon { ifConName = name, ifConInfix = is_infix,- ifConUserTvBinders = user_tvbs,- ifConEqSpec = eq_spec, ifConCtxt = ctxt, ifConArgTys = arg_tys,- ifConStricts = stricts, ifConFields = fields })- | gadt_style = pp_prefix_con <+> dcolon <+> ppr_gadt_ty- | otherwise = ppr_ex_quant pp_h98_con- where- pp_h98_con- | not (null fields) = pp_prefix_con <+> pp_field_args- | is_infix- , [ty1, ty2] <- pp_args- = sep [ ty1- , pprInfixIfDeclBndr how_much (occName name)- , ty2]- | otherwise = pp_prefix_con <+> sep pp_args-- how_much = ss_how_much ss- tys_w_strs :: [(IfaceBang, IfaceType)]- tys_w_strs = zip stricts arg_tys- pp_prefix_con = pprPrefixIfDeclBndr how_much (occName name)-- -- If we're pretty-printing a H98-style declaration with existential- -- quantification, then user_tvbs will always consist of the universal- -- tyvar binders followed by the existential tyvar binders. So to recover- -- the visibilities of the existential tyvar binders, we can simply drop- -- the universal tyvar binders from user_tvbs.- ex_tvbs = dropList tc_binders user_tvbs- ppr_ex_quant = pprIfaceForAllPartMust ex_tvbs ctxt- pp_gadt_res_ty = mk_user_con_res_ty eq_spec- ppr_gadt_ty = pprIfaceForAllPart user_tvbs ctxt pp_tau-- -- A bit gruesome this, but we can't form the full con_tau, and ppr it,- -- 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)- [] -> panic "pp_con_taus"- | otherwise- = sep [pp_field_args, arrow <+> pp_gadt_res_ty]-- ppr_bang IfNoBang = whenPprDebug $ char '_'- ppr_bang IfStrict = char '!'- ppr_bang IfUnpack = text "{-# UNPACK #-}"- ppr_bang (IfUnpackCo co) = text "! {-# UNPACK #-}" <>- pprParendIfaceCoercion co-- pprFieldArgTy, pprArgTy :: (IfaceBang, IfaceType) -> SDoc- -- If using record syntax, the only reason one would need to parenthesize- -- a compound field type is if it's preceded by a bang pattern.- pprFieldArgTy (bang, ty) = ppr_arg_ty (bang_prec bang) bang ty- -- If not using record syntax, a compound field type might need to be- -- parenthesized if one of the following holds:- --- -- 1. We're using Haskell98 syntax.- -- 2. The field type is preceded with a bang pattern.- pprArgTy (bang, ty) = ppr_arg_ty (max gadt_prec (bang_prec bang)) bang ty-- ppr_arg_ty :: PprPrec -> IfaceBang -> IfaceType -> SDoc- ppr_arg_ty prec bang ty = ppr_bang bang <> pprPrecIfaceType prec ty-- -- If we're displaying the fields GADT-style, e.g.,- --- -- data Foo a where- -- MkFoo :: (Int -> Int) -> Maybe a -> Foo- --- -- Then we use `funPrec`, since that will ensure `Int -> Int` gets the- -- parentheses that it requires, but simple compound types like `Maybe a`- -- (which don't require parentheses in a function argument position) won't- -- get them, assuming that there are no bang patterns (see bang_prec).- --- -- If we're displaying the fields Haskell98-style, e.g.,- --- -- data Foo a = MkFoo (Int -> Int) (Maybe a)- --- -- Then not only must we parenthesize `Int -> Int`, we must also- -- parenthesize compound fields like (Maybe a). Therefore, we pick- -- `appPrec`, which has higher precedence than `funPrec`.- gadt_prec :: PprPrec- gadt_prec- | gadt_style = funPrec- | otherwise = appPrec-- -- The presence of bang patterns or UNPACK annotations requires- -- surrounding the type with parentheses, if needed (#13699)- bang_prec :: IfaceBang -> PprPrec- bang_prec IfNoBang = topPrec- bang_prec IfStrict = appPrec- bang_prec IfUnpack = appPrec- bang_prec IfUnpackCo{} = appPrec-- pp_args :: [SDoc] -- No records, e.g., ` Maybe a -> Int -> ...` or- -- `!(Maybe a) -> !Int -> ...`- pp_args = map pprArgTy tys_w_strs-- pp_field_args :: SDoc -- Records, e.g., { x :: Maybe a, y :: Int } or- -- { x :: !(Maybe a), y :: !Int }- pp_field_args = braces $ sep $ punctuate comma $ ppr_trim $- zipWith maybe_show_label fields tys_w_strs-- maybe_show_label :: FieldLabel -> (IfaceBang, IfaceType) -> Maybe SDoc- maybe_show_label lbl bty- | showSub ss sel = Just (pprPrefixIfDeclBndr how_much occ- <+> dcolon <+> pprFieldArgTy bty)- | otherwise = Nothing- where- sel = flSelector lbl- occ = mkVarOccFS (flLabel lbl)-- mk_user_con_res_ty :: IfaceEqSpec -> SDoc- -- See Note [Result type of a data family GADT]- mk_user_con_res_ty eq_spec- | IfDataInstance _ tc tys <- parent- = pprIfaceType (IfaceTyConApp tc (substIfaceAppArgs gadt_subst tys))- | otherwise- = ppr_tc_app gadt_subst- where- gadt_subst = mkIfaceTySubst eq_spec-- -- When pretty-printing a GADT return type, we:- --- -- 1. Take the data tycon binders, extract their variable names and- -- visibilities, and construct suitable arguments from them. (This is- -- the role of mk_tc_app_args.)- -- 2. Apply the GADT substitution constructed from the eq_spec.- -- (See Note [Result type of a data family GADT].)- -- 3. Pretty-print the data type constructor applied to its arguments.- -- This process will omit any invisible arguments, such as coercion- -- variables, if necessary. (See Note- -- [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in TyCoRep.)- ppr_tc_app gadt_subst =- pprPrefixIfDeclBndr how_much (occName tycon)- <+> pprParendIfaceAppArgs- (substIfaceAppArgs gadt_subst (mk_tc_app_args tc_binders))-- mk_tc_app_args :: [IfaceTyConBinder] -> IfaceAppArgs- mk_tc_app_args [] = IA_Nil- mk_tc_app_args (Bndr bndr vis:tc_bndrs) =- IA_Arg (IfaceTyVar (ifaceBndrName bndr)) (tyConBndrVisArgFlag vis)- (mk_tc_app_args tc_bndrs)--instance Outputable IfaceRule where- ppr (IfaceRule { ifRuleName = name, ifActivation = act, ifRuleBndrs = bndrs,- ifRuleHead = fn, ifRuleArgs = args, ifRuleRhs = rhs,- ifRuleOrph = orph })- = sep [ hsep [ pprRuleName name- , if isOrphan orph then text "[orphan]" else Outputable.empty- , ppr act- , pp_foralls ]- , nest 2 (sep [ppr fn <+> sep (map pprParendIfaceExpr args),- text "=" <+> ppr rhs]) ]- where- pp_foralls = ppUnless (null bndrs) $ forAllLit <+> pprIfaceBndrs bndrs <> dot--instance Outputable IfaceClsInst where- ppr (IfaceClsInst { ifDFun = dfun_id, ifOFlag = flag- , ifInstCls = cls, ifInstTys = mb_tcs- , ifInstOrph = orph })- = hang (text "instance" <+> ppr flag- <+> (if isOrphan orph then text "[orphan]" else Outputable.empty)- <+> ppr cls <+> brackets (pprWithCommas ppr_rough mb_tcs))- 2 (equals <+> ppr dfun_id)--instance Outputable IfaceFamInst where- ppr (IfaceFamInst { ifFamInstFam = fam, ifFamInstTys = mb_tcs- , ifFamInstAxiom = tycon_ax, ifFamInstOrph = orph })- = hang (text "family instance"- <+> (if isOrphan orph then text "[orphan]" else Outputable.empty)- <+> ppr fam <+> pprWithCommas (brackets . ppr_rough) mb_tcs)- 2 (equals <+> ppr tycon_ax)--ppr_rough :: Maybe IfaceTyCon -> SDoc-ppr_rough Nothing = dot-ppr_rough (Just tc) = ppr tc--{--Note [Result type of a data family GADT]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider- data family T a- data instance T (p,q) where- T1 :: T (Int, Maybe c)- T2 :: T (Bool, q)--The IfaceDecl actually looks like-- data TPr p q where- T1 :: forall p q. forall c. (p~Int,q~Maybe c) => TPr p q- T2 :: forall p q. (p~Bool) => TPr p q--To reconstruct the result types for T1 and T2 that we-want to pretty print, we substitute the eq-spec-[p->Int, q->Maybe c] in the arg pattern (p,q) to give- T (Int, Maybe c)-Remember that in IfaceSyn, the TyCon and DataCon share the same-universal type variables.------------------------------- Printing IfaceExpr --------------------------------------}--instance Outputable IfaceExpr where- ppr e = pprIfaceExpr noParens e--noParens :: SDoc -> SDoc-noParens pp = pp--pprParendIfaceExpr :: IfaceExpr -> SDoc-pprParendIfaceExpr = pprIfaceExpr parens---- | Pretty Print an IfaceExpre------ The first argument should be a function that adds parens in context that need--- an atomic value (e.g. function args)-pprIfaceExpr :: (SDoc -> SDoc) -> IfaceExpr -> SDoc--pprIfaceExpr _ (IfaceLcl v) = ppr v-pprIfaceExpr _ (IfaceExt v) = ppr v-pprIfaceExpr _ (IfaceLit l) = ppr l-pprIfaceExpr _ (IfaceFCall cc ty) = braces (ppr cc <+> ppr ty)-pprIfaceExpr _ (IfaceType ty) = char '@' <+> pprParendIfaceType ty-pprIfaceExpr _ (IfaceCo co) = text "@~" <+> pprParendIfaceCoercion co--pprIfaceExpr add_par app@(IfaceApp _ _) = add_par (pprIfaceApp app [])-pprIfaceExpr _ (IfaceTuple c as) = tupleParens c (pprWithCommas ppr as)--pprIfaceExpr add_par i@(IfaceLam _ _)- = add_par (sep [char '\\' <+> sep (map pprIfaceLamBndr bndrs) <+> arrow,- pprIfaceExpr noParens body])- where- (bndrs,body) = collect [] i- collect bs (IfaceLam b e) = collect (b:bs) e- collect bs e = (reverse bs, e)--pprIfaceExpr add_par (IfaceECase scrut ty)- = add_par (sep [ text "case" <+> pprIfaceExpr noParens scrut- , text "ret_ty" <+> pprParendIfaceType ty- , text "of {}" ])--pprIfaceExpr add_par (IfaceCase scrut bndr [(con, bs, rhs)])- = add_par (sep [text "case"- <+> pprIfaceExpr noParens scrut <+> text "of"- <+> ppr bndr <+> char '{' <+> ppr_con_bs con bs <+> arrow,- pprIfaceExpr noParens rhs <+> char '}'])--pprIfaceExpr add_par (IfaceCase scrut bndr alts)- = add_par (sep [text "case"- <+> pprIfaceExpr noParens scrut <+> text "of"- <+> ppr bndr <+> char '{',- nest 2 (sep (map ppr_alt alts)) <+> char '}'])--pprIfaceExpr _ (IfaceCast expr co)- = sep [pprParendIfaceExpr expr,- nest 2 (text "`cast`"),- pprParendIfaceCoercion co]--pprIfaceExpr add_par (IfaceLet (IfaceNonRec b rhs) body)- = add_par (sep [text "let {",- nest 2 (ppr_bind (b, rhs)),- text "} in",- pprIfaceExpr noParens body])--pprIfaceExpr add_par (IfaceLet (IfaceRec pairs) body)- = add_par (sep [text "letrec {",- nest 2 (sep (map ppr_bind pairs)),- text "} in",- pprIfaceExpr noParens body])--pprIfaceExpr add_par (IfaceTick tickish e)- = add_par (pprIfaceTickish tickish <+> pprIfaceExpr noParens e)--ppr_alt :: (IfaceConAlt, [IfLclName], IfaceExpr) -> SDoc-ppr_alt (con, bs, rhs) = sep [ppr_con_bs con bs,- arrow <+> pprIfaceExpr noParens rhs]--ppr_con_bs :: IfaceConAlt -> [IfLclName] -> SDoc-ppr_con_bs con bs = ppr con <+> hsep (map ppr bs)--ppr_bind :: (IfaceLetBndr, IfaceExpr) -> SDoc-ppr_bind (IfLetBndr b ty info ji, rhs)- = sep [hang (ppr b <+> dcolon <+> ppr ty) 2 (ppr ji <+> ppr info),- equals <+> pprIfaceExpr noParens rhs]---------------------pprIfaceTickish :: IfaceTickish -> SDoc-pprIfaceTickish (IfaceHpcTick m ix)- = braces (text "tick" <+> ppr m <+> ppr ix)-pprIfaceTickish (IfaceSCC cc tick scope)- = braces (pprCostCentreCore cc <+> ppr tick <+> ppr scope)-pprIfaceTickish (IfaceSource src _names)- = braces (pprUserRealSpan True src)---------------------pprIfaceApp :: IfaceExpr -> [SDoc] -> SDoc-pprIfaceApp (IfaceApp fun arg) args = pprIfaceApp fun $- nest 2 (pprParendIfaceExpr arg) : args-pprIfaceApp fun args = sep (pprParendIfaceExpr fun : args)---------------------instance Outputable IfaceConAlt where- ppr IfaceDefault = text "DEFAULT"- ppr (IfaceLitAlt l) = ppr l- ppr (IfaceDataAlt d) = ppr d---------------------instance Outputable IfaceIdDetails where- ppr IfVanillaId = Outputable.empty- ppr (IfRecSelId tc b) = text "RecSel" <+> ppr tc- <+> if b- then text "<naughty>"- else Outputable.empty- ppr IfDFunId = text "DFunId"--instance Outputable IfaceIdInfo where- ppr NoInfo = Outputable.empty- ppr (HasInfo is) = text "{-" <+> pprWithCommas ppr is- <+> text "-}"--instance Outputable IfaceInfoItem where- ppr (HsUnfold lb unf) = text "Unfolding"- <> ppWhen lb (text "(loop-breaker)")- <> colon <+> ppr unf- ppr (HsInline prag) = text "Inline:" <+> ppr prag- ppr (HsArity arity) = text "Arity:" <+> int arity- ppr (HsStrictness str) = text "Strictness:" <+> pprIfaceStrictSig str- ppr HsNoCafRefs = text "HasNoCafRefs"- ppr HsLevity = text "Never levity-polymorphic"--instance Outputable IfaceJoinInfo where- ppr IfaceNotJoinPoint = empty- ppr (IfaceJoinPoint ar) = angleBrackets (text "join" <+> ppr ar)--instance Outputable IfaceUnfolding where- ppr (IfCompulsory e) = text "<compulsory>" <+> parens (ppr e)- ppr (IfCoreUnfold s e) = (if s- then text "<stable>"- else Outputable.empty)- <+> parens (ppr e)- ppr (IfInlineRule a uok bok e) = sep [text "InlineRule"- <+> ppr (a,uok,bok),- pprParendIfaceExpr e]- ppr (IfDFunUnfold bs es) = hang (text "DFun:" <+> sep (map ppr bs) <> dot)- 2 (sep (map pprParendIfaceExpr es))--{--************************************************************************-* *- Finding the Names in IfaceSyn-* *-************************************************************************--This is used for dependency analysis in MkIface, so that we-fingerprint a declaration before the things that depend on it. It-is specific to interface-file fingerprinting in the sense that we-don't collect *all* Names: for example, the DFun of an instance is-recorded textually rather than by its fingerprint when-fingerprinting the instance, so DFuns are not dependencies.--}--freeNamesIfDecl :: IfaceDecl -> NameSet-freeNamesIfDecl (IfaceId { ifType = t, ifIdDetails = d, ifIdInfo = i})- = freeNamesIfType t &&&- freeNamesIfIdInfo i &&&- freeNamesIfIdDetails d--freeNamesIfDecl (IfaceData { ifBinders = bndrs, ifResKind = res_k- , ifParent = p, ifCtxt = ctxt, ifCons = cons })- = freeNamesIfVarBndrs bndrs &&&- freeNamesIfType res_k &&&- freeNamesIfaceTyConParent p &&&- freeNamesIfContext ctxt &&&- freeNamesIfConDecls cons--freeNamesIfDecl (IfaceSynonym { ifBinders = bndrs, ifResKind = res_k- , ifSynRhs = rhs })- = freeNamesIfVarBndrs bndrs &&&- freeNamesIfKind res_k &&&- freeNamesIfType rhs--freeNamesIfDecl (IfaceFamily { ifBinders = bndrs, ifResKind = res_k- , ifFamFlav = flav })- = freeNamesIfVarBndrs bndrs &&&- freeNamesIfKind res_k &&&- freeNamesIfFamFlav flav--freeNamesIfDecl (IfaceClass{ ifBinders = bndrs, ifBody = cls_body })- = freeNamesIfVarBndrs bndrs &&&- freeNamesIfClassBody cls_body--freeNamesIfDecl (IfaceAxiom { ifTyCon = tc, ifAxBranches = branches })- = freeNamesIfTc tc &&&- fnList freeNamesIfAxBranch branches--freeNamesIfDecl (IfacePatSyn { ifPatMatcher = (matcher, _)- , ifPatBuilder = mb_builder- , ifPatUnivBndrs = univ_bndrs- , ifPatExBndrs = ex_bndrs- , ifPatProvCtxt = prov_ctxt- , ifPatReqCtxt = req_ctxt- , ifPatArgs = args- , ifPatTy = pat_ty- , ifFieldLabels = lbls })- = unitNameSet matcher &&&- maybe emptyNameSet (unitNameSet . fst) mb_builder &&&- freeNamesIfVarBndrs univ_bndrs &&&- freeNamesIfVarBndrs ex_bndrs &&&- freeNamesIfContext prov_ctxt &&&- freeNamesIfContext req_ctxt &&&- fnList freeNamesIfType args &&&- freeNamesIfType pat_ty &&&- mkNameSet (map flSelector lbls)--freeNamesIfClassBody :: IfaceClassBody -> NameSet-freeNamesIfClassBody IfAbstractClass- = emptyNameSet-freeNamesIfClassBody (IfConcreteClass{ ifClassCtxt = ctxt, ifATs = ats, ifSigs = sigs })- = freeNamesIfContext ctxt &&&- fnList freeNamesIfAT ats &&&- fnList freeNamesIfClsSig sigs--freeNamesIfAxBranch :: IfaceAxBranch -> NameSet-freeNamesIfAxBranch (IfaceAxBranch { ifaxbTyVars = tyvars- , ifaxbCoVars = covars- , ifaxbLHS = lhs- , ifaxbRHS = rhs })- = fnList freeNamesIfTvBndr tyvars &&&- fnList freeNamesIfIdBndr covars &&&- freeNamesIfAppArgs lhs &&&- freeNamesIfType rhs--freeNamesIfIdDetails :: IfaceIdDetails -> NameSet-freeNamesIfIdDetails (IfRecSelId tc _) =- either freeNamesIfTc freeNamesIfDecl tc-freeNamesIfIdDetails _ = emptyNameSet---- All other changes are handled via the version info on the tycon-freeNamesIfFamFlav :: IfaceFamTyConFlav -> NameSet-freeNamesIfFamFlav IfaceOpenSynFamilyTyCon = emptyNameSet-freeNamesIfFamFlav IfaceDataFamilyTyCon = emptyNameSet-freeNamesIfFamFlav (IfaceClosedSynFamilyTyCon (Just (ax, br)))- = unitNameSet ax &&& fnList freeNamesIfAxBranch br-freeNamesIfFamFlav (IfaceClosedSynFamilyTyCon Nothing) = emptyNameSet-freeNamesIfFamFlav IfaceAbstractClosedSynFamilyTyCon = emptyNameSet-freeNamesIfFamFlav IfaceBuiltInSynFamTyCon = emptyNameSet--freeNamesIfContext :: IfaceContext -> NameSet-freeNamesIfContext = fnList freeNamesIfType--freeNamesIfAT :: IfaceAT -> NameSet-freeNamesIfAT (IfaceAT decl mb_def)- = freeNamesIfDecl decl &&&- case mb_def of- Nothing -> emptyNameSet- Just rhs -> freeNamesIfType rhs--freeNamesIfClsSig :: IfaceClassOp -> NameSet-freeNamesIfClsSig (IfaceClassOp _n ty dm) = freeNamesIfType ty &&& freeNamesDM dm--freeNamesDM :: Maybe (DefMethSpec IfaceType) -> NameSet-freeNamesDM (Just (GenericDM ty)) = freeNamesIfType ty-freeNamesDM _ = emptyNameSet--freeNamesIfConDecls :: IfaceConDecls -> NameSet-freeNamesIfConDecls (IfDataTyCon c) = fnList freeNamesIfConDecl c-freeNamesIfConDecls (IfNewTyCon c) = freeNamesIfConDecl c-freeNamesIfConDecls _ = emptyNameSet--freeNamesIfConDecl :: IfaceConDecl -> NameSet-freeNamesIfConDecl (IfCon { ifConExTCvs = ex_tvs, ifConCtxt = ctxt- , ifConArgTys = arg_tys- , ifConFields = flds- , ifConEqSpec = eq_spec- , ifConStricts = bangs })- = fnList freeNamesIfBndr ex_tvs &&&- freeNamesIfContext ctxt &&&- fnList freeNamesIfType arg_tys &&&- mkNameSet (map flSelector flds) &&&- fnList freeNamesIfType (map snd eq_spec) &&& -- equality constraints- fnList freeNamesIfBang bangs--freeNamesIfBang :: IfaceBang -> NameSet-freeNamesIfBang (IfUnpackCo co) = freeNamesIfCoercion co-freeNamesIfBang _ = emptyNameSet--freeNamesIfKind :: IfaceType -> NameSet-freeNamesIfKind = freeNamesIfType--freeNamesIfAppArgs :: IfaceAppArgs -> NameSet-freeNamesIfAppArgs (IA_Arg t _ ts) = freeNamesIfType t &&& freeNamesIfAppArgs ts-freeNamesIfAppArgs IA_Nil = emptyNameSet--freeNamesIfType :: IfaceType -> NameSet-freeNamesIfType (IfaceFreeTyVar _) = emptyNameSet-freeNamesIfType (IfaceTyVar _) = emptyNameSet-freeNamesIfType (IfaceAppTy s t) = freeNamesIfType s &&& freeNamesIfAppArgs t-freeNamesIfType (IfaceTyConApp tc ts) = freeNamesIfTc tc &&& freeNamesIfAppArgs ts-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 (IfaceCastTy t c) = freeNamesIfType t &&& freeNamesIfCoercion c-freeNamesIfType (IfaceCoercionTy c) = freeNamesIfCoercion c--freeNamesIfMCoercion :: IfaceMCoercion -> NameSet-freeNamesIfMCoercion IfaceMRefl = emptyNameSet-freeNamesIfMCoercion (IfaceMCo co) = freeNamesIfCoercion co--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 (IfaceTyConAppCo _ tc cos)- = freeNamesIfTc tc &&& fnList freeNamesIfCoercion cos-freeNamesIfCoercion (IfaceAppCo c1 c2)- = freeNamesIfCoercion c1 &&& freeNamesIfCoercion c2-freeNamesIfCoercion (IfaceForAllCo _ kind_co co)- = freeNamesIfCoercion kind_co &&& freeNamesIfCoercion co-freeNamesIfCoercion (IfaceFreeCoVar _) = emptyNameSet-freeNamesIfCoercion (IfaceCoVarCo _) = emptyNameSet-freeNamesIfCoercion (IfaceHoleCo _) = emptyNameSet-freeNamesIfCoercion (IfaceAxiomInstCo ax _ cos)- = unitNameSet ax &&& fnList freeNamesIfCoercion cos-freeNamesIfCoercion (IfaceUnivCo p _ t1 t2)- = freeNamesIfProv p &&& freeNamesIfType t1 &&& freeNamesIfType t2-freeNamesIfCoercion (IfaceSymCo c)- = freeNamesIfCoercion c-freeNamesIfCoercion (IfaceTransCo c1 c2)- = freeNamesIfCoercion c1 &&& freeNamesIfCoercion c2-freeNamesIfCoercion (IfaceNthCo _ co)- = freeNamesIfCoercion co-freeNamesIfCoercion (IfaceLRCo _ co)- = freeNamesIfCoercion co-freeNamesIfCoercion (IfaceInstCo co co2)- = freeNamesIfCoercion co &&& freeNamesIfCoercion co2-freeNamesIfCoercion (IfaceKindCo c)- = freeNamesIfCoercion c-freeNamesIfCoercion (IfaceSubCo co)- = freeNamesIfCoercion co-freeNamesIfCoercion (IfaceAxiomRuleCo _ax cos)- -- the axiom is just a string, so we don't count it as a name.- = fnList freeNamesIfCoercion cos--freeNamesIfProv :: IfaceUnivCoProv -> NameSet-freeNamesIfProv IfaceUnsafeCoerceProv = emptyNameSet-freeNamesIfProv (IfacePhantomProv co) = freeNamesIfCoercion co-freeNamesIfProv (IfaceProofIrrelProv co) = freeNamesIfCoercion co-freeNamesIfProv (IfacePluginProv _) = emptyNameSet--freeNamesIfVarBndr :: VarBndr IfaceBndr vis -> NameSet-freeNamesIfVarBndr (Bndr bndr _) = freeNamesIfBndr bndr--freeNamesIfVarBndrs :: [VarBndr IfaceBndr vis] -> NameSet-freeNamesIfVarBndrs = fnList freeNamesIfVarBndr--freeNamesIfBndr :: IfaceBndr -> NameSet-freeNamesIfBndr (IfaceIdBndr b) = freeNamesIfIdBndr b-freeNamesIfBndr (IfaceTvBndr b) = freeNamesIfTvBndr b--freeNamesIfBndrs :: [IfaceBndr] -> NameSet-freeNamesIfBndrs = fnList freeNamesIfBndr--freeNamesIfLetBndr :: IfaceLetBndr -> NameSet--- Remember IfaceLetBndr is used only for *nested* bindings--- The IdInfo can contain an unfolding (in the case of--- local INLINE pragmas), so look there too-freeNamesIfLetBndr (IfLetBndr _name ty info _ji) = freeNamesIfType ty- &&& freeNamesIfIdInfo info--freeNamesIfTvBndr :: IfaceTvBndr -> NameSet-freeNamesIfTvBndr (_fs,k) = freeNamesIfKind k- -- kinds can have Names inside, because of promotion--freeNamesIfIdBndr :: IfaceIdBndr -> NameSet-freeNamesIfIdBndr (_fs,k) = freeNamesIfKind k--freeNamesIfIdInfo :: IfaceIdInfo -> NameSet-freeNamesIfIdInfo NoInfo = emptyNameSet-freeNamesIfIdInfo (HasInfo i) = fnList freeNamesItem i--freeNamesItem :: IfaceInfoItem -> NameSet-freeNamesItem (HsUnfold _ u) = freeNamesIfUnfold u-freeNamesItem _ = emptyNameSet--freeNamesIfUnfold :: IfaceUnfolding -> NameSet-freeNamesIfUnfold (IfCoreUnfold _ e) = freeNamesIfExpr e-freeNamesIfUnfold (IfCompulsory e) = freeNamesIfExpr e-freeNamesIfUnfold (IfInlineRule _ _ _ e) = freeNamesIfExpr e-freeNamesIfUnfold (IfDFunUnfold bs es) = freeNamesIfBndrs bs &&& fnList freeNamesIfExpr es--freeNamesIfExpr :: IfaceExpr -> NameSet-freeNamesIfExpr (IfaceExt v) = unitNameSet v-freeNamesIfExpr (IfaceFCall _ ty) = freeNamesIfType ty-freeNamesIfExpr (IfaceType ty) = freeNamesIfType ty-freeNamesIfExpr (IfaceCo co) = freeNamesIfCoercion co-freeNamesIfExpr (IfaceTuple _ as) = fnList freeNamesIfExpr as-freeNamesIfExpr (IfaceLam (b,_) body) = freeNamesIfBndr b &&& freeNamesIfExpr body-freeNamesIfExpr (IfaceApp f a) = freeNamesIfExpr f &&& freeNamesIfExpr a-freeNamesIfExpr (IfaceCast e co) = freeNamesIfExpr e &&& freeNamesIfCoercion co-freeNamesIfExpr (IfaceTick _ e) = freeNamesIfExpr e-freeNamesIfExpr (IfaceECase e ty) = freeNamesIfExpr e &&& freeNamesIfType ty-freeNamesIfExpr (IfaceCase s _ alts)- = freeNamesIfExpr s &&& fnList fn_alt alts &&& fn_cons alts- where- fn_alt (_con,_bs,r) = freeNamesIfExpr r-- -- Depend on the data constructors. Just one will do!- -- Note [Tracking data constructors]- fn_cons [] = emptyNameSet- fn_cons ((IfaceDefault ,_,_) : xs) = fn_cons xs- fn_cons ((IfaceDataAlt con,_,_) : _ ) = unitNameSet con- fn_cons (_ : _ ) = emptyNameSet--freeNamesIfExpr (IfaceLet (IfaceNonRec bndr rhs) body)- = freeNamesIfLetBndr bndr &&& freeNamesIfExpr rhs &&& freeNamesIfExpr body--freeNamesIfExpr (IfaceLet (IfaceRec as) x)- = fnList fn_pair as &&& freeNamesIfExpr x- where- fn_pair (bndr, rhs) = freeNamesIfLetBndr bndr &&& freeNamesIfExpr rhs--freeNamesIfExpr _ = emptyNameSet--freeNamesIfTc :: IfaceTyCon -> NameSet-freeNamesIfTc tc = unitNameSet (ifaceTyConName tc)--- ToDo: shouldn't we include IfaceIntTc & co.?--freeNamesIfRule :: IfaceRule -> NameSet-freeNamesIfRule (IfaceRule { ifRuleBndrs = bs, ifRuleHead = f- , ifRuleArgs = es, ifRuleRhs = rhs })- = unitNameSet f &&&- fnList freeNamesIfBndr bs &&&- fnList freeNamesIfExpr es &&&- freeNamesIfExpr rhs--freeNamesIfFamInst :: IfaceFamInst -> NameSet-freeNamesIfFamInst (IfaceFamInst { ifFamInstFam = famName- , ifFamInstAxiom = axName })- = unitNameSet famName &&&- unitNameSet axName--freeNamesIfaceTyConParent :: IfaceTyConParent -> NameSet-freeNamesIfaceTyConParent IfNoParent = emptyNameSet-freeNamesIfaceTyConParent (IfDataInstance ax tc tys)- = unitNameSet ax &&& freeNamesIfTc tc &&& freeNamesIfAppArgs tys---- helpers-(&&&) :: NameSet -> NameSet -> NameSet-(&&&) = unionNameSet--fnList :: (a -> NameSet) -> [a] -> NameSet-fnList f = foldr (&&&) emptyNameSet . map f--{--Note [Tracking data constructors]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-In a case expression- case e of { C a -> ...; ... }-You might think that we don't need to include the datacon C-in the free names, because its type will probably show up in-the free names of 'e'. But in rare circumstances this may-not happen. Here's the one that bit me:-- module DynFlags where- import {-# SOURCE #-} Packages( PackageState )- data DynFlags = DF ... PackageState ...-- module Packages where- import DynFlags- data PackageState = PS ...- lookupModule (df :: DynFlags)- = case df of- DF ...p... -> case p of- PS ... -> ...--Now, lookupModule depends on DynFlags, but the transitive dependency-on the *locally-defined* type PackageState is not visible. We need-to take account of the use of the data constructor PS in the pattern match.---************************************************************************-* *- Binary instances-* *-************************************************************************--Note that there is a bit of subtlety here when we encode names. While-IfaceTopBndrs is really just a synonym for Name, we need to take care to-encode them with {get,put}IfaceTopBndr. The difference becomes important when-we go to fingerprint an IfaceDecl. See Note [Fingerprinting IfaceDecls] for-details.---}--instance Binary IfaceDecl where- put_ bh (IfaceId name ty details idinfo) = do- putByte bh 0- putIfaceTopBndr bh name- lazyPut bh (ty, details, idinfo)- -- See Note [Lazy deserialization of IfaceId]-- put_ bh (IfaceData a1 a2 a3 a4 a5 a6 a7 a8 a9) = do- putByte bh 2- putIfaceTopBndr bh a1- put_ bh a2- put_ bh a3- put_ bh a4- put_ bh a5- put_ bh a6- put_ bh a7- put_ bh a8- put_ bh a9-- put_ bh (IfaceSynonym a1 a2 a3 a4 a5) = do- putByte bh 3- putIfaceTopBndr bh a1- put_ bh a2- put_ bh a3- put_ bh a4- put_ bh a5-- put_ bh (IfaceFamily a1 a2 a3 a4 a5 a6) = do- putByte bh 4- putIfaceTopBndr bh a1- put_ bh a2- put_ bh a3- put_ bh a4- put_ bh a5- put_ bh a6-- -- NB: Written in a funny way to avoid an interface change- put_ bh (IfaceClass {- ifName = a2,- ifRoles = a3,- ifBinders = a4,- ifFDs = a5,- ifBody = IfConcreteClass {- ifClassCtxt = a1,- ifATs = a6,- ifSigs = a7,- ifMinDef = a8- }}) = do- putByte bh 5- put_ bh a1- putIfaceTopBndr bh a2- put_ bh a3- put_ bh a4- put_ bh a5- put_ bh a6- put_ bh a7- put_ bh a8-- put_ bh (IfaceAxiom a1 a2 a3 a4) = do- putByte bh 6- putIfaceTopBndr bh a1- put_ bh a2- put_ bh a3- put_ bh a4-- put_ bh (IfacePatSyn a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = do- putByte bh 7- putIfaceTopBndr bh a1- put_ bh a2- put_ bh a3- put_ bh a4- put_ bh a5- put_ bh a6- put_ bh a7- put_ bh a8- put_ bh a9- put_ bh a10- put_ bh a11-- put_ bh (IfaceClass {- ifName = a1,- ifRoles = a2,- ifBinders = a3,- ifFDs = a4,- ifBody = IfAbstractClass }) = do- putByte bh 8- putIfaceTopBndr bh a1- put_ bh a2- put_ bh a3- put_ bh a4-- get bh = do- h <- getByte bh- case h of- 0 -> do name <- get bh- ~(ty, details, idinfo) <- lazyGet bh- -- See Note [Lazy deserialization of IfaceId]- return (IfaceId name ty details idinfo)- 1 -> error "Binary.get(TyClDecl): ForeignType"- 2 -> do a1 <- getIfaceTopBndr bh- a2 <- get bh- a3 <- get bh- a4 <- get bh- a5 <- get bh- a6 <- get bh- a7 <- get bh- a8 <- get bh- a9 <- get bh- return (IfaceData a1 a2 a3 a4 a5 a6 a7 a8 a9)- 3 -> do a1 <- getIfaceTopBndr bh- a2 <- get bh- a3 <- get bh- a4 <- get bh- a5 <- get bh- return (IfaceSynonym a1 a2 a3 a4 a5)- 4 -> do a1 <- getIfaceTopBndr bh- a2 <- get bh- a3 <- get bh- a4 <- get bh- a5 <- get bh- a6 <- get bh- return (IfaceFamily a1 a2 a3 a4 a5 a6)- 5 -> do a1 <- get bh- a2 <- getIfaceTopBndr bh- a3 <- get bh- a4 <- get bh- a5 <- get bh- a6 <- get bh- a7 <- get bh- a8 <- get bh- return (IfaceClass {- ifName = a2,- ifRoles = a3,- ifBinders = a4,- ifFDs = a5,- ifBody = IfConcreteClass {- ifClassCtxt = a1,- ifATs = a6,- ifSigs = a7,- ifMinDef = a8- }})- 6 -> do a1 <- getIfaceTopBndr bh- a2 <- get bh- a3 <- get bh- a4 <- get bh- return (IfaceAxiom a1 a2 a3 a4)- 7 -> do a1 <- getIfaceTopBndr bh- a2 <- get bh- a3 <- get bh- a4 <- get bh- a5 <- get bh- a6 <- get bh- a7 <- get bh- a8 <- get bh- a9 <- get bh- a10 <- get bh- a11 <- get bh- return (IfacePatSyn a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11)- 8 -> do a1 <- getIfaceTopBndr bh- a2 <- get bh- a3 <- get bh- a4 <- get bh- return (IfaceClass {- ifName = a1,- ifRoles = a2,- ifBinders = a3,- ifFDs = a4,- ifBody = IfAbstractClass })- _ -> panic (unwords ["Unknown IfaceDecl tag:", show h])--{- Note [Lazy deserialization of IfaceId]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The use of lazyPut and lazyGet in the IfaceId Binary instance is-purely for performance reasons, to avoid deserializing details about-identifiers that will never be used. It's not involved in tying the-knot in the type checker. It saved ~1% of the total build time of GHC.--When we read an interface file, we extend the PTE, a mapping of Names-to TyThings, with the declarations we have read. The extension of the-PTE is strict in the Names, but not in the TyThings themselves.-LoadIface.loadDecl calculates the list of (Name, TyThing) bindings to-add to the PTE. For an IfaceId, there's just one binding to add; and-the ty, details, and idinfo fields of an IfaceId are used only in the-TyThing. So by reading those fields lazily we may be able to save the-work of ever having to deserialize them (into IfaceType, etc.).--For IfaceData and IfaceClass, loadDecl creates extra implicit bindings-(the constructors and field selectors of the data declaration, or the-methods of the class), whose Names depend on more than just the Name-of the type constructor or class itself. So deserializing them lazily-would be more involved. Similar comments apply to the other-constructors of IfaceDecl with the additional point that they probably-represent a small proportion of all declarations.--}--instance Binary IfaceFamTyConFlav where- put_ bh IfaceDataFamilyTyCon = putByte bh 0- put_ bh IfaceOpenSynFamilyTyCon = putByte bh 1- put_ bh (IfaceClosedSynFamilyTyCon mb) = putByte bh 2 >> put_ bh mb- put_ bh IfaceAbstractClosedSynFamilyTyCon = putByte bh 3- put_ _ IfaceBuiltInSynFamTyCon- = pprPanic "Cannot serialize IfaceBuiltInSynFamTyCon, used for pretty-printing only" Outputable.empty-- get bh = do { h <- getByte bh- ; case h of- 0 -> return IfaceDataFamilyTyCon- 1 -> return IfaceOpenSynFamilyTyCon- 2 -> do { mb <- get bh- ; return (IfaceClosedSynFamilyTyCon mb) }- 3 -> return IfaceAbstractClosedSynFamilyTyCon- _ -> pprPanic "Binary.get(IfaceFamTyConFlav): Invalid tag"- (ppr (fromIntegral h :: Int)) }--instance Binary IfaceClassOp where- put_ bh (IfaceClassOp n ty def) = do- putIfaceTopBndr bh n- put_ bh ty- put_ bh def- get bh = do- n <- getIfaceTopBndr bh- ty <- get bh- def <- get bh- return (IfaceClassOp n ty def)--instance Binary IfaceAT where- put_ bh (IfaceAT dec defs) = do- put_ bh dec- put_ bh defs- get bh = do- dec <- get bh- defs <- get bh- return (IfaceAT dec defs)--instance Binary IfaceAxBranch where- put_ bh (IfaceAxBranch a1 a2 a3 a4 a5 a6 a7) = do- put_ bh a1- put_ bh a2- put_ bh a3- put_ bh a4- put_ bh a5- put_ bh a6- put_ bh a7- get bh = do- a1 <- get bh- a2 <- get bh- a3 <- get bh- a4 <- get bh- a5 <- get bh- a6 <- get bh- a7 <- get bh- return (IfaceAxBranch a1 a2 a3 a4 a5 a6 a7)--instance Binary IfaceConDecls where- put_ bh IfAbstractTyCon = putByte bh 0- put_ bh (IfDataTyCon cs) = putByte bh 1 >> put_ bh cs- put_ bh (IfNewTyCon c) = putByte bh 2 >> put_ bh c- get bh = do- h <- getByte bh- case h of- 0 -> return IfAbstractTyCon- 1 -> liftM IfDataTyCon (get bh)- 2 -> liftM IfNewTyCon (get bh)- _ -> error "Binary(IfaceConDecls).get: Invalid IfaceConDecls"--instance Binary IfaceConDecl where- put_ bh (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11) = do- putIfaceTopBndr bh a1- put_ bh a2- put_ bh a3- put_ bh a4- put_ bh a5- put_ bh a6- put_ bh a7- put_ bh a8- put_ bh (length a9)- mapM_ (put_ bh) a9- put_ bh a10- put_ bh a11- get bh = do- a1 <- getIfaceTopBndr bh- a2 <- get bh- a3 <- get bh- a4 <- get bh- a5 <- get bh- a6 <- get bh- a7 <- get bh- a8 <- get bh- n_fields <- get bh- a9 <- replicateM n_fields (get bh)- a10 <- get bh- a11 <- get bh- return (IfCon a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11)--instance Binary IfaceBang where- put_ bh IfNoBang = putByte bh 0- put_ bh IfStrict = putByte bh 1- put_ bh IfUnpack = putByte bh 2- put_ bh (IfUnpackCo co) = putByte bh 3 >> put_ bh co-- get bh = do- h <- getByte bh- case h of- 0 -> do return IfNoBang- 1 -> do return IfStrict- 2 -> do return IfUnpack- _ -> do { a <- get bh; return (IfUnpackCo a) }--instance Binary IfaceSrcBang where- put_ bh (IfSrcBang a1 a2) =- do put_ bh a1- put_ bh a2-- get bh =- do a1 <- get bh- a2 <- get bh- return (IfSrcBang a1 a2)--instance Binary IfaceClsInst where- put_ bh (IfaceClsInst cls tys dfun flag orph) = do- put_ bh cls- put_ bh tys- put_ bh dfun- put_ bh flag- put_ bh orph- get bh = do- cls <- get bh- tys <- get bh- dfun <- get bh- flag <- get bh- orph <- get bh- return (IfaceClsInst cls tys dfun flag orph)--instance Binary IfaceFamInst where- put_ bh (IfaceFamInst fam tys name orph) = do- put_ bh fam- put_ bh tys- put_ bh name- put_ bh orph- get bh = do- fam <- get bh- tys <- get bh- name <- get bh- orph <- get bh- return (IfaceFamInst fam tys name orph)--instance Binary IfaceRule where- put_ bh (IfaceRule a1 a2 a3 a4 a5 a6 a7 a8) = do- put_ bh a1- put_ bh a2- put_ bh a3- put_ bh a4- put_ bh a5- put_ bh a6- put_ bh a7- put_ bh a8- get bh = do- a1 <- get bh- a2 <- get bh- a3 <- get bh- a4 <- get bh- a5 <- get bh- a6 <- get bh- a7 <- get bh- a8 <- get bh- return (IfaceRule a1 a2 a3 a4 a5 a6 a7 a8)--instance Binary IfaceAnnotation where- put_ bh (IfaceAnnotation a1 a2) = do- put_ bh a1- put_ bh a2- get bh = do- a1 <- get bh- a2 <- get bh- return (IfaceAnnotation a1 a2)--instance Binary IfaceIdDetails where- put_ bh IfVanillaId = putByte bh 0- put_ bh (IfRecSelId a b) = putByte bh 1 >> put_ bh a >> put_ bh b- put_ bh IfDFunId = putByte bh 2- get bh = do- h <- getByte bh- case h of- 0 -> return IfVanillaId- 1 -> do { a <- get bh; b <- get bh; return (IfRecSelId a b) }- _ -> return IfDFunId--instance Binary IfaceIdInfo where- put_ bh NoInfo = putByte bh 0- put_ bh (HasInfo i) = putByte bh 1 >> lazyPut bh i -- NB lazyPut-- get bh = do- h <- getByte bh- case h of- 0 -> return NoInfo- _ -> liftM HasInfo $ lazyGet bh -- NB lazyGet--instance Binary IfaceInfoItem where- put_ bh (HsArity aa) = putByte bh 0 >> put_ bh aa- put_ bh (HsStrictness ab) = putByte bh 1 >> put_ bh ab- put_ bh (HsUnfold lb ad) = putByte bh 2 >> put_ bh lb >> put_ bh ad- put_ bh (HsInline ad) = putByte bh 3 >> put_ bh ad- put_ bh HsNoCafRefs = putByte bh 4- put_ bh HsLevity = putByte bh 5- get bh = do- h <- getByte bh- case h of- 0 -> liftM HsArity $ get bh- 1 -> liftM HsStrictness $ get bh- 2 -> do lb <- get bh- ad <- get bh- return (HsUnfold lb ad)- 3 -> liftM HsInline $ get bh- 4 -> return HsNoCafRefs- _ -> return HsLevity--instance Binary IfaceUnfolding where- put_ bh (IfCoreUnfold s e) = do- putByte bh 0- put_ bh s- put_ bh e- put_ bh (IfInlineRule a b c d) = do- putByte bh 1- put_ bh a- put_ bh b- put_ bh c- put_ bh d- put_ bh (IfDFunUnfold as bs) = do- putByte bh 2- put_ bh as- put_ bh bs- put_ bh (IfCompulsory e) = do- putByte bh 3- put_ bh e- get bh = do- h <- getByte bh- case h of- 0 -> do s <- get bh- e <- get bh- return (IfCoreUnfold s e)- 1 -> do a <- get bh- b <- get bh- c <- get bh- d <- get bh- return (IfInlineRule a b c d)- 2 -> do as <- get bh- bs <- get bh- return (IfDFunUnfold as bs)- _ -> do e <- get bh- return (IfCompulsory e)---instance Binary IfaceExpr where- put_ bh (IfaceLcl aa) = do- putByte bh 0- put_ bh aa- put_ bh (IfaceType ab) = do- putByte bh 1- put_ bh ab- put_ bh (IfaceCo ab) = do- putByte bh 2- put_ bh ab- put_ bh (IfaceTuple ac ad) = do- putByte bh 3- put_ bh ac- put_ bh ad- put_ bh (IfaceLam (ae, os) af) = do- putByte bh 4- put_ bh ae- put_ bh os- put_ bh af- put_ bh (IfaceApp ag ah) = do- putByte bh 5- put_ bh ag- put_ bh ah- put_ bh (IfaceCase ai aj ak) = do- putByte bh 6- put_ bh ai- put_ bh aj- put_ bh ak- put_ bh (IfaceLet al am) = do- putByte bh 7- put_ bh al- put_ bh am- put_ bh (IfaceTick an ao) = do- putByte bh 8- put_ bh an- put_ bh ao- put_ bh (IfaceLit ap) = do- putByte bh 9- put_ bh ap- put_ bh (IfaceFCall as at) = do- putByte bh 10- put_ bh as- put_ bh at- put_ bh (IfaceExt aa) = do- putByte bh 11- put_ bh aa- put_ bh (IfaceCast ie ico) = do- putByte bh 12- put_ bh ie- put_ bh ico- put_ bh (IfaceECase a b) = do- putByte bh 13- put_ bh a- put_ bh b- get bh = do- h <- getByte bh- case h of- 0 -> do aa <- get bh- return (IfaceLcl aa)- 1 -> do ab <- get bh- return (IfaceType ab)- 2 -> do ab <- get bh- return (IfaceCo ab)- 3 -> do ac <- get bh- ad <- get bh- return (IfaceTuple ac ad)- 4 -> do ae <- get bh- os <- get bh- af <- get bh- return (IfaceLam (ae, os) af)- 5 -> do ag <- get bh- ah <- get bh- return (IfaceApp ag ah)- 6 -> do ai <- get bh- aj <- get bh- ak <- get bh- return (IfaceCase ai aj ak)- 7 -> do al <- get bh- am <- get bh- return (IfaceLet al am)- 8 -> do an <- get bh- ao <- get bh- return (IfaceTick an ao)- 9 -> do ap <- get bh- return (IfaceLit ap)- 10 -> do as <- get bh- at <- get bh- return (IfaceFCall as at)- 11 -> do aa <- get bh- return (IfaceExt aa)- 12 -> do ie <- get bh- ico <- get bh- return (IfaceCast ie ico)- 13 -> do a <- get bh- b <- get bh- return (IfaceECase a b)- _ -> panic ("get IfaceExpr " ++ show h)--instance Binary IfaceTickish where- put_ bh (IfaceHpcTick m ix) = do- putByte bh 0- put_ bh m- put_ bh ix- put_ bh (IfaceSCC cc tick push) = do- putByte bh 1- put_ bh cc- put_ bh tick- put_ bh push- put_ bh (IfaceSource src name) = do- putByte bh 2- put_ bh (srcSpanFile src)- put_ bh (srcSpanStartLine src)- put_ bh (srcSpanStartCol src)- put_ bh (srcSpanEndLine src)- put_ bh (srcSpanEndCol src)- put_ bh name-- get bh = do- h <- getByte bh- case h of- 0 -> do m <- get bh- ix <- get bh- return (IfaceHpcTick m ix)- 1 -> do cc <- get bh- tick <- get bh- push <- get bh- return (IfaceSCC cc tick push)- 2 -> do file <- get bh- sl <- get bh- sc <- get bh- el <- get bh- ec <- get bh- let start = mkRealSrcLoc file sl sc- end = mkRealSrcLoc file el ec- name <- get bh- return (IfaceSource (mkRealSrcSpan start end) name)- _ -> panic ("get IfaceTickish " ++ show h)--instance Binary IfaceConAlt where- put_ bh IfaceDefault = putByte bh 0- put_ bh (IfaceDataAlt aa) = putByte bh 1 >> put_ bh aa- put_ bh (IfaceLitAlt ac) = putByte bh 2 >> put_ bh ac- get bh = do- h <- getByte bh- case h of- 0 -> return IfaceDefault- 1 -> liftM IfaceDataAlt $ get bh- _ -> liftM IfaceLitAlt $ get bh--instance Binary IfaceBinding where- put_ bh (IfaceNonRec aa ab) = putByte bh 0 >> put_ bh aa >> put_ bh ab- put_ bh (IfaceRec ac) = putByte bh 1 >> put_ bh ac- get bh = do- h <- getByte bh- case h of- 0 -> do { aa <- get bh; ab <- get bh; return (IfaceNonRec aa ab) }- _ -> do { ac <- get bh; return (IfaceRec ac) }--instance Binary IfaceLetBndr where- put_ bh (IfLetBndr a b c d) = do- put_ bh a- put_ bh b- put_ bh c- put_ bh d- get bh = do a <- get bh- b <- get bh- c <- get bh- d <- get bh- return (IfLetBndr a b c d)--instance Binary IfaceJoinInfo where- put_ bh IfaceNotJoinPoint = putByte bh 0- put_ bh (IfaceJoinPoint ar) = do- putByte bh 1- put_ bh ar- get bh = do- h <- getByte bh- case h of- 0 -> return IfaceNotJoinPoint- _ -> liftM IfaceJoinPoint $ get bh--instance Binary IfaceTyConParent where- put_ bh IfNoParent = putByte bh 0- put_ bh (IfDataInstance ax pr ty) = do- putByte bh 1- put_ bh ax- put_ bh pr- put_ bh ty- get bh = do- h <- getByte bh- case h of- 0 -> return IfNoParent- _ -> do- ax <- get bh- pr <- get bh- ty <- get bh- return $ IfDataInstance ax pr ty--instance Binary IfaceCompleteMatch where- put_ bh (IfaceCompleteMatch cs ts) = put_ bh cs >> put_ bh ts- get bh = IfaceCompleteMatch <$> get bh <*> get bh---{--************************************************************************-* *- NFData instances- See Note [Avoiding space leaks in toIface*] in ToIface-* *-************************************************************************--}--instance NFData IfaceDecl where- rnf = \case- IfaceId f1 f2 f3 f4 ->- rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4-- IfaceData f1 f2 f3 f4 f5 f6 f7 f8 f9 ->- f1 `seq` seqList f2 `seq` f3 `seq` f4 `seq` f5 `seq`- rnf f6 `seq` rnf f7 `seq` rnf f8 `seq` rnf f9-- IfaceSynonym f1 f2 f3 f4 f5 ->- rnf f1 `seq` f2 `seq` seqList f3 `seq` rnf f4 `seq` rnf f5-- IfaceFamily f1 f2 f3 f4 f5 f6 ->- rnf f1 `seq` rnf f2 `seq` seqList f3 `seq` rnf f4 `seq` rnf f5 `seq` f6 `seq` ()-- IfaceClass f1 f2 f3 f4 f5 ->- rnf f1 `seq` f2 `seq` seqList f3 `seq` rnf f4 `seq` rnf f5-- IfaceAxiom nm tycon role ax ->- rnf nm `seq`- rnf tycon `seq`- role `seq`- rnf ax-- IfacePatSyn f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 ->- rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` f5 `seq` f6 `seq`- rnf f7 `seq` rnf f8 `seq` rnf f9 `seq` rnf f10 `seq` f11 `seq` ()--instance NFData IfaceAxBranch where- rnf (IfaceAxBranch f1 f2 f3 f4 f5 f6 f7) =- rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` f5 `seq` rnf f6 `seq` rnf f7--instance NFData IfaceClassBody where- rnf = \case- IfAbstractClass -> ()- IfConcreteClass f1 f2 f3 f4 -> rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` f4 `seq` ()--instance NFData IfaceAT where- rnf (IfaceAT f1 f2) = rnf f1 `seq` rnf f2--instance NFData IfaceClassOp where- rnf (IfaceClassOp f1 f2 f3) = rnf f1 `seq` rnf f2 `seq` f3 `seq` ()--instance NFData IfaceTyConParent where- rnf = \case- IfNoParent -> ()- IfDataInstance f1 f2 f3 -> rnf f1 `seq` rnf f2 `seq` rnf f3--instance NFData IfaceConDecls where- rnf = \case- IfAbstractTyCon -> ()- IfDataTyCon f1 -> rnf f1- IfNewTyCon f1 -> rnf f1--instance NFData IfaceConDecl where- rnf (IfCon f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11) =- rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` f5 `seq` rnf f6 `seq`- rnf f7 `seq` rnf f8 `seq` f9 `seq` rnf f10 `seq` rnf f11--instance NFData IfaceSrcBang where- rnf (IfSrcBang f1 f2) = f1 `seq` f2 `seq` ()--instance NFData IfaceBang where- rnf x = x `seq` ()--instance NFData IfaceIdDetails where- rnf = \case- IfVanillaId -> ()- IfRecSelId (Left tycon) b -> rnf tycon `seq` rnf b- IfRecSelId (Right decl) b -> rnf decl `seq` rnf b- IfDFunId -> ()--instance NFData IfaceIdInfo where- rnf = \case- NoInfo -> ()- HasInfo f1 -> rnf f1--instance NFData IfaceInfoItem where- rnf = \case- HsArity a -> rnf a- HsStrictness str -> seqStrictSig str- HsInline p -> p `seq` () -- TODO: seq further?- HsUnfold b unf -> rnf b `seq` rnf unf- HsNoCafRefs -> ()- HsLevity -> ()--instance NFData IfaceUnfolding where- rnf = \case- IfCoreUnfold inlinable expr ->- rnf inlinable `seq` rnf expr- IfCompulsory expr ->- rnf expr- IfInlineRule arity b1 b2 e ->- rnf arity `seq` rnf b1 `seq` rnf b2 `seq` rnf e- IfDFunUnfold bndrs exprs ->- rnf bndrs `seq` rnf exprs--instance NFData IfaceExpr where- rnf = \case- IfaceLcl nm -> rnf nm- IfaceExt nm -> rnf nm- IfaceType ty -> rnf ty- IfaceCo co -> rnf co- IfaceTuple sort exprs -> sort `seq` rnf exprs- IfaceLam bndr expr -> rnf bndr `seq` rnf expr- IfaceApp e1 e2 -> rnf e1 `seq` rnf e2- IfaceCase e nm alts -> rnf e `seq` nm `seq` rnf alts- IfaceECase e ty -> rnf e `seq` rnf ty- IfaceLet bind e -> rnf bind `seq` rnf e- IfaceCast e co -> rnf e `seq` rnf co- IfaceLit l -> l `seq` () -- FIXME- IfaceFCall fc ty -> fc `seq` rnf ty- IfaceTick tick e -> rnf tick `seq` rnf e--instance NFData IfaceBinding where- rnf = \case- IfaceNonRec bndr e -> rnf bndr `seq` rnf e- IfaceRec binds -> rnf binds--instance NFData IfaceLetBndr where- rnf (IfLetBndr nm ty id_info join_info) =- rnf nm `seq` rnf ty `seq` rnf id_info `seq` rnf join_info--instance NFData IfaceFamTyConFlav where- rnf = \case- IfaceDataFamilyTyCon -> ()- IfaceOpenSynFamilyTyCon -> ()- IfaceClosedSynFamilyTyCon f1 -> rnf f1- IfaceAbstractClosedSynFamilyTyCon -> ()- IfaceBuiltInSynFamTyCon -> ()--instance NFData IfaceJoinInfo where- rnf x = x `seq` ()--instance NFData IfaceTickish where- rnf = \case- IfaceHpcTick m i -> rnf m `seq` rnf i- IfaceSCC cc b1 b2 -> cc `seq` rnf b1 `seq` rnf b2- IfaceSource src str -> src `seq` rnf str--instance NFData IfaceConAlt where- rnf = \case- IfaceDefault -> ()- IfaceDataAlt nm -> rnf nm- IfaceLitAlt lit -> lit `seq` ()--instance NFData IfaceCompleteMatch where- rnf (IfaceCompleteMatch f1 f2) = rnf f1 `seq` rnf f2--instance NFData IfaceRule where- rnf (IfaceRule f1 f2 f3 f4 f5 f6 f7 f8) =- rnf f1 `seq` f2 `seq` rnf f3 `seq` rnf f4 `seq` rnf f5 `seq` rnf f6 `seq` rnf f7 `seq` f8 `seq` ()--instance NFData IfaceFamInst where- rnf (IfaceFamInst f1 f2 f3 f4) =- rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` f4 `seq` ()--instance NFData IfaceClsInst where- rnf (IfaceClsInst f1 f2 f3 f4 f5) =- f1 `seq` rnf f2 `seq` rnf f3 `seq` f4 `seq` f5 `seq` ()--instance NFData IfaceAnnotation where- rnf (IfaceAnnotation f1 f2) = f1 `seq` f2 `seq` ()
− compiler/iface/IfaceType.hs
@@ -1,2060 +0,0 @@-{--(c) The University of Glasgow 2006-(c) The GRASP/AQUA Project, Glasgow University, 1993-1998---This module defines interface types and binders--}--{-# LANGUAGE CPP, FlexibleInstances, BangPatterns #-}-{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE LambdaCase #-}- -- FlexibleInstances for Binary (DefMethSpec IfaceType)--module IfaceType (- IfExtName, IfLclName,-- IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..),- IfaceMCoercion(..),- IfaceUnivCoProv(..),- IfaceTyCon(..), IfaceTyConInfo(..), IfaceTyConSort(..),- IfaceTyLit(..), IfaceAppArgs(..),- IfaceContext, IfaceBndr(..), IfaceOneShot(..), IfaceLamBndr,- IfaceTvBndr, IfaceIdBndr, IfaceTyConBinder,- IfaceForAllBndr, ArgFlag(..), AnonArgFlag(..),- ForallVisFlag(..), ShowForAllFlag(..),- mkIfaceForAllTvBndr,- mkIfaceTyConKind,-- ifForAllBndrVar, ifForAllBndrName, ifaceBndrName,- ifTyConBinderVar, ifTyConBinderName,-- -- Equality testing- isIfaceLiftedTypeKind,-- -- Conversion from IfaceAppArgs to IfaceTypes/ArgFlags- appArgsIfaceTypes, appArgsIfaceTypesArgFlags,-- -- Printing- SuppressBndrSig(..),- UseBndrParens(..),- pprIfaceType, pprParendIfaceType, pprPrecIfaceType,- pprIfaceContext, pprIfaceContextArr,- pprIfaceIdBndr, pprIfaceLamBndr, pprIfaceTvBndr, pprIfaceTyConBinders,- pprIfaceBndrs, pprIfaceAppArgs, pprParendIfaceAppArgs,- pprIfaceForAllPart, pprIfaceForAllPartMust, pprIfaceForAll,- pprIfaceSigmaType, pprIfaceTyLit,- pprIfaceCoercion, pprParendIfaceCoercion,- splitIfaceSigmaTy, pprIfaceTypeApp, pprUserIfaceForAll,- pprIfaceCoTcApp, pprTyTcApp, pprIfacePrefixApp,- isIfaceTauType,-- suppressIfaceInvisibles,- stripIfaceInvisVars,- stripInvisArgs,-- mkIfaceTySubst, substIfaceTyVar, substIfaceAppArgs, inDomIfaceTySubst- ) where--#include "HsVersions.h"--import GhcPrelude--import {-# SOURCE #-} TysWiredIn ( coercibleTyCon, heqTyCon- , liftedRepDataConTyCon, tupleTyConName )-import {-# SOURCE #-} Type ( isRuntimeRepTy )--import DynFlags-import TyCon hiding ( pprPromotionQuote )-import CoAxiom-import Var-import PrelNames-import Name-import BasicTypes-import Binary-import Outputable-import FastString-import FastStringEnv-import Util--import Data.Maybe( isJust )-import qualified Data.Semigroup as Semi-import Control.DeepSeq--{--************************************************************************-* *- Local (nested) binders-* *-************************************************************************--}--type IfLclName = FastString -- A local name in iface syntax--type IfExtName = Name -- An External or WiredIn Name can appear in IfaceSyn- -- (However Internal or System Names never should)--data IfaceBndr -- Local (non-top-level) binders- = IfaceIdBndr {-# UNPACK #-} !IfaceIdBndr- | IfaceTvBndr {-# UNPACK #-} !IfaceTvBndr--type IfaceIdBndr = (IfLclName, IfaceType)-type IfaceTvBndr = (IfLclName, IfaceKind)--ifaceTvBndrName :: IfaceTvBndr -> IfLclName-ifaceTvBndrName (n,_) = n--ifaceIdBndrName :: IfaceIdBndr -> IfLclName-ifaceIdBndrName (n,_) = n--ifaceBndrName :: IfaceBndr -> IfLclName-ifaceBndrName (IfaceTvBndr bndr) = ifaceTvBndrName bndr-ifaceBndrName (IfaceIdBndr bndr) = ifaceIdBndrName bndr--ifaceBndrType :: IfaceBndr -> IfaceType-ifaceBndrType (IfaceIdBndr (_, t)) = t-ifaceBndrType (IfaceTvBndr (_, t)) = t--type IfaceLamBndr = (IfaceBndr, IfaceOneShot)--data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy- = IfaceNoOneShot -- and Note [The oneShot function] in MkId- | IfaceOneShot---{--%************************************************************************-%* *- IfaceType-%* *-%************************************************************************--}----------------------------------type IfaceKind = IfaceType---- | A kind of universal type, used for types and kinds.------ Any time a 'Type' is pretty-printed, it is first converted to an 'IfaceType'--- before being printed. See Note [Pretty printing via IfaceSyn] in PprTyThing-data IfaceType- = IfaceFreeTyVar TyVar -- See Note [Free tyvars in IfaceType]- | IfaceTyVar IfLclName -- Type/coercion variable only, not tycon- | IfaceLitTy IfaceTyLit- | IfaceAppTy IfaceType IfaceAppArgs- -- See Note [Suppressing invisible arguments] for- -- an explanation of why the second field isn't- -- IfaceType, analogous to AppTy.- | IfaceFunTy AnonArgFlag IfaceType IfaceType- | IfaceForAllTy IfaceForAllBndr IfaceType- | IfaceTyConApp IfaceTyCon IfaceAppArgs -- Not necessarily saturated- -- Includes newtypes, synonyms, tuples- | IfaceCastTy IfaceType IfaceCoercion- | IfaceCoercionTy IfaceCoercion-- | IfaceTupleTy -- Saturated tuples (unsaturated ones use IfaceTyConApp)- TupleSort -- What sort of tuple?- PromotionFlag -- A bit like IfaceTyCon- IfaceAppArgs -- arity = length args- -- For promoted data cons, the kind args are omitted--type IfacePredType = IfaceType-type IfaceContext = [IfacePredType]--data IfaceTyLit- = IfaceNumTyLit Integer- | IfaceStrTyLit FastString- deriving (Eq)--type IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis-type IfaceForAllBndr = VarBndr IfaceBndr ArgFlag---- | Make an 'IfaceForAllBndr' from an 'IfaceTvBndr'.-mkIfaceForAllTvBndr :: ArgFlag -> IfaceTvBndr -> IfaceForAllBndr-mkIfaceForAllTvBndr vis var = Bndr (IfaceTvBndr var) vis---- | Build the 'tyConKind' from the binders and the result kind.--- Keep in sync with 'mkTyConKind' in types/TyCon.-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 (NamedTCB vis)) k = IfaceForAllTy (Bndr tv vis) k---- | Stores the arguments in a type application as a list.--- See @Note [Suppressing invisible arguments]@.-data IfaceAppArgs- = IA_Nil- | IA_Arg IfaceType -- The type argument-- ArgFlag -- The argument's visibility. We store this here so- -- that we can:- --- -- 1. Avoid pretty-printing invisible (i.e., specified- -- or inferred) arguments when- -- -fprint-explicit-kinds isn't enabled, or- -- 2. When -fprint-explicit-kinds *is*, enabled, print- -- specified arguments in @(...) and inferred- -- arguments in @{...}.-- IfaceAppArgs -- The rest of the arguments--instance Semi.Semigroup IfaceAppArgs where- IA_Nil <> xs = xs- IA_Arg ty argf rest <> xs = IA_Arg ty argf (rest Semi.<> xs)--instance Monoid IfaceAppArgs where- mempty = IA_Nil- mappend = (Semi.<>)---- Encodes type constructors, kind constructors,--- coercion constructors, the lot.--- We have to tag them in order to pretty print them--- properly.-data IfaceTyCon = IfaceTyCon { ifaceTyConName :: IfExtName- , ifaceTyConInfo :: IfaceTyConInfo }- deriving (Eq)---- | The various types of TyCons which have special, built-in syntax.-data IfaceTyConSort = IfaceNormalTyCon -- ^ a regular tycon-- | IfaceTupleTyCon !Arity !TupleSort- -- ^ e.g. @(a, b, c)@ or @(#a, b, c#)@.- -- The arity is the tuple width, not the tycon arity- -- (which is twice the width in the case of unboxed- -- tuples).-- | IfaceSumTyCon !Arity- -- ^ e.g. @(a | b | c)@-- | IfaceEqualityTyCon- -- ^ A heterogeneous equality TyCon- -- (i.e. eqPrimTyCon, eqReprPrimTyCon, heqTyCon)- -- that is actually being applied to two types- -- of the same kind. This affects pretty-printing- -- only: see Note [Equality predicates in IfaceType]- deriving (Eq)--{- Note [Free tyvars in IfaceType]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Nowadays (since Nov 16, 2016) we pretty-print a Type by converting to-an IfaceType and pretty printing that. This eliminates a lot of-pretty-print duplication, and it matches what we do with pretty--printing TyThings. See Note [Pretty printing via IfaceSyn] in PprTyThing.--It works fine for closed types, but when printing debug traces (e.g.-when using -ddump-tc-trace) we print a lot of /open/ types. These-types are full of TcTyVars, and it's absolutely crucial to print them-in their full glory, with their unique, TcTyVarDetails etc.--So we simply embed a TyVar in IfaceType with the IfaceFreeTyVar constructor.-Note that:--* We never expect to serialise an IfaceFreeTyVar into an interface file, nor- to deserialise one. IfaceFreeTyVar is used only in the "convert to IfaceType- and then pretty-print" pipeline.--We do the same for covars, naturally.--Note [Equality predicates in IfaceType]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-GHC has several varieties of type equality (see Note [The equality types story]-in TysPrim for details). In an effort to avoid confusing users, we suppress-the differences during pretty printing unless certain flags are enabled.-Here is how each equality predicate* is printed in homogeneous and-heterogeneous contexts, depending on which combination of the--fprint-explicit-kinds and -fprint-equality-relations flags is used:-----------------------------------------------------------------------------------------------| Predicate | Neither flag | -fprint-explicit-kinds |-|-------------------------------|----------------------------|-----------------------------|-| a ~ b (homogeneous) | a ~ b | (a :: Type) ~ (b :: Type) |-| a ~~ b, homogeneously | a ~ b | (a :: Type) ~ (b :: Type) |-| a ~~ b, heterogeneously | a ~~ c | (a :: Type) ~~ (c :: k) |-| a ~# b, homogeneously | a ~ b | (a :: Type) ~ (b :: Type) |-| a ~# b, heterogeneously | a ~~ c | (a :: Type) ~~ (c :: k) |-| Coercible a b (homogeneous) | Coercible a b | Coercible @Type a b |-| a ~R# b, homogeneously | Coercible a b | Coercible @Type a b |-| a ~R# b, heterogeneously | a ~R# b | (a :: Type) ~R# (c :: k) |-|-------------------------------|----------------------------|-----------------------------|-| Predicate | -fprint-equality-relations | Both flags |-|-------------------------------|----------------------------|-----------------------------|-| a ~ b (homogeneous) | a ~ b | (a :: Type) ~ (b :: Type) |-| a ~~ b, homogeneously | a ~~ b | (a :: Type) ~~ (b :: Type) |-| a ~~ b, heterogeneously | a ~~ c | (a :: Type) ~~ (c :: k) |-| a ~# b, homogeneously | a ~# b | (a :: Type) ~# (b :: Type) |-| a ~# b, heterogeneously | a ~# c | (a :: Type) ~# (c :: k) |-| Coercible a b (homogeneous) | Coercible a b | Coercible @Type a b |-| a ~R# b, homogeneously | a ~R# b | (a :: Type) ~R# (b :: Type) |-| a ~R# b, heterogeneously | a ~R# b | (a :: Type) ~R# (c :: k) |-----------------------------------------------------------------------------------------------(* There is no heterogeneous, representational, lifted equality counterpart-to (~~). There could be, but there seems to be no use for it.)--This table adheres to the following rules:--A. With -fprint-equality-relations, print the true equality relation.-B. Without -fprint-equality-relations:- i. If the equality is representational and homogeneous, use Coercible.- ii. Otherwise, if the equality is representational, use ~R#.- iii. If the equality is nominal and homogeneous, use ~.- iv. Otherwise, if the equality is nominal, use ~~.-C. With -fprint-explicit-kinds, print kinds on both sides of an infix operator,- as above; or print the kind with Coercible.-D. Without -fprint-explicit-kinds, don't print kinds.--A hetero-kinded equality is used homogeneously when it is applied to two-identical kinds. Unfortunately, determining this from an IfaceType isn't-possible since we can't see through type synonyms. Consequently, we need to-record whether this particular application is homogeneous in IfaceTyConSort-for the purposes of pretty-printing.--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 :: PromotionFlag- , ifaceTyConSort :: IfaceTyConSort }- deriving (Eq)--data IfaceMCoercion- = IfaceMRefl- | IfaceMCo IfaceCoercion--data IfaceCoercion- = IfaceReflCo IfaceType- | IfaceGReflCo Role IfaceType (IfaceMCoercion)- | IfaceFunCo Role IfaceCoercion IfaceCoercion- | IfaceTyConAppCo Role IfaceTyCon [IfaceCoercion]- | IfaceAppCo IfaceCoercion IfaceCoercion- | IfaceForAllCo IfaceBndr IfaceCoercion IfaceCoercion- | IfaceCoVarCo IfLclName- | IfaceAxiomInstCo IfExtName BranchIndex [IfaceCoercion]- | IfaceAxiomRuleCo IfLclName [IfaceCoercion]- -- There are only a fixed number of CoAxiomRules, so it suffices- -- to use an IfaceLclName to distinguish them.- -- See Note [Adding built-in type families] in TcTypeNats- | IfaceUnivCo IfaceUnivCoProv Role IfaceType IfaceType- | IfaceSymCo IfaceCoercion- | IfaceTransCo IfaceCoercion IfaceCoercion- | IfaceNthCo Int IfaceCoercion- | IfaceLRCo LeftOrRight IfaceCoercion- | IfaceInstCo IfaceCoercion IfaceCoercion- | IfaceKindCo IfaceCoercion- | IfaceSubCo IfaceCoercion- | IfaceFreeCoVar CoVar -- See Note [Free tyvars in IfaceType]- | IfaceHoleCo CoVar -- ^ See Note [Holes in IfaceCoercion]--data IfaceUnivCoProv- = IfaceUnsafeCoerceProv- | IfacePhantomProv IfaceCoercion- | IfaceProofIrrelProv IfaceCoercion- | IfacePluginProv String--{- Note [Holes in IfaceCoercion]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When typechecking fails the typechecker will produce a HoleCo to stand-in place of the unproven assertion. While we generally don't want to-let these unproven assertions leak into interface files, we still need-to be able to pretty-print them as we use IfaceType's pretty-printer-to render Types. For this reason IfaceCoercion has a IfaceHoleCo-constructor; however, we fails when asked to serialize to a-IfaceHoleCo to ensure that they don't end up in an interface file.---%************************************************************************-%* *- Functions over IFaceTypes-* *-************************************************************************--}--ifaceTyConHasKey :: IfaceTyCon -> Unique -> Bool-ifaceTyConHasKey tc key = ifaceTyConName tc `hasKey` key--isIfaceLiftedTypeKind :: IfaceKind -> Bool-isIfaceLiftedTypeKind (IfaceTyConApp tc IA_Nil)- = isLiftedTypeKindTyConName (ifaceTyConName tc)-isIfaceLiftedTypeKind (IfaceTyConApp tc- (IA_Arg (IfaceTyConApp ptr_rep_lifted IA_Nil)- Required IA_Nil))- = tc `ifaceTyConHasKey` tYPETyConKey- && ptr_rep_lifted `ifaceTyConHasKey` liftedRepDataConKey-isIfaceLiftedTypeKind _ = False--splitIfaceSigmaTy :: IfaceType -> ([IfaceForAllBndr], [IfacePredType], IfaceType)--- Mainly for printing purposes------ Here we split nested IfaceSigmaTy properly.------ @--- forall t. T t => forall m a b. M m => (a -> m b) -> t a -> m (t b)--- @------ If you called @splitIfaceSigmaTy@ on this type:------ @--- ([t, m, a, b], [T t, M m], (a -> m b) -> t a -> m (t b))--- @-splitIfaceSigmaTy ty- = case (bndrs, theta) of- ([], []) -> (bndrs, theta, tau)- _ -> let (bndrs', theta', tau') = splitIfaceSigmaTy tau- in (bndrs ++ bndrs', theta ++ theta', tau')- where- (bndrs, rho) = split_foralls ty- (theta, tau) = split_rho rho-- split_foralls (IfaceForAllTy bndr ty)- = case split_foralls ty of { (bndrs, rho) -> (bndr:bndrs, rho) }- split_foralls rho = ([], rho)-- split_rho (IfaceFunTy InvisArg ty1 ty2)- = case split_rho ty2 of { (ps, tau) -> (ty1:ps, tau) }- split_rho tau = ([], tau)--suppressIfaceInvisibles :: DynFlags -> [IfaceTyConBinder] -> [a] -> [a]-suppressIfaceInvisibles dflags tys xs- | gopt Opt_PrintExplicitKinds dflags = xs- | otherwise = suppress tys xs- where- suppress _ [] = []- suppress [] a = a- suppress (k:ks) (x:xs)- | isInvisibleTyConBinder k = suppress ks xs- | otherwise = x : suppress ks xs--stripIfaceInvisVars :: DynFlags -> [IfaceTyConBinder] -> [IfaceTyConBinder]-stripIfaceInvisVars dflags tyvars- | gopt Opt_PrintExplicitKinds dflags = tyvars- | otherwise = filterOut isInvisibleTyConBinder tyvars---- | Extract an 'IfaceBndr' from an 'IfaceForAllBndr'.-ifForAllBndrVar :: IfaceForAllBndr -> IfaceBndr-ifForAllBndrVar = binderVar---- | Extract the variable name from an 'IfaceForAllBndr'.-ifForAllBndrName :: IfaceForAllBndr -> IfLclName-ifForAllBndrName fab = ifaceBndrName (ifForAllBndrVar fab)---- | Extract an 'IfaceBndr' from an 'IfaceTyConBinder'.-ifTyConBinderVar :: IfaceTyConBinder -> IfaceBndr-ifTyConBinderVar = binderVar---- | Extract the variable name from an 'IfaceTyConBinder'.-ifTyConBinderName :: IfaceTyConBinder -> IfLclName-ifTyConBinderName tcb = ifaceBndrName (ifTyConBinderVar tcb)--ifTypeIsVarFree :: IfaceType -> Bool--- Returns True if the type definitely has no variables at all--- Just used to control pretty printing-ifTypeIsVarFree ty = go ty- where- go (IfaceTyVar {}) = False- go (IfaceFreeTyVar {}) = False- go (IfaceAppTy fun args) = go fun && go_args args- go (IfaceFunTy _ arg res) = go arg && go res- go (IfaceForAllTy {}) = False- go (IfaceTyConApp _ args) = go_args args- go (IfaceTupleTy _ _ args) = go_args args- go (IfaceLitTy _) = True- go (IfaceCastTy {}) = False -- Safe- go (IfaceCoercionTy {}) = False -- Safe-- go_args IA_Nil = True- go_args (IA_Arg arg _ args) = go arg && go_args args--{- Note [Substitution on IfaceType]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Substitutions on IfaceType are done only during pretty-printing to-construct the result type of a GADT, and does not deal with binders-(eg IfaceForAll), so it doesn't need fancy capture stuff. -}--type IfaceTySubst = FastStringEnv IfaceType -- Note [Substitution on IfaceType]--mkIfaceTySubst :: [(IfLclName,IfaceType)] -> IfaceTySubst--- See Note [Substitution on IfaceType]-mkIfaceTySubst eq_spec = mkFsEnv eq_spec--inDomIfaceTySubst :: IfaceTySubst -> IfaceTvBndr -> Bool--- See Note [Substitution on IfaceType]-inDomIfaceTySubst subst (fs, _) = isJust (lookupFsEnv subst fs)--substIfaceType :: IfaceTySubst -> IfaceType -> IfaceType--- See Note [Substitution on IfaceType]-substIfaceType env ty- = go ty- where- 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 ty@(IfaceLitTy {}) = ty- go (IfaceTyConApp tc tys) = IfaceTyConApp tc (substIfaceAppArgs env tys)- go (IfaceTupleTy s i tys) = IfaceTupleTy s i (substIfaceAppArgs env tys)- go (IfaceForAllTy {}) = pprPanic "substIfaceType" (ppr ty)- go (IfaceCastTy ty co) = IfaceCastTy (go ty) (go_co co)- go (IfaceCoercionTy co) = IfaceCoercionTy (go_co co)-- go_mco IfaceMRefl = IfaceMRefl- go_mco (IfaceMCo co) = IfaceMCo $ go_co co-- 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 (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)- go_co (IfaceFreeCoVar cv) = IfaceFreeCoVar cv- go_co (IfaceCoVarCo cv) = IfaceCoVarCo cv- go_co (IfaceHoleCo cv) = IfaceHoleCo cv- go_co (IfaceAxiomInstCo a i cos) = IfaceAxiomInstCo a i (go_cos cos)- go_co (IfaceUnivCo prov r t1 t2) = IfaceUnivCo (go_prov prov) r (go t1) (go t2)- go_co (IfaceSymCo co) = IfaceSymCo (go_co co)- go_co (IfaceTransCo co1 co2) = IfaceTransCo (go_co co1) (go_co co2)- go_co (IfaceNthCo n co) = IfaceNthCo n (go_co co)- go_co (IfaceLRCo lr co) = IfaceLRCo lr (go_co co)- go_co (IfaceInstCo c1 c2) = IfaceInstCo (go_co c1) (go_co c2)- go_co (IfaceKindCo co) = IfaceKindCo (go_co co)- go_co (IfaceSubCo co) = IfaceSubCo (go_co co)- go_co (IfaceAxiomRuleCo n cos) = IfaceAxiomRuleCo n (go_cos cos)-- go_cos = map go_co-- go_prov IfaceUnsafeCoerceProv = IfaceUnsafeCoerceProv- go_prov (IfacePhantomProv co) = IfacePhantomProv (go_co co)- go_prov (IfaceProofIrrelProv co) = IfaceProofIrrelProv (go_co co)- go_prov (IfacePluginProv str) = IfacePluginProv str--substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs-substIfaceAppArgs env args- = go args- where- go IA_Nil = IA_Nil- go (IA_Arg ty arg tys) = IA_Arg (substIfaceType env ty) arg (go tys)--substIfaceTyVar :: IfaceTySubst -> IfLclName -> IfaceType-substIfaceTyVar env tv- | Just ty <- lookupFsEnv env tv = ty- | otherwise = IfaceTyVar tv---{--************************************************************************-* *- Functions over IfaceAppArgs-* *-************************************************************************--}--stripInvisArgs :: DynFlags -> IfaceAppArgs -> IfaceAppArgs-stripInvisArgs dflags tys- | gopt Opt_PrintExplicitKinds dflags = tys- | otherwise = suppress_invis tys- where- suppress_invis c- = case c of- IA_Nil -> IA_Nil- IA_Arg t argf ts- | isVisibleArgFlag argf- -> IA_Arg t argf $ suppress_invis ts- -- Keep recursing through the remainder of the arguments, as it's- -- possible that there are remaining invisible ones.- -- See the "In type declarations" section of Note [VarBndrs,- -- TyCoVarBinders, TyConBinders, and visibility] in TyCoRep.- | otherwise- -> suppress_invis ts--appArgsIfaceTypes :: IfaceAppArgs -> [IfaceType]-appArgsIfaceTypes IA_Nil = []-appArgsIfaceTypes (IA_Arg t _ ts) = t : appArgsIfaceTypes ts--appArgsIfaceTypesArgFlags :: IfaceAppArgs -> [(IfaceType, ArgFlag)]-appArgsIfaceTypesArgFlags IA_Nil = []-appArgsIfaceTypesArgFlags (IA_Arg t a ts)- = (t, a) : appArgsIfaceTypesArgFlags ts--ifaceVisAppArgsLength :: IfaceAppArgs -> Int-ifaceVisAppArgsLength = go 0- where- go !n IA_Nil = n- go n (IA_Arg _ argf rest)- | isVisibleArgFlag argf = go (n+1) rest- | otherwise = go n rest--{--Note [Suppressing invisible arguments]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We use the IfaceAppArgs data type to specify which of the arguments to a type-should be displayed when pretty-printing, under the control of--fprint-explicit-kinds.-See also Type.filterOutInvisibleTypes.-For example, given-- T :: forall k. (k->*) -> k -> * -- Ordinary kind polymorphism- 'Just :: forall k. k -> 'Maybe k -- Promoted--we want-- T * Tree Int prints as T Tree Int- 'Just * prints as Just *--For type constructors (IfaceTyConApp), IfaceAppArgs is a quite natural fit,-since the corresponding Core constructor:-- data Type- = ...- | TyConApp TyCon [Type]--Already puts all of its arguments into a list. So when converting a Type to an-IfaceType (see toIfaceAppArgsX in ToIface), we simply use the kind of the TyCon-(which is cached) to guide the process of converting the argument Types into an-IfaceAppArgs list.--We also want this behavior for IfaceAppTy, since given:-- data Proxy (a :: k)- f :: forall (t :: forall a. a -> Type). Proxy Type (t Bool True)--We want to print the return type as `Proxy (t True)` without the use of--fprint-explicit-kinds (#15330). Accomplishing this is trickier than in the-tycon case, because the corresponding Core constructor for IfaceAppTy:-- data Type- = ...- | AppTy Type Type--Only stores one argument at a time. Therefore, when converting an AppTy to an-IfaceAppTy (in toIfaceTypeX in ToIface), we:--1. Flatten the chain of AppTys down as much as possible-2. Use typeKind to determine the function Type's kind-3. Use this kind to guide the process of converting the argument Types into an- IfaceAppArgs list.--By flattening the arguments like this, we obtain two benefits:--(a) We can reuse the same machinery to pretty-print IfaceTyConApp arguments as- we do IfaceTyApp arguments, which means that we only need to implement the- logic to filter out invisible arguments once.-(b) Unlike for tycons, finding the kind of a type in general (through typeKind)- is not a constant-time operation, so by flattening the arguments first, we- decrease the number of times we have to call typeKind.--Note [Pretty-printing invisible arguments]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Note [Suppressing invisible arguments] is all about how to avoid printing-invisible arguments when the -fprint-explicit-kinds flag is disables. Well,-what about when it's enabled? Then we can and should print invisible kind-arguments, and this Note explains how we do it.--As two running examples, consider the following code:-- {-# LANGUAGE PolyKinds #-}- data T1 a- data T2 (a :: k)--When displaying these types (with -fprint-explicit-kinds on), we could just-do the following:-- T1 k a- T2 k a--That certainly gets the job done. But it lacks a crucial piece of information:-is the `k` argument inferred or specified? To communicate this, we use visible-kind application syntax to distinguish the two cases:-- T1 @{k} a- T2 @k a--Here, @{k} indicates that `k` is an inferred argument, and @k indicates that-`k` is a specified argument. (See-Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in TyCoRep for-a lengthier explanation on what "inferred" and "specified" mean.)--************************************************************************-* *- Pretty-printing-* *-************************************************************************--}--if_print_coercions :: SDoc -- ^ if printing coercions- -> SDoc -- ^ otherwise- -> SDoc-if_print_coercions yes no- = sdocWithDynFlags $ \dflags ->- getPprStyle $ \style ->- if gopt Opt_PrintExplicitCoercions dflags- || dumpStyle style || debugStyle style- then yes- else no--pprIfaceInfixApp :: PprPrec -> SDoc -> SDoc -> SDoc -> SDoc-pprIfaceInfixApp ctxt_prec pp_tc pp_ty1 pp_ty2- = maybeParen ctxt_prec opPrec $- sep [pp_ty1, pp_tc <+> pp_ty2]--pprIfacePrefixApp :: PprPrec -> SDoc -> [SDoc] -> SDoc-pprIfacePrefixApp ctxt_prec pp_fun pp_tys- | null pp_tys = pp_fun- | otherwise = maybeParen ctxt_prec appPrec $- hang pp_fun 2 (sep pp_tys)--isIfaceTauType :: IfaceType -> Bool-isIfaceTauType (IfaceForAllTy _ _) = False-isIfaceTauType (IfaceFunTy InvisArg _ _) = False-isIfaceTauType _ = True---- ----------------------------- Printing binders --------------------------------------instance Outputable IfaceBndr where- ppr (IfaceIdBndr bndr) = pprIfaceIdBndr bndr- ppr (IfaceTvBndr bndr) = char '@' <+> pprIfaceTvBndr bndr (SuppressBndrSig False)- (UseBndrParens False)--pprIfaceBndrs :: [IfaceBndr] -> SDoc-pprIfaceBndrs bs = sep (map ppr bs)--pprIfaceLamBndr :: IfaceLamBndr -> SDoc-pprIfaceLamBndr (b, IfaceNoOneShot) = ppr b-pprIfaceLamBndr (b, IfaceOneShot) = ppr b <> text "[OneShot]"--pprIfaceIdBndr :: IfaceIdBndr -> SDoc-pprIfaceIdBndr (name, ty) = parens (ppr name <+> dcolon <+> ppr ty)--{- Note [Suppressing binder signatures]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-When printing the binders in a 'forall', we want to keep the kind annotations:-- forall (a :: k). blah- ^^^^- good--On the other hand, when we print the binders of a data declaration in :info,-the kind information would be redundant due to the standalone kind signature:-- type F :: Symbol -> Type- type F (s :: Symbol) = blah- ^^^^^^^^^- redundant--Here we'd like to omit the kind annotation:-- type F :: Symbol -> Type- type F s = blah--}---- | Do we want to suppress kind annotations on binders?--- See Note [Suppressing binder signatures]-newtype SuppressBndrSig = SuppressBndrSig Bool--newtype UseBndrParens = UseBndrParens Bool--pprIfaceTvBndr :: IfaceTvBndr -> SuppressBndrSig -> UseBndrParens -> SDoc-pprIfaceTvBndr (tv, ki) (SuppressBndrSig suppress_sig) (UseBndrParens use_parens)- | suppress_sig = ppr tv- | isIfaceLiftedTypeKind ki = ppr tv- | otherwise = maybe_parens (ppr tv <+> dcolon <+> ppr ki)- where- maybe_parens | use_parens = parens- | otherwise = id--pprIfaceTyConBinders :: SuppressBndrSig -> [IfaceTyConBinder] -> SDoc-pprIfaceTyConBinders suppress_sig = sep . map go- where- go :: IfaceTyConBinder -> SDoc- go (Bndr (IfaceIdBndr bndr) _) = pprIfaceIdBndr bndr- go (Bndr (IfaceTvBndr bndr) vis) =- -- See Note [Pretty-printing invisible arguments]- case vis of- AnonTCB VisArg -> ppr_bndr (UseBndrParens True)- AnonTCB InvisArg -> char '@' <> braces (ppr_bndr (UseBndrParens False))- -- The above case is rare. (See Note [AnonTCB InvisArg] in TyCon.)- -- Should we print these differently?- NamedTCB Required -> ppr_bndr (UseBndrParens True)- NamedTCB Specified -> char '@' <> ppr_bndr (UseBndrParens True)- NamedTCB Inferred -> char '@' <> braces (ppr_bndr (UseBndrParens False))- where- ppr_bndr = pprIfaceTvBndr bndr suppress_sig--instance Binary IfaceBndr where- put_ bh (IfaceIdBndr aa) = do- putByte bh 0- put_ bh aa- put_ bh (IfaceTvBndr ab) = do- putByte bh 1- put_ bh ab- get bh = do- h <- getByte bh- case h of- 0 -> do aa <- get bh- return (IfaceIdBndr aa)- _ -> do ab <- get bh- return (IfaceTvBndr ab)--instance Binary IfaceOneShot where- put_ bh IfaceNoOneShot = do- putByte bh 0- put_ bh IfaceOneShot = do- putByte bh 1- get bh = do- h <- getByte bh- case h of- 0 -> do return IfaceNoOneShot- _ -> do return IfaceOneShot---- ----------------------------- Printing IfaceType ------------------------------------------------------------------------instance Outputable IfaceType where- ppr ty = pprIfaceType ty--pprIfaceType, pprParendIfaceType :: IfaceType -> SDoc-pprIfaceType = pprPrecIfaceType topPrec-pprParendIfaceType = pprPrecIfaceType appPrec--pprPrecIfaceType :: PprPrec -> IfaceType -> SDoc--- We still need `eliminateRuntimeRep`, since the `pprPrecIfaceType` maybe--- called from other places, besides `:type` and `:info`.-pprPrecIfaceType prec ty = eliminateRuntimeRep (ppr_ty prec) ty--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 _ (IfaceFreeTyVar tyvar) = ppr tyvar -- This is the main reason for IfaceFreeTyVar!-ppr_ty _ (IfaceTyVar tyvar) = ppr tyvar -- See Note [TcTyVars in IfaceType]-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- = -- 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)]- 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_ty ctxt_prec (IfaceAppTy t ts)- = if_print_coercions- ppr_app_ty- ppr_app_ty_no_casts- where- ppr_app_ty =- sdocWithDynFlags $ \dflags ->- pprIfacePrefixApp ctxt_prec- (ppr_ty funPrec t)- (map (ppr_app_arg appPrec) (tys_wo_kinds dflags))-- tys_wo_kinds dflags = appArgsIfaceTypesArgFlags $ stripInvisArgs dflags ts-- -- Strip any casts from the head of the application- ppr_app_ty_no_casts =- case t of- IfaceCastTy head _ -> ppr_ty ctxt_prec (mk_app_tys head ts)- _ -> ppr_app_ty-- mk_app_tys :: IfaceType -> IfaceAppArgs -> IfaceType- mk_app_tys (IfaceTyConApp tc tys1) tys2 =- IfaceTyConApp tc (tys1 `mappend` tys2)- mk_app_tys t1 tys2 = IfaceAppTy t1 tys2--ppr_ty ctxt_prec (IfaceCastTy ty co)- = if_print_coercions- (parens (ppr_ty topPrec ty <+> text "|>" <+> ppr co))- (ppr_ty ctxt_prec ty)--ppr_ty ctxt_prec (IfaceCoercionTy co)- = if_print_coercions- (ppr_co ctxt_prec co)- (text "<>")--{- Note [Defaulting RuntimeRep variables]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-RuntimeRep variables are considered by many (most?) users to be little-more than syntactic noise. When the notion was introduced there was a-significant and understandable push-back from those with pedagogy in-mind, which argued that RuntimeRep variables would throw a wrench into-nearly any teach approach since they appear in even the lowly ($)-function's type,-- ($) :: forall (w :: RuntimeRep) a (b :: TYPE w). (a -> b) -> a -> b--which is significantly less readable than its non RuntimeRep-polymorphic type of-- ($) :: (a -> b) -> a -> b--Moreover, unboxed types don't appear all that often in run-of-the-mill-Haskell programs, so it makes little sense to make all users pay this-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)--This applies to /quantified/ variables like 'w' above. What about-variables that are /free/ in the type being printed, which certainly-happens in error messages. Suppose (#16074) we are reporting a-mismatch between two skolems- (a :: RuntimeRep) ~ (b :: RuntimeRep)-We certainly don't want to say "Can't match LiftedRep ~ LiftedRep"!--But if we are printing the type- (forall (a :: Type r). blah-we do want to turn that (free) r into LiftedRep, so it prints as- (forall a. blah)--Conclusion: keep track of whether we we are in the kind of a-binder; ohly if so, convert free RuntimeRep variables to LiftedRep.--}---- | Default 'RuntimeRep' variables to 'LiftedPtr'. e.g.------ @--- ($) :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r).--- (a -> b) -> a -> b--- @------ turns in to,------ @ ($) :: forall a (b :: *). (a -> b) -> a -> b @------ 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- where- go :: Bool -- True <=> Inside the kind of a binder- -> FastStringEnv () -- Set of enclosing forall-ed RuntimeRep variables- -> IfaceType -- (replace them with LiftedRep)- -> IfaceType- go ink subs (IfaceForAllTy (Bndr (IfaceTvBndr (var, var_kind)) argf) ty)- | isRuntimeRep var_kind- , isInvisibleArgFlag argf -- Don't default *visible* quantification- -- or we get the mess in #13963- = let subs' = extendFsEnv subs var ()- -- Record that we should replace it with LiftedRep,- -- and recurse, discarding the forall- in go ink subs' 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 in_kind _ ty@(IfaceFreeTyVar tv)- -- See Note [Defaulting RuntimeRep variables], about free vars- | in_kind && Type.isRuntimeRepTy (tyVarKind tv)- = IfaceTyConApp liftedRep IA_Nil- | otherwise- = ty-- go ink subs (IfaceTyConApp tc tc_args)- = IfaceTyConApp tc (go_args ink subs tc_args)-- 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 (IfaceAppTy t ts)- = IfaceAppTy (go ink subs t) (go_args ink subs ts)-- go ink subs (IfaceCastTy x co)- = IfaceCastTy (go ink subs x) co-- 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 subs (Bndr (IfaceTvBndr (n, t)) argf)- = Bndr (IfaceTvBndr (n, go True subs t)) argf-- go_args :: Bool -> FastStringEnv () -> 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- = sdocWithDynFlags $ \dflags ->- getPprStyle $ \sty ->- if userStyle sty && not (gopt Opt_PrintExplicitRuntimeReps dflags)- then f (defaultRuntimeRepVars ty)- else f ty--instance Outputable IfaceAppArgs where- ppr tca = pprIfaceAppArgs tca--pprIfaceAppArgs, pprParendIfaceAppArgs :: IfaceAppArgs -> SDoc-pprIfaceAppArgs = ppr_app_args topPrec-pprParendIfaceAppArgs = ppr_app_args appPrec--ppr_app_args :: PprPrec -> IfaceAppArgs -> SDoc-ppr_app_args ctx_prec = go- where- go :: IfaceAppArgs -> SDoc- go IA_Nil = empty- go (IA_Arg t argf ts) = ppr_app_arg ctx_prec (t, argf) <+> go ts---- See Note [Pretty-printing invisible arguments]-ppr_app_arg :: PprPrec -> (IfaceType, ArgFlag) -> SDoc-ppr_app_arg ctx_prec (t, argf) =- sdocWithDynFlags $ \dflags ->- let print_kinds = gopt Opt_PrintExplicitKinds dflags- in case argf of- Required -> ppr_ty ctx_prec t- Specified | print_kinds- -> char '@' <> ppr_ty appPrec t- Inferred | print_kinds- -> char '@' <> braces (ppr_ty topPrec t)- _ -> empty----------------------pprIfaceForAllPart :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc-pprIfaceForAllPart tvs ctxt sdoc- = ppr_iface_forall_part ShowForAllWhen tvs ctxt sdoc---- | Like 'pprIfaceForAllPart', but always uses an explicit @forall@.-pprIfaceForAllPartMust :: [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc-pprIfaceForAllPartMust tvs ctxt sdoc- = ppr_iface_forall_part ShowForAllMust tvs ctxt sdoc--pprIfaceForAllCoPart :: [(IfLclName, IfaceCoercion)] -> SDoc -> SDoc-pprIfaceForAllCoPart tvs sdoc- = sep [ pprIfaceForAllCo tvs, sdoc ]--ppr_iface_forall_part :: ShowForAllFlag- -> [IfaceForAllBndr] -> [IfacePredType] -> SDoc -> SDoc-ppr_iface_forall_part show_forall tvs ctxt sdoc- = sep [ case show_forall of- ShowForAllMust -> pprIfaceForAll tvs- ShowForAllWhen -> pprUserIfaceForAll tvs- , pprIfaceContextArr ctxt- , sdoc]---- | Render the "forall ... ." or "forall ... ->" bit of a type.-pprIfaceForAll :: [IfaceForAllBndr] -> SDoc-pprIfaceForAll [] = empty-pprIfaceForAll bndrs@(Bndr _ vis : _)- = sep [ add_separator (forAllLit <+> fsep docs)- , pprIfaceForAll bndrs' ]- where- (bndrs', docs) = ppr_itv_bndrs bndrs vis-- add_separator stuff = case vis of- Required -> stuff <+> arrow- _inv -> stuff <> dot----- | Render the ... in @(forall ... .)@ or @(forall ... ->)@.--- Returns both the list of not-yet-rendered binders and the doc.--- No anonymous binders here!-ppr_itv_bndrs :: [IfaceForAllBndr]- -> ArgFlag -- ^ visibility of the first binder in the list- -> ([IfaceForAllBndr], [SDoc])-ppr_itv_bndrs all_bndrs@(bndr@(Bndr _ vis) : bndrs) vis1- | vis `sameVis` vis1 = let (bndrs', doc) = ppr_itv_bndrs bndrs vis1 in- (bndrs', pprIfaceForAllBndr bndr : doc)- | otherwise = (all_bndrs, [])-ppr_itv_bndrs [] _ = ([], [])--pprIfaceForAllCo :: [(IfLclName, IfaceCoercion)] -> SDoc-pprIfaceForAllCo [] = empty-pprIfaceForAllCo tvs = text "forall" <+> pprIfaceForAllCoBndrs tvs <> dot--pprIfaceForAllCoBndrs :: [(IfLclName, IfaceCoercion)] -> SDoc-pprIfaceForAllCoBndrs bndrs = hsep $ map pprIfaceForAllCoBndr bndrs--pprIfaceForAllBndr :: IfaceForAllBndr -> SDoc-pprIfaceForAllBndr bndr =- case bndr of- Bndr (IfaceTvBndr tv) Inferred ->- sdocWithDynFlags $ \dflags ->- if gopt Opt_PrintExplicitForalls dflags- then braces $ pprIfaceTvBndr tv suppress_sig (UseBndrParens False)- else pprIfaceTvBndr tv suppress_sig (UseBndrParens True)- Bndr (IfaceTvBndr tv) _ ->- pprIfaceTvBndr tv suppress_sig (UseBndrParens True)- Bndr (IfaceIdBndr idv) _ -> pprIfaceIdBndr idv- where- -- See Note [Suppressing binder signatures] in IfaceType- suppress_sig = SuppressBndrSig False--pprIfaceForAllCoBndr :: (IfLclName, IfaceCoercion) -> SDoc-pprIfaceForAllCoBndr (tv, kind_co)- = parens (ppr tv <+> dcolon <+> pprIfaceCoercion kind_co)---- | Show forall flag------ Unconditionally show the forall quantifier with ('ShowForAllMust')--- or when ('ShowForAllWhen') the names used are free in the binder--- or when compiling with -fprint-explicit-foralls.-data ShowForAllFlag = ShowForAllMust | ShowForAllWhen--pprIfaceSigmaType :: ShowForAllFlag -> IfaceType -> SDoc-pprIfaceSigmaType show_forall ty- = eliminateRuntimeRep ppr_fn ty- where- ppr_fn iface_ty =- let (tvs, theta, tau) = splitIfaceSigmaTy iface_ty- in ppr_iface_forall_part show_forall tvs theta (ppr tau)--pprUserIfaceForAll :: [IfaceForAllBndr] -> SDoc-pprUserIfaceForAll tvs- = sdocWithDynFlags $ \dflags ->- -- See Note [When to print foralls] in this module.- ppWhen (any tv_has_kind_var tvs- || any tv_is_required tvs- || gopt Opt_PrintExplicitForalls dflags) $- pprIfaceForAll tvs- where- tv_has_kind_var (Bndr (IfaceTvBndr (_,kind)) _)- = not (ifTypeIsVarFree kind)- tv_has_kind_var _ = False-- tv_is_required = isVisibleArgFlag . binderArgFlag--{--Note [When to print foralls]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We opt to explicitly pretty-print `forall`s if any of the following-criteria are met:--1. -fprint-explicit-foralls is on.--2. A bound type variable has a polymorphic kind. E.g.,-- forall k (a::k). Proxy a -> Proxy a-- Since a's kind mentions a variable k, we print the foralls.--3. A bound type variable is a visible argument (#14238).- Suppose we are printing the kind of:-- T :: forall k -> k -> Type-- The "forall k ->" notation means that this kind argument is required.- That is, it must be supplied at uses of T. E.g.,-- f :: T (Type->Type) Monad -> Int-- So we print an explicit "T :: forall k -> k -> Type",- because omitting it and printing "T :: k -> Type" would be- utterly misleading.-- See Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility]- in TyCoRep.--N.B. Until now (Aug 2018) we didn't check anything for coercion variables.--Note [Printing foralls in type family instances]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We use the same criteria as in Note [When to print foralls] to determine-whether a type family instance should be pretty-printed with an explicit-`forall`. Example:-- type family Foo (a :: k) :: k where- Foo Maybe = []- Foo (a :: Type) = Int- Foo a = a--Without -fprint-explicit-foralls enabled, this will be pretty-printed as:--type family Foo (a :: k) :: k where- Foo Maybe = []- Foo a = Int- forall k (a :: k). Foo a = a--Note that only the third equation has an explicit forall, since it has a type-variable with a non-Type kind. (If -fprint-explicit-foralls were enabled, then-the second equation would be preceded with `forall a.`.)--There is one tricky point in the implementation: what visibility-do we give the type variables in a type family instance? Type family instances-only store type *variables*, not type variable *binders*, and only the latter-has visibility information. We opt to default the visibility of each of these-type variables to Specified because users can't ever instantiate these-variables manually, so the choice of visibility is only relevant to-pretty-printing. (This is why the `k` in `forall k (a :: k). ...` above is-printed the way it is, even though it wasn't written explicitly in the-original source code.)--We adopt the same strategy for data family instances. Example:-- data family DF (a :: k)- data instance DF '[a, b] = DFList--That data family instance is pretty-printed as:-- data instance forall j (a :: j) (b :: j). DF '[a, b] = DFList--This is despite that the representation tycon for this data instance (call it-$DF:List) actually has different visibilities for its binders.-However, the visibilities of these binders are utterly irrelevant to the-programmer, who cares only about the specificity of variables in `DF`'s type,-not $DF:List's type. Therefore, we opt to pretty-print all variables in data-family instances as Specified.--Note [Printing promoted type constructors]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider this GHCi session (#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- IsPromoted -> (space <>)- _ -> id-pprSpaceIfPromotedTyCon _- = id---- See equivalent function in TyCoRep.hs-pprIfaceTyList :: PprPrec -> IfaceType -> IfaceType -> SDoc--- Given a type-level list (t1 ': t2), see if we can print--- it in list notation [t1, ...].--- Precondition: Opt_PrintExplicitKinds is off-pprIfaceTyList ctxt_prec ty1 ty2- = case gather ty2 of- (arg_tys, Nothing)- -> char '\'' <> brackets (pprSpaceIfPromotedTyCon ty1 (fsep- (punctuate comma (map (ppr_ty topPrec) (ty1:arg_tys)))))- (arg_tys, Just tl)- -> maybeParen ctxt_prec funPrec $ hang (ppr_ty funPrec ty1)- 2 (fsep [ colon <+> ppr_ty funPrec ty | ty <- arg_tys ++ [tl]])- where- gather :: IfaceType -> ([IfaceType], Maybe IfaceType)- -- (gather ty) = (tys, Nothing) means ty is a list [t1, .., tn]- -- = (tys, Just tl) means ty is of form t1:t2:...tn:tl- gather (IfaceTyConApp tc tys)- | tc `ifaceTyConHasKey` consDataConKey- , IA_Arg _ argf (IA_Arg ty1 Required (IA_Arg ty2 Required IA_Nil)) <- tys- , isInvisibleArgFlag argf- , (args, tl) <- gather ty2- = (ty1:args, tl)- | tc `ifaceTyConHasKey` nilDataConKey- = ([], Nothing)- gather ty = ([], Just ty)--pprIfaceTypeApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc-pprIfaceTypeApp prec tc args = pprTyTcApp prec tc args--pprTyTcApp :: PprPrec -> IfaceTyCon -> IfaceAppArgs -> SDoc-pprTyTcApp ctxt_prec tc tys =- sdocWithDynFlags $ \dflags ->- getPprStyle $ \style ->- pprTyTcApp' ctxt_prec tc tys dflags style--pprTyTcApp' :: PprPrec -> IfaceTyCon -> IfaceAppArgs- -> DynFlags -> PprStyle -> SDoc-pprTyTcApp' ctxt_prec tc tys dflags style- | ifaceTyConName tc `hasKey` ipClassKey- , IA_Arg (IfaceLitTy (IfaceStrTyLit n))- Required (IA_Arg ty Required IA_Nil) <- tys- = maybeParen ctxt_prec funPrec- $ char '?' <> ftext n <> text "::" <> ppr_ty topPrec ty-- | IfaceTupleTyCon arity sort <- ifaceTyConSort info- , not (debugStyle style)- , arity == ifaceVisAppArgsLength tys- = pprTuple ctxt_prec sort (ifaceTyConIsPromoted info) tys-- | IfaceSumTyCon arity <- ifaceTyConSort info- = pprSum arity (ifaceTyConIsPromoted info) tys-- | tc `ifaceTyConHasKey` consDataConKey- , not (gopt Opt_PrintExplicitKinds dflags)- , IA_Arg _ argf (IA_Arg ty1 Required (IA_Arg ty2 Required IA_Nil)) <- tys- , isInvisibleArgFlag argf- = pprIfaceTyList ctxt_prec ty1 ty2-- | tc `ifaceTyConHasKey` tYPETyConKey- , IA_Arg (IfaceTyConApp rep IA_Nil) Required IA_Nil <- tys- , rep `ifaceTyConHasKey` liftedRepDataConKey- = ppr_kind_type ctxt_prec-- | otherwise- = getPprDebug $ \dbg ->- if | not dbg && tc `ifaceTyConHasKey` errorMessageTypeErrorFamKey- -- Suppress detail unles you _really_ want to see- -> text "(TypeError ...)"-- | Just doc <- ppr_equality ctxt_prec tc (appArgsIfaceTypes tys)- -> doc-- | otherwise- -> ppr_iface_tc_app ppr_app_arg ctxt_prec tc tys_wo_kinds- where- info = ifaceTyConInfo tc- tys_wo_kinds = appArgsIfaceTypesArgFlags $ stripInvisArgs dflags tys--ppr_kind_type :: PprPrec -> SDoc-ppr_kind_type ctxt_prec =- sdocWithDynFlags $ \dflags ->- if useStarIsType dflags- then maybeParen ctxt_prec starPrec $- unicodeSyntax (char '★') (char '*')- else text "Type"---- | Pretty-print a type-level equality.--- Returns (Just doc) if the argument is a /saturated/ application--- of eqTyCon (~)--- eqPrimTyCon (~#)--- eqReprPrimTyCon (~R#)--- heqTyCon (~~)------ See Note [Equality predicates in IfaceType]--- and Note [The equality types story] in TysPrim-ppr_equality :: PprPrec -> IfaceTyCon -> [IfaceType] -> Maybe SDoc-ppr_equality ctxt_prec tc args- | hetero_eq_tc- , [k1, k2, t1, t2] <- args- = Just $ print_equality (k1, k2, t1, t2)-- | hom_eq_tc- , [k, t1, t2] <- args- = Just $ print_equality (k, k, t1, t2)-- | otherwise- = Nothing- where- homogeneous = tc_name `hasKey` eqTyConKey -- (~)- || hetero_tc_used_homogeneously- where- hetero_tc_used_homogeneously- = case ifaceTyConSort $ ifaceTyConInfo tc of- IfaceEqualityTyCon -> True- _other -> False- -- True <=> a heterogeneous equality whose arguments- -- are (in this case) of the same kind-- tc_name = ifaceTyConName tc- pp = ppr_ty- hom_eq_tc = tc_name `hasKey` eqTyConKey -- (~)- hetero_eq_tc = tc_name `hasKey` eqPrimTyConKey -- (~#)- || tc_name `hasKey` eqReprPrimTyConKey -- (~R#)- || tc_name `hasKey` heqTyConKey -- (~~)- nominal_eq_tc = tc_name `hasKey` heqTyConKey -- (~~)- || tc_name `hasKey` eqPrimTyConKey -- (~#)- print_equality args =- sdocWithDynFlags $ \dflags ->- getPprStyle $ \style ->- print_equality' args style dflags-- print_equality' (ki1, ki2, ty1, ty2) style dflags- | -- If -fprint-equality-relations is on, just print the original TyCon- print_eqs- = ppr_infix_eq (ppr tc)-- | -- Homogeneous use of heterogeneous equality (ty1 ~~ ty2)- -- or unlifted equality (ty1 ~# ty2)- nominal_eq_tc, homogeneous- = ppr_infix_eq (text "~")-- | -- Heterogeneous use of unlifted equality (ty1 ~# ty2)- not homogeneous- = ppr_infix_eq (ppr heqTyCon)-- | -- Homogeneous use of representational unlifted equality (ty1 ~R# ty2)- tc_name `hasKey` eqReprPrimTyConKey, homogeneous- = let ki | print_kinds = [pp appPrec ki1]- | otherwise = []- in pprIfacePrefixApp ctxt_prec (ppr coercibleTyCon)- (ki ++ [pp appPrec ty1, pp appPrec ty2])-- -- The other cases work as you'd expect- | otherwise- = ppr_infix_eq (ppr tc)- where- ppr_infix_eq :: SDoc -> SDoc- ppr_infix_eq eq_op = pprIfaceInfixApp ctxt_prec eq_op- (pp_ty_ki ty1 ki1) (pp_ty_ki ty2 ki2)- where- pp_ty_ki ty ki- | print_kinds- = parens (pp topPrec ty <+> dcolon <+> pp opPrec ki)- | otherwise- = pp opPrec ty-- print_kinds = gopt Opt_PrintExplicitKinds dflags- print_eqs = gopt Opt_PrintEqualityRelations dflags ||- dumpStyle style || debugStyle style---pprIfaceCoTcApp :: PprPrec -> IfaceTyCon -> [IfaceCoercion] -> SDoc-pprIfaceCoTcApp ctxt_prec tc tys =- ppr_iface_tc_app (\prec (co, _) -> ppr_co prec co) ctxt_prec tc- (map (, Required) tys)- -- We are trying to re-use ppr_iface_tc_app here, which requires its- -- arguments to be accompanied by visibilities. But visibility is- -- irrelevant when printing coercions, so just default everything to- -- Required.---- | Pretty-prints an application of a type constructor to some arguments--- (whose visibilities are known). This is polymorphic (over @a@) since we use--- this function to pretty-print two different things:------ 1. Types (from `pprTyTcApp'`)------ 2. Coercions (from 'pprIfaceCoTcApp')-ppr_iface_tc_app :: (PprPrec -> (a, ArgFlag) -> SDoc)- -> PprPrec -> IfaceTyCon -> [(a, ArgFlag)] -> SDoc-ppr_iface_tc_app pp _ tc [ty]- | tc `ifaceTyConHasKey` listTyConKey = pprPromotionQuote tc <> brackets (pp topPrec ty)--ppr_iface_tc_app pp ctxt_prec tc tys- | tc `ifaceTyConHasKey` liftedTypeKindTyConKey- = ppr_kind_type ctxt_prec-- | not (isSymOcc (nameOccName (ifaceTyConName tc)))- = pprIfacePrefixApp ctxt_prec (ppr tc) (map (pp appPrec) tys)-- | [ ty1@(_, Required)- , ty2@(_, Required) ] <- tys- -- Infix, two visible arguments (we know nothing of precedence though).- -- Don't apply this special case if one of the arguments is invisible,- -- lest we print something like (@LiftedRep -> @LiftedRep) (#15941).- = pprIfaceInfixApp ctxt_prec (ppr tc)- (pp opPrec ty1) (pp opPrec ty2)-- | otherwise- = pprIfacePrefixApp ctxt_prec (parens (ppr tc)) (map (pp appPrec) tys)--pprSum :: Arity -> PromotionFlag -> IfaceAppArgs -> SDoc-pprSum _arity is_promoted args- = -- drop the RuntimeRep vars.- -- See Note [Unboxed tuple RuntimeRep vars] in TyCon- let tys = appArgsIfaceTypes args- args' = drop (length tys `div` 2) tys- in pprPromotionQuoteI is_promoted- <> sumParens (pprWithBars (ppr_ty topPrec) args')--pprTuple :: PprPrec -> TupleSort -> PromotionFlag -> IfaceAppArgs -> SDoc-pprTuple ctxt_prec sort promoted args =- case promoted of- IsPromoted- -> let tys = appArgsIfaceTypes args- args' = drop (length tys `div` 2) tys- spaceIfPromoted = case args' of- arg0:_ -> pprSpaceIfPromotedTyCon arg0- _ -> id- in ppr_tuple_app args' $- pprPromotionQuoteI IsPromoted <>- tupleParens sort (spaceIfPromoted (pprWithCommas pprIfaceType args'))-- NotPromoted- | ConstraintTuple <- sort- , IA_Nil <- args- -> maybeParen ctxt_prec sigPrec $- text "() :: Constraint"-- | otherwise- -> -- drop the RuntimeRep vars.- -- See Note [Unboxed tuple RuntimeRep vars] in TyCon- let tys = appArgsIfaceTypes args- args' = case sort of- UnboxedTuple -> drop (length tys `div` 2) tys- _ -> tys- in- ppr_tuple_app args' $- pprPromotionQuoteI promoted <>- tupleParens sort (pprWithCommas pprIfaceType args')- where- ppr_tuple_app :: [IfaceType] -> SDoc -> SDoc- ppr_tuple_app args_wo_runtime_reps ppr_args_w_parens- -- Special-case unary boxed tuples so that they are pretty-printed as- -- `Unit x`, not `(x)`- | [_] <- args_wo_runtime_reps- , BoxedTuple <- sort- = let unit_tc_info = IfaceTyConInfo promoted IfaceNormalTyCon- unit_tc = IfaceTyCon (tupleTyConName sort 1) unit_tc_info in- pprPrecIfaceType ctxt_prec $ IfaceTyConApp unit_tc args- | otherwise- = ppr_args_w_parens--pprIfaceTyLit :: IfaceTyLit -> SDoc-pprIfaceTyLit (IfaceNumTyLit n) = integer n-pprIfaceTyLit (IfaceStrTyLit n) = text (show n)--pprIfaceCoercion, pprParendIfaceCoercion :: IfaceCoercion -> SDoc-pprIfaceCoercion = ppr_co topPrec-pprParendIfaceCoercion = ppr_co appPrec--ppr_co :: PprPrec -> IfaceCoercion -> SDoc-ppr_co _ (IfaceReflCo ty) = angleBrackets (ppr ty) <> ppr_role Nominal-ppr_co _ (IfaceGReflCo r ty IfaceMRefl)- = angleBrackets (ppr ty) <> ppr_role r-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)- = maybeParen ctxt_prec funPrec $- sep (ppr_co funPrec co1 : ppr_fun_tail 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_co _ (IfaceTyConAppCo r tc cos)- = parens (pprIfaceCoTcApp topPrec tc cos) <> ppr_role r-ppr_co ctxt_prec (IfaceAppCo co1 co2)- = maybeParen ctxt_prec appPrec $- ppr_co funPrec co1 <+> pprParendIfaceCoercion co2-ppr_co ctxt_prec co@(IfaceForAllCo {})- = maybeParen ctxt_prec funPrec $- pprIfaceForAllCoPart tvs (pprIfaceCoercion inner_co)- where- (tvs, inner_co) = split_co co-- 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')- = let (tvs, co'') = split_co co' in ((name,kind_co):tvs,co'')- split_co co' = ([], co')---- Why these three? See Note [TcTyVars in IfaceType]-ppr_co _ (IfaceFreeCoVar covar) = ppr covar-ppr_co _ (IfaceCoVarCo covar) = ppr covar-ppr_co _ (IfaceHoleCo covar) = braces (ppr covar)--ppr_co ctxt_prec (IfaceUnivCo IfaceUnsafeCoerceProv r ty1 ty2)- = maybeParen ctxt_prec appPrec $- text "UnsafeCo" <+> ppr r <+>- pprParendIfaceType ty1 <+> pprParendIfaceType ty2--ppr_co _ (IfaceUnivCo prov role ty1 ty2)- = text "Univ" <> (parens $- sep [ ppr role <+> pprIfaceUnivCoProv prov- , dcolon <+> ppr ty1 <> comma <+> ppr ty2 ])--ppr_co ctxt_prec (IfaceInstCo co ty)- = maybeParen ctxt_prec appPrec $- text "Inst" <+> pprParendIfaceCoercion co- <+> pprParendIfaceCoercion ty--ppr_co ctxt_prec (IfaceAxiomRuleCo tc cos)- = maybeParen ctxt_prec appPrec $ ppr tc <+> parens (interpp'SP cos)--ppr_co ctxt_prec (IfaceAxiomInstCo n i cos)- = ppr_special_co ctxt_prec (ppr n <> brackets (ppr i)) cos-ppr_co ctxt_prec (IfaceSymCo co)- = ppr_special_co ctxt_prec (text "Sym") [co]-ppr_co ctxt_prec (IfaceTransCo co1 co2)- = maybeParen ctxt_prec opPrec $- ppr_co opPrec co1 <+> semi <+> ppr_co opPrec co2-ppr_co ctxt_prec (IfaceNthCo d co)- = ppr_special_co ctxt_prec (text "Nth:" <> int d) [co]-ppr_co ctxt_prec (IfaceLRCo lr co)- = ppr_special_co ctxt_prec (ppr lr) [co]-ppr_co ctxt_prec (IfaceSubCo co)- = ppr_special_co ctxt_prec (text "Sub") [co]-ppr_co ctxt_prec (IfaceKindCo co)- = ppr_special_co ctxt_prec (text "Kind") [co]--ppr_special_co :: PprPrec -> SDoc -> [IfaceCoercion] -> SDoc-ppr_special_co ctxt_prec doc cos- = maybeParen ctxt_prec appPrec- (sep [doc, nest 4 (sep (map pprParendIfaceCoercion cos))])--ppr_role :: Role -> SDoc-ppr_role r = underscore <> pp_role- where pp_role = case r of- Nominal -> char 'N'- Representational -> char 'R'- Phantom -> char 'P'---------------------pprIfaceUnivCoProv :: IfaceUnivCoProv -> SDoc-pprIfaceUnivCoProv IfaceUnsafeCoerceProv- = text "unsafe"-pprIfaceUnivCoProv (IfacePhantomProv co)- = text "phantom" <+> pprParendIfaceCoercion co-pprIfaceUnivCoProv (IfaceProofIrrelProv co)- = text "irrel" <+> pprParendIfaceCoercion co-pprIfaceUnivCoProv (IfacePluginProv s)- = text "plugin" <+> doubleQuotes (text s)----------------------instance Outputable IfaceTyCon where- ppr tc = pprPromotionQuote tc <> ppr (ifaceTyConName tc)--pprPromotionQuote :: IfaceTyCon -> SDoc-pprPromotionQuote tc =- pprPromotionQuoteI $ ifaceTyConIsPromoted $ ifaceTyConInfo tc--pprPromotionQuoteI :: PromotionFlag -> SDoc-pprPromotionQuoteI NotPromoted = empty-pprPromotionQuoteI IsPromoted = char '\''--instance Outputable IfaceCoercion where- ppr = pprIfaceCoercion--instance Binary IfaceTyCon where- put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i-- get bh = do n <- get bh- i <- get bh- return (IfaceTyCon n i)--instance Binary IfaceTyConSort where- put_ bh IfaceNormalTyCon = putByte bh 0- put_ bh (IfaceTupleTyCon arity sort) = putByte bh 1 >> put_ bh arity >> put_ bh sort- put_ bh (IfaceSumTyCon arity) = putByte bh 2 >> put_ bh arity- put_ bh IfaceEqualityTyCon = putByte bh 3-- get bh = do- n <- getByte bh- case n of- 0 -> return IfaceNormalTyCon- 1 -> IfaceTupleTyCon <$> get bh <*> get bh- 2 -> IfaceSumTyCon <$> get bh- _ -> return IfaceEqualityTyCon--instance Binary IfaceTyConInfo where- put_ bh (IfaceTyConInfo i s) = put_ bh i >> put_ bh s-- get bh = IfaceTyConInfo <$> get bh <*> get bh--instance Outputable IfaceTyLit where- ppr = pprIfaceTyLit--instance Binary IfaceTyLit where- put_ bh (IfaceNumTyLit n) = putByte bh 1 >> put_ bh n- put_ bh (IfaceStrTyLit n) = putByte bh 2 >> put_ bh n-- get bh =- do tag <- getByte bh- case tag of- 1 -> do { n <- get bh- ; return (IfaceNumTyLit n) }- 2 -> do { n <- get bh- ; return (IfaceStrTyLit n) }- _ -> panic ("get IfaceTyLit " ++ show tag)--instance Binary IfaceAppArgs where- put_ bh tk =- case tk of- IA_Arg t a ts -> putByte bh 0 >> put_ bh t >> put_ bh a >> put_ bh ts- IA_Nil -> putByte bh 1-- get bh =- do c <- getByte bh- case c of- 0 -> do- t <- get bh- a <- get bh- ts <- get bh- return $! IA_Arg t a ts- 1 -> return IA_Nil- _ -> panic ("get IfaceAppArgs " ++ show c)------------------------- Some notes about printing contexts------ In the event that we are printing a singleton context (e.g. @Eq a@) we can--- omit parentheses. However, we must take care to set the precedence correctly--- to opPrec, since something like @a :~: b@ must be parenthesized (see--- #9658).------ When printing a larger context we use 'fsep' instead of 'sep' so that--- the context doesn't get displayed as a giant column. Rather than,--- instance (Eq a,--- Eq b,--- Eq c,--- Eq d,--- Eq e,--- Eq f,--- Eq g,--- Eq h,--- Eq i,--- Eq j,--- Eq k,--- Eq l) =>--- Eq (a, b, c, d, e, f, g, h, i, j, k, l)------ we want------ instance (Eq a, Eq b, Eq c, Eq d, Eq e, Eq f, Eq g, Eq h, Eq i,--- Eq j, Eq k, Eq l) =>--- Eq (a, b, c, d, e, f, g, h, i, j, k, l)------ | Prints "(C a, D b) =>", including the arrow.--- Used when we want to print a context in a type, so we--- use 'funPrec' to decide whether to parenthesise a singleton--- predicate; e.g. Num a => a -> a-pprIfaceContextArr :: [IfacePredType] -> SDoc-pprIfaceContextArr [] = empty-pprIfaceContextArr [pred] = ppr_ty funPrec pred <+> darrow-pprIfaceContextArr preds = ppr_parend_preds preds <+> darrow---- | Prints a context or @()@ if empty--- You give it the context precedence-pprIfaceContext :: PprPrec -> [IfacePredType] -> SDoc-pprIfaceContext _ [] = text "()"-pprIfaceContext prec [pred] = ppr_ty prec pred-pprIfaceContext _ preds = ppr_parend_preds preds--ppr_parend_preds :: [IfacePredType] -> SDoc-ppr_parend_preds preds = parens (fsep (punctuate comma (map ppr preds)))--instance Binary IfaceType where- put_ _ (IfaceFreeTyVar tv)- = pprPanic "Can't serialise IfaceFreeTyVar" (ppr tv)-- put_ bh (IfaceForAllTy aa ab) = do- putByte bh 0- put_ bh aa- put_ bh ab- put_ bh (IfaceTyVar ad) = do- putByte bh 1- put_ bh ad- put_ bh (IfaceAppTy ae af) = do- putByte bh 2- put_ bh ae- put_ bh af- put_ bh (IfaceFunTy af ag ah) = do- putByte bh 3- put_ bh af- put_ bh ag- put_ bh ah- put_ bh (IfaceTyConApp tc tys)- = do { putByte bh 5; put_ bh tc; put_ bh tys }- put_ bh (IfaceCastTy a b)- = do { putByte bh 6; put_ bh a; put_ bh b }- put_ bh (IfaceCoercionTy a)- = do { putByte bh 7; put_ bh a }- put_ bh (IfaceTupleTy s i tys)- = do { putByte bh 8; put_ bh s; put_ bh i; put_ bh tys }- put_ bh (IfaceLitTy n)- = do { putByte bh 9; put_ bh n }-- get bh = do- h <- getByte bh- case h of- 0 -> do aa <- get bh- ab <- get bh- return (IfaceForAllTy aa ab)- 1 -> do ad <- get bh- return (IfaceTyVar ad)- 2 -> do ae <- get bh- af <- get bh- return (IfaceAppTy ae af)- 3 -> do af <- get bh- ag <- get bh- ah <- get bh- return (IfaceFunTy af ag ah)- 5 -> do { tc <- get bh; tys <- get bh- ; return (IfaceTyConApp tc tys) }- 6 -> do { a <- get bh; b <- get bh- ; return (IfaceCastTy a b) }- 7 -> do { a <- get bh- ; return (IfaceCoercionTy a) }-- 8 -> do { s <- get bh; i <- get bh; tys <- get bh- ; return (IfaceTupleTy s i tys) }- _ -> do n <- get bh- return (IfaceLitTy n)--instance Binary IfaceMCoercion where- put_ bh IfaceMRefl = do- putByte bh 1- put_ bh (IfaceMCo co) = do- putByte bh 2- put_ bh co-- get bh = do- tag <- getByte bh- case tag of- 1 -> return IfaceMRefl- 2 -> do a <- get bh- return $ IfaceMCo a- _ -> panic ("get IfaceMCoercion " ++ show tag)--instance Binary IfaceCoercion where- put_ bh (IfaceReflCo a) = do- putByte bh 1- put_ bh a- put_ bh (IfaceGReflCo a b c) = do- putByte bh 2- put_ bh a- put_ bh b- put_ bh c- put_ bh (IfaceFunCo a b c) = do- putByte bh 3- put_ bh a- put_ bh b- put_ bh c- put_ bh (IfaceTyConAppCo a b c) = do- putByte bh 4- put_ bh a- put_ bh b- put_ bh c- put_ bh (IfaceAppCo a b) = do- putByte bh 5- put_ bh a- put_ bh b- put_ bh (IfaceForAllCo a b c) = do- putByte bh 6- put_ bh a- put_ bh b- put_ bh c- put_ bh (IfaceCoVarCo a) = do- putByte bh 7- put_ bh a- put_ bh (IfaceAxiomInstCo a b c) = do- putByte bh 8- put_ bh a- put_ bh b- put_ bh c- put_ bh (IfaceUnivCo a b c d) = do- putByte bh 9- put_ bh a- put_ bh b- put_ bh c- put_ bh d- put_ bh (IfaceSymCo a) = do- putByte bh 10- put_ bh a- put_ bh (IfaceTransCo a b) = do- putByte bh 11- put_ bh a- put_ bh b- put_ bh (IfaceNthCo a b) = do- putByte bh 12- put_ bh a- put_ bh b- put_ bh (IfaceLRCo a b) = do- putByte bh 13- put_ bh a- put_ bh b- put_ bh (IfaceInstCo a b) = do- putByte bh 14- put_ bh a- put_ bh b- put_ bh (IfaceKindCo a) = do- putByte bh 15- put_ bh a- put_ bh (IfaceSubCo a) = do- putByte bh 16- put_ bh a- put_ bh (IfaceAxiomRuleCo a b) = do- putByte bh 17- put_ bh a- put_ bh b- put_ _ (IfaceFreeCoVar cv)- = pprPanic "Can't serialise IfaceFreeCoVar" (ppr cv)- put_ _ (IfaceHoleCo cv)- = pprPanic "Can't serialise IfaceHoleCo" (ppr cv)- -- See Note [Holes in IfaceCoercion]-- get bh = do- tag <- getByte bh- case tag of- 1 -> do a <- get bh- return $ IfaceReflCo a- 2 -> do a <- get bh- b <- get bh- c <- get bh- return $ IfaceGReflCo a b c- 3 -> do a <- get bh- b <- get bh- c <- get bh- return $ IfaceFunCo a b c- 4 -> do a <- get bh- b <- get bh- c <- get bh- return $ IfaceTyConAppCo a b c- 5 -> do a <- get bh- b <- get bh- return $ IfaceAppCo a b- 6 -> do a <- get bh- b <- get bh- c <- get bh- return $ IfaceForAllCo a b c- 7 -> do a <- get bh- return $ IfaceCoVarCo a- 8 -> do a <- get bh- b <- get bh- c <- get bh- return $ IfaceAxiomInstCo a b c- 9 -> do a <- get bh- b <- get bh- c <- get bh- d <- get bh- return $ IfaceUnivCo a b c d- 10-> do a <- get bh- return $ IfaceSymCo a- 11-> do a <- get bh- b <- get bh- return $ IfaceTransCo a b- 12-> do a <- get bh- b <- get bh- return $ IfaceNthCo a b- 13-> do a <- get bh- b <- get bh- return $ IfaceLRCo a b- 14-> do a <- get bh- b <- get bh- return $ IfaceInstCo a b- 15-> do a <- get bh- return $ IfaceKindCo a- 16-> do a <- get bh- return $ IfaceSubCo a- 17-> do a <- get bh- b <- get bh- return $ IfaceAxiomRuleCo a b- _ -> panic ("get IfaceCoercion " ++ show tag)--instance Binary IfaceUnivCoProv where- put_ bh IfaceUnsafeCoerceProv = putByte bh 1- put_ bh (IfacePhantomProv a) = do- putByte bh 2- put_ bh a- put_ bh (IfaceProofIrrelProv a) = do- putByte bh 3- put_ bh a- put_ bh (IfacePluginProv a) = do- putByte bh 4- put_ bh a-- get bh = do- tag <- getByte bh- case tag of- 1 -> return $ IfaceUnsafeCoerceProv- 2 -> do a <- get bh- return $ IfacePhantomProv a- 3 -> do a <- get bh- return $ IfaceProofIrrelProv a- 4 -> do a <- get bh- return $ IfacePluginProv a- _ -> panic ("get IfaceUnivCoProv " ++ show tag)---instance Binary (DefMethSpec IfaceType) where- put_ bh VanillaDM = putByte bh 0- put_ bh (GenericDM t) = putByte bh 1 >> put_ bh t- get bh = do- h <- getByte bh- case h of- 0 -> return VanillaDM- _ -> do { t <- get bh; return (GenericDM t) }--instance NFData IfaceType where- rnf = \case- IfaceFreeTyVar f1 -> f1 `seq` ()- 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- IfaceForAllTy f1 f2 -> f1 `seq` rnf f2- IfaceTyConApp f1 f2 -> rnf f1 `seq` rnf f2- IfaceCastTy f1 f2 -> rnf f1 `seq` rnf f2- IfaceCoercionTy f1 -> rnf f1- IfaceTupleTy f1 f2 f3 -> f1 `seq` f2 `seq` rnf f3--instance NFData IfaceTyLit where- rnf = \case- IfaceNumTyLit f1 -> rnf f1- IfaceStrTyLit f1 -> rnf f1--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- 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- IfaceCoVarCo f1 -> rnf f1- IfaceAxiomInstCo f1 f2 f3 -> rnf f1 `seq` rnf f2 `seq` rnf f3- IfaceAxiomRuleCo f1 f2 -> rnf f1 `seq` rnf f2- IfaceUnivCo f1 f2 f3 f4 -> rnf f1 `seq` f2 `seq` rnf f3 `seq` rnf f4- IfaceSymCo f1 -> rnf f1- IfaceTransCo f1 f2 -> rnf f1 `seq` rnf f2- IfaceNthCo f1 f2 -> rnf f1 `seq` rnf f2- IfaceLRCo f1 f2 -> f1 `seq` rnf f2- IfaceInstCo f1 f2 -> rnf f1 `seq` rnf f2- IfaceKindCo f1 -> rnf f1- IfaceSubCo f1 -> rnf f1- IfaceFreeCoVar f1 -> f1 `seq` ()- IfaceHoleCo f1 -> f1 `seq` ()--instance NFData IfaceUnivCoProv where- rnf x = seq x ()--instance NFData IfaceMCoercion where- rnf x = seq x ()--instance NFData IfaceOneShot where- rnf x = seq x ()--instance NFData IfaceTyConSort where- rnf = \case- IfaceNormalTyCon -> ()- IfaceTupleTyCon arity sort -> rnf arity `seq` sort `seq` ()- IfaceSumTyCon arity -> rnf arity- IfaceEqualityTyCon -> ()--instance NFData IfaceTyConInfo where- rnf (IfaceTyConInfo f s) = f `seq` rnf s--instance NFData IfaceTyCon where- rnf (IfaceTyCon nm info) = rnf nm `seq` rnf info--instance NFData IfaceBndr where- rnf = \case- IfaceIdBndr id_bndr -> rnf id_bndr- IfaceTvBndr tv_bndr -> rnf tv_bndr--instance NFData IfaceAppArgs where- rnf = \case- IA_Nil -> ()- IA_Arg f1 f2 f3 -> rnf f1 `seq` f2 `seq` rnf f3
− compiler/iface/IfaceType.hs-boot
@@ -1,15 +0,0 @@--- Used only by ToIface.hs-boot--module IfaceType( IfaceType, IfaceTyCon, IfaceForAllBndr- , IfaceCoercion, IfaceTyLit, IfaceAppArgs ) where--import Var (VarBndr, ArgFlag)--data IfaceAppArgs--data IfaceType-data IfaceTyCon-data IfaceTyLit-data IfaceCoercion-data IfaceBndr-type IfaceForAllBndr = VarBndr IfaceBndr ArgFlag
− compiler/iface/ToIface.hs
@@ -1,684 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE Strict #-} -- See Note [Avoiding space leaks in toIface*]---- | Functions for converting Core things to interface file things.-module ToIface- ( -- * Binders- toIfaceTvBndr- , toIfaceTvBndrs- , toIfaceIdBndr- , toIfaceBndr- , toIfaceForAllBndr- , toIfaceTyCoVarBinders- , toIfaceTyVar- -- * Types- , toIfaceType, toIfaceTypeX- , toIfaceKind- , toIfaceTcArgs- , toIfaceTyCon- , toIfaceTyCon_name- , toIfaceTyLit- -- * Tidying types- , tidyToIfaceType- , tidyToIfaceContext- , tidyToIfaceTcArgs- -- * Coercions- , toIfaceCoercion, toIfaceCoercionX- -- * Pattern synonyms- , patSynToIfaceDecl- -- * Expressions- , toIfaceExpr- , toIfaceBang- , toIfaceSrcBang- , toIfaceLetBndr- , toIfaceIdDetails- , toIfaceIdInfo- , toIfUnfolding- , toIfaceOneShot- , toIfaceTickish- , toIfaceBind- , toIfaceAlt- , toIfaceCon- , toIfaceApp- , toIfaceVar- ) where--#include "HsVersions.h"--import GhcPrelude--import IfaceSyn-import DataCon-import Id-import IdInfo-import CoreSyn-import TyCon hiding ( pprPromotionQuote )-import CoAxiom-import TysPrim ( eqPrimTyCon, eqReprPrimTyCon )-import TysWiredIn ( heqTyCon )-import MkId ( noinlineIdName )-import PrelNames-import Name-import BasicTypes-import Type-import PatSyn-import Outputable-import FastString-import Util-import Var-import VarEnv-import VarSet-import TyCoRep-import TyCoTidy ( tidyCo )-import Demand ( isTopSig )--import Data.Maybe ( catMaybes )--{- Note [Avoiding space leaks in toIface*]- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--Building a interface file depends on the output of the simplifier.-If we build these lazily this would mean keeping the Core AST alive-much longer than necessary causing a space "leak".--This happens for example when we only write the interface file to disk-after code gen has run, in which case we might carry megabytes of core-AST in the heap which is no longer needed.--We avoid this in two ways.-* First we use -XStrict in ToIface which avoids many thunks to begin with.-* Second we define NFData instance for IFaceSyn and use them to- force any remaining thunks.---XStrict is not sufficient as patterns of the form `f (g x)` would still-result in a thunk being allocated for `g x`.--NFData is sufficient for the space leak, but using -XStrict reduces allocation-by ~0.1% when compiling with -O. (nofib/spectral/simple, T10370).-It's essentially free performance hence we use -XStrict on top of NFData.--MR !1633 on gitlab, has more discussion on the topic.--}-------------------toIfaceTvBndr :: TyVar -> IfaceTvBndr-toIfaceTvBndr = toIfaceTvBndrX emptyVarSet--toIfaceTvBndrX :: VarSet -> TyVar -> IfaceTvBndr-toIfaceTvBndrX fr tyvar = ( occNameFS (getOccName tyvar)- , toIfaceTypeX fr (tyVarKind tyvar)- )--toIfaceTvBndrs :: [TyVar] -> [IfaceTvBndr]-toIfaceTvBndrs = map toIfaceTvBndr--toIfaceIdBndr :: Id -> IfaceIdBndr-toIfaceIdBndr = toIfaceIdBndrX emptyVarSet--toIfaceIdBndrX :: VarSet -> CoVar -> IfaceIdBndr-toIfaceIdBndrX fr covar = ( occNameFS (getOccName covar)- , toIfaceTypeX fr (varType covar)- )--toIfaceBndr :: Var -> IfaceBndr-toIfaceBndr var- | isId var = IfaceIdBndr (toIfaceIdBndr var)- | otherwise = IfaceTvBndr (toIfaceTvBndr var)--toIfaceBndrX :: VarSet -> Var -> IfaceBndr-toIfaceBndrX fr var- | isId var = IfaceIdBndr (toIfaceIdBndrX fr var)- | otherwise = IfaceTvBndr (toIfaceTvBndrX fr var)--toIfaceTyCoVarBinder :: VarBndr Var vis -> VarBndr IfaceBndr vis-toIfaceTyCoVarBinder (Bndr tv vis) = Bndr (toIfaceBndr tv) vis--toIfaceTyCoVarBinders :: [VarBndr Var vis] -> [VarBndr IfaceBndr vis]-toIfaceTyCoVarBinders = map toIfaceTyCoVarBinder--{--************************************************************************-* *- Conversion from Type to IfaceType-* *-************************************************************************--}--toIfaceKind :: Type -> IfaceType-toIfaceKind = toIfaceType------------------------toIfaceType :: Type -> IfaceType-toIfaceType = toIfaceTypeX emptyVarSet--toIfaceTypeX :: VarSet -> Type -> IfaceType--- (toIfaceTypeX free ty)--- translates the tyvars in 'free' as IfaceFreeTyVars------ Synonyms are retained in the interface type-toIfaceTypeX fr (TyVarTy tv) -- See Note [TcTyVars in IfaceType] in IfaceType- | tv `elemVarSet` fr = IfaceFreeTyVar tv- | otherwise = IfaceTyVar (toIfaceTyVar tv)-toIfaceTypeX fr ty@(AppTy {}) =- -- Flatten as many argument AppTys as possible, then turn them into an- -- IfaceAppArgs list.- -- See Note [Suppressing invisible arguments] in IfaceType.- let (head, args) = splitAppTys ty- in IfaceAppTy (toIfaceTypeX fr head) (toIfaceAppTyArgsX fr head args)-toIfaceTypeX _ (LitTy n) = IfaceLitTy (toIfaceTyLit n)-toIfaceTypeX fr (ForAllTy b t) = IfaceForAllTy (toIfaceForAllBndrX fr b)- (toIfaceTypeX (fr `delVarSet` binderVar b) t)-toIfaceTypeX fr (FunTy { ft_arg = t1, ft_res = t2, ft_af = af })- = IfaceFunTy af (toIfaceTypeX fr t1) (toIfaceTypeX fr t2)-toIfaceTypeX fr (CastTy ty co) = IfaceCastTy (toIfaceTypeX fr ty) (toIfaceCoercionX fr co)-toIfaceTypeX fr (CoercionTy co) = IfaceCoercionTy (toIfaceCoercionX fr co)--toIfaceTypeX fr (TyConApp tc tys)- -- tuples- | Just sort <- tyConTuple_maybe tc- , n_tys == arity- = IfaceTupleTy sort NotPromoted (toIfaceTcArgsX fr tc tys)-- | Just dc <- isPromotedDataCon_maybe tc- , isTupleDataCon dc- , n_tys == 2*arity- = IfaceTupleTy BoxedTuple IsPromoted (toIfaceTcArgsX fr tc (drop arity tys))-- | tc `elem` [ eqPrimTyCon, eqReprPrimTyCon, heqTyCon ]- , (k1:k2:_) <- tys- = let info = IfaceTyConInfo NotPromoted sort- sort | k1 `eqType` k2 = IfaceEqualityTyCon- | otherwise = IfaceNormalTyCon- in IfaceTyConApp (IfaceTyCon (tyConName tc) info) (toIfaceTcArgsX fr tc tys)-- -- other applications- | otherwise- = IfaceTyConApp (toIfaceTyCon tc) (toIfaceTcArgsX fr tc tys)- where- arity = tyConArity tc- n_tys = length tys--toIfaceTyVar :: TyVar -> FastString-toIfaceTyVar = occNameFS . getOccName--toIfaceCoVar :: CoVar -> FastString-toIfaceCoVar = occNameFS . getOccName--toIfaceForAllBndr :: TyCoVarBinder -> IfaceForAllBndr-toIfaceForAllBndr = toIfaceForAllBndrX emptyVarSet--toIfaceForAllBndrX :: VarSet -> TyCoVarBinder -> IfaceForAllBndr-toIfaceForAllBndrX fr (Bndr v vis) = Bndr (toIfaceBndrX fr v) vis-------------------toIfaceTyCon :: TyCon -> IfaceTyCon-toIfaceTyCon tc- = IfaceTyCon tc_name info- where- tc_name = tyConName tc- info = IfaceTyConInfo promoted sort- promoted | isPromotedDataCon tc = IsPromoted- | otherwise = NotPromoted-- tupleSort :: TyCon -> Maybe IfaceTyConSort- tupleSort tc' =- case tyConTuple_maybe tc' of- Just UnboxedTuple -> let arity = tyConArity tc' `div` 2- in Just $ IfaceTupleTyCon arity UnboxedTuple- Just sort -> let arity = tyConArity tc'- in Just $ IfaceTupleTyCon arity sort- Nothing -> Nothing-- sort- | Just tsort <- tupleSort tc = tsort-- | Just dcon <- isPromotedDataCon_maybe tc- , let tc' = dataConTyCon dcon- , Just tsort <- tupleSort tc' = tsort-- | isUnboxedSumTyCon tc- , Just cons <- isDataSumTyCon_maybe tc = IfaceSumTyCon (length cons)-- | otherwise = IfaceNormalTyCon---toIfaceTyCon_name :: Name -> IfaceTyCon-toIfaceTyCon_name n = IfaceTyCon n info- where info = IfaceTyConInfo NotPromoted IfaceNormalTyCon- -- Used for the "rough-match" tycon stuff,- -- where pretty-printing is not an issue--toIfaceTyLit :: TyLit -> IfaceTyLit-toIfaceTyLit (NumTyLit x) = IfaceNumTyLit x-toIfaceTyLit (StrTyLit x) = IfaceStrTyLit x-------------------toIfaceCoercion :: Coercion -> IfaceCoercion-toIfaceCoercion = toIfaceCoercionX emptyVarSet--toIfaceCoercionX :: VarSet -> Coercion -> IfaceCoercion--- (toIfaceCoercionX free ty)--- translates the tyvars in 'free' as IfaceFreeTyVars-toIfaceCoercionX fr co- = go co- where- go_mco MRefl = IfaceMRefl- go_mco (MCo co) = IfaceMCo $ go co-- go (Refl ty) = IfaceReflCo (toIfaceTypeX fr ty)- go (GRefl r ty mco) = IfaceGReflCo r (toIfaceTypeX fr ty) (go_mco mco)- go (CoVarCo cv)- -- See [TcTyVars in IfaceType] in IfaceType- | cv `elemVarSet` fr = IfaceFreeCoVar cv- | otherwise = IfaceCoVarCo (toIfaceCoVar cv)- go (HoleCo h) = IfaceHoleCo (coHoleCoVar h)-- go (AppCo co1 co2) = IfaceAppCo (go co1) (go co2)- go (SymCo co) = IfaceSymCo (go co)- go (TransCo co1 co2) = IfaceTransCo (go co1) (go co2)- go (NthCo _r d co) = IfaceNthCo d (go co)- go (LRCo lr co) = IfaceLRCo lr (go co)- go (InstCo co arg) = IfaceInstCo (go co) (go arg)- go (KindCo c) = IfaceKindCo (go c)- go (SubCo co) = IfaceSubCo (go co)- go (AxiomRuleCo co cs) = IfaceAxiomRuleCo (coaxrName co) (map go cs)- go (AxiomInstCo c i cs) = IfaceAxiomInstCo (coAxiomName c) i (map go cs)- go (UnivCo p r t1 t2) = IfaceUnivCo (go_prov p) r- (toIfaceTypeX fr t1)- (toIfaceTypeX fr t2)- go (TyConAppCo r tc cos)- | tc `hasKey` funTyConKey- , [_,_,_,_] <- cos = pprPanic "toIfaceCoercion" (ppr co)- | otherwise = IfaceTyConAppCo r (toIfaceTyCon tc) (map go cos)- go (FunCo r co1 co2) = IfaceFunCo r (go co1) (go co2)-- go (ForAllCo tv k co) = IfaceForAllCo (toIfaceBndr tv)- (toIfaceCoercionX fr' k)- (toIfaceCoercionX fr' co)- where- fr' = fr `delVarSet` tv-- go_prov :: UnivCoProvenance -> IfaceUnivCoProv- go_prov UnsafeCoerceProv = IfaceUnsafeCoerceProv- go_prov (PhantomProv co) = IfacePhantomProv (go co)- go_prov (ProofIrrelProv co) = IfaceProofIrrelProv (go co)- go_prov (PluginProv str) = IfacePluginProv str--toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs-toIfaceTcArgs = toIfaceTcArgsX emptyVarSet--toIfaceTcArgsX :: VarSet -> TyCon -> [Type] -> IfaceAppArgs-toIfaceTcArgsX fr tc ty_args = toIfaceAppArgsX fr (tyConKind tc) ty_args--toIfaceAppTyArgsX :: VarSet -> Type -> [Type] -> IfaceAppArgs-toIfaceAppTyArgsX fr ty ty_args = toIfaceAppArgsX fr (typeKind ty) ty_args--toIfaceAppArgsX :: VarSet -> Kind -> [Type] -> IfaceAppArgs--- See Note [Suppressing invisible arguments] in IfaceType--- We produce a result list of args describing visibility--- The awkward case is--- T :: forall k. * -> k--- And consider--- T (forall j. blah) * blib--- Is 'blib' visible? It depends on the visibility flag on j,--- so we have to substitute for k. Annoying!-toIfaceAppArgsX fr kind ty_args- = go (mkEmptyTCvSubst in_scope) kind ty_args- where- in_scope = mkInScopeSet (tyCoVarsOfTypes ty_args)-- go _ _ [] = IA_Nil- go env ty ts- | Just ty' <- coreView ty- = go env ty' ts- go env (ForAllTy (Bndr tv vis) res) (t:ts)- = IA_Arg t' vis ts'- where- t' = toIfaceTypeX fr t- ts' = go (extendTCvSubst env tv t) res ts-- go env (FunTy { ft_af = af, ft_res = res }) (t:ts)- = IA_Arg (toIfaceTypeX fr t) argf (go env res ts)- where- argf = case af of- VisArg -> Required- InvisArg -> Inferred- -- It's rare for a kind to have a constraint argument, but- -- it can happen. See Note [AnonTCB InvisArg] in TyCon.-- go env ty ts@(t1:ts1)- | not (isEmptyTCvSubst env)- = go (zapTCvSubst env) (substTy env ty) ts- -- See Note [Care with kind instantiation] in Type.hs-- | otherwise- = -- There's a kind error in the type we are trying to print- -- e.g. kind = k, ty_args = [Int]- -- This is probably a compiler bug, so we print a trace and- -- carry on as if it were FunTy. Without the test for- -- isEmptyTCvSubst we'd get an infinite loop (#15473)- WARN( True, ppr kind $$ ppr ty_args )- IA_Arg (toIfaceTypeX fr t1) Required (go env ty ts1)--tidyToIfaceType :: TidyEnv -> Type -> IfaceType-tidyToIfaceType env ty = toIfaceType (tidyType env ty)--tidyToIfaceTcArgs :: TidyEnv -> TyCon -> [Type] -> IfaceAppArgs-tidyToIfaceTcArgs env tc tys = toIfaceTcArgs tc (tidyTypes env tys)--tidyToIfaceContext :: TidyEnv -> ThetaType -> IfaceContext-tidyToIfaceContext env theta = map (tidyToIfaceType env) theta--{--************************************************************************-* *- Conversion of pattern synonyms-* *-************************************************************************--}--patSynToIfaceDecl :: PatSyn -> IfaceDecl-patSynToIfaceDecl ps- = IfacePatSyn { ifName = getName $ ps- , ifPatMatcher = to_if_pr (patSynMatcher ps)- , ifPatBuilder = fmap to_if_pr (patSynBuilder ps)- , ifPatIsInfix = patSynIsInfix ps- , ifPatUnivBndrs = map toIfaceForAllBndr univ_bndrs'- , ifPatExBndrs = map toIfaceForAllBndr ex_bndrs'- , ifPatProvCtxt = tidyToIfaceContext env2 prov_theta- , ifPatReqCtxt = tidyToIfaceContext env2 req_theta- , ifPatArgs = map (tidyToIfaceType env2) args- , ifPatTy = tidyToIfaceType env2 rhs_ty- , ifFieldLabels = (patSynFieldLabels ps)- }- where- (_univ_tvs, req_theta, _ex_tvs, prov_theta, args, rhs_ty) = patSynSig ps- univ_bndrs = patSynUnivTyVarBinders ps- ex_bndrs = patSynExTyVarBinders ps- (env1, univ_bndrs') = tidyTyCoVarBinders emptyTidyEnv univ_bndrs- (env2, ex_bndrs') = tidyTyCoVarBinders env1 ex_bndrs- to_if_pr (id, needs_dummy) = (idName id, needs_dummy)--{--************************************************************************-* *- Conversion of other things-* *-************************************************************************--}--toIfaceBang :: TidyEnv -> HsImplBang -> IfaceBang-toIfaceBang _ HsLazy = IfNoBang-toIfaceBang _ (HsUnpack Nothing) = IfUnpack-toIfaceBang env (HsUnpack (Just co)) = IfUnpackCo (toIfaceCoercion (tidyCo env co))-toIfaceBang _ HsStrict = IfStrict--toIfaceSrcBang :: HsSrcBang -> IfaceSrcBang-toIfaceSrcBang (HsSrcBang _ unpk bang) = IfSrcBang unpk bang--toIfaceLetBndr :: Id -> IfaceLetBndr-toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id))- (toIfaceType (idType id))- (toIfaceIdInfo (idInfo id))- (toIfaceJoinInfo (isJoinId_maybe id))- -- Put into the interface file any IdInfo that CoreTidy.tidyLetBndr- -- has left on the Id. See Note [IdInfo on nested let-bindings] in IfaceSyn--toIfaceIdDetails :: IdDetails -> IfaceIdDetails-toIfaceIdDetails VanillaId = IfVanillaId-toIfaceIdDetails (DFunId {}) = IfDFunId-toIfaceIdDetails (RecSelId { sel_naughty = n- , sel_tycon = tc }) =- let iface = case tc of- RecSelData ty_con -> Left (toIfaceTyCon ty_con)- RecSelPatSyn pat_syn -> Right (patSynToIfaceDecl pat_syn)- in IfRecSelId iface n-- -- The remaining cases are all "implicit Ids" which don't- -- appear in interface files at all-toIfaceIdDetails other = pprTrace "toIfaceIdDetails" (ppr other)- IfVanillaId -- Unexpected; the other--toIfaceIdInfo :: IdInfo -> IfaceIdInfo-toIfaceIdInfo id_info- = case catMaybes [arity_hsinfo, caf_hsinfo, strict_hsinfo,- inline_hsinfo, unfold_hsinfo, levity_hsinfo] of- [] -> NoInfo- infos -> HasInfo infos- -- NB: strictness and arity must appear in the list before unfolding- -- See TcIface.tcUnfolding- where- ------------ Arity --------------- arity_info = arityInfo id_info- arity_hsinfo | arity_info == 0 = Nothing- | otherwise = Just (HsArity arity_info)-- ------------ Caf Info --------------- caf_info = cafInfo id_info- caf_hsinfo = case caf_info of- NoCafRefs -> Just HsNoCafRefs- _other -> Nothing-- ------------ Strictness --------------- -- No point in explicitly exporting TopSig- sig_info = strictnessInfo id_info- strict_hsinfo | not (isTopSig sig_info) = Just (HsStrictness sig_info)- | otherwise = Nothing-- ------------ Unfolding --------------- unfold_hsinfo = toIfUnfolding loop_breaker (unfoldingInfo id_info)- loop_breaker = isStrongLoopBreaker (occInfo id_info)-- ------------ Inline prag --------------- inline_prag = inlinePragInfo id_info- inline_hsinfo | isDefaultInlinePragma inline_prag = Nothing- | otherwise = Just (HsInline inline_prag)-- ------------ Levity polymorphism ----------- levity_hsinfo | isNeverLevPolyIdInfo id_info = Just HsLevity- | otherwise = Nothing--toIfaceJoinInfo :: Maybe JoinArity -> IfaceJoinInfo-toIfaceJoinInfo (Just ar) = IfaceJoinPoint ar-toIfaceJoinInfo Nothing = IfaceNotJoinPoint-----------------------------toIfUnfolding :: Bool -> Unfolding -> Maybe IfaceInfoItem-toIfUnfolding lb (CoreUnfolding { uf_tmpl = rhs- , uf_src = src- , uf_guidance = guidance })- = Just $ HsUnfold lb $- case src of- InlineStable- -> case guidance of- UnfWhen {ug_arity = arity, ug_unsat_ok = unsat_ok, ug_boring_ok = boring_ok }- -> IfInlineRule arity unsat_ok boring_ok if_rhs- _other -> IfCoreUnfold True if_rhs- InlineCompulsory -> IfCompulsory if_rhs- InlineRhs -> IfCoreUnfold False if_rhs- -- Yes, even if guidance is UnfNever, expose the unfolding- -- If we didn't want to expose the unfolding, TidyPgm would- -- have stuck in NoUnfolding. For supercompilation we want- -- to see that unfolding!- where- if_rhs = toIfaceExpr rhs--toIfUnfolding lb (DFunUnfolding { df_bndrs = bndrs, df_args = args })- = Just (HsUnfold lb (IfDFunUnfold (map toIfaceBndr bndrs) (map toIfaceExpr args)))- -- No need to serialise the data constructor;- -- we can recover it from the type of the dfun--toIfUnfolding _ (OtherCon {}) = Nothing- -- The binding site of an Id doesn't have OtherCon, except perhaps- -- where we have called zapUnfolding; and that evald'ness info is- -- not needed by importing modules--toIfUnfolding _ BootUnfolding = Nothing- -- Can't happen; we only have BootUnfolding for imported binders--toIfUnfolding _ NoUnfolding = Nothing--{--************************************************************************-* *- Conversion of expressions-* *-************************************************************************--}--toIfaceExpr :: CoreExpr -> IfaceExpr-toIfaceExpr (Var v) = toIfaceVar v-toIfaceExpr (Lit l) = IfaceLit l-toIfaceExpr (Type ty) = IfaceType (toIfaceType ty)-toIfaceExpr (Coercion co) = IfaceCo (toIfaceCoercion co)-toIfaceExpr (Lam x b) = IfaceLam (toIfaceBndr x, toIfaceOneShot x) (toIfaceExpr b)-toIfaceExpr (App f a) = toIfaceApp f [a]-toIfaceExpr (Case s x ty as)- | null as = IfaceECase (toIfaceExpr s) (toIfaceType ty)- | otherwise = IfaceCase (toIfaceExpr s) (getOccFS x) (map toIfaceAlt as)-toIfaceExpr (Let b e) = IfaceLet (toIfaceBind b) (toIfaceExpr e)-toIfaceExpr (Cast e co) = IfaceCast (toIfaceExpr e) (toIfaceCoercion co)-toIfaceExpr (Tick t e)- | Just t' <- toIfaceTickish t = IfaceTick t' (toIfaceExpr e)- | otherwise = toIfaceExpr e--toIfaceOneShot :: Id -> IfaceOneShot-toIfaceOneShot id | isId id- , OneShotLam <- oneShotInfo (idInfo id)- = IfaceOneShot- | otherwise- = IfaceNoOneShot------------------------toIfaceTickish :: Tickish Id -> Maybe IfaceTickish-toIfaceTickish (ProfNote cc tick push) = Just (IfaceSCC cc tick push)-toIfaceTickish (HpcTick modl ix) = Just (IfaceHpcTick modl ix)-toIfaceTickish (SourceNote src names) = Just (IfaceSource src names)-toIfaceTickish (Breakpoint {}) = Nothing- -- Ignore breakpoints, since they are relevant only to GHCi, and- -- should not be serialised (#8333)------------------------toIfaceBind :: Bind Id -> IfaceBinding-toIfaceBind (NonRec b r) = IfaceNonRec (toIfaceLetBndr b) (toIfaceExpr r)-toIfaceBind (Rec prs) = IfaceRec [(toIfaceLetBndr b, toIfaceExpr r) | (b,r) <- prs]------------------------toIfaceAlt :: (AltCon, [Var], CoreExpr)- -> (IfaceConAlt, [FastString], IfaceExpr)-toIfaceAlt (c,bs,r) = (toIfaceCon c, map getOccFS bs, toIfaceExpr r)------------------------toIfaceCon :: AltCon -> IfaceConAlt-toIfaceCon (DataAlt dc) = IfaceDataAlt (getName dc)-toIfaceCon (LitAlt l) = IfaceLitAlt l-toIfaceCon DEFAULT = IfaceDefault------------------------toIfaceApp :: Expr CoreBndr -> [Arg CoreBndr] -> IfaceExpr-toIfaceApp (App f a) as = toIfaceApp f (a:as)-toIfaceApp (Var v) as- = case isDataConWorkId_maybe v of- -- We convert the *worker* for tuples into IfaceTuples- Just dc | saturated- , Just tup_sort <- tyConTuple_maybe tc- -> IfaceTuple tup_sort tup_args- where- val_args = dropWhile isTypeArg as- saturated = val_args `lengthIs` idArity v- tup_args = map toIfaceExpr val_args- tc = dataConTyCon dc-- _ -> mkIfaceApps (toIfaceVar v) as--toIfaceApp e as = mkIfaceApps (toIfaceExpr e) as--mkIfaceApps :: IfaceExpr -> [CoreExpr] -> IfaceExpr-mkIfaceApps f as = foldl' (\f a -> IfaceApp f (toIfaceExpr a)) f as------------------------toIfaceVar :: Id -> IfaceExpr-toIfaceVar v- | isBootUnfolding (idUnfolding v)- = -- See Note [Inlining and hs-boot files]- IfaceApp (IfaceApp (IfaceExt noinlineIdName)- (IfaceType (toIfaceType (idType v))))- (IfaceExt name) -- don't use mkIfaceApps, or infinite loop-- | Just fcall <- isFCallId_maybe v = IfaceFCall fcall (toIfaceType (idType v))- -- Foreign calls have special syntax-- | isExternalName name = IfaceExt name- | otherwise = IfaceLcl (getOccFS name)- where name = idName v---{- Note [Inlining and hs-boot files]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider this example (#10083, #12789):-- ---------- RSR.hs-boot ------------- module RSR where- data RSR- eqRSR :: RSR -> RSR -> Bool-- ---------- SR.hs ------------- module SR where- import {-# SOURCE #-} RSR- data SR = MkSR RSR- eqSR (MkSR r1) (MkSR r2) = eqRSR r1 r2-- ---------- RSR.hs ------------- module RSR where- import SR- data RSR = MkRSR SR -- deriving( Eq )- eqRSR (MkRSR s1) (MkRSR s2) = (eqSR s1 s2)- foo x y = not (eqRSR x y)--When compiling RSR we get this code-- RSR.eqRSR :: RSR -> RSR -> Bool- RSR.eqRSR = \ (ds1 :: RSR.RSR) (ds2 :: RSR.RSR) ->- case ds1 of _ { RSR.MkRSR s1 ->- case ds2 of _ { RSR.MkRSR s2 ->- SR.eqSR s1 s2 }}-- RSR.foo :: RSR -> RSR -> Bool- RSR.foo = \ (x :: RSR) (y :: RSR) -> not (RSR.eqRSR x y)--Now, when optimising foo:- Inline eqRSR (small, non-rec)- Inline eqSR (small, non-rec)-but the result of inlining eqSR from SR is another call to eqRSR, so-everything repeats. Neither eqSR nor eqRSR are (apparently) loop-breakers.--Solution: in the unfolding of eqSR in SR.hi, replace `eqRSR` in SR-with `noinline eqRSR`, so that eqRSR doesn't get inlined. This means-that when GHC inlines `eqSR`, it will not also inline `eqRSR`, exactly-as would have been the case if `foo` had been defined in SR.hs (and-marked as a loop-breaker).--But how do we arrange for this to happen? There are two ingredients:-- 1. When we serialize out unfoldings to IfaceExprs (toIfaceVar),- for every variable reference we see if we are referring to an- 'Id' that came from an hs-boot file. If so, we add a `noinline`- to the reference.-- 2. But how do we know if a reference came from an hs-boot file- or not? We could record this directly in the 'IdInfo', but- actually we deduce this by looking at the unfolding: 'Id's- that come from boot files are given a special unfolding- (upon typechecking) 'BootUnfolding' which say that there is- no unfolding, and the reason is because the 'Id' came from- a boot file.--Here is a solution that doesn't work: when compiling RSR,-add a NOINLINE pragma to every function exported by the boot-file-for RSR (if it exists). Doing so makes the bootstrapped GHC itself-slower by 8% overall (on #9872a-d, and T1969: the reason-is that these NOINLINE'd functions now can't be profitably inlined-outside of the hs-boot loop.---}
− compiler/iface/ToIface.hs-boot
@@ -1,18 +0,0 @@-module ToIface where--import {-# SOURCE #-} TyCoRep ( Type, TyLit, Coercion )-import {-# SOURCE #-} IfaceType( IfaceType, IfaceTyCon, IfaceForAllBndr- , IfaceCoercion, IfaceTyLit, IfaceAppArgs )-import Var ( TyCoVarBinder )-import VarEnv ( TidyEnv )-import TyCon ( TyCon )-import VarSet( VarSet )---- For TyCoRep-toIfaceTypeX :: VarSet -> Type -> IfaceType-toIfaceTyLit :: TyLit -> IfaceTyLit-toIfaceForAllBndr :: TyCoVarBinder -> IfaceForAllBndr-toIfaceTyCon :: TyCon -> IfaceTyCon-toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs-toIfaceCoercionX :: VarSet -> Coercion -> IfaceCoercion-tidyToIfaceTcArgs :: TidyEnv -> TyCon -> [Type] -> IfaceAppArgs
compiler/main/DynFlags.hs view
@@ -18,6 +18,7 @@ {-# OPTIONS_GHC -fno-cse #-} -- -fno-cse is needed for GLOBAL_VAR's to behave properly+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module DynFlags ( -- * Dynamic flags and associated configuration types@@ -55,7 +56,7 @@ PackageFlag(..), PackageArg(..), ModRenaming(..), packageFlagsChanged, IgnorePackageFlag(..), TrustFlag(..),- PackageDBFlag(..), PkgConfRef(..),+ PackageDBFlag(..), PkgDbRef(..), Option(..), showOpt, DynLibLoader(..), fFlags, fLangFlags, xFlags,@@ -96,7 +97,7 @@ sToolDir, sTopDir, sTmpDir,- sSystemPackageConfig,+ sGlobalPackageDatabasePath, sLdSupportsCompactUnwind, sLdSupportsBuildId, sLdSupportsFilelist,@@ -153,7 +154,7 @@ programName, projectVersion, ghcUsagePath, ghciUsagePath, topDir, tmpDir, versionedAppDir, versionedFilePath,- extraGccViaCFlags, systemPackageConfig,+ extraGccViaCFlags, globalPackageDatabasePath, pgm_L, pgm_P, pgm_F, pgm_c, pgm_a, pgm_l, pgm_dll, pgm_T, pgm_windres, pgm_libtool, pgm_ar, pgm_ranlib, pgm_lo, pgm_lc, pgm_lcc, pgm_i,@@ -254,11 +255,10 @@ import GHC.UniqueSubdir (uniqueSubdir) import PlatformConstants import Module-import PackageConfig import {-# SOURCE #-} Plugins import {-# SOURCE #-} Hooks import {-# SOURCE #-} PrelNames ( mAIN )-import {-# SOURCE #-} Packages (PackageState, emptyPackageState)+import {-# SOURCE #-} Packages (PackageState, emptyPackageState, PackageDatabase) import DriverPhases ( Phase(..), phaseInputExt ) import Config import CliOption@@ -564,7 +564,7 @@ | Opt_RegsGraph -- do graph coloring register allocation | Opt_RegsIterative -- do iterative coalescing graph coloring register allocation | Opt_PedanticBottoms -- Be picky about how we treat bottom- | Opt_LlvmTBAA -- Use LLVM TBAA infastructure for improving AA (hidden flag)+ | Opt_LlvmTBAA -- Use LLVM TBAA infrastructure for improving AA (hidden flag) | Opt_LlvmFillUndefWithGarbage -- Testing for undef bugs (hidden flag) | Opt_IrrefutableTuples | Opt_CmmSink@@ -973,7 +973,7 @@ rawSettings :: [(String, String)], integerLibrary :: IntegerLibrary,- -- ^ IntegerGMP or IntegerSimple. Set at configure time, but may be overriden+ -- ^ IntegerGMP or IntegerSimple. Set at configure time, but may be overridden -- by GHC-API users. See Note [The integer library] in PrelNames llvmConfig :: LlvmConfig, -- ^ N.B. It's important that this field is lazy since we load the LLVM@@ -1107,7 +1107,7 @@ -- they don't have to be loaded each time they are needed. See -- 'DynamicLoading.initializePlugins'. staticPlugins :: [StaticPlugin],- -- ^ staic plugins which do not need dynamic loading. These plugins are+ -- ^ static plugins which do not need dynamic loading. These plugins are -- intended to be added by GHC API users directly to this list. -- -- To add dynamically loaded plugins through the GHC API see@@ -1146,11 +1146,23 @@ packageEnv :: Maybe FilePath, -- ^ Filepath to the package environment file (if overriding default) - -- Package state- -- NB. do not modify this field, it is calculated by- -- Packages.initPackages- pkgDatabase :: Maybe [(FilePath, [PackageConfig])],+ pkgDatabase :: Maybe [PackageDatabase],+ -- ^ Stack of package databases for the target platform.+ --+ -- A "package database" is a misleading name as it is really a Unit+ -- database (cf Note [The identifier lexicon]).+ --+ -- This field is populated by `initPackages`.+ --+ -- 'Nothing' means the databases have never been read from disk. If+ -- `initPackages` is called again, it doesn't reload the databases from+ -- disk.+ pkgState :: PackageState,+ -- ^ Consolidated unit database built by 'initPackages' from the package+ -- databases in 'pkgDatabase' and flags ('-ignore-package', etc.).+ --+ -- It also contains mapping from module names to actual Modules. -- Temporary files -- These have to be IORefs, because the defaultCleanupHandler needs to@@ -1341,12 +1353,15 @@ = [s1] | (s1,rest) <- break (== ',') s = [s1] ++ settings (drop 1 rest)+#if __GLASGOW_HASKELL__ <= 810 | otherwise = panic $ "Invalid cfg parameters." ++ exampleString+#endif assignment as | (name, _:val) <- break (== '=') as = (name,read val) | otherwise = panic $ "Invalid cfg parameters." ++ exampleString+ exampleString = "Example parameters: uncondWeight=1000," ++ "condBranchWeight=800,switchWeight=0,callWeight=300" ++ ",likelyCondWeight=900,unlikelyCondWeight=300" ++@@ -1437,8 +1452,8 @@ tmpDir dflags = fileSettings_tmpDir $ fileSettings dflags extraGccViaCFlags :: DynFlags -> [String] extraGccViaCFlags dflags = toolSettings_extraGccViaCFlags $ toolSettings dflags-systemPackageConfig :: DynFlags -> FilePath-systemPackageConfig dflags = fileSettings_systemPackageConfig $ fileSettings dflags+globalPackageDatabasePath :: DynFlags -> FilePath+globalPackageDatabasePath dflags = fileSettings_globalPackageDatabase $ fileSettings dflags pgm_L :: DynFlags -> String pgm_L dflags = toolSettings_pgm_L $ toolSettings dflags pgm_P :: DynFlags -> (String,[Option])@@ -1644,7 +1659,7 @@ deriving (Eq) -- NB: equality instance is used by packageFlagsChanged data PackageDBFlag- = PackageDB PkgConfRef+ = PackageDB PkgDbRef | NoUserPackageDB | NoGlobalPackageDB | ClearPackageDBs@@ -1953,7 +1968,7 @@ maxRefHoleFits = Just 6, refLevelHoleFits = Nothing, maxUncoveredPatterns = 4,- maxPmCheckModels = 100,+ maxPmCheckModels = 30, simplTickFactor = 100, specConstrThreshold = Just 2000, specConstrCount = Just 3,@@ -2030,7 +2045,6 @@ trustFlags = [], packageEnv = Nothing, pkgDatabase = Nothing,- -- This gets filled in with GHC.setSessionDynFlags pkgState = emptyPackageState, ways = defaultWays mySettings, buildTag = mkBuildTag (defaultWays mySettings),@@ -3006,7 +3020,7 @@ Nothing -> upd (\d -> d { parMakeCount = Nothing }))) -- When the number of parallel builds -- is omitted, it is the same- -- as specifing that the number of+ -- as specifying that the number of -- parallel builds is equal to the -- result of getNumProcessors , make_ord_flag defFlag "instantiated-with" (sepArg setUnitIdInsts)@@ -3022,8 +3036,6 @@ ------- ways --------------------------------------------------------------- , make_ord_flag defGhcFlag "prof" (NoArg (addWay WayProf)) , make_ord_flag defGhcFlag "eventlog" (NoArg (addWay WayEventLog))- , make_dep_flag defGhcFlag "smp"- (NoArg $ addWay WayThreaded) "Use -threaded instead" , make_ord_flag defGhcFlag "debug" (NoArg (addWay WayDebug)) , make_ord_flag defGhcFlag "threaded" (NoArg (addWay WayThreaded)) @@ -3855,19 +3867,19 @@ package_flags_deps = [ ------- Packages ---------------------------------------------------- make_ord_flag defFlag "package-db"- (HasArg (addPkgConfRef . PkgConfFile))- , make_ord_flag defFlag "clear-package-db" (NoArg clearPkgConf)- , make_ord_flag defFlag "no-global-package-db" (NoArg removeGlobalPkgConf)- , make_ord_flag defFlag "no-user-package-db" (NoArg removeUserPkgConf)+ (HasArg (addPkgDbRef . PkgDbPath))+ , make_ord_flag defFlag "clear-package-db" (NoArg clearPkgDb)+ , make_ord_flag defFlag "no-global-package-db" (NoArg removeGlobalPkgDb)+ , make_ord_flag defFlag "no-user-package-db" (NoArg removeUserPkgDb) , make_ord_flag defFlag "global-package-db"- (NoArg (addPkgConfRef GlobalPkgConf))+ (NoArg (addPkgDbRef GlobalPkgDb)) , make_ord_flag defFlag "user-package-db"- (NoArg (addPkgConfRef UserPkgConf))+ (NoArg (addPkgDbRef UserPkgDb)) -- backwards compat with GHC<=7.4 : , make_dep_flag defFlag "package-conf"- (HasArg $ addPkgConfRef . PkgConfFile) "Use -package-db instead"+ (HasArg $ addPkgDbRef . PkgDbPath) "Use -package-db instead" , make_dep_flag defFlag "no-user-package-conf"- (NoArg removeUserPkgConf) "Use -no-user-package-db instead"+ (NoArg removeUserPkgDb) "Use -no-user-package-db instead" , make_ord_flag defGhcFlag "package-name" (HasArg $ \name -> do upd (setUnitId name)) -- TODO: Since we JUST deprecated@@ -4788,7 +4800,7 @@ * Eta reduction wasn't happening in the simplifier, but it was happening in CorePrep, on $fBla = MkDict (/\a. K a)- * Result: rhsIsStatic told TidyPgm that $fBla might have CAF refs+ * Result: rhsIsStatic told GHC.Iface.Tidy that $fBla might have CAF refs but the eta-reduced version (MkDict K) obviously doesn't Simple solution: just let the simplifier do eta-reduction even in -O0. After all, CorePrep does it unconditionally! Not a big deal, but@@ -5181,7 +5193,7 @@ Opt_D_no_debug_output] forceRecompile :: DynP ()--- Whenver we -ddump, force recompilation (by switching off the+-- Whenever we -ddump, force recompilation (by switching off the -- recompilation checker), else you don't see the dump! However, -- don't switch it off in --make mode, else *everything* gets -- recompiled which probably isn't what you want@@ -5200,26 +5212,26 @@ setDebugLevel :: Maybe Int -> DynP () setDebugLevel mb_n = upd (\dfs -> dfs{ debugLevel = mb_n `orElse` 2 }) -data PkgConfRef- = GlobalPkgConf- | UserPkgConf- | PkgConfFile FilePath+data PkgDbRef+ = GlobalPkgDb+ | UserPkgDb+ | PkgDbPath FilePath deriving Eq -addPkgConfRef :: PkgConfRef -> DynP ()-addPkgConfRef p = upd $ \s ->+addPkgDbRef :: PkgDbRef -> DynP ()+addPkgDbRef p = upd $ \s -> s { packageDBFlags = PackageDB p : packageDBFlags s } -removeUserPkgConf :: DynP ()-removeUserPkgConf = upd $ \s ->+removeUserPkgDb :: DynP ()+removeUserPkgDb = upd $ \s -> s { packageDBFlags = NoUserPackageDB : packageDBFlags s } -removeGlobalPkgConf :: DynP ()-removeGlobalPkgConf = upd $ \s ->+removeGlobalPkgDb :: DynP ()+removeGlobalPkgDb = upd $ \s -> s { packageDBFlags = NoGlobalPackageDB : packageDBFlags s } -clearPkgConf :: DynP ()-clearPkgConf = upd $ \s ->+clearPkgDb :: DynP ()+clearPkgDb = upd $ \s -> s { packageDBFlags = ClearPackageDBs : packageDBFlags s } parsePackageFlag :: String -- the flag@@ -5366,13 +5378,13 @@ parseEnvFile envfile = mapM_ parseEntry . lines where parseEntry str = case words str of- ("package-db": _) -> addPkgConfRef (PkgConfFile (envdir </> db))+ ("package-db": _) -> addPkgDbRef (PkgDbPath (envdir </> db)) -- relative package dbs are interpreted relative to the env file where envdir = takeDirectory envfile db = drop 11 str- ["clear-package-db"] -> clearPkgConf- ["global-package-db"] -> addPkgConfRef GlobalPkgConf- ["user-package-db"] -> addPkgConfRef UserPkgConf+ ["clear-package-db"] -> clearPkgDb+ ["global-package-db"] -> addPkgDbRef GlobalPkgDb+ ["user-package-db"] -> addPkgDbRef UserPkgDb ["package-id", pkgid] -> exposePackageId pkgid (('-':'-':_):_) -> return () -- comments -- and the original syntax introduced in 7.10:@@ -5602,7 +5614,7 @@ ("Debug on", showBool debugIsOn), ("LibDir", topDir dflags), -- The path of the global package database used by GHC- ("Global Package DB", systemPackageConfig dflags)+ ("Global Package DB", globalPackageDatabasePath dflags) ] where showBool True = "YES"
compiler/main/FileSettings.hs view
@@ -7,10 +7,10 @@ -- | Paths to various files and directories used by GHC, including those that -- provide more settings. data FileSettings = FileSettings- { fileSettings_ghcUsagePath :: FilePath -- ditto- , fileSettings_ghciUsagePath :: FilePath -- ditto- , fileSettings_toolDir :: Maybe FilePath -- ditto- , fileSettings_topDir :: FilePath -- ditto- , fileSettings_tmpDir :: String -- no trailing '/'- , fileSettings_systemPackageConfig :: FilePath+ { fileSettings_ghcUsagePath :: FilePath -- ditto+ , fileSettings_ghciUsagePath :: FilePath -- ditto+ , fileSettings_toolDir :: Maybe FilePath -- ditto+ , fileSettings_topDir :: FilePath -- ditto+ , fileSettings_tmpDir :: String -- no trailing '/'+ , fileSettings_globalPackageDatabase :: FilePath }
compiler/main/HeaderInfo.hs view
@@ -64,7 +64,8 @@ ([(Maybe FastString, Located ModuleName)], [(Maybe FastString, Located ModuleName)], Located ModuleName))- -- ^ The source imports, normal imports, and the module name.+ -- ^ The source imports and normal imports (with optional package+ -- names from -XPackageImports), and the module name. getImports dflags buf filename source_filename = do let loc = mkRealSrcLoc (mkFastString filename) 1 1 case unP parseHeader (mkPState dflags buf loc) of
compiler/main/Hooks.hs view
@@ -21,6 +21,8 @@ , runRnSpliceHook , getValueSafelyHook , createIservProcessHook+ , stgToCmmHook+ , cmmToRawCmmHook ) where import GhcPrelude@@ -43,6 +45,12 @@ import Type import System.Process import BasicTypes+import Module+import TyCon+import CostCentre+import GHC.Stg.Syntax+import Stream+import GHC.Cmm import GHC.Hs.Extension import Data.Maybe@@ -73,6 +81,8 @@ , runRnSpliceHook = Nothing , getValueSafelyHook = Nothing , createIservProcessHook = Nothing+ , stgToCmmHook = Nothing+ , cmmToRawCmmHook = Nothing } data Hooks = Hooks@@ -95,6 +105,10 @@ , getValueSafelyHook :: Maybe (HscEnv -> Name -> Type -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle)+ , stgToCmmHook :: Maybe (DynFlags -> Module -> [TyCon] -> CollectedCCs+ -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ())+ , cmmToRawCmmHook :: Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroup ()+ -> IO (Stream IO RawCmmGroup ())) } getHooked :: (Functor f, HasDynFlags f) => (Hooks -> Maybe a) -> a -> f a
compiler/main/HscTypes.hs view
@@ -195,7 +195,7 @@ , isHsBootOrSig, isHsigFile ) import qualified DriverPhases as Phase import BasicTypes-import IfaceSyn+import GHC.Iface.Syntax import Maybes import Outputable import SrcLoc@@ -224,6 +224,8 @@ import Control.Concurrent import System.Process ( ProcessHandle ) import Control.DeepSeq+import Control.Monad.Trans.Reader+import Control.Monad.Trans.Class -- ----------------------------------------------------------------------------- -- Compilation state@@ -1059,7 +1061,7 @@ -- module is Safe (so doesn't require the package be trusted -- itself) but imports some trustworthy modules from its own -- package (which does require its own package be trusted).- -- See Note [RnNames . Trust Own Package]+ -- See Note [Trust Own Package] in GHC.Rename.Names mi_complete_sigs :: [IfaceCompleteMatch], mi_doc_hdr :: Maybe HsDocString,@@ -1433,7 +1435,8 @@ mg_safe_haskell :: SafeHaskellMode, -- ^ Safe Haskell mode mg_trust_pkg :: Bool, -- ^ Do we need to trust our -- own package for Safe Haskell?- -- See Note [RnNames . Trust Own Package]+ -- See Note [Trust Own Package]+ -- in GHC.Rename.Names mg_doc_hdr :: !(Maybe HsDocString), -- ^ Module header. mg_decl_docs :: !DeclDocMap, -- ^ Docs on declarations.@@ -1607,7 +1610,7 @@ TcRnDriver.externaliseAndTidyId, so they get Names like Ghic4.foo. - Ids bound by the debugger etc have Names constructed by- IfaceEnv.newInteractiveBinder; at the call sites it is followed by+ GHC.Iface.Env.newInteractiveBinder; at the call sites it is followed by mkVanillaGlobal or mkVanillaGlobalWithInfo. So again, they are all Global, External. @@ -1651,7 +1654,7 @@ data InteractiveContext = InteractiveContext { ic_dflags :: DynFlags,- -- ^ The 'DynFlags' used to evaluate interative expressions+ -- ^ The 'DynFlags' used to evaluate interactive expressions -- and statements. ic_mod_index :: Int,@@ -1982,8 +1985,8 @@ -- (1) don't qualify if the package in question is "main", and (2) only qualify -- with a unit id if the package ID would be ambiguous. mkQualPackage :: DynFlags -> QueryQualifyPackage-mkQualPackage dflags pkg_key- | pkg_key == mainUnitId || pkg_key == interactiveUnitId+mkQualPackage dflags uid+ | uid == mainUnitId || uid == interactiveUnitId -- Skip the lookup if it's main, since it won't be in the package -- database! = False@@ -1994,7 +1997,7 @@ = False | otherwise = True- where mb_pkgid = fmap sourcePackageId (lookupPackage dflags pkg_key)+ where mb_pkgid = fmap sourcePackageId (lookupUnit dflags uid) -- | A function which only qualifies package names if necessary; but -- qualifies all other identifiers.@@ -2042,9 +2045,9 @@ -- scope, just for a start! -- N.B. the set of TyThings returned here *must* match the set of--- names returned by LoadIface.ifaceDeclImplicitBndrs, in the sense that+-- names returned by GHC.Iface.Load.ifaceDeclImplicitBndrs, in the sense that -- TyThing.getOccName should define a bijection between the two lists.--- This invariant is used in LoadIface.loadDecl (see note [Tricky iface loop])+-- This invariant is used in GHC.Iface.Load.loadDecl (see note [Tricky iface loop]) -- The order of the list does not matter. implicitTyThings :: TyThing -> [TyThing] implicitTyThings (AnId _) = []@@ -2323,6 +2326,10 @@ lookupTyCon :: Name -> m TyCon lookupTyCon = liftM tyThingTyCon . lookupThing +-- Instance used in DsMeta+instance MonadThings m => MonadThings (ReaderT s m) where+ lookupThing = lift . lookupThing+ {- ************************************************************************ * *@@ -2467,7 +2474,7 @@ -- or that are in the dep_pkgs of those modules -- The bool indicates if the package is required to be -- trusted when the module is imported as a safe import- -- (Safe Haskell). See Note [RnNames . Tracking Trust Transitively]+ -- (Safe Haskell). See Note [Tracking Trust Transitively] in GHC.Rename.Names , dep_orphs :: [Module] -- ^ Transitive closure of orphan modules (whether@@ -2490,7 +2497,7 @@ -- ^ All the plugins used while compiling this module. } deriving( Eq )- -- Equality used only for old/new comparison in MkIface.addFingerprints+ -- Equality used only for old/new comparison in GHC.Iface.Utils.addFingerprints -- See 'TcRnTypes.ImportAvails' for details on dependencies. instance Binary Dependencies where@@ -3098,7 +3105,7 @@ -} data HsParsedModule = HsParsedModule {- hpm_module :: Located (HsModule GhcPs),+ hpm_module :: Located HsModule, hpm_src_files :: [FilePath], -- ^ extra source files (e.g. from #includes). The lexer collects -- these from '# <file> <line>' pragmas, which the C preprocessor
− compiler/main/PackageConfig.hs
@@ -1,154 +0,0 @@-{-# LANGUAGE CPP, RecordWildCards, FlexibleInstances, MultiParamTypeClasses #-}---- |--- Package configuration information: essentially the interface to Cabal, with--- some utilities------ (c) The University of Glasgow, 2004----module PackageConfig (- -- $package_naming-- -- * UnitId- packageConfigId,- expandedPackageConfigId,- definitePackageConfigId,- installedPackageConfigId,-- -- * The PackageConfig type: information about a package- PackageConfig,- InstalledPackageInfo(..),- ComponentId(..),- SourcePackageId(..),- PackageName(..),- Version(..),- defaultPackageConfig,- sourcePackageIdString,- packageNameString,- pprPackageConfig,- ) where--#include "HsVersions.h"--import GhcPrelude--import GHC.PackageDb-import Data.Version--import FastString-import Outputable-import Module-import Unique---- -------------------------------------------------------------------------------- Our PackageConfig type is the InstalledPackageInfo from ghc-boot,--- which is similar to a subset of the InstalledPackageInfo type from Cabal.--type PackageConfig = InstalledPackageInfo- ComponentId- SourcePackageId- PackageName- Module.InstalledUnitId- Module.UnitId- Module.ModuleName- Module.Module---- TODO: there's no need for these to be FastString, as we don't need the uniq--- feature, but ghc doesn't currently have convenient support for any--- other compact string types, e.g. plain ByteString or Text.--newtype SourcePackageId = SourcePackageId FastString deriving (Eq, Ord)-newtype PackageName = PackageName FastString deriving (Eq, Ord)--instance BinaryStringRep SourcePackageId where- fromStringRep = SourcePackageId . mkFastStringByteString- toStringRep (SourcePackageId s) = bytesFS s--instance BinaryStringRep PackageName where- fromStringRep = PackageName . mkFastStringByteString- toStringRep (PackageName s) = bytesFS s--instance Uniquable SourcePackageId where- getUnique (SourcePackageId n) = getUnique n--instance Uniquable PackageName where- getUnique (PackageName n) = getUnique n--instance Outputable SourcePackageId where- ppr (SourcePackageId str) = ftext str--instance Outputable PackageName where- ppr (PackageName str) = ftext str--defaultPackageConfig :: PackageConfig-defaultPackageConfig = emptyInstalledPackageInfo--sourcePackageIdString :: PackageConfig -> String-sourcePackageIdString pkg = unpackFS str- where- SourcePackageId str = sourcePackageId pkg--packageNameString :: PackageConfig -> String-packageNameString pkg = unpackFS str- where- PackageName str = packageName pkg--pprPackageConfig :: PackageConfig -> SDoc-pprPackageConfig InstalledPackageInfo {..} =- vcat [- field "name" (ppr packageName),- field "version" (text (showVersion packageVersion)),- field "id" (ppr unitId),- field "exposed" (ppr exposed),- field "exposed-modules" (ppr exposedModules),- field "hidden-modules" (fsep (map ppr hiddenModules)),- field "trusted" (ppr trusted),- field "import-dirs" (fsep (map text importDirs)),- field "library-dirs" (fsep (map text libraryDirs)),- field "dynamic-library-dirs" (fsep (map text libraryDynDirs)),- field "hs-libraries" (fsep (map text hsLibraries)),- field "extra-libraries" (fsep (map text extraLibraries)),- field "extra-ghci-libraries" (fsep (map text extraGHCiLibraries)),- field "include-dirs" (fsep (map text includeDirs)),- field "includes" (fsep (map text includes)),- field "depends" (fsep (map ppr depends)),- field "cc-options" (fsep (map text ccOptions)),- field "ld-options" (fsep (map text ldOptions)),- field "framework-dirs" (fsep (map text frameworkDirs)),- field "frameworks" (fsep (map text frameworks)),- field "haddock-interfaces" (fsep (map text haddockInterfaces)),- field "haddock-html" (fsep (map text haddockHTMLs))- ]- where- field name body = text name <> colon <+> nest 4 body---- -------------------------------------------------------------------------------- UnitId (package names, versions and dep hash)---- $package_naming--- #package_naming#--- Mostly the compiler deals in terms of 'UnitId's, which are md5 hashes--- of a package ID, keys of its dependencies, and Cabal flags. You're expected--- to pass in the unit id in the @-this-unit-id@ flag. However, for--- wired-in packages like @base@ & @rts@, we don't necessarily know what the--- version is, so these are handled specially; see #wired_in_packages#.---- | Get the GHC 'UnitId' right out of a Cabalish 'PackageConfig'-installedPackageConfigId :: PackageConfig -> InstalledUnitId-installedPackageConfigId = unitId--packageConfigId :: PackageConfig -> UnitId-packageConfigId p =- if indefinite p- then newUnitId (componentId p) (instantiatedWith p)- else DefiniteUnitId (DefUnitId (unitId p))--expandedPackageConfigId :: PackageConfig -> UnitId-expandedPackageConfigId p =- newUnitId (componentId p) (instantiatedWith p)--definitePackageConfigId :: PackageConfig -> Maybe DefUnitId-definitePackageConfigId p =- case packageConfigId p of- DefiniteUnitId def_uid -> Just def_uid- _ -> Nothing
− compiler/main/PackageConfig.hs-boot
@@ -1,7 +0,0 @@-module PackageConfig where-import FastString-import {-# SOURCE #-} Module-import GHC.PackageDb-newtype PackageName = PackageName FastString-newtype SourcePackageId = SourcePackageId FastString-type PackageConfig = InstalledPackageInfo ComponentId SourcePackageId PackageName UnitId ModuleName Module
compiler/main/Packages.hs view
@@ -4,22 +4,23 @@ -- | Package manipulation module Packages (- module PackageConfig,+ module UnitInfo, -- * Reading the package config, and processing cmdline args- PackageState(preloadPackages, explicitPackages, moduleToPkgConfAll, requirementContext),- PackageConfigMap,+ PackageState(preloadPackages, explicitPackages, moduleNameProvidersMap, requirementContext),+ PackageDatabase (..),+ UnitInfoMap, emptyPackageState, initPackages,- readPackageConfigs,+ readPackageDatabases,+ readPackageDatabase, getPackageConfRefs,- resolvePackageConfig,- readPackageConfig,- listPackageConfigMap,+ resolvePackageDatabase,+ listUnitInfoMap, -- * Querying the package config- lookupPackage,- lookupPackage',+ lookupUnit,+ lookupUnit', lookupInstalledPackage, lookupPackageName, improveUnitId,@@ -45,7 +46,7 @@ getPackageExtraCcOpts, getPackageFrameworkPath, getPackageFrameworks,- getPackageConfigMap,+ getUnitInfoMap, getPreloadPackagesAnd, collectArchives,@@ -68,7 +69,7 @@ import GhcPrelude import GHC.PackageDb-import PackageConfig+import UnitInfo import DynFlags import Name ( Name, nameModule_maybe ) import UniqFM@@ -80,18 +81,16 @@ import GHC.Platform import Outputable import Maybes-import CmdLineParser import System.Environment ( getEnv ) import FastString-import ErrUtils ( debugTraceMsg, MsgDoc, dumpIfSet_dyn, compilationProgressMsg,+import ErrUtils ( debugTraceMsg, MsgDoc, dumpIfSet_dyn, withTiming, DumpFormat (..) ) import Exception import System.Directory import System.FilePath as FilePath import qualified System.FilePath.Posix as FilePath.Posix-import System.IO.Error ( isDoesNotExistError ) import Control.Monad import Data.Graph (stronglyConnComp, SCC(..)) import Data.Char ( toUpper )@@ -173,9 +172,9 @@ fromOrigPackage :: Maybe Bool -- | Is the module available from a reexport of an exposed package? -- There could be multiple.- , fromExposedReexport :: [PackageConfig]+ , fromExposedReexport :: [UnitInfo] -- | Is the module available from a reexport of a hidden package?- , fromHiddenReexport :: [PackageConfig]+ , fromHiddenReexport :: [UnitInfo] -- | Did the module export come from a package flag? (ToDo: track -- more information. , fromPackageFlag :: Bool@@ -206,9 +205,9 @@ fromExposedModules e = ModOrigin (Just e) [] [] False -- | Smart constructor for a module which is in @reexported-modules@. Takes--- as an argument whether or not the reexporting package is expsed, and--- also its 'PackageConfig'.-fromReexportedModules :: Bool -> PackageConfig -> ModuleOrigin+-- as an argument whether or not the reexporting package is exposed, and+-- also its 'UnitInfo'.+fromReexportedModules :: Bool -> UnitInfo -> ModuleOrigin fromReexportedModules True pkg = ModOrigin Nothing [pkg] [] False fromReexportedModules False pkg = ModOrigin Nothing [] [pkg] False @@ -246,10 +245,10 @@ -- | 'UniqFM' map from 'InstalledUnitId' type InstalledUnitIdMap = UniqDFM --- | 'UniqFM' map from 'UnitId' to 'PackageConfig', plus+-- | 'UniqFM' map from 'UnitId' to 'UnitInfo', plus -- the transitive closure of preload packages.-data PackageConfigMap = PackageConfigMap {- unPackageConfigMap :: InstalledUnitIdMap PackageConfig,+data UnitInfoMap = UnitInfoMap {+ unUnitInfoMap :: InstalledUnitIdMap UnitInfo, -- | The set of transitively reachable packages according -- to the explicitly provided command line arguments. -- See Note [UnitId to InstalledUnitId improvement]@@ -312,19 +311,21 @@ type WiredUnitId = DefUnitId type PreloadUnitId = InstalledUnitId --- | Map from 'ModuleName' to 'Module' to all the origins of the bindings--- in scope. The 'PackageConf' is not cached, mostly for convenience reasons--- (since this is the slow path, we'll just look it up again).-type ModuleToPkgConfAll =+-- | Map from 'ModuleName' to a set of of module providers (i.e. a 'Module' and+-- its 'ModuleOrigin').+--+-- NB: the set is in fact a 'Map Module ModuleOrigin', probably to keep only one+-- origin for a given 'Module'+type ModuleNameProvidersMap = Map ModuleName (Map Module ModuleOrigin) data PackageState = PackageState {- -- | A mapping of 'UnitId' to 'PackageConfig'. This list is adjusted- -- so that only valid packages are here. 'PackageConfig' reflects+ -- | A mapping of 'UnitId' to 'UnitInfo'. This list is adjusted+ -- so that only valid packages are here. 'UnitInfo' reflects -- what was stored *on disk*, except for the 'trusted' flag, which -- is adjusted at runtime. (In particular, some packages in this map -- may have the 'exposed' flag be 'False'.)- pkgIdMap :: PackageConfigMap,+ unitInfoMap :: UnitInfoMap, -- | A mapping of 'PackageName' to 'ComponentId'. This is used when -- users refer to packages in Backpack includes.@@ -346,10 +347,10 @@ -- | This is a full map from 'ModuleName' to all modules which may possibly -- be providing it. These providers may be hidden (but we'll still want -- to report them in error messages), or it may be an ambiguous import.- moduleToPkgConfAll :: !ModuleToPkgConfAll,+ moduleNameProvidersMap :: !ModuleNameProvidersMap, - -- | A map, like 'moduleToPkgConfAll', but controlling plugin visibility.- pluginModuleToPkgConfAll :: !ModuleToPkgConfAll,+ -- | A map, like 'moduleNameProvidersMap', but controlling plugin visibility.+ pluginModuleNameProvidersMap :: !ModuleNameProvidersMap, -- | A map saying, for each requirement, what interfaces must be merged -- together when we use them. For example, if our dependencies@@ -363,33 +364,39 @@ emptyPackageState :: PackageState emptyPackageState = PackageState {- pkgIdMap = emptyPackageConfigMap,+ unitInfoMap = emptyUnitInfoMap, packageNameMap = Map.empty, unwireMap = Map.empty, preloadPackages = [], explicitPackages = [],- moduleToPkgConfAll = Map.empty,- pluginModuleToPkgConfAll = Map.empty,+ moduleNameProvidersMap = Map.empty,+ pluginModuleNameProvidersMap = Map.empty, requirementContext = Map.empty } -type InstalledPackageIndex = Map InstalledUnitId PackageConfig+-- | Package database+data PackageDatabase = PackageDatabase+ { packageDatabasePath :: FilePath+ , packageDatabaseUnits :: [UnitInfo]+ } +type InstalledPackageIndex = Map InstalledUnitId UnitInfo+ -- | Empty package configuration map-emptyPackageConfigMap :: PackageConfigMap-emptyPackageConfigMap = PackageConfigMap emptyUDFM emptyUniqSet+emptyUnitInfoMap :: UnitInfoMap+emptyUnitInfoMap = UnitInfoMap emptyUDFM emptyUniqSet --- | Find the package we know about with the given unit id, if any-lookupPackage :: DynFlags -> UnitId -> Maybe PackageConfig-lookupPackage dflags = lookupPackage' (isIndefinite dflags) (pkgIdMap (pkgState dflags))+-- | Find the unit we know about with the given unit id, if any+lookupUnit :: DynFlags -> UnitId -> Maybe UnitInfo+lookupUnit dflags = lookupUnit' (isIndefinite dflags) (unitInfoMap (pkgState dflags)) -- | A more specialized interface, which takes a boolean specifying -- whether or not to look for on-the-fly renamed interfaces, and--- just a 'PackageConfigMap' rather than a 'DynFlags' (so it can+-- just a 'UnitInfoMap' rather than a 'DynFlags' (so it can -- be used while we're initializing 'DynFlags'-lookupPackage' :: Bool -> PackageConfigMap -> UnitId -> Maybe PackageConfig-lookupPackage' False (PackageConfigMap pkg_map _) uid = lookupUDFM pkg_map uid-lookupPackage' True m@(PackageConfigMap pkg_map _) uid =+lookupUnit' :: Bool -> UnitInfoMap -> UnitId -> Maybe UnitInfo+lookupUnit' False (UnitInfoMap pkg_map _) uid = lookupUDFM pkg_map uid+lookupUnit' True m@(UnitInfoMap pkg_map _) uid = case splitUnitIdInsts uid of (iuid, Just indef) -> fmap (renamePackage m (indefUnitIdInsts indef))@@ -400,10 +407,10 @@ -- | Find the indefinite package for a given 'ComponentId'. -- The way this works is just by fiat'ing that every indefinite package's -- unit key is precisely its component ID; and that they share uniques.-lookupComponentId :: DynFlags -> ComponentId -> Maybe PackageConfig+lookupComponentId :: DynFlags -> ComponentId -> Maybe UnitInfo lookupComponentId dflags (ComponentId cid_fs) = lookupUDFM pkg_map cid_fs where- PackageConfigMap pkg_map = pkgIdMap (pkgState dflags)+ UnitInfoMap pkg_map = unitInfoMap (pkgState dflags) -} -- | Find the package we know about with the given package name (e.g. @foo@), if any@@ -412,35 +419,35 @@ lookupPackageName dflags n = Map.lookup n (packageNameMap (pkgState dflags)) -- | Search for packages with a given package ID (e.g. \"foo-0.1\")-searchPackageId :: DynFlags -> SourcePackageId -> [PackageConfig]+searchPackageId :: DynFlags -> SourcePackageId -> [UnitInfo] searchPackageId dflags pid = filter ((pid ==) . sourcePackageId)- (listPackageConfigMap dflags)+ (listUnitInfoMap dflags) -- | Extends the package configuration map with a list of package configs.-extendPackageConfigMap- :: PackageConfigMap -> [PackageConfig] -> PackageConfigMap-extendPackageConfigMap (PackageConfigMap pkg_map closure) new_pkgs- = PackageConfigMap (foldl' add pkg_map new_pkgs) closure+extendUnitInfoMap+ :: UnitInfoMap -> [UnitInfo] -> UnitInfoMap+extendUnitInfoMap (UnitInfoMap pkg_map closure) new_pkgs+ = UnitInfoMap (foldl' add pkg_map new_pkgs) closure -- We also add the expanded version of the packageConfigId, so that -- 'improveUnitId' can find it.- where add pkg_map p = addToUDFM (addToUDFM pkg_map (expandedPackageConfigId p) p)- (installedPackageConfigId p) p+ where add pkg_map p = addToUDFM (addToUDFM pkg_map (expandedUnitInfoId p) p)+ (installedUnitInfoId p) p -- | Looks up the package with the given id in the package state, panicing if it is -- not found-getPackageDetails :: HasDebugCallStack => DynFlags -> UnitId -> PackageConfig+getPackageDetails :: HasDebugCallStack => DynFlags -> UnitId -> UnitInfo getPackageDetails dflags pid =- case lookupPackage dflags pid of+ case lookupUnit dflags pid of Just config -> config Nothing -> pprPanic "getPackageDetails" (ppr pid) -lookupInstalledPackage :: DynFlags -> InstalledUnitId -> Maybe PackageConfig-lookupInstalledPackage dflags uid = lookupInstalledPackage' (pkgIdMap (pkgState dflags)) uid+lookupInstalledPackage :: DynFlags -> InstalledUnitId -> Maybe UnitInfo+lookupInstalledPackage dflags uid = lookupInstalledPackage' (unitInfoMap (pkgState dflags)) uid -lookupInstalledPackage' :: PackageConfigMap -> InstalledUnitId -> Maybe PackageConfig-lookupInstalledPackage' (PackageConfigMap db _) uid = lookupUDFM db uid+lookupInstalledPackage' :: UnitInfoMap -> InstalledUnitId -> Maybe UnitInfo+lookupInstalledPackage' (UnitInfoMap db _) uid = lookupUDFM db uid -getInstalledPackageDetails :: HasDebugCallStack => DynFlags -> InstalledUnitId -> PackageConfig+getInstalledPackageDetails :: HasDebugCallStack => DynFlags -> InstalledUnitId -> UnitInfo getInstalledPackageDetails dflags uid = case lookupInstalledPackage dflags uid of Just config -> config@@ -450,17 +457,16 @@ -- this function, although all packages in this map are "visible", this -- does not imply that the exposed-modules of the package are available -- (they may have been thinned or renamed).-listPackageConfigMap :: DynFlags -> [PackageConfig]-listPackageConfigMap dflags = eltsUDFM pkg_map+listUnitInfoMap :: DynFlags -> [UnitInfo]+listUnitInfoMap dflags = eltsUDFM pkg_map where- PackageConfigMap pkg_map _ = pkgIdMap (pkgState dflags)+ UnitInfoMap pkg_map _ = unitInfoMap (pkgState dflags) -- ---------------------------------------------------------------------------- -- Loading the package db files and building up the package state --- | Call this after 'DynFlags.parseDynFlags'. It reads the package--- database files, and sets up various internal tables of package--- information, according to the package-related flags on the+-- | Read the package database files, and sets up various internal tables of+-- package information, according to the package-related flags on the -- command-line (@-package@, @-hide-package@ etc.) -- -- Returns a list of packages to link in if we're doing dynamic linking.@@ -472,46 +478,52 @@ -- 'pkgState' in 'DynFlags' and return a list of packages to -- link in. initPackages :: DynFlags -> IO (DynFlags, [PreloadUnitId])-initPackages dflags0 = withTiming dflags0+initPackages dflags = withTiming dflags (text "initializing package database") forcePkgDb $ do- dflags <- interpretPackageEnv dflags0- pkg_db <-+ read_pkg_dbs <- case pkgDatabase dflags of- Nothing -> readPackageConfigs dflags- Just db -> return $ map (\(p, pkgs)- -> (p, setBatchPackageFlags dflags pkgs)) db+ Nothing -> readPackageDatabases dflags+ Just dbs -> return dbs++ let+ distrust_all db = db { packageDatabaseUnits = distrustAllUnits (packageDatabaseUnits db) }++ pkg_dbs+ | gopt Opt_DistrustAllPackages dflags = map distrust_all read_pkg_dbs+ | otherwise = read_pkg_dbs+ (pkg_state, preload, insts)- <- mkPackageState dflags pkg_db []- return (dflags{ pkgDatabase = Just pkg_db,+ <- mkPackageState dflags pkg_dbs []+ return (dflags{ pkgDatabase = Just read_pkg_dbs, pkgState = pkg_state, thisUnitIdInsts_ = insts }, preload) where- forcePkgDb (dflags, _) = pkgIdMap (pkgState dflags) `seq` ()+ forcePkgDb (dflags, _) = unitInfoMap (pkgState dflags) `seq` () -- ----------------------------------------------------------------------------- -- Reading the package database(s) -readPackageConfigs :: DynFlags -> IO [(FilePath, [PackageConfig])]-readPackageConfigs dflags = do+readPackageDatabases :: DynFlags -> IO [PackageDatabase]+readPackageDatabases dflags = do conf_refs <- getPackageConfRefs dflags- confs <- liftM catMaybes $ mapM (resolvePackageConfig dflags) conf_refs- mapM (readPackageConfig dflags) confs+ confs <- liftM catMaybes $ mapM (resolvePackageDatabase dflags) conf_refs+ mapM (readPackageDatabase dflags) confs -getPackageConfRefs :: DynFlags -> IO [PkgConfRef]+getPackageConfRefs :: DynFlags -> IO [PkgDbRef] getPackageConfRefs dflags = do- let system_conf_refs = [UserPkgConf, GlobalPkgConf]+ let system_conf_refs = [UserPkgDb, GlobalPkgDb] e_pkg_path <- tryIO (getEnv $ map toUpper (programName dflags) ++ "_PACKAGE_PATH") let base_conf_refs = case e_pkg_path of Left _ -> system_conf_refs Right path | not (null path) && isSearchPathSeparator (last path)- -> map PkgConfFile (splitSearchPath (init path)) ++ system_conf_refs+ -> map PkgDbPath (splitSearchPath (init path)) ++ system_conf_refs | otherwise- -> map PkgConfFile (splitSearchPath path)+ -> map PkgDbPath (splitSearchPath path) -- Apply the package DB-related flags from the command line to get the -- final list of package DBs.@@ -528,36 +540,39 @@ doFlag NoGlobalPackageDB dbs = filter isNotGlobal dbs doFlag ClearPackageDBs _ = [] - isNotUser UserPkgConf = False+ isNotUser UserPkgDb = False isNotUser _ = True - isNotGlobal GlobalPkgConf = False+ isNotGlobal GlobalPkgDb = False isNotGlobal _ = True -resolvePackageConfig :: DynFlags -> PkgConfRef -> IO (Maybe FilePath)-resolvePackageConfig dflags GlobalPkgConf = return $ Just (systemPackageConfig dflags)+-- | Return the path of a package database from a 'PkgDbRef'. Return 'Nothing'+-- when the user database filepath is expected but the latter doesn't exist.+-- -- NB: This logic is reimplemented in Cabal, so if you change it,--- make sure you update Cabal. (Or, better yet, dump it in the+-- make sure you update Cabal. (Or, better yet, dump it in the -- compiler info so Cabal can use the info.)-resolvePackageConfig dflags UserPkgConf = runMaybeT $ do+resolvePackageDatabase :: DynFlags -> PkgDbRef -> IO (Maybe FilePath)+resolvePackageDatabase dflags GlobalPkgDb = return $ Just (globalPackageDatabasePath dflags)+resolvePackageDatabase dflags UserPkgDb = runMaybeT $ do dir <- versionedAppDir dflags let pkgconf = dir </> "package.conf.d" exist <- tryMaybeT $ doesDirectoryExist pkgconf if exist then return pkgconf else mzero-resolvePackageConfig _ (PkgConfFile name) = return $ Just name+resolvePackageDatabase _ (PkgDbPath name) = return $ Just name -readPackageConfig :: DynFlags -> FilePath -> IO (FilePath, [PackageConfig])-readPackageConfig dflags conf_file = do+readPackageDatabase :: DynFlags -> FilePath -> IO PackageDatabase+readPackageDatabase dflags conf_file = do isdir <- doesDirectoryExist conf_file proto_pkg_configs <- if isdir- then readDirStylePackageConfig conf_file+ then readDirStyleUnitInfo conf_file else do isfile <- doesFileExist conf_file if isfile then do- mpkgs <- tryReadOldFileStylePackageConfig+ mpkgs <- tryReadOldFileStyleUnitInfo case mpkgs of Just pkgs -> return pkgs Nothing -> throwGhcExceptionIO $ InstallationError $@@ -569,17 +584,16 @@ "can't find a package database at " ++ conf_file let- -- Fix #16360: remove trailing slash from conf_file before calculting pkgroot+ -- Fix #16360: remove trailing slash from conf_file before calculating pkgroot conf_file' = dropTrailingPathSeparator conf_file top_dir = topDir dflags pkgroot = takeDirectory conf_file'- pkg_configs1 = map (mungePackageConfig top_dir pkgroot)+ pkg_configs1 = map (mungeUnitInfo top_dir pkgroot) proto_pkg_configs- pkg_configs2 = setBatchPackageFlags dflags pkg_configs1 --- return (conf_file', pkg_configs2)+ return $ PackageDatabase conf_file' pkg_configs1 where- readDirStylePackageConfig conf_dir = do+ readDirStyleUnitInfo conf_dir = do let filename = conf_dir </> "package.cache" cache_exists <- doesFileExist filename if cache_exists@@ -617,7 +631,7 @@ -- We cannot just replace the file with a new dir style since Cabal still -- assumes it's a file and tries to overwrite with 'writeFile'. -- ghc-pkg also cooperates with this workaround.- tryReadOldFileStylePackageConfig = do+ tryReadOldFileStyleUnitInfo = do content <- readFile conf_file `catchIO` \_ -> return "" if take 2 content == "[]" then do@@ -625,26 +639,22 @@ direxists <- doesDirectoryExist conf_dir if direxists then do debugTraceMsg dflags 2 (text "Ignoring old file-style db and trying:" <+> text conf_dir)- liftM Just (readDirStylePackageConfig conf_dir)+ liftM Just (readDirStyleUnitInfo conf_dir) else return (Just []) -- ghc-pkg will create it when it's updated else return Nothing -setBatchPackageFlags :: DynFlags -> [PackageConfig] -> [PackageConfig]-setBatchPackageFlags dflags pkgs = maybeDistrustAll pkgs+distrustAllUnits :: [UnitInfo] -> [UnitInfo]+distrustAllUnits pkgs = map distrust pkgs where- maybeDistrustAll pkgs'- | gopt Opt_DistrustAllPackages dflags = map distrust pkgs'- | otherwise = pkgs'- distrust pkg = pkg{ trusted = False } -mungePackageConfig :: FilePath -> FilePath- -> PackageConfig -> PackageConfig-mungePackageConfig top_dir pkgroot =+mungeUnitInfo :: FilePath -> FilePath+ -> UnitInfo -> UnitInfo+mungeUnitInfo top_dir pkgroot = mungeDynLibFields . mungePackagePaths top_dir pkgroot -mungeDynLibFields :: PackageConfig -> PackageConfig+mungeDynLibFields :: UnitInfo -> UnitInfo mungeDynLibFields pkg = pkg { libraryDynDirs = libraryDynDirs pkg@@ -655,7 +665,7 @@ orIfNull flags _ = flags -- TODO: This code is duplicated in utils/ghc-pkg/Main.hs-mungePackagePaths :: FilePath -> FilePath -> PackageConfig -> PackageConfig+mungePackagePaths :: FilePath -> FilePath -> UnitInfo -> UnitInfo -- Perform path/URL variable substitution as per the Cabal ${pkgroot} spec -- (http://www.haskell.org/pipermail/libraries/2009-May/011772.html) -- Paths/URLs can be relative to ${pkgroot} or ${pkgrooturl}.@@ -713,9 +723,9 @@ :: DynFlags -> PackagePrecedenceIndex -> UnusablePackages- -> [PackageConfig]+ -> [UnitInfo] -> TrustFlag- -> IO [PackageConfig]+ -> IO [UnitInfo] applyTrustFlag dflags prec_map unusable pkgs flag = case flag of -- we trust all matching packages. Maybe should only trust first one?@@ -729,8 +739,7 @@ DistrustPackage str -> case selectPackages prec_map (PackageArg str) pkgs unusable of Left ps -> trustFlagErr dflags flag ps- Right (ps,qs) -> return (map distrust ps ++ qs)- where distrust p = p {trusted=False}+ Right (ps,qs) -> return (distrustAllUnits ps ++ qs) -- | A little utility to tell if the 'thisPackage' is indefinite -- (if it is not, we should never use on-the-fly renaming.)@@ -740,11 +749,11 @@ applyPackageFlag :: DynFlags -> PackagePrecedenceIndex- -> PackageConfigMap+ -> UnitInfoMap -> UnusablePackages -> Bool -- if False, if you expose a package, it implicitly hides -- any previously exposed packages with the same name- -> [PackageConfig]+ -> [UnitInfo] -> VisibilityMap -- Initially exposed -> PackageFlag -- flag to apply -> IO VisibilityMap -- Now exposed@@ -826,10 +835,10 @@ -- packages. Furthermore, any packages it returns are *renamed* -- if the 'UnitArg' has a renaming associated with it. findPackages :: PackagePrecedenceIndex- -> PackageConfigMap -> PackageArg -> [PackageConfig]+ -> UnitInfoMap -> PackageArg -> [UnitInfo] -> UnusablePackages- -> Either [(PackageConfig, UnusablePackageReason)]- [PackageConfig]+ -> Either [(UnitInfo, UnusablePackageReason)]+ [UnitInfo] findPackages prec_map pkg_db arg pkgs unusable = let ps = mapMaybe (finder arg) pkgs in if null ps@@ -843,16 +852,16 @@ else Nothing finder (UnitIdArg uid) p = let (iuid, mb_indef) = splitUnitIdInsts uid- in if iuid == installedPackageConfigId p+ in if iuid == installedUnitInfoId p then Just (case mb_indef of Nothing -> p Just indef -> renamePackage pkg_db (indefUnitIdInsts indef) p) else Nothing -selectPackages :: PackagePrecedenceIndex -> PackageArg -> [PackageConfig]+selectPackages :: PackagePrecedenceIndex -> PackageArg -> [UnitInfo] -> UnusablePackages- -> Either [(PackageConfig, UnusablePackageReason)]- ([PackageConfig], [PackageConfig])+ -> Either [(UnitInfo, UnusablePackageReason)]+ ([UnitInfo], [UnitInfo]) selectPackages prec_map arg pkgs unusable = let matches = matching arg (ps,rest) = partition matches pkgs@@ -860,9 +869,9 @@ then Left (filter (matches.fst) (Map.elems unusable)) else Right (sortByPreference prec_map ps, rest) --- | Rename a 'PackageConfig' according to some module instantiation.-renamePackage :: PackageConfigMap -> [(ModuleName, Module)]- -> PackageConfig -> PackageConfig+-- | Rename a 'UnitInfo' according to some module instantiation.+renamePackage :: UnitInfoMap -> [(ModuleName, Module)]+ -> UnitInfo -> UnitInfo renamePackage pkg_map insts conf = let hsubst = listToUFM insts smod = renameHoleModule' pkg_map hsubst@@ -876,22 +885,22 @@ -- A package named on the command line can either include the -- version, or just the name if it is unambiguous.-matchingStr :: String -> PackageConfig -> Bool+matchingStr :: String -> UnitInfo -> Bool matchingStr str p = str == sourcePackageIdString p || str == packageNameString p -matchingId :: InstalledUnitId -> PackageConfig -> Bool-matchingId uid p = uid == installedPackageConfigId p+matchingId :: InstalledUnitId -> UnitInfo -> Bool+matchingId uid p = uid == installedUnitInfoId p -matching :: PackageArg -> PackageConfig -> Bool+matching :: PackageArg -> UnitInfo -> Bool matching (PackageArg str) = matchingStr str matching (UnitIdArg (DefiniteUnitId (DefUnitId uid))) = matchingId uid matching (UnitIdArg _) = \_ -> False -- TODO: warn in this case -- | This sorts a list of packages, putting "preferred" packages first. -- See 'compareByPreference' for the semantics of "preference".-sortByPreference :: PackagePrecedenceIndex -> [PackageConfig] -> [PackageConfig]+sortByPreference :: PackagePrecedenceIndex -> [UnitInfo] -> [UnitInfo] sortByPreference prec_map = sortBy (flip (compareByPreference prec_map)) -- | Returns 'GT' if @pkg@ should be preferred over @pkg'@ when picking@@ -914,8 +923,8 @@ -- in the @PrelNames@ module. compareByPreference :: PackagePrecedenceIndex- -> PackageConfig- -> PackageConfig+ -> UnitInfo+ -> UnitInfo -> Ordering compareByPreference prec_map pkg pkg' | Just prec <- Map.lookup (unitId pkg) prec_map@@ -946,21 +955,21 @@ packageFlagErr :: DynFlags -> PackageFlag- -> [(PackageConfig, UnusablePackageReason)]+ -> [(UnitInfo, UnusablePackageReason)] -> IO a packageFlagErr dflags flag reasons = packageFlagErr' dflags (pprFlag flag) reasons trustFlagErr :: DynFlags -> TrustFlag- -> [(PackageConfig, UnusablePackageReason)]+ -> [(UnitInfo, UnusablePackageReason)] -> IO a trustFlagErr dflags flag reasons = packageFlagErr' dflags (pprTrustFlag flag) reasons packageFlagErr' :: DynFlags -> SDoc- -> [(PackageConfig, UnusablePackageReason)]+ -> [(UnitInfo, UnusablePackageReason)] -> IO a packageFlagErr' dflags flag_doc reasons = throwGhcExceptionIO (CmdLineError (showSDoc dflags $ err))@@ -990,16 +999,16 @@ type WiredInUnitId = String type WiredPackagesMap = Map WiredUnitId WiredUnitId -wired_in_pkgids :: [WiredInUnitId]-wired_in_pkgids = map unitIdString wiredInUnitIds+wired_in_unitids :: [WiredInUnitId]+wired_in_unitids = map unitIdString wiredInUnitIds findWiredInPackages :: DynFlags -> PackagePrecedenceIndex- -> [PackageConfig] -- database+ -> [UnitInfo] -- database -> VisibilityMap -- info on what packages are visible -- for wired in selection- -> IO ([PackageConfig], -- package database updated for wired in+ -> IO ([UnitInfo], -- package database updated for wired in WiredPackagesMap) -- map from unit id to wired identity findWiredInPackages dflags prec_map pkgs vis_map = do@@ -1007,7 +1016,7 @@ -- their canonical names (eg. base-1.0 ==> base), as described -- in Note [Wired-in packages] in Module let- matches :: PackageConfig -> WiredInUnitId -> Bool+ matches :: UnitInfo -> WiredInUnitId -> Bool pc `matches` pid -- See Note [The integer library] in PrelNames | pid == unitIdString integerUnitId@@ -1031,8 +1040,8 @@ -- this works even when there is no exposed wired in package -- available. --- findWiredInPackage :: [PackageConfig] -> WiredInUnitId- -> IO (Maybe (WiredInUnitId, PackageConfig))+ findWiredInPackage :: [UnitInfo] -> WiredInUnitId+ -> IO (Maybe (WiredInUnitId, UnitInfo)) findWiredInPackage pkgs wired_pkg = let all_ps = [ p | p <- pkgs, p `matches` wired_pkg ] all_exposed_ps =@@ -1050,8 +1059,8 @@ <> text wired_pkg <> text " not found." return Nothing- pick :: PackageConfig- -> IO (Maybe (WiredInUnitId, PackageConfig))+ pick :: UnitInfo+ -> IO (Maybe (WiredInUnitId, UnitInfo)) pick pkg = do debugTraceMsg dflags 2 $ text "wired-in package "@@ -1061,7 +1070,7 @@ return (Just (wired_pkg, pkg)) - mb_wired_in_pkgs <- mapM (findWiredInPackage pkgs) wired_in_pkgids+ mb_wired_in_pkgs <- mapM (findWiredInPackage pkgs) wired_in_unitids let wired_in_pkgs = catMaybes mb_wired_in_pkgs @@ -1074,7 +1083,7 @@ -- latest, base-3.0 is a compat wrapper depending on base-4.0. {- deleteOtherWiredInPackages pkgs = filterOut bad pkgs- where bad p = any (p `matches`) wired_in_pkgids+ where bad p = any (p `matches`) wired_in_unitids && package p `notElem` map fst wired_in_ids -} @@ -1082,12 +1091,12 @@ wiredInMap = Map.fromList [ (key, DefUnitId (stringToInstalledUnitId wiredInUnitId)) | (wiredInUnitId, pkg) <- wired_in_pkgs- , Just key <- pure $ definitePackageConfigId pkg+ , Just key <- pure $ definiteUnitInfoId pkg ] updateWiredInDependencies pkgs = map (upd_deps . upd_pkg) pkgs where upd_pkg pkg- | Just def_uid <- definitePackageConfigId pkg+ | Just def_uid <- definiteUnitInfoId pkg , Just wiredInUnitId <- Map.lookup def_uid wiredInMap = let fs = installedUnitIdFS (unDefUnitId wiredInUnitId) in pkg {@@ -1166,7 +1175,7 @@ ppr (ShadowedDependencies uids) = brackets (text "shadowed" <+> ppr uids) type UnusablePackages = Map InstalledUnitId- (PackageConfig, UnusablePackageReason)+ (UnitInfo, UnusablePackageReason) pprReason :: SDoc -> UnusablePackageReason -> SDoc pprReason pref reason = case reason of@@ -1186,7 +1195,7 @@ pref <+> text "unusable due to shadowed dependencies:" $$ nest 2 (hsep (map ppr deps)) -reportCycles :: DynFlags -> [SCC PackageConfig] -> IO ()+reportCycles :: DynFlags -> [SCC UnitInfo] -> IO () reportCycles dflags sccs = mapM_ report sccs where report (AcyclicSCC _) = return ()@@ -1222,11 +1231,11 @@ -- | Given a list of 'InstalledUnitId's to remove, a database, -- and a reverse dependency index (as computed by 'reverseDeps'), -- remove those packages, plus any packages which depend on them.--- Returns the pruned database, as well as a list of 'PackageConfig's+-- Returns the pruned database, as well as a list of 'UnitInfo's -- that was removed. removePackages :: [InstalledUnitId] -> RevIndex -> InstalledPackageIndex- -> (InstalledPackageIndex, [PackageConfig])+ -> (InstalledPackageIndex, [UnitInfo]) removePackages uids index m = go uids (m,[]) where go [] (m,pkgs) = (m,pkgs)@@ -1238,19 +1247,19 @@ | otherwise = go uids (m,pkgs) --- | Given a 'PackageConfig' from some 'InstalledPackageIndex',+-- | Given a 'UnitInfo' from some 'InstalledPackageIndex', -- return all entries in 'depends' which correspond to packages -- that do not exist in the index. depsNotAvailable :: InstalledPackageIndex- -> PackageConfig+ -> UnitInfo -> [InstalledUnitId] depsNotAvailable pkg_map pkg = filter (not . (`Map.member` pkg_map)) (depends pkg) --- | Given a 'PackageConfig' from some 'InstalledPackageIndex'+-- | Given a 'UnitInfo' from some 'InstalledPackageIndex' -- return all entries in 'abiDepends' which correspond to packages -- that do not exist, OR have mismatching ABIs. depsAbiMismatch :: InstalledPackageIndex- -> PackageConfig+ -> UnitInfo -> [InstalledUnitId] depsAbiMismatch pkg_map pkg = map fst . filter (not . abiMatch) $ abiDepends pkg where@@ -1263,7 +1272,7 @@ -- ----------------------------------------------------------------------------- -- Ignore packages -ignorePackages :: [IgnorePackageFlag] -> [PackageConfig] -> UnusablePackages+ignorePackages :: [IgnorePackageFlag] -> [UnitInfo] -> UnusablePackages ignorePackages flags pkgs = Map.fromList (concatMap doit flags) where doit (IgnorePackage str) =@@ -1290,11 +1299,11 @@ -- packages with the same unit id in later databases override -- earlier ones. This does NOT check if the resulting database -- makes sense (that's done by 'validateDatabase').-mergeDatabases :: DynFlags -> [(FilePath, [PackageConfig])]+mergeDatabases :: DynFlags -> [PackageDatabase] -> IO (InstalledPackageIndex, PackagePrecedenceIndex) mergeDatabases dflags = foldM merge (Map.empty, Map.empty) . zip [1..] where- merge (pkg_map, prec_map) (i, (db_path, db)) = do+ merge (pkg_map, prec_map) (i, PackageDatabase db_path db) = do debugTraceMsg dflags 2 $ text "loading package database" <+> text db_path forM_ (Set.toList override_set) $ \pkg ->@@ -1331,7 +1340,7 @@ -- 4. Remove all packages which have deps with mismatching ABIs -- validateDatabase :: DynFlags -> InstalledPackageIndex- -> (InstalledPackageIndex, UnusablePackages, [SCC PackageConfig])+ -> (InstalledPackageIndex, UnusablePackages, [SCC UnitInfo]) validateDatabase dflags pkg_map1 = (pkg_map5, unusable, sccs) where@@ -1384,7 +1393,7 @@ :: DynFlags -- initial databases, in the order they were specified on -- the command line (later databases shadow earlier ones)- -> [(FilePath, [PackageConfig])]+ -> [PackageDatabase] -> [PreloadUnitId] -- preloaded packages -> IO (PackageState, [PreloadUnitId], -- new packages to preload@@ -1432,7 +1441,7 @@ the purposes of computing the module map. * if any flag refers to a package which was removed by 1-5, then we can give an error message explaining why- * if -hide-all-packages what not specified, this step also+ * if -hide-all-packages was not specified, this step also hides packages which are superseded by later exposed packages * this step is done TWICE if -plugin-package/-hide-all-plugin-packages are used@@ -1444,7 +1453,7 @@ we build a mapping saying what every in scope module name points to. -} - -- This, and the other reverse's that you will see, are due to the face that+ -- This, and the other reverse's that you will see, are due to the fact that -- packageFlags, pluginPackageFlags, etc. are all specified in *reverse* order -- than they are on the command line. let other_flags = reverse (packageFlags dflags)@@ -1465,7 +1474,7 @@ -- or not packages are visible or not) pkgs1 <- foldM (applyTrustFlag dflags prec_map unusable) (Map.elems pkg_map2) (reverse (trustFlags dflags))- let prelim_pkg_db = extendPackageConfigMap emptyPackageConfigMap pkgs1+ let prelim_pkg_db = extendUnitInfoMap emptyUnitInfoMap pkgs1 -- -- Calculate the initial set of units from package databases, prior to any package flags.@@ -1491,7 +1500,7 @@ -- When exposing units, we want to consider all of those in the most preferable -- packages. We can implement that by looking for units that are equi-preferable -- with the most preferable unit for package. Being equi-preferable means that- -- they must be in the same database, with the same version, and the same pacakge name.+ -- they must be in the same database, with the same version, and the same package name. -- -- We must take care to consider all these units and not just the most -- preferable one, otherwise we can end up with problems like #16228.@@ -1531,7 +1540,7 @@ -- package arguments we need to key against the old versions. -- (pkgs2, wired_map) <- findWiredInPackages dflags prec_map pkgs1 vis_map2- let pkg_db = extendPackageConfigMap emptyPackageConfigMap pkgs2+ let pkg_db = extendUnitInfoMap emptyUnitInfoMap pkgs2 -- Update the visibility map, so we treat wired packages as visible. let vis_map = updateVisibilityMap wired_map vis_map2@@ -1595,7 +1604,7 @@ -- add base & rts to the preload packages basicLinkedPackages | gopt Opt_AutoLinkPackages dflags- = filter (flip elemUDFM (unPackageConfigMap pkg_db))+ = filter (flip elemUDFM (unUnitInfoMap pkg_db)) [baseUnitId, rtsUnitId] | otherwise = [] -- but in any case remove the current package from the set of@@ -1611,8 +1620,8 @@ dep_preload <- closeDeps dflags pkg_db (zip (map toInstalledUnitId preload3) (repeat Nothing)) let new_dep_preload = filter (`notElem` preload0) dep_preload - let mod_map1 = mkModuleToPkgConfAll dflags pkg_db vis_map- mod_map2 = mkUnusableModuleToPkgConfAll unusable+ let mod_map1 = mkModuleNameProvidersMap dflags pkg_db vis_map+ mod_map2 = mkUnusableModuleNameProvidersMap unusable mod_map = Map.union mod_map1 mod_map2 dumpIfSet_dyn (dflags { pprCols = 200 }) Opt_D_dump_mod_map "Mod Map"@@ -1623,9 +1632,9 @@ let !pstate = PackageState{ preloadPackages = dep_preload, explicitPackages = explicit_pkgs,- pkgIdMap = pkg_db,- moduleToPkgConfAll = mod_map,- pluginModuleToPkgConfAll = mkModuleToPkgConfAll dflags pkg_db plugin_vis_map,+ unitInfoMap = pkg_db,+ moduleNameProvidersMap = mod_map,+ pluginModuleNameProvidersMap = mkModuleNameProvidersMap dflags pkg_db plugin_vis_map, packageNameMap = pkgname_map, unwireMap = Map.fromList [ (v,k) | (k,v) <- Map.toList wired_map ], requirementContext = req_ctx@@ -1647,12 +1656,12 @@ -- in the installed package database, which makes handling indefinite -- packages a bit bothersome. -mkModuleToPkgConfAll+mkModuleNameProvidersMap :: DynFlags- -> PackageConfigMap+ -> UnitInfoMap -> VisibilityMap- -> ModuleToPkgConfAll-mkModuleToPkgConfAll dflags pkg_db vis_map =+ -> ModuleNameProvidersMap+mkModuleNameProvidersMap dflags pkg_db vis_map = -- What should we fold on? Both situations are awkward: -- -- * Folding on the visibility map means that we won't create@@ -1662,7 +1671,7 @@ -- * Folding on pkg_db is awkward because if we have an -- Backpack instantiation, we need to possibly add a -- package from pkg_db multiple times to the actual- -- ModuleToPkgConfAll. Also, we don't really want+ -- ModuleNameProvidersMap. Also, we don't really want -- definite package instantiations to show up in the -- list of possibilities. --@@ -1676,7 +1685,7 @@ default_vis = Map.fromList [ (packageConfigId pkg, mempty)- | pkg <- eltsUDFM (unPackageConfigMap pkg_db)+ | pkg <- eltsUDFM (unUnitInfoMap pkg_db) -- Exclude specific instantiations of an indefinite -- package , indefinite pkg || null (instantiatedWith pkg)@@ -1688,7 +1697,7 @@ UnitVisibility { uv_expose_all = b, uv_renamings = rns } = addListTo modmap theBindings where- pkg = pkg_lookup uid+ pkg = unit_lookup uid theBindings :: [(ModuleName, Map Module ModuleOrigin)] theBindings = newBindings b rns@@ -1714,7 +1723,7 @@ case exposedReexport of Nothing -> (pk, m, fromExposedModules e) Just (Module pk' m') ->- let pkg' = pkg_lookup pk'+ let pkg' = unit_lookup pk' in (pk', m', fromReexportedModules e pkg') return (m, mkModMap pk' m' origin') @@ -1725,15 +1734,15 @@ hiddens = [(m, mkModMap pk m ModHidden) | m <- hidden_mods] pk = packageConfigId pkg- pkg_lookup uid = lookupPackage' (isIndefinite dflags) pkg_db uid- `orElse` pprPanic "pkg_lookup" (ppr uid)+ unit_lookup uid = lookupUnit' (isIndefinite dflags) pkg_db uid+ `orElse` pprPanic "unit_lookup" (ppr uid) exposed_mods = exposedModules pkg hidden_mods = hiddenModules pkg --- | Make a 'ModuleToPkgConfAll' covering a set of unusable packages.-mkUnusableModuleToPkgConfAll :: UnusablePackages -> ModuleToPkgConfAll-mkUnusableModuleToPkgConfAll unusables =+-- | Make a 'ModuleNameProvidersMap' covering a set of unusable packages.+mkUnusableModuleNameProvidersMap :: UnusablePackages -> ModuleNameProvidersMap+mkUnusableModuleNameProvidersMap unusables = Map.foldl' extend_modmap Map.empty unusables where extend_modmap modmap (pkg, reason) = addListTo modmap bindings@@ -1784,7 +1793,7 @@ getPackageIncludePath dflags pkgs = collectIncludeDirs `fmap` getPreloadPackagesAnd dflags pkgs -collectIncludeDirs :: [PackageConfig] -> [FilePath]+collectIncludeDirs :: [UnitInfo] -> [FilePath] collectIncludeDirs ps = ordNub (filter notNull (concatMap includeDirs ps)) -- | Find all the library paths in these and the preload packages@@ -1792,7 +1801,7 @@ getPackageLibraryPath dflags pkgs = collectLibraryPaths dflags `fmap` getPreloadPackagesAnd dflags pkgs -collectLibraryPaths :: DynFlags -> [PackageConfig] -> [FilePath]+collectLibraryPaths :: DynFlags -> [UnitInfo] -> [FilePath] collectLibraryPaths dflags = ordNub . filter notNull . concatMap (libraryDirsForWay dflags) @@ -1802,14 +1811,14 @@ getPackageLinkOpts dflags pkgs = collectLinkOpts dflags `fmap` getPreloadPackagesAnd dflags pkgs -collectLinkOpts :: DynFlags -> [PackageConfig] -> ([String], [String], [String])+collectLinkOpts :: DynFlags -> [UnitInfo] -> ([String], [String], [String]) collectLinkOpts dflags ps = ( concatMap (map ("-l" ++) . packageHsLibs dflags) ps, concatMap (map ("-l" ++) . extraLibraries) ps, concatMap ldOptions ps )-collectArchives :: DynFlags -> PackageConfig -> IO [FilePath]+collectArchives :: DynFlags -> UnitInfo -> IO [FilePath] collectArchives dflags pc = filterM doesFileExist [ searchPath </> ("lib" ++ lib ++ ".a") | searchPath <- searchPaths@@ -1825,7 +1834,7 @@ , f <- (\n -> "lib" ++ n ++ ".a") <$> packageHsLibs dflags p ] filterM (doesFileExist . fst) candidates -packageHsLibs :: DynFlags -> PackageConfig -> [String]+packageHsLibs :: DynFlags -> UnitInfo -> [String] packageHsLibs dflags p = map (mkDynName . addSuffix) (hsLibraries p) where ways0 = ways dflags@@ -1874,7 +1883,7 @@ | otherwise = '_':t -- | Either the 'libraryDirs' or 'libraryDynDirs' as appropriate for the way.-libraryDirsForWay :: DynFlags -> PackageConfig -> [String]+libraryDirsForWay :: DynFlags -> UnitInfo -> [String] libraryDirsForWay dflags | WayDyn `elem` ways dflags = libraryDynDirs | otherwise = libraryDirs@@ -1904,19 +1913,19 @@ -- list of modules which take that name. lookupModuleInAllPackages :: DynFlags -> ModuleName- -> [(Module, PackageConfig)]+ -> [(Module, UnitInfo)] lookupModuleInAllPackages dflags m = case lookupModuleWithSuggestions dflags m Nothing of LookupFound a b -> [(a,b)] LookupMultiple rs -> map f rs- where f (m,_) = (m, expectJust "lookupModule" (lookupPackage dflags+ where f (m,_) = (m, expectJust "lookupModule" (lookupUnit dflags (moduleUnitId m))) _ -> [] -- | The result of performing a lookup data LookupResult = -- | Found the module uniquely, nothing else to do- LookupFound Module PackageConfig+ LookupFound Module UnitInfo -- | Multiple modules with the same name in scope | LookupMultiple [(Module, ModuleOrigin)] -- | No modules found, but there were some hidden ones with@@ -1938,7 +1947,7 @@ -> LookupResult lookupModuleWithSuggestions dflags = lookupModuleWithSuggestions' dflags- (moduleToPkgConfAll (pkgState dflags))+ (moduleNameProvidersMap (pkgState dflags)) lookupPluginModuleWithSuggestions :: DynFlags -> ModuleName@@ -1946,10 +1955,10 @@ -> LookupResult lookupPluginModuleWithSuggestions dflags = lookupModuleWithSuggestions' dflags- (pluginModuleToPkgConfAll (pkgState dflags))+ (pluginModuleNameProvidersMap (pkgState dflags)) lookupModuleWithSuggestions' :: DynFlags- -> ModuleToPkgConfAll+ -> ModuleNameProvidersMap -> ModuleName -> Maybe FastString -> LookupResult@@ -1959,14 +1968,14 @@ Just xs -> case foldl' classify ([],[],[], []) (Map.toList xs) of ([], [], [], []) -> LookupNotFound suggestions- (_, _, _, [(m, _)]) -> LookupFound m (mod_pkg m)+ (_, _, _, [(m, _)]) -> LookupFound m (mod_unit m) (_, _, _, exposed@(_:_)) -> LookupMultiple exposed ([], [], unusable@(_:_), []) -> LookupUnusable unusable (hidden_pkg, hidden_mod, _, []) -> LookupHidden hidden_pkg hidden_mod where classify (hidden_pkg, hidden_mod, unusable, exposed) (m, origin0) =- let origin = filterOrigin mb_pn (mod_pkg m) origin0+ let origin = filterOrigin mb_pn (mod_unit m) origin0 x = (m, origin) in case origin of ModHidden@@ -1980,14 +1989,14 @@ | otherwise -> (x:hidden_pkg, hidden_mod, unusable, exposed) - pkg_lookup p = lookupPackage dflags p `orElse` pprPanic "lookupModuleWithSuggestions" (ppr p <+> ppr m)- mod_pkg = pkg_lookup . moduleUnitId+ unit_lookup p = lookupUnit dflags p `orElse` pprPanic "lookupModuleWithSuggestions" (ppr p <+> ppr m)+ mod_unit = unit_lookup . moduleUnitId -- Filters out origins which are not associated with the given package -- qualifier. No-op if there is no package qualifier. Test if this -- excluded all origins with 'originEmpty'. filterOrigin :: Maybe FastString- -> PackageConfig+ -> UnitInfo -> ModuleOrigin -> ModuleOrigin filterOrigin Nothing _ o = o@@ -2013,7 +2022,7 @@ all_mods :: [(String, ModuleSuggestion)] -- All modules all_mods = sortBy (comparing fst) $ [ (moduleNameString m, suggestion)- | (m, e) <- Map.toList (moduleToPkgConfAll (pkgState dflags))+ | (m, e) <- Map.toList (moduleNameProvidersMap (pkgState dflags)) , suggestion <- map (getSuggestion m) (Map.toList e) ] getSuggestion name (mod, origin) =@@ -2022,12 +2031,12 @@ listVisibleModuleNames :: DynFlags -> [ModuleName] listVisibleModuleNames dflags =- map fst (filter visible (Map.toList (moduleToPkgConfAll (pkgState dflags))))+ map fst (filter visible (Map.toList (moduleNameProvidersMap (pkgState dflags)))) where visible (_, ms) = any originVisible (Map.elems ms) --- | Find all the 'PackageConfig' in both the preload packages from 'DynFlags' and corresponding to the list of--- 'PackageConfig's-getPreloadPackagesAnd :: DynFlags -> [PreloadUnitId] -> IO [PackageConfig]+-- | Find all the 'UnitInfo' in both the preload packages from 'DynFlags' and corresponding to the list of+-- 'UnitInfo's+getPreloadPackagesAnd :: DynFlags -> [PreloadUnitId] -> IO [UnitInfo] getPreloadPackagesAnd dflags pkgids0 = let pkgids = pkgids0 ++@@ -2039,7 +2048,7 @@ else map (toInstalledUnitId . moduleUnitId . snd) (thisUnitIdInsts dflags) state = pkgState dflags- pkg_map = pkgIdMap state+ pkg_map = unitInfoMap state preload = preloadPackages state pairs = zip pkgids (repeat Nothing) in do@@ -2049,7 +2058,7 @@ -- Takes a list of packages, and returns the list with dependencies included, -- in reverse dependency order (a package appears before those it depends on). closeDeps :: DynFlags- -> PackageConfigMap+ -> UnitInfoMap -> [(InstalledUnitId, Maybe InstalledUnitId)] -> IO [InstalledUnitId] closeDeps dflags pkg_map ps@@ -2062,14 +2071,14 @@ Succeeded r -> return r closeDepsErr :: DynFlags- -> PackageConfigMap+ -> UnitInfoMap -> [(InstalledUnitId,Maybe InstalledUnitId)] -> MaybeErr MsgDoc [InstalledUnitId] closeDepsErr dflags pkg_map ps = foldM (add_package dflags pkg_map) [] ps -- internal helper add_package :: DynFlags- -> PackageConfigMap+ -> UnitInfoMap -> [PreloadUnitId] -> (PreloadUnitId,Maybe PreloadUnitId) -> MaybeErr MsgDoc [PreloadUnitId]@@ -2153,11 +2162,11 @@ -- | Show (very verbose) package info pprPackages :: DynFlags -> SDoc-pprPackages = pprPackagesWith pprPackageConfig+pprPackages = pprPackagesWith pprUnitInfo -pprPackagesWith :: (PackageConfig -> SDoc) -> DynFlags -> SDoc+pprPackagesWith :: (UnitInfo -> SDoc) -> DynFlags -> SDoc pprPackagesWith pprIPI dflags =- vcat (intersperse (text "---") (map pprIPI (listPackageConfigMap dflags)))+ vcat (intersperse (text "---") (map pprIPI (listUnitInfoMap dflags))) -- | Show simplified package info. --@@ -2171,7 +2180,7 @@ in e <> t <> text " " <> ftext i -- | Show the mapping of modules to where they come from.-pprModuleMap :: ModuleToPkgConfAll -> SDoc+pprModuleMap :: ModuleNameProvidersMap -> SDoc pprModuleMap mod_map = vcat (map pprLine (Map.toList mod_map)) where@@ -2181,161 +2190,26 @@ | m == moduleName m' = ppr (moduleUnitId m') <+> parens (ppr o) | otherwise = ppr m' <+> parens (ppr o) -fsPackageName :: PackageConfig -> FastString+fsPackageName :: UnitInfo -> FastString fsPackageName = mkFastString . packageNameString -- | Given a fully instantiated 'UnitId', improve it into a -- 'InstalledUnitId' if we can find it in the package database.-improveUnitId :: PackageConfigMap -> UnitId -> UnitId+improveUnitId :: UnitInfoMap -> UnitId -> UnitId improveUnitId _ uid@(DefiniteUnitId _) = uid -- short circuit improveUnitId pkg_map uid = -- Do NOT lookup indefinite ones, they won't be useful!- case lookupPackage' False pkg_map uid of+ case lookupUnit' False pkg_map uid of Nothing -> uid Just pkg -> -- Do NOT improve if the indefinite unit id is not -- part of the closure unique set. See -- Note [UnitId to InstalledUnitId improvement]- if installedPackageConfigId pkg `elementOfUniqSet` preloadClosure pkg_map+ if installedUnitInfoId pkg `elementOfUniqSet` preloadClosure pkg_map then packageConfigId pkg else uid --- | Retrieve the 'PackageConfigMap' from 'DynFlags'; used+-- | Retrieve the 'UnitInfoMap' from 'DynFlags'; used -- in the @hs-boot@ loop-breaker.-getPackageConfigMap :: DynFlags -> PackageConfigMap-getPackageConfigMap = pkgIdMap . pkgState---- -------------------------------------------------------------------------------- | Find the package environment (if one exists)------ We interpret the package environment as a set of package flags; to be--- specific, if we find a package environment file like------ > clear-package-db--- > global-package-db--- > package-db blah/package.conf.d--- > package-id id1--- > package-id id2------ we interpret this as------ > [ -hide-all-packages--- > , -clear-package-db--- > , -global-package-db--- > , -package-db blah/package.conf.d--- > , -package-id id1--- > , -package-id id2--- > ]------ There's also an older syntax alias for package-id, which is just an--- unadorned package id------ > id1--- > id2----interpretPackageEnv :: DynFlags -> IO DynFlags-interpretPackageEnv dflags = do- mPkgEnv <- runMaybeT $ msum $ [- getCmdLineArg >>= \env -> msum [- probeNullEnv env- , probeEnvFile env- , probeEnvName env- , cmdLineError env- ]- , getEnvVar >>= \env -> msum [- probeNullEnv env- , probeEnvFile env- , probeEnvName env- , envError env- ]- , notIfHideAllPackages >> msum [- findLocalEnvFile >>= probeEnvFile- , probeEnvName defaultEnvName- ]- ]- case mPkgEnv of- Nothing ->- -- No environment found. Leave DynFlags unchanged.- return dflags- Just "-" -> do- -- Explicitly disabled environment file. Leave DynFlags unchanged.- return dflags- Just envfile -> do- content <- readFile envfile- compilationProgressMsg dflags ("Loaded package environment from " ++ envfile)- let (_, dflags') = runCmdLine (runEwM (setFlagsFromEnvFile envfile content)) dflags-- return dflags'- where- -- Loading environments (by name or by location)-- namedEnvPath :: String -> MaybeT IO FilePath- namedEnvPath name = do- appdir <- versionedAppDir dflags- return $ appdir </> "environments" </> name-- probeEnvName :: String -> MaybeT IO FilePath- probeEnvName name = probeEnvFile =<< namedEnvPath name-- probeEnvFile :: FilePath -> MaybeT IO FilePath- probeEnvFile path = do- guard =<< liftMaybeT (doesFileExist path)- return path-- probeNullEnv :: FilePath -> MaybeT IO FilePath- probeNullEnv "-" = return "-"- probeNullEnv _ = mzero-- -- Various ways to define which environment to use-- getCmdLineArg :: MaybeT IO String- getCmdLineArg = MaybeT $ return $ packageEnv dflags-- getEnvVar :: MaybeT IO String- getEnvVar = do- mvar <- liftMaybeT $ try $ getEnv "GHC_ENVIRONMENT"- case mvar of- Right var -> return var- Left err -> if isDoesNotExistError err then mzero- else liftMaybeT $ throwIO err-- notIfHideAllPackages :: MaybeT IO ()- notIfHideAllPackages =- guard (not (gopt Opt_HideAllPackages dflags))-- defaultEnvName :: String- defaultEnvName = "default"-- -- e.g. .ghc.environment.x86_64-linux-7.6.3- localEnvFileName :: FilePath- localEnvFileName = ".ghc.environment" <.> versionedFilePath dflags-- -- Search for an env file, starting in the current dir and looking upwards.- -- Fail if we get to the users home dir or the filesystem root. That is,- -- we don't look for an env file in the user's home dir. The user-wide- -- env lives in ghc's versionedAppDir/environments/default- findLocalEnvFile :: MaybeT IO FilePath- findLocalEnvFile = do- curdir <- liftMaybeT getCurrentDirectory- homedir <- tryMaybeT getHomeDirectory- let probe dir | isDrive dir || dir == homedir- = mzero- probe dir = do- let file = dir </> localEnvFileName- exists <- liftMaybeT (doesFileExist file)- if exists- then return file- else probe (takeDirectory dir)- probe curdir-- -- Error reporting-- cmdLineError :: String -> MaybeT IO a- cmdLineError env = liftMaybeT . throwGhcExceptionIO . CmdLineError $- "Package environment " ++ show env ++ " not found"-- envError :: String -> MaybeT IO a- envError env = liftMaybeT . throwGhcExceptionIO . CmdLineError $- "Package environment "- ++ show env- ++ " (specified in GHC_ENVIRONMENT) not found"+getUnitInfoMap :: DynFlags -> UnitInfoMap+getUnitInfoMap = unitInfoMap . pkgState
compiler/main/Packages.hs-boot view
@@ -3,9 +3,10 @@ import {-# SOURCE #-} DynFlags(DynFlags) import {-# SOURCE #-} Module(ComponentId, UnitId, InstalledUnitId) data PackageState-data PackageConfigMap+data UnitInfoMap+data PackageDatabase emptyPackageState :: PackageState componentIdString :: DynFlags -> ComponentId -> Maybe String displayInstalledUnitId :: DynFlags -> InstalledUnitId -> Maybe String-improveUnitId :: PackageConfigMap -> UnitId -> UnitId-getPackageConfigMap :: DynFlags -> PackageConfigMap+improveUnitId :: UnitInfoMap -> UnitId -> UnitId+getUnitInfoMap :: DynFlags -> UnitInfoMap
compiler/main/Plugins.hs view
@@ -119,7 +119,7 @@ , interfaceLoadAction :: forall lcl . [CommandLineOption] -> ModIface -> IfM lcl ModIface -- ^ Modify an interface that have been loaded. This is called by- -- LoadIface when an interface is successfully loaded. Not applied to+ -- GHC.Iface.Load when an interface is successfully loaded. Not applied to -- the loading of the plugin interface. Tools that rely on information from -- modules other than the currently compiled one should implement this -- function.@@ -201,7 +201,7 @@ -- | Default plugin: does nothing at all, except for marking that safe -- inference has failed unless @-fplugin-trustworthy@ is passed. For--- compatibility reaso you should base all your plugin definitions on this+-- compatibility reason you should base all your plugin definitions on this -- default value. defaultPlugin :: Plugin defaultPlugin = Plugin {
compiler/main/Settings.hs view
@@ -7,7 +7,7 @@ , sToolDir , sTopDir , sTmpDir- , sSystemPackageConfig+ , sGlobalPackageDatabasePath , sLdSupportsCompactUnwind , sLdSupportsBuildId , sLdSupportsFilelist@@ -99,8 +99,8 @@ sTopDir = fileSettings_topDir . sFileSettings sTmpDir :: Settings -> String sTmpDir = fileSettings_tmpDir . sFileSettings-sSystemPackageConfig :: Settings -> FilePath-sSystemPackageConfig = fileSettings_systemPackageConfig . sFileSettings+sGlobalPackageDatabasePath :: Settings -> FilePath+sGlobalPackageDatabasePath = fileSettings_globalPackageDatabase . sFileSettings sLdSupportsCompactUnwind :: Settings -> Bool sLdSupportsCompactUnwind = toolSettings_ldSupportsCompactUnwind . sToolSettings
+ compiler/main/UnitInfo.hs view
@@ -0,0 +1,154 @@+{-# LANGUAGE CPP, RecordWildCards, FlexibleInstances, MultiParamTypeClasses #-}++-- |+-- Package configuration information: essentially the interface to Cabal, with+-- some utilities+--+-- (c) The University of Glasgow, 2004+--+module UnitInfo (+ -- $package_naming++ -- * UnitId+ packageConfigId,+ expandedUnitInfoId,+ definiteUnitInfoId,+ installedUnitInfoId,++ -- * The UnitInfo type: information about a unit+ UnitInfo,+ InstalledPackageInfo(..),+ ComponentId(..),+ SourcePackageId(..),+ PackageName(..),+ Version(..),+ defaultUnitInfo,+ sourcePackageIdString,+ packageNameString,+ pprUnitInfo,+ ) where++#include "HsVersions.h"++import GhcPrelude++import GHC.PackageDb+import Data.Version++import FastString+import Outputable+import Module+import Unique++-- -----------------------------------------------------------------------------+-- Our UnitInfo type is the InstalledPackageInfo from ghc-boot,+-- which is similar to a subset of the InstalledPackageInfo type from Cabal.++type UnitInfo = InstalledPackageInfo+ ComponentId+ SourcePackageId+ PackageName+ Module.InstalledUnitId+ Module.UnitId+ Module.ModuleName+ Module.Module++-- TODO: there's no need for these to be FastString, as we don't need the uniq+-- feature, but ghc doesn't currently have convenient support for any+-- other compact string types, e.g. plain ByteString or Text.++newtype SourcePackageId = SourcePackageId FastString deriving (Eq, Ord)+newtype PackageName = PackageName FastString deriving (Eq, Ord)++instance BinaryStringRep SourcePackageId where+ fromStringRep = SourcePackageId . mkFastStringByteString+ toStringRep (SourcePackageId s) = bytesFS s++instance BinaryStringRep PackageName where+ fromStringRep = PackageName . mkFastStringByteString+ toStringRep (PackageName s) = bytesFS s++instance Uniquable SourcePackageId where+ getUnique (SourcePackageId n) = getUnique n++instance Uniquable PackageName where+ getUnique (PackageName n) = getUnique n++instance Outputable SourcePackageId where+ ppr (SourcePackageId str) = ftext str++instance Outputable PackageName where+ ppr (PackageName str) = ftext str++defaultUnitInfo :: UnitInfo+defaultUnitInfo = emptyInstalledPackageInfo++sourcePackageIdString :: UnitInfo -> String+sourcePackageIdString pkg = unpackFS str+ where+ SourcePackageId str = sourcePackageId pkg++packageNameString :: UnitInfo -> String+packageNameString pkg = unpackFS str+ where+ PackageName str = packageName pkg++pprUnitInfo :: UnitInfo -> SDoc+pprUnitInfo InstalledPackageInfo {..} =+ vcat [+ field "name" (ppr packageName),+ field "version" (text (showVersion packageVersion)),+ field "id" (ppr unitId),+ field "exposed" (ppr exposed),+ field "exposed-modules" (ppr exposedModules),+ field "hidden-modules" (fsep (map ppr hiddenModules)),+ field "trusted" (ppr trusted),+ field "import-dirs" (fsep (map text importDirs)),+ field "library-dirs" (fsep (map text libraryDirs)),+ field "dynamic-library-dirs" (fsep (map text libraryDynDirs)),+ field "hs-libraries" (fsep (map text hsLibraries)),+ field "extra-libraries" (fsep (map text extraLibraries)),+ field "extra-ghci-libraries" (fsep (map text extraGHCiLibraries)),+ field "include-dirs" (fsep (map text includeDirs)),+ field "includes" (fsep (map text includes)),+ field "depends" (fsep (map ppr depends)),+ field "cc-options" (fsep (map text ccOptions)),+ field "ld-options" (fsep (map text ldOptions)),+ field "framework-dirs" (fsep (map text frameworkDirs)),+ field "frameworks" (fsep (map text frameworks)),+ field "haddock-interfaces" (fsep (map text haddockInterfaces)),+ field "haddock-html" (fsep (map text haddockHTMLs))+ ]+ where+ field name body = text name <> colon <+> nest 4 body++-- -----------------------------------------------------------------------------+-- UnitId (package names, versions and dep hash)++-- $package_naming+-- #package_naming#+-- Mostly the compiler deals in terms of 'UnitId's, which are md5 hashes+-- of a package ID, keys of its dependencies, and Cabal flags. You're expected+-- to pass in the unit id in the @-this-unit-id@ flag. However, for+-- wired-in packages like @base@ & @rts@, we don't necessarily know what the+-- version is, so these are handled specially; see #wired_in_packages#.++-- | Get the GHC 'UnitId' right out of a Cabalish 'UnitInfo'+installedUnitInfoId :: UnitInfo -> InstalledUnitId+installedUnitInfoId = unitId++packageConfigId :: UnitInfo -> UnitId+packageConfigId p =+ if indefinite p+ then newUnitId (componentId p) (instantiatedWith p)+ else DefiniteUnitId (DefUnitId (unitId p))++expandedUnitInfoId :: UnitInfo -> UnitId+expandedUnitInfoId p =+ newUnitId (componentId p) (instantiatedWith p)++definiteUnitInfoId :: UnitInfo -> Maybe DefUnitId+definiteUnitInfoId p =+ case packageConfigId p of+ DefiniteUnitId def_uid -> Just def_uid+ _ -> Nothing
+ compiler/nativeGen/Reg.hs view
@@ -0,0 +1,241 @@+-- | An architecture independent description of a register.+-- This needs to stay architecture independent because it is used+-- by NCGMonad and the register allocators, which are shared+-- by all architectures.+--+module Reg (+ RegNo,+ Reg(..),+ regPair,+ regSingle,+ isRealReg, takeRealReg,+ isVirtualReg, takeVirtualReg,++ VirtualReg(..),+ renameVirtualReg,+ classOfVirtualReg,+ getHiVirtualRegFromLo,+ getHiVRegFromLo,++ RealReg(..),+ regNosOfRealReg,+ realRegsAlias,++ liftPatchFnToRegReg+)++where++import GhcPrelude++import Outputable+import Unique+import RegClass+import Data.List++-- | An identifier for a primitive real machine register.+type RegNo+ = Int++-- VirtualRegs are virtual registers. The register allocator will+-- eventually have to map them into RealRegs, or into spill slots.+--+-- VirtualRegs are allocated on the fly, usually to represent a single+-- value in the abstract assembly code (i.e. dynamic registers are+-- usually single assignment).+--+-- The single assignment restriction isn't necessary to get correct code,+-- although a better register allocation will result if single+-- assignment is used -- because the allocator maps a VirtualReg into+-- a single RealReg, even if the VirtualReg has multiple live ranges.+--+-- Virtual regs can be of either class, so that info is attached.+--+data VirtualReg+ = VirtualRegI {-# UNPACK #-} !Unique+ | VirtualRegHi {-# UNPACK #-} !Unique -- High part of 2-word register+ | VirtualRegF {-# UNPACK #-} !Unique+ | VirtualRegD {-# UNPACK #-} !Unique++ deriving (Eq, Show)++-- This is laborious, but necessary. We can't derive Ord because+-- Unique doesn't have an Ord instance. Note nonDetCmpUnique in the+-- implementation. See Note [No Ord for Unique]+-- This is non-deterministic but we do not currently support deterministic+-- code-generation. See Note [Unique Determinism and code generation]+instance Ord VirtualReg where+ compare (VirtualRegI a) (VirtualRegI b) = nonDetCmpUnique a b+ compare (VirtualRegHi a) (VirtualRegHi b) = nonDetCmpUnique a b+ compare (VirtualRegF a) (VirtualRegF b) = nonDetCmpUnique a b+ compare (VirtualRegD a) (VirtualRegD b) = nonDetCmpUnique a b++ compare VirtualRegI{} _ = LT+ compare _ VirtualRegI{} = GT+ compare VirtualRegHi{} _ = LT+ compare _ VirtualRegHi{} = GT+ compare VirtualRegF{} _ = LT+ compare _ VirtualRegF{} = GT++++instance Uniquable VirtualReg where+ getUnique reg+ = case reg of+ VirtualRegI u -> u+ VirtualRegHi u -> u+ VirtualRegF u -> u+ VirtualRegD u -> u++instance Outputable VirtualReg where+ ppr reg+ = case reg of+ VirtualRegI u -> text "%vI_" <> pprUniqueAlways u+ VirtualRegHi u -> text "%vHi_" <> pprUniqueAlways u+ -- this code is kinda wrong on x86+ -- because float and double occupy the same register set+ -- namely SSE2 register xmm0 .. xmm15+ VirtualRegF u -> text "%vFloat_" <> pprUniqueAlways u+ VirtualRegD u -> text "%vDouble_" <> pprUniqueAlways u++++renameVirtualReg :: Unique -> VirtualReg -> VirtualReg+renameVirtualReg u r+ = case r of+ VirtualRegI _ -> VirtualRegI u+ VirtualRegHi _ -> VirtualRegHi u+ VirtualRegF _ -> VirtualRegF u+ VirtualRegD _ -> VirtualRegD u+++classOfVirtualReg :: VirtualReg -> RegClass+classOfVirtualReg vr+ = case vr of+ VirtualRegI{} -> RcInteger+ VirtualRegHi{} -> RcInteger+ VirtualRegF{} -> RcFloat+ VirtualRegD{} -> RcDouble++++-- Determine the upper-half vreg for a 64-bit quantity on a 32-bit platform+-- when supplied with the vreg for the lower-half of the quantity.+-- (NB. Not reversible).+getHiVirtualRegFromLo :: VirtualReg -> VirtualReg+getHiVirtualRegFromLo reg+ = case reg of+ -- makes a pseudo-unique with tag 'H'+ VirtualRegI u -> VirtualRegHi (newTagUnique u 'H')+ _ -> panic "Reg.getHiVirtualRegFromLo"++getHiVRegFromLo :: Reg -> Reg+getHiVRegFromLo reg+ = case reg of+ RegVirtual vr -> RegVirtual (getHiVirtualRegFromLo vr)+ RegReal _ -> panic "Reg.getHiVRegFromLo"+++------------------------------------------------------------------------------------+-- | RealRegs are machine regs which are available for allocation, in+-- the usual way. We know what class they are, because that's part of+-- the processor's architecture.+--+-- RealRegPairs are pairs of real registers that are allocated together+-- to hold a larger value, such as with Double regs on SPARC.+--+data RealReg+ = RealRegSingle {-# UNPACK #-} !RegNo+ | RealRegPair {-# UNPACK #-} !RegNo {-# UNPACK #-} !RegNo+ deriving (Eq, Show, Ord)++instance Uniquable RealReg where+ getUnique reg+ = case reg of+ RealRegSingle i -> mkRegSingleUnique i+ RealRegPair r1 r2 -> mkRegPairUnique (r1 * 65536 + r2)++instance Outputable RealReg where+ ppr reg+ = case reg of+ RealRegSingle i -> text "%r" <> int i+ RealRegPair r1 r2 -> text "%r(" <> int r1+ <> vbar <> int r2 <> text ")"++regNosOfRealReg :: RealReg -> [RegNo]+regNosOfRealReg rr+ = case rr of+ RealRegSingle r1 -> [r1]+ RealRegPair r1 r2 -> [r1, r2]+++realRegsAlias :: RealReg -> RealReg -> Bool+realRegsAlias rr1 rr2+ = not $ null $ intersect (regNosOfRealReg rr1) (regNosOfRealReg rr2)++--------------------------------------------------------------------------------+-- | A register, either virtual or real+data Reg+ = RegVirtual !VirtualReg+ | RegReal !RealReg+ deriving (Eq, Ord)++regSingle :: RegNo -> Reg+regSingle regNo = RegReal $ RealRegSingle regNo++regPair :: RegNo -> RegNo -> Reg+regPair regNo1 regNo2 = RegReal $ RealRegPair regNo1 regNo2+++-- We like to have Uniques for Reg so that we can make UniqFM and UniqSets+-- in the register allocator.+instance Uniquable Reg where+ getUnique reg+ = case reg of+ RegVirtual vr -> getUnique vr+ RegReal rr -> getUnique rr++-- | Print a reg in a generic manner+-- If you want the architecture specific names, then use the pprReg+-- function from the appropriate Ppr module.+instance Outputable Reg where+ ppr reg+ = case reg of+ RegVirtual vr -> ppr vr+ RegReal rr -> ppr rr+++isRealReg :: Reg -> Bool+isRealReg reg+ = case reg of+ RegReal _ -> True+ RegVirtual _ -> False++takeRealReg :: Reg -> Maybe RealReg+takeRealReg reg+ = case reg of+ RegReal rr -> Just rr+ _ -> Nothing+++isVirtualReg :: Reg -> Bool+isVirtualReg reg+ = case reg of+ RegReal _ -> False+ RegVirtual _ -> True++takeVirtualReg :: Reg -> Maybe VirtualReg+takeVirtualReg reg+ = case reg of+ RegReal _ -> Nothing+ RegVirtual vr -> Just vr+++-- | The patch function supplied by the allocator maps VirtualReg to RealReg+-- regs, but sometimes we want to apply it to plain old Reg.+--+liftPatchFnToRegReg :: (VirtualReg -> RealReg) -> (Reg -> Reg)+liftPatchFnToRegReg patchF reg+ = case reg of+ RegVirtual vr -> RegReal (patchF vr)+ RegReal _ -> reg
+ compiler/nativeGen/RegClass.hs view
@@ -0,0 +1,32 @@+-- | An architecture independent description of a register's class.+module RegClass+ ( RegClass (..) )++where++import GhcPrelude++import Outputable+import Unique+++-- | The class of a register.+-- Used in the register allocator.+-- We treat all registers in a class as being interchangeable.+--+data RegClass+ = RcInteger+ | RcFloat+ | RcDouble+ deriving Eq+++instance Uniquable RegClass where+ getUnique RcInteger = mkRegClassUnique 0+ getUnique RcFloat = mkRegClassUnique 1+ getUnique RcDouble = mkRegClassUnique 2++instance Outputable RegClass where+ ppr RcInteger = Outputable.text "I"+ ppr RcFloat = Outputable.text "F"+ ppr RcDouble = Outputable.text "D"
compiler/parser/HaddockUtils.hs view
@@ -1,3 +1,4 @@+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module HaddockUtils where
compiler/parser/RdrHsSyn.hs view
@@ -1042,7 +1042,7 @@ importQualifiedPostEnabled <- getBit ImportQualifiedPostBit - -- Error if 'qualified' found in postpostive position and+ -- Error if 'qualified' found in postpositive position and -- 'ImportQualifiedPost' is not in effect. whenJust mPost $ \post -> when (not importQualifiedPostEnabled) $
compiler/prelude/PrelNames.hs view
@@ -64,8 +64,8 @@ 2. The knownKeyNames (which consist of the basicKnownKeyNames from the module, and those names reachable via the wired-in stuff from TysWiredIn) are used to initialise the "OrigNameCache" in- IfaceEnv. This initialization ensures that when the type checker- or renamer (both of which use IfaceEnv) look up an original name+ GHC.Iface.Env. This initialization ensures that when the type checker+ or renamer (both of which use GHC.Iface.Env) look up an original name (i.e. a pair of a Module and an OccName) for a known-key name they get the correct Unique. @@ -95,17 +95,17 @@ looked up in the orig-name cache) b) The known infinite families of names are specially serialised by- BinIface.putName, with that special treatment detected when we read back to- ensure that we get back to the correct uniques. See Note [Symbol table- representation of names] in BinIface and Note [How tuples work] in- TysWiredIn.+ GHC.Iface.Binary.putName, with that special treatment detected when we read+ back to ensure that we get back to the correct uniques. See Note [Symbol+ table representation of names] in GHC.Iface.Binary and Note [How tuples+ work] in TysWiredIn. Most of the infinite families cannot occur in source code, so mechanisms (a) and (b) suffice to ensure that they always have the right Unique. In particular, implicit param TyCon names, constraint tuples and Any TyCons cannot be mentioned by the user. For those things that *can* appear in source programs, - c) IfaceEnv.lookupOrigNameCache uses isBuiltInOcc_maybe to map built-in syntax+ c) GHC.Iface.Env.lookupOrigNameCache uses isBuiltInOcc_maybe to map built-in syntax directly onto the corresponding name, rather than trying to find it in the original-name cache. @@ -143,6 +143,7 @@ -} {-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module PrelNames ( Unique, Uniquable(..), hasKey, -- Re-exported for convenience
compiler/prelude/PrelRules.hs view
@@ -722,7 +722,7 @@ Note the massive shift on line "!!!!". It can't happen, because we've checked that w < 64, but the optimiser didn't spot that. We DO NOT want to constant-fold this! Moreover, if the programmer writes (n `uncheckedShiftL` 9223372036854775807), we-can't constant fold it, but if it gets to the assember we get+can't constant fold it, but if it gets to the assembler we get Error: operand type mismatch for `shl' So the best thing to do is to rewrite the shift with a call to error,@@ -1582,7 +1582,7 @@ | Just (LitNumber LitNumInt x _) <- exprIsLiteral_maybe id_unf arg , x >= 0 , x <= (wordSizeInBits dflags - 1)- -- Make sure x is small enough to yield a decently small iteger+ -- Make sure x is small enough to yield a decently small integer -- Attempting to construct the Integer for -- (bitInteger 9223372036854775807#) -- would be a bad idea (#14959)@@ -2217,7 +2217,7 @@ -1# -> e2 100 -> e3 because there isn't a data constructor with tag -1 or 100. In this case the-out-of-range alterantive is dead code -- we know the range of tags for x.+out-of-range alternative is dead code -- we know the range of tags for x. Hence caseRules returns (AltCon -> Maybe AltCon), with Nothing indicating an alternative that is unreachable.
compiler/prelude/PrimOp.hs view
@@ -30,7 +30,7 @@ import TysPrim import TysWiredIn -import CmmType+import GHC.Cmm.Type import Demand import Id ( Id, mkVanillaGlobalWithInfo ) import IdInfo ( vanillaIdInfo, setCafInfo, CafInfo(NoCafRefs) )@@ -363,7 +363,7 @@ ---------- can_fail ---------------------------- A primop "can_fail" if it can fail with an *unchecked* exception on some elements of its input domain. Main examples:- division (fails on zero demoninator)+ division (fails on zero denominator) array indexing (fails if the index is out of bounds) An "unchecked exception" is one that is an outright error, (not@@ -581,7 +581,7 @@ eta expand unsaturated primop applications very late in the Core pipeline. Not only would this produce unnecessary thunks, but it would also result in nasty inconsistencies in CAFfy-ness determinations (see #16846 and-Note [CAFfyness inconsistencies due to late eta expansion] in TidyPgm).+Note [CAFfyness inconsistencies due to late eta expansion] in GHC.Iface.Tidy). However, it was quite unnecessary for hasNoBinding to claim this; primops in fact *do* have curried definitions which are found in GHC.PrimopWrappers, which
compiler/prelude/TysPrim.hs view
@@ -6,6 +6,7 @@ -} {-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- | This module defines TyCons that can't be expressed in Haskell. -- They are all, therefore, wired-in TyCons. C.f module TysWiredIn@@ -442,7 +443,7 @@ We abbreviate '*' specially: type * = TYPE 'LiftedRep -The 'rr' parameter tells us how the value is represented at runime.+The 'rr' parameter tells us how the value is represented at runtime. Generally speaking, you can't be polymorphic in 'rr'. E.g f :: forall (rr:RuntimeRep) (a:TYPE rr). a -> [a]
compiler/prelude/TysWiredIn.hs view
@@ -7,6 +7,8 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+ -- | This module is about types that can be defined in Haskell, but which -- must be wired into the compiler nonetheless. C.f module TysPrim module TysWiredIn (@@ -680,12 +682,12 @@ pretty-print saturated constraint tuples with round parens; see BasicTypes.tupleParens. -* In quite a lot of places things are restrcted just to+* In quite a lot of places things are restricted just to BoxedTuple/UnboxedTuple, and then we used BasicTypes.Boxity to distinguish E.g. tupleTyCon has a Boxity argument * When looking up an OccName in the original-name cache- (IfaceEnv.lookupOrigNameCache), we spot the tuple OccName to make sure+ (GHC.Iface.Env.lookupOrigNameCache), we spot the tuple OccName to make sure we get the right wired-in name. This guy can't tell the difference between BoxedTuple and ConstraintTuple (same OccName!), so tuples are not serialised into interface files using OccNames at all.@@ -702,7 +704,7 @@ single value after CPR analysis - A boxed one-tuple is used by DsUtils.mkSelectorBinds, when there is just one binder-Basically it keeps everythig uniform.+Basically it keeps everything uniform. However the /naming/ of the type/data constructors for one-tuples is a bit odd:@@ -1340,7 +1342,7 @@ {- Note [Boxing primitive types] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-For a handful of primitive types (Int, Char, Word, Flaot, Double),+For a handful of primitive types (Int, Char, Word, Float, Double), we can readily box and an unboxed version (Int#, Char# etc) using the corresponding data constructor. This is useful in a couple of places, notably let-floating -}
compiler/simplCore/CoreMonad.hs view
@@ -7,6 +7,8 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveFunctor #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+ module CoreMonad ( -- * Configuration of the core-to-core passes CoreToDo(..), runWhen, runMaybe,@@ -415,7 +417,7 @@ pprTickCounts counts = vcat (map pprTickGroup groups) where- groups :: [[(Tick,Int)]] -- Each group shares a comon tag+ groups :: [[(Tick,Int)]] -- Each group shares a common tag -- toList returns common tags adjacent groups = groupBy same_tag (Map.toList counts) same_tag (tick1,_) (tick2,_) = tickToTag tick1 == tickToTag tick2
compiler/simplCore/OccurAnal.hs view
@@ -13,6 +13,8 @@ {-# LANGUAGE CPP, BangPatterns, MultiWayIf, ViewPatterns #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+ module OccurAnal ( occurAnalysePgm, occurAnalyseExpr, occurAnalyseExpr_NoBinderSwap ) where@@ -283,8 +285,8 @@ We avoid infinite inlinings by choosing loop breakers, and ensuring that a loop breaker cuts each loop. -See also Note [Inlining and hs-boot files] in ToIface, which deals-with a closely related source of infinite loops.+See also Note [Inlining and hs-boot files] in GHC.Core.ToIface, which+deals with a closely related source of infinite loops. Fundamentally, we do SCC analysis on a graph. For each recursive group we choose a loop breaker, delete all edges to that node,@@ -523,7 +525,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BUT for *automatically-generated* rules, the programmer can't be responsible for the "programmer error" in Note [Rules for imported-functions]. In paricular, consider specialising a recursive function+functions]. In particular, consider specialising a recursive function defined in another module. If we specialise a recursive function B.g, we get g_spec = .....(B.g Int).....@@ -1300,7 +1302,7 @@ -> VarSet -- Loop-breaker dependencies -> NodeScore nodeScore env old_bndr new_bndr bind_rhs lb_deps- | not (isId old_bndr) -- A type or cercion variable is never a loop breaker+ | not (isId old_bndr) -- A type or coercion variable is never a loop breaker = (100, 0, False) | old_bndr `elemVarSet` lb_deps -- Self-recursive things are great loop breakers@@ -1974,7 +1976,7 @@ Simplify.mkDupableAlt In this example, though, the Simplifier will bring 'a' and 'b' back to-life, beause it binds 'y' to (a,b) (imagine got inlined and+life, because it binds 'y' to (a,b) (imagine got inlined and scrutinised y). -} @@ -2119,7 +2121,7 @@ -- The result binders have one-shot-ness set that they might not have had originally. -- This happens in (build (\c n -> e)). Here the occurrence analyser -- linearity context knows that c,n are one-shot, and it records that fact in- -- the binder. This is useful to guide subsequent float-in/float-out tranformations+ -- the binder. This is useful to guide subsequent float-in/float-out transformations oneShotGroup env@(OccEnv { occ_one_shots = ctxt }) bndrs = go ctxt bndrs []@@ -2210,7 +2212,7 @@ Note [Binder swap] ~~~~~~~~~~~~~~~~~~-The "binder swap" tranformation swaps occurrence of the+The "binder swap" transformation swaps occurrence of the scrutinee of a case for occurrences of the case-binder: (1) case x of b { pi -> ri }@@ -2559,7 +2561,7 @@ This showed up in #15696 we had something like case eq_sel d of co -> ...(typeError @(...co...) "urk")... -Then 'd' was substitued by a dictionary, so the expression+Then 'd' was substituted by a dictionary, so the expression simpified to case (Coercion <blah>) of co -> ...(typeError @(...co...) "urk")...
compiler/specialise/Rules.hs view
@@ -77,7 +77,7 @@ the IdInfo for that Id. See Note [Attach rules to local ids] in DsBinds -* TidyPgm strips off all the rules from local Ids and adds them to+* GHC.Iface.Tidy strips off all the rules from local Ids and adds them to mg_rules, so that the ModGuts has *all* the locally-declared rules. * The HomePackageTable contains a ModDetails for each home package@@ -128,7 +128,7 @@ (b) from the ModGuts, (c) from the CoreMonad, and (d) from its mutable variable- [Of coures this means that we won't see new EPS rules that come in+ [Of course this means that we won't see new EPS rules that come in during a single simplifier iteration, but that probably does not matter.] @@ -317,7 +317,7 @@ {- Note [Where rules are found] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The rules for an Id come from two places:- (a) the ones it is born with, stored inside the Id iself (idCoreRules fn),+ (a) the ones it is born with, stored inside the Id itself (idCoreRules fn), (b) rules added in other modules, stored in the global RuleBase (imp_rules) It's tempting to think that
compiler/typecheck/Constraint.hs view
@@ -7,6 +7,8 @@ {-# LANGUAGE CPP, GeneralizedNewtypeDeriving #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+ module Constraint ( -- QCInst QCInst(..), isPendingScInst,@@ -265,7 +267,7 @@ Example 2: a ~ b, where a :: *, b :: k, where k is a kind variable We don't want to use this to substitute 'b' for 'a', in case- 'k' is subsequently unifed with (say) *->*, because then+ 'k' is subsequently unified with (say) *->*, because then we'd have ill-kinded types floating about. Rather we want to defer using the equality altogether until 'k' get resolved. @@ -453,7 +455,7 @@ tyCoVarsOfCts = fvVarSet . tyCoFVsOfCts -- | Returns free variables of a bag of constraints as a deterministically--- odered list. See Note [Deterministic FV] in FV.+-- ordered list. See Note [Deterministic FV] in FV. tyCoVarsOfCtsList :: Cts -> [TcTyCoVar] tyCoVarsOfCtsList = fvVarList . tyCoFVsOfCts @@ -827,7 +829,7 @@ It's a bit of a special case, but it's easy to do. The runtime cost is low because the unsolved set is usually empty anyway (errors- aside), and the first non-imlicit-parameter will terminate the search.+ aside), and the first non-implicit-parameter will terminate the search. The special case is worth it (#11480, comment:2) because it applies to CallStack constraints, which aren't type errors. If we have@@ -1181,7 +1183,7 @@ forall a k (b::k). { wanted constraints } * Having solved {wanted}, before discarding the now-solved implication,- the costraint solver checks the dependency order of the skolem+ the constraint solver checks the dependency order of the skolem variables (ic_skols). This is done in setImplicationStatus. * This check is only necessary if the implication was born from a@@ -1196,7 +1198,7 @@ * Be careful /NOT/ to discard an implication with non-Nothing ic_telescope, even if ic_wanted is empty. We must give the- constraint solver a chance to make that bad-telesope test! Hence+ constraint solver a chance to make that bad-telescope test! Hence the extra guard in emitResidualTvConstraint; see #16247 See also TcHsType Note [Keeping scoped variables in order: Explicit]
compiler/typecheck/TcEvidence.hs view
@@ -4,14 +4,14 @@ module TcEvidence ( - -- HsWrapper+ -- * HsWrapper HsWrapper(..), (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpLams, mkWpLet, mkWpCastN, mkWpCastR, collectHsWrapBinders, mkWpFun, idHsWrapper, isIdHsWrapper, isErasableHsWrapper, pprHsWrapper, - -- Evidence bindings+ -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), EvBindMap(..), emptyEvBindMap, extendEvBinds, lookupEvBind, evBindMapBinds, foldEvBindMap, filterEvBindMap,@@ -19,7 +19,7 @@ EvBind(..), emptyTcEvBinds, isEmptyTcEvBinds, mkGivenEvBind, mkWantedEvBind, evBindVar, isCoEvBindsVar, - -- EvTerm (already a CoreExpr)+ -- * EvTerm (already a CoreExpr) EvTerm(..), EvExpr, evId, evCoercion, evCast, evDFunApp, evDataConApp, evSelector, mkEvCast, evVarsOfTerm, mkEvScSelectors, evTypeable, findNeededEvVars,@@ -28,7 +28,7 @@ EvCallStack(..), EvTypeable(..), - -- TcCoercion+ -- * TcCoercion TcCoercion, TcCoercionR, TcCoercionN, TcCoercionP, CoercionHole, TcMCoercion, Role(..), LeftOrRight(..), pickLR,@@ -45,7 +45,10 @@ mkTcCoVarCo, isTcReflCo, isTcReflexiveCo, isTcGReflMCo, tcCoToMCo, tcCoercionRole,- unwrapIP, wrapIP+ unwrapIP, wrapIP,++ -- * QuoteWrapper+ QuoteWrapper(..), applyQuoteWrapper, quoteWrapperTyVarTy ) where #include "HsVersions.h" @@ -924,7 +927,7 @@ help it (WpCast co) = add_parens $ sep [it False, nest 2 (text "|>" <+> pprParendCo co)] help it (WpEvApp id) = no_parens $ sep [it True, nest 2 (ppr id)]- help it (WpTyApp ty) = no_parens $ sep [it True, text "@" <+> pprParendType ty]+ help it (WpTyApp ty) = no_parens $ sep [it True, text "@" <> pprParendType ty] help it (WpEvLam id) = add_parens $ sep [ text "\\" <> pprLamBndr id <> dot, it False] help it (WpTyLam tv) = add_parens $ sep [text "/\\" <> pprLamBndr tv <> dot, it False] help it (WpLet binds) = add_parens $ sep [text "let" <+> braces (ppr binds), it False]@@ -1002,3 +1005,25 @@ -- dictionary. See 'unwrapIP'. wrapIP :: Type -> CoercionR wrapIP ty = mkSymCo (unwrapIP ty)++----------------------------------------------------------------------+-- A datatype used to pass information when desugaring quotations+----------------------------------------------------------------------++-- We have to pass a `EvVar` and `Type` into `dsBracket` so that the+-- correct evidence and types are applied to all the TH combinators.+-- This data type bundles them up together with some convenience methods.+--+-- The EvVar is evidence for `Quote m`+-- The Type is a metavariable for `m`+--+data QuoteWrapper = QuoteWrapper EvVar Type deriving Data.Data++quoteWrapperTyVarTy :: QuoteWrapper -> Type+quoteWrapperTyVarTy (QuoteWrapper _ t) = t++-- | Convert the QuoteWrapper into a normal HsWrapper which can be used to+-- apply its contents.+applyQuoteWrapper :: QuoteWrapper -> HsWrapper+applyQuoteWrapper (QuoteWrapper ev_var m_var)+ = mkWpEvVarApps [ev_var] <.> mkWpTyApps [m_var]
compiler/typecheck/TcOrigin.hs view
@@ -7,6 +7,9 @@ {-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+ module TcOrigin ( -- UserTypeCtxt UserTypeCtxt(..), pprUserTypeCtxt, isSigMaybe,@@ -430,6 +433,7 @@ | HoleOrigin | UnboundOccurrenceOf OccName | ListOrigin -- An overloaded list+ | BracketOrigin -- An overloaded quotation bracket | StaticOrigin -- A static form | FailablePattern (LPat GhcTcId) -- A failable pattern in do-notation for the -- MonadFail Proposal (MFP). Obsolete when@@ -639,7 +643,7 @@ pprCtO (LiteralOrigin lit) = hsep [text "the literal", quotes (ppr lit)] pprCtO (ArithSeqOrigin seq) = hsep [text "the arithmetic sequence", quotes (ppr seq)] pprCtO SectionOrigin = text "an operator section"-pprCtO AssocFamPatOrigin = text "the LHS of a famly instance"+pprCtO AssocFamPatOrigin = text "the LHS of a family instance" pprCtO TupleOrigin = text "a tuple" pprCtO NegateOrigin = text "a use of syntactic negation" pprCtO (ScOrigin n) = text "the superclasses of an instance declaration"@@ -655,4 +659,5 @@ pprCtO HoleOrigin = text "a use of" <+> quotes (text "_") pprCtO ListOrigin = text "an overloaded list" pprCtO StaticOrigin = text "a static form"+pprCtO BracketOrigin = text "a quotation bracket" pprCtO _ = panic "pprCtOrigin"
compiler/typecheck/TcRnTypes.hs view
@@ -142,7 +142,7 @@ -- | A 'NameShape' is a substitution on 'Name's that can be used -- to refine the identities of a hole while we are renaming interfaces--- (see 'RnModIface'). Specifically, a 'NameShape' for+-- (see 'GHC.Iface.Rename'). Specifically, a 'NameShape' for -- 'ns_module_name' @A@, defines a mapping from @{A.T}@ -- (for some 'OccName' @T@) to some arbitrary other 'Name'. --@@ -242,7 +242,7 @@ -- was originally a hi-boot file. -- We need the module name so we can test when it's appropriate -- to look in this env.- -- See Note [Tying the knot] in TcIface+ -- See Note [Tying the knot] in GHC.IfaceToCore if_rec_types :: Maybe (Module, IfG TypeEnv) -- Allows a read effect, so it can be in a mutable -- variable; c.f. handling the external package type env@@ -275,8 +275,8 @@ -- This field is used to make sure "implicit" declarations -- (anything that cannot be exported in mi_exports) get -- wired up correctly in typecheckIfacesForMerging. Most- -- of the time it's @Nothing@. See Note [Resolving never-exported Names in TcIface]- -- in TcIface.+ -- of the time it's @Nothing@. See Note [Resolving never-exported Names]+ -- in GHC.IfaceToCore. if_implicits_env :: Maybe TypeEnv, if_tv_env :: FastStringEnv TyVar, -- Nested tyvar bindings@@ -385,15 +385,15 @@ -- then moduleUnitId this_mod == thisPackage dflags -- -- - For any code involving Names, we want semantic modules.--- See lookupIfaceTop in IfaceEnv, mkIface and addFingerprints--- in MkIface, and tcLookupGlobal in TcEnv+-- See lookupIfaceTop in GHC.Iface.Env, mkIface and addFingerprints+-- in GHC.Iface.Utils, and tcLookupGlobal in TcEnv -- -- - When reading interfaces, we want the identity module to -- identify the specific interface we want (such interfaces -- should never be loaded into the EPS). However, if a -- hole module <A> is requested, we look for A.hi--- in the home library we are compiling. (See LoadIface.)--- Similarly, in RnNames we check for self-imports using+-- in the home library we are compiling. (See GHC.Iface.Load.)+-- Similarly, in GHC.Rename.Names we check for self-imports using -- identity modules, to allow signatures to import their implementor. -- -- - For recompilation avoidance, you want the identity module,@@ -650,7 +650,7 @@ { sb_mds :: ModDetails -- There was a hi-boot file, , sb_tcs :: NameSet } -- defining these TyCons, -- What is sb_tcs used for? See Note [Extra dependencies from .hs-boot files]--- in RnSource+-- in GHC.Rename.Source {- Note [Tracking unused binding and imports]@@ -664,9 +664,9 @@ and *used* Names (local or imported) Used (a) to report "defined but not used"- (see RnNames.reportUnusedNames)+ (see GHC.Rename.Names.reportUnusedNames) (b) to generate version-tracking usage info in interface- files (see MkIface.mkUsedNames)+ files (see GHC.Iface.Utils.mkUsedNames) This usage info is mainly gathered by the renamer's gathering of free-variables @@ -697,7 +697,7 @@ (c) Top-level variables appearing free in a TH bracket See Note [Keeping things alive for Template Haskell]- in RnSplice+ in GHC.Rename.Splice (d) The data constructor of a newtype that is used to solve a Coercible instance (e.g. #10347). Example@@ -719,8 +719,8 @@ simplifier does not discard them as dead code, and so that they are exposed in the interface file (but not to export to the user). - * RnNames.reportUnusedNames. Where newtype data constructors like (d)- are imported, we don't want to report them as unused.+ * GHC.Rename.Names.reportUnusedNames. Where newtype data constructors+ like (d) are imported, we don't want to report them as unused. ************************************************************************@@ -911,7 +911,12 @@ data SpliceType = Typed | Untyped -data ThStage -- See Note [Template Haskell state diagram] in TcSplice+data ThStage -- See Note [Template Haskell state diagram]+ -- and Note [Template Haskell levels] in TcSplice+ -- Start at: Comp+ -- At bracket: wrap current stage in Brack+ -- At splice: currently Brack: return to previous stage+ -- currently Comp/Splice: compile and run = Splice SpliceType -- Inside a top-level splice -- This code will be run *at compile time*; -- the result replaces the splice@@ -925,7 +930,7 @@ -- -- 'addModFinalizer' inserts finalizers here, and from here they are taken -- to construct an @HsSpliced@ annotation for untyped splices. See Note- -- [Delaying modFinalizers in untyped splices] in "RnSplice".+ -- [Delaying modFinalizers in untyped splices] in GHC.Rename.Splice. -- -- For typed splices, the typechecker takes finalizers from here and -- inserts them in the list of finalizers in the global environment.@@ -948,7 +953,14 @@ | TcPending -- Typechecking the inside of a typed bracket (TcRef [PendingTcSplice]) -- Accumulate pending splices here (TcRef WantedConstraints) -- and type constraints here+ QuoteWrapper -- A type variable and evidence variable+ -- for the overall monad of+ -- the bracket. Splices are checked+ -- against this monad. The evidence+ -- variable is used for desugaring+ -- `lift`. + topStage, topAnnStage, topSpliceStage :: ThStage topStage = Comp topAnnStage = Splice Untyped@@ -973,11 +985,10 @@ thLevel :: ThStage -> ThLevel thLevel (Splice _) = 0-thLevel (RunSplice _) =- -- See Note [RunSplice ThLevel].- panic "thLevel: called when running a splice" thLevel Comp = 1 thLevel (Brack s _) = thLevel s + 1+thLevel (RunSplice _) = panic "thLevel: called when running a splice"+ -- See Note [RunSplice ThLevel]. {- Node [RunSplice ThLevel] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -1173,7 +1184,7 @@ If an Id has ClosedTypeId=True (in its IdBindingInfo), then the Id's type is /definitely/ closed (has no free type variables). Specifically,- a) The Id's acutal type is closed (has no free tyvars)+ a) The Id's actual type is closed (has no free tyvars) b) Either the Id has a (closed) user-supplied type signature or all its free variables are Global/ClosedLet or NonClosedLet with ClosedTypeId=True.@@ -1349,13 +1360,13 @@ -- where True for the bool indicates the package is required to be -- trusted is the more logical design, doing so complicates a lot -- of code not concerned with Safe Haskell.- -- See Note [RnNames . Tracking Trust Transitively]+ -- See Note [Tracking Trust Transitively] in GHC.Rename.Names imp_trust_own_pkg :: Bool, -- ^ Do we require that our own package is trusted? -- This is to handle efficiently the case where a Safe module imports -- a Trustworthy module that resides in the same package as it.- -- See Note [RnNames . Trust Own Package]+ -- See Note [Trust Own Package] in GHC.Rename.Names imp_orphs :: [Module], -- ^ Orphan modules below us in the import tree (and maybe including@@ -1433,7 +1444,7 @@ = ImportByUser IsBootInterface -- Ordinary user import (perhaps {-# SOURCE #-}) | ImportBySystem -- Non user import. | ImportByPlugin -- Importing a plugin;- -- See Note [Care with plugin imports] in LoadIface+ -- See Note [Care with plugin imports] in GHC.Iface.Load instance Outputable WhereFrom where ppr (ImportByUser is_boot) | is_boot = text "{- SOURCE -}"@@ -1512,7 +1523,7 @@ -- -- NB: The order of sig_inst_skols is irrelevant -- for a CompleteSig, but for a PartialSig see- -- Note [Quantified varaibles in partial type signatures]+ -- Note [Quantified variables in partial type signatures] , sig_inst_theta :: TcThetaType -- Instantiated theta. In the case of a@@ -1543,7 +1554,7 @@ But that's ok: tcMatchesFun (called by tcRhs) can deal with that It happens, too! See Note [Polymorphic methods] in TcClassDcl. -Note [Quantified varaibles in partial type signatures]+Note [Quantified variables in partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider f :: forall a b. _ -> a -> _ -> b
compiler/typecheck/TcType.hs view
@@ -16,6 +16,7 @@ -} {-# LANGUAGE CPP, ScopedTypeVariables, MultiWayIf, FlexibleContexts #-}+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module TcType ( --------------------------------@@ -120,14 +121,14 @@ tcSplitIOType_maybe, -- :: Type -> Maybe Type --------------------------------- -- Rexported from Kind+ -- Reexported from Kind Kind, tcTypeKind, liftedTypeKind, constraintKind, isLiftedTypeKind, isUnliftedTypeKind, classifiesTypeWithValues, --------------------------------- -- Rexported from Type+ -- Reexported from Type Type, PredType, ThetaType, TyCoBinder, ArgFlag(..), AnonArgFlag(..), ForallVisFlag(..), @@ -298,7 +299,7 @@ and kinds generated by TcHsType. - The pattern-match overlap checker calls the constraint solver,- long afer TcTyVars have been zonked away+ long after TcTyVars have been zonked away It's convenient to simply treat these TyVars as skolem constants, which of course they are. We give them a level number of "outermost",@@ -458,7 +459,7 @@ Note [Signature skolems] ~~~~~~~~~~~~~~~~~~~~~~~~-A TyVarTv is a specialised variant of TauTv, with the following invarints:+A TyVarTv is a specialised variant of TauTv, with the following invariants: * A TyVarTv can be unified only with a TyVar, not with any other type@@ -553,7 +554,7 @@ -- See Note [The flattening story] in TcFlatten | FlatSkolTv -- A flatten skolem tyvar- -- Just like FlatMetaTv, but is comletely "owned" by+ -- Just like FlatMetaTv, but is completely "owned" by -- its Given CFunEqCan. -- It is filled in /only/ by unflattenGivens -- See Note [The flattening story] in TcFlatten
compiler/types/Class.hs view
@@ -212,7 +212,7 @@ parent class. Thus class C a b where type F b x a :: *-We make F use the same Name for 'a' as C does, and similary 'b'.+We make F use the same Name for 'a' as C does, and similarly 'b'. The reason for this is when checking instances it's easier to match them up, to ensure they match. Eg
compiler/types/Coercion.hs view
@@ -116,11 +116,11 @@ #include "HsVersions.h" -import {-# SOURCE #-} ToIface (toIfaceTyCon, tidyToIfaceTcArgs)+import {-# SOURCE #-} GHC.CoreToIface (toIfaceTyCon, tidyToIfaceTcArgs) import GhcPrelude -import IfaceType+import GHC.Iface.Type import TyCoRep import TyCoFVs import TyCoPpr@@ -231,7 +231,7 @@ ppr_co_ax_branch ppr_rhs fam_tc branch = foldr1 (flip hangNotEmpty 2) [ pprUserForAll (mkTyCoVarBinders Inferred bndrs')- -- See Note [Printing foralls in type family instances] in IfaceType+ -- See Note [Printing foralls in type family instances] in GHC.Iface.Type , pp_lhs <+> ppr_rhs tidy_env ee_rhs , text "-- Defined" <+> pp_loc ] where@@ -1943,7 +1943,7 @@ callback: We want 'liftCoSubstVarBndrUsing' to be general enough to be reused in- FamInstEnv, therefore the input arg 'fun' returns a pair with polymophic type+ FamInstEnv, therefore the input arg 'fun' returns a pair with polymorphic type in snd. However in 'liftCoSubstVarBndr', we don't need the snd, so we use unit and ignore the fourth component of the return value.
compiler/types/FamInstEnv.hs view
@@ -5,6 +5,8 @@ {-# LANGUAGE CPP, GADTs, ScopedTypeVariables, BangPatterns, TupleSections, DeriveFunctor #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+ module FamInstEnv ( FamInst(..), FamFlavor(..), famInstAxiom, famInstTyCon, famInstRHS, famInstsRepTyCons, famInstRepTyCon_maybe, dataFamInstRepTyCon,@@ -245,7 +247,7 @@ Note [Lazy axiom match] ~~~~~~~~~~~~~~~~~~~~~~~ It is Vitally Important that mkImportedFamInst is *lazy* in its axiom-parameter. The axiom is loaded lazily, via a forkM, in TcIface. Sometime+parameter. The axiom is loaded lazily, via a forkM, in GHC.IfaceToCore. Sometime later, mkImportedFamInst is called using that axiom. However, the axiom may itself depend on entities which are not yet loaded as of the time of the mkImportedFamInst. Thus, if mkImportedFamInst eagerly looks at the@@ -685,7 +687,7 @@ -> [TyVar] -> [TyVar] -> [CoVar] -> TyCon -> [Type] -> Type -> CoAxiom Unbranched--- Make a single-branch CoAxiom, incluidng making the branch itself+-- Make a single-branch CoAxiom, including making the branch itself -- Used for both type family (Nominal) and data family (Representational) -- axioms, hence passing in the Role mkSingleCoAxiom role ax_name tvs eta_tvs cvs fam_tc lhs_tys rhs_ty@@ -1091,7 +1093,7 @@ -- but *not* newtypes -- Works on type-synonym families always; data-families only if -- the role we seek is representational--- It does *not* normlise the type arguments first, so this may not+-- It does *not* normalise the type arguments first, so this may not -- go as far as you want. If you want normalised type arguments, -- use normaliseTcArgs first. --@@ -1644,7 +1646,7 @@ they did, then looking up `F b1` would yield the same flatten var for each.) So, even though `forall`-bound variables should really be in the in-scope set only when they are in scope, we retain these variables even- outside of their scope. This ensures that, if we enounter a fresh+ outside of their scope. This ensures that, if we encounter a fresh `forall`-bound b, we will rename it to b2, not b1. Note that keeping a larger in-scope set than strictly necessary is always OK, as in-scope sets are only ever used to avoid collisions.
compiler/types/InstEnv.hs view
@@ -320,7 +320,7 @@ {- Note [When exactly is an instance decl an orphan?] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~- (see MkIface.instanceToIfaceInst, which implements this)+ (see GHC.Iface.Utils.instanceToIfaceInst, which implements this) Roughly speaking, an instance is an orphan if its head (after the =>) mentions nothing defined in this module. @@ -490,7 +490,7 @@ -- ^ True when when the instance heads are the same -- e.g. both are Eq [(a,b)] -- Used for overriding in GHCi--- Obviously should be insenstive to alpha-renaming+-- Obviously should be insensitive to alpha-renaming identicalClsInstHead (ClsInst { is_cls_nm = cls_nm1, is_tcs = rough1, is_tys = tys1 }) (ClsInst { is_cls_nm = cls_nm2, is_tcs = rough2, is_tys = tys2 }) = cls_nm1 == cls_nm2@@ -702,7 +702,7 @@ will eventually apply. GHC keeps going, and matches on the generic `C a'. The fix is to, at each step, check to see if there's a reverse match, and if so, abort the search. This prevents hugs from-prematurely chosing a generic instance when a more specific one+prematurely choosing a generic instance when a more specific one exists. --Jeff
compiler/types/OptCoercion.hs view
@@ -1166,7 +1166,7 @@ , tc1 == tc2 , isInjectiveTyCon tc r -- See Note [NthCo and newtypes] in TyCoRep , let n = length tys1- , tys2 `lengthIs` n -- This can fail in an erroneous progam+ , tys2 `lengthIs` n -- This can fail in an erroneous program -- E.g. T a ~# T a b -- #14607 = ASSERT( tc == tc1 )
compiler/types/TyCoFVs.hs view
@@ -84,7 +84,7 @@ This looks deceptively similar, but while FV internally builds a list- and set-generating function, the VarSet functions manipulate sets directly, and- the latter peforms a lot worse than the naive FV version.+ the latter performs a lot worse than the naive FV version. 3. Accumulator-style VarSet version: this is what we use now. We do use VarSet as our data structure, but delegate the actual work to a new@@ -811,7 +811,7 @@ -- -- It is also meant to be stable: that is, variables should not -- be reordered unnecessarily. This is specified in Note [ScopedSort]--- See also Note [Ordering of implicit variables] in RnTypes+-- See also Note [Ordering of implicit variables] in GHC.Rename.Types scopedSort :: [TyCoVar] -> [TyCoVar] scopedSort = go [] []
compiler/types/TyCoPpr.hs view
@@ -5,7 +5,7 @@ PprPrec(..), topPrec, sigPrec, opPrec, funPrec, appPrec, maybeParen, -- * Pretty-printing types- pprType, pprParendType, pprPrecType, pprPrecTypeX,+ pprType, pprParendType, pprTidiedType, pprPrecType, pprPrecTypeX, pprTypeApp, pprTCvBndr, pprTCvBndrs, pprSigmaType, pprTheta, pprParendTheta, pprForAll, pprUserForAll,@@ -27,8 +27,10 @@ import GhcPrelude -import {-# SOURCE #-} ToIface( toIfaceTypeX, toIfaceTyLit, toIfaceForAllBndr- , toIfaceTyCon, toIfaceTcArgs, toIfaceCoercionX )+import {-# SOURCE #-} GHC.CoreToIface+ ( toIfaceTypeX, toIfaceTyLit, toIfaceForAllBndr+ , toIfaceTyCon, toIfaceTcArgs, toIfaceCoercionX )+ import {-# SOURCE #-} DataCon( dataConFullSig , dataConUserTyVarBinders , DataCon )@@ -42,7 +44,7 @@ import Class import Var -import IfaceType+import GHC.Iface.Type import VarSet import VarEnv@@ -68,7 +70,7 @@ works just by setting the initial context precedence very high. Note that any function which pretty-prints a @Type@ first converts the @Type@-to an @IfaceType@. See Note [IfaceType and pretty-printing] in IfaceType.+to an @IfaceType@. See Note [IfaceType and pretty-printing] in GHC.Iface.Type. See Note [Precedence in types] in BasicTypes. -}@@ -76,12 +78,15 @@ -------------------------------------------------------- -- When pretty-printing types, we convert to IfaceType, -- and pretty-print that.--- See Note [Pretty printing via IfaceSyn] in PprTyThing+-- See Note [Pretty printing via Iface syntax] in PprTyThing -------------------------------------------------------- -pprType, pprParendType :: Type -> SDoc+pprType, pprParendType, pprTidiedType :: Type -> SDoc pprType = pprPrecType topPrec pprParendType = pprPrecType appPrec++-- already pre-tidied+pprTidiedType = pprIfaceType . toIfaceTypeX emptyVarSet pprPrecType :: PprPrec -> Type -> SDoc pprPrecType = pprPrecTypeX emptyTidyEnv
compiler/types/TyCoRep.hs view
@@ -76,7 +76,7 @@ import {-# SOURCE #-} ConLike ( ConLike(..), conLikeName ) -- friends:-import IfaceType+import GHC.Iface.Type import Var import VarSet import Name hiding ( varName )@@ -1101,7 +1101,7 @@ Coercions have the following invariant Refl (similar for GRefl r ty MRefl) is always lifted as far as possible. -You might think that a consequencs is:+You might think that a consequences is: Every identity coercions has Refl at the root But that's not quite true because of coercion variables. Consider@@ -1565,7 +1565,7 @@ holes are easier. - Moreover, nothing is lost from the lack of let-bindings. For- dicionaries want to achieve sharing to avoid recomoputing the+ dictionaries want to achieve sharing to avoid recomoputing the dictionary. But coercions are entirely erased, so there's little benefit to sharing. Indeed, even if we had a let-binding, we always inline types and coercions at every use site and drop the
compiler/types/TyCoSubst.hs view
@@ -6,6 +6,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE BangPatterns #-}+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} -- | Substitution into types and coercions. module TyCoSubst@@ -527,7 +528,7 @@ x's type (in order to, e.g., bring the scoped type variable `a` into scope). This requires performing a substitution for the fresh skolem variables. -This subsitution needs to affect the kind of the coercion hole, too --+This substitution needs to affect the kind of the coercion hole, too -- otherwise, the kind will have an out-of-scope variable in it. More problematically in practice (we won't actually notice the out-of-scope variable ever), skolems in the kind might have too high a level, triggering a failure to uphold the
compiler/types/TyCoTidy.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE BangPatterns #-}+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- | Tidying types and coercions for printing in error messages. module TyCoTidy@@ -95,8 +97,8 @@ tidyFreeTyCoVars :: TidyEnv -> [TyCoVar] -> TidyEnv -- ^ Add the free 'TyVar's to the env in tidy form, -- so that we can tidy the type they are free in-tidyFreeTyCoVars (full_occ_env, var_env) tyvars- = fst (tidyOpenTyCoVars (full_occ_env, var_env) tyvars)+tidyFreeTyCoVars tidy_env tyvars+ = fst (tidyOpenTyCoVars tidy_env tyvars) --------------- tidyOpenTyCoVars :: TidyEnv -> [TyCoVar] -> (TidyEnv, [TyCoVar])@@ -144,7 +146,7 @@ -- The following two functions differ from mkForAllTys and splitForAllTys in that--- they expect/preserve the ArgFlag argument. Thes belong to types/Type.hs, but+-- they expect/preserve the ArgFlag argument. These belong to types/Type.hs, but -- how should they be named? mkForAllTys' :: [(TyCoVar, ArgFlag)] -> Type -> Type mkForAllTys' tvvs ty = foldr strictMkForAllTy ty tvvs@@ -232,5 +234,3 @@ tidyCos :: TidyEnv -> [Coercion] -> [Coercion] tidyCos env = map (tidyCo env)--
compiler/types/TyCon.hs view
@@ -400,7 +400,7 @@ See also: * [Injectivity annotation] in GHC.Hs.Decls- * [Renaming injectivity annotation] in RnSource+ * [Renaming injectivity annotation] in GHC.Rename.Source * [Verifying injectivity annotation] in FamInstEnv * [Type inference for type families with injectivity] in TcInteract @@ -479,7 +479,7 @@ isInvisibleTyConBinder tcb = not (isVisibleTyConBinder tcb) -- Build the 'tyConKind' from the binders and the result kind.--- Keep in sync with 'mkTyConKind' in iface/IfaceType.+-- Keep in sync with 'mkTyConKind' in GHC.Iface.Type. mkTyConKind :: [TyConBinder] -> Kind -> Kind mkTyConKind bndrs res_kind = foldr mk res_kind bndrs where@@ -1490,7 +1490,7 @@ -- fields. For instance, in @data Foo = Foo Float# Float#@ the two fields will -- take only 8 bytes, which for 64-bit arch will be equal to 1 word. -- See also mkVirtHeapOffsetsWithPadding for details of how data fields are--- layed out.+-- laid out. primRepSizeB :: DynFlags -> PrimRep -> Int primRepSizeB dflags IntRep = wORD_SIZE dflags primRepSizeB dflags WordRep = wORD_SIZE dflags@@ -2526,7 +2526,7 @@ its relative index in the constructor list. That was quadratic and prohibitive for large data types with more than 10k constructors. -The current strategy is to build a NameEnv with a mapping from costructor's+The current strategy is to build a NameEnv with a mapping from constructor's Name to ConTag and pass it down to buildDataCon for efficient lookup. Relevant ticket: #14657
compiler/types/Type.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE CPP, FlexibleContexts #-} {-# OPTIONS_GHC -fno-warn-orphans #-}+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} -- | Main functions for manipulating types and type-related things module Type (@@ -1128,7 +1129,7 @@ = -- We have not run out of arguments, but the function doesn't -- have the right kind to apply to them; so panic. -- Without the explicit isEmptyVarEnv test, an ill-kinded type- -- would give an infniite loop, which is very unhelpful+ -- would give an infinite loop, which is very unhelpful -- c.f. #15473 pprPanic "piResultTys2" (ppr ty $$ ppr orig_args $$ ppr all_args) @@ -1159,7 +1160,7 @@ T (forall b. b->b) * :: (b -> b)[ b :-> *] :: * -> * -In other words we must intantiate the forall!+In other words we must instantiate the forall! Similarly (#15428) S :: forall k f. k -> f k@@ -1170,7 +1171,7 @@ :: * -> * -> * So again we must instantiate. -The same thing happens in ToIface.toIfaceAppArgsX.+The same thing happens in GHC.CoreToIface.toIfaceAppArgsX. ---------------------------------------------------------------------@@ -2440,7 +2441,7 @@ typeKind (AppTy fun arg) = go fun [arg] where- -- Accumulate the type arugments, so we can call piResultTys,+ -- Accumulate the type arguments, so we can call piResultTys, -- rather than a succession of calls to piResultTy (which is -- asymptotically costly as the number of arguments increases) go (AppTy fun arg) args = go fun (arg:args)@@ -2480,7 +2481,7 @@ tcTypeKind (AppTy fun arg) = go fun [arg] where- -- Accumulate the type arugments, so we can call piResultTys,+ -- Accumulate the type arguments, so we can call piResultTys, -- rather than a succession of calls to piResultTy (which is -- asymptotically costly as the number of arguments increases) go (AppTy fun arg) args = go fun (arg:args)@@ -2937,7 +2938,7 @@ %* * %************************************************************************ -Most pretty-printing is either in TyCoRep or IfaceType.+Most pretty-printing is either in TyCoRep or GHC.Iface.Type. -}
compiler/utils/Binary.hs view
@@ -670,7 +670,7 @@ actually generated by GHC. In the old scheme this was encoded as a list of 19 chars. This gave a size of 77 Bytes, one for the length of the list and 76-since we encod chars as Word32 as well.+since we encode chars as Word32 as well. We can easily do better. The new plan is: @@ -1037,7 +1037,7 @@ -- These two settings have different needs while serializing Names: -- -- * Names in interface files are serialized via a symbol table (see Note--- [Symbol table representation of names] in BinIface).+-- [Symbol table representation of names] in GHC.Iface.Binary). -- -- * During fingerprinting a binding Name is serialized as the OccName and a -- non-binding Name is serialized as the fingerprint of the thing they
compiler/utils/Digraph.hs view
@@ -464,7 +464,7 @@ newtype Time = Time Int deriving (Eq,Ord,Num,Outputable) ---Allow for specialzation+--Allow for specialization {-# INLINEABLE classifyEdges #-} -- | Given a start vertex, a way to get successors from a node
compiler/utils/FastString.hs view
@@ -20,7 +20,7 @@ -- -- * Pointer and size of a Latin-1 encoded string. -- * Practically no operations.--- * Outputing them is fast.+-- * Outputting them is fast. -- * Generated by 'sLit'. -- * Turn into 'Outputable.SDoc' with 'Outputable.ptext' -- * Requires manual memory management.@@ -73,7 +73,7 @@ nilFS, isUnderscoreFS, - -- ** Outputing+ -- ** Outputting hPutFS, -- ** Internal
compiler/utils/Fingerprint.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- ---------------------------------------------------------------------------- --
compiler/utils/Outputable.hs view
@@ -34,12 +34,12 @@ sep, cat, fsep, fcat, hang, hangNotEmpty, punctuate, ppWhen, ppUnless,- speakNth, speakN, speakNOf, plural, isOrAre, doOrDoes,+ speakNth, speakN, speakNOf, plural, isOrAre, doOrDoes, itsOrTheir, unicodeSyntax, coloured, keyword, - -- * Converting 'SDoc' into strings and outputing it+ -- * Converting 'SDoc' into strings and outputting it printSDoc, printSDocLn, printForUser, printForUserPartWay, printForC, bufLeftRenderSDoc, pprCode, mkCodeStyle,@@ -124,6 +124,8 @@ import Numeric (showFFloat) import Data.Graph (SCC(..)) import Data.List (intersperse)+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NEL import GHC.Fingerprint import GHC.Show ( showMultiLineString )@@ -819,6 +821,9 @@ instance (Outputable a) => Outputable [a] where ppr xs = brackets (fsep (punctuate comma (map ppr xs))) +instance (Outputable a) => Outputable (NonEmpty a) where+ ppr = ppr . NEL.toList+ instance (Outputable a) => Outputable (Set a) where ppr s = braces (fsep (punctuate comma (map ppr (Set.toList s)))) @@ -1154,6 +1159,15 @@ doOrDoes :: [a] -> SDoc doOrDoes [_] = text "does" doOrDoes _ = text "do"++-- | Determines the form of possessive appropriate for the length of a list:+--+-- > itsOrTheir [x] = text "its"+-- > itsOrTheir [x,y] = text "their"+-- > itsOrTheir [] = text "their" -- probably avoid this+itsOrTheir :: [a] -> SDoc+itsOrTheir [_] = text "its"+itsOrTheir _ = text "their" {- ************************************************************************
+ compiler/utils/Stream.hs view
@@ -0,0 +1,135 @@+-- -----------------------------------------------------------------------------+--+-- (c) The University of Glasgow 2012+--+-- Monadic streams+--+-- -----------------------------------------------------------------------------+module Stream (+ Stream(..), yield, liftIO,+ collect, collect_, consume, fromList,+ Stream.map, Stream.mapM, Stream.mapAccumL, Stream.mapAccumL_+ ) where++import GhcPrelude++import Control.Monad++-- |+-- @Stream m a b@ is a computation in some Monad @m@ that delivers a sequence+-- of elements of type @a@ followed by a result of type @b@.+--+-- More concretely, a value of type @Stream m a b@ can be run using @runStream@+-- in the Monad @m@, and it delivers either+--+-- * the final result: @Left b@, or+-- * @Right (a,str)@, where @a@ is the next element in the stream, and @str@+-- is a computation to get the rest of the stream.+--+-- Stream is itself a Monad, and provides an operation 'yield' that+-- produces a new element of the stream. This makes it convenient to turn+-- existing monadic computations into streams.+--+-- The idea is that Stream is useful for making a monadic computation+-- that produces values from time to time. This can be used for+-- knitting together two complex monadic operations, so that the+-- producer does not have to produce all its values before the+-- consumer starts consuming them. We make the producer into a+-- Stream, and the consumer pulls on the stream each time it wants a+-- new value.+--+newtype Stream m a b = Stream { runStream :: m (Either b (a, Stream m a b)) }++instance Monad f => Functor (Stream f a) where+ fmap = liftM++instance Monad m => Applicative (Stream m a) where+ pure a = Stream (return (Left a))+ (<*>) = ap++instance Monad m => Monad (Stream m a) where++ Stream m >>= k = Stream $ do+ r <- m+ case r of+ Left b -> runStream (k b)+ Right (a,str) -> return (Right (a, str >>= k))++yield :: Monad m => a -> Stream m a ()+yield a = Stream (return (Right (a, return ())))++liftIO :: IO a -> Stream IO b a+liftIO io = Stream $ io >>= return . Left++-- | Turn a Stream into an ordinary list, by demanding all the elements.+collect :: Monad m => Stream m a () -> m [a]+collect str = go str []+ where+ go str acc = do+ r <- runStream str+ case r of+ Left () -> return (reverse acc)+ Right (a, str') -> go str' (a:acc)++-- | Turn a Stream into an ordinary list, by demanding all the elements.+collect_ :: Monad m => Stream m a r -> m ([a], r)+collect_ str = go str []+ where+ go str acc = do+ r <- runStream str+ case r of+ Left r -> return (reverse acc, r)+ Right (a, str') -> go str' (a:acc)++consume :: Monad m => Stream m a b -> (a -> m ()) -> m b+consume str f = do+ r <- runStream str+ case r of+ Left ret -> return ret+ Right (a, str') -> do+ f a+ consume str' f++-- | Turn a list into a 'Stream', by yielding each element in turn.+fromList :: Monad m => [a] -> Stream m a ()+fromList = mapM_ yield++-- | Apply a function to each element of a 'Stream', lazily+map :: Monad m => (a -> b) -> Stream m a x -> Stream m b x+map f str = Stream $ do+ r <- runStream str+ case r of+ Left x -> return (Left x)+ Right (a, str') -> return (Right (f a, Stream.map f str'))++-- | Apply a monadic operation to each element of a 'Stream', lazily+mapM :: Monad m => (a -> m b) -> Stream m a x -> Stream m b x+mapM f str = Stream $ do+ r <- runStream str+ case r of+ Left x -> return (Left x)+ Right (a, str') -> do+ b <- f a+ return (Right (b, Stream.mapM f str'))++-- | analog of the list-based 'mapAccumL' on Streams. This is a simple+-- way to map over a Stream while carrying some state around.+mapAccumL :: Monad m => (c -> a -> m (c,b)) -> c -> Stream m a ()+ -> Stream m b c+mapAccumL f c str = Stream $ do+ r <- runStream str+ case r of+ Left () -> return (Left c)+ Right (a, str') -> do+ (c',b) <- f c a+ return (Right (b, mapAccumL f c' str'))++mapAccumL_ :: Monad m => (c -> a -> m (c,b)) -> c -> Stream m a r+ -> Stream m b (c, r)+mapAccumL_ f c str = Stream $ do+ r <- runStream str+ case r of+ Left r -> return (Left (c, r))+ Right (a, str') -> do+ (c',b) <- f c a+ return (Right (b, mapAccumL_ f c' str'))
compiler/utils/Util.hs view
@@ -6,6 +6,8 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE TupleSections #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+ -- | Highly random utility functions -- module Util (@@ -323,21 +325,21 @@ #else zipEqual _ [] [] = [] zipEqual msg (a:as) (b:bs) = (a,b) : zipEqual msg as bs-zipEqual msg _ _ = panic ("zipEqual: unequal lists:"++msg)+zipEqual msg _ _ = panic ("zipEqual: unequal lists: "++msg) zipWithEqual msg z (a:as) (b:bs)= z a b : zipWithEqual msg z as bs zipWithEqual _ _ [] [] = []-zipWithEqual msg _ _ _ = panic ("zipWithEqual: unequal lists:"++msg)+zipWithEqual msg _ _ _ = panic ("zipWithEqual: unequal lists: "++msg) zipWith3Equal msg z (a:as) (b:bs) (c:cs) = z a b c : zipWith3Equal msg z as bs cs zipWith3Equal _ _ [] [] [] = []-zipWith3Equal msg _ _ _ _ = panic ("zipWith3Equal: unequal lists:"++msg)+zipWith3Equal msg _ _ _ _ = panic ("zipWith3Equal: unequal lists: "++msg) zipWith4Equal msg z (a:as) (b:bs) (c:cs) (d:ds) = z a b c d : zipWith4Equal msg z as bs cs ds zipWith4Equal _ _ [] [] [] [] = []-zipWith4Equal msg _ _ _ _ _ = panic ("zipWith4Equal: unequal lists:"++msg)+zipWith4Equal msg _ _ _ _ _ = panic ("zipWith4Equal: unequal lists: "++msg) #endif -- | 'zipLazy' is a kind of 'zip' that is lazy in the second list (observe the ~)@@ -701,7 +703,7 @@ | otherwise = go n xs countWhile :: (a -> Bool) -> [a] -> Int--- Length of an /initial prefix/ of the list satsifying p+-- Length of an /initial prefix/ of the list satisfying p countWhile p = go 0 where go !n (x:xs) | p x = go (n+1) xs go !n _ = n@@ -977,7 +979,7 @@ poss_str user_entered , distance <= fuzzy_threshold ] where- -- Work out an approriate match threshold:+ -- Work out an appropriate match threshold: -- We report a candidate if its edit distance is <= the threshold, -- The threshold is set to about a quarter of the # of characters the user entered -- Length Threshold
ghc-lib-parser.cabal view
@@ -1,7 +1,7 @@ cabal-version: >=1.22 build-type: Simple name: ghc-lib-parser-version: 0.20200102+version: 0.20200201 license: BSD3 license-file: LICENSE category: Development@@ -50,7 +50,7 @@ includes/CodeGen.Platform.hs compiler/HsVersions.h compiler/Unique.h-tested-with: GHC==8.8.1, GHC==8.6.5, GHC==8.4.3+tested-with: GHC==8.8.2, GHC==8.6.5, GHC==8.4.4 source-repository head type: git location: git@github.com:digital-asset/ghc-lib.git@@ -130,6 +130,7 @@ libraries/ghc-boot-th compiler/basicTypes compiler/specialise+ compiler/nativeGen compiler/profiling compiler/simplCore compiler/typecheck@@ -145,7 +146,6 @@ libraries/ghci compiler/ghci compiler/main- compiler/cmm compiler/. compiler autogen-modules:@@ -166,7 +166,6 @@ Class CliOption CmdLineParser- CmmType CoAxiom Coercion ConLike@@ -210,6 +209,19 @@ FiniteMap ForeignCall GHC.BaseDir+ GHC.Cmm+ GHC.Cmm.BlockId+ GHC.Cmm.CLabel+ GHC.Cmm.Dataflow.Block+ GHC.Cmm.Dataflow.Collections+ GHC.Cmm.Dataflow.Graph+ GHC.Cmm.Dataflow.Label+ GHC.Cmm.Expr+ GHC.Cmm.MachOp+ GHC.Cmm.Node+ GHC.Cmm.Switch+ GHC.Cmm.Type+ GHC.CoreToIface GHC.Exts.Heap GHC.Exts.Heap.ClosureTypes GHC.Exts.Heap.Closures@@ -234,12 +246,25 @@ GHC.Hs.Types GHC.Hs.Utils GHC.HsToCore.PmCheck.Types+ GHC.Iface.Syntax+ GHC.Iface.Type GHC.LanguageExtensions GHC.LanguageExtensions.Type GHC.Lexeme GHC.PackageDb GHC.Platform+ GHC.Platform.ARM+ GHC.Platform.ARM64+ GHC.Platform.NoRegs+ GHC.Platform.PPC+ GHC.Platform.Regs+ GHC.Platform.S390X+ GHC.Platform.SPARC+ GHC.Platform.X86+ GHC.Platform.X86_64+ GHC.Runtime.Layout GHC.Serialized+ GHC.Stg.Syntax GHC.Types.RepType GHC.UniqueSubdir GHC.Version@@ -258,8 +283,6 @@ IOEnv Id IdInfo- IfaceSyn- IfaceType InstEnv InteractiveEvalTypes Json@@ -291,7 +314,6 @@ OptCoercion OrdList Outputable- PackageConfig Packages Pair Panic@@ -310,10 +332,13 @@ PrimOp RdrHsSyn RdrName+ Reg+ RegClass Rules Settings SizedSeq SrcLoc+ Stream StringBuffer SysTools.BaseDir SysTools.Terminal@@ -322,7 +347,6 @@ TcOrigin TcRnTypes TcType- ToIface ToolSettings TrieMap TyCoFVs@@ -341,6 +365,7 @@ UniqSet UniqSupply Unique+ UnitInfo Util Var VarEnv
ghc-lib/stage0/compiler/build/Lexer.hs view
@@ -8,9 +8,10 @@ {-# LANGUAGE MultiWayIf #-} {-# OPTIONS_GHC -funbox-strict-fields #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Lexer (- Token(..), lexer, pragState, mkPState, mkPStatePure, PState(..),+ Token(..), lexer, lexerDbg, pragState, mkPState, mkPStatePure, PState(..), P(..), ParseResult(..), mkParserFlags, mkParserFlags', ParserFlags(..), appendWarning, appendError,@@ -573,7 +574,7 @@ , (0,alex_action_112) ] -{-# LINE 662 "compiler/parser/Lexer.x" #-}+{-# LINE 663 "compiler/parser/Lexer.x" #-} -- -----------------------------------------------------------------------------@@ -2723,7 +2724,8 @@ -- This is the top-level function: called from the parser each time a -- new token is to be read from the input. -lexer :: Bool -> (Located Token -> P a) -> P a+lexer, lexerDbg :: Bool -> (Located Token -> P a) -> P a+ lexer queueComments cont = do alr <- getBit AlternativeLayoutRuleBit let lexTokenFun = if alr then lexTokenAlr else lexToken@@ -2741,6 +2743,11 @@ if (queueComments && isComment tok) then queueComment (L (RealSrcSpan span) tok) >> lexer queueComments cont else cont (L (RealSrcSpan span) tok)++-- Use this instead of 'lexer' in Parser.y to dump the tokens for debugging.+lexerDbg queueComments cont = lexer queueComments contDbg+ where+ contDbg tok = trace ("token: " ++ show (unLoc tok)) (cont tok) lexTokenAlr :: P (RealLocated Token) lexTokenAlr = do mPending <- popPendingImplicitToken
ghc-lib/stage0/compiler/build/Parser.hs view
@@ -46,7 +46,7 @@ import HscTypes ( IsBootInterface, WarningTxt(..) ) import DynFlags import BkpSyn-import PackageConfig+import UnitInfo -- compiler/utils import OrdList@@ -219,15 +219,15 @@ happyOut32 :: (HappyAbsSyn ) -> HappyWrap32 happyOut32 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut32 #-}-newtype HappyWrap33 = HappyWrap33 (Located (HsModule GhcPs))-happyIn33 :: (Located (HsModule GhcPs)) -> (HappyAbsSyn )+newtype HappyWrap33 = HappyWrap33 (Located HsModule)+happyIn33 :: (Located HsModule) -> (HappyAbsSyn ) happyIn33 x = Happy_GHC_Exts.unsafeCoerce# (HappyWrap33 x) {-# INLINE happyIn33 #-} happyOut33 :: (HappyAbsSyn ) -> HappyWrap33 happyOut33 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut33 #-}-newtype HappyWrap34 = HappyWrap34 (Located (HsModule GhcPs))-happyIn34 :: (Located (HsModule GhcPs)) -> (HappyAbsSyn )+newtype HappyWrap34 = HappyWrap34 (Located HsModule)+happyIn34 :: (Located HsModule) -> (HappyAbsSyn ) happyIn34 x = Happy_GHC_Exts.unsafeCoerce# (HappyWrap34 x) {-# INLINE happyIn34 #-} happyOut34 :: (HappyAbsSyn ) -> HappyWrap34@@ -295,8 +295,8 @@ happyOut42 :: (HappyAbsSyn ) -> HappyWrap42 happyOut42 x = Happy_GHC_Exts.unsafeCoerce# x {-# INLINE happyOut42 #-}-newtype HappyWrap43 = HappyWrap43 (Located (HsModule GhcPs))-happyIn43 :: (Located (HsModule GhcPs)) -> (HappyAbsSyn )+newtype HappyWrap43 = HappyWrap43 (Located HsModule)+happyIn43 :: (Located HsModule) -> (HappyAbsSyn ) happyIn43 x = Happy_GHC_Exts.unsafeCoerce# (HappyWrap43 x) {-# INLINE happyIn43 #-} happyOut43 :: (HappyAbsSyn ) -> HappyWrap43
ghc-lib/stage0/lib/ghcautoconf.h view
@@ -452,7 +452,7 @@ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 -/* Define to 1 if info tables are layed out next to code */+/* Define to 1 if info tables are laid out next to code */ #define TABLES_NEXT_TO_CODE 1 /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
ghc-lib/stage0/lib/ghcversion.h view
@@ -6,7 +6,7 @@ #endif #define __GLASGOW_HASKELL_PATCHLEVEL1__ 0-#define __GLASGOW_HASKELL_PATCHLEVEL2__ 20200101+#define __GLASGOW_HASKELL_PATCHLEVEL2__ 20200131 #define MIN_VERSION_GLASGOW_HASKELL(ma,mi,pl1,pl2) (\ ((ma)*100+(mi)) < __GLASGOW_HASKELL__ || \
ghc-lib/stage0/lib/llvm-passes view
@@ -1,5 +1,5 @@ [-(0, "-mem2reg -globalopt"),+(0, "-mem2reg -globalopt -lower-expect"), (1, "-O1 -globalopt"), (2, "-O2") ]
ghc-lib/stage0/lib/settings view
@@ -1,4 +1,4 @@-[("GCC extra via C opts", "-fwrapv -fno-builtin")+[("GCC extra via C opts", "") ,("C compiler command", "cc") ,("C compiler flags", "") ,("C++ compiler flags", "")
ghc-lib/stage0/libraries/ghc-boot/build/GHC/Version.hs view
@@ -3,19 +3,19 @@ import Prelude -- See Note [Why do we import Prelude here?] cProjectGitCommitId :: String-cProjectGitCommitId = "b84c09d533faf576c406ce9f7163efecf3037787"+cProjectGitCommitId = "01b15b835a7555c501df862b4dc8cc8eaff86afc" cProjectVersion :: String-cProjectVersion = "8.11.0.20200101"+cProjectVersion = "8.11.0.20200131" cProjectVersionInt :: String cProjectVersionInt = "811" cProjectPatchLevel :: String-cProjectPatchLevel = "020200101"+cProjectPatchLevel = "020200131" cProjectPatchLevel1 :: String cProjectPatchLevel1 = "0" cProjectPatchLevel2 :: String-cProjectPatchLevel2 = "20200101"+cProjectPatchLevel2 = "20200131"
includes/CodeGen.Platform.hs view
@@ -1,5 +1,5 @@ -import CmmExpr+import GHC.Cmm.Expr #if !(defined(MACHREGS_i386) || defined(MACHREGS_x86_64) \ || defined(MACHREGS_sparc) || defined(MACHREGS_powerpc)) import PlainPanic
libraries/ghc-boot/GHC/PackageDb.hs view
@@ -30,12 +30,12 @@ -- the internal package format which is specialised just for GHC. -- -- GHC the compiler only needs some of the information which is kept about--- registerd packages, such as module names, various paths etc. On the other+-- registered packages, such as module names, various paths etc. On the other -- hand ghc-pkg has to keep all the information from Cabal packages and be able -- to regurgitate it for users and other tools. -- -- The first trick is that we duplicate some of the information in the package--- database. We essentially keep two versions of the datbase in one file, one+-- database. We essentially keep two versions of the database in one file, one -- version used only by ghc-pkg which keeps the full information (using the -- serialised form of the 'InstalledPackageInfo' type defined by the Cabal -- library); and a second version written by ghc-pkg and read by GHC which has
libraries/template-haskell/Language/Haskell/TH.hs view
@@ -8,6 +8,7 @@ -- * The monad and its operations Q, runQ,+ Quote(..), -- ** Administration: errors, locations and IO reportError, -- :: String -> Q () reportWarning, -- :: String -> Q ()@@ -53,7 +54,6 @@ Name, NameSpace, -- Abstract -- ** Constructing names mkName, -- :: String -> Name- newName, -- :: String -> Q Name -- ** Deconstructing names nameBase, -- :: Name -> String nameModule, -- :: Name -> Maybe String@@ -84,7 +84,7 @@ Pat(..), FieldExp, FieldPat, -- ** Types Type(..), TyVarBndr(..), TyLit(..), Kind, Cxt, Pred, Syntax.Role(..),- FamilyResultSig(..), Syntax.InjectivityAnn(..), PatSynType,+ FamilyResultSig(..), Syntax.InjectivityAnn(..), PatSynType, BangType, VarBangType, -- * Library functions module Language.Haskell.TH.Lib,
libraries/template-haskell/Language/Haskell/TH/Lib.hs view
@@ -159,7 +159,7 @@ ) import Language.Haskell.TH.Syntax -import Control.Monad (liftM2)+import Control.Applicative ( liftA2 ) import Foreign.ForeignPtr import Data.Word import Prelude@@ -172,97 +172,97 @@ ------------------------------------------------------------------------------- -- * Dec -tySynD :: Name -> [TyVarBndr] -> TypeQ -> DecQ+tySynD :: Quote m => Name -> [TyVarBndr] -> m Type -> m Dec tySynD tc tvs rhs = do { rhs1 <- rhs; return (TySynD tc tvs rhs1) } -dataD :: CxtQ -> Name -> [TyVarBndr] -> Maybe Kind -> [ConQ] -> [DerivClauseQ]- -> DecQ+dataD :: Quote m => m Cxt -> Name -> [TyVarBndr] -> Maybe Kind -> [m Con] -> [m DerivClause]+ -> m Dec dataD ctxt tc tvs ksig cons derivs = do ctxt1 <- ctxt- cons1 <- sequence cons- derivs1 <- sequence derivs+ cons1 <- sequenceA cons+ derivs1 <- sequenceA derivs return (DataD ctxt1 tc tvs ksig cons1 derivs1) -newtypeD :: CxtQ -> Name -> [TyVarBndr] -> Maybe Kind -> ConQ -> [DerivClauseQ]- -> DecQ+newtypeD :: Quote m => m Cxt -> Name -> [TyVarBndr] -> Maybe Kind -> m Con -> [m DerivClause]+ -> m Dec newtypeD ctxt tc tvs ksig con derivs = do ctxt1 <- ctxt con1 <- con- derivs1 <- sequence derivs+ derivs1 <- sequenceA derivs return (NewtypeD ctxt1 tc tvs ksig con1 derivs1) -classD :: CxtQ -> Name -> [TyVarBndr] -> [FunDep] -> [DecQ] -> DecQ+classD :: Quote m => m Cxt -> Name -> [TyVarBndr] -> [FunDep] -> [m Dec] -> m Dec classD ctxt cls tvs fds decs = do- decs1 <- sequence decs+ decs1 <- sequenceA decs ctxt1 <- ctxt return $ ClassD ctxt1 cls tvs fds decs1 -pragRuleD :: String -> [RuleBndrQ] -> ExpQ -> ExpQ -> Phases -> DecQ+pragRuleD :: Quote m => String -> [m RuleBndr] -> m Exp -> m Exp -> Phases -> m Dec pragRuleD n bndrs lhs rhs phases = do- bndrs1 <- sequence bndrs+ bndrs1 <- sequenceA bndrs lhs1 <- lhs rhs1 <- rhs return $ PragmaD $ RuleP n Nothing bndrs1 lhs1 rhs1 phases -dataInstD :: CxtQ -> Name -> [TypeQ] -> Maybe Kind -> [ConQ] -> [DerivClauseQ]- -> DecQ+dataInstD :: Quote m => m Cxt -> Name -> [m Type] -> Maybe Kind -> [m Con] -> [m DerivClause]+ -> m Dec dataInstD ctxt tc tys ksig cons derivs = do ctxt1 <- ctxt ty1 <- foldl appT (conT tc) tys- cons1 <- sequence cons- derivs1 <- sequence derivs+ cons1 <- sequenceA cons+ derivs1 <- sequenceA derivs return (DataInstD ctxt1 Nothing ty1 ksig cons1 derivs1) -newtypeInstD :: CxtQ -> Name -> [TypeQ] -> Maybe Kind -> ConQ -> [DerivClauseQ]- -> DecQ+newtypeInstD :: Quote m => m Cxt -> Name -> [m Type] -> Maybe Kind -> m Con -> [m DerivClause]+ -> m Dec newtypeInstD ctxt tc tys ksig con derivs = do ctxt1 <- ctxt ty1 <- foldl appT (conT tc) tys con1 <- con- derivs1 <- sequence derivs+ derivs1 <- sequenceA derivs return (NewtypeInstD ctxt1 Nothing ty1 ksig con1 derivs1) -dataFamilyD :: Name -> [TyVarBndr] -> Maybe Kind -> DecQ+dataFamilyD :: Quote m => Name -> [TyVarBndr] -> Maybe Kind -> m Dec dataFamilyD tc tvs kind- = return $ DataFamilyD tc tvs kind+ = pure $ DataFamilyD tc tvs kind -openTypeFamilyD :: Name -> [TyVarBndr] -> FamilyResultSig- -> Maybe InjectivityAnn -> DecQ+openTypeFamilyD :: Quote m => Name -> [TyVarBndr] -> FamilyResultSig+ -> Maybe InjectivityAnn -> m Dec openTypeFamilyD tc tvs res inj- = return $ OpenTypeFamilyD (TypeFamilyHead tc tvs res inj)+ = pure $ OpenTypeFamilyD (TypeFamilyHead tc tvs res inj) -closedTypeFamilyD :: Name -> [TyVarBndr] -> FamilyResultSig- -> Maybe InjectivityAnn -> [TySynEqnQ] -> DecQ+closedTypeFamilyD :: Quote m => Name -> [TyVarBndr] -> FamilyResultSig+ -> Maybe InjectivityAnn -> [m TySynEqn] -> m Dec closedTypeFamilyD tc tvs result injectivity eqns =- do eqns1 <- sequence eqns+ do eqns1 <- sequenceA eqns return (ClosedTypeFamilyD (TypeFamilyHead tc tvs result injectivity) eqns1) -tySynEqn :: (Maybe [TyVarBndr]) -> TypeQ -> TypeQ -> TySynEqnQ+tySynEqn :: Quote m => (Maybe [TyVarBndr]) -> m Type -> m Type -> m TySynEqn tySynEqn tvs lhs rhs = do lhs1 <- lhs rhs1 <- rhs return (TySynEqn tvs lhs1 rhs1) -forallC :: [TyVarBndr] -> CxtQ -> ConQ -> ConQ-forallC ns ctxt con = liftM2 (ForallC ns) ctxt con+forallC :: Quote m => [TyVarBndr] -> m Cxt -> m Con -> m Con+forallC ns ctxt con = liftA2 (ForallC ns) ctxt con ------------------------------------------------------------------------------- -- * Type -forallT :: [TyVarBndr] -> CxtQ -> TypeQ -> TypeQ+forallT :: Quote m => [TyVarBndr] -> m Cxt -> m Type -> m Type forallT tvars ctxt ty = do ctxt1 <- ctxt ty1 <- ty return $ ForallT tvars ctxt1 ty1 -sigT :: TypeQ -> Kind -> TypeQ+sigT :: Quote m => m Type -> Kind -> m Type sigT t k = do t' <- t@@ -298,12 +298,12 @@ ------------------------------------------------------------------------------- -- * Top Level Declarations -derivClause :: Maybe DerivStrategy -> [PredQ] -> DerivClauseQ+derivClause :: Quote m => Maybe DerivStrategy -> [m Pred] -> m DerivClause derivClause mds p = do p' <- cxt p return $ DerivClause mds p' -standaloneDerivWithStrategyD :: Maybe DerivStrategy -> CxtQ -> TypeQ -> DecQ+standaloneDerivWithStrategyD :: Quote m => Maybe DerivStrategy -> m Cxt -> m Type -> m Dec standaloneDerivWithStrategyD mds ctxt ty = do ctxt' <- ctxt ty' <- ty@@ -326,8 +326,8 @@ ------------------------------------------------------------------------------- -- * Tuple expressions -tupE :: [ExpQ] -> ExpQ-tupE es = do { es1 <- sequence es; return (TupE $ map Just es1)}+tupE :: Quote m => [m Exp] -> m Exp+tupE es = do { es1 <- sequenceA es; return (TupE $ map Just es1)} -unboxedTupE :: [ExpQ] -> ExpQ-unboxedTupE es = do { es1 <- sequence es; return (UnboxedTupE $ map Just es1)}+unboxedTupE :: Quote m => [m Exp] -> m Exp+unboxedTupE es = do { es1 <- sequenceA es; return (UnboxedTupE $ map Just es1)}
libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs view
@@ -16,7 +16,7 @@ import Language.Haskell.TH.Syntax hiding (Role, InjectivityAnn) import qualified Language.Haskell.TH.Syntax as TH-import Control.Monad( liftM, liftM2 )+import Control.Applicative(liftA, liftA2) import Data.Word( Word8 ) import Prelude @@ -31,6 +31,7 @@ type TExpQ a = Q (TExp a) type DecQ = Q Dec type DecsQ = Q [Dec]+type Decs = [Dec] -- Defined as it is more convenient to wire-in type ConQ = Q Con type TypeQ = Q Type type KindQ = Q Kind@@ -91,675 +92,675 @@ rationalL :: Rational -> Lit rationalL = RationalL -litP :: Lit -> PatQ-litP l = return (LitP l)+litP :: Quote m => Lit -> m Pat+litP l = pure (LitP l) -varP :: Name -> PatQ-varP v = return (VarP v)+varP :: Quote m => Name -> m Pat+varP v = pure (VarP v) -tupP :: [PatQ] -> PatQ-tupP ps = do { ps1 <- sequence ps; return (TupP ps1)}+tupP :: Quote m => [m Pat] -> m Pat+tupP ps = do { ps1 <- sequenceA ps; pure (TupP ps1)} -unboxedTupP :: [PatQ] -> PatQ-unboxedTupP ps = do { ps1 <- sequence ps; return (UnboxedTupP ps1)}+unboxedTupP :: Quote m => [m Pat] -> m Pat+unboxedTupP ps = do { ps1 <- sequenceA ps; pure (UnboxedTupP ps1)} -unboxedSumP :: PatQ -> SumAlt -> SumArity -> PatQ-unboxedSumP p alt arity = do { p1 <- p; return (UnboxedSumP p1 alt arity) }+unboxedSumP :: Quote m => m Pat -> SumAlt -> SumArity -> m Pat+unboxedSumP p alt arity = do { p1 <- p; pure (UnboxedSumP p1 alt arity) } -conP :: Name -> [PatQ] -> PatQ-conP n ps = do ps' <- sequence ps- return (ConP n ps')-infixP :: PatQ -> Name -> PatQ -> PatQ+conP :: Quote m => Name -> [m Pat] -> m Pat+conP n ps = do ps' <- sequenceA ps+ pure (ConP n ps')+infixP :: Quote m => m Pat -> Name -> m Pat -> m Pat infixP p1 n p2 = do p1' <- p1 p2' <- p2- return (InfixP p1' n p2')-uInfixP :: PatQ -> Name -> PatQ -> PatQ+ pure (InfixP p1' n p2')+uInfixP :: Quote m => m Pat -> Name -> m Pat -> m Pat uInfixP p1 n p2 = do p1' <- p1 p2' <- p2- return (UInfixP p1' n p2')-parensP :: PatQ -> PatQ+ pure (UInfixP p1' n p2')+parensP :: Quote m => m Pat -> m Pat parensP p = do p' <- p- return (ParensP p')+ pure (ParensP p') -tildeP :: PatQ -> PatQ+tildeP :: Quote m => m Pat -> m Pat tildeP p = do p' <- p- return (TildeP p')-bangP :: PatQ -> PatQ+ pure (TildeP p')+bangP :: Quote m => m Pat -> m Pat bangP p = do p' <- p- return (BangP p')-asP :: Name -> PatQ -> PatQ+ pure (BangP p')+asP :: Quote m => Name -> m Pat -> m Pat asP n p = do p' <- p- return (AsP n p')-wildP :: PatQ-wildP = return WildP-recP :: Name -> [FieldPatQ] -> PatQ-recP n fps = do fps' <- sequence fps- return (RecP n fps')-listP :: [PatQ] -> PatQ-listP ps = do ps' <- sequence ps- return (ListP ps')-sigP :: PatQ -> TypeQ -> PatQ+ pure (AsP n p')+wildP :: Quote m => m Pat+wildP = pure WildP+recP :: Quote m => Name -> [m FieldPat] -> m Pat+recP n fps = do fps' <- sequenceA fps+ pure (RecP n fps')+listP :: Quote m => [m Pat] -> m Pat+listP ps = do ps' <- sequenceA ps+ pure (ListP ps')+sigP :: Quote m => m Pat -> m Type -> m Pat sigP p t = do p' <- p t' <- t- return (SigP p' t')-viewP :: ExpQ -> PatQ -> PatQ+ pure (SigP p' t')+viewP :: Quote m => m Exp -> m Pat -> m Pat viewP e p = do e' <- e p' <- p- return (ViewP e' p')+ pure (ViewP e' p') -fieldPat :: Name -> PatQ -> FieldPatQ+fieldPat :: Quote m => Name -> m Pat -> m FieldPat fieldPat n p = do p' <- p- return (n, p')+ pure (n, p') ------------------------------------------------------------------------------- -- * Stmt -bindS :: PatQ -> ExpQ -> StmtQ-bindS p e = liftM2 BindS p e+bindS :: Quote m => m Pat -> m Exp -> m Stmt+bindS p e = liftA2 BindS p e -letS :: [DecQ] -> StmtQ-letS ds = do { ds1 <- sequence ds; return (LetS ds1) }+letS :: Quote m => [m Dec] -> m Stmt+letS ds = do { ds1 <- sequenceA ds; pure (LetS ds1) } -noBindS :: ExpQ -> StmtQ-noBindS e = do { e1 <- e; return (NoBindS e1) }+noBindS :: Quote m => m Exp -> m Stmt+noBindS e = do { e1 <- e; pure (NoBindS e1) } -parS :: [[StmtQ]] -> StmtQ-parS sss = do { sss1 <- mapM sequence sss; return (ParS sss1) }+parS :: Quote m => [[m Stmt]] -> m Stmt+parS sss = do { sss1 <- traverse sequenceA sss; pure (ParS sss1) } -recS :: [StmtQ] -> StmtQ-recS ss = do { ss1 <- sequence ss; return (RecS ss1) }+recS :: Quote m => [m Stmt] -> m Stmt+recS ss = do { ss1 <- sequenceA ss; pure (RecS ss1) } ------------------------------------------------------------------------------- -- * Range -fromR :: ExpQ -> RangeQ-fromR x = do { a <- x; return (FromR a) }+fromR :: Quote m => m Exp -> m Range+fromR x = do { a <- x; pure (FromR a) } -fromThenR :: ExpQ -> ExpQ -> RangeQ-fromThenR x y = do { a <- x; b <- y; return (FromThenR a b) }+fromThenR :: Quote m => m Exp -> m Exp -> m Range+fromThenR x y = do { a <- x; b <- y; pure (FromThenR a b) } -fromToR :: ExpQ -> ExpQ -> RangeQ-fromToR x y = do { a <- x; b <- y; return (FromToR a b) }+fromToR :: Quote m => m Exp -> m Exp -> m Range+fromToR x y = do { a <- x; b <- y; pure (FromToR a b) } -fromThenToR :: ExpQ -> ExpQ -> ExpQ -> RangeQ+fromThenToR :: Quote m => m Exp -> m Exp -> m Exp -> m Range fromThenToR x y z = do { a <- x; b <- y; c <- z;- return (FromThenToR a b c) }+ pure (FromThenToR a b c) } ------------------------------------------------------------------------------- -- * Body -normalB :: ExpQ -> BodyQ-normalB e = do { e1 <- e; return (NormalB e1) }+normalB :: Quote m => m Exp -> m Body+normalB e = do { e1 <- e; pure (NormalB e1) } -guardedB :: [Q (Guard,Exp)] -> BodyQ-guardedB ges = do { ges' <- sequence ges; return (GuardedB ges') }+guardedB :: Quote m => [m (Guard,Exp)] -> m Body+guardedB ges = do { ges' <- sequenceA ges; pure (GuardedB ges') } ------------------------------------------------------------------------------- -- * Guard -normalG :: ExpQ -> GuardQ-normalG e = do { e1 <- e; return (NormalG e1) }+normalG :: Quote m => m Exp -> m Guard+normalG e = do { e1 <- e; pure (NormalG e1) } -normalGE :: ExpQ -> ExpQ -> Q (Guard, Exp)-normalGE g e = do { g1 <- g; e1 <- e; return (NormalG g1, e1) }+normalGE :: Quote m => m Exp -> m Exp -> m (Guard, Exp)+normalGE g e = do { g1 <- g; e1 <- e; pure (NormalG g1, e1) } -patG :: [StmtQ] -> GuardQ-patG ss = do { ss' <- sequence ss; return (PatG ss') }+patG :: Quote m => [m Stmt] -> m Guard+patG ss = do { ss' <- sequenceA ss; pure (PatG ss') } -patGE :: [StmtQ] -> ExpQ -> Q (Guard, Exp)-patGE ss e = do { ss' <- sequence ss;+patGE :: Quote m => [m Stmt] -> m Exp -> m (Guard, Exp)+patGE ss e = do { ss' <- sequenceA ss; e' <- e;- return (PatG ss', e') }+ pure (PatG ss', e') } ------------------------------------------------------------------------------- -- * Match and Clause -- | Use with 'caseE'-match :: PatQ -> BodyQ -> [DecQ] -> MatchQ+match :: Quote m => m Pat -> m Body -> [m Dec] -> m Match match p rhs ds = do { p' <- p; r' <- rhs;- ds' <- sequence ds;- return (Match p' r' ds') }+ ds' <- sequenceA ds;+ pure (Match p' r' ds') } -- | Use with 'funD'-clause :: [PatQ] -> BodyQ -> [DecQ] -> ClauseQ-clause ps r ds = do { ps' <- sequence ps;+clause :: Quote m => [m Pat] -> m Body -> [m Dec] -> m Clause+clause ps r ds = do { ps' <- sequenceA ps; r' <- r;- ds' <- sequence ds;- return (Clause ps' r' ds') }+ ds' <- sequenceA ds;+ pure (Clause ps' r' ds') } --------------------------------------------------------------------------- -- * Exp -- | Dynamically binding a variable (unhygenic)-dyn :: String -> ExpQ-dyn s = return (VarE (mkName s))+dyn :: Quote m => String -> m Exp+dyn s = pure (VarE (mkName s)) -varE :: Name -> ExpQ-varE s = return (VarE s)+varE :: Quote m => Name -> m Exp+varE s = pure (VarE s) -conE :: Name -> ExpQ-conE s = return (ConE s)+conE :: Quote m => Name -> m Exp+conE s = pure (ConE s) -litE :: Lit -> ExpQ-litE c = return (LitE c)+litE :: Quote m => Lit -> m Exp+litE c = pure (LitE c) -appE :: ExpQ -> ExpQ -> ExpQ-appE x y = do { a <- x; b <- y; return (AppE a b)}+appE :: Quote m => m Exp -> m Exp -> m Exp+appE x y = do { a <- x; b <- y; pure (AppE a b)} -appTypeE :: ExpQ -> TypeQ -> ExpQ-appTypeE x t = do { a <- x; s <- t; return (AppTypeE a s) }+appTypeE :: Quote m => m Exp -> m Type -> m Exp+appTypeE x t = do { a <- x; s <- t; pure (AppTypeE a s) } -parensE :: ExpQ -> ExpQ-parensE x = do { x' <- x; return (ParensE x') }+parensE :: Quote m => m Exp -> m Exp+parensE x = do { x' <- x; pure (ParensE x') } -uInfixE :: ExpQ -> ExpQ -> ExpQ -> ExpQ+uInfixE :: Quote m => m Exp -> m Exp -> m Exp -> m Exp uInfixE x s y = do { x' <- x; s' <- s; y' <- y;- return (UInfixE x' s' y') }+ pure (UInfixE x' s' y') } -infixE :: Maybe ExpQ -> ExpQ -> Maybe ExpQ -> ExpQ+infixE :: Quote m => Maybe (m Exp) -> m Exp -> Maybe (m Exp) -> m Exp infixE (Just x) s (Just y) = do { a <- x; s' <- s; b <- y;- return (InfixE (Just a) s' (Just b))}+ pure (InfixE (Just a) s' (Just b))} infixE Nothing s (Just y) = do { s' <- s; b <- y;- return (InfixE Nothing s' (Just b))}+ pure (InfixE Nothing s' (Just b))} infixE (Just x) s Nothing = do { a <- x; s' <- s;- return (InfixE (Just a) s' Nothing)}-infixE Nothing s Nothing = do { s' <- s; return (InfixE Nothing s' Nothing) }+ pure (InfixE (Just a) s' Nothing)}+infixE Nothing s Nothing = do { s' <- s; pure (InfixE Nothing s' Nothing) } -infixApp :: ExpQ -> ExpQ -> ExpQ -> ExpQ+infixApp :: Quote m => m Exp -> m Exp -> m Exp -> m Exp infixApp x y z = infixE (Just x) y (Just z)-sectionL :: ExpQ -> ExpQ -> ExpQ+sectionL :: Quote m => m Exp -> m Exp -> m Exp sectionL x y = infixE (Just x) y Nothing-sectionR :: ExpQ -> ExpQ -> ExpQ+sectionR :: Quote m => m Exp -> m Exp -> m Exp sectionR x y = infixE Nothing x (Just y) -lamE :: [PatQ] -> ExpQ -> ExpQ-lamE ps e = do ps' <- sequence ps+lamE :: Quote m => [m Pat] -> m Exp -> m Exp+lamE ps e = do ps' <- sequenceA ps e' <- e- return (LamE ps' e')+ pure (LamE ps' e') -- | Single-arg lambda-lam1E :: PatQ -> ExpQ -> ExpQ+lam1E :: Quote m => m Pat -> m Exp -> m Exp lam1E p e = lamE [p] e -lamCaseE :: [MatchQ] -> ExpQ-lamCaseE ms = sequence ms >>= return . LamCaseE+lamCaseE :: Quote m => [m Match] -> m Exp+lamCaseE ms = LamCaseE <$> sequenceA ms -tupE :: [Maybe ExpQ] -> ExpQ-tupE es = do { es1 <- traverse sequence es; return (TupE es1)}+tupE :: Quote m => [Maybe (m Exp)] -> m Exp+tupE es = do { es1 <- traverse sequenceA es; pure (TupE es1)} -unboxedTupE :: [Maybe ExpQ] -> ExpQ-unboxedTupE es = do { es1 <- traverse sequence es; return (UnboxedTupE es1)}+unboxedTupE :: Quote m => [Maybe (m Exp)] -> m Exp+unboxedTupE es = do { es1 <- traverse sequenceA es; pure (UnboxedTupE es1)} -unboxedSumE :: ExpQ -> SumAlt -> SumArity -> ExpQ-unboxedSumE e alt arity = do { e1 <- e; return (UnboxedSumE e1 alt arity) }+unboxedSumE :: Quote m => m Exp -> SumAlt -> SumArity -> m Exp+unboxedSumE e alt arity = do { e1 <- e; pure (UnboxedSumE e1 alt arity) } -condE :: ExpQ -> ExpQ -> ExpQ -> ExpQ-condE x y z = do { a <- x; b <- y; c <- z; return (CondE a b c)}+condE :: Quote m => m Exp -> m Exp -> m Exp -> m Exp+condE x y z = do { a <- x; b <- y; c <- z; pure (CondE a b c)} -multiIfE :: [Q (Guard, Exp)] -> ExpQ-multiIfE alts = sequence alts >>= return . MultiIfE+multiIfE :: Quote m => [m (Guard, Exp)] -> m Exp+multiIfE alts = MultiIfE <$> sequenceA alts -letE :: [DecQ] -> ExpQ -> ExpQ-letE ds e = do { ds2 <- sequence ds; e2 <- e; return (LetE ds2 e2) }+letE :: Quote m => [m Dec] -> m Exp -> m Exp+letE ds e = do { ds2 <- sequenceA ds; e2 <- e; pure (LetE ds2 e2) } -caseE :: ExpQ -> [MatchQ] -> ExpQ-caseE e ms = do { e1 <- e; ms1 <- sequence ms; return (CaseE e1 ms1) }+caseE :: Quote m => m Exp -> [m Match] -> m Exp+caseE e ms = do { e1 <- e; ms1 <- sequenceA ms; pure (CaseE e1 ms1) } -doE :: [StmtQ] -> ExpQ-doE ss = do { ss1 <- sequence ss; return (DoE ss1) }+doE :: Quote m => [m Stmt] -> m Exp+doE ss = do { ss1 <- sequenceA ss; pure (DoE ss1) } -mdoE :: [StmtQ] -> ExpQ-mdoE ss = do { ss1 <- sequence ss; return (MDoE ss1) }+mdoE :: Quote m => [m Stmt] -> m Exp+mdoE ss = do { ss1 <- sequenceA ss; pure (MDoE ss1) } -compE :: [StmtQ] -> ExpQ-compE ss = do { ss1 <- sequence ss; return (CompE ss1) }+compE :: Quote m => [m Stmt] -> m Exp+compE ss = do { ss1 <- sequenceA ss; pure (CompE ss1) } -arithSeqE :: RangeQ -> ExpQ-arithSeqE r = do { r' <- r; return (ArithSeqE r') }+arithSeqE :: Quote m => m Range -> m Exp+arithSeqE r = do { r' <- r; pure (ArithSeqE r') } -listE :: [ExpQ] -> ExpQ-listE es = do { es1 <- sequence es; return (ListE es1) }+listE :: Quote m => [m Exp] -> m Exp+listE es = do { es1 <- sequenceA es; pure (ListE es1) } -sigE :: ExpQ -> TypeQ -> ExpQ-sigE e t = do { e1 <- e; t1 <- t; return (SigE e1 t1) }+sigE :: Quote m => m Exp -> m Type -> m Exp+sigE e t = do { e1 <- e; t1 <- t; pure (SigE e1 t1) } -recConE :: Name -> [Q (Name,Exp)] -> ExpQ-recConE c fs = do { flds <- sequence fs; return (RecConE c flds) }+recConE :: Quote m => Name -> [m (Name,Exp)] -> m Exp+recConE c fs = do { flds <- sequenceA fs; pure (RecConE c flds) } -recUpdE :: ExpQ -> [Q (Name,Exp)] -> ExpQ-recUpdE e fs = do { e1 <- e; flds <- sequence fs; return (RecUpdE e1 flds) }+recUpdE :: Quote m => m Exp -> [m (Name,Exp)] -> m Exp+recUpdE e fs = do { e1 <- e; flds <- sequenceA fs; pure (RecUpdE e1 flds) } -stringE :: String -> ExpQ+stringE :: Quote m => String -> m Exp stringE = litE . stringL -fieldExp :: Name -> ExpQ -> Q (Name, Exp)-fieldExp s e = do { e' <- e; return (s,e') }+fieldExp :: Quote m => Name -> m Exp -> m (Name, Exp)+fieldExp s e = do { e' <- e; pure (s,e') } -- | @staticE x = [| static x |]@-staticE :: ExpQ -> ExpQ+staticE :: Quote m => m Exp -> m Exp staticE = fmap StaticE -unboundVarE :: Name -> ExpQ-unboundVarE s = return (UnboundVarE s)+unboundVarE :: Quote m => Name -> m Exp+unboundVarE s = pure (UnboundVarE s) -labelE :: String -> ExpQ-labelE s = return (LabelE s)+labelE :: Quote m => String -> m Exp+labelE s = pure (LabelE s) -implicitParamVarE :: String -> ExpQ-implicitParamVarE n = return (ImplicitParamVarE n)+implicitParamVarE :: Quote m => String -> m Exp+implicitParamVarE n = pure (ImplicitParamVarE n) -- ** 'arithSeqE' Shortcuts-fromE :: ExpQ -> ExpQ-fromE x = do { a <- x; return (ArithSeqE (FromR a)) }+fromE :: Quote m => m Exp -> m Exp+fromE x = do { a <- x; pure (ArithSeqE (FromR a)) } -fromThenE :: ExpQ -> ExpQ -> ExpQ-fromThenE x y = do { a <- x; b <- y; return (ArithSeqE (FromThenR a b)) }+fromThenE :: Quote m => m Exp -> m Exp -> m Exp+fromThenE x y = do { a <- x; b <- y; pure (ArithSeqE (FromThenR a b)) } -fromToE :: ExpQ -> ExpQ -> ExpQ-fromToE x y = do { a <- x; b <- y; return (ArithSeqE (FromToR a b)) }+fromToE :: Quote m => m Exp -> m Exp -> m Exp+fromToE x y = do { a <- x; b <- y; pure (ArithSeqE (FromToR a b)) } -fromThenToE :: ExpQ -> ExpQ -> ExpQ -> ExpQ+fromThenToE :: Quote m => m Exp -> m Exp -> m Exp -> m Exp fromThenToE x y z = do { a <- x; b <- y; c <- z;- return (ArithSeqE (FromThenToR a b c)) }+ pure (ArithSeqE (FromThenToR a b c)) } ------------------------------------------------------------------------------- -- * Dec -valD :: PatQ -> BodyQ -> [DecQ] -> DecQ+valD :: Quote m => m Pat -> m Body -> [m Dec] -> m Dec valD p b ds = do { p' <- p- ; ds' <- sequence ds+ ; ds' <- sequenceA ds ; b' <- b- ; return (ValD p' b' ds')+ ; pure (ValD p' b' ds') } -funD :: Name -> [ClauseQ] -> DecQ+funD :: Quote m => Name -> [m Clause] -> m Dec funD nm cs =- do { cs1 <- sequence cs- ; return (FunD nm cs1)+ do { cs1 <- sequenceA cs+ ; pure (FunD nm cs1) } -tySynD :: Name -> [TyVarBndrQ] -> TypeQ -> DecQ+tySynD :: Quote m => Name -> [m TyVarBndr] -> m Type -> m Dec tySynD tc tvs rhs = do { tvs1 <- sequenceA tvs ; rhs1 <- rhs- ; return (TySynD tc tvs1 rhs1)+ ; pure (TySynD tc tvs1 rhs1) } -dataD :: CxtQ -> Name -> [TyVarBndrQ] -> Maybe KindQ -> [ConQ]- -> [DerivClauseQ] -> DecQ+dataD :: Quote m => m Cxt -> Name -> [m TyVarBndr] -> Maybe (m Kind) -> [m Con]+ -> [m DerivClause] -> m Dec dataD ctxt tc tvs ksig cons derivs = do ctxt1 <- ctxt tvs1 <- sequenceA tvs ksig1 <- sequenceA ksig- cons1 <- sequence cons- derivs1 <- sequence derivs- return (DataD ctxt1 tc tvs1 ksig1 cons1 derivs1)+ cons1 <- sequenceA cons+ derivs1 <- sequenceA derivs+ pure (DataD ctxt1 tc tvs1 ksig1 cons1 derivs1) -newtypeD :: CxtQ -> Name -> [TyVarBndrQ] -> Maybe KindQ -> ConQ- -> [DerivClauseQ] -> DecQ+newtypeD :: Quote m => m Cxt -> Name -> [m TyVarBndr] -> Maybe (m Kind) -> m Con+ -> [m DerivClause] -> m Dec newtypeD ctxt tc tvs ksig con derivs = do ctxt1 <- ctxt tvs1 <- sequenceA tvs ksig1 <- sequenceA ksig con1 <- con- derivs1 <- sequence derivs- return (NewtypeD ctxt1 tc tvs1 ksig1 con1 derivs1)+ derivs1 <- sequenceA derivs+ pure (NewtypeD ctxt1 tc tvs1 ksig1 con1 derivs1) -classD :: CxtQ -> Name -> [TyVarBndrQ] -> [FunDep] -> [DecQ] -> DecQ+classD :: Quote m => m Cxt -> Name -> [m TyVarBndr] -> [FunDep] -> [m Dec] -> m Dec classD ctxt cls tvs fds decs = do tvs1 <- sequenceA tvs decs1 <- sequenceA decs ctxt1 <- ctxt- return $ ClassD ctxt1 cls tvs1 fds decs1+ pure $ ClassD ctxt1 cls tvs1 fds decs1 -instanceD :: CxtQ -> TypeQ -> [DecQ] -> DecQ+instanceD :: Quote m => m Cxt -> m Type -> [m Dec] -> m Dec instanceD = instanceWithOverlapD Nothing -instanceWithOverlapD :: Maybe Overlap -> CxtQ -> TypeQ -> [DecQ] -> DecQ+instanceWithOverlapD :: Quote m => Maybe Overlap -> m Cxt -> m Type -> [m Dec] -> m Dec instanceWithOverlapD o ctxt ty decs = do ctxt1 <- ctxt- decs1 <- sequence decs+ decs1 <- sequenceA decs ty1 <- ty- return $ InstanceD o ctxt1 ty1 decs1+ pure $ InstanceD o ctxt1 ty1 decs1 -sigD :: Name -> TypeQ -> DecQ-sigD fun ty = liftM (SigD fun) $ ty+sigD :: Quote m => Name -> m Type -> m Dec+sigD fun ty = liftA (SigD fun) $ ty -kiSigD :: Name -> KindQ -> DecQ-kiSigD fun ki = liftM (KiSigD fun) $ ki+kiSigD :: Quote m => Name -> m Kind -> m Dec+kiSigD fun ki = liftA (KiSigD fun) $ ki -forImpD :: Callconv -> Safety -> String -> Name -> TypeQ -> DecQ+forImpD :: Quote m => Callconv -> Safety -> String -> Name -> m Type -> m Dec forImpD cc s str n ty = do ty' <- ty- return $ ForeignD (ImportF cc s str n ty')+ pure $ ForeignD (ImportF cc s str n ty') -infixLD :: Int -> Name -> DecQ-infixLD prec nm = return (InfixD (Fixity prec InfixL) nm)+infixLD :: Quote m => Int -> Name -> m Dec+infixLD prec nm = pure (InfixD (Fixity prec InfixL) nm) -infixRD :: Int -> Name -> DecQ-infixRD prec nm = return (InfixD (Fixity prec InfixR) nm)+infixRD :: Quote m => Int -> Name -> m Dec+infixRD prec nm = pure (InfixD (Fixity prec InfixR) nm) -infixND :: Int -> Name -> DecQ-infixND prec nm = return (InfixD (Fixity prec InfixN) nm)+infixND :: Quote m => Int -> Name -> m Dec+infixND prec nm = pure (InfixD (Fixity prec InfixN) nm) -pragInlD :: Name -> Inline -> RuleMatch -> Phases -> DecQ+pragInlD :: Quote m => Name -> Inline -> RuleMatch -> Phases -> m Dec pragInlD name inline rm phases- = return $ PragmaD $ InlineP name inline rm phases+ = pure $ PragmaD $ InlineP name inline rm phases -pragSpecD :: Name -> TypeQ -> Phases -> DecQ+pragSpecD :: Quote m => Name -> m Type -> Phases -> m Dec pragSpecD n ty phases = do ty1 <- ty- return $ PragmaD $ SpecialiseP n ty1 Nothing phases+ pure $ PragmaD $ SpecialiseP n ty1 Nothing phases -pragSpecInlD :: Name -> TypeQ -> Inline -> Phases -> DecQ+pragSpecInlD :: Quote m => Name -> m Type -> Inline -> Phases -> m Dec pragSpecInlD n ty inline phases = do ty1 <- ty- return $ PragmaD $ SpecialiseP n ty1 (Just inline) phases+ pure $ PragmaD $ SpecialiseP n ty1 (Just inline) phases -pragSpecInstD :: TypeQ -> DecQ+pragSpecInstD :: Quote m => m Type -> m Dec pragSpecInstD ty = do ty1 <- ty- return $ PragmaD $ SpecialiseInstP ty1+ pure $ PragmaD $ SpecialiseInstP ty1 -pragRuleD :: String -> Maybe [TyVarBndrQ] -> [RuleBndrQ] -> ExpQ -> ExpQ- -> Phases -> DecQ+pragRuleD :: Quote m => String -> Maybe [m TyVarBndr] -> [m RuleBndr] -> m Exp -> m Exp+ -> Phases -> m Dec pragRuleD n ty_bndrs tm_bndrs lhs rhs phases = do- ty_bndrs1 <- traverse sequence ty_bndrs- tm_bndrs1 <- sequence tm_bndrs+ ty_bndrs1 <- traverse sequenceA ty_bndrs+ tm_bndrs1 <- sequenceA tm_bndrs lhs1 <- lhs rhs1 <- rhs- return $ PragmaD $ RuleP n ty_bndrs1 tm_bndrs1 lhs1 rhs1 phases+ pure $ PragmaD $ RuleP n ty_bndrs1 tm_bndrs1 lhs1 rhs1 phases -pragAnnD :: AnnTarget -> ExpQ -> DecQ+pragAnnD :: Quote m => AnnTarget -> m Exp -> m Dec pragAnnD target expr = do exp1 <- expr- return $ PragmaD $ AnnP target exp1+ pure $ PragmaD $ AnnP target exp1 -pragLineD :: Int -> String -> DecQ-pragLineD line file = return $ PragmaD $ LineP line file+pragLineD :: Quote m => Int -> String -> m Dec+pragLineD line file = pure $ PragmaD $ LineP line file -pragCompleteD :: [Name] -> Maybe Name -> DecQ-pragCompleteD cls mty = return $ PragmaD $ CompleteP cls mty+pragCompleteD :: Quote m => [Name] -> Maybe Name -> m Dec+pragCompleteD cls mty = pure $ PragmaD $ CompleteP cls mty -dataInstD :: CxtQ -> (Maybe [TyVarBndrQ]) -> TypeQ -> Maybe KindQ -> [ConQ]- -> [DerivClauseQ] -> DecQ+dataInstD :: Quote m => m Cxt -> (Maybe [m TyVarBndr]) -> m Type -> Maybe (m Kind) -> [m Con]+ -> [m DerivClause] -> m Dec dataInstD ctxt mb_bndrs ty ksig cons derivs = do ctxt1 <- ctxt- mb_bndrs1 <- traverse sequence mb_bndrs+ mb_bndrs1 <- traverse sequenceA mb_bndrs ty1 <- ty ksig1 <- sequenceA ksig cons1 <- sequenceA cons derivs1 <- sequenceA derivs- return (DataInstD ctxt1 mb_bndrs1 ty1 ksig1 cons1 derivs1)+ pure (DataInstD ctxt1 mb_bndrs1 ty1 ksig1 cons1 derivs1) -newtypeInstD :: CxtQ -> (Maybe [TyVarBndrQ]) -> TypeQ -> Maybe KindQ -> ConQ- -> [DerivClauseQ] -> DecQ+newtypeInstD :: Quote m => m Cxt -> (Maybe [m TyVarBndr]) -> m Type -> Maybe (m Kind) -> m Con+ -> [m DerivClause] -> m Dec newtypeInstD ctxt mb_bndrs ty ksig con derivs = do ctxt1 <- ctxt- mb_bndrs1 <- traverse sequence mb_bndrs+ mb_bndrs1 <- traverse sequenceA mb_bndrs ty1 <- ty ksig1 <- sequenceA ksig con1 <- con- derivs1 <- sequence derivs- return (NewtypeInstD ctxt1 mb_bndrs1 ty1 ksig1 con1 derivs1)+ derivs1 <- sequenceA derivs+ pure (NewtypeInstD ctxt1 mb_bndrs1 ty1 ksig1 con1 derivs1) -tySynInstD :: TySynEqnQ -> DecQ+tySynInstD :: Quote m => m TySynEqn -> m Dec tySynInstD eqn = do eqn1 <- eqn- return (TySynInstD eqn1)+ pure (TySynInstD eqn1) -dataFamilyD :: Name -> [TyVarBndrQ] -> Maybe KindQ -> DecQ+dataFamilyD :: Quote m => Name -> [m TyVarBndr] -> Maybe (m Kind) -> m Dec dataFamilyD tc tvs kind = do tvs' <- sequenceA tvs kind' <- sequenceA kind- return $ DataFamilyD tc tvs' kind'+ pure $ DataFamilyD tc tvs' kind' -openTypeFamilyD :: Name -> [TyVarBndrQ] -> FamilyResultSigQ- -> Maybe InjectivityAnn -> DecQ+openTypeFamilyD :: Quote m => Name -> [m TyVarBndr] -> m FamilyResultSig+ -> Maybe InjectivityAnn -> m Dec openTypeFamilyD tc tvs res inj = do tvs' <- sequenceA tvs res' <- res- return $ OpenTypeFamilyD (TypeFamilyHead tc tvs' res' inj)+ pure $ OpenTypeFamilyD (TypeFamilyHead tc tvs' res' inj) -closedTypeFamilyD :: Name -> [TyVarBndrQ] -> FamilyResultSigQ- -> Maybe InjectivityAnn -> [TySynEqnQ] -> DecQ+closedTypeFamilyD :: Quote m => Name -> [m TyVarBndr] -> m FamilyResultSig+ -> Maybe InjectivityAnn -> [m TySynEqn] -> m Dec closedTypeFamilyD tc tvs result injectivity eqns = do tvs1 <- sequenceA tvs result1 <- result eqns1 <- sequenceA eqns- return (ClosedTypeFamilyD (TypeFamilyHead tc tvs1 result1 injectivity) eqns1)+ pure (ClosedTypeFamilyD (TypeFamilyHead tc tvs1 result1 injectivity) eqns1) -roleAnnotD :: Name -> [Role] -> DecQ-roleAnnotD name roles = return $ RoleAnnotD name roles+roleAnnotD :: Quote m => Name -> [Role] -> m Dec+roleAnnotD name roles = pure $ RoleAnnotD name roles -standaloneDerivD :: CxtQ -> TypeQ -> DecQ+standaloneDerivD :: Quote m => m Cxt -> m Type -> m Dec standaloneDerivD = standaloneDerivWithStrategyD Nothing -standaloneDerivWithStrategyD :: Maybe DerivStrategyQ -> CxtQ -> TypeQ -> DecQ+standaloneDerivWithStrategyD :: Quote m => Maybe (m DerivStrategy) -> m Cxt -> m Type -> m Dec standaloneDerivWithStrategyD mdsq ctxtq tyq = do mds <- sequenceA mdsq ctxt <- ctxtq ty <- tyq- return $ StandaloneDerivD mds ctxt ty+ pure $ StandaloneDerivD mds ctxt ty -defaultSigD :: Name -> TypeQ -> DecQ+defaultSigD :: Quote m => Name -> m Type -> m Dec defaultSigD n tyq = do ty <- tyq- return $ DefaultSigD n ty+ pure $ DefaultSigD n ty -- | Pattern synonym declaration-patSynD :: Name -> PatSynArgsQ -> PatSynDirQ -> PatQ -> DecQ+patSynD :: Quote m => Name -> m PatSynArgs -> m PatSynDir -> m Pat -> m Dec patSynD name args dir pat = do args' <- args dir' <- dir pat' <- pat- return (PatSynD name args' dir' pat')+ pure (PatSynD name args' dir' pat') -- | Pattern synonym type signature-patSynSigD :: Name -> TypeQ -> DecQ+patSynSigD :: Quote m => Name -> m Type -> m Dec patSynSigD nm ty = do ty' <- ty- return $ PatSynSigD nm ty'+ pure $ PatSynSigD nm ty' -- | Implicit parameter binding declaration. Can only be used in let -- and where clauses which consist entirely of implicit bindings.-implicitParamBindD :: String -> ExpQ -> DecQ+implicitParamBindD :: Quote m => String -> m Exp -> m Dec implicitParamBindD n e = do e' <- e- return $ ImplicitParamBindD n e'+ pure $ ImplicitParamBindD n e' -tySynEqn :: (Maybe [TyVarBndrQ]) -> TypeQ -> TypeQ -> TySynEqnQ+tySynEqn :: Quote m => (Maybe [m TyVarBndr]) -> m Type -> m Type -> m TySynEqn tySynEqn mb_bndrs lhs rhs = do- mb_bndrs1 <- traverse sequence mb_bndrs+ mb_bndrs1 <- traverse sequenceA mb_bndrs lhs1 <- lhs rhs1 <- rhs- return (TySynEqn mb_bndrs1 lhs1 rhs1)+ pure (TySynEqn mb_bndrs1 lhs1 rhs1) -cxt :: [PredQ] -> CxtQ-cxt = sequence+cxt :: Quote m => [m Pred] -> m Cxt+cxt = sequenceA -derivClause :: Maybe DerivStrategyQ -> [PredQ] -> DerivClauseQ+derivClause :: Quote m => Maybe (m DerivStrategy) -> [m Pred] -> m DerivClause derivClause mds p = do mds' <- sequenceA mds p' <- cxt p- return $ DerivClause mds' p'+ pure $ DerivClause mds' p' -stockStrategy :: DerivStrategyQ+stockStrategy :: Quote m => m DerivStrategy stockStrategy = pure StockStrategy -anyclassStrategy :: DerivStrategyQ+anyclassStrategy :: Quote m => m DerivStrategy anyclassStrategy = pure AnyclassStrategy -newtypeStrategy :: DerivStrategyQ+newtypeStrategy :: Quote m => m DerivStrategy newtypeStrategy = pure NewtypeStrategy -viaStrategy :: TypeQ -> DerivStrategyQ+viaStrategy :: Quote m => m Type -> m DerivStrategy viaStrategy = fmap ViaStrategy -normalC :: Name -> [BangTypeQ] -> ConQ-normalC con strtys = liftM (NormalC con) $ sequence strtys+normalC :: Quote m => Name -> [m BangType] -> m Con+normalC con strtys = liftA (NormalC con) $ sequenceA strtys -recC :: Name -> [VarBangTypeQ] -> ConQ-recC con varstrtys = liftM (RecC con) $ sequence varstrtys+recC :: Quote m => Name -> [m VarBangType] -> m Con+recC con varstrtys = liftA (RecC con) $ sequenceA varstrtys -infixC :: Q (Bang, Type) -> Name -> Q (Bang, Type) -> ConQ+infixC :: Quote m => m (Bang, Type) -> Name -> m (Bang, Type) -> m Con infixC st1 con st2 = do st1' <- st1 st2' <- st2- return $ InfixC st1' con st2'+ pure $ InfixC st1' con st2' -forallC :: [TyVarBndrQ] -> CxtQ -> ConQ -> ConQ+forallC :: Quote m => [m TyVarBndr] -> m Cxt -> m Con -> m Con forallC ns ctxt con = do ns' <- sequenceA ns ctxt' <- ctxt con' <- con pure $ ForallC ns' ctxt' con' -gadtC :: [Name] -> [StrictTypeQ] -> TypeQ -> ConQ-gadtC cons strtys ty = liftM2 (GadtC cons) (sequence strtys) ty+gadtC :: Quote m => [Name] -> [m StrictType] -> m Type -> m Con+gadtC cons strtys ty = liftA2 (GadtC cons) (sequenceA strtys) ty -recGadtC :: [Name] -> [VarStrictTypeQ] -> TypeQ -> ConQ-recGadtC cons varstrtys ty = liftM2 (RecGadtC cons) (sequence varstrtys) ty+recGadtC :: Quote m => [Name] -> [m VarStrictType] -> m Type -> m Con+recGadtC cons varstrtys ty = liftA2 (RecGadtC cons) (sequenceA varstrtys) ty ------------------------------------------------------------------------------- -- * Type -forallT :: [TyVarBndrQ] -> CxtQ -> TypeQ -> TypeQ+forallT :: Quote m => [m TyVarBndr] -> m Cxt -> m Type -> m Type forallT tvars ctxt ty = do tvars1 <- sequenceA tvars ctxt1 <- ctxt ty1 <- ty- return $ ForallT tvars1 ctxt1 ty1+ pure $ ForallT tvars1 ctxt1 ty1 -forallVisT :: [TyVarBndrQ] -> TypeQ -> TypeQ+forallVisT :: Quote m => [m TyVarBndr] -> m Type -> m Type forallVisT tvars ty = ForallVisT <$> sequenceA tvars <*> ty -varT :: Name -> TypeQ-varT = return . VarT+varT :: Quote m => Name -> m Type+varT = pure . VarT -conT :: Name -> TypeQ-conT = return . ConT+conT :: Quote m => Name -> m Type+conT = pure . ConT -infixT :: TypeQ -> Name -> TypeQ -> TypeQ+infixT :: Quote m => m Type -> Name -> m Type -> m Type infixT t1 n t2 = do t1' <- t1 t2' <- t2- return (InfixT t1' n t2')+ pure (InfixT t1' n t2') -uInfixT :: TypeQ -> Name -> TypeQ -> TypeQ+uInfixT :: Quote m => m Type -> Name -> m Type -> m Type uInfixT t1 n t2 = do t1' <- t1 t2' <- t2- return (UInfixT t1' n t2')+ pure (UInfixT t1' n t2') -parensT :: TypeQ -> TypeQ+parensT :: Quote m => m Type -> m Type parensT t = do t' <- t- return (ParensT t')+ pure (ParensT t') -appT :: TypeQ -> TypeQ -> TypeQ+appT :: Quote m => m Type -> m Type -> m Type appT t1 t2 = do t1' <- t1 t2' <- t2- return $ AppT t1' t2'+ pure $ AppT t1' t2' -appKindT :: TypeQ -> KindQ -> TypeQ+appKindT :: Quote m => m Type -> m Kind -> m Type appKindT ty ki = do ty' <- ty ki' <- ki- return $ AppKindT ty' ki'+ pure $ AppKindT ty' ki' -arrowT :: TypeQ-arrowT = return ArrowT+arrowT :: Quote m => m Type+arrowT = pure ArrowT -listT :: TypeQ-listT = return ListT+listT :: Quote m => m Type+listT = pure ListT -litT :: TyLitQ -> TypeQ+litT :: Quote m => m TyLit -> m Type litT l = fmap LitT l -tupleT :: Int -> TypeQ-tupleT i = return (TupleT i)+tupleT :: Quote m => Int -> m Type+tupleT i = pure (TupleT i) -unboxedTupleT :: Int -> TypeQ-unboxedTupleT i = return (UnboxedTupleT i)+unboxedTupleT :: Quote m => Int -> m Type+unboxedTupleT i = pure (UnboxedTupleT i) -unboxedSumT :: SumArity -> TypeQ-unboxedSumT arity = return (UnboxedSumT arity)+unboxedSumT :: Quote m => SumArity -> m Type+unboxedSumT arity = pure (UnboxedSumT arity) -sigT :: TypeQ -> KindQ -> TypeQ+sigT :: Quote m => m Type -> m Kind -> m Type sigT t k = do t' <- t k' <- k- return $ SigT t' k'+ pure $ SigT t' k' -equalityT :: TypeQ-equalityT = return EqualityT+equalityT :: Quote m => m Type+equalityT = pure EqualityT -wildCardT :: TypeQ-wildCardT = return WildCardT+wildCardT :: Quote m => m Type+wildCardT = pure WildCardT -implicitParamT :: String -> TypeQ -> TypeQ+implicitParamT :: Quote m => String -> m Type -> m Type implicitParamT n t = do t' <- t- return $ ImplicitParamT n t'+ pure $ ImplicitParamT n t' {-# DEPRECATED classP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please use 'conT' and 'appT'." #-}-classP :: Name -> [Q Type] -> Q Pred+classP :: Quote m => Name -> [m Type] -> m Pred classP cla tys = do- tysl <- sequence tys- return (foldl AppT (ConT cla) tysl)+ tysl <- sequenceA tys+ pure (foldl AppT (ConT cla) tysl) {-# DEPRECATED equalP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please see 'equalityT'." #-}-equalP :: TypeQ -> TypeQ -> PredQ+equalP :: Quote m => m Type -> m Type -> m Pred equalP tleft tright = do tleft1 <- tleft tright1 <- tright eqT <- equalityT- return (foldl AppT eqT [tleft1, tright1])+ pure (foldl AppT eqT [tleft1, tright1]) -promotedT :: Name -> TypeQ-promotedT = return . PromotedT+promotedT :: Quote m => Name -> m Type+promotedT = pure . PromotedT -promotedTupleT :: Int -> TypeQ-promotedTupleT i = return (PromotedTupleT i)+promotedTupleT :: Quote m => Int -> m Type+promotedTupleT i = pure (PromotedTupleT i) -promotedNilT :: TypeQ-promotedNilT = return PromotedNilT+promotedNilT :: Quote m => m Type+promotedNilT = pure PromotedNilT -promotedConsT :: TypeQ-promotedConsT = return PromotedConsT+promotedConsT :: Quote m => m Type+promotedConsT = pure PromotedConsT -noSourceUnpackedness, sourceNoUnpack, sourceUnpack :: SourceUnpackednessQ-noSourceUnpackedness = return NoSourceUnpackedness-sourceNoUnpack = return SourceNoUnpack-sourceUnpack = return SourceUnpack+noSourceUnpackedness, sourceNoUnpack, sourceUnpack :: Quote m => m SourceUnpackedness+noSourceUnpackedness = pure NoSourceUnpackedness+sourceNoUnpack = pure SourceNoUnpack+sourceUnpack = pure SourceUnpack -noSourceStrictness, sourceLazy, sourceStrict :: SourceStrictnessQ-noSourceStrictness = return NoSourceStrictness-sourceLazy = return SourceLazy-sourceStrict = return SourceStrict+noSourceStrictness, sourceLazy, sourceStrict :: Quote m => m SourceStrictness+noSourceStrictness = pure NoSourceStrictness+sourceLazy = pure SourceLazy+sourceStrict = pure SourceStrict {-# DEPRECATED isStrict ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ",@@ -770,49 +771,52 @@ {-# DEPRECATED unpacked ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ", "Example usage: 'bang sourceUnpack sourceStrict'"] #-}-isStrict, notStrict, unpacked :: Q Strict+isStrict, notStrict, unpacked :: Quote m => m Strict isStrict = bang noSourceUnpackedness sourceStrict notStrict = bang noSourceUnpackedness noSourceStrictness unpacked = bang sourceUnpack sourceStrict -bang :: SourceUnpackednessQ -> SourceStrictnessQ -> BangQ+bang :: Quote m => m SourceUnpackedness -> m SourceStrictness -> m Bang bang u s = do u' <- u s' <- s- return (Bang u' s')+ pure (Bang u' s') -bangType :: BangQ -> TypeQ -> BangTypeQ-bangType = liftM2 (,)+bangType :: Quote m => m Bang -> m Type -> m BangType+bangType = liftA2 (,) -varBangType :: Name -> BangTypeQ -> VarBangTypeQ-varBangType v bt = do (b, t) <- bt- return (v, b, t)+varBangType :: Quote m => Name -> m BangType -> m VarBangType+varBangType v bt = (\(b, t) -> (v, b, t)) <$> bt {-# DEPRECATED strictType "As of @template-haskell-2.11.0.0@, 'StrictType' has been replaced by 'BangType'. Please use 'bangType' instead." #-}-strictType :: Q Strict -> TypeQ -> StrictTypeQ+strictType :: Quote m => m Strict -> m Type -> m StrictType strictType = bangType {-# DEPRECATED varStrictType "As of @template-haskell-2.11.0.0@, 'VarStrictType' has been replaced by 'VarBangType'. Please use 'varBangType' instead." #-}-varStrictType :: Name -> StrictTypeQ -> VarStrictTypeQ+varStrictType :: Quote m => Name -> m StrictType -> m VarStrictType varStrictType = varBangType -- * Type Literals -numTyLit :: Integer -> TyLitQ-numTyLit n = if n >= 0 then return (NumTyLit n)- else fail ("Negative type-level number: " ++ show n)+-- MonadFail here complicates things (a lot) because it would mean we would+-- have to emit a MonadFail constraint during typechecking if there was any+-- chance the desugaring would use numTyLit, which in general is hard to+-- predict.+numTyLit :: Quote m => Integer -> m TyLit+numTyLit n = if n >= 0 then pure (NumTyLit n)+ else error ("Negative type-level number: " ++ show n) -strTyLit :: String -> TyLitQ-strTyLit s = return (StrTyLit s)+strTyLit :: Quote m => String -> m TyLit+strTyLit s = pure (StrTyLit s) ------------------------------------------------------------------------------- -- * Kind -plainTV :: Name -> TyVarBndrQ+plainTV :: Quote m => Name -> m TyVarBndr plainTV = pure . PlainTV -kindedTV :: Name -> KindQ -> TyVarBndrQ+kindedTV :: Quote m => Name -> m Kind -> m TyVarBndr kindedTV n = fmap (KindedTV n) varK :: Name -> Kind@@ -824,31 +828,31 @@ tupleK :: Int -> Kind tupleK = TupleT -arrowK :: Kind+arrowK :: Kind arrowK = ArrowT -listK :: Kind+listK :: Kind listK = ListT appK :: Kind -> Kind -> Kind appK = AppT -starK :: KindQ+starK :: Quote m => m Kind starK = pure StarT -constraintK :: KindQ+constraintK :: Quote m => m Kind constraintK = pure ConstraintT ------------------------------------------------------------------------------- -- * Type family result -noSig :: FamilyResultSigQ+noSig :: Quote m => m FamilyResultSig noSig = pure NoSig -kindSig :: KindQ -> FamilyResultSigQ+kindSig :: Quote m => m Kind -> m FamilyResultSig kindSig = fmap KindSig -tyVarSig :: TyVarBndrQ -> FamilyResultSigQ+tyVarSig :: Quote m => m TyVarBndr -> m FamilyResultSig tyVarSig = fmap TyVarSig -------------------------------------------------------------------------------@@ -887,23 +891,23 @@ ------------------------------------------------------------------------------- -- * FunDep -funDep :: [Name] -> [Name] -> FunDep+funDep :: [Name] -> [Name] -> FunDep funDep = FunDep ------------------------------------------------------------------------------- -- * RuleBndr-ruleVar :: Name -> RuleBndrQ-ruleVar = return . RuleVar+ruleVar :: Quote m => Name -> m RuleBndr+ruleVar = pure . RuleVar -typedRuleVar :: Name -> TypeQ -> RuleBndrQ-typedRuleVar n ty = ty >>= return . TypedRuleVar n+typedRuleVar :: Quote m => Name -> m Type -> m RuleBndr+typedRuleVar n ty = TypedRuleVar n <$> ty ------------------------------------------------------------------------------- -- * AnnTarget-valueAnnotation :: Name -> AnnTarget+valueAnnotation :: Name -> AnnTarget valueAnnotation = ValueAnnotation -typeAnnotation :: Name -> AnnTarget+typeAnnotation :: Name -> AnnTarget typeAnnotation = TypeAnnotation moduleAnnotation :: AnnTarget@@ -912,35 +916,35 @@ ------------------------------------------------------------------------------- -- * Pattern Synonyms (sub constructs) -unidir, implBidir :: PatSynDirQ-unidir = return Unidir-implBidir = return ImplBidir+unidir, implBidir :: Quote m => m PatSynDir+unidir = pure Unidir+implBidir = pure ImplBidir -explBidir :: [ClauseQ] -> PatSynDirQ+explBidir :: Quote m => [m Clause] -> m PatSynDir explBidir cls = do- cls' <- sequence cls- return (ExplBidir cls')+ cls' <- sequenceA cls+ pure (ExplBidir cls') -prefixPatSyn :: [Name] -> PatSynArgsQ-prefixPatSyn args = return $ PrefixPatSyn args+prefixPatSyn :: Quote m => [Name] -> m PatSynArgs+prefixPatSyn args = pure $ PrefixPatSyn args -recordPatSyn :: [Name] -> PatSynArgsQ-recordPatSyn sels = return $ RecordPatSyn sels+recordPatSyn :: Quote m => [Name] -> m PatSynArgs+recordPatSyn sels = pure $ RecordPatSyn sels -infixPatSyn :: Name -> Name -> PatSynArgsQ-infixPatSyn arg1 arg2 = return $ InfixPatSyn arg1 arg2+infixPatSyn :: Quote m => Name -> Name -> m PatSynArgs+infixPatSyn arg1 arg2 = pure $ InfixPatSyn arg1 arg2 -------------------------------------------------------------- -- * Useful helper function -appsE :: [ExpQ] -> ExpQ+appsE :: Quote m => [m Exp] -> m Exp appsE [] = error "appsE []" appsE [x] = x appsE (x:y:zs) = appsE ( (appE x y) : zs ) --- | Return the Module at the place of splicing. Can be used as an+-- | pure the Module at the place of splicing. Can be used as an -- input for 'reifyModule'. thisModule :: Q Module thisModule = do loc <- location- return $ Module (mkPkgName $ loc_package loc) (mkModName $ loc_module loc)+ pure $ Module (mkPkgName $ loc_package loc) (mkModName $ loc_module loc)
libraries/template-haskell/Language/Haskell/TH/Syntax.hs view
@@ -204,6 +204,67 @@ ----------------------------------------------------- --+-- The Quote class+--+-----------------------------------------------------++++-- | The 'Quote' class implements the minimal interface which is necessary for+-- desugaring quotations.+--+-- * The @Monad m@ superclass is needed to stitch together the different+-- AST fragments.+-- * 'newName' is used when desugaring binding structures such as lambdas+-- to generate fresh names.+--+-- Therefore the type of an untyped quotation in GHC is `Quote m => m Exp`+--+-- For many years the type of a quotation was fixed to be `Q Exp` but by+-- more precisely specifying the minimal interface it enables the `Exp` to+-- be extracted purely from the quotation without interacting with `Q`.+class Monad m => Quote m where+ {- |+ Generate a fresh name, which cannot be captured.++ For example, this:++ @f = $(do+ nm1 <- newName \"x\"+ let nm2 = 'mkName' \"x\"+ return ('LamE' ['VarP' nm1] (LamE [VarP nm2] ('VarE' nm1)))+ )@++ will produce the splice++ >f = \x0 -> \x -> x0++ In particular, the occurrence @VarE nm1@ refers to the binding @VarP nm1@,+ and is not captured by the binding @VarP nm2@.++ Although names generated by @newName@ cannot /be captured/, they can+ /capture/ other names. For example, this:++ >g = $(do+ > nm1 <- newName "x"+ > let nm2 = mkName "x"+ > return (LamE [VarP nm2] (LamE [VarP nm1] (VarE nm2)))+ > )++ will produce the splice++ >g = \x -> \x0 -> x0++ since the occurrence @VarE nm2@ is captured by the innermost binding+ of @x@, namely @VarP nm1@.+ -}+ newName :: String -> m Name++instance Quote Q where+ newName s = Q (qNewName s)++-----------------------------------------------------+-- -- The TExp type -- -----------------------------------------------------@@ -250,7 +311,7 @@ -- expression -- -- Levity-polymorphic since /template-haskell-2.16.0.0/.-unTypeQ :: forall (r :: RuntimeRep) (a :: TYPE r). Q (TExp a) -> Q Exp+unTypeQ :: forall (r :: RuntimeRep) (a :: TYPE r) m . Quote m => m (TExp a) -> m Exp unTypeQ m = do { TExp e <- m ; return e } @@ -260,7 +321,8 @@ -- really does have the type you claim it has. -- -- Levity-polymorphic since /template-haskell-2.16.0.0/.-unsafeTExpCoerce :: forall (r :: RuntimeRep) (a :: TYPE r). Q Exp -> Q (TExp a)+unsafeTExpCoerce :: forall (r :: RuntimeRep) (a :: TYPE r) m .+ Quote m => m Exp -> m (TExp a) unsafeTExpCoerce m = do { e <- m ; return (TExp e) } @@ -280,43 +342,7 @@ ---------------------------------------------------- -- Packaged versions for the programmer, hiding the Quasi-ness -{- |-Generate a fresh name, which cannot be captured. -For example, this:--@f = $(do- nm1 <- newName \"x\"- let nm2 = 'mkName' \"x\"- return ('LamE' ['VarP' nm1] (LamE [VarP nm2] ('VarE' nm1)))- )@--will produce the splice-->f = \x0 -> \x -> x0--In particular, the occurrence @VarE nm1@ refers to the binding @VarP nm1@,-and is not captured by the binding @VarP nm2@.--Although names generated by @newName@ cannot /be captured/, they can-/capture/ other names. For example, this:-->g = $(do-> nm1 <- newName "x"-> let nm2 = mkName "x"-> return (LamE [VarP nm2] (LamE [VarP nm1] (VarE nm2)))-> )--will produce the splice-->g = \x -> \x0 -> x0--since the occurrence @VarE nm2@ is captured by the innermost binding-of @x@, namely @VarP nm1@.--}-newName :: String -> Q Name-newName s = Q (qNewName s)- -- | Report an error (True) or warning (False), -- but carry on; use 'fail' to stop. report :: Bool -> String -> Q ()@@ -654,13 +680,7 @@ -- The following operations are used solely in DsMeta when desugaring brackets -- They are not necessary for the user, who can use ordinary return and (>>=) etc -returnQ :: a -> Q a-returnQ = return--bindQ :: Q a -> (a -> Q b) -> Q b-bindQ = (>>=)--sequenceQ :: [Q a] -> Q [a]+sequenceQ :: forall m . Monad m => forall a . [m a] -> m [a] sequenceQ = sequence @@ -700,15 +720,15 @@ class Lift (t :: TYPE r) where -- | Turn a value into a Template Haskell expression, suitable for use in -- a splice.- lift :: t -> Q Exp- default lift :: (r ~ 'LiftedRep) => t -> Q Exp+ lift :: Quote m => t -> m Exp+ default lift :: (r ~ 'LiftedRep, Quote m) => t -> m Exp lift = unTypeQ . liftTyped -- | Turn a value into a Template Haskell typed expression, suitable for use -- in a typed splice. -- -- @since 2.16.0.0- liftTyped :: t -> Q (TExp t)+ liftTyped :: Quote m => t -> m (TExp t) -- If you add any instances here, consider updating test th/TH_Lift@@ -832,7 +852,7 @@ liftTyped x = unsafeTExpCoerce (lift x) lift xs = do { xs' <- mapM lift xs; return (ListE xs') } -liftString :: String -> Q Exp+liftString :: Quote m => String -> m Exp -- Used in TcExpr to short-circuit the lifting for strings liftString s = return (LitE (StringL s)) @@ -1724,7 +1744,7 @@ -- | In 'PrimTyConI', is the type constructor unlifted? type Unlifted = Bool --- | 'InstanceDec' desribes a single instance of a class or type function.+-- | 'InstanceDec' describes a single instance of a class or type function. -- It is just a 'Dec', but guaranteed to be one of the following: -- -- * 'InstanceD' (with empty @['Dec']@)