packages feed

ghc 9.10.1 → 9.10.2

raw patch · 150 files changed

+3452/−1340 lines, 150 filesdep ~bytestringdep ~ghc-bootdep ~ghc-heapPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: bytestring, ghc-boot, ghc-heap, ghci

API changes (from Hackage documentation)

- GHC: BreakInfo :: Module -> Int -> BreakInfo
- GHC: [breakInfo] :: ExecResult -> Maybe BreakInfo
- GHC: [breakInfo_module] :: BreakInfo -> Module
- GHC: [breakInfo_number] :: BreakInfo -> Int
- GHC: [resumeBreakInfo] :: Resume -> Maybe BreakInfo
- GHC: data BreakInfo
- GHC.Builtin.Names: bignatFromWordListIdKey :: Unique
- GHC.Builtin.Names: bignatFromWordListName :: Name
- GHC.Core.LateCC.Types: LateCCAllBinds :: LateCCBindSpec
- GHC.Core.TyCo.Compare: tcEqTypeVis :: Type -> Type -> Bool
- GHC.Core.TyCo.Ppr: pprWithExplicitKindsWhen :: Bool -> SDoc -> SDoc
- GHC.CoreToStg.Prep: [cp_convertNumLit] :: CorePrepConfig -> !LitNumType -> Integer -> Maybe CoreExpr
- GHC.CoreToStg.Prep: mkConvertNumLiteral :: Platform -> HomeUnit -> (Name -> IO TyThing) -> IO (LitNumType -> Integer -> Maybe CoreExpr)
- GHC.Plugins: zapIdDemandInfo :: Id -> Id
- GHC.Rename.Pat: instance GHC.Internal.Base.Monoid GHC.Rename.Pat.HsTyPatRnBuilder
- GHC.Rename.Pat: instance GHC.Internal.Base.Semigroup GHC.Rename.Pat.HsTyPatRnBuilder
- GHC.Runtime.Eval: [breakInfo] :: ExecResult -> Maybe BreakInfo
- GHC.Runtime.Eval: [historyBreakInfo] :: History -> BreakInfo
- GHC.Runtime.Eval: [resumeBreakInfo] :: Resume -> Maybe BreakInfo
- GHC.Runtime.Eval.Types: [breakInfo] :: ExecResult -> Maybe BreakInfo
- GHC.Runtime.Eval.Types: [historyBreakInfo] :: History -> BreakInfo
- GHC.Runtime.Eval.Types: [resumeBreakInfo] :: Resume -> Maybe BreakInfo
- GHC.Runtime.Interpreter: evalBreakInfo :: HomePackageTable -> EvalBreakpoint -> BreakInfo
- GHC.Runtime.Interpreter.Types: [instLookupSymbolCache] :: ExtInterpInstance c -> !MVar (UniqFM FastString (Ptr ()))
- GHC.SysTools.Cpp: [useHsCpp] :: CppOpts -> !Bool
- GHC.SysTools.Tasks: runCpp :: Logger -> TmpFs -> DynFlags -> [Option] -> IO ()
- GHC.SysTools.Tasks: runHsCpp :: Logger -> DynFlags -> [Option] -> IO ()
- GHC.Tc.Errors.Types: [teq_mismatch_ppr_explicit_kinds] :: MismatchMsg -> Bool
- GHC.Tc.Types.Constraint: arisesFromGivens :: Ct -> Bool
- GHC.Tc.Types.Evidence: mkWpVisTyLam :: TyVar -> Type -> HsWrapper
- GHC.Tc.Utils.TcType: tcEqTypeVis :: Type -> Type -> Bool
- GHC.Types.BreakInfo: BreakInfo :: Module -> Int -> BreakInfo
- GHC.Types.BreakInfo: [breakInfo_module] :: BreakInfo -> Module
- GHC.Types.BreakInfo: [breakInfo_number] :: BreakInfo -> Int
- GHC.Types.BreakInfo: data BreakInfo
- GHC.Types.Id: zapIdDemandInfo :: Id -> Id
- GHC.Types.Id.Info: zapDemandInfo :: IdInfo -> Maybe IdInfo
+ GHC: BreakpointId :: !Module -> !Int -> BreakpointId
+ GHC: InternalBreakpointId :: !Module -> !Int -> !Module -> !Int -> InternalBreakpointId
+ GHC: Opt_SpecEval :: GeneralFlag
+ GHC: Opt_SpecEvalDictFun :: GeneralFlag
+ GHC: [bi_tick_index] :: BreakpointId -> !Int
+ GHC: [bi_tick_mod] :: BreakpointId -> !Module
+ GHC: [breakPointId] :: ExecResult -> Maybe InternalBreakpointId
+ GHC: [ibi_info_index] :: InternalBreakpointId -> !Int
+ GHC: [ibi_info_mod] :: InternalBreakpointId -> !Module
+ GHC: [ibi_tick_index] :: InternalBreakpointId -> !Int
+ GHC: [ibi_tick_mod] :: InternalBreakpointId -> !Module
+ GHC: [resumeBreakpointId] :: Resume -> Maybe InternalBreakpointId
+ GHC: data BreakpointId
+ GHC: data InternalBreakpointId
+ GHC.Builtin.Names: zonkAnyTyConKey :: Unique
+ GHC.Builtin.Types: soloDataConName :: Name
+ GHC.Builtin.Types: zonkAnyTyCon :: TyCon
+ GHC.Builtin.Types.Prim: realWorldMutableByteArrayPrimTy :: Type
+ GHC.ByteCode.Types: BCOByteArray :: !ByteArray# -> BCOByteArray a
+ GHC.ByteCode.Types: [getBCOByteArray] :: BCOByteArray a -> !ByteArray#
+ GHC.ByteCode.Types: data BCOByteArray a
+ GHC.ByteCode.Types: data FlatBag a
+ GHC.ByteCode.Types: elemsFlatBag :: FlatBag a -> [a]
+ GHC.ByteCode.Types: fromSizedSeq :: SizedSeq a -> FlatBag a
+ GHC.ByteCode.Types: mkBCOByteArray :: UArray Int a -> BCOByteArray a
+ GHC.ByteCode.Types: sizeFlatBag :: FlatBag a -> Word
+ GHC.CmmToAsm.AArch64.Instr: CLZ :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.AArch64.Instr: CMN :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.AArch64.Instr: FSQRT :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.AArch64.Instr: RBIT :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.AArch64.Instr: REV :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.AArch64.Instr: REV16 :: Operand -> Operand -> Instr
+ GHC.CmmToAsm.AArch64.Instr: UMULH :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.AArch64.Instr: UMULL :: Operand -> Operand -> Operand -> Instr
+ GHC.CmmToAsm.AArch64.Instr: canFallthroughTo :: Instr -> BlockId -> Bool
+ GHC.CmmToAsm.Instr: canFallthroughTo :: Instruction instr => instr -> BlockId -> Bool
+ GHC.CmmToAsm.PPC.Instr: canFallthroughTo :: Instr -> BlockId -> Bool
+ GHC.CmmToAsm.X86.Instr: canFallthroughTo :: Instr -> BlockId -> Bool
+ GHC.Core.LateCC.Types: LateCCBinds :: LateCCBindSpec
+ GHC.Core.TyCo.Compare: mayLookIdentical :: Type -> Type -> Bool
+ GHC.Core.TyCo.Ppr: pprWithInvisibleBitsWhen :: Bool -> SDoc -> SDoc
+ GHC.CoreToStg.Prep: [cp_platform] :: CorePrepConfig -> Platform
+ GHC.CoreToStg.Prep: [cp_specEvalDFun] :: CorePrepConfig -> !Bool
+ GHC.CoreToStg.Prep: [cp_specEval] :: CorePrepConfig -> !Bool
+ GHC.Data.FlatBag: data FlatBag a
+ GHC.Data.FlatBag: elemsFlatBag :: FlatBag a -> [a]
+ GHC.Data.FlatBag: emptyFlatBag :: FlatBag a
+ GHC.Data.FlatBag: fromList :: Word -> [a] -> FlatBag a
+ GHC.Data.FlatBag: fromSizedSeq :: SizedSeq a -> FlatBag a
+ GHC.Data.FlatBag: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (GHC.Data.FlatBag.FlatBag a)
+ GHC.Data.FlatBag: instance GHC.Internal.Base.Functor GHC.Data.FlatBag.FlatBag
+ GHC.Data.FlatBag: instance GHC.Internal.Data.Foldable.Foldable GHC.Data.FlatBag.FlatBag
+ GHC.Data.FlatBag: instance GHC.Internal.Data.Traversable.Traversable GHC.Data.FlatBag.FlatBag
+ GHC.Data.FlatBag: mappendFlatBag :: FlatBag a -> FlatBag a -> FlatBag a
+ GHC.Data.FlatBag: sizeFlatBag :: FlatBag a -> Word
+ GHC.Data.FlatBag: unitFlatBag :: a -> FlatBag a
+ GHC.Data.SmallArray: foldMapSmallArray :: Monoid m => (a -> m) -> SmallArray a -> m
+ GHC.Data.SmallArray: mapSmallArray :: (a -> b) -> SmallArray a -> SmallArray b
+ GHC.Data.SmallArray: rnfSmallArray :: NFData a => SmallArray a -> ()
+ GHC.Data.SmallArray: sizeofSmallArray :: SmallArray a -> Int
+ GHC.Driver.DynFlags: Opt_SpecEval :: GeneralFlag
+ GHC.Driver.DynFlags: Opt_SpecEvalDictFun :: GeneralFlag
+ GHC.Driver.Flags: Opt_SpecEval :: GeneralFlag
+ GHC.Driver.Flags: Opt_SpecEvalDictFun :: GeneralFlag
+ GHC.Driver.Session: Opt_SpecEval :: GeneralFlag
+ GHC.Driver.Session: Opt_SpecEvalDictFun :: GeneralFlag
+ GHC.Driver.Session: opt_CmmP :: DynFlags -> [String]
+ GHC.Driver.Session: opt_CmmP_signature :: DynFlags -> Fingerprint
+ GHC.Driver.Session: opt_JSP :: DynFlags -> [String]
+ GHC.Driver.Session: opt_JSP_signature :: DynFlags -> ([String], Fingerprint)
+ GHC.Driver.Session: pgm_CmmP :: DynFlags -> (String, [Option])
+ GHC.Driver.Session: pgm_JSP :: DynFlags -> (String, [Option])
+ GHC.Driver.Session: sOpt_CmmP :: Settings -> [String]
+ GHC.Driver.Session: sOpt_CmmP_fingerprint :: Settings -> Fingerprint
+ GHC.Driver.Session: sOpt_JSP :: Settings -> [String]
+ GHC.Driver.Session: sOpt_JSP_fingerprint :: Settings -> Fingerprint
+ GHC.Hs.Type: HsTPRnB :: Bag Name -> Bag Name -> Bag Name -> HsTyPatRnBuilder
+ GHC.Hs.Type: [hstpb_exp_tvs] :: HsTyPatRnBuilder -> Bag Name
+ GHC.Hs.Type: [hstpb_imp_tvs] :: HsTyPatRnBuilder -> Bag Name
+ GHC.Hs.Type: [hstpb_nwcs] :: HsTyPatRnBuilder -> Bag Name
+ GHC.Hs.Type: buildHsTyPatRn :: HsTyPatRnBuilder -> HsTyPatRn
+ GHC.Hs.Type: builderFromHsTyPatRn :: HsTyPatRn -> HsTyPatRnBuilder
+ GHC.Hs.Type: data HsTyPatRnBuilder
+ GHC.Hs.Type: instance GHC.Internal.Base.Monoid GHC.Hs.Type.HsTyPatRnBuilder
+ GHC.Hs.Type: instance GHC.Internal.Base.Semigroup GHC.Hs.Type.HsTyPatRnBuilder
+ GHC.Hs.Type: tpBuilderExplicitTV :: Name -> HsTyPatRnBuilder
+ GHC.Hs.Type: tpBuilderPatSig :: HsPSRn -> HsTyPatRnBuilder
+ GHC.Linker.Types: [loaded_pkg_hs_dlls] :: LoadedPkgInfo -> ![RemotePtr LoadedDLL]
+ GHC.Plugins: floatifyIdDemandInfo :: Id -> Id
+ GHC.Runtime.Eval: [breakPointId] :: ExecResult -> Maybe InternalBreakpointId
+ GHC.Runtime.Eval: [historyBreakpointId] :: History -> InternalBreakpointId
+ GHC.Runtime.Eval: [resumeBreakpointId] :: Resume -> Maybe InternalBreakpointId
+ GHC.Runtime.Eval.Types: [breakPointId] :: ExecResult -> Maybe InternalBreakpointId
+ GHC.Runtime.Eval.Types: [historyBreakpointId] :: History -> InternalBreakpointId
+ GHC.Runtime.Eval.Types: [resumeBreakpointId] :: Resume -> Maybe InternalBreakpointId
+ GHC.Runtime.Interpreter: [LookupSymbolInDLL] :: RemotePtr LoadedDLL -> String -> Message (Maybe (RemotePtr ()))
+ GHC.Runtime.Interpreter: evalBreakpointToId :: HomePackageTable -> EvalBreakpoint -> InternalBreakpointId
+ GHC.Runtime.Interpreter: lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ()))
+ GHC.Runtime.Interpreter.Process: [LookupSymbolInDLL] :: RemotePtr LoadedDLL -> String -> Message (Maybe (RemotePtr ()))
+ GHC.Runtime.Interpreter.Types: [interpLookupSymbolCache] :: Interp -> !MVar (UniqFM FastString (Ptr ()))
+ GHC.Settings: [toolSettings_cmmCppSupportsG0] :: ToolSettings -> Bool
+ GHC.Settings: [toolSettings_opt_CmmP] :: ToolSettings -> [String]
+ GHC.Settings: [toolSettings_opt_CmmP_fingerprint] :: ToolSettings -> Fingerprint
+ GHC.Settings: [toolSettings_opt_JSP] :: ToolSettings -> [String]
+ GHC.Settings: [toolSettings_opt_JSP_fingerprint] :: ToolSettings -> Fingerprint
+ GHC.Settings: [toolSettings_pgm_CmmP] :: ToolSettings -> (String, [Option])
+ GHC.Settings: [toolSettings_pgm_JSP] :: ToolSettings -> (String, [Option])
+ GHC.Settings: sOpt_CmmP :: Settings -> [String]
+ GHC.Settings: sOpt_CmmP_fingerprint :: Settings -> Fingerprint
+ GHC.Settings: sOpt_JSP :: Settings -> [String]
+ GHC.Settings: sOpt_JSP_fingerprint :: Settings -> Fingerprint
+ GHC.Settings: sPgm_CmmP :: Settings -> (String, [Option])
+ GHC.Settings: sPgm_JSP :: Settings -> (String, [Option])
+ GHC.StgToCmm.Config: [stgToCmmAllowWordMul2Instr] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Config: [stgToCmmSaveFCallTargetToLocal] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmAllowWordMul2Instr] :: StgToCmmConfig -> !Bool
+ GHC.StgToCmm.Monad: [stgToCmmSaveFCallTargetToLocal] :: StgToCmmConfig -> !Bool
+ GHC.SysTools.Cpp: [sourceCodePreprocessor] :: CppOpts -> !SourceCodePreprocessor
+ GHC.SysTools.Tasks: SCPCmmCpp :: SourceCodePreprocessor
+ GHC.SysTools.Tasks: SCPCpp :: SourceCodePreprocessor
+ GHC.SysTools.Tasks: SCPHsCpp :: SourceCodePreprocessor
+ GHC.SysTools.Tasks: SCPJsCpp :: SourceCodePreprocessor
+ GHC.SysTools.Tasks: data SourceCodePreprocessor
+ GHC.SysTools.Tasks: instance GHC.Classes.Eq GHC.SysTools.Tasks.SourceCodePreprocessor
+ GHC.SysTools.Tasks: runSourceCodePreprocessor :: Logger -> TmpFs -> DynFlags -> SourceCodePreprocessor -> [Option] -> IO ()
+ GHC.Tc.Gen.HsType: tyLitFromLit :: HsLit GhcRn -> Maybe (HsTyLit GhcRn)
+ GHC.Tc.Gen.HsType: tyLitFromOverloadedLit :: OverLitVal -> Maybe (HsTyLit GhcRn)
+ GHC.Tc.Types: [tcg_zany_n] :: TcGblEnv -> TcRef Integer
+ GHC.Tc.Types.Evidence: mkWpForAllCast :: [ForAllTyBinder] -> Type -> HsWrapper
+ GHC.Tc.Utils.Env: failIllegalTyCon :: WhatLooking -> TyCon -> TcM a
+ GHC.Tc.Utils.Env: failIllegalTyVal :: Name -> TcM a
+ GHC.Tc.Utils.Instantiate: skolemiseRequired :: SkolemInfo -> VisArity -> TcSigmaType -> TcM (VisArity, HsWrapper, [Name], [ForAllTyBinder], [EvVar], TcRhoType)
+ GHC.Tc.Utils.Monad: newZonkAnyType :: Kind -> TcM Type
+ GHC.Tc.Utils.TcType: mayLookIdentical :: Type -> Type -> Bool
+ GHC.Tc.Utils.TcType: tcSplitForAllTyVarsReqTVBindersN :: Arity -> Type -> (Arity, [ForAllTyBinder], Type)
+ GHC.Types.Breakpoint: BreakpointId :: !Module -> !Int -> BreakpointId
+ GHC.Types.Breakpoint: InternalBreakpointId :: !Module -> !Int -> !Module -> !Int -> InternalBreakpointId
+ GHC.Types.Breakpoint: [bi_tick_index] :: BreakpointId -> !Int
+ GHC.Types.Breakpoint: [bi_tick_mod] :: BreakpointId -> !Module
+ GHC.Types.Breakpoint: [ibi_info_index] :: InternalBreakpointId -> !Int
+ GHC.Types.Breakpoint: [ibi_info_mod] :: InternalBreakpointId -> !Module
+ GHC.Types.Breakpoint: [ibi_tick_index] :: InternalBreakpointId -> !Int
+ GHC.Types.Breakpoint: [ibi_tick_mod] :: InternalBreakpointId -> !Module
+ GHC.Types.Breakpoint: data BreakpointId
+ GHC.Types.Breakpoint: data InternalBreakpointId
+ GHC.Types.Breakpoint: toBreakpointId :: InternalBreakpointId -> BreakpointId
+ GHC.Types.Demand: floatifyDmd :: Demand -> Demand
+ GHC.Types.Id: floatifyIdDemandInfo :: Id -> Id
+ GHC.Types.Id.Info: floatifyDemandInfo :: IdInfo -> Maybe IdInfo
+ GHC.Types.Id.Info: lazifyDemandInfo :: IdInfo -> Maybe IdInfo
+ GHC.Utils.Fingerprint: fingerprintStrings :: [String] -> Fingerprint
- GHC: ExecBreak :: [Name] -> Maybe BreakInfo -> ExecResult
+ GHC: ExecBreak :: [Name] -> Maybe InternalBreakpointId -> ExecResult
- GHC: Resume :: String -> ForeignRef (ResumeContext [HValueRef]) -> ResumeBindings -> [Id] -> ForeignHValue -> Maybe BreakInfo -> SrcSpan -> String -> RemotePtr CostCentreStack -> [History] -> Int -> Resume
+ GHC: Resume :: String -> ForeignRef (ResumeContext [HValueRef]) -> ResumeBindings -> [Id] -> ForeignHValue -> Maybe InternalBreakpointId -> SrcSpan -> String -> RemotePtr CostCentreStack -> [History] -> Int -> Resume
- GHC: setupBreakpoint :: GhcMonad m => HscEnv -> BreakInfo -> Int -> m ()
+ GHC: setupBreakpoint :: GhcMonad m => HscEnv -> BreakpointId -> Int -> m ()
- GHC.ByteCode.Instr: BRK_FUN :: ForeignRef BreakArray -> !Word16 -> RemotePtr ModuleName -> RemotePtr CostCentre -> BCInstr
+ GHC.ByteCode.Instr: BRK_FUN :: ForeignRef BreakArray -> RemotePtr ModuleName -> !Word16 -> RemotePtr ModuleName -> !Word16 -> RemotePtr CostCentre -> BCInstr
- GHC.ByteCode.Linker: linkBCO :: Interp -> LinkerEnv -> NameEnv Int -> UnlinkedBCO -> IO ResolvedBCO
+ GHC.ByteCode.Linker: linkBCO :: Interp -> PkgsLoaded -> LinkerEnv -> NameEnv Int -> UnlinkedBCO -> IO ResolvedBCO
- GHC.ByteCode.Linker: lookupIE :: Interp -> ItblEnv -> Name -> IO (Ptr ())
+ GHC.ByteCode.Linker: lookupIE :: Interp -> PkgsLoaded -> ItblEnv -> Name -> IO (Ptr ())
- GHC.ByteCode.Types: UnlinkedBCO :: !Name -> {-# UNPACK #-} !Int -> !UArray Int Word16 -> !UArray Int Word64 -> !SizedSeq BCONPtr -> !SizedSeq BCOPtr -> UnlinkedBCO
+ GHC.ByteCode.Types: UnlinkedBCO :: !Name -> {-# UNPACK #-} !Int -> !BCOByteArray Word16 -> !BCOByteArray Word -> !FlatBag BCONPtr -> !FlatBag BCOPtr -> UnlinkedBCO
- GHC.ByteCode.Types: [unlinkedBCOBitmap] :: UnlinkedBCO -> !UArray Int Word64
+ GHC.ByteCode.Types: [unlinkedBCOBitmap] :: UnlinkedBCO -> !BCOByteArray Word
- GHC.ByteCode.Types: [unlinkedBCOInstrs] :: UnlinkedBCO -> !UArray Int Word16
+ GHC.ByteCode.Types: [unlinkedBCOInstrs] :: UnlinkedBCO -> !BCOByteArray Word16
- GHC.ByteCode.Types: [unlinkedBCOLits] :: UnlinkedBCO -> !SizedSeq BCONPtr
+ GHC.ByteCode.Types: [unlinkedBCOLits] :: UnlinkedBCO -> !FlatBag BCONPtr
- GHC.ByteCode.Types: [unlinkedBCOPtrs] :: UnlinkedBCO -> !SizedSeq BCOPtr
+ GHC.ByteCode.Types: [unlinkedBCOPtrs] :: UnlinkedBCO -> !FlatBag BCOPtr
- GHC.CmmToAsm.AArch64.Instr: BL :: Target -> [Reg] -> [Reg] -> Instr
+ GHC.CmmToAsm.AArch64.Instr: BL :: Target -> [Reg] -> Instr
- GHC.Core.Opt.Arity: exprEtaExpandArity :: ArityOpts -> CoreExpr -> Maybe SafeArityType
+ GHC.Core.Opt.Arity: exprEtaExpandArity :: HasDebugCallStack => ArityOpts -> CoreExpr -> Maybe SafeArityType
- GHC.CoreToStg.Prep: CorePrepConfig :: !Bool -> !LitNumType -> Integer -> Maybe CoreExpr -> !Maybe ArityOpts -> CorePrepConfig
+ GHC.CoreToStg.Prep: CorePrepConfig :: !Bool -> Platform -> !Maybe ArityOpts -> !Bool -> !Bool -> CorePrepConfig
- GHC.Linker.Types: LoadedPkgInfo :: !UnitId -> ![LibrarySpec] -> ![LibrarySpec] -> UniqDSet UnitId -> LoadedPkgInfo
+ GHC.Linker.Types: LoadedPkgInfo :: !UnitId -> ![LibrarySpec] -> ![LibrarySpec] -> ![RemotePtr LoadedDLL] -> UniqDSet UnitId -> LoadedPkgInfo
- GHC.Plugins: mkLocalCoVar :: Name -> Type -> CoVar
+ GHC.Plugins: mkLocalCoVar :: HasDebugCallStack => Name -> Type -> CoVar
- GHC.Plugins: mkLocalIdOrCoVar :: Name -> Mult -> Type -> Id
+ GHC.Plugins: mkLocalIdOrCoVar :: HasDebugCallStack => Name -> Mult -> Type -> Id
- GHC.Plugins: mkVanillaGlobal :: Name -> Type -> Id
+ GHC.Plugins: mkVanillaGlobal :: HasDebugCallStack => Name -> Type -> Id
- GHC.Plugins: mkVanillaGlobalWithInfo :: Name -> Type -> IdInfo -> Id
+ GHC.Plugins: mkVanillaGlobalWithInfo :: HasDebugCallStack => Name -> Type -> IdInfo -> Id
- GHC.Runtime.Eval: ExecBreak :: [Name] -> Maybe BreakInfo -> ExecResult
+ GHC.Runtime.Eval: ExecBreak :: [Name] -> Maybe InternalBreakpointId -> ExecResult
- GHC.Runtime.Eval: History :: ForeignHValue -> BreakInfo -> [String] -> History
+ GHC.Runtime.Eval: History :: ForeignHValue -> InternalBreakpointId -> [String] -> History
- GHC.Runtime.Eval: Resume :: String -> ForeignRef (ResumeContext [HValueRef]) -> ResumeBindings -> [Id] -> ForeignHValue -> Maybe BreakInfo -> SrcSpan -> String -> RemotePtr CostCentreStack -> [History] -> Int -> Resume
+ GHC.Runtime.Eval: Resume :: String -> ForeignRef (ResumeContext [HValueRef]) -> ResumeBindings -> [Id] -> ForeignHValue -> Maybe InternalBreakpointId -> SrcSpan -> String -> RemotePtr CostCentreStack -> [History] -> Int -> Resume
- GHC.Runtime.Eval: setupBreakpoint :: GhcMonad m => HscEnv -> BreakInfo -> Int -> m ()
+ GHC.Runtime.Eval: setupBreakpoint :: GhcMonad m => HscEnv -> BreakpointId -> Int -> m ()
- GHC.Runtime.Eval.Types: ExecBreak :: [Name] -> Maybe BreakInfo -> ExecResult
+ GHC.Runtime.Eval.Types: ExecBreak :: [Name] -> Maybe InternalBreakpointId -> ExecResult
- GHC.Runtime.Eval.Types: History :: ForeignHValue -> BreakInfo -> [String] -> History
+ GHC.Runtime.Eval.Types: History :: ForeignHValue -> InternalBreakpointId -> [String] -> History
- GHC.Runtime.Eval.Types: Resume :: String -> ForeignRef (ResumeContext [HValueRef]) -> ResumeBindings -> [Id] -> ForeignHValue -> Maybe BreakInfo -> SrcSpan -> String -> RemotePtr CostCentreStack -> [History] -> Int -> Resume
+ GHC.Runtime.Eval.Types: Resume :: String -> ForeignRef (ResumeContext [HValueRef]) -> ResumeBindings -> [Id] -> ForeignHValue -> Maybe InternalBreakpointId -> SrcSpan -> String -> RemotePtr CostCentreStack -> [History] -> Int -> Resume
- GHC.Runtime.Interpreter: [LoadDLL] :: String -> Message (Maybe String)
+ GHC.Runtime.Interpreter: [LoadDLL] :: String -> Message (Either String (RemotePtr LoadedDLL))
- GHC.Runtime.Interpreter: loadDLL :: Interp -> String -> IO (Maybe String)
+ GHC.Runtime.Interpreter: loadDLL :: Interp -> String -> IO (Either String (RemotePtr LoadedDLL))
- GHC.Runtime.Interpreter.Process: [LoadDLL] :: String -> Message (Maybe String)
+ GHC.Runtime.Interpreter.Process: [LoadDLL] :: String -> Message (Either String (RemotePtr LoadedDLL))
- GHC.Runtime.Interpreter.Types: ExtInterpInstance :: {-# UNPACK #-} !InterpProcess -> !MVar [HValueRef] -> !MVar (UniqFM FastString (Ptr ())) -> !c -> ExtInterpInstance c
+ GHC.Runtime.Interpreter.Types: ExtInterpInstance :: {-# UNPACK #-} !InterpProcess -> !MVar [HValueRef] -> !c -> ExtInterpInstance c
- GHC.Runtime.Interpreter.Types: Interp :: !InterpInstance -> !Loader -> Interp
+ GHC.Runtime.Interpreter.Types: Interp :: !InterpInstance -> !Loader -> !MVar (UniqFM FastString (Ptr ())) -> Interp
- GHC.Settings: ToolSettings :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> String -> (String, [Option]) -> String -> String -> String -> (String, [Option]) -> (String, [Option]) -> (String, [Option]) -> Maybe (String, [Option]) -> String -> String -> String -> String -> String -> (String, [Option]) -> (String, [Option]) -> (String, [Option]) -> String -> [String] -> [String] -> Fingerprint -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> ToolSettings
+ GHC.Settings: ToolSettings :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> String -> (String, [Option]) -> (String, [Option]) -> (String, [Option]) -> String -> String -> String -> (String, [Option]) -> (String, [Option]) -> (String, [Option]) -> Maybe (String, [Option]) -> String -> String -> String -> String -> String -> (String, [Option]) -> (String, [Option]) -> (String, [Option]) -> String -> [String] -> [String] -> [String] -> [String] -> Fingerprint -> Fingerprint -> Fingerprint -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> [String] -> ToolSettings
- GHC.StgToCmm.Config: StgToCmmConfig :: !Profile -> Module -> !TempDir -> !SDocContext -> !Bool -> !Maybe Word -> !Int -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> (FMASign -> Bool) -> !Bool -> Maybe String -> !Bool -> !Bool -> !Bool -> StgToCmmConfig
+ GHC.StgToCmm.Config: StgToCmmConfig :: !Profile -> Module -> !TempDir -> !SDocContext -> !Bool -> !Maybe Word -> !Int -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> (FMASign -> Bool) -> !Bool -> !Bool -> Maybe String -> !Bool -> !Bool -> !Bool -> StgToCmmConfig
- GHC.StgToCmm.Monad: StgToCmmConfig :: !Profile -> Module -> !TempDir -> !SDocContext -> !Bool -> !Maybe Word -> !Int -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> (FMASign -> Bool) -> !Bool -> Maybe String -> !Bool -> !Bool -> !Bool -> StgToCmmConfig
+ GHC.StgToCmm.Monad: StgToCmmConfig :: !Profile -> Module -> !TempDir -> !SDocContext -> !Bool -> !Maybe Word -> !Int -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> !Bool -> (FMASign -> Bool) -> !Bool -> !Bool -> Maybe String -> !Bool -> !Bool -> !Bool -> StgToCmmConfig
- GHC.SysTools.Cpp: CppOpts :: !Bool -> !Bool -> CppOpts
+ GHC.SysTools.Cpp: CppOpts :: !SourceCodePreprocessor -> !Bool -> CppOpts
- GHC.Tc.Errors.Types: TypeEqMismatch :: Bool -> ErrorItem -> Type -> Type -> Type -> Type -> Maybe TypedThing -> Maybe SameOccInfo -> MismatchMsg
+ GHC.Tc.Errors.Types: TypeEqMismatch :: ErrorItem -> Type -> Type -> Type -> Type -> Maybe TypedThing -> Maybe SameOccInfo -> MismatchMsg
- GHC.Tc.Types: TcGblEnv :: Module -> Module -> HscSource -> GlobalRdrEnv -> Maybe [Type] -> FixityEnv -> TypeEnv -> KnotVars (IORef TypeEnv) -> !InstEnv -> !FamInstEnv -> AnnEnv -> [AvailInfo] -> ImportAvails -> DefUses -> TcRef [GlobalRdrElt] -> TcRef NameSet -> TcRef Bool -> TcRef Bool -> TcRef ([Linkable], PkgsLoaded) -> TcRef OccSet -> [(Module, Fingerprint)] -> Maybe [(LIE GhcRn, Avails)] -> [LImportDecl GhcRn] -> Maybe (HsGroup GhcRn) -> TcRef [FilePath] -> TcRef [LHsDecl GhcPs] -> TcRef [(ForeignSrcLang, FilePath)] -> TcRef NameSet -> TcRef [(TcLclEnv, ThModFinalizers)] -> TcRef [String] -> TcRef (Map TypeRep Dynamic) -> TcRef (Maybe (ForeignRef (IORef QState))) -> TcRef THDocs -> Bag EvBind -> Maybe Id -> LHsBinds GhcTc -> NameSet -> [LTcSpecPrag] -> Warnings GhcRn -> [Annotation] -> [TyCon] -> NameSet -> [ClsInst] -> [FamInst] -> [LRuleDecl GhcTc] -> [LForeignDecl GhcTc] -> [PatSyn] -> (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName)) -> !AnyHpcUsage -> SelfBootInfo -> Maybe Name -> TcRef Bool -> TcRef (Messages TcRnMessage) -> [TcPluginSolver] -> UniqFM TyCon [TcPluginRewriter] -> [FillDefaulting] -> [HoleFitPlugin] -> RealSrcSpan -> TcRef WantedConstraints -> !CompleteMatches -> TcRef CostCentreState -> TcRef (ModuleEnv Int) -> TcGblEnv
+ GHC.Tc.Types: TcGblEnv :: Module -> Module -> HscSource -> GlobalRdrEnv -> Maybe [Type] -> FixityEnv -> TypeEnv -> KnotVars (IORef TypeEnv) -> !InstEnv -> !FamInstEnv -> AnnEnv -> [AvailInfo] -> ImportAvails -> DefUses -> TcRef [GlobalRdrElt] -> TcRef NameSet -> TcRef Bool -> TcRef Bool -> TcRef ([Linkable], PkgsLoaded) -> TcRef OccSet -> TcRef Integer -> [(Module, Fingerprint)] -> Maybe [(LIE GhcRn, Avails)] -> [LImportDecl GhcRn] -> Maybe (HsGroup GhcRn) -> TcRef [FilePath] -> TcRef [LHsDecl GhcPs] -> TcRef [(ForeignSrcLang, FilePath)] -> TcRef NameSet -> TcRef [(TcLclEnv, ThModFinalizers)] -> TcRef [String] -> TcRef (Map TypeRep Dynamic) -> TcRef (Maybe (ForeignRef (IORef QState))) -> TcRef THDocs -> Bag EvBind -> Maybe Id -> LHsBinds GhcTc -> NameSet -> [LTcSpecPrag] -> Warnings GhcRn -> [Annotation] -> [TyCon] -> NameSet -> [ClsInst] -> [FamInst] -> [LRuleDecl GhcTc] -> [LForeignDecl GhcTc] -> [PatSyn] -> (Maybe (LHsDoc GhcRn), Maybe (XRec GhcRn ModuleName)) -> !AnyHpcUsage -> SelfBootInfo -> Maybe Name -> TcRef Bool -> TcRef (Messages TcRnMessage) -> [TcPluginSolver] -> UniqFM TyCon [TcPluginRewriter] -> [FillDefaulting] -> [HoleFitPlugin] -> RealSrcSpan -> TcRef WantedConstraints -> !CompleteMatches -> TcRef CostCentreState -> TcRef (ModuleEnv Int) -> TcGblEnv
- GHC.Types.Id: mkLocalCoVar :: Name -> Type -> CoVar
+ GHC.Types.Id: mkLocalCoVar :: HasDebugCallStack => Name -> Type -> CoVar
- GHC.Types.Id: mkLocalIdOrCoVar :: Name -> Mult -> Type -> Id
+ GHC.Types.Id: mkLocalIdOrCoVar :: HasDebugCallStack => Name -> Mult -> Type -> Id
- GHC.Types.Id: mkVanillaGlobal :: Name -> Type -> Id
+ GHC.Types.Id: mkVanillaGlobal :: HasDebugCallStack => Name -> Type -> Id
- GHC.Types.Id: mkVanillaGlobalWithInfo :: Name -> Type -> IdInfo -> Id
+ GHC.Types.Id: mkVanillaGlobalWithInfo :: HasDebugCallStack => Name -> Type -> IdInfo -> Id
- GHC.Utils.Exception: throw :: forall a e. (?callStack :: CallStack, Exception e) => e -> a
+ GHC.Utils.Exception: throw :: forall a e. (HasCallStack, Exception e) => e -> a

Files

GHC.hs view
@@ -157,14 +157,14 @@         -- ** The debugger         SingleStep(..),         Resume(..),-        History(historyBreakInfo, historyEnclosingDecls),+        History(historyBreakpointId, historyEnclosingDecls),         GHC.getHistorySpan, getHistoryModule,         abandon, abandonAll,         getResumeContext,         GHC.obtainTermFromId, GHC.obtainTermFromVal, reconstructType,         modInfoModBreaks,         ModBreaks(..), BreakIndex,-        BreakInfo(..),+        BreakpointId(..), InternalBreakpointId(..),         GHC.Runtime.Eval.back,         GHC.Runtime.Eval.forward,         GHC.Runtime.Eval.setupBreakpoint,@@ -337,6 +337,7 @@ import GHC.Parser.Annotation import GHC.Parser.Utils +import GHC.Iface.Env ( trace_if ) import GHC.Iface.Load        ( loadSysInterface ) import GHC.Hs import GHC.Builtin.Types.Prim ( alphaTyVars )@@ -392,8 +393,9 @@ import GHC.Types.Name.Env import GHC.Types.Name.Ppr import GHC.Types.TypeEnv-import GHC.Types.BreakInfo+import GHC.Types.Breakpoint import GHC.Types.PkgQual+import GHC.Types.Unique.FM  import GHC.Unit import GHC.Unit.Env@@ -673,6 +675,7 @@ setTopSessionDynFlags dflags = do   hsc_env <- getSession   logger  <- getLogger+  lookup_cache  <- liftIO $ newMVar emptyUFM    -- Interpreter   interp <- if@@ -702,7 +705,7 @@             }          s <- liftIO $ newMVar InterpPending          loader <- liftIO Loader.uninitializedLoader-         return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader))+         return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache))      -- JavaScript interpreter     | ArchJavaScript <- platformArch (targetPlatform dflags)@@ -720,7 +723,7 @@               , jsInterpFinderOpts  = initFinderOpts dflags               , jsInterpFinderCache = hsc_FC hsc_env               }-         return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader))+         return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache))      -- Internal interpreter     | otherwise@@ -728,7 +731,7 @@ #if defined(HAVE_INTERNAL_INTERPRETER)      do       loader <- liftIO Loader.uninitializedLoader-      return (Just (Interp InternalInterp loader))+      return (Just (Interp InternalInterp loader lookup_cache)) #else       return Nothing #endif@@ -1701,6 +1704,7 @@  findQualifiedModule :: GhcMonad m => PkgQual -> ModuleName -> m Module findQualifiedModule pkgqual mod_name = withSession $ \hsc_env -> do+  liftIO $ trace_if (hsc_logger hsc_env) (text "findQualifiedModule" <+> ppr mod_name <+> ppr pkgqual)   let mhome_unit = hsc_home_unit_maybe hsc_env   let dflags    = hsc_dflags hsc_env   case pkgqual of@@ -1763,7 +1767,8 @@ lookupQualifiedModule pkgqual mod_name = findQualifiedModule pkgqual mod_name  lookupLoadedHomeModule :: GhcMonad m => UnitId -> ModuleName -> m (Maybe Module)-lookupLoadedHomeModule uid mod_name = withSession $ \hsc_env ->+lookupLoadedHomeModule uid mod_name = withSession $ \hsc_env -> do+  liftIO $ trace_if (hsc_logger hsc_env) (text "lookupLoadedHomeModule" <+> ppr mod_name <+> ppr uid)   case lookupHug  (hsc_HUG hsc_env) uid mod_name  of     Just mod_info      -> return (Just (mi_module (hm_iface mod_info)))     _not_a_home_module -> return Nothing
GHC/Builtin/Names.hs view
@@ -276,7 +276,7 @@         -- Dynamic         toDynName, -        -- GHC.Internal.Numeric stuff+        -- Numeric stuff         negateName, minusName, geName, eqName,         mkRationalBase2Name, mkRationalBase10Name, @@ -430,7 +430,6 @@         naturalPowModName,         naturalSizeInBaseName, -        bignatFromWordListName,         bignatEqName,          -- Float/Double@@ -1203,7 +1202,6 @@    , naturalLogBaseName    , naturalPowModName    , naturalSizeInBaseName-   , bignatFromWordListName    , bignatEqName    , bignatCompareName    , bignatCompareWordName@@ -1215,7 +1213,6 @@ bniVarQual str key = varQual gHC_INTERNAL_NUM_INTEGER (fsLit str) key  -- Types and DataCons-bignatFromWordListName    = bnbVarQual "bigNatFromWordList#"       bignatFromWordListIdKey bignatEqName              = bnbVarQual "bigNatEq#"                 bignatEqIdKey bignatCompareName         = bnbVarQual "bigNatCompare"             bignatCompareIdKey bignatCompareWordName     = bnbVarQual "bigNatCompareWord#"        bignatCompareWordIdKey@@ -2010,6 +2007,12 @@ unsatisfiableClassNameKey :: Unique unsatisfiableClassNameKey = mkPreludeTyConUnique 170 +anyTyConKey :: Unique+anyTyConKey = mkPreludeTyConUnique 171++zonkAnyTyConKey :: Unique+zonkAnyTyConKey = mkPreludeTyConUnique 172+ -- Custom user type-errors errorMessageTypeErrorFamKey :: Unique errorMessageTypeErrorFamKey = mkPreludeTyConUnique 181@@ -2023,9 +2026,6 @@ specTyConKey :: Unique specTyConKey = mkPreludeTyConUnique 185 -anyTyConKey :: Unique-anyTyConKey = mkPreludeTyConUnique 186- smallArrayPrimTyConKey        = mkPreludeTyConUnique  187 smallMutableArrayPrimTyConKey = mkPreludeTyConUnique  188 @@ -2641,7 +2641,6 @@    , naturalLogBaseIdKey    , naturalPowModIdKey    , naturalSizeInBaseIdKey-   , bignatFromWordListIdKey    , bignatEqIdKey    , bignatCompareIdKey    , bignatCompareWordIdKey@@ -2709,7 +2708,6 @@ naturalPowModIdKey         = mkPreludeMiscIdUnique 683 naturalSizeInBaseIdKey     = mkPreludeMiscIdUnique 684 -bignatFromWordListIdKey    = mkPreludeMiscIdUnique 690 bignatEqIdKey              = mkPreludeMiscIdUnique 691 bignatCompareIdKey         = mkPreludeMiscIdUnique 692 bignatCompareWordIdKey     = mkPreludeMiscIdUnique 693
GHC/Builtin/PrimOps.hs-boot view
@@ -1,5 +1,6 @@ module GHC.Builtin.PrimOps where -import GHC.Prelude ()+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Base ()  data PrimOp
GHC/Builtin/Types.hs view
@@ -78,6 +78,7 @@         promotedTupleDataCon,         unitTyCon, unitDataCon, unitDataConId, unitTy, unitTyConKey,         soloTyCon,+        soloDataConName,         pairTyCon, mkPromotedPairTy, isPromotedPairType,         unboxedUnitTy,         unboxedUnitTyCon, unboxedUnitDataCon,@@ -91,7 +92,7 @@         cTupleSelId, cTupleSelIdName,          -- * Any-        anyTyCon, anyTy, anyTypeOfKind,+        anyTyCon, anyTy, anyTypeOfKind, zonkAnyTyCon,          -- * Recovery TyCon         makeRecoveryTyCon,@@ -184,7 +185,7 @@ import GHC.Core.TyCon import GHC.Core.Class     ( Class, mkClass ) import GHC.Core.Map.Type  ( TypeMap, emptyTypeMap, extendTypeMap, lookupTypeMap )-import qualified GHC.Core.TyCo.Rep as TyCoRep (Type(TyConApp))+import qualified GHC.Core.TyCo.Rep as TyCoRep ( Type(TyConApp) )  import GHC.Types.TyThing import GHC.Types.SourceText@@ -309,6 +310,7 @@                 , soloTyCon                  , anyTyCon+                , zonkAnyTyCon                 , boolTyCon                 , charTyCon                 , stringTyCon@@ -419,58 +421,107 @@ {- Note [Any types] ~~~~~~~~~~~~~~~~-The type constructor Any,+The type constructors `Any` and `ZonkAny` are closed type families declared thus: -    type family Any :: k where { }+    type family Any     :: forall k.        k where { }+    type family ZonkAny :: forall k. Nat -> k where { } -It has these properties:+They are used when we want a type of a particular kind, but we don't really care+what that type is.  The leading example is this: `ZonkAny` is used to instantiate+un-constrained type variables after type checking. For example, consider the+term (length [] :: Int), where -  * Note that 'Any' is kind polymorphic since in some program we may-    need to use Any to fill in a type variable of some kind other than *-    (see #959 for examples).  Its kind is thus `forall k. k``.+  length :: forall a. [a] -> Int+  []     :: forall a. [a] -  * It is defined in module GHC.Types, and exported so that it is-    available to users.  For this reason it's treated like any other-    wired-in type:-      - has a fixed unique, anyTyConKey,-      - lives in the global name cache+We must type-apply `length` and `[]`, but to what type? It doesn't matter!+The typechecker will end up with -  * It is a *closed* type family, with no instances.  This means that-    if   ty :: '(k1, k2)  we add a given coercion-             g :: ty ~ (Fst ty, Snd ty)-    If Any was a *data* type, then we'd get inconsistency because 'ty'-    could be (Any '(k1,k2)) and then we'd have an equality with Any on-    one side and '(,) on the other. See also #9097 and #9636.+  length @alpha ([] @alpha) -  * When instantiated at a lifted type it is inhabited by at least one value,-    namely bottom+where `alpha` is an un-constrained unification variable.  The "zonking" process zaps+that unconstrained `alpha` to an arbitrary type (ZonkAny @Type 3), where the `3` is+arbitrary (see wrinkle (Any5) below).  This is done in `GHC.Tc.Zonk.Type.commitFlexi`.+So we end up with -  * You can safely coerce any /lifted/ type to Any, and back with unsafeCoerce.+  length @(ZonkAny @Type 3) ([] @(ZonkAny @Type 3)) -  * It does not claim to be a *data* type, and that's important for-    the code generator, because the code gen may *enter* a data value-    but never enters a function value.+`Any` and `ZonkAny` differ only in the presence of the `Nat` argument; see+wrinkle (Any4). -  * It is wired-in so we can easily refer to it where we don't have a name-    environment (e.g. see Rules.matchRule for one example)+Wrinkles: -It's used to instantiate un-constrained type variables after type checking. For-example, 'length' has type+(Any1) `Any` and `ZonkAny` are kind polymorphic since in some program we may+   need to use `ZonkAny` to fill in a type variable of some kind other than *+   (see #959 for examples). -  length :: forall a. [a] -> Int+(Any2) They are /closed/ type families, with no instances.  For example, suppose that+   with  alpha :: '(k1, k2)  we add a given coercion+             g :: alpha ~ (Fst alpha, Snd alpha)+   and we zonked alpha = ZonkAny @(k1,k2) n.  Then, if `ZonkAny` was a /data/ type,+   we'd get inconsistency because we'd have a Given equality with `ZonkAny` on one+   side and '(,) on the other. See also #9097 and #9636. -and the list datacon for the empty list has type+   See #25244 for a suggestion that we instead use an /open/ type family for which+   you cannot provide instances.  Probably the difference is not very important. -  [] :: forall a. [a]+(Any3) They do not claim to be /data/ types, and that's important for+   the code generator, because the code gen may /enter/ a data value+   but never enters a function value. -In order to compose these two terms as @length []@ a type-application is required, but there is no constraint on the-choice.  In this situation GHC uses 'Any',+(Any4) `ZonkAny` takes a `Nat` argument so that we can readily make up /distinct/+   types (#24817).  Consider -> length @(Any @Type) ([] @(Any @Type))+     data SBool a where { STrue :: SBool True; SFalse :: SBool False } -Above, we print kinds explicitly, as if with -fprint-explicit-kinds.+     foo :: forall a b. (SBool a, SBool b) +     bar :: Bool+     bar = case foo @alpha @beta of+             (STrue, SFalse) -> True   -- This branch is not inaccessible!+             _               -> False++   Now, what are `alpha` and `beta`? If we zonk both of them to the same type+   `Any @Type`, the pattern-match checker will (wrongly) report that the first+   branch is inaccessible.  So we zonk them to two /different/ types:+       alpha :=  ZonkAny @Type 4   and   beta :=  ZonkAny @Type k 5+   (The actual numbers are arbitrary; they just need to differ.)++   The unique-name generation comes from field `tcg_zany_n` of `TcGblEnv`; and+   `GHC.Tc.Zonk.Type.commitFlexi` calls `GHC.Tc.Utils.Monad.newZonkAnyType` to+   make up a fresh type.++   If this example seems unconvincing (e.g. in this case foo must be bottom)+   see #24817 for larger but more compelling examples.++(Any5) `Any` and `ZonkAny` are wired-in so we can easily refer to it where we+    don't have a name environment (e.g. see Rules.matchRule for one example)++(Any6) `Any` is defined in library module ghc-prim:GHC.Types, and exported so that+    it is available to users.  For this reason it's treated like any other+    wired-in type:+      - has a fixed unique, anyTyConKey,+      - lives in the global name cache+    Currently `ZonkAny` is not available to users; but it could easily be.++(Any7) Properties of `Any`:+  * When `Any` is instantiated at a lifted type it is inhabited by at least one value,+    namely bottom.++  * You can safely coerce any /lifted/ type to `Any` and back with `unsafeCoerce`.++  * You can safely coerce any /lifted/ type to Any, and back with unsafeCoerce.+  * You can safely coerce any /unlifted/ type to `Any` and back with `unsafeCoerceUnlifted`.++  * You can coerce /any/ type to `Any` and back with `unsafeCoerce#`, but it's only safe when+    the kinds of both the type and `Any` match.++  * For lifted/unlifted types `unsafeCoerce[Unlifted]` should be preferred over+    `unsafeCoerce#` as they prevent accidentally coercing between types with kinds+    that don't match.++    See examples in ghc-prim:GHC.Types+ The Any tycon used to be quite magic, but we have since been able to implement it merely with an empty kind polymorphic type family. See #10886 for a bit of history.@@ -482,6 +533,7 @@     mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Any") anyTyConKey anyTyCon  anyTyCon :: TyCon+-- See Note [Any types] anyTyCon = mkFamilyTyCon anyTyConName binders res_kind Nothing                          (ClosedSynFamilyTyCon Nothing)                          Nothing@@ -496,6 +548,24 @@ anyTypeOfKind :: Kind -> Type anyTypeOfKind kind = mkTyConApp anyTyCon [kind] +zonkAnyTyConName :: Name+zonkAnyTyConName =+    mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "ZonkAny") zonkAnyTyConKey zonkAnyTyCon++zonkAnyTyCon :: TyCon+-- ZonkAnyTyCon :: forall k. Nat -> k+-- See Note [Any types]+zonkAnyTyCon = mkFamilyTyCon zonkAnyTyConName+                         [ mkNamedTyConBinder Specified kv+                         , mkAnonTyConBinder nat_kv ]+                         (mkTyVarTy kv)+                         Nothing+                         (ClosedSynFamilyTyCon Nothing)+                         Nothing+                         NotInjective+  where+    [kv,nat_kv] = mkTemplateKindVars [liftedTypeKind, naturalTy]+ -- | Make a fake, recovery 'TyCon' from an existing one. -- Used when recovering from errors in type declarations makeRecoveryTyCon :: TyCon -> TyCon@@ -827,7 +897,6 @@       ":"    -> Just consDataConName        -- function tycon-      "FUN"  -> Just fUNTyConName       "->"  -> Just unrestrictedFunTyConName        -- tuple data/tycon@@ -986,40 +1055,36 @@     isCTupleOcc_maybe  mod occ <|>     isSumTyOcc_maybe   mod occ -mkTupleOcc :: NameSpace -> Boxity -> Arity -> OccName--- No need to cache these, the caching is done in mk_tuple-mkTupleOcc ns Boxed   ar = mkOccName ns (mkBoxedTupleStr ns ar)-mkTupleOcc ns Unboxed ar = mkOccName ns (mkUnboxedTupleStr ns ar)+mkTupleOcc :: NameSpace -> Boxity -> Arity -> (OccName, BuiltInSyntax)+mkTupleOcc ns b ar = (mkOccName ns str, built_in)+  where (str, built_in) = mkTupleStr' ns b ar  mkCTupleOcc :: NameSpace -> Arity -> OccName mkCTupleOcc ns ar = mkOccName ns (mkConstraintTupleStr ar)  mkTupleStr :: Boxity -> NameSpace -> Arity -> String-mkTupleStr Boxed   = mkBoxedTupleStr-mkTupleStr Unboxed = mkUnboxedTupleStr--mkBoxedTupleStr :: NameSpace -> Arity -> String-mkBoxedTupleStr ns 0-  | isDataConNameSpace ns = "()"-  | otherwise             = "Unit"-mkBoxedTupleStr ns 1-  | isDataConNameSpace ns = "MkSolo"  -- See Note [One-tuples]-  | otherwise             = "Solo"-mkBoxedTupleStr ns ar-  | isDataConNameSpace ns = '(' : commas ar ++ ")"-  | otherwise             = "Tuple" ++ showInt ar ""-+mkTupleStr b ns ar = str+  where (str, _) = mkTupleStr' ns b ar -mkUnboxedTupleStr :: NameSpace -> Arity -> String-mkUnboxedTupleStr ns 0-  | isDataConNameSpace ns = "(##)"-  | otherwise             = "Unit#"-mkUnboxedTupleStr ns 1-  | isDataConNameSpace ns = "(# #)"  -- See Note [One-tuples]-  | otherwise             = "Solo#"-mkUnboxedTupleStr ns ar-  | isDataConNameSpace ns = "(#" ++ commas ar ++ "#)"-  | otherwise             = "Tuple" ++ show ar ++ "#"+mkTupleStr' :: NameSpace -> Boxity -> Arity -> (String, BuiltInSyntax)+mkTupleStr' ns Boxed 0+  | isDataConNameSpace ns = ("()", BuiltInSyntax)+  | otherwise             = ("Unit", UserSyntax)+mkTupleStr' ns Boxed 1+  | isDataConNameSpace ns = ("MkSolo", UserSyntax)  -- See Note [One-tuples]+  | otherwise             = ("Solo",   UserSyntax)+mkTupleStr' ns Boxed ar+  | isDataConNameSpace ns = ('(' : commas ar ++ ")", BuiltInSyntax)+  | otherwise             = ("Tuple" ++ showInt ar "", UserSyntax)+mkTupleStr' ns Unboxed 0+  | isDataConNameSpace ns = ("(##)",  BuiltInSyntax)+  | otherwise             = ("Unit#", UserSyntax)+mkTupleStr' ns Unboxed 1+  | isDataConNameSpace ns = ("(# #)", BuiltInSyntax) -- See Note [One-tuples]+  | otherwise             = ("Solo#", UserSyntax)+mkTupleStr' ns Unboxed ar+  | isDataConNameSpace ns = ("(#" ++ commas ar ++ "#)", BuiltInSyntax)+  | otherwise             = ("Tuple" ++ show ar ++ "#", UserSyntax)  mkConstraintTupleStr :: Arity -> String mkConstraintTupleStr 0 = "CUnit"@@ -1175,10 +1240,10 @@      boxity  = Boxed     modu    = gHC_INTERNAL_TUPLE-    tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq-                         (ATyCon tycon) UserSyntax-    dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq-                            (AConLike (RealDataCon tuple_con)) BuiltInSyntax+    tc_name = mkWiredInName modu occ tc_uniq (ATyCon tycon) built_in+      where (occ, built_in) = mkTupleOcc tcName boxity arity+    dc_name = mkWiredInName modu occ dc_uniq (AConLike (RealDataCon tuple_con)) built_in+      where (occ, built_in) = mkTupleOcc dataName boxity arity     tc_uniq = mkTupleTyConUnique   boxity arity     dc_uniq = mkTupleDataConUnique boxity arity @@ -1209,10 +1274,10 @@      boxity  = Unboxed     modu    = gHC_TYPES-    tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq-                         (ATyCon tycon) UserSyntax-    dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq-                            (AConLike (RealDataCon tuple_con)) BuiltInSyntax+    tc_name = mkWiredInName modu occ tc_uniq (ATyCon tycon) built_in+      where (occ, built_in) = mkTupleOcc tcName boxity arity+    dc_name = mkWiredInName modu occ dc_uniq (AConLike (RealDataCon tuple_con)) built_in+      where (occ, built_in) = mkTupleOcc dataName boxity arity     tc_uniq = mkTupleTyConUnique   boxity arity     dc_uniq = mkTupleDataConUnique boxity arity @@ -1275,6 +1340,9 @@  soloTyConName :: Name soloTyConName = tyConName soloTyCon++soloDataConName :: Name+soloDataConName = tupleDataConName Boxed 1  pairTyCon :: TyCon pairTyCon = tupleTyCon Boxed 2
GHC/Builtin/Types/Prim.hs view
@@ -63,7 +63,8 @@         doublePrimTyCon,        doublePrimTy, doublePrimTyConName,          statePrimTyCon,         mkStatePrimTy,-        realWorldTyCon,         realWorldTy, realWorldStatePrimTy,+        realWorldTyCon,         realWorldTy,+        realWorldStatePrimTy,   realWorldMutableByteArrayPrimTy,          proxyPrimTyCon,         mkProxyPrimTy, @@ -1178,7 +1179,9 @@ realWorldTy          = mkTyConTy realWorldTyCon realWorldStatePrimTy :: Type realWorldStatePrimTy = mkStatePrimTy realWorldTy        -- State# RealWorld-+realWorldMutableByteArrayPrimTy :: Type+realWorldMutableByteArrayPrimTy+  = mkMutableByteArrayPrimTy realWorldTy -- MutableByteArray# RealWorld  mkProxyPrimTy :: Type -> Type -> Type mkProxyPrimTy k ty = TyConApp proxyPrimTyCon [k, ty]
GHC/Builtin/primops.txt.pp view
@@ -2630,18 +2630,45 @@ section "Exceptions" ------------------------------------------------------------------------ --- Note [Strictness for mask/unmask/catch]--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- Note [Strict IO wrappers]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -- Consider this example, which comes from GHC.IO.Handle.Internals:---    wantReadableHandle3 f ma b st+--    wantReadableHandle3 f mv b st --      = case ... of---          DEFAULT -> case ma of MVar a -> ...---          0#      -> maskAsyncExceptions# (\st -> case ma of MVar a -> ...)+--          DEFAULT -> case mv of MVar a -> ...+--          0#      -> maskAsyncExceptions# (\st -> case mv of MVar a -> ...) -- The outer case just decides whether to mask exceptions, but we don't want--- thereby to hide the strictness in 'ma'!  Hence the use of strictOnceApply1Dmd--- in mask and unmask. But catch really is lazy in its first argument, see--- #11555. So for IO actions 'ma' we often use a wrapper around it that is--- head-strict in 'ma': GHC.IO.catchException.+-- thereby to hide the strictness in `mv`!  Hence the use of strictOnceApply1Dmd+-- in mask#, unmask# and atomically# (where we use strictManyApply1Dmd to respect+-- that it potentially calls its action multiple times).+--+-- Note [Strictness for catch-style primops]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- The catch#-style primops always call their action, just like outlined+-- in Note [Strict IO wrappers].+-- However, it is important that we give their first arg lazyApply1Dmd and not+-- strictOnceApply1Dmd, like for mask#. Here is why. Consider a call+--+--   catch# act handler s+--+-- If `act = raiseIO# ...`, using strictOnceApply1Dmd for `act` would mean that+-- the call forwards the dead-end flag from `act` (see Note [Dead ends] and+-- Note [Precise exceptions and strictness analysis]).+-- This would cause dead code elimination to discard the continuation of the+-- catch# call, among other things. This first came up in #11555.+--+-- Hence catch# uses lazyApply1Dmd in order /not/ to forward the dead-end flag+-- from `act`. (This is a bit brutal, but the language of strictness types is+-- not expressive enough to give it a more precise semantics that is still+-- sound.)+-- For perf reasons we often (but not always) choose to use a wrapper around+-- catch# that is head-strict in `act`: GHC.IO.catchException.+--+-- A similar caveat applies to prompt#, which can be seen as a+-- generalisation of catch# as explained in GHC.Prim#continuations#.+-- The reason is that even if `act` appears dead-ending (e.g., looping)+-- `prompt# tag ma s` might return alright due to a (higher-order) use of+-- `control0#` in `act`. This came up in #25439.  primop  CatchOp "catch#" GenPrimOp           (State# RealWorld -> (# State# RealWorld, a_reppoly #) )@@ -2658,7 +2685,7 @@    strictness  = { \ _arity -> mkClosedDmdSig [ lazyApply1Dmd                                                  , lazyApply2Dmd                                                  , topDmd] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strictness for catch-style primops]    out_of_line = True    effect = ReadWriteEffect    -- Either inner computation might potentially raise an unchecked exception,@@ -2724,7 +2751,7 @@      in continuation-style primops\" for details. }    with    strictness  = { \ _arity -> mkClosedDmdSig [strictOnceApply1Dmd,topDmd] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strict IO wrappers]    out_of_line = True    effect = ReadWriteEffect @@ -2739,6 +2766,7 @@      in continuation-style primops\" for details. }    with    strictness  = { \ _arity -> mkClosedDmdSig [strictOnceApply1Dmd,topDmd] topDiv }+                 -- See Note [Strict IO wrappers]    out_of_line = True    effect = ReadWriteEffect @@ -2753,7 +2781,7 @@      in continuation-style primops\" for details. }    with    strictness  = { \ _arity -> mkClosedDmdSig [strictOnceApply1Dmd,topDmd] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strict IO wrappers]    out_of_line = True    effect = ReadWriteEffect @@ -2939,7 +2967,8 @@      -> State# RealWorld -> (# State# RealWorld, a #)    { See "GHC.Prim#continuations". }    with-   strictness = { \ _arity -> mkClosedDmdSig [topDmd, strictOnceApply1Dmd, topDmd] topDiv }+   strictness = { \ _arity -> mkClosedDmdSig [topDmd, lazyApply1Dmd, topDmd] topDiv }+                 -- See Note [Strictness for catch-style primops]    out_of_line = True    effect = ReadWriteEffect @@ -2967,7 +2996,7 @@    -> State# RealWorld -> (# State# RealWorld, a_levpoly #)    with    strictness  = { \ _arity -> mkClosedDmdSig [strictManyApply1Dmd,topDmd] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strict IO wrappers]    out_of_line = True    effect = ReadWriteEffect @@ -2996,7 +3025,7 @@    strictness  = { \ _arity -> mkClosedDmdSig [ lazyApply1Dmd                                                  , lazyApply1Dmd                                                  , topDmd ] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strictness for catch-style primops]    out_of_line = True    effect = ReadWriteEffect @@ -3008,7 +3037,7 @@    strictness  = { \ _arity -> mkClosedDmdSig [ lazyApply1Dmd                                                  , lazyApply2Dmd                                                  , topDmd ] topDiv }-                 -- See Note [Strictness for mask/unmask/catch]+                 -- See Note [Strictness for catch-style primops]    out_of_line = True    effect = ReadWriteEffect @@ -3695,6 +3724,7 @@    with    out_of_line = True    strictness = { \ _arity -> mkClosedDmdSig [topDmd, topDmd, strictOnceApply1Dmd] topDiv }+                 -- See Note [Strict IO wrappers]    effect = ReadWriteEffect    -- The invoked computation may have side effects 
GHC/ByteCode/Asm.hs view
@@ -71,9 +71,9 @@   where     bco_refs (UnlinkedBCO _ _ _ _ nonptrs ptrs)         = unionManyUniqDSets (-             mkUniqDSet [ n | BCOPtrName n <- ssElts ptrs ] :-             mkUniqDSet [ n | BCONPtrItbl n <- ssElts nonptrs ] :-             map bco_refs [ bco | BCOPtrBCO bco <- ssElts ptrs ]+             mkUniqDSet [ n | BCOPtrName n <- elemsFlatBag ptrs ] :+             mkUniqDSet [ n | BCONPtrItbl n <- elemsFlatBag nonptrs ] :+             map bco_refs [ bco | BCOPtrBCO bco <- elemsFlatBag ptrs ]           )  -- -----------------------------------------------------------------------------@@ -213,9 +213,9 @@              (text "bytecode instruction count mismatch")    let asm_insns = ssElts final_insns-      insns_arr = Array.listArray (0, fromIntegral n_insns - 1) asm_insns-      bitmap_arr = mkBitmapArray bsize bitmap-      ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr final_lits final_ptrs+      !insns_arr =  mkBCOByteArray $ Array.listArray (0 :: Int, fromIntegral n_insns - 1) asm_insns+      !bitmap_arr = mkBCOByteArray $ mkBitmapArray bsize bitmap+      ul_bco = UnlinkedBCO nm arity insns_arr bitmap_arr (fromSizedSeq final_lits) (fromSizedSeq final_ptrs)    -- 8 Aug 01: Finalisers aren't safe when attached to non-primitive   -- objects, since they might get run too early.  Disable this until@@ -224,7 +224,7 @@    return ul_bco -mkBitmapArray :: Word -> [StgWord] -> UArray Int Word64+mkBitmapArray :: Word -> [StgWord] -> UArray Int Word -- Here the return type must be an array of Words, not StgWords, -- because the underlying ByteArray# will end up as a component -- of a BCO object.@@ -513,11 +513,16 @@   CCALL off m_addr i       -> do np <- addr m_addr                                  emit bci_CCALL [wOp off, Op np, SmallOp i]   PRIMCALL                 -> emit bci_PRIMCALL []-  BRK_FUN arr index mod cc -> do p1 <- ptr (BCOPtrBreakArray arr)-                                 m <- addr mod+  BRK_FUN arr tick_mod tickx info_mod infox cc ->+                              do p1 <- ptr (BCOPtrBreakArray arr)+                                 tick_addr <- addr tick_mod+                                 info_addr <- addr info_mod                                  np <- addr cc-                                 emit bci_BRK_FUN [Op p1, SmallOp index,-                                                   Op m, Op np]+                                 emit bci_BRK_FUN [ Op p1+                                                  , Op tick_addr, Op info_addr+                                                  , SmallOp tickx, SmallOp infox+                                                  , Op np+                                                  ]    where     literal (LitLabel fs (Just sz) _)
GHC/ByteCode/Instr.hs view
@@ -83,7 +83,7 @@    | PUSH16_W !ByteOff    | PUSH32_W !ByteOff -   -- Push a ptr  (these all map to PUSH_G really)+   -- Push a (heap) ptr  (these all map to PUSH_G really)    | PUSH_G       Name    | PUSH_PRIMOP  PrimOp    | PUSH_BCO     (ProtoBCO Name)@@ -206,7 +206,11 @@                    -- Note [unboxed tuple bytecodes and tuple_BCO] in GHC.StgToByteCode     -- Breakpoints-   | BRK_FUN          (ForeignRef BreakArray) !Word16 (RemotePtr ModuleName)+   | BRK_FUN          (ForeignRef BreakArray)+                      (RemotePtr ModuleName) -- breakpoint tick module+                      !Word16                -- breakpoint tick index+                      (RemotePtr ModuleName) -- breakpoint info module+                      !Word16                -- breakpoint info index                       (RemotePtr CostCentre)  -- -----------------------------------------------------------------------------@@ -358,8 +362,11 @@    ppr ENTER                 = text "ENTER"    ppr (RETURN pk)           = text "RETURN  " <+> ppr pk    ppr (RETURN_TUPLE)        = text "RETURN_TUPLE"-   ppr (BRK_FUN _ index _ _) = text "BRK_FUN" <+> text "<breakarray>"-                               <+> ppr index <+> text "<module>" <+> text "<cc>"+   ppr (BRK_FUN _ _tick_mod tickx _info_mod infox _)+                             = text "BRK_FUN" <+> text "<breakarray>"+                               <+> text "<tick_module>" <+> ppr tickx+                               <+> text "<info_module>" <+> ppr infox+                               <+> text "<cc>"   
GHC/ByteCode/Linker.hs view
@@ -24,6 +24,7 @@ import GHCi.ResolvedBCO  import GHC.Builtin.PrimOps+import GHC.Builtin.PrimOps.Ids import GHC.Builtin.Names  import GHC.Unit.Types@@ -38,6 +39,8 @@  import GHC.Types.Name import GHC.Types.Name.Env+import qualified GHC.Types.Id as Id+import GHC.Types.Unique.DFM  import Language.Haskell.Syntax.Module.Name @@ -52,31 +55,35 @@  linkBCO   :: Interp+  -> PkgsLoaded   -> LinkerEnv   -> NameEnv Int   -> UnlinkedBCO   -> IO ResolvedBCO-linkBCO interp le bco_ix+linkBCO interp pkgs_loaded le bco_ix            (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do   -- fromIntegral Word -> Word64 should be a no op if Word is Word64   -- otherwise it will result in a cast to longlong on 32bit systems.-  lits <- mapM (fmap fromIntegral . lookupLiteral interp le) (ssElts lits0)-  ptrs <- mapM (resolvePtr interp le bco_ix) (ssElts ptrs0)-  return (ResolvedBCO isLittleEndian arity insns bitmap-              (listArray (0, fromIntegral (sizeSS lits0)-1) lits)+  (lits :: [Word]) <- mapM (fmap fromIntegral . lookupLiteral interp pkgs_loaded le) (elemsFlatBag lits0)+  ptrs <- mapM (resolvePtr interp pkgs_loaded le bco_ix) (elemsFlatBag ptrs0)+  let lits' = listArray (0 :: Int, fromIntegral (sizeFlatBag lits0)-1) lits+  return (ResolvedBCO isLittleEndian arity+              insns+              bitmap+              (mkBCOByteArray lits')               (addListToSS emptySS ptrs)) -lookupLiteral :: Interp -> LinkerEnv -> BCONPtr -> IO Word-lookupLiteral interp le ptr = case ptr of+lookupLiteral :: Interp -> PkgsLoaded -> LinkerEnv -> BCONPtr -> IO Word+lookupLiteral interp pkgs_loaded le ptr = case ptr of   BCONPtrWord lit -> return lit   BCONPtrLbl  sym -> do     Ptr a# <- lookupStaticPtr interp sym     return (W# (int2Word# (addr2Int# a#)))   BCONPtrItbl nm -> do-    Ptr a# <- lookupIE interp (itbl_env le) nm+    Ptr a# <- lookupIE interp pkgs_loaded (itbl_env le) nm     return (W# (int2Word# (addr2Int# a#)))   BCONPtrAddr nm -> do-    Ptr a# <- lookupAddr interp (addr_env le) nm+    Ptr a# <- lookupAddr interp pkgs_loaded (addr_env le) nm     return (W# (int2Word# (addr2Int# a#)))   BCONPtrStr _ ->     -- should be eliminated during assembleBCOs@@ -90,19 +97,19 @@     Nothing  -> linkFail "GHC.ByteCode.Linker: can't find label"                   (unpackFS addr_of_label_string) -lookupIE :: Interp -> ItblEnv -> Name -> IO (Ptr ())-lookupIE interp ie con_nm =+lookupIE :: Interp -> PkgsLoaded -> ItblEnv -> Name -> IO (Ptr ())+lookupIE interp pkgs_loaded ie con_nm =   case lookupNameEnv ie con_nm of     Just (_, ItblPtr a) -> return (fromRemotePtr (castRemotePtr a))     Nothing -> do -- try looking up in the object files.        let sym_to_find1 = nameToCLabel con_nm "con_info"-       m <- lookupSymbol interp sym_to_find1+       m <- lookupHsSymbol interp pkgs_loaded con_nm "con_info"        case m of           Just addr -> return addr           Nothing              -> do -- perhaps a nullary constructor?                    let sym_to_find2 = nameToCLabel con_nm "static_info"-                   n <- lookupSymbol interp sym_to_find2+                   n <- lookupHsSymbol interp pkgs_loaded con_nm "static_info"                    case n of                       Just addr -> return addr                       Nothing   -> linkFail "GHC.ByteCode.Linker.lookupIE"@@ -110,34 +117,35 @@                                        unpackFS sym_to_find2)  -- see Note [Generating code for top-level string literal bindings] in GHC.StgToByteCode-lookupAddr :: Interp -> AddrEnv -> Name -> IO (Ptr ())-lookupAddr interp ae addr_nm = do+lookupAddr :: Interp -> PkgsLoaded -> AddrEnv -> Name -> IO (Ptr ())+lookupAddr interp pkgs_loaded ae addr_nm = do   case lookupNameEnv ae addr_nm of     Just (_, AddrPtr ptr) -> return (fromRemotePtr ptr)     Nothing -> do -- try looking up in the object files.       let sym_to_find = nameToCLabel addr_nm "bytes"                           -- see Note [Bytes label] in GHC.Cmm.CLabel-      m <- lookupSymbol interp sym_to_find+      m <- lookupHsSymbol interp pkgs_loaded addr_nm "bytes"       case m of         Just ptr -> return ptr         Nothing -> linkFail "GHC.ByteCode.Linker.lookupAddr"                      (unpackFS sym_to_find) -lookupPrimOp :: Interp -> PrimOp -> IO (RemotePtr ())-lookupPrimOp interp primop = do+lookupPrimOp :: Interp -> PkgsLoaded -> PrimOp -> IO (RemotePtr ())+lookupPrimOp interp pkgs_loaded primop = do   let sym_to_find = primopToCLabel primop "closure"-  m <- lookupSymbol interp (mkFastString sym_to_find)+  m <- lookupHsSymbol interp pkgs_loaded (Id.idName $ primOpId primop) "closure"   case m of     Just p -> return (toRemotePtr p)     Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE(primop)" sym_to_find  resolvePtr   :: Interp+  -> PkgsLoaded   -> LinkerEnv   -> NameEnv Int   -> BCOPtr   -> IO ResolvedBCOPtr-resolvePtr interp le bco_ix ptr = case ptr of+resolvePtr interp pkgs_loaded le bco_ix ptr = case ptr of   BCOPtrName nm     | Just ix <- lookupNameEnv bco_ix nm     -> return (ResolvedBCORef ix) -- ref to another BCO in this group@@ -149,19 +157,41 @@     -> assertPpr (isExternalName nm) (ppr nm) $        do           let sym_to_find = nameToCLabel nm "closure"-          m <- lookupSymbol interp sym_to_find+          m <- lookupHsSymbol interp pkgs_loaded nm "closure"           case m of             Just p -> return (ResolvedBCOStaticPtr (toRemotePtr p))             Nothing -> linkFail "GHC.ByteCode.Linker.lookupCE" (unpackFS sym_to_find)    BCOPtrPrimOp op-    -> ResolvedBCOStaticPtr <$> lookupPrimOp interp op+    -> ResolvedBCOStaticPtr <$> lookupPrimOp interp pkgs_loaded op    BCOPtrBCO bco-    -> ResolvedBCOPtrBCO <$> linkBCO interp le bco_ix bco+    -> ResolvedBCOPtrBCO <$> linkBCO interp pkgs_loaded le bco_ix bco    BCOPtrBreakArray breakarray     -> withForeignRef breakarray $ \ba -> return (ResolvedBCOPtrBreakArray ba)++-- | Look up the address of a Haskell symbol in the currently+-- loaded units.+--+-- See Note [Looking up symbols in the relevant objects].+lookupHsSymbol :: Interp -> PkgsLoaded -> Name -> String -> IO (Maybe (Ptr ()))+lookupHsSymbol interp pkgs_loaded nm sym_suffix = do+  massertPpr (isExternalName nm) (ppr nm)+  let sym_to_find = nameToCLabel nm sym_suffix+      pkg_id = moduleUnitId $ nameModule nm+      loaded_dlls = maybe [] loaded_pkg_hs_dlls $ lookupUDFM pkgs_loaded pkg_id++      go (dll:dlls) = do+        mb_ptr <- lookupSymbolInDLL interp dll sym_to_find+        case mb_ptr of+          Just ptr -> pure (Just ptr)+          Nothing -> go dlls+      go [] =+        -- See Note [Symbols may not be found in pkgs_loaded] in GHC.Linker.Types+        lookupSymbol interp sym_to_find++  go loaded_dlls  linkFail :: String -> String -> IO a linkFail who what
GHC/ByteCode/Types.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards            #-} {-# LANGUAGE TypeApplications           #-}+{-# LANGUAGE MagicHash                  #-}+{-# LANGUAGE UnliftedNewtypes           #-} -- --  (c) The University of Glasgow 2002-2006 --@@ -8,6 +10,7 @@ -- | Bytecode assembler types module GHC.ByteCode.Types   ( CompiledByteCode(..), seqCompiledByteCode+  , BCOByteArray(..), mkBCOByteArray   , FFIInfo(..)   , RegBitmap(..)   , NativeCallType(..), NativeCallInfo(..), voidTupleReturnInfo, voidPrimCallInfo@@ -18,12 +21,13 @@   , CgBreakInfo(..)   , ModBreaks (..), BreakIndex, emptyModBreaks   , CCostCentre+  , FlatBag, sizeFlatBag, fromSizedSeq, elemsFlatBag   ) where  import GHC.Prelude  import GHC.Data.FastString-import GHC.Data.SizedSeq+import GHC.Data.FlatBag import GHC.Types.Name import GHC.Types.Name.Env import GHC.Utils.Outputable@@ -33,10 +37,10 @@ import GHCi.RemoteTypes import GHCi.FFI import Control.DeepSeq+import GHCi.ResolvedBCO ( BCOByteArray(..), mkBCOByteArray )  import Foreign import Data.Array-import Data.Array.Base  ( UArray(..) ) import Data.ByteString (ByteString) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap@@ -152,10 +156,10 @@    = UnlinkedBCO {         unlinkedBCOName   :: !Name,         unlinkedBCOArity  :: {-# UNPACK #-} !Int,-        unlinkedBCOInstrs :: !(UArray Int Word16),      -- insns-        unlinkedBCOBitmap :: !(UArray Int Word64),      -- bitmap-        unlinkedBCOLits   :: !(SizedSeq BCONPtr),       -- non-ptrs-        unlinkedBCOPtrs   :: !(SizedSeq BCOPtr)         -- ptrs+        unlinkedBCOInstrs :: !(BCOByteArray Word16),      -- insns+        unlinkedBCOBitmap :: !(BCOByteArray Word),      -- bitmap+        unlinkedBCOLits   :: !(FlatBag BCONPtr),       -- non-ptrs+        unlinkedBCOPtrs   :: !(FlatBag BCOPtr)         -- ptrs    }  instance NFData UnlinkedBCO where@@ -210,8 +214,8 @@ instance Outputable UnlinkedBCO where    ppr (UnlinkedBCO nm _arity _insns _bitmap lits ptrs)       = sep [text "BCO", ppr nm, text "with",-             ppr (sizeSS lits), text "lits",-             ppr (sizeSS ptrs), text "ptrs" ]+             ppr (sizeFlatBag lits), text "lits",+             ppr (sizeFlatBag ptrs), text "ptrs" ]  instance Outputable CgBreakInfo where    ppr info = text "CgBreakInfo" <+>
GHC/Cmm/Dominators.hs view
@@ -23,7 +23,6 @@ import GHC.Prelude  import Data.Array.IArray-import Data.Foldable() import qualified Data.Tree as Tree  import Data.Word
GHC/Cmm/Lexer.hs view
@@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-missing-signatures #-} {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-}-{-# LINE 13 "_build/source-dist/ghc-9.10.1-src/ghc-9.10.1/compiler/GHC/Cmm/Lexer.x" #-}+{-# LINE 13 "_build/source-dist/ghc-9.10.2-src/ghc-9.10.2/compiler/GHC/Cmm/Lexer.x" #-} module GHC.Cmm.Lexer (    CmmToken(..), cmmlex,   ) where@@ -680,7 +680,7 @@         -- match when checking the right context, just         -- the first match will do. #endif-{-# LINE 134 "_build/source-dist/ghc-9.10.1-src/ghc-9.10.1/compiler/GHC/Cmm/Lexer.x" #-}+{-# LINE 134 "_build/source-dist/ghc-9.10.2-src/ghc-9.10.2/compiler/GHC/Cmm/Lexer.x" #-} data CmmToken   = CmmT_SpecChar  Char   | CmmT_DotDot
GHC/Cmm/Opt.hs view
@@ -213,23 +213,33 @@   = Just $! CmmMachOp op [pic, CmmLit $ cmmOffsetLit lit off ]   where off = fromIntegral (narrowS rep n) --- Make a RegOff if we can+-- Make a RegOff if we can. We don't perform this optimization if rep is greater+-- than the host word size because we use an Int to store the offset. See+-- #24893 and #24700. This should be fixed to ensure that optimizations don't+-- depend on the compiler host platform. cmmMachOpFoldM _ (MO_Add _) [CmmReg reg, CmmLit (CmmInt n rep)]+  | validOffsetRep rep   = Just $! cmmRegOff reg (fromIntegral (narrowS rep n)) cmmMachOpFoldM _ (MO_Add _) [CmmRegOff reg off, CmmLit (CmmInt n rep)]+  | validOffsetRep rep   = Just $! cmmRegOff reg (off + fromIntegral (narrowS rep n)) cmmMachOpFoldM _ (MO_Sub _) [CmmReg reg, CmmLit (CmmInt n rep)]+  | validOffsetRep rep   = Just $! cmmRegOff reg (- fromIntegral (narrowS rep n)) cmmMachOpFoldM _ (MO_Sub _) [CmmRegOff reg off, CmmLit (CmmInt n rep)]+  | validOffsetRep rep   = Just $! cmmRegOff reg (off - fromIntegral (narrowS rep n))  -- Fold label(+/-)offset into a CmmLit where possible  cmmMachOpFoldM _ (MO_Add _) [CmmLit lit, CmmLit (CmmInt i rep)]+  | validOffsetRep rep   = Just $! CmmLit (cmmOffsetLit lit (fromIntegral (narrowU rep i))) cmmMachOpFoldM _ (MO_Add _) [CmmLit (CmmInt i rep), CmmLit lit]+  | validOffsetRep rep   = Just $! CmmLit (cmmOffsetLit lit (fromIntegral (narrowU rep i))) cmmMachOpFoldM _ (MO_Sub _) [CmmLit lit, CmmLit (CmmInt i rep)]+  | validOffsetRep rep   = Just $! CmmLit (cmmOffsetLit lit (fromIntegral (negate (narrowU rep i))))  @@ -409,6 +419,13 @@ -- Anything else is just too hard.  cmmMachOpFoldM _ _ _ = Nothing++-- | Check that a literal width is compatible with the host word size used to+-- store offsets. This should be fixed properly (using larger types to store+-- literal offsets). See #24893+validOffsetRep :: Width -> Bool+validOffsetRep rep = widthInBits rep <= finiteBitSize (undefined :: Int)+  {- Note [Comparison operators] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GHC/Cmm/ThreadSanitizer.hs view
@@ -184,7 +184,7 @@     restore = blockFromList restore_nodes  -- | Mirrors __tsan_memory_order--- <https://github.com/llvm-mirror/compiler-rt/blob/master/include/sanitizer/tsan_interface_atomic.h#L32>+-- <https://github.com/llvm/llvm-project/blob/main/compiler-rt/include/sanitizer/tsan_interface_atomic.h#L34> memoryOrderToTsanMemoryOrder :: Env -> MemoryOrdering -> CmmExpr memoryOrderToTsanMemoryOrder env mord =     mkIntExpr (platform env) n@@ -294,4 +294,3 @@            AMO_Or   -> "fetch_or"            AMO_Xor  -> "fetch_xor"     fn = fsLit $ "__tsan_atomic" ++ show (widthInBits w) ++ "_" ++ op'-
GHC/CmmToAsm/AArch64.hs view
@@ -47,6 +47,7 @@         patchRegsOfInstr        = AArch64.patchRegsOfInstr         isJumpishInstr          = AArch64.isJumpishInstr         jumpDestsOfInstr        = AArch64.jumpDestsOfInstr+        canFallthroughTo        = AArch64.canFallthroughTo         patchJumpInstr          = AArch64.patchJumpInstr         mkSpillInstr            = AArch64.mkSpillInstr         mkLoadInstr             = AArch64.mkLoadInstr
GHC/CmmToAsm/AArch64/CodeGen.hs view
@@ -1556,7 +1556,7 @@   -- pprTraceM "genCCall target" (ppr target)   -- pprTraceM "genCCall formal" (ppr dest_regs)   -- pprTraceM "genCCall actual" (ppr arg_regs)-+  platform <- getPlatform   case target of     -- The target :: ForeignTarget call can either     -- be a foreign procedure with an address expr@@ -1584,7 +1584,6 @@       let (_res_hints, arg_hints) = foreignTargetHints target           arg_regs'' = zipWith (\(r, f, c) h -> (r,f,h,c)) arg_regs' arg_hints -      platform <- getPlatform       let packStack = platformOS platform == OSDarwin        (stackSpace', passRegs, passArgumentsCode) <- passArguments packStack allGpArgRegs allFpArgRegs arg_regs'' 0 [] nilOL@@ -1595,7 +1594,7 @@                        then 8 * (stackSpace' `div` 8 + 1)                        else stackSpace' -      (returnRegs, readResultsCode)   <- readResults allGpArgRegs allFpArgRegs dest_regs [] nilOL+      readResultsCode <- readResults allGpArgRegs allFpArgRegs dest_regs [] nilOL        let moveStackDown 0 = toOL [ PUSH_STACK_FRAME                                  , DELTA (-16) ]@@ -1613,7 +1612,7 @@       let code =    call_target_code          -- compute the label (possibly into a register)             `appOL` moveStackDown (stackSpace `div` 8)             `appOL` passArgumentsCode         -- put the arguments into x0, ...-            `appOL` (unitOL $ BL call_target passRegs returnRegs) -- branch and link.+            `appOL` (unitOL $ BL call_target passRegs) -- branch and link.             `appOL` readResultsCode           -- parse the results into registers             `appOL` moveStackUp (stackSpace `div` 8)       return (code, Nothing)@@ -1621,10 +1620,303 @@     PrimTarget MO_F32_Fabs       | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs ->         unaryFloatOp W32 (\d x -> unitOL $ FABS d x) arg_reg dest_reg+      | otherwise -> panic "mal-formed MO_F32_Fabs"     PrimTarget MO_F64_Fabs       | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs ->         unaryFloatOp W64 (\d x -> unitOL $ FABS d x) arg_reg dest_reg+      | otherwise -> panic "mal-formed MO_F64_Fabs"+    PrimTarget MO_F32_Sqrt+      | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs ->+        unaryFloatOp W32 (\d x -> unitOL $ FSQRT d x) arg_reg dest_reg+      | otherwise -> panic "mal-formed MO_F32_Sqrt"+    PrimTarget MO_F64_Sqrt+      | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs ->+        unaryFloatOp W64 (\d x -> unitOL $ FSQRT d x) arg_reg dest_reg+      | otherwise -> panic "mal-formed MO_F64_Sqrt" ++    PrimTarget (MO_S_Mul2 w)+          -- Life is easier when we're working with word sized operands,+          -- we can use SMULH to compute the high 64 bits, and dst_needed+          -- checks if the high half's bits are all the same as the low half's+          -- top bit.+          | w == W64+          , [src_a, src_b] <- arg_regs+          -- dst_needed = did the result fit into just the low half+          , [dst_needed, dst_hi, dst_lo] <- dest_regs+            ->  do+              (reg_a, _format_x, code_x) <- getSomeReg src_a+              (reg_b, _format_y, code_y) <- getSomeReg src_b++              let lo = getRegisterReg platform (CmmLocal dst_lo)+                  hi = getRegisterReg platform (CmmLocal dst_hi)+                  nd = getRegisterReg platform (CmmLocal dst_needed)+              return (+                  code_x `appOL`+                  code_y `snocOL`+                  MUL   (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL`+                  SMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL`+                  -- Are all high bits equal to the sign bit of the low word?+                  -- nd = (hi == ASR(lo,width-1)) ? 1 : 0+                  CMP   (OpReg W64 hi) (OpRegShift W64 lo SASR (widthInBits w - 1)) `snocOL`+                  CSET  (OpReg W64 nd) NE+                  , Nothing)+            -- For sizes < platform width, we can just perform a multiply and shift+            -- using the normal 64 bit multiply. Calculating the dst_needed value is+            -- complicated a little by the need to be careful when truncation happens.+            -- Currently this case can't be generated since+            -- timesInt2# :: Int# -> Int# -> (# Int#, Int#, Int# #)+            -- TODO: Should this be removed or would other primops be useful?+          | w < W64+          , [src_a, src_b] <- arg_regs+          , [dst_needed, dst_hi, dst_lo] <- dest_regs+            ->  do+              (reg_a', _format_x, code_a) <- getSomeReg src_a+              (reg_b', _format_y, code_b) <- getSomeReg src_b++              let lo = getRegisterReg platform (CmmLocal dst_lo)+                  hi = getRegisterReg platform (CmmLocal dst_hi)+                  nd = getRegisterReg platform (CmmLocal dst_needed)+                  -- Do everything in a full 64 bit registers+                  w' = platformWordWidth platform++              (reg_a, code_a') <- signExtendReg w w' reg_a'+              (reg_b, code_b') <- signExtendReg w w' reg_b'++              return (+                  code_a  `appOL`+                  code_b  `appOL`+                  code_a' `appOL`+                  code_b' `snocOL`+                  -- the low 2w' of lo contains the full multiplication;+                  -- eg: int8 * int8 -> int16 result+                  -- so lo is in the last w of the register, and hi is in the second w.+                  SMULL (OpReg w' lo) (OpReg w' reg_a) (OpReg w' reg_b) `snocOL`+                  -- Make sure we hold onto the sign bits for dst_needed+                  ASR (OpReg w' hi) (OpReg w' lo)    (OpImm (ImmInt $ widthInBits w)) `appOL`+                  -- lo can now be truncated so we can get at it's top bit easily.+                  truncateReg w' w lo `snocOL`+                  -- Note the use of CMN (compare negative), not CMP: we want to+                  -- test if the top half is negative one and the top+                  -- bit of the bottom half is positive one. eg:+                  -- hi = 0b1111_1111  (actually 64 bits)+                  -- lo = 0b1010_1111  (-81, so the result didn't need the top half)+                  -- lo' = ASR(lo,7)   (second reg of SMN)+                  --     = 0b0000_0001 (theeshift gives us 1 for negative,+                  --                    and 0 for positive)+                  -- hi == -lo'?+                  -- 0b1111_1111 == 0b1111_1111 (yes, top half is just overflow)+                  -- Another way to think of this is if hi + lo' == 0, which is what+                  -- CMN really is under the hood.+                  CMN   (OpReg w' hi) (OpRegShift w' lo SLSR (widthInBits w - 1)) `snocOL`+                  -- Set dst_needed to 1 if hi and lo' were (negatively) equal+                  CSET  (OpReg w' nd) EQ `appOL`+                  -- Finally truncate hi to drop any extraneous sign bits.+                  truncateReg w' w hi+                  , Nothing)+          -- Can't handle > 64 bit operands+          | otherwise -> unsupported (MO_S_Mul2 w)+    PrimTarget (MO_U_Mul2  w)+          -- The unsigned case is much simpler than the signed, all we need to+          -- do is the multiplication straight into the destination registers.+          | w == W64+          , [src_a, src_b] <- arg_regs+          , [dst_hi, dst_lo] <- dest_regs+            ->  do+              (reg_a, _format_x, code_x) <- getSomeReg src_a+              (reg_b, _format_y, code_y) <- getSomeReg src_b++              let lo = getRegisterReg platform (CmmLocal dst_lo)+                  hi = getRegisterReg platform (CmmLocal dst_hi)+              return (+                  code_x `appOL`+                  code_y `snocOL`+                  MUL   (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL`+                  UMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b)+                  , Nothing)+            -- For sizes < platform width, we can just perform a multiply and shift+            -- Need to be careful to truncate the low half, but the upper half should be+            -- be ok if the invariant in [Signed arithmetic on AArch64] is maintained.+            -- Currently this case can't be produced by the compiler since+            -- timesWord2# :: Word# -> Word# -> (# Word#, Word# #)+            -- TODO: Remove? Or would the extra primop be useful for avoiding the extra+            -- steps needed to do this in userland?+          | w < W64+          , [src_a, src_b] <- arg_regs+          , [dst_hi, dst_lo] <- dest_regs+            ->  do+              (reg_a, _format_x, code_x) <- getSomeReg src_a+              (reg_b, _format_y, code_y) <- getSomeReg src_b++              let lo = getRegisterReg platform (CmmLocal dst_lo)+                  hi = getRegisterReg platform (CmmLocal dst_hi)+                  w' = opRegWidth w+              return (+                  code_x `appOL`+                  code_y `snocOL`+                  -- UMULL: Xd = Wa * Wb with 64 bit result+                  -- W64 inputs should have been caught by case above+                  UMULL (OpReg W64 lo) (OpReg w' reg_a) (OpReg w' reg_b) `snocOL`+                  -- Extract and truncate high result+                  -- hi[w:0] = lo[2w:w]+                  UBFX (OpReg W64 hi) (OpReg W64 lo)+                      (OpImm (ImmInt $ widthInBits w)) -- lsb+                      (OpImm (ImmInt $ widthInBits w)) -- width to extract+                      `appOL`+                  truncateReg W64 w lo+                  , Nothing)+          | otherwise -> unsupported (MO_U_Mul2  w)+    PrimTarget (MO_Clz  w)+          | w == W64 || w == W32+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst_reg = getRegisterReg platform (CmmLocal dst)+              return (+                  code_x `snocOL`+                  CLZ   (OpReg w dst_reg) (OpReg w reg_a)+                  , Nothing)+          | w == W16+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst' = getRegisterReg platform (CmmLocal dst)+                  r n = OpReg W32 n+                  imm n = OpImm (ImmInt n)+              {- dst = clz(x << 16 | 0x0000_8000) -}+              return (+                  code_x `appOL` toOL+                    [ LSL (r dst') (r reg_a) (imm 16)+                    , ORR (r dst') (r dst')  (imm 0x00008000)+                    , CLZ (r dst') (r dst')+                    ]+                  , Nothing)+          | w == W8+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst' = getRegisterReg platform (CmmLocal dst)+                  r n = OpReg W32 n+                  imm n = OpImm (ImmInt n)+              {- dst = clz(x << 24 | 0x0080_0000) -}+              return (+                  code_x `appOL` toOL+                    [ LSL (r dst') (r reg_a) (imm 24)+                    , ORR (r dst') (r dst')  (imm 0x00800000)+                    , CLZ (r dst') (r dst')+                    ]+                  , Nothing)+            | otherwise -> unsupported (MO_Clz  w)+    PrimTarget (MO_Ctz  w)+          | w == W64 || w == W32+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst_reg = getRegisterReg platform (CmmLocal dst)+              return (+                  code_x `snocOL`+                  RBIT (OpReg w dst_reg) (OpReg w reg_a) `snocOL`+                  CLZ  (OpReg w dst_reg) (OpReg w dst_reg)+                  , Nothing)+          | w == W16+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst' = getRegisterReg platform (CmmLocal dst)+                  r n = OpReg W32 n+                  imm n = OpImm (ImmInt n)+              {- dst = clz(reverseBits(x) | 0x0000_8000) -}+              return (+                  code_x `appOL` toOL+                    [ RBIT (r dst') (r reg_a)+                    , ORR  (r dst') (r dst') (imm 0x00008000)+                    , CLZ  (r dst') (r dst')+                    ]+                  , Nothing)+          | w == W8+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst' = getRegisterReg platform (CmmLocal dst)+                  r n = OpReg W32 n+                  imm n = OpImm (ImmInt n)+              {- dst = clz(reverseBits(x) | 0x0080_0000) -}+              return (+                  code_x `appOL` toOL+                    [ RBIT (r dst') (r reg_a)+                    , ORR (r dst')  (r dst') (imm 0x00800000)+                    , CLZ  (r dst')  (r dst')+                    ]+                  , Nothing)+            | otherwise -> unsupported (MO_Ctz  w)+    PrimTarget (MO_BRev  w)+          | w == W64 || w == W32+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst_reg = getRegisterReg platform (CmmLocal dst)+              return (+                  code_x `snocOL`+                  RBIT (OpReg w dst_reg) (OpReg w reg_a)+                  , Nothing)+          | w == W16+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst' = getRegisterReg platform (CmmLocal dst)+                  r n = OpReg W32 n+                  imm n = OpImm (ImmInt n)+              {- dst = reverseBits32(x << 16) -}+              return (+                  code_x `appOL` toOL+                    [ LSL  (r dst') (r reg_a) (imm 16)+                    , RBIT (r dst') (r dst')+                    ]+                  , Nothing)+          | w == W8+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst' = getRegisterReg platform (CmmLocal dst)+                  r n = OpReg W32 n+                  imm n = OpImm (ImmInt n)+              {- dst = reverseBits32(x << 24) -}+              return (+                  code_x `appOL` toOL+                    [ LSL  (r dst') (r reg_a) (imm 24)+                    , RBIT (r dst') (r dst')+                    ]+                  , Nothing)+            | otherwise -> unsupported (MO_BRev  w)+    PrimTarget (MO_BSwap  w)+          | w == W64 || w == W32+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst_reg = getRegisterReg platform (CmmLocal dst)+              return $ (code_x `snocOL` REV (OpReg w dst_reg) (OpReg w reg_a), Nothing)+          | w == W16+          , [src] <- arg_regs+          , [dst] <- dest_regs+          -> do+              (reg_a, _format_x, code_x) <- getSomeReg src+              let dst' = getRegisterReg platform (CmmLocal dst)+                  r n = OpReg W32 n+              -- Swaps the bytes in each 16bit word+              -- TODO: Expose the 32 & 64 bit version of this?+              return $ (code_x `snocOL` REV16 (r dst') (r reg_a), Nothing)+          | otherwise -> unsupported (MO_BSwap w)+     -- or a possibly side-effecting machine operation     -- mop :: CallishMachOp (see GHC.Cmm.MachOp)     PrimTarget mop -> do@@ -1653,8 +1945,6 @@         MO_F64_Log1P -> mkCCall "log1p"         MO_F64_Exp   -> mkCCall "exp"         MO_F64_ExpM1 -> mkCCall "expm1"-        MO_F64_Fabs  -> mkCCall "fabs"-        MO_F64_Sqrt  -> mkCCall "sqrt"          -- 32 bit float ops         MO_F32_Pwr   -> mkCCall "powf"@@ -1675,8 +1965,6 @@         MO_F32_Log1P -> mkCCall "log1pf"         MO_F32_Exp   -> mkCCall "expf"         MO_F32_ExpM1 -> mkCCall "expm1f"-        MO_F32_Fabs  -> mkCCall "fabsf"-        MO_F32_Sqrt  -> mkCCall "sqrtf"          -- 64-bit primops         MO_I64_ToI   -> mkCCall "hs_int64ToInt"@@ -1714,7 +2002,6 @@          -- Arithmatic         -- These are not supported on X86, so I doubt they are used much.-        MO_S_Mul2     _w -> unsupported mop         MO_S_QuotRem  _w -> unsupported mop         MO_U_QuotRem  _w -> unsupported mop         MO_U_QuotRem2 _w -> unsupported mop@@ -1723,7 +2010,6 @@         MO_SubWordC   _w -> unsupported mop         MO_AddIntC    _w -> unsupported mop         MO_SubIntC    _w -> unsupported mop-        MO_U_Mul2     _w -> unsupported mop          -- Memory Ordering         MO_AcquireFence     ->  return (unitOL DMBISH, Nothing)@@ -1751,10 +2037,6 @@         MO_PopCnt w         -> mkCCall (popCntLabel w)         MO_Pdep w           -> mkCCall (pdepLabel w)         MO_Pext w           -> mkCCall (pextLabel w)-        MO_Clz w            -> mkCCall (clzLabel w)-        MO_Ctz w            -> mkCCall (ctzLabel w)-        MO_BSwap w          -> mkCCall (bSwapLabel w)-        MO_BRev w           -> mkCCall (bRevLabel w)          -- -- Atomic read-modify-write.         MO_AtomicRead w ord@@ -1943,8 +2225,8 @@      passArguments _ _ _ _ _ _ _ = pprPanic "passArguments" (text "invalid state") -    readResults :: [Reg] -> [Reg] -> [LocalReg] -> [Reg]-> InstrBlock -> NatM ([Reg], InstrBlock)-    readResults _ _ [] accumRegs accumCode = return (accumRegs, accumCode)+    readResults :: [Reg] -> [Reg] -> [LocalReg] -> [Reg]-> InstrBlock -> NatM (InstrBlock)+    readResults _ _ [] _ accumCode = return accumCode     readResults [] _ _ _ _ = do       platform <- getPlatform       pprPanic "genCCall, out of gp registers when reading results" (pdoc platform target)
GHC/CmmToAsm/AArch64/Instr.hs view
@@ -79,11 +79,14 @@   -- 1. Arithmetic Instructions ------------------------------------------------   ADD dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)   CMP l r                  -> usage (regOp l ++ regOp r, [])+  CMN l r                  -> usage (regOp l ++ regOp r, [])   MSUB dst src1 src2 src3  -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst)   MUL dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)   NEG dst src              -> usage (regOp src, regOp dst)   SMULH dst src1 src2      -> usage (regOp src1 ++ regOp src2, regOp dst)   SMULL dst src1 src2      -> usage (regOp src1 ++ regOp src2, regOp dst)+  UMULH dst src1 src2      -> usage (regOp src1 ++ regOp src2, regOp dst)+  UMULL dst src1 src2      -> usage (regOp src1 ++ regOp src2, regOp dst)   SDIV dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)   SUB dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)   UDIV dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)@@ -97,6 +100,11 @@   UXTB dst src             -> usage (regOp src, regOp dst)   SXTH dst src             -> usage (regOp src, regOp dst)   UXTH dst src             -> usage (regOp src, regOp dst)+  CLZ  dst src             -> usage (regOp src, regOp dst)+  RBIT dst src             -> usage (regOp src, regOp dst)+  REV   dst src            -> usage (regOp src, regOp dst)+  -- REV32 dst src            -> usage (regOp src, regOp dst)+  REV16 dst src            -> usage (regOp src, regOp dst)   -- 3. Logical and Move Instructions ------------------------------------------   AND dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)   ASR dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)@@ -112,7 +120,7 @@   J t                      -> usage (regTarget t, [])   B t                      -> usage (regTarget t, [])   BCOND _ t                -> usage (regTarget t, [])-  BL t ps _rs              -> usage (regTarget t ++ ps, callerSavedRegisters)+  BL t ps                  -> usage (regTarget t ++ ps, callerSavedRegisters)    -- 5. Atomic Instructions ----------------------------------------------------   -- 6. Conditional Instructions -----------------------------------------------@@ -133,10 +141,12 @@   SCVTF dst src            -> usage (regOp src, regOp dst)   FCVTZS dst src           -> usage (regOp src, regOp dst)   FABS dst src             -> usage (regOp src, regOp dst)+  FSQRT dst src            -> usage (regOp src, regOp dst)   FMA _ dst src1 src2 src3 ->     usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst) -  _ -> panic $ "regUsageOfInstr: " ++ instrCon instr+  LOCATION{} -> panic $ "regUsageOfInstr: " ++ instrCon instr+  NEWBLOCK{} -> panic $ "regUsageOfInstr: " ++ instrCon instr    where         -- filtering the usage is necessary, otherwise the register@@ -167,6 +177,8 @@         interesting _        (RegReal (RealRegSingle (-1))) = False         interesting platform (RegReal (RealRegSingle i))    = freeReg platform i +-- Note [AArch64 Register assignments]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Save caller save registers -- This is x0-x18 --@@ -189,6 +201,8 @@ -- '---------------------------------------------------------------------------------------------------------------------------------------------------------------' -- IR: Indirect result location register, IP: Intra-procedure register, PL: Platform register, FP: Frame pointer, LR: Link register, SP: Stack pointer -- BR: Base, SL: SpLim+--+-- TODO: The zero register is currently mapped to -1 but should get it's own separate number. callerSavedRegisters :: [Reg] callerSavedRegisters     = map regSingle [0..18]@@ -209,11 +223,14 @@     -- 1. Arithmetic Instructions ----------------------------------------------     ADD o1 o2 o3   -> ADD (patchOp o1) (patchOp o2) (patchOp o3)     CMP o1 o2      -> CMP (patchOp o1) (patchOp o2)+    CMN o1 o2      -> CMN (patchOp o1) (patchOp o2)     MSUB o1 o2 o3 o4 -> MSUB (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4)     MUL o1 o2 o3   -> MUL (patchOp o1) (patchOp o2) (patchOp o3)     NEG o1 o2      -> NEG (patchOp o1) (patchOp o2)     SMULH o1 o2 o3 -> SMULH (patchOp o1) (patchOp o2)  (patchOp o3)     SMULL o1 o2 o3 -> SMULL (patchOp o1) (patchOp o2)  (patchOp o3)+    UMULH o1 o2 o3 -> UMULH (patchOp o1) (patchOp o2)  (patchOp o3)+    UMULL o1 o2 o3 -> UMULL (patchOp o1) (patchOp o2)  (patchOp o3)     SDIV o1 o2 o3  -> SDIV (patchOp o1) (patchOp o2) (patchOp o3)     SUB o1 o2 o3   -> SUB  (patchOp o1) (patchOp o2) (patchOp o3)     UDIV o1 o2 o3  -> UDIV (patchOp o1) (patchOp o2) (patchOp o3)@@ -227,7 +244,13 @@     UXTB o1 o2       -> UXTB (patchOp o1) (patchOp o2)     SXTH o1 o2       -> SXTH (patchOp o1) (patchOp o2)     UXTH o1 o2       -> UXTH (patchOp o1) (patchOp o2)+    CLZ o1 o2        -> CLZ  (patchOp o1) (patchOp o2)+    RBIT o1 o2       -> RBIT (patchOp o1) (patchOp o2)+    REV   o1 o2      -> REV  (patchOp o1) (patchOp o2)+    -- REV32 o1 o2      -> REV32 (patchOp o1) (patchOp o2)+    REV16 o1 o2      -> REV16 (patchOp o1) (patchOp o2) +     -- 3. Logical and Move Instructions ----------------------------------------     AND o1 o2 o3   -> AND  (patchOp o1) (patchOp o2) (patchOp o3)     ASR o1 o2 o3   -> ASR  (patchOp o1) (patchOp o2) (patchOp o3)@@ -243,7 +266,7 @@     -- 4. Branch Instructions --------------------------------------------------     J t            -> J (patchTarget t)     B t            -> B (patchTarget t)-    BL t rs ts     -> BL (patchTarget t) rs ts+    BL t rs        -> BL (patchTarget t) rs     BCOND c t      -> BCOND c (patchTarget t)      -- 5. Atomic Instructions --------------------------------------------------@@ -265,10 +288,12 @@     SCVTF o1 o2    -> SCVTF (patchOp o1) (patchOp o2)     FCVTZS o1 o2   -> FCVTZS (patchOp o1) (patchOp o2)     FABS o1 o2     -> FABS (patchOp o1) (patchOp o2)+    FSQRT o1 o2    -> FSQRT (patchOp o1) (patchOp o2)     FMA s o1 o2 o3 o4 ->       FMA s (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) -    _              -> panic $ "patchRegsOfInstr: " ++ instrCon instr+    NEWBLOCK{}     -> panic $ "patchRegsOfInstr: " ++ instrCon instr+    LOCATION{}     -> panic $ "patchRegsOfInstr: " ++ instrCon instr     where         patchOp :: Operand -> Operand         patchOp (OpReg w r) = OpReg w (env r)@@ -307,10 +332,16 @@ jumpDestsOfInstr (CBNZ _ t) = [ id | TBlock id <- [t]] jumpDestsOfInstr (J t) = [id | TBlock id <- [t]] jumpDestsOfInstr (B t) = [id | TBlock id <- [t]]-jumpDestsOfInstr (BL t _ _) = [ id | TBlock id <- [t]]+jumpDestsOfInstr (BL t _) = [ id | TBlock id <- [t]] jumpDestsOfInstr (BCOND _ t) = [ id | TBlock id <- [t]] jumpDestsOfInstr _ = [] +canFallthroughTo :: Instr -> BlockId -> Bool+canFallthroughTo (ANN _ i) bid = canFallthroughTo i bid+canFallthroughTo (J (TBlock target)) bid = bid == target+canFallthroughTo (B (TBlock target)) bid = bid == target+canFallthroughTo _ _ = False+ -- | Change the destination of this jump instruction. -- Used in the linear allocator when adding fixup blocks for join -- points.@@ -322,7 +353,7 @@         CBNZ r (TBlock bid) -> CBNZ r (TBlock (patchF bid))         J (TBlock bid) -> J (TBlock (patchF bid))         B (TBlock bid) -> B (TBlock (patchF bid))-        BL (TBlock bid) ps rs -> BL (TBlock (patchF bid)) ps rs+        BL (TBlock bid) ps -> BL (TBlock (patchF bid)) ps         BCOND c (TBlock bid) -> BCOND c (TBlock (patchF bid))         _ -> panic $ "patchJumpInstr: " ++ instrCon instr @@ -540,6 +571,7 @@     -- | ADR ...     -- | ADRP ...     | CMP Operand Operand -- rd - op2+    | CMN Operand Operand -- rd + op2     -- | MADD ...     -- | MNEG ...     | MSUB Operand Operand Operand Operand -- rd = ra - rn × rm@@ -562,8 +594,8 @@     -- | UMADDL ...  -- Xd = Xa + Wn × Wm     -- | UMNEGL ... -- Xd = - Wn × Wm     -- | UMSUBL ... -- Xd = Xa - Wn × Wm-    -- | UMULH ... -- Xd = (Xn × Xm)_127:64-    -- | UMULL ... -- Xd = Wn × Wm+    | UMULH Operand Operand Operand -- Xd = (Xn × Xm)_127:64+    | UMULL Operand Operand Operand -- Xd = Wn × Wm      -- 2. Bit Manipulation Instructions ----------------------------------------     | SBFM Operand Operand Operand Operand -- rd = rn[i,j]@@ -576,6 +608,14 @@     -- Signed/Unsigned bitfield extract     | SBFX Operand Operand Operand Operand -- rd = rn[i,j]     | UBFX Operand Operand Operand Operand -- rd = rn[i,j]+    | CLZ  Operand Operand -- rd = countLeadingZeros(rn)+    | RBIT Operand Operand -- rd = reverseBits(rn)+    | REV Operand Operand   -- rd = reverseBytes(rn): (for 32 & 64 bit operands)+                            -- 0xAABBCCDD -> 0xDDCCBBAA+    | REV16 Operand Operand -- rd = reverseBytes16(rn)+                            -- 0xAABB_CCDD -> xBBAA_DDCC+    -- | REV32 Operand Operand -- rd = reverseBytes32(rn) - 64bit operands only!+    --                         -- 0xAABBCCDD_EEFFGGHH -> 0XDDCCBBAA_HHGGFFEE      -- 3. Logical and Move Instructions ----------------------------------------     | AND Operand Operand Operand -- rd = rn & op2@@ -604,7 +644,7 @@     -- Branching.     | J Target            -- like B, but only generated from genJump. Used to distinguish genJumps from others.     | B Target            -- unconditional branching b/br. (To a blockid, label or register)-    | BL Target [Reg] [Reg] -- branch and link (e.g. set x30 to next pc, and branch)+    | BL Target [Reg] -- branch and link (e.g. set x30 to next pc, and branch)     | BCOND Cond Target   -- branch with condition. b.<cond>      -- 8. Synchronization Instructions -----------------------------------------@@ -618,6 +658,8 @@     | FCVTZS Operand Operand     -- Float ABSolute value     | FABS Operand Operand+    -- Float SQuare RooT+    | FSQRT Operand Operand      -- | Floating-point fused multiply-add instructions     --@@ -644,18 +686,26 @@       POP_STACK_FRAME{} -> "POP_STACK_FRAME"       ADD{} -> "ADD"       CMP{} -> "CMP"+      CMN{} -> "CMN"       MSUB{} -> "MSUB"       MUL{} -> "MUL"       NEG{} -> "NEG"       SDIV{} -> "SDIV"       SMULH{} -> "SMULH"       SMULL{} -> "SMULL"+      UMULH{} -> "UMULH"+      UMULL{} -> "UMULL"       SUB{} -> "SUB"       UDIV{} -> "UDIV"       SBFM{} -> "SBFM"       UBFM{} -> "UBFM"       SBFX{} -> "SBFX"       UBFX{} -> "UBFX"+      CLZ{} -> "CLZ"+      RBIT{} -> "RBIT"+      REV{} -> "REV"+      REV16{} -> "REV16"+      -- REV32{} -> "REV32"       AND{} -> "AND"       ASR{} -> "ASR"       EOR{} -> "EOR"@@ -682,6 +732,7 @@       SCVTF{} -> "SCVTF"       FCVTZS{} -> "FCVTZS"       FABS{} -> "FABS"+      FSQRT{} -> "FSQRT"       FMA variant _ _ _ _ ->         case variant of           FMAdd  -> "FMADD"
GHC/CmmToAsm/AArch64/Ppr.hs view
@@ -316,6 +316,7 @@          | w == W64 = text "sp"          | w == W32 = text "wsp" +    -- See Note [AArch64 Register assignments]     ppr_reg_no w i          | i < 0, w == W32 = text "wzr"          | i < 0, w == W64 = text "xzr"@@ -372,12 +373,15 @@   CMP  o1 o2     | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfcmp") o1 o2     | otherwise -> op2 (text "\tcmp") o1 o2+  CMN  o1 o2       -> op2 (text "\tcmn") o1 o2   MSUB o1 o2 o3 o4 -> op4 (text "\tmsub") o1 o2 o3 o4   MUL  o1 o2 o3     | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 -> op3 (text "\tfmul") o1 o2 o3     | otherwise -> op3 (text "\tmul") o1 o2 o3   SMULH o1 o2 o3 -> op3 (text "\tsmulh") o1 o2 o3   SMULL o1 o2 o3 -> op3 (text "\tsmull") o1 o2 o3+  UMULH o1 o2 o3 -> op3 (text "\tumulh") o1 o2 o3+  UMULL o1 o2 o3 -> op3 (text "\tumull") o1 o2 o3   NEG  o1 o2     | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfneg") o1 o2     | otherwise -> op2 (text "\tneg") o1 o2@@ -393,6 +397,11 @@   -- 2. Bit Manipulation Instructions ------------------------------------------   SBFM o1 o2 o3 o4 -> op4 (text "\tsbfm") o1 o2 o3 o4   UBFM o1 o2 o3 o4 -> op4 (text "\tubfm") o1 o2 o3 o4+  CLZ  o1 o2       -> op2 (text "\tclz")  o1 o2+  RBIT  o1 o2      -> op2 (text "\trbit")  o1 o2+  REV o1 o2        -> op2 (text "\trev")  o1 o2+  REV16 o1 o2      -> op2 (text "\trev16")  o1 o2+  -- REV32 o1 o2      -> op2 (text "\trev32")  o1 o2   -- signed and unsigned bitfield extract   SBFX o1 o2 o3 o4 -> op4 (text "\tsbfx") o1 o2 o3 o4   UBFX o1 o2 o3 o4 -> op4 (text "\tubfx") o1 o2 o3 o4@@ -421,9 +430,9 @@   B (TLabel lbl) -> line $ text "\tb" <+> pprAsmLabel platform lbl   B (TReg r)     -> line $ text "\tbr" <+> pprReg W64 r -  BL (TBlock bid) _ _ -> line $ text "\tbl" <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))-  BL (TLabel lbl) _ _ -> line $ text "\tbl" <+> pprAsmLabel platform lbl-  BL (TReg r)     _ _ -> line $ text "\tblr" <+> pprReg W64 r+  BL (TBlock bid) _ -> line $ text "\tbl" <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))+  BL (TLabel lbl) _ -> line $ text "\tbl" <+> pprAsmLabel platform lbl+  BL (TReg r)     _ -> line $ text "\tblr" <+> pprReg W64 r    BCOND c (TBlock bid) -> line $ text "\t" <> pprBcond c <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))   BCOND c (TLabel lbl) -> line $ text "\t" <> pprBcond c <+> pprAsmLabel platform lbl@@ -525,6 +534,7 @@   SCVTF o1 o2 -> op2 (text "\tscvtf") o1 o2   FCVTZS o1 o2 -> op2 (text "\tfcvtzs") o1 o2   FABS o1 o2 -> op2 (text "\tfabs") o1 o2+  FSQRT o1 o2 -> op2 (text "\tfsqrt") o1 o2   FMA variant d r1 r2 r3 ->     let fma = case variant of                 FMAdd  -> text "\tfmadd"
GHC/CmmToAsm/AArch64/Regs.hs view
@@ -17,6 +17,7 @@ import GHC.Utils.Panic import GHC.Platform +-- TODO: Should this include the zero register? allMachRegNos   :: [RegNo] allMachRegNos   = [0..31] ++ [32..63] -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
GHC/CmmToAsm/BlockLayout.hs view
@@ -771,10 +771,9 @@ dropJumps _    [] = [] dropJumps info (BasicBlock lbl ins:todo)     | Just ins <- nonEmpty ins --This can happen because of shortcutting-    , [dest] <- jumpDestsOfInstr (NE.last ins)     , BasicBlock nextLbl _ : _ <- todo-    , not (mapMember dest info)-    , nextLbl == dest+    , canFallthroughTo (NE.last ins) nextLbl+    , not (mapMember nextLbl info)     = BasicBlock lbl (NE.init ins) : dropJumps info todo     | otherwise     = BasicBlock lbl ins : dropJumps info todo
GHC/CmmToAsm/Instr.hs view
@@ -71,10 +71,16 @@                 :: instr -> Bool  -        -- | Give the possible destinations of this jump instruction.+        -- | Give the possible *local block* destinations of this jump instruction.         --      Must be defined for all jumpish instructions.         jumpDestsOfInstr                 :: instr -> [BlockId]++        -- | Check if the instr always transfers control flow+        -- to the given block. Used by code layout to eliminate+        -- jumps that can be replaced by fall through.+        canFallthroughTo+                :: instr -> BlockId -> Bool           -- | Change the destination of this jump instruction.
GHC/CmmToAsm/Monad.hs view
@@ -78,8 +78,15 @@     cmmTopCodeGen             :: RawCmmDecl -> NatM [NatCmmDecl statics instr],     generateJumpTableForInstr :: instr -> Maybe (NatCmmDecl statics instr),     getJumpDestBlockId        :: jumpDest -> Maybe BlockId,+    -- | Does this jump always jump to a single destination and is shortcutable?+    --+    -- We use this to determine shortcutable instructions - See Note [What is shortcutting]+    -- Note that if we return a destination here we *most* support the relevant shortcutting in+    -- shortcutStatics for jump tables and shortcutJump for the instructions itself.     canShortcut               :: instr -> Maybe jumpDest,+    -- | Replace references to blockIds with other destinations - used to update jump tables.     shortcutStatics           :: (BlockId -> Maybe jumpDest) -> statics -> statics,+    -- | Change the jump destination(s) of an instruction.     shortcutJump              :: (BlockId -> Maybe jumpDest) -> instr -> instr,     -- | 'Module' is only for printing internal labels. See Note [Internal proc     -- labels] in CLabel.@@ -104,6 +111,25 @@     -- ^ Turn the sequence of @jcc l1; jmp l2@ into @jncc l2; \<block_l1>@     -- when possible.     }++{- Note [supporting shortcutting]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+For the concept of shortcutting see Note [What is shortcutting].++In order to support shortcutting across multiple backends uniformly we+use canShortcut, shortcutStatics and shortcutJump.++canShortcut tells us if the backend support shortcutting of a instruction+and if so what destination we should retarget instruction to instead.++shortcutStatics exists to allow us to update jump destinations in jump tables.++shortcutJump updates the instructions itself.++A backend can opt out of those by always returning Nothing for canShortcut+and implementing shortcutStatics/shortcutJump as \_ x -> x++-}  {- Note [pprNatCmmDeclS and pprNatCmmDeclH] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GHC/CmmToAsm/PPC.hs view
@@ -46,6 +46,7 @@    patchRegsOfInstr    = PPC.patchRegsOfInstr    isJumpishInstr      = PPC.isJumpishInstr    jumpDestsOfInstr    = PPC.jumpDestsOfInstr+   canFallthroughTo    = PPC.canFallthroughTo    patchJumpInstr      = PPC.patchJumpInstr    mkSpillInstr        = PPC.mkSpillInstr    mkLoadInstr         = PPC.mkLoadInstr
GHC/CmmToAsm/PPC/CodeGen.hs view
@@ -1770,7 +1770,7 @@                                 _ -> panic "genCall': unknown calling conv."          argReps = map (cmmExprType platform) args-        (argHints, _) = foreignTargetHints target+        (_, argHints) = foreignTargetHints target          roundTo a x | x `mod` a == 0 = x                     | otherwise = x + a - (x `mod` a)
GHC/CmmToAsm/PPC/Instr.hs view
@@ -22,6 +22,7 @@    , patchJumpInstr    , patchRegsOfInstr    , jumpDestsOfInstr+   , canFallthroughTo    , takeRegRegMoveInstr    , takeDeltaInstr    , mkRegRegMoveInstr@@ -508,6 +509,13 @@     BL{}        -> True     JMP{}       -> True     _           -> False++canFallthroughTo :: Instr -> BlockId -> Bool+canFallthroughTo instr bid+ = case instr of+        BCC _ target _      -> target == bid+        BCCFAR _ target _   -> target == bid+        _                   -> False   -- | Checks whether this instruction is a jump/branch instruction.
GHC/CmmToAsm/Reg/Graph/TrivColorable.hs view
@@ -183,7 +183,8 @@                             ArchPPC       -> 26                             ArchPPC_64 _  -> 20                             ArchARM _ _ _ -> panic "trivColorable ArchARM"-                            ArchAArch64   -> 28 -- 32 - D1..D4+                            ArchAArch64   -> 24 -- 32 - F1 .. F4, D1..D4 - it's odd but see Note [AArch64 Register assignments] for our reg use.+                                                -- Seems we reserve different registers for D1..D4 and F1 .. F4 somehow, we should fix this.                             ArchAlpha     -> panic "trivColorable ArchAlpha"                             ArchMipseb    -> panic "trivColorable ArchMipseb"                             ArchMipsel    -> panic "trivColorable ArchMipsel"
GHC/CmmToAsm/Reg/Liveness.hs view
@@ -126,6 +126,11 @@                 Instr instr     -> isJumpishInstr instr                 _               -> False +        canFallthroughTo i bid+         = case i of+                Instr instr     -> canFallthroughTo instr bid+                _               -> False+         jumpDestsOfInstr i          = case i of                 Instr instr     -> jumpDestsOfInstr instr
GHC/CmmToAsm/X86.hs view
@@ -51,6 +51,7 @@    patchRegsOfInstr        = X86.patchRegsOfInstr    isJumpishInstr          = X86.isJumpishInstr    jumpDestsOfInstr        = X86.jumpDestsOfInstr+   canFallthroughTo        = X86.canFallthroughTo    patchJumpInstr          = X86.patchJumpInstr    mkSpillInstr            = X86.mkSpillInstr    mkLoadInstr             = X86.mkLoadInstr
GHC/CmmToAsm/X86/CodeGen.hs view
@@ -2660,10 +2660,11 @@            -> [CmmFormal]       -- ^ where to put the result            -> [CmmActual]       -- ^ arguments (of mixed type)            -> NatM InstrBlock-genCCall32 addr conv dest_regs args = do+genCCall32 addr conv@(ForeignConvention _ argHints _ _) dest_regs args = do         config <- getConfig         let platform = ncgPlatform config-            prom_args = map (maybePromoteCArg platform W32) args+            args_hints = zip args (argHints ++ repeat NoHint)+            prom_args = map (maybePromoteCArg platform W32) args_hints              -- If the size is smaller than the word, we widen things (see maybePromoteCArg)             arg_size_bytes :: CmmType -> Int@@ -2817,10 +2818,11 @@            -> [CmmFormal]       -- ^ where to put the result            -> [CmmActual]       -- ^ arguments (of mixed type)            -> NatM InstrBlock-genCCall64 addr conv dest_regs args = do+genCCall64 addr conv@(ForeignConvention _ argHints _ _) dest_regs args = do     platform <- getPlatform     -- load up the register arguments-    let prom_args = map (maybePromoteCArg platform W32) args+    let args_hints = zip args (argHints ++ repeat NoHint)+    let prom_args = map (maybePromoteCArg platform W32) args_hints      let load_args :: [CmmExpr]                   -> [Reg]         -- int regs avail for args@@ -3058,9 +3060,11 @@             assign_code dest_regs)  -maybePromoteCArg :: Platform -> Width -> CmmExpr -> CmmExpr-maybePromoteCArg platform wto arg- | wfrom < wto = CmmMachOp (MO_UU_Conv wfrom wto) [arg]+maybePromoteCArg :: Platform -> Width -> (CmmExpr, ForeignHint) -> CmmExpr+maybePromoteCArg platform wto (arg, hint)+ | wfrom < wto = case hint of+     SignedHint -> CmmMachOp (MO_SS_Conv wfrom wto) [arg]+     _          -> CmmMachOp (MO_UU_Conv wfrom wto) [arg]  | otherwise   = arg  where    wfrom = cmmExprWidth platform arg
GHC/CmmToAsm/X86/Instr.hs view
@@ -31,6 +31,7 @@    , mkSpillInstr    , mkRegRegMoveInstr    , jumpDestsOfInstr+   , canFallthroughTo    , patchRegsOfInstr    , patchJumpInstr    , isMetaInstr@@ -669,6 +670,17 @@         CALL{}          -> True         _               -> False +canFallthroughTo :: Instr -> BlockId -> Bool+canFallthroughTo insn bid+  = case insn of+    JXX _ target          -> bid == target+    JMP_TBL _ targets _ _ -> all isTargetBid targets+    _                     -> False+  where+    isTargetBid target = case target of+      Nothing                      -> True+      Just (DestBlockId target) -> target == bid+      _                  -> False  jumpDestsOfInstr         :: Instr
GHC/CmmToLlvm.hs view
@@ -11,7 +11,7 @@    ) where -import GHC.Prelude hiding ( head )+import GHC.Prelude  import GHC.Llvm import GHC.CmmToLlvm.Base@@ -38,8 +38,7 @@ import qualified GHC.Data.Stream as Stream  import Control.Monad ( when, forM_ )-import Data.List.NonEmpty ( head )-import Data.Maybe ( fromMaybe, catMaybes )+import Data.Maybe ( fromMaybe, catMaybes, isNothing ) import System.IO  -- -----------------------------------------------------------------------------@@ -69,11 +68,13 @@            "up to" <+> text (llvmVersionStr supportedLlvmVersionUpperBound) <+> "(non inclusive) is supported." <+>            "System LLVM version: " <> text (llvmVersionStr ver) $$            "We will try though..."-         let isS390X = platformArch (llvmCgPlatform cfg)  == ArchS390X-         let major_ver = head . llvmVersionNE $ ver-         when (isS390X && major_ver < 10 && doWarn) $ putMsg logger $-           "Warning: For s390x the GHC calling convention is only supported since LLVM version 10." <+>-           "You are using LLVM version: " <> text (llvmVersionStr ver)++       when (isNothing mb_ver) $ do+         let doWarn = llvmCgDoWarn cfg+         when doWarn $ putMsg logger $+           "Failed to detect LLVM version!" $$+           "Make sure LLVM is installed correctly." $$+           "We will try though..."         -- HACK: the Nothing case here is potentially wrong here but we        -- currently don't use the LLVM version to guide code generation
GHC/Core/LateCC.hs view
@@ -21,6 +21,7 @@ import GHC.Utils.Error import GHC.Utils.Logger import GHC.Utils.Outputable+import GHC.Types.RepType (mightBeFunTy)  -- | Late cost center insertion logic used by the driver addLateCostCenters ::@@ -78,8 +79,11 @@     top_level_cc_pred :: CoreExpr -> Bool     top_level_cc_pred =         case lateCCConfig_whichBinds of-          LateCCAllBinds ->-            const True+          LateCCBinds -> \rhs ->+            -- Make sure we record any functions. Even if it's something like `f = g`.+            mightBeFunTy (exprType rhs) ||+            -- If the RHS is a CAF doing work also insert a CC.+            not (exprIsWorkFree rhs)           LateCCOverloadedBinds ->             isOverloadedTy . exprType           LateCCNone ->
GHC/Core/LateCC/TopLevelBinds.hs view
@@ -3,16 +3,18 @@  import GHC.Prelude -import GHC.Core--- import GHC.Core.LateCC import GHC.Core.LateCC.Types import GHC.Core.LateCC.Utils++import GHC.Core import GHC.Core.Opt.Monad import GHC.Driver.DynFlags import GHC.Types.Id import GHC.Types.Name import GHC.Unit.Module.ModGuts +import Data.Maybe+ {- Note [Collecting late cost centres] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Usually cost centres defined by a module are collected@@ -26,7 +28,7 @@  Note [Adding late cost centres to top level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The basic idea is very simple. For every top level binder+The basic idea is very simple. For a top level binder `f = rhs` we compile it as if the user had written `f = {-# SCC f #-} rhs`. @@ -37,6 +39,21 @@ we provide flags for both approaches as they have different tradeoffs. +To reduce overhead we ignore workfree bindings because they don't contribute+meaningfully to a performance profile. This reduces code size massively as it+allows us to allocate definitions like `val = Just 32` at compile time instead+of turning them into a CAF of the form `val = <scc val> let x = Just 32 in x` which+would be the alternative.++We make an exception for rhss with function types. This allows us to get+cost centres on eta-reduced definitions like `f = g`. By putting a tick onto+`f`s rhs we end up with++    f = \eta1 eta2 ... etan ->+        <scc f> g eta1 ... etan++Which can make it easier to understand call graphs of an application.+ We also don't add a cost centre for any binder that is a constructor worker or wrapper. These will never meaningfully enrich the resulting profile so we improve efficiency by omitting those.@@ -89,15 +106,20 @@      doBndr :: Id -> CoreExpr -> LateCCM s CoreExpr     doBndr bndr rhs-      -- Cost centres on constructor workers are pretty much useless-      -- so we don't emit them if we are looking at the rhs of a constructor-      -- binding.-      | Just _ <- isDataConId_maybe bndr = pure rhs-      | otherwise = if pred rhs then addCC bndr rhs else pure rhs+      -- Not a constructor worker.+      -- Cost centres on constructor workers are pretty much useless so we don't emit them+      -- if we are looking at the rhs of a constructor binding.+      | isNothing (isDataConId_maybe bndr)+      , pred rhs+      = addCC bndr rhs+      | otherwise = pure rhs      -- We want to put the cost centre below the lambda as we only care about-    -- executions of the RHS.+    -- executions of the RHS. Note that the lambdas might be hidden under ticks+    -- or casts. So look through these as well.     addCC :: Id -> CoreExpr -> LateCCM s CoreExpr+    addCC bndr (Cast rhs co) = pure Cast <*> addCC bndr rhs <*> pure co+    addCC bndr (Tick t rhs) = (Tick t) <$> addCC bndr rhs     addCC bndr (Lam b rhs) = Lam b <$> addCC bndr rhs     addCC bndr rhs = do       let name = idName bndr
GHC/Core/LateCC/Types.hs view
@@ -34,7 +34,7 @@ -- | The types of top-level bindings we support adding cost centers to. data LateCCBindSpec =       LateCCNone-    | LateCCAllBinds+    | LateCCBinds     | LateCCOverloadedBinds  -- | Late cost centre insertion environment
GHC/Core/Map/Type.hs view
@@ -228,7 +228,7 @@     andEq TEQX e = hasCast e     andEq TEQ  e = e -    -- See Note [Comparing nullary type synonyms] in GHC.Core.Type+    -- See Note [Comparing nullary type synonyms] in GHC.Core.TyCo.Compare     go (D _ (TyConApp tc1 [])) (D _ (TyConApp tc2 []))       | tc1 == tc2       = TEQ
GHC/Core/Opt/Arity.hs view
@@ -860,7 +860,7 @@  -- | The Arity returned is the number of value args the -- expression can be applied to without doing much work-exprEtaExpandArity :: ArityOpts -> CoreExpr -> Maybe SafeArityType+exprEtaExpandArity :: HasDebugCallStack => ArityOpts -> CoreExpr -> Maybe SafeArityType -- exprEtaExpandArity is used when eta expanding --      e  ==>  \xy -> e x y -- Nothing if the expression has arity 0@@ -2359,8 +2359,8 @@                                 (mkNomReflCo (varType tcv)) co)     -- coreTyLamForAllTyFlag: See Note [The EtaInfo mechanism], particularly     -- the (EtaInfo Invariant).  (sym co) wraps a lambda that always has-    -- a ForAllTyFlag of coreTyLamForAllTyFlag; see wrinkle (FC4) in-    -- Note [ForAllCo] in GHC.Core.TyCo.Rep+    -- a ForAllTyFlag of coreTyLamForAllTyFlag; see Note [Required foralls in Core]+    -- in GHC.Core.TyCo.Rep  {- ************************************************************************
GHC/Core/Opt/ConstantFold.hs view
@@ -2660,6 +2660,10 @@      inline f_ty (f a b c) = <f's unfolding> a b c   (if f has an unfolding, EVEN if it's a loop breaker) +  Additionally the rule looks through ticks/casts as well (#24808):+      inline f_ty (f a b c |> co) = <f's unfolding> a b c |> co+      inline f_ty <tick> ( f a b c ) = <tick> <f's unfolding> a b c+   It's important to allow the argument to 'inline' to have args itself   (a) because its more forgiving to allow the programmer to write       either  inline f a b c@@ -2672,11 +2676,17 @@ -}  match_inline :: [Expr CoreBndr] -> Maybe (Expr CoreBndr)-match_inline (Type _ : e : _)-  | (Var f, args1) <- collectArgs e,-    Just unf <- maybeUnfoldingTemplate (realIdUnfolding f)-             -- Ignore the IdUnfoldingFun here!-  = Just (mkApps unf args1)+match_inline (Type _ : e : _) = go e+  -- Maybe Monad ahead:+  where+    go (Var f)      = -- Ignore the IdUnfoldingFun here!+                      (maybeUnfoldingTemplate (realIdUnfolding f))+    go (App f a)    = do { f' <- go f; pure $ App f' a }+    -- inline (f |> co)+    go (Cast e co)  = do { app <- go e; pure (Cast app co) }+    -- inline (<tick> f)+    go (Tick t e)   = do { app <- go e; pure (Tick t app) }+    go _            = Nothing  match_inline _ = Nothing 
GHC/Core/Opt/DmdAnal.hs view
@@ -1028,10 +1028,10 @@       TopLevel         | isInterestingTopLevelFn var         -- Top-level things will be used multiple times or not at-        -- all anyway, hence the multDmd below: It means we don't+        -- all anyway, hence the `floatifyDmd`: it means we don't         -- have to track whether @var@ is used strictly or at most-        -- once, because ultimately it never will.-        -> addVarDmd fn_ty var (C_0N `multDmd` (C_11 :* sd)) -- discard strictness+        -- once, because ultimately it never will+        -> addVarDmd fn_ty var (floatifyDmd (C_11 :* sd))         | otherwise         -> fn_ty -- don't bother tracking; just annotate with 'topDmd' later   -- Everything else:
GHC/Core/Opt/OccurAnal.hs view
@@ -1035,8 +1035,6 @@   | otherwise   = (adj_rhs_uds : adj_unf_uds : adj_rule_uds, final_bndr_with_rules, final_rhs )   where-    is_join_point = isJoinPoint mb_join-     --------- Right hand side ---------     -- For join points, set occ_encl to OccVanilla, via setTailCtxt.  If we have     --    join j = Just (f x) in ...@@ -1044,12 +1042,9 @@     --    let y = f x in join j = Just y in ...     -- That's that OccRhs would do; but there's no point because     -- j will never be scrutinised.-    env1 | is_join_point = setTailCtxt env-         | otherwise     = setNonTailCtxt rhs_ctxt env  -- Zap occ_join_points+    rhs_env  = mkRhsOccEnv env NonRecursive rhs_ctxt mb_join bndr rhs     rhs_ctxt = mkNonRecRhsCtxt bndr unf -    -- See Note [Sources of one-shot information]-    rhs_env = addOneShotsFromDmd bndr env1     -- See Note [Join arity prediction based on joinRhsArity]     -- Match join arity O from mb_join_arity with manifest join arity M as     -- returned by of occAnalLamTail. It's totally OK for them to mismatch;@@ -1059,16 +1054,15 @@     final_bndr_with_rules       | noBinderSwaps env = bndr -- See Note [Unfoldings and rules]       | otherwise         = bndr `setIdSpecialisation` mkRuleInfo rules'-                                 `setIdUnfolding` unf2+                                 `setIdUnfolding` unf1     final_bndr_no_rules       | noBinderSwaps env = bndr -- See Note [Unfoldings and rules]-      | otherwise         = bndr `setIdUnfolding` unf2+      | otherwise         = bndr `setIdUnfolding` unf1      --------- Unfolding ---------     -- See Note [Join points and unfoldings/rules]     unf = idUnfolding bndr     WTUD unf_tuds unf1 = occAnalUnfolding rhs_env unf-    unf2 = markNonRecUnfoldingOneShots mb_join unf1     adj_unf_uds = adjustTailArity mb_join unf_tuds      --------- Rules ---------@@ -1142,10 +1136,8 @@   | isDeadOcc occ  -- Check for dead code: see Note [Dead code]   = WUD body_uds binds   | otherwise-  = let (tagged_bndr, mb_join) = tagNonRecBinder lvl occ bndr+  = let (bndr', mb_join) = tagNonRecBinder lvl occ bndr         !(WUD rhs_uds' rhs') = adjustNonRecRhs mb_join wtuds-        !unf'  = markNonRecUnfoldingOneShots mb_join (idUnfolding tagged_bndr)-        !bndr' = tagged_bndr `setIdUnfolding` unf'     in WUD (body_uds `andUDs` rhs_uds')            (NonRec bndr' rhs' : binds)   where@@ -1750,10 +1742,9 @@     -- Instead, do the occAnalLamTail call here and postpone adjustTailUsage     -- until occAnalRec. In effect, we pretend that the RHS becomes a     -- non-recursive join point and fix up later with adjustTailUsage.-    rhs_env | isJoinId bndr = setTailCtxt env-            | otherwise     = setNonTailCtxt OccRhs env-            -- If bndr isn't an /existing/ join point, it's safe to zap the-            -- occ_join_points, because they can't occur in RHS.+    rhs_env = mkRhsOccEnv env Recursive OccRhs (idJoinPointHood bndr) bndr rhs+            -- If bndr isn't an /existing/ join point (so idJoinPointHood = NotJoinPoint),+            -- it's safe to zap the occ_join_points, because they can't occur in RHS.     WTUD (TUD rhs_ja unadj_rhs_uds) rhs' = occAnalLamTail rhs_env rhs       -- The corresponding call to adjustTailUsage is in occAnalRec and tagRecBinders @@ -2167,7 +2158,7 @@     in WTUD (TUD (joinRhsArity expr) usage) expr'  occ_anal_lam_tail :: OccEnv -> CoreExpr -> WithUsageDetails CoreExpr--- Does not markInsidLam etc for the outmost batch of lambdas+-- Does not markInsideLam etc for the outmost batch of lambdas occ_anal_lam_tail env expr@(Lam {})   = go env [] expr   where@@ -2308,20 +2299,8 @@  occAnalRule _ other_rule = (other_rule, emptyDetails, TUD 0 emptyDetails) -{- Note [Join point RHSs]-~~~~~~~~~~~~~~~~~~~~~~~~~-Consider-   x = e-   join j = Just x--We want to inline x into j right away, so we don't want to give-the join point a RhsCtxt (#14137).  It's not a huge deal, because-the FloatIn pass knows to float into join point RHSs; and the simplifier-does not float things out of join point RHSs.  But it's a simple, cheap-thing to do.  See #14137.--Note [Occurrences in stable unfoldings]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+{- Note [Occurrences in stable unfoldings]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider     f p = BIG     {-# INLINE g #-}@@ -2357,17 +2336,33 @@ empty.   This just saves a bit of allocation and reconstruction; not a big deal. -This fast path exposes a tricky cornder, though (#22761). Supose we have+Two tricky corners:++* Dead bindings (#22761). Supose we have     Unfolding = \x. let y = foo in x+1-which includes a dead binding for `y`. In occAnalUnfolding we occ-anal-the unfolding and produce /no/ occurrences of `foo` (since `y` is-dead).  But if we discard the occ-analysed syntax tree (which we do on-our fast path), and use the old one, we still /have/ an occurrence of-`foo` -- and that can lead to out-of-scope variables (#22761).+  which includes a dead binding for `y`. In occAnalUnfolding we occ-anal+  the unfolding and produce /no/ occurrences of `foo` (since `y` is+  dead).  But if we discard the occ-analysed syntax tree (which we do on+  our fast path), and use the old one, we still /have/ an occurrence of+  `foo` -- and that can lead to out-of-scope variables (#22761). -Solution: always keep occ-analysed trees in unfoldings and rules, so they-have no dead code.  See Note [OccInfo in unfoldings and rules] in GHC.Core.+  Solution: always keep occ-analysed trees in unfoldings and rules, so they+  have no dead code.  See Note [OccInfo in unfoldings and rules] in GHC.Core. +* One-shot binders. Consider+     {- f has Stable unfolding \p q -> blah+        Demand on f is LC(L,C(1,!P(L)); that is, one-shot in its second ar -}+     f = \x y. blah++   Now we `mkRhsOccEnv` will build an OccEnv for f's RHS that has+          occ_one_shots = [NoOneShortInfo, OneShotLam]+   This will put OneShotLam on the \y.  And it'll put it on the \q.  But the+   noBinderSwap check will mean that we discard this new occ-anal'd unfolding+   and keep the old one, with no OneShotInfo.++   This looks a little inconsistent, but the Stable unfolding is just used for+   inlinings; OneShotInfo isn't a lot of use here.+ Note [Cascading inlines] ~~~~~~~~~~~~~~~~~~~~~~~~ By default we use an OccRhs for the RHS of a binding.  This tells the@@ -2592,7 +2587,7 @@             | otherwise             = case one_shots of                 []                -> (env_args, []) -- Fast path; one_shots is often empty-                (os : one_shots') -> (addOneShots os env_args, one_shots')+                (os : one_shots') -> (setOneShots os env_args, one_shots')  {- Applications are dealt with specially because we want@@ -2888,42 +2883,125 @@      -- non-default alternative.  That in turn influences      -- pre/postInlineUnconditionally.  Grep for "occ_int_cxt"! +{- Note [The OccEnv for a right hand side]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+How do we create the OccEnv for a RHS (in mkRhsOccEnv)?++For a non-join point binding, x = rhs++  * occ_encl: set to OccRhs; but see `mkNonRecRhsCtxt` for wrinkles++  * occ_join_points: zap them!++  * occ_one_shots: initialise from the idDemandInfo;+    see Note [Sources of one-shot information]++For a join point binding,  j x = rhs++  * occ_encl: Consider+       x = e+       join j = Just x+    We want to inline x into j right away, so we don't want to give the join point+    a OccRhs (#14137); we want OccVanilla.  It's not a huge deal, because the+    FloatIn pass knows to float into join point RHSs; and the simplifier does not+    float things out of join point RHSs.  But it's a simple, cheap thing to do.++  * occ_join_points: no need to zap.++  * occ_one_shots: we start with one-shot-info from the context, which indeed+    applies to the /body/ of the join point, after walking past the binders.+    So we add to the front a OneShotInfo for each value-binder of the join+    point: see `extendOneShotsForJoinPoint`. (Failing to account for the join-point+    binders caused #25096.)++    For the join point binders themselves, of a /non-recursive/ join point,+    we make the binder a OneShotLam.  Again see `extendOneShotsForJoinPoint`.++    These one-shot infos then get attached to the binder by `occAnalLamTail`.+-}+ setNonTailCtxt :: OccEncl -> OccEnv -> OccEnv setNonTailCtxt ctxt !env   = env { occ_encl        = ctxt         , occ_one_shots   = []-        , occ_join_points = zapped_jp_env }-  where-    -- zapped_jp_env is basically just emptyVarEnv (hence zapped).  See (W3) of-    -- Note [Occurrence analysis for join points] Zapping improves efficiency,-    -- slightly, if you accidentally introduce a bug, in which you zap [jx :-> uds] and-    -- then find an occurrence of jx anyway, you might lose those uds, and-    -- that might mean we don't record all occurrencs, and that means we-    -- duplicate a redex....  a very nasty bug (which I encountered!).  Hence-    -- this DEBUG code which doesn't remove jx from the envt; it just gives it-    -- emptyDetails, which in turn causes a panic in mkOneOcc. That will catch-    -- this bug before it does any damage.-#ifdef DEBUG-    zapped_jp_env = mapVarEnv (\ _ -> emptyVarEnv) (occ_join_points env)-#else-    zapped_jp_env = emptyVarEnv-#endif+        , occ_join_points = zapJoinPointInfo (occ_join_points env) }  setTailCtxt :: OccEnv -> OccEnv-setTailCtxt !env-  = env { occ_encl = OccVanilla }+setTailCtxt !env = env { occ_encl = OccVanilla }     -- Preserve occ_one_shots, occ_join points     -- Do not use OccRhs for the RHS of a join point (which is a tail ctxt):-    --    see Note [Join point RHSs] -addOneShots :: OneShots -> OccEnv -> OccEnv-addOneShots os !env+mkRhsOccEnv :: OccEnv -> RecFlag -> OccEncl -> JoinPointHood -> Id -> CoreExpr -> OccEnv+-- See Note [The OccEnv for a right hand side]+-- For a join point:+--   - Keep occ_one_shots, occ_joinPoints from the context+--   - But push enough OneShotInfo onto occ_one_shots to account+--     for the join-point value binders+--   - Set occ_encl to OccVanilla+-- For non-join points+--   - Zap occ_one_shots and occ_join_points+--   - Set occ_encl to specified OccEncl+mkRhsOccEnv env@(OccEnv { occ_one_shots = ctxt_one_shots, occ_join_points = ctxt_join_points })+            is_rec encl jp_hood bndr rhs+  | JoinPoint join_arity <- jp_hood+  = env { occ_encl        = OccVanilla+        , occ_one_shots   = extendOneShotsForJoinPoint is_rec join_arity rhs ctxt_one_shots+        , occ_join_points = ctxt_join_points }++  | otherwise+  = env { occ_encl        = encl+        , occ_one_shots   = argOneShots (idDemandInfo bndr)+                            -- argOneShots: see Note [Sources of one-shot information]+        , occ_join_points = zapJoinPointInfo ctxt_join_points }++zapJoinPointInfo :: JoinPointInfo -> JoinPointInfo+-- (zapJoinPointInfo jp_info) basically just returns emptyVarEnv (hence zapped).+-- See (W3) of Note [Occurrence analysis for join points]+--+-- Zapping improves efficiency, slightly, if you accidentally introduce a bug,+-- in which you zap [jx :-> uds] and then find an occurrence of jx anyway, you+-- might lose those uds, and that might mean we don't record all occurrencs, and+-- that means we duplicate a redex....  a very nasty bug (which I encountered!).+-- Hence this DEBUG code which doesn't remove jx from the envt; it just gives it+-- emptyDetails, which in turn causes a panic in mkOneOcc. That will catch this+-- bug before it does any damage.+#ifdef DEBUG+zapJoinPointInfo jp_info = mapVarEnv (\ _ -> emptyVarEnv) jp_info+#else+zapJoinPointInfo _       = emptyVarEnv+#endif++extendOneShotsForJoinPoint+  :: RecFlag -> JoinArity -> CoreExpr+  -> [OneShotInfo] -> [OneShotInfo]+-- Push enough OneShortInfos on the front of ctxt_one_shots+-- to account for the value lambdas of the join point+extendOneShotsForJoinPoint is_rec join_arity rhs ctxt_one_shots+  = go join_arity rhs+  where+    -- For a /non-recursive/ join point we can mark all+    -- its join-lambda as one-shot; and it's a good idea to do so+    -- But not so for recursive ones+    os = case is_rec of+           NonRecursive -> OneShotLam+           Recursive    -> NoOneShotInfo++    go 0 _        = ctxt_one_shots+    go n (Lam b rhs)+      | isId b    = os : go (n-1) rhs+      | otherwise =      go (n-1) rhs+    go _ _        = []  -- Not enough lambdas.  This can legitimately happen.+                        -- e.g.    let j = case ... in j True+                        -- This will become an arity-1 join point after the+                        -- simplifier has eta-expanded it; but it may not have+                        -- enough lambdas /yet/. (Lint checks that JoinIds do+                        -- have enough lambdas.)++setOneShots :: OneShots -> OccEnv -> OccEnv+setOneShots os !env   | null os   = env  -- Fast path for common case   | otherwise = env { occ_one_shots = os } -addOneShotsFromDmd :: Id -> OccEnv -> OccEnv-addOneShotsFromDmd bndr = addOneShots (argOneShots (idDemandInfo bndr))- isRhsEnv :: OccEnv -> Bool isRhsEnv (OccEnv { occ_encl = cxt }) = case cxt of                                           OccRhs -> True@@ -3705,17 +3783,10 @@                 -> WithUsageDetails CoreExpr -- ^ This function concentrates shared logic between occAnalNonRecBind and the -- AcyclicSCC case of occAnalRec.---   * It applies 'markNonRecJoinOneShots' to the RHS---   * and returns the adjusted rhs UsageDetails combined with the body usage+-- It returns the adjusted rhs UsageDetails combined with the body usage adjustNonRecRhs mb_join_arity rhs_wuds@(WTUD _ rhs)-  = WUD rhs_uds' rhs'-  where-    --------- Marking (non-rec) join binders one-shot ----------    !rhs' | JoinPoint ja <- mb_join_arity = markNonRecJoinOneShots ja rhs-          | otherwise                     = rhs+  = WUD (adjustTailUsage mb_join_arity rhs_wuds) rhs -    --------- Adjusting right-hand side usage ----------    rhs_uds' = adjustTailUsage mb_join_arity rhs_wuds  adjustTailUsage :: JoinPointHood                 -> WithTailUsageDetails CoreExpr    -- Rhs usage, AFTER occAnalLamTail@@ -3732,33 +3803,6 @@ adjustTailArity :: JoinPointHood -> TailUsageDetails -> UsageDetails adjustTailArity mb_rhs_ja (TUD ja usage)   = markAllNonTailIf (mb_rhs_ja /= JoinPoint ja) usage--markNonRecJoinOneShots :: JoinArity -> CoreExpr -> CoreExpr--- For a /non-recursive/ join point we can mark all--- its join-lambda as one-shot; and it's a good idea to do so-markNonRecJoinOneShots join_arity rhs-  = go join_arity rhs-  where-    go 0 rhs         = rhs-    go n (Lam b rhs) = Lam (if isId b then setOneShotLambda b else b)-                           (go (n-1) rhs)-    go _ rhs         = rhs  -- Not enough lambdas.  This can legitimately happen.-                            -- e.g.    let j = case ... in j True-                            -- This will become an arity-1 join point after the-                            -- simplifier has eta-expanded it; but it may not have-                            -- enough lambdas /yet/. (Lint checks that JoinIds do-                            -- have enough lambdas.)--markNonRecUnfoldingOneShots :: JoinPointHood -> Unfolding -> Unfolding--- ^ Apply 'markNonRecJoinOneShots' to a stable unfolding-markNonRecUnfoldingOneShots mb_join_arity unf-  | JoinPoint ja <- mb_join_arity-  , CoreUnfolding{uf_src=src,uf_tmpl=tmpl} <- unf-  , isStableSource src-  , let !tmpl' = markNonRecJoinOneShots ja tmpl-  = unf{uf_tmpl=tmpl'}-  | otherwise-  = unf  type IdWithOccInfo = Id 
GHC/Core/Opt/SetLevels.hs view
@@ -991,6 +991,11 @@     as /another/ MFE, so we tell lvlFloatRhs not to do that, via the is_bot     argument. +    Do /not/ do this for bottoming /join-point/ bindings.   They may call other+    join points (#24768), and floating to the top would abstract over those join+    points, which we should never do.++ See Maessen's paper 1999 "Bottom extraction: factoring error handling out of functional programs" (unpublished I think). @@ -1188,9 +1193,11 @@      deann_rhs  = deAnnotate rhs     mb_bot_str = exprBotStrictness_maybe deann_rhs-    is_bot_lam = isJust mb_bot_str+    is_bot_lam = not is_join && isJust mb_bot_str         -- is_bot_lam: looks like (\xy. bot), maybe zero lams-        -- NB: not isBottomThunk!  See Note [Bottoming floats] point (3)+        -- NB: not isBottomThunk!+        -- NB: not is_join: don't send bottoming join points to the top.+        -- See Note [Bottoming floats] point (3)      n_extra    = count isId abs_vars     mb_join_arity = idJoinPointHood bndr@@ -1809,7 +1816,6 @@           env@(LE { le_subst = subst, le_lvl_env = lvl_env, le_env = id_env })           dest_lvl vs   = do { let vs1  = map zap vs-                      -- See Note [Zapping the demand info]        ; (subst', vs2) <- case is_rec of                             NonRecursive -> cloneBndrs      subst vs1                             Recursive    -> cloneRecIdBndrs subst vs1@@ -1822,9 +1828,12 @@        ; return (env', vs2) }   where     zap :: Var -> Var-    zap v | isId v    = zap_join (zapIdDemandInfo v)+    -- See Note [Floatifying demand info when floating]+    -- and Note [Zapping JoinId when floating]+    zap v | isId v    = zap_join (floatifyIdDemandInfo v)           | otherwise = v +    -- See Note [Zapping JoinId when floating]     zap_join | isTopLvl dest_lvl = zapJoinId              | otherwise         = id @@ -1833,16 +1842,38 @@   | isTyVar v = delVarEnv    id_env v   | otherwise = extendVarEnv id_env v ([v1], assert (not (isCoVar v1)) $ Var v1) -{--Note [Zapping the demand info]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-VERY IMPORTANT: we must zap the demand info if the thing is going to-float out, because it may be less demanded than at its original-binding site.  Eg-   f :: Int -> Int-   f x = let v = 3*4 in v+x-Here v is strict; but if we float v to top level, it isn't any more.+{- Note [Zapping JoinId when floating]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+If we are floating a join point, it won't be one anymore, so we zap+the join point information. -Similarly, if we're floating a join point, it won't be one anymore, so we zap-join point information as well.+Note [Floatifying demand info when floating]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When floating we must lazify the outer demand info on the Id+because it may be less demanded than at its original binding site.+For example:+     f :: Int -> Int+     f x = let v = 3*4 in v+x+Here v is strict and used at most once; but if we float v to top level,+that isn't true any more. Specifically, we lose track of v's cardinality info:+  * if `f` is called multiple times, then `v` is used more than once+  * if `f` is never called, then `v` is never evaluated.++But NOTE that we only need to adjust the /top-level/ cardinality info.+For example+     let x = (e1,e2)+     in ...(case x of (a,b) -> a+b)...+If we float x outwards, it may no longer be strict, but IF it is ever+evaluated THEN its components will be evaluated.  So we to lazify and+many-ify its demand-info, not discard it entirely.++Same if we have+     let f = \x y . blah+     in ...(f a b)...(f c d)...+Here `f` will get a demand like SC(S,C(1,L)). If we float it out, we can+keep that `1C` called-once inner demand. It's only the outer strictness+that we kill.++Conclusion: to floatify a demand, just do `multDmd C_0N` to reflect the+fact that `v` may be used any number of times, from zero upwards. -}
GHC/Core/Opt/Simplify/Iteration.hs view
@@ -971,7 +971,7 @@      -- Demand info: Note [Setting the demand info]     info3 | isEvaldUnfolding new_unf-          = zapDemandInfo info2 `orElse` info2+          = lazifyDemandInfo info2 `orElse` info2           | otherwise           = info2 @@ -2278,34 +2278,44 @@             (ApplyToVal { sc_arg = arg, sc_env = arg_se                         , sc_cont = cont, sc_hole_ty = fun_ty })   | fun_id `hasKey` runRWKey-  , [ TyArg {}, TyArg {} ] <- rev_args-  -- Do this even if (contIsStop cont)+  , [ TyArg { as_arg_ty = hole_ty }, TyArg {} ] <- rev_args+  -- Do this even if (contIsStop cont), or if seCaseCase is off.   -- See Note [No eta-expansion in runRW#]   = do { let arg_env = arg_se `setInScopeFromE` env-             ty'   = contResultType cont +             overall_res_ty  = contResultType cont+             -- hole_ty is the type of the current runRW# application+             (outer_cont, new_runrw_res_ty, inner_cont)+                | seCaseCase env = (mkBoringStop overall_res_ty, overall_res_ty, cont)+                | otherwise      = (cont, hole_ty, mkBoringStop hole_ty)+                -- Only when case-of-case is on. See GHC.Driver.Config.Core.Opt.Simplify+                --    Note [Case-of-case and full laziness]+        -- If the argument is a literal lambda already, take a short cut-       -- This isn't just efficiency; if we don't do this we get a beta-redex-       -- every time, so the simplifier keeps doing more iterations.+       -- This isn't just efficiency:+       --    * If we don't do this we get a beta-redex every time, so the+       --      simplifier keeps doing more iterations.+       --    * Even more important: see Note [No eta-expansion in runRW#]        ; arg' <- case arg of            Lam s body -> do { (env', s') <- simplBinder arg_env s-                            ; body' <- simplExprC env' body cont+                            ; body' <- simplExprC env' body inner_cont                             ; return (Lam s' body') }                             -- Important: do not try to eta-expand this lambda                             -- See Note [No eta-expansion in runRW#]+            _ -> do { s' <- newId (fsLit "s") ManyTy realWorldStatePrimTy                    ; let (m,_,_) = splitFunTy fun_ty                          env'  = arg_env `addNewInScopeIds` [s']                          cont' = ApplyToVal { sc_dup = Simplified, sc_arg = Var s'-                                            , sc_env = env', sc_cont = cont-                                            , sc_hole_ty = mkVisFunTy m realWorldStatePrimTy ty' }+                                            , sc_env = env', sc_cont = inner_cont+                                            , sc_hole_ty = mkVisFunTy m realWorldStatePrimTy new_runrw_res_ty }                                 -- cont' applies to s', then K                    ; body' <- simplExprC env' arg cont'                    ; return (Lam s' body') } -       ; let rr'   = getRuntimeRep ty'-             call' = mkApps (Var fun_id) [mkTyArg rr', mkTyArg ty', arg']-       ; return (emptyFloats env, call') }+       ; let rr'   = getRuntimeRep new_runrw_res_ty+             call' = mkApps (Var fun_id) [mkTyArg rr', mkTyArg new_runrw_res_ty, arg']+       ; rebuild env call' outer_cont }  ---------- Simplify value arguments -------------------- rebuildCall env fun_info@@ -2318,7 +2328,8 @@    -- Strict arguments   | isStrictArgInfo fun_info-  , seCaseCase env+  , seCaseCase env    -- Only when case-of-case is on. See GHC.Driver.Config.Core.Opt.Simplify+                      --    Note [Case-of-case and full laziness]   = -- pprTrace "Strict Arg" (ppr arg $$ ppr (seIdSubst env) $$ ppr (seInScope env)) $     simplExprF (arg_se `setInScopeFromE` env) arg                (StrictArg { sc_fun = fun_info, sc_fun_ty = fun_ty@@ -3136,7 +3147,9 @@ --------------------------------------------------  reallyRebuildCase env scrut case_bndr alts cont-  | not (seCaseCase env)+  | not (seCaseCase env)    -- Only when case-of-case is on.+                            -- See GHC.Driver.Config.Core.Opt.Simplify+                            --    Note [Case-of-case and full laziness]   = do { case_expr <- simplAlts env scrut case_bndr alts                                 (mkBoringStop (contHoleType cont))        ; rebuild env case_expr cont }
GHC/Core/Opt/SpecConstr.hs view
@@ -639,6 +639,17 @@ representing strict fields. See Note [Call-by-value for worker args] for why we do this. +(SCF1) The arg_id might be an /imported/ Id like M.foo_acf (see #24944).+  We don't want to make+     case M.foo_acf of M.foo_acf { DEFAULT -> blah }+  because the binder of a case-expression should never be imported.  Rather,+  we must localise it thus:+     case M.foo_acf of foo_acf { DEFAULT -> blah }+  We keep the same unique, so in the next round of simplification we'll replace+  any M.foo_acf's in `blah` by `foo_acf`.++  c.f. Note [Localise pattern binders] in GHC.HsToCore.Utils.+ Note [Specialising on dictionaries] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In #21386, SpecConstr saw this call:@@ -2028,8 +2039,8 @@        | otherwise        = return (extra_qvs, pat) --- See Note [SpecConstr and strict fields] mkSeqs :: [Var] -> Type -> CoreExpr -> CoreExpr+-- See Note [SpecConstr and strict fields] mkSeqs seqees res_ty rhs =   foldr addEval rhs seqees     where@@ -2037,7 +2048,11 @@       addEval arg_id rhs         -- Argument representing strict field and it's worth passing via cbv         | shouldStrictifyIdForCbv arg_id-        = Case (Var arg_id) arg_id res_ty ([Alt DEFAULT [] rhs])+        = Case (Var arg_id)+               (localiseId arg_id)  -- See (SCF1) in Note [SpecConstr and strict fields]+               res_ty+               ([Alt DEFAULT [] rhs])+         | otherwise         = rhs 
GHC/Core/Opt/Specialise.hs view
@@ -1485,11 +1485,12 @@              -- This is important: see Note [Update unfolding after specialisation]              -- And in any case cloneBndrSM discards non-Stable unfoldings -             fn3 = zapIdDemandInfo fn2+             fn3 = floatifyIdDemandInfo fn2              -- We zap the demand info because the binding may float,              -- which would invalidate the demand info (see #17810 for example).              -- Destroying demand info is not terrible; specialisation is              -- always followed soon by demand analysis.+             -- See Note [Floatifying demand info when floating] in GHC.Core.Opt.SetLevels               body_env2 = body_env1 `bringFloatedDictsIntoScope` ud_binds rhs_uds                                    `extendInScope` fn3
GHC/Core/TyCo/Compare.hs view
@@ -12,8 +12,9 @@     nonDetCmpTypesX, nonDetCmpTc,     eqVarBndrs, -    pickyEqType, tcEqType, tcEqKind, tcEqTypeNoKindCheck, tcEqTypeVis,+    pickyEqType, tcEqType, tcEqKind, tcEqTypeNoKindCheck,     tcEqTyConApps,+    mayLookIdentical,     -- * Visiblity comparision    eqForAllVis, cmpForAllVis@@ -22,7 +23,8 @@  import GHC.Prelude -import GHC.Core.Type( typeKind, coreView, tcSplitAppTyNoView_maybe, splitAppTyNoView_maybe )+import GHC.Core.Type( typeKind, coreView, tcSplitAppTyNoView_maybe, splitAppTyNoView_maybe+                    , isLevityTy, isRuntimeRepTy, isMultiplicityTy )  import GHC.Core.TyCo.Rep import GHC.Core.TyCo.FVs@@ -129,52 +131,119 @@ See #19226. -} +mayLookIdentical :: Type -> Type -> Bool+-- | Returns True if the /visible/ part of the types+-- might look equal, even if they are really unequal (in the invisible bits)+--+-- This function is very similar to tc_eq_type but it is much more+-- heuristic.  Notably, it is always safe to return True, even with types+-- that might (in truth) be unequal  -- this affects error messages only+-- (Originally there were one function with an extra flag, but the result+--  was hard to understand.)+mayLookIdentical orig_ty1 orig_ty2+  = go orig_env orig_ty1 orig_ty2+  where+    orig_env = mkRnEnv2 $ mkInScopeSet $ tyCoVarsOfTypes [orig_ty1, orig_ty2]++    go :: RnEnv2 -> Type -> Type -> Bool+    -- See Note [Comparing nullary type synonyms]+    go _  (TyConApp tc1 []) (TyConApp tc2 []) | tc1 == tc2 = True++    go env t1 t2 | Just t1' <- coreView t1 = go env t1' t2+    go env t1 t2 | Just t2' <- coreView t2 = go env t1 t2'++    go env (TyVarTy tv1)   (TyVarTy tv2)   = rnOccL env tv1 == rnOccR env tv2+    go _   (LitTy lit1)    (LitTy lit2)    = lit1 == lit2+    go env (CastTy t1 _)   t2              = go env t1 t2+    go env t1              (CastTy t2 _)   = go env t1 t2+    go _   (CoercionTy {}) (CoercionTy {}) = True++    go env (ForAllTy (Bndr tv1 vis1) ty1)+           (ForAllTy (Bndr tv2 vis2) ty2)+      =  vis1 `eqForAllVis` vis2  -- See Note [ForAllTy and type equality]+      && go (rnBndr2 env tv1 tv2) ty1 ty2+         -- Visible stuff only: ignore kinds of binders++    -- If we have (forall (r::RunTimeRep). ty1  ~   blah) then respond+    -- with True.  Reason: the type pretty-printer defaults RuntimeRep+    -- foralls (see Ghc.Iface.Type.hideNonStandardTypes).  That can make,+    -- say (forall r. TYPE r -> Type) into (Type -> Type), so it looks the+    -- same as a very different type (#24553).  By responding True, we+    -- tell GHC (see calls of mayLookIdentical) to display without defaulting.+    -- See Note [Showing invisible bits of types in error messages]+    -- in GHC.Tc.Errors.Ppr+    go _ (ForAllTy b _) _ | isDefaultableBndr b = True+    go _ _ (ForAllTy b _) | isDefaultableBndr b = True++    go env (FunTy _ w1 arg1 res1) (FunTy _ w2 arg2 res2)+      = go env arg1 arg2 && go env res1 res2 && go env w1 w2+        -- Visible stuff only: ignore agg kinds++      -- See Note [Equality on AppTys] in GHC.Core.Type+    go env (AppTy s1 t1) ty2+      | Just (s2, t2) <- tcSplitAppTyNoView_maybe ty2+      = go env s1 s2 && go env t1 t2+    go env ty1 (AppTy s2 t2)+      | Just (s1, t1) <- tcSplitAppTyNoView_maybe ty1+      = go env s1 s2 && go env t1 t2++    go env (TyConApp tc1 ts1)   (TyConApp tc2 ts2)+      = tc1 == tc2 && gos env (tyConBinders tc1) ts1 ts2++    go _ _ _ = False++    gos :: RnEnv2 -> [TyConBinder] -> [Type] -> [Type] -> Bool+    gos _   _         []       []      = True+    gos env bs (t1:ts1) (t2:ts2)+      | (invisible, bs') <- case bs of+                               []     -> (False,                    [])+                               (b:bs) -> (isInvisibleTyConBinder b, bs)+      = (invisible || go env t1 t2) && gos env bs' ts1 ts2++    gos _ _ _ _ = False++ -- | Type equality comparing both visible and invisible arguments and expanding -- type synonyms. tcEqTypeNoSyns :: Type -> Type -> Bool-tcEqTypeNoSyns ta tb = tc_eq_type False False ta tb---- | Like 'tcEqType', but returns True if the /visible/ part of the types--- are equal, even if they are really unequal (in the invisible bits)-tcEqTypeVis :: Type -> Type -> Bool-tcEqTypeVis ty1 ty2 = tc_eq_type False True ty1 ty2+tcEqTypeNoSyns ta tb = tc_eq_type False ta tb  -- | Like 'pickyEqTypeVis', but returns a Bool for convenience pickyEqType :: Type -> Type -> Bool -- Check when two types _look_ the same, _including_ synonyms. -- So (pickyEqType String [Char]) returns False -- This ignores kinds and coercions, because this is used only for printing.-pickyEqType ty1 ty2 = tc_eq_type True False ty1 ty2+pickyEqType ty1 ty2 = tc_eq_type True ty1 ty2  -- | Real worker for 'tcEqType'. No kind check! tc_eq_type :: Bool          -- ^ True <=> do not expand type synonyms-           -> Bool          -- ^ True <=> compare visible args only            -> Type -> Type            -> Bool -- Flags False, False is the usual setting for tc_eq_type -- See Note [Computing equality on types] in Type-tc_eq_type keep_syns vis_only orig_ty1 orig_ty2+{-# INLINE tc_eq_type #-} -- See Note [Specialising tc_eq_type].+tc_eq_type keep_syns orig_ty1 orig_ty2   = go orig_env orig_ty1 orig_ty2   where+    orig_env = mkRnEnv2 $ mkInScopeSet $ tyCoVarsOfTypes [orig_ty1, orig_ty2]+     go :: RnEnv2 -> Type -> Type -> Bool-    -- See Note [Comparing nullary type synonyms] in GHC.Core.Type.-    go _   (TyConApp tc1 []) (TyConApp tc2 [])-      | tc1 == tc2-      = True+    -- See Note [Comparing nullary type synonyms]+    go _ (TyConApp tc1 []) (TyConApp tc2 []) | tc1 == tc2 = True      go env t1 t2 | not keep_syns, Just t1' <- coreView t1 = go env t1' t2     go env t1 t2 | not keep_syns, Just t2' <- coreView t2 = go env t1 t2' -    go env (TyVarTy tv1) (TyVarTy tv2)-      = rnOccL env tv1 == rnOccR env tv2--    go _   (LitTy lit1) (LitTy lit2)-      = lit1 == lit2+    go env (TyVarTy tv1)   (TyVarTy tv2)   = rnOccL env tv1 == rnOccR env tv2+    go _   (LitTy lit1)    (LitTy lit2)    = lit1 == lit2+    go env (CastTy t1 _)   t2              = go env t1 t2+    go env t1              (CastTy t2 _)   = go env t1 t2+    go _   (CoercionTy {}) (CoercionTy {}) = True      go env (ForAllTy (Bndr tv1 vis1) ty1)            (ForAllTy (Bndr tv2 vis2) ty2)       =  vis1 `eqForAllVis` vis2  -- See Note [ForAllTy and type equality]-      && (vis_only || go env (varType tv1) (varType tv2))+      && go env (varType tv1) (varType tv2)       && go (rnBndr2 env tv1 tv2) ty1 ty2      -- Make sure we handle all FunTy cases since falling through to the@@ -183,11 +252,9 @@     -- See Note [Equality on FunTys] in GHC.Core.TyCo.Rep: we must check     -- kinds here     go env (FunTy _ w1 arg1 res1) (FunTy _ w2 arg2 res2)-      = kinds_eq && go env arg1 arg2 && go env res1 res2 && go env w1 w2-      where-        kinds_eq | vis_only  = True-                 | otherwise = go env (typeKind arg1) (typeKind arg2) &&-                               go env (typeKind res1) (typeKind res2)+      = go env (typeKind arg1) (typeKind arg2) &&+        go env (typeKind res1) (typeKind res2) &&+        go env arg1 arg2 && go env res1 res2 && go env w1 w2        -- See Note [Equality on AppTys] in GHC.Core.Type     go env (AppTy s1 t1)        ty2@@ -198,32 +265,24 @@       = go env s1 s2 && go env t1 t2      go env (TyConApp tc1 ts1)   (TyConApp tc2 ts2)-      = tc1 == tc2 && gos env (tc_vis tc1) ts1 ts2--    go env (CastTy t1 _)   t2              = go env t1 t2-    go env t1              (CastTy t2 _)   = go env t1 t2-    go _   (CoercionTy {}) (CoercionTy {}) = True+      = tc1 == tc2 && gos env ts1 ts2      go _ _ _ = False -    gos _   _         []       []      = True-    gos env (ig:igs) (t1:ts1) (t2:ts2) = (ig || go env t1 t2)-                                      && gos env igs ts1 ts2-    gos _ _ _ _ = False+    gos _   []       []       = True+    gos env (t1:ts1) (t2:ts2) = go env t1 t2 && gos env ts1 ts2+    gos _ _ _                 = False -    tc_vis :: TyCon -> [Bool]  -- True for the fields we should ignore-    tc_vis tc | vis_only  = inviss ++ repeat False    -- Ignore invisibles-              | otherwise = repeat False              -- Ignore nothing-       -- The repeat False is necessary because tycons-       -- can legitimately be oversaturated-      where-        bndrs = tyConBinders tc-        inviss  = map isInvisibleTyConBinder bndrs -    orig_env = mkRnEnv2 $ mkInScopeSet $ tyCoVarsOfTypes [orig_ty1, orig_ty2]--{-# INLINE tc_eq_type #-} -- See Note [Specialising tc_eq_type].-+isDefaultableBndr :: ForAllTyBinder -> Bool+-- This function should line up with the defaulting done+--   by GHC.Iface.Type.defaultIfaceTyVarsOfKind+-- See Note [Showing invisible bits of types in error messages]+--   in GHC.Tc.Errors.Ppr+isDefaultableBndr (Bndr tv vis)+  = isInvisibleForAllTyFlag vis && is_defaultable (tyVarKind tv)+  where+    is_defaultable ki = isLevityTy ki || isRuntimeRepTy ki  || isMultiplicityTy ki  -- | Do these denote the same level of visibility? 'Required' -- arguments are visible, others are not. So this function@@ -543,7 +602,7 @@     -- Returns both the resulting ordering relation between     -- the two types and whether either contains a cast.     go :: RnEnv2 -> Type -> Type -> TypeOrdering-    -- See Note [Comparing nullary type synonyms].+    -- See Note [Comparing nullary type synonyms]     go _   (TyConApp tc1 []) (TyConApp tc2 [])       | tc1 == tc2       = TEQ
GHC/Core/TyCo/Ppr.hs view
@@ -14,7 +14,7 @@         pprTyVar, pprTyVars,         pprThetaArrowTy, pprClassPred,         pprKind, pprParendKind, pprTyLit,-        pprDataCons, pprWithExplicitKindsWhen,+        pprDataCons, pprWithInvisibleBitsWhen,         pprWithTYPE, pprSourceTyCon,  @@ -330,13 +330,14 @@     -- TODO: toIfaceTcArgs seems rather wasteful here  --------------------- | Display all kind information (with @-fprint-explicit-kinds@) when the--- provided 'Bool' argument is 'True'.--- See @Note [Kind arguments in error messages]@ in "GHC.Tc.Errors".-pprWithExplicitKindsWhen :: Bool -> SDoc -> SDoc-pprWithExplicitKindsWhen b+-- | Display all foralls, runtime-reps, and kind information+-- when provided 'Bool' argument is 'True'.  See GHC.Tc.Errors.Ppr+-- Note [Showing invisible bits of types in error messages]+pprWithInvisibleBitsWhen :: Bool -> SDoc -> SDoc+pprWithInvisibleBitsWhen b   = updSDocContext $ \ctx ->-      if b then ctx { sdocPrintExplicitKinds = True }+      if b then ctx { sdocPrintExplicitKinds   = True+                    , sdocPrintExplicitRuntimeReps = True }            else ctx  -- | This variant preserves any use of TYPE in a type, effectively
GHC/Core/TyCo/Rep.hs view
@@ -1190,6 +1190,24 @@ The Int in the AxiomInstCo constructor is the 0-indexed number of the chosen branch. +Note [Required foralls in Core]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider the CoreExpr (Lam a e) where `a` is a TyVar, and (e::e_ty).+It has type+   forall a. e_ty+Note the Specified visibility of (forall a. e_ty); the Core type just isn't able+to express more than one visiblity, and we pick `Specified`.  See `exprType` and+`mkLamType` in GHC.Core.Utils, and `GHC.Type.Var.coreLamForAllTyFlag`.++So how can we ever get a term of type (forall a -> e_ty)?  Answer: /only/ via a+cast built with ForAllCo.  See `GHC.Tc.Types.Evidence.mkWpForAllCast`.  This does+not seem very satisfying, but it does the job.++An alternative would be to put a visibility flag into `Lam` (a huge change),+or into a `TyVar` (a more plausible change), but we leave that for the future.++See also Note [ForAllTy and type equality] in GHC.Core.TyCo.Compare.+ Note [ForAllCo] ~~~~~~~~~~~~~~~ See also Note [ForAllTy and type equality] in GHC.Core.TyCo.Compare.@@ -1246,10 +1264,7 @@   in the typing rule.  See also Note [ForAllTy and type equality] in   GHC.Core.TyCo.Compare. -(FC4) A lambda term (Lam a e) has type (forall a. ty), with visibility-  flag `GHC.Type.Var.coreTyLamForAllTyFlag`, not (forall a -> ty).-  See `GHC.Type.Var.coreTyLamForAllTyFlag` and `GHC.Core.Utils.mkLamType`.-  The only way to get a term of type (forall a -> ty) is to cast a lambda.+(FC4) See Note [Required foralls in Core].  (FC5) In a /type/, in (ForAllTy cv ty) where cv is a CoVar, we insist that   `cv` must appear free in `ty`; see Note [Unused coercion variable in ForAllTy]
GHC/Core/TyCo/Subst.hs view
@@ -62,7 +62,7 @@    , mkCoercionType    , coercionKind, coercionLKind, coVarKindsTypesRole ) import {-# SOURCE #-} GHC.Core.TyCo.Ppr ( pprTyVar )-import {-# SOURCE #-} GHC.Core.Ppr ( )+import {-# SOURCE #-} GHC.Core.Ppr ( ) -- instance Outputable CoreExpr import {-# SOURCE #-} GHC.Core ( CoreExpr )  import GHC.Core.TyCo.Rep
GHC/Core/Type.hs view
@@ -1954,6 +1954,8 @@   _           -> False  -- | Is this a function?+-- Note: `forall {b}. Show b => b -> IO b` will not be considered a function by this function.+--       It would merely be a forall wrapping a function type. isFunTy :: Type -> Bool isFunTy ty   | FunTy {} <- coreFullView ty = True
GHC/Core/Unify.hs view
@@ -1066,7 +1066,7 @@ -- Respects newtypes, PredTypes -- See Note [Computing equality on types] in GHC.Core.Type unify_ty _env (TyConApp tc1 []) (TyConApp tc2 []) _kco-  -- See Note [Comparing nullary type synonyms] in GHC.Core.Type.+  -- See Note [Comparing nullary type synonyms] in GHC.Core.TyCo.Compare   | tc1 == tc2   = return () 
GHC/Core/Utils.hs view
@@ -168,7 +168,7 @@ mkLamType v body_ty    | isTyVar v    = mkForAllTy (Bndr v coreTyLamForAllTyFlag) body_ty-     -- coreTyLamForAllTyFlag: see (FC4) in Note [ForAllCo]+     -- coreTyLamForAllTyFlag: see Note [Required foralls in Core]      --                        in GHC.Core.TyCo.Rep     | isCoVar v
GHC/CoreToStg/Prep.hs view
@@ -14,7 +14,6 @@    , CorePrepPgmConfig (..)    , corePrepPgm    , corePrepExpr-   , mkConvertNumLiteral    ) where @@ -24,11 +23,13 @@  import GHC.Driver.Flags -import GHC.Tc.Utils.Env import GHC.Unit  import GHC.Builtin.Names+import GHC.Builtin.PrimOps+import GHC.Builtin.PrimOps.Ids import GHC.Builtin.Types+import GHC.Builtin.Types.Prim  import GHC.Core.Utils import GHC.Core.Opt.Arity@@ -60,14 +61,16 @@ import GHC.Types.Id.Info import GHC.Types.Id.Make ( realWorldPrimId ) import GHC.Types.Basic-import GHC.Types.Name   ( Name, NamedThing(..), nameSrcSpan, isInternalName )+import GHC.Types.Name   ( NamedThing(..), nameSrcSpan, isInternalName ) import GHC.Types.SrcLoc ( SrcSpan(..), realSrcLocSpan, mkRealSrcLoc ) import GHC.Types.Literal import GHC.Types.Tickish-import GHC.Types.TyThing import GHC.Types.Unique.Supply -import Data.List        ( unfoldr )+import qualified Data.ByteString as BS+import qualified Data.ByteString.Builder as BB+import Data.ByteString.Builder.Prim+ import Control.Monad  {-@@ -805,11 +808,10 @@   = return (emptyFloats, Type (cpSubstTy env ty)) cpeRhsE env (Coercion co)   = return (emptyFloats, Coercion (cpSubstCo env co))-cpeRhsE env expr@(Lit (LitNumber nt i))-   = case cp_convertNumLit (cpe_config env) nt i of-      Nothing -> return (emptyFloats, expr)-      Just e  -> cpeRhsE env e-cpeRhsE _env expr@(Lit {}) = return (emptyFloats, expr)+cpeRhsE env expr@(Lit lit)+  | LitNumber LitNumBigNat i <- lit+    = cpeBigNatLit env i+  | otherwise = return (emptyFloats, expr) cpeRhsE env expr@(Var {})  = cpeApp env expr cpeRhsE env expr@(App {})  = cpeApp env expr @@ -1548,7 +1550,7 @@          -- See wrinkle (EA2) in Note [Eta expansion of arguments in CorePrep]    | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O1 or -O2-  , not (has_join_in_tail_context arg)+  , not (eta_would_wreck_join arg)             -- See Wrinkle (EA1) of Note [Eta expansion of arguments in CorePrep]   = case exprEtaExpandArity ao arg of       Nothing -> 0@@ -1557,15 +1559,15 @@   | otherwise   = exprArity arg -- this is cheap enough for -O0 -has_join_in_tail_context :: CoreExpr -> Bool+eta_would_wreck_join :: CoreExpr -> Bool -- ^ Identify the cases where we'd generate invalid `CpeApp`s as described in -- Wrinkle (EA1) of Note [Eta expansion of arguments in CorePrep]-has_join_in_tail_context (Let bs e)            = isJoinBind bs || has_join_in_tail_context e-has_join_in_tail_context (Lam b e) | isTyVar b = has_join_in_tail_context e-has_join_in_tail_context (Cast e _)            = has_join_in_tail_context e-has_join_in_tail_context (Tick _ e)            = has_join_in_tail_context e-has_join_in_tail_context (Case _ _ _ alts)     = any has_join_in_tail_context (rhssOfAlts alts)-has_join_in_tail_context _                     = False+eta_would_wreck_join (Let bs e)        = isJoinBind bs || eta_would_wreck_join e+eta_would_wreck_join (Lam _ e)         = eta_would_wreck_join e+eta_would_wreck_join (Cast e _)        = eta_would_wreck_join e+eta_would_wreck_join (Tick _ e)        = eta_would_wreck_join e+eta_would_wreck_join (Case _ _ _ alts) = any eta_would_wreck_join (rhssOfAlts alts)+eta_would_wreck_join _                 = False  maybeSaturate :: Id -> CpeApp -> Int -> [CoreTickish] -> UniqSM CpeRhs maybeSaturate fn expr n_args unsat_ticks@@ -1698,7 +1700,8 @@  (EA1) When eta expanding an argument headed by a join point, we might get       "crap", as Note [Eta expansion for join points] in GHC.Core.Opt.Arity puts-      it.+      it.  This crap means the output does not conform to the syntax in+      Note [CorePrep invariants], which then makes later passes crash (#25033).       Consider          f (join j x = rhs in ...(j 1)...(j 2)...)@@ -1713,16 +1716,23 @@       In our case, (join j x = rhs in ...(j 1)...(j 2)...) is not a valid       `CpeApp` (see Note [CorePrep invariants]) and we'd get a crash in the App       case of `coreToStgExpr`.-      Hence we simply check for the cases where an intervening join point-      binding in the tail context of the argument would lead to the introduction-      of such crap via `has_join_in_tail_context`, in which case we abstain from-      eta expansion. +      Hence, in `eta_would_wreck_join`, we check for the cases where an+      intervening join point binding in the tail context of the argument would+      make eta-expansion break Note [CorePrep invariants], in which+      case we abstain from eta expansion.+       This scenario occurs rarely; hence it's OK to generate sub-optimal code.       The alternative would be to fix Note [Eta expansion for join points], but       that's quite challenging due to unfoldings of (recursive) join points. -(EA2) In cpeArgArity, if float_decision = FloatNone) the `arg` will look like+      `eta_would_wreck_join` sees if there are any join points, like `j` above+      that would be messed up.   It must look inside lambdas (#25033); consider+             f (\x. join j y = ... in ...(j 1)...(j 3)...)+      We can't eta expand that `\x` any more than we could if the join was at+      the top.  (And when there's a lambda, we don't have a thunk anyway.)++(EA2) In cpeArgArity, if float_decision=FloatNone the `arg` will look like            let <binds> in rhs       where <binds> is non-empty and can't be floated out of a lazy context (see       `wantFloatLocal`). So we can't eta-expand it anyway, so we can return 0@@ -1894,6 +1904,16 @@ See also Note [Floats and FloatDecision] for how we maintain whole groups of floats and how far they go. +Note [Controlling Speculative Evaluation]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Most of the time, speculative evaluation has a positive effect on performance,+but we have found a case where speculative evaluation of dictionary functions+leads to a performance regression #25284.++Therefore we have some flags to control it. See the optimization section in+the User's Guide for the description of these flags and when to use them.+ Note [Floats and FloatDecision] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We have a special datatype `Floats` for modelling a telescope of `FloatingBind`@@ -2068,7 +2088,15 @@     is_lifted   = not is_unlifted     is_hnf      = exprIsHNF rhs     is_strict   = isStrUsedDmd dmd-    ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs+    cfg         = cpe_config env++    ok_for_spec = exprOkForSpecEval call_ok_for_spec rhs+    -- See Note [Controlling Speculative Evaluation]+    call_ok_for_spec x+      | is_rec_call x                           = False+      | not (cp_specEval cfg)                   = False+      | not (cp_specEvalDFun cfg) && isDFunId x = False+      | otherwise                               = True     is_rec_call = (`elemUnVarSet` cpe_rec_ids env)     is_data_con = isJust . isDataConId_maybe @@ -2293,14 +2321,17 @@   -- cases. This is helpful when debugging demand analysis or type   -- checker bugs which can sometimes manifest as segmentation faults. -  , cp_convertNumLit           :: !(LitNumType -> Integer -> Maybe CoreExpr)-  -- ^ Convert some numeric literals (Integer, Natural) into their final-  -- Core form.+  , cp_platform                :: Platform    , cp_arityOpts               :: !(Maybe ArityOpts)   -- ^ Configuration for arity analysis ('exprEtaExpandArity').   -- See Note [Eta expansion of arguments in CorePrep]   -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead+  , cp_specEval                :: !Bool+  -- ^ Whether to perform speculative evaluation+  -- See Note [Controlling Speculative Evaluation]+  , cp_specEvalDFun            :: !Bool+  -- ^ Whether to perform speculative evaluation on DFuns   }  data CorePrepEnv@@ -2532,57 +2563,119 @@ -- Numeric literals -- --------------------------------------------------------------------------- --- | Create a function that converts Bignum literals into their final CoreExpr-mkConvertNumLiteral-   :: Platform-   -> HomeUnit-   -> (Name -> IO TyThing)-   -> IO (LitNumType -> Integer -> Maybe CoreExpr)-mkConvertNumLiteral platform home_unit lookup_global = do-   let-      guardBignum act-         | isHomeUnitInstanceOf home_unit primUnitId-         = return $ panic "Bignum literals are not supported in ghc-prim"-         | isHomeUnitInstanceOf home_unit bignumUnitId-         = return $ panic "Bignum literals are not supported in ghc-bignum"-         | otherwise = act+-- | Converts Bignum literals into their final CoreExpr+cpeBigNatLit+   :: CorePrepEnv -> Integer -> UniqSM (Floats, CpeRhs)+cpeBigNatLit env i = assert (i >= 0) $ do+  let+    platform = cp_platform (cpe_config env) -      lookupBignumId n      = guardBignum (tyThingId <$> lookup_global n)+    -- Per the documentation in GHC.Num.BigNat, a BigNat# is:+    --   "Represented as an array of limbs (Word#) stored in+    --   little-endian order (Word# themselves use machine order)."+    --+    --   "Invariant (canonical representation): higher Word# is non-zero."+    -- So we need to break up the integer into target-word-sized chunks,+    -- and encode each of them using the target's byte-order.+    encodeBigNat+      :: forall a. Num a => FixedPrim a -> BS.ByteString+    encodeBigNat encodeWord+      = BS.toStrict (BB.toLazyByteString (primUnfoldrFixed encodeWord f i))+      -- (quadratic complexity due to repeated shifts... ok for now)+      where+        f 0 = Nothing+        f x = let low  = fromInteger x :: a+                  high = x `shiftR` bits+              in Just (low, high)+        bits = platformWordSizeInBits platform -   -- The lookup is done here but the failure (panic) is reported lazily when we-   -- try to access the `bigNatFromWordList` function.-   ---   -- If we ever get built-in ByteArray# literals, we could avoid the lookup by-   -- directly using the Integer/Natural wired-in constructors for big numbers.+    words :: BS.ByteString+    words = case (platformWordSize platform, platformByteOrder platform) of+      (PW4, LittleEndian) -> encodeBigNat word32LE+      (PW4, BigEndian   ) -> encodeBigNat word32BE+      (PW8, LittleEndian) -> encodeBigNat word64LE+      (PW8, BigEndian   ) -> encodeBigNat word64BE -   bignatFromWordListId <- lookupBignumId bignatFromWordListName+  -- Ideally we would just generate a ByteArray# literal here:+  --   pure (emptyFloats, Lit (LitByteArray words))+  -- But sadly we don't have those yet, even in Core. (See also #17747.)+  -- So instead we generate:+  --   * An `Addr#` literal that contains the contents of the+  --      `ByteArray#` we want to create.  This gets its own float.+  --   * A call to `newByteArray#` with the appropriate size+  --   * A call to `copyAddrToByteArray#` to initialize the `ByteArray#`+  --   * A call to `unsafeFreezeByteArray#` to make the types match+  litAddrId <- mkSysLocalM (fsLit "bigNatGuts") ManyTy addrPrimTy+  -- returned from newByteArray#:+  deadNewByteArrayTupleId+    <- fmap (`setIdOccInfo` IAmDead) . mkSysLocalM (fsLit "tup") ManyTy $+         mkTupleTy Unboxed [ realWorldStatePrimTy+                           , realWorldMutableByteArrayPrimTy+                           ]+  stateTokenFromNewByteArrayId+    <- mkSysLocalM (fsLit "token") ManyTy realWorldStatePrimTy+  mutableByteArrayId+    <- mkSysLocalM (fsLit "mba") ManyTy realWorldMutableByteArrayPrimTy+  -- returned from copyAddrToByteArray#:+  stateTokenFromCopyId+    <- mkSysLocalM (fsLit "token") ManyTy realWorldStatePrimTy+  -- returned from unsafeFreezeByteArray#:+  deadFreezeTupleId+    <- fmap (`setIdOccInfo` IAmDead) . mkSysLocalM (fsLit "tup") ManyTy $+         mkTupleTy Unboxed [realWorldStatePrimTy, byteArrayPrimTy]+  stateTokenFromFreezeId+    <- (`setIdOccInfo` IAmDead) <$>+         mkSysLocalM (fsLit "token") ManyTy realWorldStatePrimTy+  byteArrayId <- mkSysLocalM (fsLit "ba") ManyTy byteArrayPrimTy -   let-      convertNumLit nt i = case nt of-         LitNumBigNat  -> Just (convertBignatPrim i)-         _             -> Nothing+  let+    litAddrRhs = Lit (LitString words)+      -- not "mkLitString"; that does UTF-8 encoding, which we don't want here+    litAddrFloat = mkNonRecFloat env topDmd True litAddrId litAddrRhs -      convertBignatPrim i =-         let-            -- ByteArray# literals aren't supported (yet). Were they supported,-            -- we would use them directly. We would need to handle-            -- wordSize/endianness conversion between host and target-            -- wordSize  = platformWordSize platform-            -- byteOrder = platformByteOrder platform+    contentsLength = mkIntLit platform (toInteger (BS.length words)) -            -- For now we build a list of Words and we produce-            -- `bigNatFromWordList# list_of_words`+    newByteArrayCall =+      Var (primOpId NewByteArrayOp_Char)+        `App` Type realWorldTy+        `App` contentsLength+        `App` Var realWorldPrimId -            words = mkListExpr wordTy (reverse (unfoldr f i))-               where-                  f 0 = Nothing-                  f x = let low  = x .&. mask-                            high = x `shiftR` bits-                        in Just (mkConApp wordDataCon [Lit (mkLitWord platform low)], high)-                  bits = platformWordSizeInBits platform-                  mask = 2 ^ bits - 1+    copyContentsCall =+      Var (primOpId CopyAddrToByteArrayOp)+        `App` Type realWorldTy+        `App` Var litAddrId+        `App` Var mutableByteArrayId+        `App` mkIntLit platform 0+        `App` contentsLength+        `App` Var stateTokenFromNewByteArrayId -         in mkApps (Var bignatFromWordListId) [words]+    unsafeFreezeCall =+      Var (primOpId UnsafeFreezeByteArrayOp)+        `App` Type realWorldTy+        `App` Var mutableByteArrayId+        `App` Var stateTokenFromCopyId +    unboxed2tuple_altcon :: AltCon+    unboxed2tuple_altcon = DataAlt (tupleDataCon Unboxed 2) -   return convertNumLit+    finalRhs =+      Case newByteArrayCall deadNewByteArrayTupleId byteArrayPrimTy+        [ Alt unboxed2tuple_altcon+              [stateTokenFromNewByteArrayId, mutableByteArrayId]+              copyContentsCase+        ]++    copyContentsCase =+      Case copyContentsCall stateTokenFromCopyId byteArrayPrimTy+        [ Alt DEFAULT [] unsafeFreezeCase+        ]++    unsafeFreezeCase =+      Case unsafeFreezeCall deadFreezeTupleId byteArrayPrimTy+        [ Alt unboxed2tuple_altcon+              [stateTokenFromFreezeId, byteArrayId]+              (Var byteArrayId)+        ]++  pure (emptyFloats `snocFloat` litAddrFloat, finalRhs)
+ GHC/Data/FlatBag.hs view
@@ -0,0 +1,129 @@+{-# LANGUAGE UnboxedTuples #-}+module GHC.Data.FlatBag+  ( FlatBag+  , emptyFlatBag+  , unitFlatBag+  , sizeFlatBag+  , elemsFlatBag+  , mappendFlatBag+  -- * Construction+  , fromList+  , fromSizedSeq+  ) where++import GHC.Prelude++import GHC.Data.SizedSeq (SizedSeq, ssElts, sizeSS)++import Control.DeepSeq++import GHC.Data.SmallArray++-- | Store elements in a flattened representation.+--+-- A 'FlatBag' is a data structure that stores an ordered list of elements+-- in a flat structure, avoiding the overhead of a linked list.+-- Use this data structure, if the code requires the following properties:+--+-- * Elements are stored in a long-lived object, and benefit from a flattened+--   representation.+-- * The 'FlatBag' will be traversed but not extended or filtered.+-- * The number of elements should be known.+-- * Sharing of the empty case improves memory behaviour.+--+-- A 'FlagBag' aims to have as little overhead as possible to store its elements.+-- To achieve that, it distinguishes between the empty case, singleton, tuple+-- and general case.+-- Thus, we only pay for the additional three words of an 'Array' if we have at least+-- three elements.+data FlatBag a+  = EmptyFlatBag+  | UnitFlatBag !a+  | TupleFlatBag !a !a+  | FlatBag {-# UNPACK #-} !(SmallArray a)++instance Functor FlatBag where+  fmap _ EmptyFlatBag = EmptyFlatBag+  fmap f (UnitFlatBag a) = UnitFlatBag $ f a+  fmap f (TupleFlatBag a b) = TupleFlatBag (f a) (f b)+  fmap f (FlatBag e) = FlatBag $ mapSmallArray f e++instance Foldable FlatBag where+  foldMap _ EmptyFlatBag = mempty+  foldMap f (UnitFlatBag a) = f a+  foldMap f (TupleFlatBag a b) = f a `mappend` f b+  foldMap f (FlatBag arr) = foldMapSmallArray f arr++  length = fromIntegral . sizeFlatBag++instance Traversable FlatBag where+  traverse _ EmptyFlatBag = pure EmptyFlatBag+  traverse f (UnitFlatBag a) = UnitFlatBag <$> f a+  traverse f (TupleFlatBag a b) = TupleFlatBag <$> f a <*> f b+  traverse f fl@(FlatBag arr) = fromList (fromIntegral $ sizeofSmallArray arr) <$> traverse f (elemsFlatBag fl)++instance NFData a => NFData (FlatBag a) where+  rnf EmptyFlatBag = ()+  rnf (UnitFlatBag a) = rnf a+  rnf (TupleFlatBag a b) = rnf a `seq` rnf b+  rnf (FlatBag arr) = rnfSmallArray arr++-- | Create an empty 'FlatBag'.+--+-- The empty 'FlatBag' is shared over all instances.+emptyFlatBag :: FlatBag a+emptyFlatBag = EmptyFlatBag++-- | Create a singleton 'FlatBag'.+unitFlatBag :: a -> FlatBag a+unitFlatBag = UnitFlatBag++-- | Calculate the size of+sizeFlatBag :: FlatBag a -> Word+sizeFlatBag EmptyFlatBag = 0+sizeFlatBag UnitFlatBag{} = 1+sizeFlatBag TupleFlatBag{} = 2+sizeFlatBag (FlatBag arr) = fromIntegral $ sizeofSmallArray arr++-- | Get all elements that are stored in the 'FlatBag'.+elemsFlatBag :: FlatBag a -> [a]+elemsFlatBag EmptyFlatBag = []+elemsFlatBag (UnitFlatBag a) = [a]+elemsFlatBag (TupleFlatBag a b) = [a, b]+elemsFlatBag (FlatBag arr) =+  [indexSmallArray arr i | i <- [0 .. sizeofSmallArray arr - 1]]++-- | Combine two 'FlatBag's.+--+-- The new 'FlatBag' contains all elements from both 'FlatBag's.+--+-- If one of the 'FlatBag's is empty, the old 'FlatBag' is reused.+mappendFlatBag :: FlatBag a -> FlatBag a -> FlatBag a+mappendFlatBag EmptyFlatBag b = b+mappendFlatBag a EmptyFlatBag = a+mappendFlatBag (UnitFlatBag a) (UnitFlatBag b) = TupleFlatBag a b+mappendFlatBag a b =+  fromList (sizeFlatBag a + sizeFlatBag b)+           (elemsFlatBag a ++ elemsFlatBag b)++-- | Store the list in a flattened memory representation, avoiding the memory overhead+-- of a linked list.+--+-- The size 'n' needs to be smaller or equal to the length of the list.+-- If it is smaller than the length of the list, overflowing elements are+-- discarded. It is undefined behaviour to set 'n' to be bigger than the+-- length of the list.+fromList :: Word -> [a] -> FlatBag a+fromList n elts =+  case elts of+    [] -> EmptyFlatBag+    [a] -> UnitFlatBag a+    [a, b] -> TupleFlatBag a b+    xs ->+      FlatBag (listToArray (fromIntegral n) fst snd (zip [0..] xs))++-- | Convert a 'SizedSeq' into its flattened representation.+-- A 'FlatBag a' is more memory efficient than '[a]', if no further modification+-- is necessary.+fromSizedSeq :: SizedSeq a -> FlatBag a+fromSizedSeq s = fromList (sizeSS s) (ssElts s)
GHC/Data/SmallArray.hs view
@@ -11,13 +11,18 @@   , freezeSmallArray   , unsafeFreezeSmallArray   , indexSmallArray+  , sizeofSmallArray   , listToArray+  , mapSmallArray+  , foldMapSmallArray+  , rnfSmallArray   ) where  import GHC.Exts import GHC.Prelude import GHC.ST+import Control.DeepSeq  data SmallArray a = SmallArray (SmallArray# a) @@ -64,6 +69,14 @@   case unsafeFreezeSmallArray# ma s of     (# s', a #) -> (# s', SmallArray a #) +-- | Get the size of a 'SmallArray'+sizeofSmallArray+  :: SmallArray a+  -> Int+{-# INLINE sizeofSmallArray #-}+sizeofSmallArray (SmallArray sa#) =+  case sizeofSmallArray# sa# of+    s -> I# s  -- | Index a small-array (no bounds checking!) indexSmallArray@@ -71,9 +84,51 @@   -> Int          -- ^ index   -> a {-# INLINE indexSmallArray #-}-indexSmallArray (SmallArray sa#) (I# i) = case indexSmallArray# sa# i of-  (# v #) -> v+indexSmallArray (SmallArray sa#) (I# i) =+  case indexSmallArray# sa# i of+    (# v #) -> v +-- | Map a function over the elements of a 'SmallArray'+--+mapSmallArray :: (a -> b) -> SmallArray a -> SmallArray b+{-# INLINE mapSmallArray #-}+mapSmallArray f sa = runST $ ST $ \s ->+  let+    n = sizeofSmallArray sa+    go !i saMut# state#+      | i < n =+        let+          a = indexSmallArray sa i+          newState# = writeSmallArray saMut# i (f a) state#+        in+          go (i + 1) saMut# newState#+      | otherwise = state#+  in+  case newSmallArray n (error "SmallArray: internal error, uninitialised elements") s of+    (# s', mutArr #) ->+      case go 0 mutArr s' of+        s'' -> unsafeFreezeSmallArray mutArr s''++-- | Fold the values of a 'SmallArray' into a 'Monoid m' of choice+foldMapSmallArray :: Monoid m => (a -> m) -> SmallArray a -> m+{-# INLINE foldMapSmallArray #-}+foldMapSmallArray f sa = go 0+  where+    n = sizeofSmallArray sa+    go i+      | i < n = f (indexSmallArray sa i) `mappend` go (i + 1)+      | otherwise = mempty++-- | Force the elements of the given 'SmallArray'+--+rnfSmallArray :: NFData a => SmallArray a -> ()+{-# INLINE rnfSmallArray #-}+rnfSmallArray sa = go 0+  where+    n = sizeofSmallArray sa+    go !i+      | i < n = rnf (indexSmallArray sa i) `seq` go (i + 1)+      | otherwise = ()  -- | Convert a list into an array. listToArray :: Int -> (e -> Int) -> (e -> a) -> [e] -> SmallArray a
GHC/Data/Word64Map/Strict.hs view
@@ -248,4 +248,3 @@     ) where  import GHC.Data.Word64Map.Strict.Internal-import Prelude ()
GHC/Driver/CmdLine.hs view
@@ -31,7 +31,7 @@ import GHC.Types.Error import GHC.Utils.Error import GHC.Driver.Errors.Types-import GHC.Driver.Errors.Ppr ()+import GHC.Driver.Errors.Ppr () -- instance Diagnostic DriverMessage import GHC.Utils.Outputable (text)  import Data.Function
GHC/Driver/Config/Core/Opt/Simplify.hs view
@@ -80,6 +80,7 @@ initGentleSimplMode dflags = (initSimplMode dflags InitialPhase "Gentle")   { -- Don't do case-of-case transformations.     -- This makes full laziness work better+    -- See Note [Case-of-case and full laziness]     sm_case_case = False   } @@ -89,3 +90,37 @@     (True, True) -> FloatEnabled     (True, False)-> FloatNestedOnly     (False, _)   -> FloatDisabled+++{- Note [Case-of-case and full laziness]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Case-of-case can hide opportunities for let-floating (full laziness).+For example+   rec { f = \y. case (expensive x) of (a,b) -> blah }+We might hope to float the (expensive x) out of the \y-loop.+But if we inline `expensive` we might get+   \y. case (case x of I# x' -> body) of (a,b) -> blah+Now if we do case-of-case we get+   \y. case x if I# x2 ->+       case body of (a,b) -> blah++Sadly, at this point `body` mentions `x2`, so we can't float it out of the+\y-loop.++Solution: don't do case-of-case in the "gentle" simplification phase that+precedes the first float-out transformation.  Implementation:++  * `sm_case_case` field in SimplMode++  * Consult `sm_case_case` (via `seCaseCase`) before doing case-of-case+    in GHC.Core.Opt.Simplify.Iteration.rebuildCall.++Wrinkles++* This applies equally to the case-of-runRW# transformation:+    case (runRW# (\s. body)) of (a,b) -> blah+    --->+    runRW# (\s. case body of (a,b) -> blah)+  Again, don't do this when `sm_case_case` is off.  See #25055 for+  a motivating example.+-}
GHC/Driver/Config/CoreToStg/Prep.hs view
@@ -10,7 +10,6 @@ import GHC.Driver.Session import GHC.Driver.Config.Core.Lint import GHC.Driver.Config.Core.Opt.Arity-import GHC.Tc.Utils.Env import GHC.Types.Var import GHC.Utils.Outputable ( alwaysQualify ) @@ -19,17 +18,14 @@ initCorePrepConfig :: HscEnv -> IO CorePrepConfig initCorePrepConfig hsc_env = do    let dflags = hsc_dflags hsc_env-   convertNumLit <- do-     let platform = targetPlatform dflags-         home_unit = hsc_home_unit hsc_env-         lookup_global = lookupGlobal hsc_env-     mkConvertNumLiteral platform home_unit lookup_global    return $ CorePrepConfig       { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases dflags-      , cp_convertNumLit = convertNumLit+      , cp_platform  = targetPlatform dflags       , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags                        then Just (initArityOpts dflags)                        else Nothing+      , cp_specEval  = gopt Opt_SpecEval dflags+      , cp_specEvalDFun = gopt Opt_SpecEvalDictFun dflags       }  initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig
GHC/Driver/Config/Diagnostic.hs view
@@ -19,7 +19,7 @@ import GHC.Utils.Outputable import GHC.Utils.Error (DiagOpts (..)) import GHC.Driver.Errors.Types (GhcMessage, GhcMessageOpts (..), PsMessage, DriverMessage, DriverMessageOpts (..), checkBuildingCabalPackage)-import GHC.Driver.Errors.Ppr ()+import GHC.Driver.Errors.Ppr () -- Diagnostic instances import GHC.Tc.Errors.Types import GHC.HsToCore.Errors.Types import GHC.Types.Error
GHC/Driver/Config/StgToCmm.hs view
@@ -14,6 +14,7 @@ import GHC.Driver.Session import GHC.Platform import GHC.Platform.Profile+import GHC.Platform.Regs import GHC.Utils.Error import GHC.Unit.Module import GHC.Utils.Outputable@@ -76,13 +77,16 @@         | otherwise         -> const True -  , stgToCmmAllowIntMul2Instr         = (ncg && x86ish) || llvm+  , stgToCmmAllowIntMul2Instr         = (ncg && (x86ish || aarch64)) || llvm+  , stgToCmmAllowWordMul2Instr        = (ncg && (x86ish || ppc || aarch64)) || llvm   -- SIMD flags   , stgToCmmVecInstrsErr  = vec_err   , stgToCmmAvx           = isAvxEnabled                   dflags   , stgToCmmAvx2          = isAvx2Enabled                  dflags   , stgToCmmAvx512f       = isAvx512fEnabled               dflags   , stgToCmmTickyAP       = gopt Opt_Ticky_AP dflags+  -- See Note [Saving foreign call target to local]+  , stgToCmmSaveFCallTargetToLocal = any (callerSaves platform) $ activeStgRegs platform   } where profile  = targetProfile dflags           platform = profilePlatform profile           bk_end  = backend dflags@@ -92,6 +96,9 @@                           JSPrimitives      -> (False, False)                           NcgPrimitives     -> (True, False)                           LlvmPrimitives    -> (False, True)+          aarch64 = case platformArch platform of+                      ArchAArch64  -> True+                      _            -> False           x86ish  = case platformArch platform of                       ArchX86    -> True                       ArchX86_64 -> True
GHC/Driver/DynFlags.hs view
@@ -1300,6 +1300,8 @@ --   RegsGraph suffers performance regression. See #7679 --  , ([2],     Opt_StaticArgumentTransformation) --   Static Argument Transformation needs investigation. See #9374+    , ([0,1,2], Opt_SpecEval)+    , ([0,1,2], Opt_SpecEvalDictFun)     ]  type TurnOnFlag = Bool   -- True  <=> we are turning the flag on
GHC/Driver/Errors/Ppr.hs view
@@ -14,8 +14,8 @@ import GHC.Driver.Errors.Types import GHC.Driver.Flags import GHC.Driver.DynFlags-import GHC.HsToCore.Errors.Ppr ()-import GHC.Parser.Errors.Ppr ()+import GHC.HsToCore.Errors.Ppr () -- instance Diagnostic DsMessage+import GHC.Parser.Errors.Ppr () -- instance Diagnostic PsMessage import GHC.Types.Error import GHC.Types.Error.Codes import GHC.Unit.Types@@ -30,8 +30,8 @@ import GHC.Tc.Errors.Types (TcRnMessage) import GHC.HsToCore.Errors.Types (DsMessage) import GHC.Iface.Errors.Types-import GHC.Tc.Errors.Ppr ()-import GHC.Iface.Errors.Ppr ()+import GHC.Tc.Errors.Ppr () -- instance Diagnostic TcRnMessage+import GHC.Iface.Errors.Ppr () -- instance Diagnostic IfaceMessage  -- -- Suggestions
GHC/Driver/Flags.hs view
@@ -316,7 +316,10 @@    | Opt_NumConstantFolding    | Opt_CoreConstantFolding    | Opt_FastPAPCalls                  -- #6084+   | Opt_SpecEval+   | Opt_SpecEvalDictFun   -- See Note [Controlling Speculative Evaluation] +    -- Inference flags    | Opt_DoTagInferenceChecks @@ -550,6 +553,8 @@    , Opt_WorkerWrapper    , Opt_WorkerWrapperUnlift    , Opt_SolveConstantDicts+   , Opt_SpecEval+   , Opt_SpecEvalDictFun    ]  -- | The set of flags which affect code generation and can change a program's
GHC/Driver/Hooks.hs view
@@ -154,8 +154,6 @@                                  -> IO (Stream IO RawCmmGroup a)))   } -{-# DEPRECATED cmmToRawCmmHook "cmmToRawCmmHook is being deprecated. If you do use it in your project, please raise a GHC issue!" #-}- class HasHooks m where     getHooks :: m Hooks 
GHC/Driver/Main.hs view
@@ -6,9 +6,6 @@  {-# OPTIONS_GHC -fprof-auto-top #-} --- Remove this after cmmToRawCmmHook removal-{-# OPTIONS_GHC -Wno-deprecations #-}- ------------------------------------------------------------------------------- -- -- | Main API for compiling plain Haskell source code.@@ -1805,7 +1802,7 @@                   if gopt Opt_ProfLateInlineCcs dflags then                     LateCCNone                   else if gopt Opt_ProfLateCcs dflags then-                    LateCCAllBinds+                    LateCCBinds                   else if gopt Opt_ProfLateOverloadedCcs dflags then                     LateCCOverloadedBinds                   else@@ -2665,7 +2662,7 @@    case interp of     -- always generate JS code for the JS interpreter (no bytecode!)-    Interp (ExternalInterp (ExtJS i)) _ ->+    Interp (ExternalInterp (ExtJS i)) _ _ ->       jsCodeGen hsc_env srcspan i this_mod stg_binds_with_deps binding_id      _ -> do
GHC/Driver/Make.hs view
@@ -299,16 +299,16 @@  -- Note [Missing home modules] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--- Sometimes user doesn't want GHC to pick up modules, not explicitly listed--- in a command line. For example, cabal may want to enable this warning--- when building a library, so that GHC warns user about modules, not listed--- neither in `exposed-modules`, nor in `other-modules`.+-- Sometimes we don't want GHC to process modules that weren't specified as+-- explicit targets. For example, cabal may want to enable this warning+-- when building a library, so that GHC warns the user about modules listed+-- neither in `exposed-modules` nor in `other-modules`. ----- Here "home module" means a module, that doesn't come from an other package.+-- Here "home module" means a module that doesn't come from another package. -- -- For example, if GHC is invoked with modules "A" and "B" as targets, -- but "A" imports some other module "C", then GHC will issue a warning--- about module "C" not being listed in a command line.+-- about module "C" not being listed in the command line. -- -- The warning in enabled by `-Wmissing-home-modules`. See #13129 warnMissingHomeModules ::  DynFlags -> [Target] -> ModuleGraph -> DriverMessages@@ -319,8 +319,6 @@   where     diag_opts = initDiagOpts dflags -    is_known_module mod = any (is_my_target mod) targets-     -- We need to be careful to handle the case where (possibly     -- path-qualified) filenames (aka 'TargetFile') rather than module     -- names are being passed on the GHC command-line.@@ -329,27 +327,31 @@     -- `ghc --make -isrc-exe Main` are supposed to be equivalent.     -- Note also that we can't always infer the associated module name     -- directly from the filename argument.  See #13727.-    is_my_target mod target =-      let tuid = targetUnitId target-      in case targetId target of-          TargetModule name-            -> moduleName (ms_mod mod) == name-                && tuid == ms_unitid mod-          TargetFile target_file _-            | Just mod_file <- ml_hs_file (ms_location mod)-            ->-             augmentByWorkingDirectory dflags target_file == mod_file ||+    is_known_module mod =+      is_module_target mod+      ||+      maybe False is_file_target (ml_hs_file (ms_location mod)) -             --  Don't warn on B.hs-boot if B.hs is specified (#16551)-             addBootSuffix target_file == mod_file ||+    is_module_target mod = (moduleName (ms_mod mod), ms_unitid mod) `Set.member` mod_targets -             --  We can get a file target even if a module name was-             --  originally specified in a command line because it can-             --  be converted in guessTarget (by appending .hs/.lhs).-             --  So let's convert it back and compare with module name-             mkModuleName (fst $ splitExtension target_file)-              == moduleName (ms_mod mod)-          _ -> False+    is_file_target file = Set.member (withoutExt file) file_targets++    file_targets = Set.fromList (mapMaybe file_target targets)++    file_target Target {targetId} =+      case targetId of+        TargetModule _ -> Nothing+        TargetFile file _ ->+          Just (withoutExt (augmentByWorkingDirectory dflags file))++    mod_targets = Set.fromList (mod_target <$> targets)++    mod_target Target {targetUnitId, targetId} =+      case targetId of+        TargetModule name -> (name, targetUnitId)+        TargetFile file _ -> (mkModuleName (withoutExt file), targetUnitId)++    withoutExt = fst . splitExtension      missing = map (moduleName . ms_mod) $       filter (not . is_known_module) $
GHC/Driver/Pipeline.hs view
@@ -542,28 +542,28 @@  compileFile :: HscEnv -> StopPhase -> (FilePath, Maybe Phase) -> IO (Maybe FilePath) compileFile hsc_env stop_phase (src, mb_phase) = do-   exists <- doesFileExist src-   when (not exists) $-        throwGhcExceptionIO (CmdLineError ("does not exist: " ++ src))+   let offset_file = augmentByWorkingDirectory dflags src+       dflags    = hsc_dflags hsc_env+       mb_o_file = outputFile dflags+       ghc_link  = ghcLink dflags      -- Set by -c or -no-link+       notStopPreprocess | StopPreprocess <- stop_phase = False+                         | _              <- stop_phase = True+       -- When linking, the -o argument refers to the linker's output.+       -- otherwise, we use it as the name for the pipeline's output.+       output+        | not (backendGeneratesCode (backend dflags)), notStopPreprocess = NoOutputFile+               -- avoid -E -fno-code undesirable interactions. see #20439+        | NoStop <- stop_phase, not (isNoLink ghc_link) = Persistent+               -- -o foo applies to linker+        | isJust mb_o_file = SpecificFile+               -- -o foo applies to the file we are compiling now+        | otherwise = Persistent+       pipe_env = mkPipeEnv stop_phase offset_file mb_phase output+       pipeline = pipelineStart pipe_env (setDumpPrefix pipe_env hsc_env) offset_file mb_phase -   let-        dflags    = hsc_dflags hsc_env-        mb_o_file = outputFile dflags-        ghc_link  = ghcLink dflags      -- Set by -c or -no-link-        notStopPreprocess | StopPreprocess <- stop_phase = False-                          | _              <- stop_phase = True-        -- When linking, the -o argument refers to the linker's output.-        -- otherwise, we use it as the name for the pipeline's output.-        output-         | not (backendGeneratesCode (backend dflags)), notStopPreprocess = NoOutputFile-                -- avoid -E -fno-code undesirable interactions. see #20439-         | NoStop <- stop_phase, not (isNoLink ghc_link) = Persistent-                -- -o foo applies to linker-         | isJust mb_o_file = SpecificFile-                -- -o foo applies to the file we are compiling now-         | otherwise = Persistent-        pipe_env = mkPipeEnv stop_phase src mb_phase output-        pipeline = pipelineStart pipe_env (setDumpPrefix pipe_env hsc_env) src mb_phase+   exists <- doesFileExist offset_file+   when (not exists) $+        throwGhcExceptionIO (CmdLineError ("does not exist: " ++ offset_file))    runPipeline (hsc_hooks hsc_env) pipeline  
GHC/Driver/Pipeline/Execute.hs view
@@ -121,8 +121,8 @@         (hsc_dflags hsc_env)         (hsc_unit_env hsc_env)         (CppOpts-          { useHsCpp       = False-          , cppLinePragmas = True+          { sourceCodePreprocessor  = SCPCmmCpp+          , cppLinePragmas          = True           })         input_fn output_fn   return output_fn@@ -652,8 +652,8 @@            (hsc_dflags hsc_env)            (hsc_unit_env hsc_env)            (CppOpts-              { useHsCpp       = True-              , cppLinePragmas = True+              { sourceCodePreprocessor  = SCPHsCpp+              , cppLinePragmas          = True               })            input_fn output_fn   return output_fn@@ -964,7 +964,11 @@          attrs :: String         attrs = intercalate "," $ mattr-              ++ ["+sse42"   | isSse4_2Enabled dflags   ]+              ++ ["+sse4.2"  | isSse4_2Enabled dflags   ]+              ++ ["+popcnt"  | isSse4_2Enabled dflags   ]+                   -- LLVM gates POPCNT instructions behind the popcnt flag,+                   -- while the GHC NCG (as well as GCC, Clang) gates it+                   -- behind SSE4.2 instead.               ++ ["+sse2"    | isSse2Enabled platform   ]               ++ ["+sse"     | isSseEnabled platform    ]               ++ ["+avx512f" | isAvx512fEnabled dflags  ]
GHC/Driver/Plugins.hs view
@@ -420,12 +420,12 @@ loadExternalPluginLib path = do   -- load library   loadDLL path >>= \case-    Just errmsg -> pprPanic "loadExternalPluginLib"-                    (vcat [ text "Can't load plugin library"-                          , text "  Library path: " <> text path-                          , text "  Error       : " <> text errmsg-                          ])-    Nothing -> do+    Left errmsg -> pprPanic "loadExternalPluginLib"+                     (vcat [ text "Can't load plugin library"+                           , text "  Library path: " <> text path+                           , text "  Error       : " <> text errmsg+                           ])+    Right _ -> do       -- resolve objects       resolveObjs >>= \case         True -> return ()
GHC/Driver/Session.hs view
@@ -112,6 +112,10 @@         sOpt_L,         sOpt_P,         sOpt_P_fingerprint,+        sOpt_JSP,+        sOpt_JSP_fingerprint,+        sOpt_CmmP,+        sOpt_CmmP_fingerprint,         sOpt_F,         sOpt_c,         sOpt_cxx,@@ -134,11 +138,11 @@         ghcUsagePath, ghciUsagePath, topDir,         versionedAppDir, versionedFilePath,         extraGccViaCFlags, globalPackageDatabasePath,-        pgm_L, pgm_P, pgm_F, pgm_c, pgm_cxx, pgm_cpp, pgm_a, pgm_l, pgm_lm,-        pgm_windres, pgm_ar,+        pgm_L, pgm_P, pgm_JSP, pgm_CmmP, pgm_F, pgm_c, pgm_cxx, pgm_cpp, pgm_a, pgm_l,+        pgm_lm, pgm_windres, pgm_ar,         pgm_ranlib, pgm_lo, pgm_lc, pgm_las, pgm_i,-        opt_L, opt_P, opt_F, opt_c, opt_cxx, opt_a, opt_l, opt_lm, opt_i,-        opt_P_signature,+        opt_L, opt_P, opt_JSP, opt_CmmP, opt_F, opt_c, opt_cxx, opt_a, opt_l, opt_lm, opt_i,+        opt_P_signature, opt_JSP_signature, opt_CmmP_signature,         opt_windres, opt_lo, opt_lc, opt_las,         updatePlatformConstants, @@ -390,6 +394,10 @@ pgm_L dflags = toolSettings_pgm_L $ toolSettings dflags pgm_P                 :: DynFlags -> (String,[Option]) pgm_P dflags = toolSettings_pgm_P $ toolSettings dflags+pgm_JSP               :: DynFlags -> (String,[Option])+pgm_JSP dflags = toolSettings_pgm_JSP $ toolSettings dflags+pgm_CmmP              :: DynFlags -> (String,[Option])+pgm_CmmP dflags = toolSettings_pgm_CmmP $ toolSettings dflags pgm_F                 :: DynFlags -> String pgm_F dflags = toolSettings_pgm_F $ toolSettings dflags pgm_c                 :: DynFlags -> String@@ -423,6 +431,11 @@ opt_P                 :: DynFlags -> [String] opt_P dflags = concatMap (wayOptP (targetPlatform dflags)) (ways dflags)             ++ toolSettings_opt_P (toolSettings dflags)+opt_JSP               :: DynFlags -> [String]+opt_JSP dflags = concatMap (wayOptP (targetPlatform dflags)) (ways dflags)+            ++ toolSettings_opt_JSP (toolSettings dflags)+opt_CmmP              :: DynFlags -> [String]+opt_CmmP dflags = toolSettings_opt_CmmP $ toolSettings dflags  -- This function packages everything that's needed to fingerprint opt_P -- flags. See Note [Repeated -optP hashing].@@ -431,6 +444,17 @@   ( concatMap (wayOptP (targetPlatform dflags)) (ways dflags)   , toolSettings_opt_P_fingerprint $ toolSettings dflags   )+-- This function packages everything that's needed to fingerprint opt_P+-- flags. See Note [Repeated -optP hashing].+opt_JSP_signature     :: DynFlags -> ([String], Fingerprint)+opt_JSP_signature dflags =+  ( concatMap (wayOptP (targetPlatform dflags)) (ways dflags)+  , toolSettings_opt_JSP_fingerprint $ toolSettings dflags+  )+-- This function packages everything that's needed to fingerprint opt_CmmP+-- flags. See Note [Repeated -optP hashing].+opt_CmmP_signature     :: DynFlags -> Fingerprint+opt_CmmP_signature = toolSettings_opt_CmmP_fingerprint . toolSettings  opt_F                 :: DynFlags -> [String] opt_F dflags= toolSettings_opt_F $ toolSettings dflags@@ -579,7 +603,8 @@          setDynObjectSuf, setDynHiSuf,          setDylibInstallName,          setObjectSuf, setHiSuf, setHieSuf, setHcSuf, parseDynLibLoaderMode,-         setPgmP, addOptl, addOptc, addOptcxx, addOptP,+         setPgmP, setPgmJSP, setPgmCmmP, addOptl, addOptc, addOptcxx, addOptP,+         addOptJSP, addOptCmmP,          addCmdlineFramework, addHaddockOpts, addGhciScript,          setInteractivePrint    :: String -> DynFlags -> DynFlags@@ -669,6 +694,14 @@ -- Config.hs should really use Option. setPgmP   f = alterToolSettings (\s -> s { toolSettings_pgm_P   = (pgm, map Option args)})   where (pgm:args) = words f+-- XXX HACK: Prelude> words "'does not' work" ===> ["'does","not'","work"]+-- Config.hs should really use Option.+setPgmJSP   f = alterToolSettings (\s -> s { toolSettings_pgm_JSP   = (pgm, map Option args)})+  where (pgm:args) = words f+-- XXX HACK: Prelude> words "'does not' work" ===> ["'does","not'","work"]+-- Config.hs should really use Option.+setPgmCmmP f = alterToolSettings (\s -> s { toolSettings_pgm_CmmP = (pgm, map Option args)})+  where (pgm:args) = words f addOptl   f = alterToolSettings (\s -> s { toolSettings_opt_l   = f : toolSettings_opt_l s}) addOptc   f = alterToolSettings (\s -> s { toolSettings_opt_c   = f : toolSettings_opt_c s}) addOptcxx f = alterToolSettings (\s -> s { toolSettings_opt_cxx = f : toolSettings_opt_cxx s})@@ -677,9 +710,15 @@           , toolSettings_opt_P_fingerprint = fingerprintStrings (f : toolSettings_opt_P s)           }           -- See Note [Repeated -optP hashing]-  where-  fingerprintStrings ss = fingerprintFingerprints $ map fingerprintString ss-+addOptJSP f = alterToolSettings $ \s -> s+          { toolSettings_opt_JSP   = f : toolSettings_opt_JSP s+          , toolSettings_opt_JSP_fingerprint = fingerprintStrings (f : toolSettings_opt_JSP s)+          }+          -- See Note [Repeated -optP hashing]+addOptCmmP f = alterToolSettings $ \s -> s+          { toolSettings_opt_CmmP = f : toolSettings_opt_CmmP s+          , toolSettings_opt_CmmP_fingerprint = fingerprintStrings (f : toolSettings_opt_CmmP s)+          }  setDepMakefile :: FilePath -> DynFlags -> DynFlags setDepMakefile f d = d { depMakefile = f }@@ -1070,6 +1109,10 @@       $ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_L   = f }   , make_ord_flag defFlag "pgmP"       (hasArg setPgmP)+  , make_ord_flag defFlag "pgmJSP"+      (hasArg setPgmJSP)+  , make_ord_flag defFlag "pgmCmmP"+      (hasArg setPgmCmmP)   , make_ord_flag defFlag "pgmF"       $ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_F   = f }   , make_ord_flag defFlag "pgmc"@@ -1124,6 +1167,10 @@       $ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_opt_L   = f : toolSettings_opt_L s }   , make_ord_flag defFlag "optP"       (hasArg addOptP)+  , make_ord_flag defFlag "optJSP"+      (hasArg addOptJSP)+  , make_ord_flag defFlag "optCmmP"+      (hasArg addOptCmmP)   , make_ord_flag defFlag "optF"       $ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_opt_F   = f : toolSettings_opt_F s }   , make_ord_flag defFlag "optc"@@ -2485,6 +2532,8 @@   flagSpec "num-constant-folding"             Opt_NumConstantFolding,   flagSpec "core-constant-folding"            Opt_CoreConstantFolding,   flagSpec "fast-pap-calls"                   Opt_FastPAPCalls,+  flagSpec "spec-eval"                        Opt_SpecEval,+  flagSpec "spec-eval-dictfun"                Opt_SpecEvalDictFun,   flagSpec "cmm-control-flow"                 Opt_CmmControlFlow,   flagSpec "show-warning-groups"              Opt_ShowWarnGroups,   flagSpec "hide-source-paths"                Opt_HideSourcePaths,
GHC/Hs/Type.hs view
@@ -38,6 +38,7 @@         HsWildCardBndrs(..),         HsPatSigType(..), HsPSRn(..),         HsTyPat(..), HsTyPatRn(..),+        HsTyPatRnBuilder(..), tpBuilderExplicitTV, tpBuilderPatSig, buildHsTyPatRn, builderFromHsTyPatRn,         HsSigType(..), LHsSigType, LHsSigWcType, LHsWcType,         HsTupleSort(..),         HsContext, LHsContext, fromMaybeContext,@@ -128,6 +129,7 @@ import Data.Data (Data)  import qualified Data.Semigroup as S+import GHC.Data.Bag  {- ************************************************************************@@ -244,6 +246,51 @@   , hstp_exp_tvs :: [Name] -- ^ Explicitly bound variable names   }   deriving Data++-- | A variant of HsTyPatRn that uses Bags for efficient concatenation.+-- See Note [Implicit and explicit type variable binders]  in GHC.Rename.Pat+data HsTyPatRnBuilder =+  HsTPRnB {+    hstpb_nwcs :: Bag Name,+    hstpb_imp_tvs :: Bag Name,+    hstpb_exp_tvs :: Bag Name+  }++tpBuilderExplicitTV :: Name -> HsTyPatRnBuilder+tpBuilderExplicitTV name = mempty {hstpb_exp_tvs = unitBag name}++tpBuilderPatSig :: HsPSRn -> HsTyPatRnBuilder+tpBuilderPatSig HsPSRn {hsps_nwcs, hsps_imp_tvs} =+  mempty {+    hstpb_nwcs = listToBag hsps_nwcs,+    hstpb_imp_tvs = listToBag hsps_imp_tvs+  }++instance Semigroup HsTyPatRnBuilder where+  HsTPRnB nwcs1 imp_tvs1 exptvs1 <> HsTPRnB nwcs2 imp_tvs2 exptvs2 =+    HsTPRnB+      (nwcs1    `unionBags` nwcs2)+      (imp_tvs1 `unionBags` imp_tvs2)+      (exptvs1  `unionBags` exptvs2)++instance Monoid HsTyPatRnBuilder where+  mempty = HsTPRnB emptyBag emptyBag emptyBag++buildHsTyPatRn :: HsTyPatRnBuilder -> HsTyPatRn+buildHsTyPatRn HsTPRnB {hstpb_nwcs, hstpb_imp_tvs, hstpb_exp_tvs} =+  HsTPRn {+    hstp_nwcs =    bagToList hstpb_nwcs,+    hstp_imp_tvs = bagToList hstpb_imp_tvs,+    hstp_exp_tvs = bagToList hstpb_exp_tvs+  }++builderFromHsTyPatRn :: HsTyPatRn -> HsTyPatRnBuilder+builderFromHsTyPatRn HsTPRn{hstp_nwcs, hstp_imp_tvs, hstp_exp_tvs} =+  HsTPRnB {+    hstpb_nwcs =    listToBag hstp_nwcs,+    hstpb_imp_tvs = listToBag hstp_imp_tvs,+    hstpb_exp_tvs = listToBag hstp_exp_tvs+  }  type instance XXHsPatSigType (GhcPass _) = DataConCantHappen type instance XXHsTyPat      (GhcPass _) = DataConCantHappen
GHC/Iface/Env.hs view
@@ -270,9 +270,9 @@                  | (occ,uniq) <- occs `zip` uniqs] }  trace_if :: Logger -> SDoc -> IO ()-{-# INLINE trace_if #-}+{-# INLINE trace_if #-} -- see Note [INLINE conditional tracing utilities] trace_if logger doc = when (logHasDumpFlag logger Opt_D_dump_if_trace) $ putMsg logger doc  trace_hi_diffs :: Logger -> SDoc -> IO ()-{-# INLINE trace_hi_diffs #-}+{-# INLINE trace_hi_diffs #-} -- see Note [INLINE conditional tracing utilities] trace_hi_diffs logger doc = when (logHasDumpFlag logger Opt_D_dump_hi_diffs) $ putMsg logger doc
GHC/Iface/Errors/Ppr.hs view
@@ -7,7 +7,7 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} -- instance Diagnostic TcRnMessage+{-# OPTIONS_GHC -fno-warn-orphans #-} -- instance Diagnostic IfaceMessage {-# LANGUAGE InstanceSigs #-}  module GHC.Iface.Errors.Ppr
GHC/Iface/Load.hs view
@@ -443,9 +443,6 @@         ; case lookupIfaceByModule hug (eps_PIT eps) mod of {             Just iface                 -> return (Succeeded iface) ;   -- Already loaded-                        -- The (src_imp == mi_boot iface) test checks that the already-loaded-                        -- interface isn't a boot iface.  This can conceivably happen,-                        -- if an earlier import had a before we got to real imports.   I think.             _ -> do {          -- READ THE MODULE IN
GHC/Iface/Recomp/Flags.hs view
@@ -50,13 +50,26 @@         -- see Note [Implicit include paths]         includePathsMinusImplicit = includePaths { includePathsQuoteImplicit = [] } -        -- -I, -D and -U flags affect CPP+        -- -I, -D and -U flags affect Haskell C/CPP Preprocessor         cpp = ( map normalise $ flattenIncludes includePathsMinusImplicit             -- normalise: eliminate spurious differences due to "./foo" vs "foo"               , picPOpts dflags               , opt_P_signature dflags)             -- See Note [Repeated -optP hashing] +        -- -I, -D and -U flags affect JavaScript C/CPP Preprocessor+        js = ( map normalise $ flattenIncludes includePathsMinusImplicit+            -- normalise: eliminate spurious differences due to "./foo" vs "foo"+              , picPOpts dflags+              , opt_JSP_signature dflags)+            -- See Note [Repeated -optP hashing]++        -- -I, -D and -U flags affect C-- CPP Preprocessor+        cmm = ( map normalise $ flattenIncludes includePathsMinusImplicit+            -- normalise: eliminate spurious differences due to "./foo" vs "foo"+              , picPOpts dflags+              , opt_CmmP_signature dflags)+         -- Note [path flags and recompilation]         paths = [ hcSuf ] @@ -70,7 +83,10 @@         -- Other flags which affect code generation         codegen = map (`gopt` dflags) (EnumSet.toList codeGenFlags) -        flags = ((mainis, safeHs, lang, cpp), (paths, prof, ticky, codegen, debugLevel, callerCcFilters))+        -- Did we include core for all bindings?+        fat_iface = gopt Opt_WriteIfSimplifiedCore dflags++        flags = ((mainis, safeHs, lang, cpp, js, cmm), (paths, prof, ticky, codegen, debugLevel, callerCcFilters, fat_iface))      in -- pprTrace "flags" (ppr flags) $        computeFingerprint nameio flags
GHC/Iface/Syntax.hs view
@@ -85,7 +85,7 @@ import GHC.Utils.Lexeme (isLexSym) import GHC.Utils.Fingerprint import GHC.Utils.Binary-import GHC.Utils.Binary.Typeable ()+import GHC.Utils.Binary.Typeable () -- instance Binary AnnPayload import GHC.Utils.Outputable as Outputable import GHC.Utils.Panic import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith,
GHC/Iface/Tidy.hs view
@@ -645,8 +645,11 @@  getTyConImplicitBinds :: TyCon -> [CoreBind] getTyConImplicitBinds tc-  | isNewTyCon tc = []  -- See Note [Compulsory newtype unfolding] in GHC.Types.Id.Make-  | otherwise     = map get_defn (mapMaybe dataConWrapId_maybe (tyConDataCons tc))+  | isDataTyCon tc = map get_defn (mapMaybe dataConWrapId_maybe (tyConDataCons tc))+  | otherwise      = []+    -- The 'otherwise' includes family TyCons of course, but also (less obviously)+    --  * Newtypes: see Note [Compulsory newtype unfolding] in GHC.Types.Id.Make+    --  * type data: we don't want any code for type-only stuff (#24620)  getClassImplicitBinds :: Class -> [CoreBind] getClassImplicitBinds cls
GHC/Iface/Type.hs view
@@ -1132,7 +1132,7 @@        -> IfaceType     go subs True (IfaceForAllTy (Bndr (IfaceTvBndr (var, var_kind)) argf) ty)      | isInvisibleForAllTyFlag argf  -- Don't default *visible* quantification-                                -- or we get the mess in #13963+                                     -- or we get the mess in #13963      , Just substituted_ty <- check_substitution var_kind       = let subs' = extendFsEnv subs var substituted_ty             -- Record that we should replace it with LiftedRep/Lifted/Many,
GHC/Iface/Type.hs-boot view
@@ -6,7 +6,7 @@ where  -- Empty import to influence the compilation ordering.--- See Note [Depend on GHC.Num.Integer] in GHC.Base+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base import GHC.Base ()  data IfaceAppArgs
GHC/Linker/Loader.hs view
@@ -55,6 +55,7 @@ import GHC.Runtime.Interpreter import GHCi.RemoteTypes import GHC.Iface.Load+import GHCi.Message (LoadedDLL)  import GHC.ByteCode.Linker import GHC.ByteCode.Asm@@ -172,7 +173,7 @@   --   -- The linker's symbol table is populated with RTS symbols using an   -- explicit list.  See rts/Linker.c for details.-  where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId [] [] emptyUniqDSet)+  where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId [] [] [] emptyUniqDSet)  extendLoadedEnv :: Interp -> [(Name,ForeignHValue)] -> IO () extendLoadedEnv interp new_bindings =@@ -221,8 +222,8 @@   -> SrcSpan   -> [Module]   -> IO (LoaderState, SuccessFlag, [Linkable], PkgsLoaded) -- ^ returns the set of linkables required+-- When called, the loader state must have been initialized (see `initLoaderState`) loadDependencies interp hsc_env pls span needed_mods = do---   initLoaderState (hsc_dflags hsc_env) dl    let opts = initLinkDepsOpts hsc_env     -- Find what packages and linkables are required@@ -512,25 +513,25 @@     DLL dll_unadorned -> do       maybe_errstr <- loadDLL interp (platformSOName platform dll_unadorned)       case maybe_errstr of-         Nothing -> maybePutStrLn logger "done"-         Just mm | platformOS platform /= OSDarwin ->+         Right _ -> maybePutStrLn logger "done"+         Left mm | platformOS platform /= OSDarwin ->            preloadFailed mm lib_paths lib_spec-         Just mm | otherwise -> do+         Left mm | otherwise -> do            -- As a backup, on Darwin, try to also load a .so file            -- since (apparently) some things install that way - see            -- ticket #8770.            let libfile = ("lib" ++ dll_unadorned) <.> "so"            err2 <- loadDLL interp libfile            case err2 of-             Nothing -> maybePutStrLn logger "done"-             Just _  -> preloadFailed mm lib_paths lib_spec+             Right _ -> maybePutStrLn logger "done"+             Left _  -> preloadFailed mm lib_paths lib_spec       return pls      DLLPath dll_path -> do       do maybe_errstr <- loadDLL interp dll_path          case maybe_errstr of-            Nothing -> maybePutStrLn logger "done"-            Just mm -> preloadFailed mm lib_paths lib_spec+            Right _ -> maybePutStrLn logger "done"+            Left mm -> preloadFailed mm lib_paths lib_spec          return pls      Framework framework ->@@ -614,7 +615,7 @@         -- Load the necessary packages and linkables         let le = linker_env pls             bco_ix = mkNameEnv [(unlinkedBCOName root_ul_bco, 0)]-        resolved <- linkBCO interp le bco_ix root_ul_bco+        resolved <- linkBCO interp (pkgs_loaded pls) le bco_ix root_ul_bco         [root_hvref] <- createBCOs interp [resolved]         fhv <- mkFinalizedHValue interp root_hvref         return (pls, fhv)@@ -677,7 +678,7 @@                        , addr_env = plusNameEnv (addr_env le) bc_strs }            -- Link the necessary packages and linkables-          new_bindings <- linkSomeBCOs interp le2 [cbc]+          new_bindings <- linkSomeBCOs interp (pkgs_loaded pls) le2 [cbc]           nms_fhvs <- makeForeignNamedHValueRefs interp new_bindings           let ce2  = extendClosureEnv (closure_env le2) nms_fhvs               !pls2 = pls { linker_env = le2 { closure_env = ce2 } }@@ -858,8 +859,8 @@     changeTempFilesLifetime tmpfs TFL_GhcSession [soFile]     m <- loadDLL interp soFile     case m of-        Nothing -> return $! pls { temp_sos = (libPath, libName) : temp_sos }-        Just err -> linkFail msg err+      Right _ -> return $! pls { temp_sos = (libPath, libName) : temp_sos }+      Left err -> linkFail msg err   where     msg = "GHC.Linker.Loader.dynLoadObjs: Loading temp shared object failed" @@ -899,7 +900,7 @@             ae2 = foldr plusNameEnv (addr_env le1) (map bc_strs cbcs)             le2 = le1 { itbl_env = ie2, addr_env = ae2 } -        names_and_refs <- linkSomeBCOs interp le2 cbcs+        names_and_refs <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs          -- We only want to add the external ones to the ClosureEnv         let (to_add, to_drop) = partition (isExternalName.fst) names_and_refs@@ -914,6 +915,7 @@  -- Link a bunch of BCOs and return references to their values linkSomeBCOs :: Interp+             -> PkgsLoaded              -> LinkerEnv              -> [CompiledByteCode]              -> IO [(Name,HValueRef)]@@ -921,7 +923,7 @@                         -- the incoming unlinked BCOs.  Each gives the                         -- value of the corresponding unlinked BCO -linkSomeBCOs interp le mods = foldr fun do_link mods []+linkSomeBCOs interp pkgs_loaded le mods = foldr fun do_link mods []  where   fun CompiledByteCode{..} inner accum = inner (bc_bcos : accum) @@ -930,7 +932,7 @@     let flat = [ bco | bcos <- mods, bco <- bcos ]         names = map unlinkedBCOName flat         bco_ix = mkNameEnv (zip names [0..])-    resolved <- sequence [ linkBCO interp le bco_ix bco | bco <- flat ]+    resolved <- sequence [ linkBCO interp pkgs_loaded le bco_ix bco | bco <- flat ]     hvrefs <- createBCOs interp resolved     return (zip names hvrefs) @@ -1092,18 +1094,18 @@                -- Link dependents first              ; pkgs' <- link pkgs deps                 -- Now link the package itself-             ; (hs_cls, extra_cls) <- loadPackage interp hsc_env pkg_cfg+             ; (hs_cls, extra_cls, loaded_dlls) <- loadPackage interp hsc_env pkg_cfg              ; let trans_deps = unionManyUniqDSets [ addOneToUniqDSet (loaded_pkg_trans_deps loaded_pkg_info) dep_pkg                                                    | dep_pkg <- deps                                                    , Just loaded_pkg_info <- pure (lookupUDFM pkgs' dep_pkg)                                                    ]-             ; return (addToUDFM pkgs' new_pkg (LoadedPkgInfo new_pkg hs_cls extra_cls trans_deps)) }+             ; return (addToUDFM pkgs' new_pkg (LoadedPkgInfo new_pkg hs_cls extra_cls loaded_dlls trans_deps)) }          | otherwise         = throwGhcExceptionIO (CmdLineError ("unknown package: " ++ unpackFS (unitIdFS new_pkg)))  -loadPackage :: Interp -> HscEnv -> UnitInfo -> IO ([LibrarySpec], [LibrarySpec])+loadPackage :: Interp -> HscEnv -> UnitInfo -> IO ([LibrarySpec], [LibrarySpec], [RemotePtr LoadedDLL]) loadPackage interp hsc_env pkg    = do         let dflags    = hsc_dflags hsc_env@@ -1145,7 +1147,9 @@         let classifieds = hs_classifieds ++ extra_classifieds          -- Complication: all the .so's must be loaded before any of the .o's.-        let known_dlls = [ dll  | DLLPath dll    <- classifieds ]+        let known_hs_dlls    = [ dll | DLLPath dll <- hs_classifieds ]+            known_extra_dlls = [ dll | DLLPath dll <- extra_classifieds ]+            known_dlls       = known_hs_dlls ++ known_extra_dlls #if defined(CAN_LOAD_DLL)             dlls       = [ dll  | DLL dll        <- classifieds ] #endif@@ -1166,10 +1170,13 @@         loadFrameworks interp platform pkg         -- See Note [Crash early load_dyn and locateLib]         -- Crash early if can't load any of `known_dlls`-        mapM_ (load_dyn interp hsc_env True) known_dlls+        mapM_ (load_dyn interp hsc_env True) known_extra_dlls+        loaded_dlls <- mapMaybeM (load_dyn interp hsc_env True) known_hs_dlls         -- For remaining `dlls` crash early only when there is surely         -- no package's DLL around ... (not is_dyn)         mapM_ (load_dyn interp hsc_env (not is_dyn) . platformSOName platform) dlls+#else+        let loaded_dlls = [] #endif         -- After loading all the DLLs, we can load the static objects.         -- Ordering isn't important here, because we do one final link@@ -1189,7 +1196,7 @@         if succeeded ok            then do              maybePutStrLn logger "done."-             return (hs_classifieds, extra_classifieds)+             return (hs_classifieds, extra_classifieds, loaded_dlls)            else let errmsg = text "unable to load unit `"                              <> pprUnitInfoForUser pkg <> text "'"                  in throwGhcExceptionIO (InstallationError (showSDoc dflags errmsg))@@ -1242,19 +1249,20 @@ -- can be passed directly to loadDLL.  They are either fully-qualified -- ("/usr/lib/libfoo.so"), or unqualified ("libfoo.so").  In the latter case, -- loadDLL is going to search the system paths to find the library.-load_dyn :: Interp -> HscEnv -> Bool -> FilePath -> IO ()+load_dyn :: Interp -> HscEnv -> Bool -> FilePath -> IO (Maybe (RemotePtr LoadedDLL)) load_dyn interp hsc_env crash_early dll = do   r <- loadDLL interp dll   case r of-    Nothing  -> return ()-    Just err ->+    Right loaded_dll -> pure (Just loaded_dll)+    Left err ->       if crash_early         then cmdLineErrorIO err-        else+        else do           when (diag_wopt Opt_WarnMissedExtraSharedLib diag_opts)             $ logMsg logger                 (mkMCDiagnostic diag_opts (WarningWithFlag Opt_WarnMissedExtraSharedLib) Nothing)                   noSrcSpan $ withPprStyle defaultUserStyle (note err)+          pure Nothing   where     diag_opts = initDiagOpts (hsc_dflags hsc_env)     logger = hsc_logger hsc_env
GHC/Linker/MacOS.hs view
@@ -172,6 +172,6 @@      findLoadDLL (p:ps) errs =        do { dll <- loadDLL interp (p </> fwk_file)           ; case dll of-              Nothing  -> return Nothing-              Just err -> findLoadDLL ps ((p ++ ": " ++ err):errs)+              Right _  -> return Nothing+              Left err -> findLoadDLL ps ((p ++ ": " ++ err):errs)           }
GHC/Linker/Types.hs view
@@ -40,7 +40,8 @@ import GHC.Unit                ( UnitId, Module ) import GHC.ByteCode.Types      ( ItblEnv, AddrEnv, CompiledByteCode ) import GHC.Fingerprint.Type    ( Fingerprint )-import GHCi.RemoteTypes        ( ForeignHValue )+import GHCi.RemoteTypes        ( ForeignHValue, RemotePtr )+import GHCi.Message            ( LoadedDLL )  import GHC.Types.Var           ( Id ) import GHC.Types.Name.Env      ( NameEnv, emptyNameEnv, extendNameEnvList, filterNameEnv )@@ -75,6 +76,53 @@  The LinkerEnv maps Names to actual closures (for interpreted code only), for use during linking.++Note [Looking up symbols in the relevant objects]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In #23415, we determined that a lot of time (>10s, or even up to >35s!) was+being spent on dynamically loading symbols before actually interpreting code+when `:main` was run in GHCi. The root cause was that for each symbol we wanted+to lookup, we would traverse the list of loaded objects and try find the symbol+in each of them with dlsym (i.e. looking up a symbol was, worst case, linear in+the amount of loaded objects).++To drastically improve load time (from +-38 seconds down to +-2s), we now:++1. For every of the native objects loaded for a given unit, store the handles returned by `dlopen`.+  - In `pkgs_loaded` of the `LoaderState`, which maps `UnitId`s to+    `LoadedPkgInfo`s, where the handles live in its field `loaded_pkg_hs_dlls`.++2. When looking up a Name (e.g. `lookupHsSymbol`), find that name's `UnitId` in+    the `pkgs_loaded` mapping,++3. And only look for the symbol (with `dlsym`) on the /handles relevant to that+    unit/, rather than in every loaded object.++Note [Symbols may not be found in pkgs_loaded]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Currently the `pkgs_loaded` mapping only contains the dynamic objects+associated with loaded units. Symbols defined in a static object (e.g. from a+statically-linked Haskell library) are found via the generic `lookupSymbol`+function call by `lookupHsSymbol` when the symbol is not found in any of the+dynamic objects of `pkgs_loaded`.++The rationale here is two-fold:++ * we have only observed major link-time issues in dynamic linking; lookups in+ the RTS linker's static symbol table seem to be fast enough++ * allowing symbol lookups restricted to a single ObjectCode would require the+ maintenance of a symbol table per `ObjectCode`, which would introduce time and+ space overhead++This fallback is further needed because we don't look in the haskell objects+loaded for the home units (see the call to `loadModuleLinkables` in+`loadDependencies`, as opposed to the call to `loadPackages'` in the same+function which updates `pkgs_loaded`). We should ultimately keep track of the+objects loaded (probably in `objs_loaded`, for which `LinkableSet` is a bit+unsatisfactory, see a suggestion in 51c5c4eb1f2a33e4dc88e6a37b7b7c135234ce9b)+and be able to lookup symbols specifically in them too (similarly to+`lookupSymbolInDLL`). -}  newtype Loader = Loader { loader_state :: MVar (Maybe LoaderState) }@@ -146,11 +194,13 @@   { loaded_pkg_uid         :: !UnitId   , loaded_pkg_hs_objs     :: ![LibrarySpec]   , loaded_pkg_non_hs_objs :: ![LibrarySpec]+  , loaded_pkg_hs_dlls     :: ![RemotePtr LoadedDLL]+    -- ^ See Note [Looking up symbols in the relevant objects]   , loaded_pkg_trans_deps  :: UniqDSet UnitId   }  instance Outputable LoadedPkgInfo where-  ppr (LoadedPkgInfo uid hs_objs non_hs_objs trans_deps) =+  ppr (LoadedPkgInfo uid hs_objs non_hs_objs _ trans_deps) =     vcat [ppr uid          , ppr hs_objs          , ppr non_hs_objs@@ -159,10 +209,10 @@  -- | Information we can use to dynamically link modules into the compiler data Linkable = LM {-  linkableTime     :: !UTCTime,          -- ^ Time at which this linkable was built+  linkableTime     :: !UTCTime,         -- ^ Time at which this linkable was built                                         -- (i.e. when the bytecodes were produced,                                         --       or the mod date on the files)-  linkableModule   :: !Module,           -- ^ The linkable module itself+  linkableModule   :: !Module,          -- ^ The linkable module itself   linkableUnlinked :: [Unlinked]     -- ^ Those files and chunks of code we have yet to link.     --
GHC/Parser/HaddockLex.hs view
@@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-missing-signatures #-} {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-}-{-# LINE 1 "_build/source-dist/ghc-9.10.1-src/ghc-9.10.1/compiler/GHC/Parser/HaddockLex.x" #-}+{-# LINE 1 "_build/source-dist/ghc-9.10.2-src/ghc-9.10.2/compiler/GHC/Parser/HaddockLex.x" #-} {-# OPTIONS_GHC -funbox-strict-fields #-}  module GHC.Parser.HaddockLex (lexHsDoc, lexStringLiteral) where@@ -352,7 +352,7 @@         -- match when checking the right context, just         -- the first match will do. #endif-{-# LINE 84 "_build/source-dist/ghc-9.10.1-src/ghc-9.10.1/compiler/GHC/Parser/HaddockLex.x" #-}+{-# LINE 84 "_build/source-dist/ghc-9.10.2-src/ghc-9.10.2/compiler/GHC/Parser/HaddockLex.x" #-} data AlexInput = AlexInput   { alexInput_position     :: !RealSrcLoc   , alexInput_string       :: !ByteString
GHC/Parser/Lexer.hs view
@@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-missing-signatures #-} {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-}-{-# LINE 43 "_build/source-dist/ghc-9.10.1-src/ghc-9.10.1/compiler/GHC/Parser/Lexer.x" #-}+{-# LINE 43 "_build/source-dist/ghc-9.10.2-src/ghc-9.10.2/compiler/GHC/Parser/Lexer.x" #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-}@@ -1215,7 +1215,7 @@         -- match when checking the right context, just         -- the first match will do. #endif-{-# LINE 793 "_build/source-dist/ghc-9.10.1-src/ghc-9.10.1/compiler/GHC/Parser/Lexer.x" #-}+{-# LINE 793 "_build/source-dist/ghc-9.10.2-src/ghc-9.10.2/compiler/GHC/Parser/Lexer.x" #-} -- Operator whitespace occurrence. See Note [Whitespace-sensitive operator parsing]. data OpWs   = OpWsPrefix         -- a !b
GHC/Parser/PostProcess.hs view
@@ -139,7 +139,6 @@ import GHC.Parser.Types import GHC.Parser.Lexer import GHC.Parser.Errors.Types-import GHC.Parser.Errors.Ppr () import GHC.Utils.Lexeme ( okConOcc ) import GHC.Types.TyThing import GHC.Core.Type    ( Specificity(..) )
GHC/Platform.hs view
@@ -79,7 +79,7 @@    , platformTablesNextToCode         :: !Bool       -- ^ Determines whether we will be compiling info tables that reside just       --   before the entry code, or with an indirection to the entry code. See-      --   TABLES_NEXT_TO_CODE in rts/include/rts/storage/InfoTables.h.+      --   TABLES_NEXT_TO_CODE in @rts/include/rts/storage/InfoTables.h@.    , platformHasLibm                  :: !Bool       -- ^ Some platforms require that we explicitly link against @libm@ if any       -- math-y things are used (which we assume to include all programs). See
GHC/Rename/Env.hs view
@@ -1031,8 +1031,32 @@  -- lookupOccRnConstr looks up an occurrence of a RdrName and displays -- constructors and pattern synonyms as suggestions if it is not in scope+--+-- There is a fallback to the type level, when the first lookup fails.+-- This is required to implement a pat-to-type transformation+-- (See Note [Pattern to type (P2T) conversion] in GHC.Tc.Gen.Pat)+-- Consider this example:+--+--   data VisProxy a where VP :: forall a -> VisProxy a+--+--   f :: VisProxy Int -> ()+--   f (VP Int) = ()+--+-- Here `Int` is actually a type, but it stays on position where+-- we expect a data constructor.+--+-- In all other cases we just use this additional lookup for better+-- error messaging (See Note [Promotion]). lookupOccRnConstr :: RdrName -> RnM Name-lookupOccRnConstr = lookupOccRn' WL_Constructor+lookupOccRnConstr rdr_name+  = do { mb_gre <- lookupOccRn_maybe rdr_name+       ; case mb_gre of+           Just gre  -> return $ greName gre+           Nothing   -> do+            { mb_ty_gre <- lookup_promoted rdr_name+            ; case mb_ty_gre of+              Just gre -> return $ greName gre+              Nothing ->  reportUnboundName' WL_Constructor rdr_name} }  -- lookupOccRnRecField looks up an occurrence of a RdrName and displays -- record fields as suggestions if it is not in scope
GHC/Rename/Module.hs view
@@ -1972,6 +1972,8 @@      is never used (invariant (I1)), so it barely makes sense to talk about      the worker. A `type data` constructor only shows up in types, where it      appears as a TyCon, specifically a PromotedDataCon -- no Id in sight.+     See #24620 for an example of what happens if you accidentally include+     a wrapper.       See `wrapped_reqd` in GHC.Types.Id.Make.mkDataConRep` for the place where      this check is implemented.
GHC/Rename/Pat.hs view
@@ -71,7 +71,6 @@ import GHC.Utils.Misc import GHC.Data.FastString ( uniqCompareFS ) import GHC.Data.List.SetOps( removeDups )-import GHC.Data.Bag ( Bag, unitBag, unionBags, emptyBag, listToBag, bagToList ) import GHC.Utils.Outputable import GHC.Utils.Panic.Plain import GHC.Types.SrcLoc@@ -89,7 +88,6 @@ import qualified Data.List.NonEmpty as NE import Data.Maybe import Data.Ratio-import qualified Data.Semigroup as S import Control.Monad.Trans.Writer.CPS import Control.Monad.Trans.Class import Control.Monad.Trans.Reader@@ -1242,43 +1240,6 @@   name <- lookupTypeOccRn rdr_name   pure (name, unitFV name) --- | A variant of HsTyPatRn that uses Bags for efficient concatenation.--- See Note [Implicit and explicit type variable binders]-data HsTyPatRnBuilder =-  HsTPRnB {-    hstpb_nwcs :: Bag Name,-    hstpb_imp_tvs :: Bag Name,-    hstpb_exp_tvs :: Bag Name-  }--tpb_exp_tv :: Name -> HsTyPatRnBuilder-tpb_exp_tv name = mempty {hstpb_exp_tvs = unitBag name}--tpb_hsps :: HsPSRn -> HsTyPatRnBuilder-tpb_hsps HsPSRn {hsps_nwcs, hsps_imp_tvs} =-  mempty {-    hstpb_nwcs = listToBag hsps_nwcs,-    hstpb_imp_tvs = listToBag hsps_imp_tvs-  }--instance Semigroup HsTyPatRnBuilder where-  HsTPRnB nwcs1 imp_tvs1 exptvs1 <> HsTPRnB nwcs2 imp_tvs2 exptvs2 =-    HsTPRnB-      (nwcs1    `unionBags` nwcs2)-      (imp_tvs1 `unionBags` imp_tvs2)-      (exptvs1  `unionBags` exptvs2)--instance Monoid HsTyPatRnBuilder where-  mempty = HsTPRnB emptyBag emptyBag emptyBag--buildHsTyPatRn :: HsTyPatRnBuilder -> HsTyPatRn-buildHsTyPatRn HsTPRnB {hstpb_nwcs, hstpb_imp_tvs, hstpb_exp_tvs} =-  HsTPRn {-    hstp_nwcs =    bagToList hstpb_nwcs,-    hstp_imp_tvs = bagToList hstpb_imp_tvs,-    hstp_exp_tvs = bagToList hstpb_exp_tvs-  }- rn_lty_pat :: LHsType GhcPs -> TPRnM (LHsType GhcRn) rn_lty_pat (L l hs_ty) = do   hs_ty' <- rn_ty_pat hs_ty@@ -1292,7 +1253,7 @@      then do -- binder       name <- liftTPRnCps $ newPatName (LamMk True) lrdr-      tellTPB (tpb_exp_tv name)+      tellTPB (tpBuilderExplicitTV name)       pure (L l name)      else do -- usage@@ -1413,7 +1374,7 @@   ~(HsPS hsps ki') <- liftRnWithCont $                       rnHsPatSigKind AlwaysBind ctxt (HsPS noAnn ki)   ty' <- rn_lty_pat ty-  tellTPB (tpb_hsps hsps)+  tellTPB (tpBuilderPatSig hsps)   pure (HsKindSig an ty' ki')  rn_ty_pat (HsSpliceTy _ splice) = do
GHC/Runtime/Eval.hs view
@@ -107,7 +107,7 @@ import GHC.Types.Unique.Supply import GHC.Types.Unique.DSet import GHC.Types.TyThing-import GHC.Types.BreakInfo+import GHC.Types.Breakpoint import GHC.Types.Unique.Map  import GHC.Unit@@ -143,29 +143,27 @@ getResumeContext :: GhcMonad m => m [Resume] getResumeContext = withSession (return . ic_resume . hsc_IC) -mkHistory :: HscEnv -> ForeignHValue -> BreakInfo -> History-mkHistory hsc_env hval bi = History hval bi (findEnclosingDecls hsc_env bi)+mkHistory :: HscEnv -> ForeignHValue -> InternalBreakpointId -> History+mkHistory hsc_env hval ibi = History hval ibi (findEnclosingDecls hsc_env ibi)  getHistoryModule :: History -> Module-getHistoryModule = breakInfo_module . historyBreakInfo+getHistoryModule = ibi_tick_mod . historyBreakpointId  getHistorySpan :: HscEnv -> History -> SrcSpan-getHistorySpan hsc_env History{..} =-  let BreakInfo{..} = historyBreakInfo in-  case lookupHugByModule breakInfo_module (hsc_HUG hsc_env) of-    Just hmi -> modBreaks_locs (getModBreaks hmi) ! breakInfo_number+getHistorySpan hsc_env hist =+  let ibi = historyBreakpointId hist in+  case lookupHugByModule (ibi_tick_mod ibi) (hsc_HUG hsc_env) of+    Just hmi -> modBreaks_locs (getModBreaks hmi) ! ibi_tick_index ibi     _ -> panic "getHistorySpan"  {- | Finds the enclosing top level function name -} -- ToDo: a better way to do this would be to keep hold of the decl_path computed -- by the coverage pass, which gives the list of lexically-enclosing bindings -- for each tick.-findEnclosingDecls :: HscEnv -> BreakInfo -> [String]-findEnclosingDecls hsc_env (BreakInfo modl ix) =-   let hmi = expectJust "findEnclosingDecls" $-             lookupHugByModule modl (hsc_HUG hsc_env)-       mb = getModBreaks hmi-   in modBreaks_decls mb ! ix+findEnclosingDecls :: HscEnv -> InternalBreakpointId -> [String]+findEnclosingDecls hsc_env ibi =+   let hmi = expectJust "findEnclosingDecls" $ lookupHugByModule (ibi_tick_mod ibi) (hsc_HUG hsc_env)+   in modBreaks_decls (getModBreaks hmi) ! ibi_tick_index ibi  -- | Update fixity environment in the current interactive context. updateFixityEnv :: GhcMonad m => FixityEnv -> m ()@@ -324,27 +322,24 @@   | otherwise              = not_tracing  where   tracing-    | EvalBreak apStack_ref maybe_break resume_ctxt _ccs <- status-    , Just (EvalBreakpoint ix mod_name) <- maybe_break+    | EvalBreak apStack_ref (Just eval_break) resume_ctxt _ccs <- status     = do        hsc_env <- getSession        let interp = hscInterp hsc_env        let dflags = hsc_dflags hsc_env-       let hmi = expectJust "handleRunStatus" $-                 lookupHpt (hsc_HPT hsc_env) (mkModuleName mod_name)-           modl = mi_module (hm_iface hmi)+       let ibi = evalBreakpointToId (hsc_HPT hsc_env) eval_break+       let hmi = expectJust "handleRunStatus" $ lookupHpt (hsc_HPT hsc_env) (moduleName (ibi_tick_mod ibi))            breaks = getModBreaks hmi         b <- liftIO $-              breakpointStatus interp (modBreaks_flags breaks) ix+              breakpointStatus interp (modBreaks_flags breaks) (ibi_tick_index ibi)        if b          then not_tracing            -- This breakpoint is explicitly enabled; we want to stop            -- instead of just logging it.          else do            apStack_fhv <- liftIO $ mkFinalizedHValue interp apStack_ref-           let bi = BreakInfo modl ix-               !history' = mkHistory hsc_env apStack_fhv bi `consBL` history+           let !history' = mkHistory hsc_env apStack_fhv ibi `consBL` history                  -- history is strict, otherwise our BoundedList is pointless.            fhv <- liftIO $ mkFinalizedHValue interp resume_ctxt            let eval_opts = initEvalOpts dflags True@@ -362,23 +357,27 @@          let interp = hscInterp hsc_env          resume_ctxt_fhv <- liftIO $ mkFinalizedHValue interp resume_ctxt          apStack_fhv <- liftIO $ mkFinalizedHValue interp apStack_ref-         let bp = evalBreakInfo (hsc_HPT hsc_env) <$> maybe_break+         let ibi = evalBreakpointToId (hsc_HPT hsc_env) <$> maybe_break          (hsc_env1, names, span, decl) <- liftIO $-           bindLocalsAtBreakpoint hsc_env apStack_fhv bp+           bindLocalsAtBreakpoint hsc_env apStack_fhv ibi          let            resume = Resume-             { resumeStmt = expr, resumeContext = resume_ctxt_fhv-             , resumeBindings = bindings, resumeFinalIds = final_ids+             { resumeStmt = expr+             , resumeContext = resume_ctxt_fhv+             , resumeBindings = bindings+             , resumeFinalIds = final_ids              , resumeApStack = apStack_fhv-             , resumeBreakInfo = bp-             , resumeSpan = span, resumeHistory = toListBL history+             , resumeBreakpointId = ibi+             , resumeSpan = span+             , resumeHistory = toListBL history              , resumeDecl = decl              , resumeCCS = ccs-             , resumeHistoryIx = 0 }+             , resumeHistoryIx = 0+             }            hsc_env2 = pushResume hsc_env1 resume           setSession hsc_env2-         return (ExecBreak names bp)+         return (ExecBreak names ibi)      -- Completed successfully     | EvalComplete allocs (EvalSuccess hvals) <- status@@ -428,16 +427,21 @@         liftIO $ Loader.deleteFromLoadedEnv interp new_names          case r of-          Resume { resumeStmt = expr, resumeContext = fhv-                 , resumeBindings = bindings, resumeFinalIds = final_ids-                 , resumeApStack = apStack, resumeBreakInfo = mb_brkpt+          Resume { resumeStmt = expr+                 , resumeContext = fhv+                 , resumeBindings = bindings+                 , resumeFinalIds = final_ids+                 , resumeApStack = apStack+                 , resumeBreakpointId = mb_brkpt                  , resumeSpan = span                  , resumeHistory = hist } ->                withVirtualCWD $ do-                when (isJust mb_brkpt && isJust mbCnt) $ do-                  setupBreakpoint hsc_env (fromJust mb_brkpt) (fromJust mbCnt)-                    -- When the user specified a break ignore count, set it-                    -- in the interpreter+                -- When the user specified a break ignore count, set it+                -- in the interpreter+                case (mb_brkpt, mbCnt) of+                  (Just brkpt, Just cnt) -> setupBreakpoint hsc_env (toBreakpointId brkpt) cnt+                  _ -> return ()+                 let eval_opts = initEvalOpts dflags (isStep step)                 status <- liftIO $ GHCi.resumeStmt interp eval_opts fhv                 let prevHistoryLst = fromListBL 50 hist@@ -449,16 +453,15 @@                                                         fromListBL 50 hist                 handleRunStatus step expr bindings final_ids status hist' -setupBreakpoint :: GhcMonad m => HscEnv -> BreakInfo -> Int -> m ()   -- #19157-setupBreakpoint hsc_env brkInfo cnt = do-  let modl :: Module = breakInfo_module brkInfo+setupBreakpoint :: GhcMonad m => HscEnv -> BreakpointId -> Int -> m ()   -- #19157+setupBreakpoint hsc_env bi cnt = do+  let modl = bi_tick_mod bi       breaks hsc_env modl = getModBreaks $ expectJust "setupBreakpoint" $          lookupHpt (hsc_HPT hsc_env) (moduleName modl)-      ix = breakInfo_number brkInfo       modBreaks  = breaks hsc_env modl       breakarray = modBreaks_flags modBreaks       interp = hscInterp hsc_env-  _ <- liftIO $ GHCi.storeBreakpoint interp breakarray ix cnt+  _ <- liftIO $ GHCi.storeBreakpoint interp breakarray (bi_tick_index bi) cnt   pure ()  back :: GhcMonad m => Int -> m ([Name], Int, SrcSpan, String)@@ -501,11 +504,11 @@         if new_ix == 0            then case r of                    Resume { resumeApStack = apStack,-                            resumeBreakInfo = mb_brkpt } ->+                            resumeBreakpointId = mb_brkpt } ->                           update_ic apStack mb_brkpt            else case history !! (new_ix - 1) of                    History{..} ->-                     update_ic historyApStack (Just historyBreakInfo)+                     update_ic historyApStack (Just historyBreakpointId)   -- -----------------------------------------------------------------------------@@ -517,7 +520,7 @@ bindLocalsAtBreakpoint         :: HscEnv         -> ForeignHValue-        -> Maybe BreakInfo+        -> Maybe InternalBreakpointId         -> IO (HscEnv, [Name], SrcSpan, String)  -- Nothing case: we stopped when an exception was raised, not at a@@ -543,25 +546,28 @@  -- Just case: we stopped at a breakpoint, we have information about the location -- of the breakpoint and the free variables of the expression.-bindLocalsAtBreakpoint hsc_env apStack_fhv (Just BreakInfo{..}) = do+bindLocalsAtBreakpoint hsc_env apStack_fhv (Just ibi) = do    let-       hmi       = expectJust "bindLocalsAtBreakpoint" $-                     lookupHpt (hsc_HPT hsc_env) (moduleName breakInfo_module)        interp    = hscInterp hsc_env-       breaks    = getModBreaks hmi-       info      = expectJust "bindLocalsAtBreakpoint2" $-                     IntMap.lookup breakInfo_number (modBreaks_breakInfo breaks)-       occs      = modBreaks_vars breaks ! breakInfo_number-       span      = modBreaks_locs breaks ! breakInfo_number-       decl      = intercalate "." $ modBreaks_decls breaks ! breakInfo_number +       info_mod  = ibi_info_mod ibi+       info_hmi  = expectJust "bindLocalsAtBreakpoint" $ lookupHpt (hsc_HPT hsc_env) (moduleName info_mod)+       info_brks = getModBreaks info_hmi+       info      = expectJust "bindLocalsAtBreakpoint2" $ IntMap.lookup (ibi_info_index ibi) (modBreaks_breakInfo info_brks)++       tick_mod  = ibi_tick_mod ibi+       tick_hmi  = expectJust "bindLocalsAtBreakpoint" $ lookupHpt (hsc_HPT hsc_env) (moduleName tick_mod)+       tick_brks = getModBreaks tick_hmi+       occs      = modBreaks_vars tick_brks ! ibi_tick_index ibi+       span      = modBreaks_locs tick_brks ! ibi_tick_index ibi+       decl      = intercalate "." $ modBreaks_decls tick_brks ! ibi_tick_index ibi+   -- Rehydrate to understand the breakpoint info relative to the current environment.   -- This design is critical to preventing leaks (#22530)    (mbVars, result_ty) <- initIfaceLoad hsc_env-                            $ initIfaceLcl breakInfo_module (text "debugger") NotBoot+                            $ initIfaceLcl info_mod (text "debugger") NotBoot                             $ hydrateCgBreakInfo info -    let             -- Filter out any unboxed ids by changing them to Nothings;@@ -614,8 +620,10 @@         -- saved/restored, but not the linker state.  See #1743, test break026.    mkNewId :: OccName -> Type -> Id -> IO Id    mkNewId occ ty old_id-     = do { name <- newInteractiveBinder hsc_env occ (getSrcSpan old_id)-          ; return (Id.mkVanillaGlobalWithInfo name ty (idInfo old_id)) }+     = do { name <- newInteractiveBinder hsc_env (mkVarOccFS (occNameFS occ)) (getSrcSpan old_id)+              -- NB: use variable namespace.+              -- Don't use record field namespaces, lest we cause #25109.+          ; return $ Id.mkVanillaGlobalWithInfo name ty (idInfo old_id) }     newTyVars :: UniqSupply -> [TcTyVar] -> Subst      -- Similarly, clone the type variables mentioned in the types
GHC/Runtime/Eval/Types.hs view
@@ -19,7 +19,7 @@ import GHC.Types.Id import GHC.Types.Name import GHC.Types.TyThing-import GHC.Types.BreakInfo+import GHC.Types.Breakpoint import GHC.Types.Name.Reader import GHC.Types.SrcLoc import GHC.Utils.Exception@@ -50,8 +50,8 @@        , execAllocation :: Word64        }   | ExecBreak-       { breakNames :: [Name]-       , breakInfo :: Maybe BreakInfo+       { breakNames   :: [Name]+       , breakPointId :: Maybe InternalBreakpointId        }  -- | Essentially a GlobalRdrEnv, but with additional cached values to allow@@ -73,11 +73,10 @@        , resumeFinalIds  :: [Id]         -- [Id] to bind on completion        , resumeApStack   :: ForeignHValue -- The object from which we can get                                         -- value of the free variables.-       , resumeBreakInfo :: Maybe BreakInfo-                                        -- the breakpoint we stopped at-                                        -- (module, index)+       , resumeBreakpointId :: Maybe InternalBreakpointId+                                        -- ^ the breakpoint we stopped at                                         -- (Nothing <=> exception)-       , resumeSpan      :: SrcSpan      -- just a copy of the SrcSpan+       , resumeSpan      :: SrcSpan     -- just a copy of the SrcSpan                                         -- from the ModBreaks,                                         -- otherwise it's a pain to                                         -- fetch the ModDetails &@@ -90,9 +89,8 @@  type ResumeBindings = ([TyThing], IcGlobalRdrEnv) -data History-   = History {-        historyApStack   :: ForeignHValue,-        historyBreakInfo :: BreakInfo,-        historyEnclosingDecls :: [String]  -- declarations enclosing the breakpoint-   }+data History = History+  { historyApStack        :: ForeignHValue+  , historyBreakpointId   :: InternalBreakpointId -- ^ breakpoint identifier+  , historyEnclosingDecls :: [String]             -- ^ declarations enclosing the breakpoint+  }
GHC/Runtime/Interpreter.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-}-{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE LambdaCase #-}  -- | Interacting with the iserv interpreter, whether it is running on an@@ -28,13 +27,14 @@   , getClosure   , getModBreaks   , seqHValue-  , evalBreakInfo+  , evalBreakpointToId   , interpreterDynamic   , interpreterProfiled    -- * The object-code linker   , initObjLinker   , lookupSymbol+  , lookupSymbolInDLL   , lookupClosure   , loadDLL   , loadArchive@@ -73,7 +73,7 @@ import GHCi.RemoteTypes import GHCi.ResolvedBCO import GHCi.BreakArray (BreakArray)-import GHC.Types.BreakInfo (BreakInfo(..))+import GHC.Types.Breakpoint import GHC.ByteCode.Types  import GHC.Linker.Types@@ -151,22 +151,22 @@   - implementation of Template Haskell (GHCi.TH)   - a few other things needed to run interpreted code -- top-level iserv directory, containing the codefor the external-  server.  This is a fairly simple wrapper, most of the functionality+- top-level iserv directory, containing the code for the external+  server. This is a fairly simple wrapper, most of the functionality   is provided by modules in libraries/ghci.  - This module which provides the interface to the server used   by the rest of GHC. -GHC works with and without -fexternal-interpreter.  With the flag, all-interpreted code is run by the iserv binary.  Without the flag,+GHC works with and without -fexternal-interpreter. With the flag, all+interpreted code is run by the iserv binary. Without the flag, interpreted code is run in the same process as GHC.  Things that do not work with -fexternal-interpreter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  dynCompileExpr cannot work, because we have no way to run code of an-unknown type in the remote process.  This API fails with an error+unknown type in the remote process. This API fails with an error message if it is used with -fexternal-interpreter.  Other Notes on Remote GHCi@@ -394,14 +394,15 @@     status <- interpCmd interp (Seq hval)     handleSeqHValueStatus interp unit_env status -evalBreakInfo :: HomePackageTable -> EvalBreakpoint -> BreakInfo-evalBreakInfo hpt (EvalBreakpoint ix mod_name) =-  BreakInfo modl ix-  where-    modl = mi_module $-           hm_iface $-           expectJust "evalBreakInfo" $-           lookupHpt hpt (mkModuleName mod_name)+evalBreakpointToId :: HomePackageTable -> EvalBreakpoint -> InternalBreakpointId+evalBreakpointToId hpt eval_break =+  let load_mod x = mi_module $ hm_iface $ expectJust "evalBreakpointToId" $ lookupHpt hpt (mkModuleName x)+  in InternalBreakpointId+        { ibi_tick_mod   = load_mod (eb_tick_mod eval_break)+        , ibi_tick_index = eb_tick_index eval_break+        , ibi_info_mod   = load_mod (eb_info_mod eval_break)+        , ibi_info_index = eb_info_index eval_break+        }  -- | Process the result of a Seq or ResumeSeq message.             #2950 handleSeqHValueStatus :: Interp -> UnitEnv -> EvalStatus () -> IO (EvalResult ())@@ -411,7 +412,7 @@       -- A breakpoint was hit; inform the user and tell them       -- which breakpoint was hit.       resume_ctxt_fhv <- liftIO $ mkFinalizedHValue interp resume_ctxt-      let bp = evalBreakInfo (ue_hpt unit_env) <$> maybe_break+      let bp = evalBreakpointToId (ue_hpt unit_env) <$> maybe_break           sdocBpLoc = brackets . ppr . getSeqBpSpan       putStrLn ("*** Ignoring breakpoint " ++             (showSDocUnsafe $ sdocBpLoc bp))@@ -421,14 +422,15 @@         handleSeqHValueStatus interp unit_env status     (EvalComplete _ r) -> return r   where-    getSeqBpSpan :: Maybe BreakInfo -> SrcSpan-    -- Just case: Stopped at a breakpoint, extract SrcSpan information-    -- from the breakpoint.-    getSeqBpSpan (Just BreakInfo{..}) =-      (modBreaks_locs (breaks breakInfo_module)) ! breakInfo_number-    -- Nothing case - should not occur!-    -- Reason: Setting of flags in libraries/ghci/GHCi/Run.hs:evalOptsSeq-    getSeqBpSpan Nothing = mkGeneralSrcSpan (fsLit "<unknown>")+    getSeqBpSpan :: Maybe InternalBreakpointId -> SrcSpan+    getSeqBpSpan = \case+      Just bi -> (modBreaks_locs (breaks (ibi_tick_mod bi))) ! ibi_tick_index bi+        -- Just case: Stopped at a breakpoint, extract SrcSpan information+        -- from the breakpoint.+      Nothing -> mkGeneralSrcSpan (fsLit "<unknown>")+        -- Nothing case - should not occur!+        -- Reason: Setting of flags in libraries/ghci/GHCi/Run.hs:evalOptsSeq+        --     breaks mod = getModBreaks $ expectJust "getSeqBpSpan" $       lookupHpt (ue_hpt unit_env) (moduleName mod) @@ -440,57 +442,78 @@ initObjLinker interp = interpCmd interp InitLinker  lookupSymbol :: Interp -> FastString -> IO (Maybe (Ptr ()))-lookupSymbol interp str = case interpInstance interp of+lookupSymbol interp str = withSymbolCache interp str $+  case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER)-  InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str))+    InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbol (unpackFS str)) #endif--  ExternalInterp ext -> case ext of-    ExtIServ i -> withIServ i $ \inst -> do-      -- Profiling of GHCi showed a lot of time and allocation spent-      -- making cross-process LookupSymbol calls, so I added a GHC-side-      -- cache which sped things up quite a lot.  We have to be careful-      -- to purge this cache when unloading code though.-      cache <- readMVar (instLookupSymbolCache inst)-      case lookupUFM cache str of-        Just p -> return (Just p)-        Nothing -> do-          m <- uninterruptibleMask_ $-                   sendMessage inst (LookupSymbol (unpackFS str))-          case m of-            Nothing -> return Nothing-            Just r -> do-              let p        = fromRemotePtr r-                  cache'   = addToUFM cache str p-              modifyMVar_ (instLookupSymbolCache inst) (const (pure cache'))-              return (Just p)+    ExternalInterp ext -> case ext of+      ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do+        uninterruptibleMask_ $+          sendMessage inst (LookupSymbol (unpackFS str))+      ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str) -    ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str)+lookupSymbolInDLL :: Interp -> RemotePtr LoadedDLL -> FastString -> IO (Maybe (Ptr ()))+lookupSymbolInDLL interp dll str = withSymbolCache interp str $+  case interpInstance interp of+#if defined(HAVE_INTERNAL_INTERPRETER)+    InternalInterp -> fmap fromRemotePtr <$> run (LookupSymbolInDLL dll (unpackFS str))+#endif+    ExternalInterp ext -> case ext of+      ExtIServ i -> withIServ i $ \inst -> fmap fromRemotePtr <$> do+        uninterruptibleMask_ $+          sendMessage inst (LookupSymbolInDLL dll (unpackFS str))+      ExtJS {} -> pprPanic "lookupSymbol not supported by the JS interpreter" (ppr str)  lookupClosure :: Interp -> String -> IO (Maybe HValueRef) lookupClosure interp str =   interpCmd interp (LookupClosure str) +-- | 'withSymbolCache' tries to find a symbol in the 'interpLookupSymbolCache'+-- which maps symbols to the address where they are loaded.+-- When there's a cache hit we simply return the cached address, when there is+-- a miss we run the action which determines the symbol's address and populate+-- the cache with the answer.+withSymbolCache :: Interp+                -> FastString+                -- ^ The symbol we are looking up in the cache+                -> IO (Maybe (Ptr ()))+                -- ^ An action which determines the address of the symbol we+                -- are looking up in the cache, which is run if there is a+                -- cache miss. The result will be cached.+                -> IO (Maybe (Ptr ()))+withSymbolCache interp str determine_addr = do++  -- Profiling of GHCi showed a lot of time and allocation spent+  -- making cross-process LookupSymbol calls, so I added a GHC-side+  -- cache which sped things up quite a lot. We have to be careful+  -- to purge this cache when unloading code though.+  --+  -- The analysis in #23415 further showed this cache should also benefit the+  -- internal interpreter's loading times, and needn't be used by the external+  -- interpreter only.+  cache <- readMVar (interpLookupSymbolCache interp)+  case lookupUFM cache str of+    Just p -> return (Just p)+    Nothing -> do++      maddr <- determine_addr+      case maddr of+        Nothing -> return Nothing+        Just p -> do+          let upd_cache cache' = addToUFM cache' str p+          modifyMVar_ (interpLookupSymbolCache interp) (pure . upd_cache)+          return (Just p)+ purgeLookupSymbolCache :: Interp -> IO ()-purgeLookupSymbolCache interp = case interpInstance interp of-#if defined(HAVE_INTERNAL_INTERPRETER)-  InternalInterp -> pure ()-#endif-  ExternalInterp ext -> withExtInterpMaybe ext $ \case-    Nothing   -> pure () -- interpreter stopped, nothing to do-    Just inst -> modifyMVar_ (instLookupSymbolCache inst) (const (pure emptyUFM))+purgeLookupSymbolCache interp = modifyMVar_ (interpLookupSymbolCache interp) (const (pure emptyUFM))  -- | loadDLL loads a dynamic library using the OS's native linker -- (i.e. dlopen() on Unix, LoadLibrary() on Windows).  It takes either -- an absolute pathname to the file, or a relative filename -- (e.g. "libfoo.so" or "foo.dll").  In the latter case, loadDLL -- searches the standard locations for the appropriate library.------ Returns:------ Nothing      => success--- Just err_msg => failure-loadDLL :: Interp -> String -> IO (Maybe String)+loadDLL :: Interp -> String -> IO (Either String (RemotePtr LoadedDLL)) loadDLL interp str = interpCmd interp (LoadDLL str)  loadArchive :: Interp -> String -> IO ()@@ -549,11 +572,9 @@                   }    pending_frees <- newMVar []-  lookup_cache  <- newMVar emptyUFM   let inst = ExtInterpInstance         { instProcess           = process         , instPendingFrees      = pending_frees-        , instLookupSymbolCache = lookup_cache         , instExtra             = ()         }   pure inst
GHC/Runtime/Interpreter/JS.hs view
@@ -41,7 +41,6 @@ import GHC.Utils.Error (logInfo) import GHC.Utils.Outputable (text) import GHC.Data.FastString-import GHC.Types.Unique.FM  import Control.Concurrent import Control.Monad@@ -178,11 +177,9 @@         }    pending_frees <- newMVar []-  lookup_cache  <- newMVar emptyUFM   let inst = ExtInterpInstance         { instProcess           = proc         , instPendingFrees      = pending_frees-        , instLookupSymbolCache = lookup_cache         , instExtra             = extra         } 
GHC/Runtime/Interpreter/Types.hs view
@@ -51,6 +51,9 @@    , interpLoader   :: !Loader       -- ^ Interpreter loader++  , interpLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ())))+      -- ^ LookupSymbol cache   }  data InterpInstance@@ -107,9 +110,6 @@       -- ^ Values that need to be freed before the next command is sent.       -- Finalizers for ForeignRefs can append values to this list       -- asynchronously.--  , instLookupSymbolCache :: !(MVar (UniqFM FastString (Ptr ())))-      -- ^ LookupSymbol cache    , instExtra             :: !c       -- ^ Instance specific extra fields
GHC/Settings.hs view
@@ -26,6 +26,8 @@   , sArSupportsDashL   , sPgm_L   , sPgm_P+  , sPgm_JSP+  , sPgm_CmmP   , sPgm_F   , sPgm_c   , sPgm_cxx@@ -45,6 +47,10 @@   , sOpt_L   , sOpt_P   , sOpt_P_fingerprint+  , sOpt_JSP+  , sOpt_JSP_fingerprint+  , sOpt_CmmP+  , sOpt_CmmP_fingerprint   , sOpt_F   , sOpt_c   , sOpt_cxx@@ -92,11 +98,16 @@   , toolSettings_ccSupportsNoPie         :: Bool   , toolSettings_useInplaceMinGW         :: Bool   , toolSettings_arSupportsDashL         :: Bool+  , toolSettings_cmmCppSupportsG0        :: Bool    -- commands for particular phases   , toolSettings_pgm_L       :: String   , -- | The Haskell C preprocessor and default options (not added by -optP)     toolSettings_pgm_P       :: (String, [Option])+  , -- | The JavaScript C preprocessor and default options (not added by -optP)+    toolSettings_pgm_JSP       :: (String, [Option])+  , -- | The C-- C Preprocessor and default options (not added by -optP)+    toolSettings_pgm_CmmP    :: (String, [Option])   , toolSettings_pgm_F       :: String   , toolSettings_pgm_c       :: String   , toolSettings_pgm_cxx     :: String@@ -124,9 +135,17 @@   -- options for particular phases   , toolSettings_opt_L             :: [String]   , toolSettings_opt_P             :: [String]+  , toolSettings_opt_JSP           :: [String]+  , toolSettings_opt_CmmP          :: [String]   , -- | cached Fingerprint of sOpt_P     -- See Note [Repeated -optP hashing]-    toolSettings_opt_P_fingerprint :: Fingerprint+    toolSettings_opt_P_fingerprint   :: Fingerprint+  , -- | cached Fingerprint of sOpt_JSP+    -- See Note [Repeated -optP hashing]+    toolSettings_opt_JSP_fingerprint :: Fingerprint+  , -- | cached Fingerprint of sOpt_CmmP+    -- See Note [Repeated -optP hashing]+    toolSettings_opt_CmmP_fingerprint :: Fingerprint   , toolSettings_opt_F             :: [String]   , toolSettings_opt_c             :: [String]   , toolSettings_opt_cxx           :: [String]@@ -205,6 +224,10 @@ sPgm_L = toolSettings_pgm_L . sToolSettings sPgm_P :: Settings -> (String, [Option]) sPgm_P = toolSettings_pgm_P . sToolSettings+sPgm_JSP :: Settings -> (String, [Option])+sPgm_JSP = toolSettings_pgm_JSP . sToolSettings+sPgm_CmmP :: Settings -> (String, [Option])+sPgm_CmmP = toolSettings_pgm_CmmP . sToolSettings sPgm_F :: Settings -> String sPgm_F = toolSettings_pgm_F . sToolSettings sPgm_c :: Settings -> String@@ -243,6 +266,14 @@ sOpt_P = toolSettings_opt_P . sToolSettings sOpt_P_fingerprint :: Settings -> Fingerprint sOpt_P_fingerprint = toolSettings_opt_P_fingerprint . sToolSettings+sOpt_JSP :: Settings -> [String]+sOpt_JSP = toolSettings_opt_JSP . sToolSettings+sOpt_JSP_fingerprint :: Settings -> Fingerprint+sOpt_JSP_fingerprint = toolSettings_opt_JSP_fingerprint . sToolSettings+sOpt_CmmP :: Settings -> [String]+sOpt_CmmP = toolSettings_opt_CmmP . sToolSettings+sOpt_CmmP_fingerprint :: Settings -> Fingerprint+sOpt_CmmP_fingerprint = toolSettings_opt_CmmP_fingerprint . sToolSettings sOpt_F :: Settings -> [String] sOpt_F = toolSettings_opt_F . sToolSettings sOpt_c :: Settings -> [String]
GHC/Settings/IO.hs view
@@ -16,9 +16,11 @@ import GHC.Utils.Fingerprint import GHC.Platform import GHC.Utils.Panic+import GHC.ResponseFile import GHC.Settings import GHC.SysTools.BaseDir +import Data.Char import Control.Monad.Trans.Except import Control.Monad.IO.Class import qualified Data.Map as Map@@ -72,29 +74,40 @@   -- just partially applying those functions and throwing 'Left's; they're   -- written in a very portable style to keep ghc-boot light.   let getSetting key = either pgmError pure $-        getRawFilePathSetting top_dir settingsFile mySettings key+        -- Escape the 'top_dir', to make sure we don't accidentally introduce an+        -- unescaped space+        getRawFilePathSetting (escapeArg top_dir) settingsFile mySettings key       getToolSetting :: String -> ExceptT SettingsError m String-      getToolSetting key = expandToolDir useInplaceMinGW mtool_dir <$> getSetting key+        -- Escape the 'mtool_dir', to make sure we don't accidentally introduce+        -- an unescaped space+      getToolSetting key = expandToolDir useInplaceMinGW (fmap escapeArg mtool_dir) <$> getSetting key   targetPlatformString <- getSetting "target platform string"   cc_prog <- getToolSetting "C compiler command"   cxx_prog <- getToolSetting "C++ compiler command"   cc_args_str <- getToolSetting "C compiler flags"   cxx_args_str <- getToolSetting "C++ compiler flags"   gccSupportsNoPie <- getBooleanSetting "C compiler supports -no-pie"+  cmmCppSupportsG0 <- getBooleanSetting "C-- CPP supports -g0"   cpp_prog <- getToolSetting "CPP command"   cpp_args_str <- getToolSetting "CPP flags"   hs_cpp_prog <- getToolSetting "Haskell CPP command"   hs_cpp_args_str <- getToolSetting "Haskell CPP flags"+  js_cpp_prog <- getToolSetting "JavaScript CPP command"+  js_cpp_args_str <- getToolSetting "JavaScript CPP flags"+  cmmCpp_prog <- getToolSetting "C-- CPP command"+  cmmCpp_args_str <- getToolSetting "C-- CPP flags"    platform <- either pgmError pure $ getTargetPlatform settingsFile mySettings    let unreg_cc_args = if platformUnregisterised platform                       then ["-DNO_REGS", "-DUSE_MINIINTERPRETER"]                       else []-      cpp_args    = map Option (words cpp_args_str)-      hs_cpp_args = map Option (words hs_cpp_args_str)-      cc_args  = words cc_args_str ++ unreg_cc_args-      cxx_args = words cxx_args_str+      cpp_args    = map Option (unescapeArgs cpp_args_str)+      hs_cpp_args = map Option (unescapeArgs hs_cpp_args_str)+      js_cpp_args = map Option (unescapeArgs js_cpp_args_str)+      cmmCpp_args = map Option (unescapeArgs cmmCpp_args_str)+      cc_args  = unescapeArgs cc_args_str ++ unreg_cc_args+      cxx_args = unescapeArgs cxx_args_str        -- The extra flags we need to pass gcc when we invoke it to compile .hc code.       --@@ -135,12 +148,12 @@   let   as_prog  = cc_prog         as_args  = map Option cc_args         ld_prog  = cc_prog-        ld_args  = map Option (cc_args ++ words cc_link_args_str)+        ld_args  = map Option (cc_args ++ unescapeArgs cc_link_args_str)   ld_r_prog <- getToolSetting "Merge objects command"   ld_r_args <- getToolSetting "Merge objects flags"   let ld_r         | null ld_r_prog = Nothing-        | otherwise      = Just (ld_r_prog, map Option $ words ld_r_args)+        | otherwise      = Just (ld_r_prog, map Option $ unescapeArgs ld_r_args)    llvmTarget <- getSetting "LLVM target" @@ -177,9 +190,12 @@       , toolSettings_ccSupportsNoPie         = gccSupportsNoPie       , toolSettings_useInplaceMinGW         = useInplaceMinGW       , toolSettings_arSupportsDashL         = arSupportsDashL+      , toolSettings_cmmCppSupportsG0        = cmmCppSupportsG0        , toolSettings_pgm_L   = unlit_path       , toolSettings_pgm_P   = (hs_cpp_prog, hs_cpp_args)+      , toolSettings_pgm_JSP = (js_cpp_prog, js_cpp_args)+      , toolSettings_pgm_CmmP = (cmmCpp_prog, cmmCpp_args)       , toolSettings_pgm_F   = ""       , toolSettings_pgm_c   = cc_prog       , toolSettings_pgm_cxx = cxx_prog@@ -198,7 +214,11 @@       , toolSettings_pgm_i   = iserv_prog       , toolSettings_opt_L       = []       , toolSettings_opt_P       = []-      , toolSettings_opt_P_fingerprint = fingerprint0+      , toolSettings_opt_JSP     = []+      , toolSettings_opt_CmmP    = []+      , toolSettings_opt_P_fingerprint   = fingerprint0+      , toolSettings_opt_JSP_fingerprint = fingerprint0+      , toolSettings_opt_CmmP_fingerprint = fingerprint0       , toolSettings_opt_F       = []       , toolSettings_opt_c       = cc_args       , toolSettings_opt_cxx     = cxx_args@@ -261,3 +281,19 @@     , platformHasLibm = targetHasLibm     , platform_constants = Nothing -- will be filled later when loading (or building) the RTS unit     }++-- ----------------------------------------------------------------------------+-- Escape Args helpers+-- ----------------------------------------------------------------------------++-- | Just like 'GHC.ResponseFile.escapeArg', but it is not exposed from base.+escapeArg :: String -> String+escapeArg = reverse . foldl' escape []++escape :: String -> Char -> String+escape cs c+  |    isSpace c+    || '\\' == c+    || '\'' == c+    || '"'  == c = c:'\\':cs -- n.b., our caller must reverse the result+  | otherwise    = c:cs
GHC/StgToByteCode.hs view
@@ -383,27 +383,40 @@ -- | Introduce break instructions for ticked expressions. -- If no breakpoint information is available, the instruction is omitted. schemeER_wrk :: StackDepth -> BCEnv -> CgStgExpr -> BcM BCInstrList-schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_no fvs mod) rhs) = do+schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_no fvs tick_mod) rhs) = do   code <- schemeE d 0 p rhs   hsc_env <- getHscEnv   current_mod <- getCurrentModule-  current_mod_breaks <- getCurrentModBreaks-  case break_info hsc_env mod current_mod current_mod_breaks of+  mb_current_mod_breaks <- getCurrentModBreaks+  case mb_current_mod_breaks of+    -- if we're not generating ModBreaks for this module for some reason, we+    -- can't store breakpoint occurrence information.     Nothing -> pure code-    Just ModBreaks {modBreaks_flags = breaks, modBreaks_module = mod_ptr, modBreaks_ccs = cc_arr} -> do-      platform <- profilePlatform <$> getProfile-      let idOffSets = getVarOffSets platform d p fvs-          ty_vars   = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs)-          toWord :: Maybe (Id, WordOff) -> Maybe (Id, Word)-          toWord = fmap (\(i, wo) -> (i, fromIntegral wo))-          breakInfo  = dehydrateCgBreakInfo ty_vars (map toWord idOffSets) tick_ty-      newBreakInfo tick_no breakInfo-      let cc | Just interp <- hsc_interp hsc_env-            , interpreterProfiled interp-            = cc_arr ! tick_no-            | otherwise = toRemotePtr nullPtr-          breakInstr = BRK_FUN breaks (fromIntegral tick_no) mod_ptr cc-      return $ breakInstr `consOL` code+    Just current_mod_breaks -> case break_info hsc_env tick_mod current_mod mb_current_mod_breaks of+      Nothing -> pure code+      Just ModBreaks {modBreaks_flags = breaks, modBreaks_module = tick_mod_ptr, modBreaks_ccs = cc_arr} -> do+        platform <- profilePlatform <$> getProfile+        let idOffSets = getVarOffSets platform d p fvs+            ty_vars   = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs)+            toWord :: Maybe (Id, WordOff) -> Maybe (Id, Word)+            toWord = fmap (\(i, wo) -> (i, fromIntegral wo))+            breakInfo  = dehydrateCgBreakInfo ty_vars (map toWord idOffSets) tick_ty++        let info_mod_ptr = modBreaks_module current_mod_breaks+        infox <- newBreakInfo breakInfo++        let cc | Just interp <- hsc_interp hsc_env+              , interpreterProfiled interp+              = cc_arr ! tick_no+              | otherwise = toRemotePtr nullPtr++        let -- cast that checks that round-tripping through Word16 doesn't change the value+            toW16 x = let r = fromIntegral x :: Word16+                      in if fromIntegral r == x+                        then r+                        else pprPanic "schemeER_wrk: breakpoint tick/info index too large!" (ppr x)+            breakInstr = BRK_FUN breaks tick_mod_ptr (toW16 tick_no) info_mod_ptr (toW16 infox) cc+        return $ breakInstr `consOL` code schemeER_wrk d p rhs = schemeE d 0 p rhs  -- | Determine the GHCi-allocated 'BreakArray' and module pointer for the module@@ -515,7 +528,7 @@                         PUSH_BCO tuple_bco `consOL`                         unitOL RETURN_TUPLE     return ( mkSlideB platform szb (d - s) -- clear to sequel-             `consOL` ret)                 -- go+             `appOL` ret)                 -- go  -- construct and return an unboxed tuple returnUnboxedTuple@@ -783,7 +796,7 @@         platform <- profilePlatform <$> getProfile         assert (sz == wordSize platform) return ()         let slide = mkSlideB platform (d - init_d + wordSize platform) (init_d - s)-        return (push_fn `appOL` (slide `consOL` unitOL ENTER))+        return (push_fn `appOL` (slide `appOL` unitOL ENTER))   do_pushes !d args reps = do       let (push_apply, n, rest_of_reps) = findPushSeq reps           (these_args, rest_of_args) = splitAt n args@@ -1405,7 +1418,7 @@               (push_target `consOL`                push_info `consOL`                PUSH_BCO args_bco `consOL`-               (mkSlideB platform szb (d - s) `consOL` unitOL PRIMCALL))+               (mkSlideB platform szb (d - s) `appOL` unitOL PRIMCALL))  -- ----------------------------------------------------------------------------- -- Deal with a CCall.@@ -2150,8 +2163,8 @@   ("Error: bytecode compiler can't handle some foreign calling conventions\n"++    "  Workaround: use -fobject-code, or compile this module to .o separately.")) -mkSlideB :: Platform -> ByteOff -> ByteOff -> BCInstr-mkSlideB platform nb db = SLIDE n d+mkSlideB :: Platform -> ByteOff -> ByteOff -> OrdList BCInstr+mkSlideB platform nb db = mkSlideW n d   where     !n = bytesToWords platform nb     !d = bytesToWords platform db@@ -2188,7 +2201,12 @@         , ffis        :: [FFIInfo]       -- ffi info blocks, to free later                                          -- Should be free()d when it is GCd         , modBreaks   :: Maybe ModBreaks -- info about breakpoints-        , breakInfo   :: IntMap CgBreakInfo++        , breakInfo   :: IntMap CgBreakInfo -- ^ Info at breakpoint occurrence.+                                            -- Indexed with breakpoint *info* index.+                                            -- See Note [Breakpoint identifiers]+                                            -- in GHC.Types.Breakpoint+        , breakInfoIdx :: !Int              -- ^ Next index for breakInfo array         }  newtype BcM r = BcM (BcM_State -> IO (BcM_State, r)) deriving (Functor)@@ -2202,7 +2220,7 @@       -> BcM r       -> IO (BcM_State, r) runBc hsc_env this_mod modBreaks (BcM m)-   = m (BcM_State hsc_env this_mod 0 [] modBreaks IntMap.empty)+   = m (BcM_State hsc_env this_mod 0 [] modBreaks IntMap.empty 0)  thenBc :: BcM a -> (a -> BcM b) -> BcM b thenBc (BcM expr) cont = BcM $ \st0 -> do@@ -2258,9 +2276,14 @@   = BcM $ \st -> let ctr = nextlabel st                  in return (st{nextlabel = ctr+n}, coerce [ctr .. ctr+n-1]) -newBreakInfo :: BreakIndex -> CgBreakInfo -> BcM ()-newBreakInfo ix info = BcM $ \st ->-  return (st{breakInfo = IntMap.insert ix info (breakInfo st)}, ())+newBreakInfo :: CgBreakInfo -> BcM Int+newBreakInfo info = BcM $ \st ->+  let ix = breakInfoIdx st+      st' = st+              { breakInfo = IntMap.insert ix info (breakInfo st)+              , breakInfoIdx = ix + 1+              }+  in return (st', ix)  getCurrentModule :: BcM Module getCurrentModule = BcM $ \st -> return (st, thisModule st)
GHC/StgToCmm/Config.hs view
@@ -70,8 +70,11 @@   , stgToCmmAllowQuotRem2             :: !Bool   -- ^ Allowed to generate QuotRem   , stgToCmmAllowExtendedAddSubInstrs :: !Bool   -- ^ Allowed to generate AddWordC, SubWordC, Add2, etc.   , stgToCmmAllowIntMul2Instr         :: !Bool   -- ^ Allowed to generate IntMul2 instruction+  , stgToCmmAllowWordMul2Instr        :: !Bool   -- ^ Allowed to generate WordMul2 instruction   , stgToCmmAllowFMAInstr             :: FMASign -> Bool -- ^ Allowed to generate FMA instruction   , stgToCmmTickyAP                   :: !Bool   -- ^ Disable use of precomputed standard thunks.+  , stgToCmmSaveFCallTargetToLocal    :: !Bool   -- ^ Save a foreign call target to a Cmm local, see+                                                 -- Note [Saving foreign call target to local] for details   ------------------------------ SIMD flags ------------------------------------   -- Each of these flags checks vector compatibility with the backend requested   -- during compilation. In essence, this means checking for @-fllvm@ which is
GHC/StgToCmm/Foreign.hs view
@@ -277,23 +277,83 @@ load_target_into_temp other_target@(PrimTarget _) =   return other_target +-- Note [Saving foreign call target to local]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- -- What we want to do here is create a new temporary for the foreign -- call argument if it is not safe to use the expression directly, -- because the expression mentions caller-saves GlobalRegs (see -- Note [Register parameter passing]). -- -- However, we can't pattern-match on the expression here, because--- this is used in a loop by GHC.Cmm.Parser, and testing the expression--- results in a black hole.  So we always create a temporary, and rely--- on GHC.Cmm.Sink to clean it up later.  (Yuck, ToDo).  The generated code--- ends up being the same, at least for the RTS .cmm code.+-- this is used in a loop by GHC.Cmm.Parser, and testing the+-- expression results in a black hole.  So when there exist+-- caller-saves GlobalRegs, we create a temporary, and rely on+-- GHC.Cmm.Sink to clean it up later. The generated code ends up being+-- the same if -fcmm-sink is enabled (implied by -O). --+-- When there doesn't exist caller-save GlobalRegs, keep the original+-- target in place. This matters for the wasm backend, otherwise it+-- cannot infer the target symbol's correct foreign function type in+-- unoptimized Cmm. For instance:+--+-- foreign import ccall unsafe "foo" c_foo :: IO ()+--+-- Without optimization, previously this would lower to something like:+--+-- [Test.c_foo_entry() { //  []+--          { []+--          }+--      {offset+--        cDk:+--            goto cDm;+--        cDm:+--            _cDj::I32 = foo;+--            call "ccall" arg hints:  []  result hints:  [] (_cDj::I32)();+--            R1 = GHC.Tuple.()_closure+1;+--            call (I32[P32[Sp]])(R1) args: 4, res: 0, upd: 4;+--      }+--  },+--+-- The wasm backend only sees "foo" being assigned to a local, but+-- there's no type signature associated with a CLabel! So it has to+-- emit a dummy .functype directive and fingers crossed that wasm-ld+-- tolerates function type mismatch. THis is horrible, not future+-- proof against upstream toolchain upgrades, and already known to+-- break in certain cases (e.g. when LTO objects are involved).+--+-- Therefore, on wasm as well as other targets that don't risk+-- mentioning caller-saved GlobalRegs in a foreign call target, just+-- keep the original call target in place and don't assign it to a+-- local. So this would now lower to something like:+--+-- [Test.c_foo_entry() { //  []+--          { []+--          }+--      {offset+--        cDo:+--            goto cDq;+--        cDq:+--            call "ccall" arg hints:  []  result hints:  [] foo();+--            R1 = GHC.Tuple.()_closure+1;+--            call (I32[P32[Sp]])(R1) args: 4, res: 0, upd: 4;+--      }+--  },+--+-- Since "foo" appears at call site directly, the wasm backend would+-- now be able to infer its type signature correctly.+ maybe_assign_temp :: CmmExpr -> FCode CmmExpr maybe_assign_temp e = do-  platform <- getPlatform-  reg <- newTemp (cmmExprType platform e)-  emitAssign (CmmLocal reg) e-  return (CmmReg (CmmLocal reg))+  do_save <- stgToCmmSaveFCallTargetToLocal <$> getStgToCmmConfig+  if do_save+    then do+      platform <- getPlatform+      reg <- newTemp (cmmExprType platform e)+      emitAssign (CmmLocal reg) e+      return (CmmReg (CmmLocal reg))+    else+      pure e  -- ----------------------------------------------------------------------------- -- Save/restore the thread state in the TSO
GHC/StgToCmm/InfoTableProv.hs view
@@ -178,7 +178,7 @@     to_ipe_buf_ent :: CgInfoProvEnt -> [Word32]     to_ipe_buf_ent cg_ipe =       [ ipeTableName cg_ipe-      , ipeClosureDesc cg_ipe+      , fromIntegral $ ipeClosureDesc cg_ipe       , ipeTypeDesc cg_ipe       , ipeLabel cg_ipe       , ipeSrcFile cg_ipe@@ -193,7 +193,6 @@ toCgIPE :: Platform -> SDocContext -> InfoProvEnt -> State StringTable CgInfoProvEnt toCgIPE platform ctx ipe = do     table_name <- lookupStringTable $ ST.pack $ renderWithContext ctx (pprCLabel platform (infoTablePtr ipe))-    closure_desc <- lookupStringTable $ ST.pack $ show (infoProvEntClosureType ipe)     type_desc <- lookupStringTable $ ST.pack $ infoTableType ipe     let label_str = maybe "" ((\(LexicalFastString s) -> unpackFS s) . snd) (infoTableProv ipe)     let (src_loc_file, src_loc_span) =@@ -208,7 +207,7 @@     src_span <- lookupStringTable $ ST.pack src_loc_span     return $ CgInfoProvEnt { ipeInfoTablePtr = infoTablePtr ipe                            , ipeTableName = table_name-                           , ipeClosureDesc = closure_desc+                           , ipeClosureDesc = fromIntegral (infoProvEntClosureType ipe)                            , ipeTypeDesc = type_desc                            , ipeLabel = label                            , ipeSrcFile = src_file@@ -218,7 +217,7 @@ data CgInfoProvEnt = CgInfoProvEnt                                { ipeInfoTablePtr :: !CLabel                                , ipeTableName :: !StrTabOffset-                               , ipeClosureDesc :: !StrTabOffset+                               , ipeClosureDesc :: !Word32                                , ipeTypeDesc :: !StrTabOffset                                , ipeLabel :: !StrTabOffset                                , ipeSrcFile :: !StrTabOffset
GHC/StgToCmm/Prim.hs view
@@ -1623,7 +1623,7 @@     else Right genericIntSubCOp    WordMul2Op -> \args -> opCallishHandledLater args $-    if allowExtAdd+    if allowWord2Mul     then Left (MO_U_Mul2     (wordWidth platform))     else Right genericWordMul2Op @@ -1850,6 +1850,7 @@   allowQuotRem2 = stgToCmmAllowQuotRem2             cfg   allowExtAdd   = stgToCmmAllowExtendedAddSubInstrs cfg   allowInt2Mul  = stgToCmmAllowIntMul2Instr         cfg+  allowWord2Mul = stgToCmmAllowWordMul2Instr        cfg    allowFMA = stgToCmmAllowFMAInstr cfg @@ -2180,8 +2181,8 @@                    -> CmmType  -- ^ index type                    -> AlignmentSpec alignmentFromTypes ty idx_ty-  | typeWidth ty < typeWidth idx_ty = NaturallyAligned-  | otherwise                       = Unaligned+  | typeWidth ty <= typeWidth idx_ty = NaturallyAligned+  | otherwise                        = Unaligned  doIndexOffAddrOp :: Maybe MachOp                  -> CmmType
GHC/StgToJS/Linker/Linker.hs view
@@ -284,10 +284,31 @@                   hPutChar h '\n'                   let emcc_opts' = emcc_opts <> opts                   go_entries emcc_opts' cc_objs es-                Nothing -> do-                  logInfo logger (vcat [text "Ignoring unexpected archive entry: ", text (Ar.filename e)])-                  go_entries emcc_opts cc_objs es+                Nothing -> case Ar.filename e of+                  -- JavaScript code linker does not support symbol table processing.+                  -- Currently the linker does nothing when the symbol table is met.+                  -- Ar/Ranlib usually do not create a record for the symbol table+                  -- in the object archive when the table has no entries.+                  -- For JavaScript code it should not be created by default. +                  "__.SYMDEF" ->+                    -- GNU Ar added the symbol table.++                    -- Emscripten Ar (at least 3.1.24 version)+                    -- adds it even when the symbol table is empty.+                    go_entries emcc_opts cc_objs es+                  "__.SYMDEF SORTED" ->+                    -- BSD-like Ar added the symbol table.++                    -- By default, Clang Ar does not add it when the+                    -- symbol table is empty (and it should be empty) but we left+                    -- it here to handle the case with symbol table completely+                    -- for GNU and BSD tools.+                    go_entries emcc_opts cc_objs es+                  unknown_name -> do+                    logInfo logger (vcat [text "Ignoring unexpected archive entry: ", text unknown_name])+                    go_entries emcc_opts cc_objs es+             -- additional JS objects (e.g. from the command-line)             go_extra emcc_opts = \case               []     -> pure emcc_opts@@ -728,12 +749,64 @@  rtsExterns :: FastString rtsExterns =+  -- Google Closure Compiler --externs option is deprecated.+  -- Need pass them as a js file with @externs module-level jsdoc.+  "/** @externs @suppress {duplicate} */\n" <>   "// GHCJS RTS externs for closure compiler ADVANCED_OPTIMIZATIONS\n\n" <>-  mconcat (map (\x -> "/** @type {*} */\nObject.d" <> mkFastString (show x) <> ";\n")-               [(7::Int)..16384])+  mconcat+    -- See GHC.StgToJS+    -- We connect all payload fields "dXX" on JavaScript Object.+    -- That's most simple way to make Google Closure Compiler prevent+    -- property names mangling.+    (map (\x -> "/** @type {*} */\nObject.d" <> mkFastString (show x) <> ";\n")+    [(1::Int)..16384]) <>+  mconcat+    (map (\x -> "/** @type {*} */\nObject." <> x <> ";\n")+    -- We do same for special STG properties as well.+    ["m", "f", "cc", "t", "size", "i", "n", "a", "r", "s"]) <>+  mconcat+    [ -- Used at h$mkForeignCallback+      "/** @type {*} */\nObject.mv;\n"+    ] <>+  mconcat+    (map (\x -> x <> ";\n")+    [ -- Externs needed by node environment+      "/** @type {string} */ var __dirname"+      -- Copied minimally from https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8+    , "/** @const */ var NodeJS = {}"+      -- NodeJS Stream interface+    , "/** @interface */ NodeJS.Stream = function () {}"+    , "/** @template THIS @this {THIS} @return {THIS} */ NodeJS.Stream.prototype.on = function() {}"+    , "/** @return {boolean} */ NodeJS.Stream.prototype.write = function() {}"+      -- NodeJS versions property contains actual versions of the environment+    , "/** @interface */ NodeJS.ProcessVersions = function() {}"+    , "/** @type {string} */ NodeJS.ProcessVersions.prototype.node"+      -- NodeJS Process interface+    , "/** @interface */ NodeJS.Process = function() {}"+    , "/** @type {!NodeJS.Stream} */ NodeJS.Process.prototype.stderr"+    , "/** @type {!NodeJS.Stream} */ NodeJS.Process.prototype.stdin"+    , "/** @type {!NodeJS.Stream} */ NodeJS.Process.prototype.stdout"+    , "/** @type {!NodeJS.ProcessVersions} */ NodeJS.Process.prototype.versions"+    , "/** @return {?} */ NodeJS.Process.prototype.exit = function() {}"+    , "/** @type {!Array<string>} */ NodeJS.Process.prototype.argv"+      -- NodeJS Process definition+    , "/** @type {!NodeJS.Process} */ var process"+      -- NodeJS Buffer class+    , "/** @extends {Uint8Array} @constructor */ function Buffer(arg1, encoding) {}"+    , "/** @return {!Buffer} */ Buffer.alloc = function() {}"+      -- Emscripten Module+    , "/** @type {*} */ var Module"+      -- Mozilla's Narcissus (JS in JS interpreter implemented on top of SpiderMonkey) environment+    , "/** @type {*} */ var putstr"+    , "/** @type {*} */ var printErr"+      -- Apples's JavaScriptCore environment+    , "/** @type {*} */ var debug"+      -- We use only Heap8 from Emscripten+    , "/** @type {!Int8Array} */ Module.HEAP8"+    ])  writeExterns :: FilePath -> IO ()-writeExterns out = writeFile (out </> "all.js.externs")+writeExterns out = writeFile (out </> "all.externs.js")   $ unpackFS rtsExterns  -- | Get all block dependencies for a given set of roots@@ -1095,8 +1168,9 @@       js_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js"       let         cpp_opts = CppOpts-          { useHsCpp       = False-          , cppLinePragmas = False -- LINE pragmas aren't JS compatible+          { sourceCodePreprocessor  = SCPJsCpp+          -- JS code requires keeping JSDoc comments for third party minification tooling+          , cppLinePragmas          = False -- LINE pragmas aren't JS compatible           }       doCpp logger               tmpfs
GHC/StgToJS/Linker/Utils.hs view
@@ -140,7 +140,7 @@    -- Put Addr# in ByteArray# or at Addr# (same thing)   , "#define PUT_ADDR(a,o,va,vo) if (!(a).arr) (a).arr = []; (a).arr[o] = va; (a).dv.setInt32(o,vo,true);\n"-  , "#define GET_ADDR(a,o,ra,ro) var ra = (((a).arr && (a).arr[o]) ? (a).arr[o] : null_); var ro = (a).dv.getInt32(o,true);\n"+  , "#define GET_ADDR(a,o,ra,ro) var ra = (((a).arr && (a).arr[o]) ? (a).arr[o] : null); var ro = (a).dv.getInt32(o,true);\n"    -- Data.Maybe.Maybe   , "#define HS_NOTHING h$ghczminternalZCGHCziInternalziMaybeziNothing\n"
GHC/StgToJS/Literal.hs view
@@ -115,7 +115,24 @@   LitDouble r              -> return [ DoubleLit . SaneDouble . r2d $ r ]   LitLabel name _size fod  -> return [ LabelLit (fod == IsFunction) (mkRawSymbol True name)                                      , IntLit 0 ]-  l -> pprPanic "genStaticLit" (ppr l)+  LitRubbish _ rep ->+    let prim_reps = runtimeRepPrimRep (text "GHC.StgToJS.Literal.genStaticLit") rep+    in case expectOnly "GHC.StgToJS.Literal.genStaticLit" prim_reps of -- Note [Post-unarisation invariants]+        BoxedRep _  -> pure [ NullLit ]+        AddrRep     -> pure [ NullLit, IntLit 0 ]+        IntRep      -> pure [ IntLit 0 ]+        Int8Rep     -> pure [ IntLit 0 ]+        Int16Rep    -> pure [ IntLit 0 ]+        Int32Rep    -> pure [ IntLit 0 ]+        Int64Rep    -> pure [ IntLit 0, IntLit 0 ]+        WordRep     -> pure [ IntLit 0 ]+        Word8Rep    -> pure [ IntLit 0 ]+        Word16Rep   -> pure [ IntLit 0 ]+        Word32Rep   -> pure [ IntLit 0 ]+        Word64Rep   -> pure [ IntLit 0, IntLit 0 ]+        FloatRep    -> pure [ DoubleLit (SaneDouble 0) ]+        DoubleRep   -> pure [ DoubleLit (SaneDouble 0) ]+        VecRep {}   -> pprPanic "GHC.StgToJS.Literal.genStaticLit: LitRubbish(VecRep) isn't supported" (ppr rep)  -- make an unsigned 32 bit number from this unsigned one, lower 32 bits toU32Expr :: Integer -> JStgExpr
GHC/StgToJS/Prim.hs view
@@ -940,7 +940,7 @@ ------------------------------- Delay/Wait Ops ---------------------------------    DelayOp     -> \[] [t]  -> pure $ PRPrimCall $ returnS (app "h$delayThread" [t])-  WaitReadOp  -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd])+  WaitReadOp  -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waitRead" [fd])   WaitWriteOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waitWrite" [fd])  ------------------------------- Concurrency Primitives -------------------------
GHC/StgToJS/Rts/Rts.hs view
@@ -371,7 +371,8 @@               , global "h$ct_stackframe" ||= toJExpr StackFrame               , global "h$vt_ptr"    ||= toJExpr PtrV               , global "h$vt_void"   ||= toJExpr VoidV-              , global "h$vt_double" ||= toJExpr IntV+              , global "h$vt_int"    ||= toJExpr IntV+              , global "h$vt_double" ||= toJExpr DoubleV               , global "h$vt_long"   ||= toJExpr LongV               , global "h$vt_addr"   ||= toJExpr AddrV               , global "h$vt_obj"    ||= toJExpr ObjV@@ -669,6 +670,10 @@                                        , r1 |= x                                        , returnS (stack .! sp)                                        ])+             , closure (ClosureInfo (global "h$reportHeapOverflow") (CIRegs 0 [PtrV]) "h$reportHeapOverflow" (CILayoutFixed 0 []) CIStackFrame mempty)+                  (return $ (appS "throw" [jString "h$reportHeapOverflow: Heap Overflow!"]))+             , closure (ClosureInfo (global "h$reportStackOverflow") (CIRegs 0 [PtrV]) "h$reportStackOverflow" (CILayoutFixed 0 []) CIStackFrame mempty)+                  (return $ (appS "throw" [jString "h$reportStackOverflow: Stack Overflow!"]))              -- Top-level statements to generate only in profiling mode              , fmap (profStat s) $ (closure (ClosureInfo (global "h$setCcs_e") (CIRegs 0 [PtrV]) "set cost centre stack" (CILayoutFixed 1 [ObjV]) CIStackFrame mempty)                            (return $
GHC/StgToJS/Types.hs view
@@ -26,7 +26,7 @@ import GHC.JS.Ident import qualified GHC.JS.Syntax as Sat import GHC.JS.Make-import GHC.JS.Ppr ()+import GHC.JS.Ppr () -- expose Outputable instances to downstream modules  import GHC.Stg.Syntax import GHC.Core.TyCon
GHC/SysTools/Cpp.hs view
@@ -40,34 +40,70 @@ import System.FilePath  data CppOpts = CppOpts-  { useHsCpp       :: !Bool-  -- ^ Use the Haskell C preprocessor, otherwise use the C preprocessor.-  -- See the Note [Preprocessing invocations]-  , cppLinePragmas :: !Bool+  { sourceCodePreprocessor  :: !SourceCodePreprocessor+  , cppLinePragmas          :: !Bool   -- ^ Enable generation of LINE pragmas   }  {- Note [Preprocessing invocations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We must consider two distinct preprocessors when preprocessing Haskell.+We must consider four distinct preprocessors when preprocessing Haskell. These are:  (1) The Haskell C preprocessor (HsCpp), which preprocesses Haskell files that make use   of the CPP language extension -(2) The C preprocessor (Cpp), which is used to preprocess C and Cmm files+(2) The C preprocessor (Cpp), which is used to preprocess C files +(3) The JavaScript preprocessor (JsCpp), which preprocesses JavaScript files++(4) The C-- preprocessor (CmmCpp), which preprocesses C-- files+ These preprocessors are indeed different. Despite often sharing the same underlying program (the C compiler), the set of flags passed determines the behaviour of the preprocessor, and Cpp and HsCpp behave differently. Specifically, we rely on "traditional" (pre-standard) preprocessing semantics (which most compilers expose via the `-traditional` flag) when preprocessing-Haskell source. This avoids, e.g., the preprocessor removing C-style comments.+Haskell source. This avoids the following situations:++  * Removal of C-style comments, which are not comments in Haskell but valid+    operators;++  * Errors due to an ANSI C preprocessor lexing the source and failing on+    names with single quotes (TH quotes, ticked promoted constructors,+    names with primes in them).++  Both of those cases may be subtle: gcc and clang permit C++-style //+  comments in C code, and Data.Array and Data.Vector both export a //+  operator whose type is such that a removed "comment" may leave code that+  typechecks but does the wrong thing. Another example is that, since ANSI+  C permits long character constants, an expression involving multiple+  functions with primes in their names may not expand macros properly when+  they occur between the primed functions.++Third special type of preprocessor for JavaScript was added laterly due to+needing to keep JSDoc comments and multiline comments. Various third party+minifying software (for example, Google Closure Compiler) uses JSDoc+information to apply more strict rules to code reduction which results in+better but more dangerous minification. JSDoc comments are usually used to+instruct minifiers where dangerous optimizations could be applied.++The fourth, the C-- preprocessor, is needed as modern compilers emit defines+for debug info generation when preprocessing.  The C-- preprocessor avoids this+by suppressing debug info generation.  The C-- preprocessor also inherits flags+passed to the C compiler.  This is done for compatibility.  Following those,+the C-- compiler receives -g0, if it was detected as supported, and flags+passed via -optCmmP specifically for the C-- preprocessor.  The combined+command line looks like:++  $pgmCmmP $optCs_without_g3s $g0_if_supported $optCmmP+ -} --- | Run either the Haskell preprocessor or the C preprocessor, as per the--- 'CppOpts' passed. See Note [Preprocessing invocations].+-- | Run either the Haskell preprocessor, JavaScript preprocessor+-- or the C preprocessor, as per the 'CppOpts' passed.+-- See Note [Preprocessing invocations]. -- -- UnitEnv is needed to compute MIN_VERSION macros doCpp :: Logger -> TmpFs -> DynFlags -> UnitEnv -> CppOpts -> FilePath -> FilePath -> IO ()@@ -95,9 +131,7 @@      let verbFlags = getVerbFlags dflags -    let cpp_prog args-          | useHsCpp opts = GHC.SysTools.runHsCpp logger dflags args-          | otherwise     = GHC.SysTools.runCpp logger tmpfs dflags args+    let cpp_prog args = runSourceCodePreprocessor logger tmpfs dflags (sourceCodePreprocessor opts) args      let platform   = targetPlatform dflags         targetArch = stringEncodeArch $ platformArch platform@@ -225,11 +259,17 @@ -- | Find out path to @ghcversion.h@ file getGhcVersionPathName :: DynFlags -> UnitEnv -> IO FilePath getGhcVersionPathName dflags unit_env = do-  candidates <- case ghcVersionFile dflags of-    Just path -> return [path]-    Nothing -> do-        ps <- mayThrowUnitErr (preloadUnitsInfo' unit_env [rtsUnitId])-        return ((</> "ghcversion.h") <$> collectIncludeDirs ps)+  let candidates = case ghcVersionFile dflags of+        -- the user has provided an explicit `ghcversion.h` file to use.+        Just path -> [path]+        -- otherwise, try to find it in the rts' include-dirs.+        -- Note: only in the RTS include-dirs! not all preload units less we may+        -- use a wrong file. See #25106 where a globally installed+        -- /usr/include/ghcversion.h file was used instead of the one provided+        -- by the rts.+        Nothing -> case lookupUnitId (ue_units unit_env) rtsUnitId of+          Nothing   -> []+          Just info -> (</> "ghcversion.h") <$> collectIncludeDirs [info]    found <- filterM doesFileExist candidates   case found of
GHC/SysTools/Tasks.hs view
@@ -107,32 +107,75 @@    | "warning: call-clobbered register used" `isContainedIn` w = False    | otherwise = True --- | Run the C preprocessor, which is different from running the--- Haskell C preprocessor (they're configured separately!).--- See also Note [Preprocessing invocations] in GHC.SysTools.Cpp-runCpp :: Logger -> TmpFs -> DynFlags -> [Option] -> IO ()-runCpp logger tmpfs dflags args = traceSystoolCommand logger "cpp" $ do-  let (p,args0) = pgm_cpp dflags-      userOpts_c = map Option $ getOpts dflags opt_c-      args2 = args0 ++ args ++ userOpts_c-  mb_env <- getGccEnv args2-  runSomethingResponseFile logger tmpfs (tmpDir dflags) cc_filter "C pre-processor" p-                           args2 mb_env+-- | See the Note [Preprocessing invocations]+data SourceCodePreprocessor+  = SCPCpp+    -- ^ Use the ordinary C preprocessor+  | SCPHsCpp+    -- ^ Use the Haskell C preprocessor (don't remove C comments, don't break on names including single quotes)+  | SCPJsCpp+    -- ^ Use the JavaScript preprocessor (don't remove jsdoc and multiline comments)+  | SCPCmmCpp+    -- ^ Use the C-- preprocessor (don't emit debug information)+  deriving (Eq) --- | Run the Haskell C preprocessor.+-- | Run source code preprocessor. -- See also Note [Preprocessing invocations] in GHC.SysTools.Cpp-runHsCpp :: Logger -> DynFlags -> [Option] -> IO ()-runHsCpp logger dflags args = traceSystoolCommand logger "hs-cpp" $ do-  let (p,args0) = pgm_P dflags-      opts = getOpts dflags opt_P-      modified_imports = augmentImports dflags opts-      args1 = map Option modified_imports+runSourceCodePreprocessor+  :: Logger+  -> TmpFs+  -> DynFlags+  -> SourceCodePreprocessor+  -> [Option]+  -> IO ()+runSourceCodePreprocessor logger tmpfs dflags preprocessor args =+  traceSystoolCommand logger logger_name $ do+    let+      (p, args0) = pgm_getter dflags+      args1 = Option <$> (augmentImports dflags $ getOpts dflags opt_getter)       args2 = [Option "-Werror" | gopt Opt_WarnIsError dflags]                 ++ [Option "-Wundef" | wopt Opt_WarnCPPUndef dflags]-  mb_env <- getGccEnv args2 -- romes: what about args0 and args?-  runSomethingFiltered logger id "Haskell C pre-processor" p-                       (args0 ++ args1 ++ args2 ++ args) Nothing mb_env+      all_args = args0 ++ args1 ++ args2 ++ args +    mb_env <- getGccEnv (args0 ++ args1)++    runSomething readable_name p all_args mb_env++  where+    toolSettings' = toolSettings dflags+    cmmG0 = ["-g0" | toolSettings_cmmCppSupportsG0 toolSettings']+    -- GCC <=10 (pre commit r11-5596-g934a54180541d2) implied -dD for debug+    -- flags by the spec snippet %{g3|ggdb3|gstabs3|gxcoff3|gvms3:-dD}.  This+    -- means that a g0 will not override a previously-specified -g3 causing+    -- debug info emission (see https://gcc.gnu.org/PR97989).  We're filtering+    -- -optc here, rather than the combined command line, in order to avoid an+    -- issue where a user has to, for some reason, override our decision.  If+    -- they see the need to do that, they can pass -optCmmP.+    g3Flags = ["-g3", "-ggdb3", "-gstabs3", "-gxcoff3", "-gvms3"]+    optCFiltered = filter (`notElem` g3Flags) . opt_c+    -- In the wild (and GHC), there is lots of code assuming that -optc gets+    -- passed to the C-- preprocessor too.  Note that the arguments are+    -- reversed by getOpts.+    cAndCmmOpt dflags =  opt_CmmP dflags ++ cmmG0 ++ optCFiltered dflags+    (logger_name, pgm_getter, opt_getter, readable_name)+      = case preprocessor of+        SCPCpp -> ("cpp", pgm_cpp, opt_c, "C pre-processor")+        SCPHsCpp -> ("hs-cpp", pgm_P, opt_P, "Haskell C pre-processor")+        SCPJsCpp -> ("js-cpp", pgm_JSP, opt_JSP, "JavaScript C pre-processor")+        SCPCmmCpp -> ("cmm-cpp", pgm_CmmP, cAndCmmOpt, "C-- C pre-processor")++    runSomethingResponseFileCpp+      = runSomethingResponseFile logger tmpfs (tmpDir dflags) cc_filter+    runSomethingFilteredOther phase_name pgm args mb_env+      = runSomethingFiltered logger id phase_name pgm args Nothing mb_env++    runSomething+      = case preprocessor of+        SCPCpp -> runSomethingResponseFileCpp+        SCPHsCpp -> runSomethingFilteredOther+        SCPJsCpp -> runSomethingFilteredOther+        SCPCmmCpp -> runSomethingResponseFileCpp+ runPp :: Logger -> DynFlags -> [Option] -> IO () runPp logger dflags args = traceSystoolCommand logger "pp" $ do   let prog = pgm_F dflags@@ -243,14 +286,17 @@               (pin, pout, perr, p) <- runInteractiveProcess pgm args'                                               Nothing Nothing               {- > llc -version-                  LLVM (http://llvm.org/):-                    LLVM version 3.5.2+                  <vendor> LLVM version 15.0.7                     ...+                  OR+                  LLVM (http://llvm.org/):+                    LLVM version 14.0.6               -}               hSetBinaryMode pout False-              _     <- hGetLine pout-              vline <- hGetLine pout-              let mb_ver = parseLlvmVersion vline+              line1 <- hGetLine pout+              mb_ver <- case parseLlvmVersion line1 of+                mb_ver@(Just _) -> return mb_ver+                Nothing -> parseLlvmVersion <$> hGetLine pout -- Try the second line               hClose pin               hClose pout               hClose perr
GHC/Tc/Errors.hs view
@@ -465,6 +465,8 @@              flav = ctFlavour ct         ; (suppress, m_evdest) <- case ctEvidence ct of+         -- For this `suppress` stuff+         -- see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint            CtGiven {} -> return (False, Nothing)            CtWanted { ctev_rewriters = rewriters, ctev_dest = dest }              -> do { rewriters' <- zonkRewriterSet rewriters@@ -2094,10 +2096,9 @@   case orig of     TypeEqOrigin { uo_actual, uo_expected, uo_thing = mb_thing } ->       (TypeEqMismatch-        { teq_mismatch_ppr_explicit_kinds = ppr_explicit_kinds-        , teq_mismatch_item = item-        , teq_mismatch_ty1  = ty1-        , teq_mismatch_ty2  = ty2+        { teq_mismatch_item     = item+        , teq_mismatch_ty1      = ty1+        , teq_mismatch_ty2      = ty2         , teq_mismatch_actual   = uo_actual         , teq_mismatch_expected = uo_expected         , teq_mismatch_what     = mb_thing@@ -2121,26 +2122,7 @@   where     orig = errorItemOrigin item     mb_same_occ = sameOccExtras ty2 ty1-    ppr_explicit_kinds = shouldPprWithExplicitKinds ty1 ty2 orig --- | Whether to print explicit kinds (with @-fprint-explicit-kinds@)--- in an 'SDoc' when a type mismatch occurs to due invisible kind arguments.------ This function first checks to see if the 'CtOrigin' argument is a--- 'TypeEqOrigin'. If so, it first checks whether the equality is a visible--- equality; if it's not, definitely print the kinds. Even if the equality is--- a visible equality, check the expected/actual types to see if the types--- have equal visible components. If the 'CtOrigin' is--- not a 'TypeEqOrigin', fall back on the actual mismatched types themselves.-shouldPprWithExplicitKinds :: Type -> Type -> CtOrigin -> Bool-shouldPprWithExplicitKinds _ty1 _ty2 (TypeEqOrigin { uo_actual = act-                                                   , uo_expected = exp-                                                   , uo_visible = vis })-  | not vis   = True                  -- See tests T15870, T16204c-  | otherwise = tcEqTypeVis act exp   -- See tests T9171, T9144.-shouldPprWithExplicitKinds ty1 ty2 _ct-  = tcEqTypeVis ty1 ty2- {- Note [Insoluble mis-match] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider [G] a ~ [a],  [W] a ~ [a] (#13674).  The Given is insoluble@@ -2401,29 +2383,6 @@       Perhaps you meant ‘getAlt’ (imported from Data.Monoid)       Perhaps you want to add ‘getAll’ to the import list       in the import of ‘Data.Monoid’--}--{--Note [Kind arguments in error messages]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-It can be terribly confusing to get an error message like (#9171)--    Couldn't match expected type ‘GetParam Base (GetParam Base Int)’-                with actual type ‘GetParam Base (GetParam Base Int)’--The reason may be that the kinds don't match up.  Typically you'll get-more useful information, but not when it's as a result of ambiguity.--To mitigate this, GHC attempts to enable the -fprint-explicit-kinds flag-whenever any error message arises due to a kind mismatch. This means that-the above error message would instead be displayed as:--    Couldn't match expected type-                  ‘GetParam @* @k2 @* Base (GetParam @* @* @k2 Base Int)’-                with actual type-                  ‘GetParam @* @k20 @* Base (GetParam @* @* @k20 Base Int)’--Which makes it clearer that the culprit is the mismatch between `k2` and `k20`. -}  -----------------------
GHC/Tc/Errors/Hole/Plugin.hs-boot view
@@ -1,3 +1,6 @@ module GHC.Tc.Errors.Hole.Plugin where +-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Base ()+ data HoleFitPlugin
GHC/Tc/Errors/Ppr.hs view
@@ -54,8 +54,8 @@ import GHC.Core.FamInstEnv ( FamInst(..), famInstAxiom, pprFamInst ) import GHC.Core.InstEnv import GHC.Core.TyCo.Rep (Type(..))-import GHC.Core.TyCo.Ppr (pprWithExplicitKindsWhen,-                          pprSourceTyCon, pprTyVars, pprWithTYPE, pprTyVar, pprTidiedType)+import GHC.Core.TyCo.Ppr (pprWithInvisibleBitsWhen, pprSourceTyCon,+                          pprTyVars, pprWithTYPE, pprTyVar, pprTidiedType) import GHC.Core.PatSyn ( patSynName, pprPatSynType ) import GHC.Core.Predicate import GHC.Core.Type@@ -536,7 +536,7 @@                                 , text "cannot be inferred from the right-hand side." ]                      in (injectivityErrorHerald $$ body $$ text "In the type family equation:", show_kinds) -         in mkSimpleDecorated $ pprWithExplicitKindsWhen show_kinds $+         in mkSimpleDecorated $ pprWithInvisibleBitsWhen show_kinds $               hang herald                 2 (vcat (map (pprCoAxBranchUser fam_tc) (eqn1 : rest_eqns)))     TcRnBangOnUnliftedType ty@@ -1182,7 +1182,7 @@                 ppr con <+> dcolon <+> ppr (dataConDisplayType True con))               IsGADT ->                 (text "A newtype must not be a GADT",-                ppr con <+> dcolon <+> pprWithExplicitKindsWhen sneaky_eq_spec+                ppr con <+> dcolon <+> pprWithInvisibleBitsWhen sneaky_eq_spec                                        (ppr $ dataConDisplayType show_linear_types con))               HasConstructorContext ->                 (text "A newtype constructor must not have a context in its type",@@ -1432,7 +1432,7 @@             , text "Perhaps enable PolyKinds or add a kind signature" ])     TcRnUninferrableTyVar tidied_tvs context ->       mkSimpleDecorated $-      pprWithExplicitKindsWhen True $+      pprWithInvisibleBitsWhen True $       vcat [ text "Uninferrable type variable"               <> plural tidied_tvs               <+> pprWithCommas pprTyVar tidied_tvs@@ -1440,7 +1440,7 @@             , pprUninferrableTyVarCtx context ]     TcRnSkolemEscape escapees tv orig_ty ->       mkSimpleDecorated $-      pprWithExplicitKindsWhen True $+      pprWithInvisibleBitsWhen True $       vcat [ sep [ text "Cannot generalise type; skolem" <> plural escapees                 , quotes $ pprTyVars escapees                 , text "would escape" <+> itsOrTheir escapees <+> text "scope"@@ -1884,7 +1884,7 @@      TcRnInvalidDefaultedTyVar wanteds proposal bad_tvs ->       mkSimpleDecorated $-      pprWithExplicitKindsWhen True $+      pprWithInvisibleBitsWhen True $       vcat [ text "Invalid defaulting proposal."            , hang (text "The following type variable" <> plural (NE.toList bad_tvs) <+> text "cannot be defaulted, as" <+> why <> colon)                 2 (pprQuotedList (NE.toList bad_tvs))@@ -4153,17 +4153,18 @@               | otherwise       = text "kind" <+> quotes (ppr exp)  pprMismatchMsg ctxt-  (TypeEqMismatch { teq_mismatch_ppr_explicit_kinds = ppr_explicit_kinds-                  , teq_mismatch_item     = item+  (TypeEqMismatch { teq_mismatch_item     = item                   , teq_mismatch_ty1      = ty1   -- These types are the actual types                   , teq_mismatch_ty2      = ty2   --   that don't match; may be swapped                   , teq_mismatch_expected = exp   -- These are the context of                   , teq_mismatch_actual   = act   --   the mis-match                   , teq_mismatch_what     = mb_thing                   , teq_mb_same_occ       = mb_same_occ })-  = addArising ct_loc $ pprWithExplicitKindsWhen ppr_explicit_kinds msg-  $$ maybe empty pprSameOccInfo mb_same_occ+  = addArising ct_loc $+    pprWithInvisibleBitsWhen ppr_invis_bits msg+    $$ maybe empty pprSameOccInfo mb_same_occ   where+     msg | Just (torc, rep) <- sORTKind_maybe exp         = msg_for_exp_sort torc rep @@ -4226,6 +4227,7 @@     ct_loc = errorItemCtLoc item     orig   = errorItemOrigin item     level  = ctLocTypeOrKind_maybe ct_loc `orElse` TypeLevel+    ppr_invis_bits = shouldPprWithInvisibleBits ty1 ty2 orig      num_args_msg = case level of       KindLevel@@ -4317,7 +4319,61 @@         _        -> pprTheta wanteds  +-- | Whether to print explicit kinds (with @-fprint-explicit-kinds@)+-- in an 'SDoc' when a type mismatch occurs to due invisible parts of the types.+-- See Note [Showing invisible bits of types in error messages]+--+-- This function first checks to see if the 'CtOrigin' argument is a+-- 'TypeEqOrigin'. If so, it first checks whether the equality is a visible+-- equality; if it's not, definitely print the kinds. Even if the equality is+-- a visible equality, check the expected/actual types to see if the types+-- have equal visible components. If the 'CtOrigin' is+-- not a 'TypeEqOrigin', fall back on the actual mismatched types themselves.+shouldPprWithInvisibleBits :: Type -> Type -> CtOrigin -> Bool+shouldPprWithInvisibleBits _ty1 _ty2 (TypeEqOrigin { uo_actual = act+                                                   , uo_expected = exp+                                                   , uo_visible = vis })+  | not vis   = True                  -- See tests T15870, T16204c+  | otherwise = mayLookIdentical act exp   -- See tests T9171, T9144.+shouldPprWithInvisibleBits ty1 ty2 _ct+  = mayLookIdentical ty1 ty2 +{- Note [Showing invisible bits of types in error messages]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+It can be terribly confusing to get an error message like (#9171)++    Couldn't match expected type ‘GetParam Base (GetParam Base Int)’+                with actual type ‘GetParam Base (GetParam Base Int)’++The reason may be that the kinds don't match up.  Typically you'll get+more useful information, but not when it's as a result of ambiguity.++To mitigate this, when we find a type or kind mis-match:++* See if normally-visible parts of the type would make the two types+  look different.  This check is made by+  `GHC.Core.TyCo.Compare.mayLookIdentical`++* If not, display the types with their normally-visible parts made visible,+  by setting flags in the `SDocContext":+  Specifically:+    - Display kind arguments: sdocPrintExplicitKinds+    - Don't default away runtime-reps: sdocPrintExplicitRuntimeReps,+           which controls `GHC.Iface.Type.hideNonStandardTypes`+  (NB: foralls are always printed by pprType, it turns out.)++As a result the above error message would instead be displayed as:++    Couldn't match expected type+                  ‘GetParam @* @k2 @* Base (GetParam @* @* @k2 Base Int)’+                with actual type+                  ‘GetParam @* @k20 @* Base (GetParam @* @* @k20 Base Int)’++Which makes it clearer that the culprit is the mismatch between `k2` and `k20`.++Another example of what goes wrong without this: #24553.+-}+ {- ********************************************************************* *                                                                      *                  Displaying potential instances@@ -6040,7 +6096,7 @@   IllegalFamilyInstance reason ->     pprIllegalFamilyInstance reason   IllegalFamilyApplicationInInstance inst_ty invis_arg tf_tc tf_args ->-    pprWithExplicitKindsWhen invis_arg $+    pprWithInvisibleBitsWhen invis_arg $       hang (text "Illegal type synonym family application"               <+> quotes (ppr tf_ty) <+> text "in instance" <> colon)          2 (ppr inst_ty)@@ -6123,7 +6179,7 @@   , not_covered_invis_vis_tvs = undetermined_tvs   , not_covered_liberal       = which_cc_failed   } =-  pprWithExplicitKindsWhen (isEmptyVarSet $ pSnd undetermined_tvs) $+  pprWithInvisibleBitsWhen (isEmptyVarSet $ pSnd undetermined_tvs) $     vcat [ sep [ text "The"                   <+> ppWhen liberal (text "liberal")                   <+> text "coverage condition fails in class"@@ -6385,7 +6441,7 @@         , text "mentions none of the type or kind variables of the class" <+>                 quotes (ppr cls <+> hsep (map ppr (classTyVars cls)))]   AssocTyVarsDontMatch vis fam_tc exp_tys act_tys ->-    pprWithExplicitKindsWhen (isInvisibleForAllTyFlag vis) $+    pprWithInvisibleBitsWhen (isInvisibleForAllTyFlag vis) $     vcat [ text "Type indexes must match class instance head"          , text "Expected:" <+> pp exp_tys          , text "  Actual:" <+> pp act_tys ]@@ -6409,7 +6465,7 @@             let (pat_tv, pat_vis) = NE.head dups             in (pat_vis,                 text "Illegal duplicate variable" <+> quotes (ppr pat_tv) <+> text "in:")-    in pprWithExplicitKindsWhen (isInvisibleForAllTyFlag pat_vis) $+    in pprWithInvisibleBitsWhen (isInvisibleForAllTyFlag pat_vis) $          hang main_msg             2 (vcat [ppr_eqn, suggestion])     where
GHC/Tc/Errors/Types.hs view
@@ -5525,8 +5525,7 @@   --   -- Test cases: T1470, tcfail212.   | TypeEqMismatch-      { teq_mismatch_ppr_explicit_kinds :: Bool-      , teq_mismatch_item     :: ErrorItem+      { teq_mismatch_item     :: ErrorItem       , teq_mismatch_ty1      :: Type       , teq_mismatch_ty2      :: Type       , teq_mismatch_expected :: Type -- ^ The overall expected type
GHC/Tc/Gen/App.hs view
@@ -56,7 +56,6 @@ import GHC.Types.Name.Reader import GHC.Types.SrcLoc import GHC.Types.Var.Env  ( emptyTidyEnv, mkInScopeSet )-import GHC.Types.SourceText import GHC.Data.Maybe import GHC.Utils.Misc import GHC.Utils.Outputable as Outputable@@ -899,18 +898,12 @@       where         unwrap_op_tv (L _ (HsTyVar _ _ op_id)) = return op_id         unwrap_op_tv _ = failWith $ TcRnIllformedTypeArgument (L l e)-    go (L l e@(HsOverLit _ lit)) =-      do { tylit <- case ol_val lit of-             HsIntegral   n -> return $ HsNumTy NoSourceText (il_value n)-             HsIsString _ s -> return $ HsStrTy NoSourceText s-             HsFractional _ -> failWith $ TcRnIllformedTypeArgument (L l e)-         ; return (L l (HsTyLit noExtField tylit)) }-    go (L l e@(HsLit _ lit)) =-      do { tylit <- case lit of-             HsChar   _ c -> return $ HsCharTy NoSourceText c-             HsString _ s -> return $ HsStrTy  NoSourceText s-             _ -> failWith $ TcRnIllformedTypeArgument (L l e)-         ; return (L l (HsTyLit noExtField tylit)) }+    go (L l (HsOverLit _ lit))+      | Just tylit <- tyLitFromOverloadedLit (ol_val lit)+      = return (L l (HsTyLit noExtField tylit))+    go (L l (HsLit _ lit))+      | Just tylit <- tyLitFromLit lit+      = return (L l (HsTyLit noExtField tylit))     go (L l (ExplicitTuple _ tup_args boxity))       -- Neither unboxed tuples (#e1,e2#) nor tuple sections (e1,,e2,) can be promoted       | isBoxed boxity
GHC/Tc/Gen/Bind.hs view
@@ -723,7 +723,6 @@  {- Note [Non-variable pattern bindings aren't linear] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~- A fundamental limitation of the typechecking algorithm is that we cannot have a binding which, at the same time, - is linear in its rhs@@ -735,17 +734,35 @@  To address this we to do a few things -- When a pattern is annotated with a multiplicity annotation `let %q pat = rhs+- (NVP1) When a pattern is annotated with a multiplicity annotation `let %q pat = rhs   in body` (note: multiplicity-annotated bindings are always parsed as a   PatBind, see Note [Multiplicity annotations] in Language.Haskell.Syntax.Binds),-  then the let is never generalised (we use the NoGen plan).-- Whenever the typechecker infers an AbsBind *and* the inner binding is a+  then the let is never generalised (we use the NoGen plan). We do this with a+  dedicated test in decideGeneralisationPlan.+- (NVP2) Whenever the typechecker infers an AbsBind *and* the inner binding is a   non-variable PatBind, then the multiplicity of the binding is inferred to be-  Many. This is a little infelicitous: sometimes the typechecker infers an-  AbsBind where it didn't need to. This may cause some programs to be spuriously-  rejected, when NoMonoLocalBinds is on.-- LinearLet implies MonoLocalBinds to avoid the AbsBind case altogether.+  Many. We do this by calling manyIfPats in tcPolyInfer. This is a little+  infelicitous: sometimes the typechecker infers an AbsBind where it didn't need+  to. This may cause some programs to be spuriously rejected, when+  NoMonoLocalBinds is on.+- (NVP3) LinearLet implies MonoLocalBinds to avoid the AbsBind case altogether.+- (NVP4) Wrinkle: even when other conditions (including MonoLocalBinds), GHC+  will generalise some binders, namely so-called closed binding groups. We need+  to make sure that the test for (NVP1) has priority over the test for closed+  binders.+- (NVP5) Wrinkle: Closed binding groups (NVP4) are usually fine to type with+  multiplicity Many. But there's one exception: when there's no binder at all,+  the binding group is considered closed. Even if the rhs contains arbitrary+  variables. +     f :: () %1 -> Bool+     f x = let !() = x in True++  If we consider `!() = x` as a generalisable group (which does nothing anyway),+  then (NVP2) will infer the pattern as multiplicity Many, and reject the+  function. We don't want that, see also #25428. So we take care not to+  generalise in this case, by excluding the no-binder case from automatic+  generalisation in decideGeneralisationPlan. -}  tcPolyInfer@@ -762,7 +779,7 @@        ; apply_mr <- checkMonomorphismRestriction mono_infos bind_list         -- AbsBinds which are PatBinds can't be linear.-       -- See Note [Non-variable pattern bindings aren't linear]+       -- See (NVP2) in Note [Non-variable pattern bindings aren't linear]        ; binds' <- manyIfPats binds'         ; traceTc "tcPolyInfer" (ppr apply_mr $$ ppr (map mbi_sig mono_infos))@@ -1871,12 +1888,17 @@         -- See Note [Always generalise top-level bindings]        | has_mult_anns_and_pats = False-        -- See Note [Non-variable pattern bindings aren't linear]+        -- See (NVP1) and (NVP4) in Note [Non-variable pattern bindings aren't linear] -      | IsGroupClosed _ True <- closed = True+      | IsGroupClosed _ True <- closed+      , not (null binders) = True         -- The 'True' means that all of the group's         -- free vars have ClosedTypeId=True; so we can ignore-        -- -XMonoLocalBinds, and generalise anyway+        -- -XMonoLocalBinds, and generalise anyway.+        -- Except if 'fv' is empty: there is no binder to generalise, so+        -- generalising does nothing. And trying to generalise hurts linear+        -- types (see #25428). So we don't force it.+        -- See (NVP5) in Note [Non-variable pattern bindings aren't linear] in GHC.Tc.Gen.Bind.        | has_partial_sigs = True         -- See Note [Partial type signatures and generalisation]
GHC/Tc/Gen/Head.hs view
@@ -37,8 +37,6 @@ import GHC.Hs.Syn.Type  import GHC.Tc.Gen.HsType-import GHC.Rename.Unbound     ( unknownNameSuggestions, WhatLooking(..) )- import GHC.Tc.Gen.Bind( chooseInferredQuantifiers ) import GHC.Tc.Gen.Sig( tcUserTypeSig, tcInstSig ) import GHC.Tc.TyCl.PatSyn( patSynBuilderOcc )@@ -78,15 +76,14 @@ import GHC.Builtin.Names import GHC.Builtin.Names.TH( liftStringName, liftName ) -import GHC.Driver.Env import GHC.Driver.DynFlags import GHC.Utils.Misc import GHC.Utils.Outputable as Outputable import GHC.Utils.Panic-import qualified GHC.LanguageExtensions as LangExt  import GHC.Data.Maybe import Control.Monad+import GHC.Rename.Unbound (WhatLooking(WL_Anything))   @@ -1164,46 +1161,11 @@               AGlobal (AConLike (RealDataCon con)) -> tcInferDataCon con              AGlobal (AConLike (PatSynCon ps)) -> tcInferPatSyn id_name ps-             (tcTyThingTyCon_maybe -> Just tc) -> fail_tycon tc -- TyCon or TcTyCon-             ATyVar name _ -> fail_tyvar name+             (tcTyThingTyCon_maybe -> Just tc) -> failIllegalTyCon WL_Anything tc -- TyCon or TcTyCon+             ATyVar name _ -> failIllegalTyVal name               _ -> failWithTc $ TcRnExpectedValueId thing }   where-    fail_tycon tc = do-      gre <- getGlobalRdrEnv-      let nm = tyConName tc-          pprov = case lookupGRE_Name gre nm of-                      Just gre -> nest 2 (pprNameProvenance gre)-                      Nothing  -> empty-          err | isClassTyCon tc = ClassTE-              | otherwise       = TyConTE-      fail_with_msg dataName nm pprov err--    fail_tyvar nm =-      let pprov = nest 2 (text "bound at" <+> ppr (getSrcLoc nm))-      in fail_with_msg varName nm pprov TyVarTE--    fail_with_msg whatName nm pprov err = do-      (import_errs, hints) <- get_suggestions whatName-      unit_state <- hsc_units <$> getTopEnv-      let-        -- TODO: unfortunate to have to convert to SDoc here.-        -- This should go away once we refactor ErrInfo.-        hint_msg = vcat $ map ppr hints-        import_err_msg = vcat $ map ppr import_errs-        info = ErrInfo { errInfoContext = pprov, errInfoSupplementary = import_err_msg $$ hint_msg }-      failWithTc $ TcRnMessageWithInfo unit_state (-              mkDetailedMessage info (TcRnIllegalTermLevelUse nm err))--    get_suggestions ns = do-      required_type_arguments <- xoptM LangExt.RequiredTypeArguments-      if required_type_arguments && isVarNameSpace ns-      then return ([], [])  -- See Note [Suppress hints with RequiredTypeArguments]-      else do-        let occ = mkOccNameFS ns (occNameFS (occName id_name))-        lcl_env <- getLocalRdrEnv-        unknownNameSuggestions lcl_env WL_Anything (mkRdrUnqual occ)-     return_id id = return (HsVar noExtField (noLocA id), idType id)  {- Note [Suppress hints with RequiredTypeArguments]
GHC/Tc/Gen/HsType.hs view
@@ -73,7 +73,10 @@         HoleMode(..),          -- Error messages-        funAppCtxt, addTyConFlavCtxt+        funAppCtxt, addTyConFlavCtxt,++        -- Utils+        tyLitFromLit, tyLitFromOverloadedLit,    ) where  import GHC.Prelude hiding ( head, init, last, tail )@@ -140,6 +143,7 @@ import Data.List ( mapAccumL ) import Control.Monad import Data.Tuple( swap )+import GHC.Types.SourceText  {-         ----------------------------@@ -4687,3 +4691,22 @@ addTyConFlavCtxt name flav   = addErrCtxt $ hsep [ text "In the", ppr flav                       , text "declaration for", quotes (ppr name) ]++{-+************************************************************************+*                                                                      *+          Utils for constructing TyLit+*                                                                      *+************************************************************************+-}+++tyLitFromLit :: HsLit GhcRn -> Maybe (HsTyLit GhcRn)+tyLitFromLit (HsString x str) = Just (HsStrTy x str)+tyLitFromLit (HsChar x char) = Just (HsCharTy x char)+tyLitFromLit _ = Nothing++tyLitFromOverloadedLit :: OverLitVal -> Maybe (HsTyLit GhcRn)+tyLitFromOverloadedLit (HsIntegral n) = Just $ HsNumTy NoSourceText (il_value n)+tyLitFromOverloadedLit (HsIsString _ s) = Just $ HsStrTy NoSourceText s+tyLitFromOverloadedLit HsFractional{} = Nothing
GHC/Tc/Gen/Match.hs view
@@ -501,6 +501,32 @@ --      coercion matching stuff in them.  It's hard to avoid the --      potential for non-trivial coercions in tcMcStmt +{-+Note [Binding in list comprehension isn't linear]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In principle, [ y | () <- xs, y <- [0,1]] could be linear in `xs`.+But, the way the desugaring works, we get something like++case xs of+  () : xs ' -> letrec next_stmt = … xs' …++In the current typing rules for letrec in Core, next_stmt is necessarily of+multiplicity Many and so is every free variable, including xs'. Which, in turns,+requires xs to be of multiplicity Many.++Rodrigo Mesquita worked out, in his master thesis, how to make letrecs having+non-Many multiplicities. But it's a fair bit of work to implement.++Since nobody actually cares about [ y | () <- xs, y <- [0,1]] being linear, then+we just conservatively make it unrestricted instead.++If we're to change that, we have to be careful that [ y | _ <- xs, y <- [0,1]]+isn't linear in `xs` since the elements of `xs` are ignored. So we'd still have+to call `tcScalingUsage` on `xs` in `tcLcStmt`, we'd just have to create a fresh+multiplicity variable. We'd also use the same multiplicity variable in the call+to `tcCheckPat` instead of `unrestricted`.+-}+ tcLcStmt :: TyCon       -- The list type constructor ([])          -> TcExprStmtChecker @@ -512,20 +538,24 @@ -- A generator, pat <- rhs tcLcStmt m_tc ctxt (BindStmt _ pat rhs) elt_ty thing_inside  = do   { pat_ty <- newFlexiTyVarTy liftedTypeKind-        ; rhs'   <- tcCheckMonoExpr rhs (mkTyConApp m_tc [pat_ty])+          -- About the next `tcScalingUsage ManyTy` and unrestricted+          -- see Note [Binding in list comprehension isn't linear]+        ; rhs'   <- tcScalingUsage ManyTy $ tcCheckMonoExpr rhs (mkTyConApp m_tc [pat_ty])         ; (pat', thing)  <- tcCheckPat (StmtCtxt ctxt) pat (unrestricted pat_ty) $+                            tcScalingUsage ManyTy $                             thing_inside elt_ty         ; return (mkTcBindStmt pat' rhs', thing) }  -- A boolean guard tcLcStmt _ _ (BodyStmt _ rhs _ _) elt_ty thing_inside   = do  { rhs'  <- tcCheckMonoExpr rhs boolTy-        ; thing <- thing_inside elt_ty+        ; thing <- tcScalingUsage ManyTy $ thing_inside elt_ty         ; return (BodyStmt boolTy rhs' noSyntaxExpr noSyntaxExpr, thing) }  -- ParStmt: See notes with tcMcStmt and Note [Scoping in parallel list comprehensions] tcLcStmt m_tc ctxt (ParStmt _ bndr_stmts_s _ _) elt_ty thing_inside-  = do  { env <- getLocalRdrEnv+  = tcScalingUsage ManyTy $ -- parallel list comprehension never desugars to something linear.+    do  { env <- getLocalRdrEnv         ; (pairs', thing) <- loop env [] bndr_stmts_s         ; return (ParStmt unitTy pairs' noExpr noSyntaxExpr, thing) }   where@@ -551,7 +581,8 @@ tcLcStmt m_tc ctxt (TransStmt { trS_form = form, trS_stmts = stmts                               , trS_bndrs =  bindersMap                               , trS_by = by, trS_using = using }) elt_ty thing_inside-  = do { let (bndr_names, n_bndr_names) = unzip bindersMap+  = tcScalingUsage ManyTy $ -- Transform statements are too complex: just make everything multiplicity Many+    do { let (bndr_names, n_bndr_names) = unzip bindersMap              unused_ty = pprPanic "tcLcStmt: inner ty" (ppr bindersMap)              -- The inner 'stmts' lack a LastStmt, so the element type              --  passed in to tcStmtsAndThen is never looked at
GHC/Tc/Gen/Pat.hs view
@@ -78,6 +78,8 @@  import Data.List( partition ) import Data.Maybe (isJust)+import Control.Monad.Trans.Writer.CPS+import Control.Monad.Trans.Class  {- ************************************************************************@@ -504,55 +506,108 @@        ; let pat' = XPat $ ExpansionPat pat (EmbTyPat arg_ty tp)        ; return (pat', result) } + -- Convert a Pat into the equivalent HsTyPat. -- See `expr_to_type` (GHC.Tc.Gen.App) for the HsExpr counterpart. -- The `TcM` monad is only used to fail on ill-formed type patterns. pat_to_type_pat :: Pat GhcRn -> TcM (HsTyPat GhcRn)-pat_to_type_pat (EmbTyPat _ tp) = return tp-pat_to_type_pat (VarPat _ lname)  = return (HsTP x b)+pat_to_type_pat pat = do+  (ty, x) <- runWriterT (pat_to_type pat)+  pure (HsTP (buildHsTyPatRn x) ty)++pat_to_type :: Pat GhcRn -> WriterT HsTyPatRnBuilder TcM (LHsType GhcRn)+pat_to_type (EmbTyPat _ (HsTP x t)) =+  do { tell (builderFromHsTyPatRn x)+     ; return t }+pat_to_type (VarPat _ lname)  =+  do { tell (tpBuilderExplicitTV (unLoc lname))+     ; return b }   where b = noLocA (HsTyVar noAnn NotPromoted lname)-        x = HsTPRn { hstp_nwcs    = []-                   , hstp_imp_tvs = []-                   , hstp_exp_tvs = [unLoc lname] }-pat_to_type_pat (WildPat _) = return (HsTP x b)+pat_to_type (WildPat _) = return b   where b = noLocA (HsWildCardTy noExtField)-        x = HsTPRn { hstp_nwcs    = []-                   , hstp_imp_tvs = []-                   , hstp_exp_tvs = [] }-pat_to_type_pat (SigPat _ pat sig_ty)-  = do { HsTP x_hstp t <- pat_to_type_pat (unLoc pat)+pat_to_type (SigPat _ pat sig_ty)+  = do { t <- pat_to_type (unLoc pat)        ; let { !(HsPS x_hsps k) = sig_ty-             ; x = append_hstp_hsps x_hstp x_hsps              ; b = noLocA (HsKindSig noAnn t k) }-       ; return (HsTP x b) }-  where-    -- Quadratic for nested signatures ((p :: t1) :: t2)-    -- but those are unlikely to occur in practice.-    append_hstp_hsps :: HsTyPatRn -> HsPSRn -> HsTyPatRn-    append_hstp_hsps t p-      = HsTPRn { hstp_nwcs     = hstp_nwcs    t ++ hsps_nwcs    p-               , hstp_imp_tvs  = hstp_imp_tvs t ++ hsps_imp_tvs p-               , hstp_exp_tvs  = hstp_exp_tvs t }-pat_to_type_pat (ParPat _ pat)-  = do { HsTP x t <- pat_to_type_pat (unLoc pat)-       ; return (HsTP x (noLocA (HsParTy noAnn t))) }-pat_to_type_pat (SplicePat (HsUntypedSpliceTop mod_finalizers pat) splice) = do-      { HsTP x t <- pat_to_type_pat pat-      ; return (HsTP x (noLocA (HsSpliceTy (HsUntypedSpliceTop mod_finalizers t) splice))) }-pat_to_type_pat pat =-  -- There are other cases to handle (ConPat, ListPat, TuplePat, etc), but these-  -- would always be rejected by the unification in `tcHsTyPat`, so it's fine to-  -- skip them here. This won't continue to be the case when visible forall is-  -- permitted in data constructors:-  ---  --   data T a where { Typed :: forall a -> a -> T a }-  --   g :: T Int -> Int-  --   g (Typed Int x) = x   -- Note the `Int` type pattern-  ---  -- See ticket #18389. When this feature lands, it would be best to extend-  -- `pat_to_type_pat` to handle as many pattern forms as possible.+       ; tell (tpBuilderPatSig x_hsps)+       ; return b }+pat_to_type (ParPat _ pat)+  = do { t <- pat_to_type (unLoc pat)+       ; return (noLocA (HsParTy noAnn t)) }+pat_to_type (SplicePat (HsUntypedSpliceTop mod_finalizers pat) splice) = do+      { t <- pat_to_type pat+      ; return (noLocA (HsSpliceTy (HsUntypedSpliceTop mod_finalizers t) splice)) }++pat_to_type (TuplePat _ pats Boxed)+  = do { tys <- traverse (pat_to_type . unLoc) pats+       ; let t = noLocA (HsExplicitTupleTy noExtField tys)+       ; pure t }+pat_to_type (ListPat _ pats)+  = do { tys <- traverse (pat_to_type . unLoc) pats+       ; let t = noLocA (HsExplicitListTy NoExtField NotPromoted tys)+       ; pure t }++pat_to_type (LitPat _ lit)+  | Just ty_lit <- tyLitFromLit lit+  = do { let t = noLocA (HsTyLit noExtField ty_lit)+      ; pure t }+pat_to_type (NPat _ (L _ lit) _ _)+  | Just ty_lit <- tyLitFromOverloadedLit (ol_val lit)+  = do { let t = noLocA (HsTyLit noExtField ty_lit)+       ; pure t}++pat_to_type (ConPat _ lname (InfixCon left right))+  = do { lty <- pat_to_type (unLoc left)+       ; rty <- pat_to_type (unLoc right)+       ; let { t = noLocA (HsOpTy noAnn NotPromoted lty lname rty)}+       ; pure t }+pat_to_type (ConPat _ lname (PrefixCon invis_args vis_args))+  = do { let { appHead = noLocA (HsTyVar noAnn NotPromoted lname)}+       ; ty_invis <- foldM apply_invis_arg appHead invis_args+       ; tys_vis <- traverse (pat_to_type . unLoc) vis_args+       ; let t = foldl' mkHsAppTy ty_invis tys_vis+       ; pure t }+      where+        apply_invis_arg :: LHsType GhcRn -> HsConPatTyArg GhcRn -> WriterT HsTyPatRnBuilder TcM (LHsType GhcRn)+        apply_invis_arg !t (HsConPatTyArg _ (HsTP argx arg))+          = do { tell (builderFromHsTyPatRn argx)+               ; pure (mkHsAppKindTy noExtField t arg)}++pat_to_type pat = lift $   failWith $ TcRnIllformedTypePattern pat   -- This failure is the only use of the TcM monad in `pat_to_type_pat`++{-+Note [Pattern to type (P2T) conversion]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider this:++  data T a b where+    MkT :: forall a. forall b -> a -> b -> T a b+    -- NB: `a` is invisible, but `b` is required++  f (MkT @[Int] (Maybe Bool) x y) = ...++The second type argument of `MkT` is Required, so we write it without+an `@` sign in the pattern match.  So the (Maybe Bool) will be+  * parsed and renamed as a term pattern+  * converted to a type when typechecking the pattern-match: the P2T conversion++This is the only place we have P2T. In type-lambdas, the "pattern" is always a+type variable:++   f :: forall a -> a -> blah+   f b (x::b) = ...++The `b` argument must be a simple variable; we can't pattern-match on types.++The function `pat_to_type` does the P2T conversion:+   pat_to_type :: Pat GhcRn -> WriterT HsTyPatRnBuilder TcM (LHsType GhcRn)++It is arranged as a writer monad, where the `HsTyPatRnBuilder` accumulates the+binders bound by the type.  (We could discover these binders by a subsequent+traversal, that would mean writing another traversal.)+-}  tc_ty_pat :: HsTyPat GhcRn -> TcTyVar -> TcM r -> TcM (TcType, r) tc_ty_pat tp tv thing_inside
GHC/Tc/Instance/Family.hs view
@@ -58,6 +58,7 @@  import qualified GHC.LanguageExtensions  as LangExt import GHC.Unit.Env (unitEnv_hpts)+import Data.List (sortOn)  {- Note [The type family instance consistency story] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -239,6 +240,49 @@ a set of utility modules that every module imports directly or indirectly.  This is basically the idea from #13092, comment:14.++Note [Order of type family consistency checks]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Consider a module M which imports modules A, B and C, all defining (open) type+family instances.++We can waste a lot of work in type family consistency checking depending on the+order in which the modules are processed.++Suppose for example that C imports A and B. When we compiled C, we will have+checked A and B for consistency against eachother. This means that, when+processing the imports of M to check type family instance consistency:++* if C is processed first, then A and B will not need to be checked for+  consistency against eachother again,+* if we process A and B before C,then the+  consistency checks between A and B will be performed again. This is wasted+  work, as we already performed them for C.++This can make a significant difference. Keeping the nomenclature of the above+example for illustration, we have observed situations in practice in which the+compilation time of M goes from 1 second (the "processing A and B first" case)+down to 80 milliseconds (the "processing C first" case).++Clearly we should engineer that C is checked before B and A, but by what scheme?++A simple one is to observe that if a module M is in the transitive closure of X+then the size of the consistent family set of M is less than or equal to size+of the consistent family set of X.++Therefore, by sorting the imports by the size of the consistent family set and+processing the largest first, we make sure to process modules in topological+order.++For a particular project, without this change we did 40 million checks and with+this change we did 22.9 million checks. This is significant as before this change+type family consistency checks accounted for 26% of total type checker allocations which+was reduced to 15%.++See tickets #25554 for discussion about this exact issue and #25555 for+why we still do redundant checks.+ -}  -- We don't need to check the current module, this is done in@@ -267,6 +311,12 @@                  where                  deps = dep_finsts . mi_deps . modIface $ mod +             ; debug_consistent_set = map (\x -> (x, length (modConsistent x))) directlyImpMods++             -- Sorting the list by size has the effect of performing a topological sort.+             -- See Note [Order of type family consistency checks]+             ; init_consistent_set = reverse (sortOn (length . modConsistent) directlyImpMods)+              ; hmiModule     = mi_module . hm_iface              ; hmiFamInstEnv = extendFamInstEnvList emptyFamInstEnv                                . md_fam_insts . hm_details@@ -276,7 +326,8 @@               } -       ; checkMany hpt_fam_insts modConsistent directlyImpMods+       ; traceTc "init_consistent_set" (ppr debug_consistent_set)+       ; checkMany hpt_fam_insts modConsistent init_consistent_set        }   where     -- See Note [Checking family instance optimization]@@ -294,6 +345,11 @@          -> TcM ()       go _ _ [] = return ()       go consistent consistent_set (mod:mods) = do+        traceTc "checkManySize" (vcat [text "mod:" <+> ppr mod+                                      , text "m1:" <+> ppr (length to_check_from_mod)+                                      , text "m2:" <+> ppr (length (to_check_from_consistent))+                                      , text "product:" <+> ppr (length to_check_from_mod * length to_check_from_consistent)+                                      ])         sequence_           [ check hpt_fam_insts m1 m2           | m1 <- to_check_from_mod
GHC/Tc/Module.hs view
@@ -434,7 +434,9 @@         ; let { dir_imp_mods = moduleEnvKeys                              . imp_mods                              $ imports }-        ; checkFamInstConsistency dir_imp_mods+        ; logger <- getLogger+        ; withTiming logger (text "ConsistencyCheck"<+>brackets (ppr this_mod)) (const ())+            $ checkFamInstConsistency dir_imp_mods         ; traceRn "rn1: } checking family instance consistency" empty          ; getGblEnv } }@@ -709,7 +711,7 @@                 -- Typecheck type/class/instance decls         ; traceTc "Tc2 (boot)" empty         ; (tcg_env, inst_infos, _deriv_binds, _th_bndrs)-             <- tcTyClsInstDecls tycl_decls deriv_decls val_binds+             <- tcTyClsInstDecls tycl_decls deriv_decls def_decls val_binds         ; setGblEnv tcg_env     $ do {          -- Emit Typeable bindings@@ -1612,7 +1614,7 @@         traceTc "Tc3" empty ;         (tcg_env, inst_infos, th_bndrs,          XValBindsLR (NValBinds deriv_binds deriv_sigs))-            <- tcTyClsInstDecls tycl_decls deriv_decls val_binds ;+            <- tcTyClsInstDecls tycl_decls deriv_decls default_decls val_binds ;          updLclCtxt (\tcl_env -> tcl_env { tcl_th_bndrs = th_bndrs `plusNameEnv` tcl_th_bndrs tcl_env }) $         setGblEnv tcg_env       $ do {@@ -1622,11 +1624,6 @@         (fi_ids, fi_decls, fi_gres) <- tcForeignImports foreign_decls ;         tcExtendGlobalValEnv fi_ids     $ do { -                -- Default declarations-        traceTc "Tc4a" empty ;-        default_tys <- tcDefaults default_decls ;-        updGblEnv (\gbl -> gbl { tcg_default = default_tys }) $ do {-                 -- Value declarations next.                 -- It is important that we check the top-level value bindings                 -- before the GHC-generated derived bindings, since the latter@@ -1686,13 +1683,14 @@         addUsedGREs NoDeprecationWarnings (bagToList fo_gres) ;          return (tcg_env', tcl_env)-    }}}}}}+    }}}}}  tcTopSrcDecls _ = panic "tcTopSrcDecls: ValBindsIn"  --------------------------- tcTyClsInstDecls :: [TyClGroup GhcRn]                  -> [LDerivDecl GhcRn]+                 -> [LDefaultDecl GhcRn]                  -> [(RecFlag, LHsBinds GhcRn)]                  -> TcM (TcGblEnv,            -- The full inst env                          [InstInfo GhcRn],    -- Source-code instance decls to@@ -1702,16 +1700,24 @@                           HsValBinds GhcRn)   -- Supporting bindings for derived                                               -- instances -tcTyClsInstDecls tycl_decls deriv_decls binds+tcTyClsInstDecls tycl_decls deriv_decls default_decls binds  = tcAddDataFamConPlaceholders (tycl_decls >>= group_instds) $    tcAddPatSynPlaceholders (getPatSynBinds binds) $    do { (tcg_env, inst_info, deriv_info, th_bndrs)           <- tcTyAndClassDecls tycl_decls ;+       ; setGblEnv tcg_env $ do {+           -- With the @TyClDecl@s and @InstDecl@s checked we're ready to           -- process the deriving clauses, including data family deriving           -- clauses discovered in @tcTyAndClassDecls@.           --+          -- But only after we've typechecked 'default' declarations.+          -- See Note [Typechecking default declarations]+          default_tys <- tcDefaults default_decls ;+          updGblEnv (\gbl -> gbl { tcg_default = default_tys }) $ do {++           -- Careful to quit now in case there were instance errors, so that           -- the deriving errors don't pile up as well.           ; failIfErrsM@@ -1720,7 +1726,7 @@           ; setGblEnv tcg_env' $ do {                 failIfErrsM               ; pure ( tcg_env', inst_info' ++ inst_info, th_bndrs, val_binds )-      }}}+      }}}}  {- ********************************************************************* *                                                                      *@@ -3141,3 +3147,43 @@     pluginUnsafe =       singleMessage $       mkPlainMsgEnvelope diag_opts noSrcSpan TcRnUnsafeDueToPlugin+++-- Note [Typechecking default declarations]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- Typechecking default declarations requires careful placement:+--+-- 1. We must check them after types (tcTyAndClassDecls) because they can refer+-- to them. E.g.+--+--    data T = MkT ...+--    default(Int, T, Integer)+--+--    -- or even (tested by T11974b and T2245)+--    default(Int, T, Integer)+--    data T = MkT ...+--+-- 2. We must check them before typechecking deriving clauses (tcInstDeclsDeriv)+-- otherwise we may lookup default default types (Integer, Double) while checking+-- deriving clauses, ignoring the default declaration.+--+-- Before this careful placement (#24566), compiling the following example+-- (T24566) with "-ddump-if-trace -ddump-tc-trace" showed a call to+-- `applyDefaultingRules` with default types set to "(Integer,Double)":+--+--     module M where+--+--     import GHC.Classes+--     default ()+--+--     data Foo a = Nothing | Just a+--       deriving (Eq, Ord)+--+-- This was an issue while building modules like M in the ghc-internal package+-- because they would spuriously fail to build if the module defining Integer+-- (ghc-bignum:GHC.Num.Integer) wasn't compiled yet and its interface not to be+-- found. The implicit dependency between M and GHC.Num.Integer isn't known to+-- the build system.+-- In addition, trying to explicitly avoid the implicit dependency with `default+-- ()` didn't work, except if *standalone* deriving was used, which was an+-- inconsistent behavior.
GHC/Tc/Solver/Equality.hs view
@@ -311,7 +311,7 @@    -> Type -> Type    -- RHS, after and before type-synonym expansion, resp    -> TcS (StopOrContinue (Either IrredCt EqCt)) --- See Note [Comparing nullary type synonyms] in GHC.Core.Type.+-- See Note [Comparing nullary type synonyms] in GHC.Core.TyCo.Compare can_eq_nc _flat _rdr_env _envs ev eq_rel ty1@(TyConApp tc1 []) _ps_ty1 (TyConApp tc2 []) _ps_ty2   | tc1 == tc2   = canEqReflexive ev eq_rel ty1@@ -2228,7 +2228,7 @@ `GHC.Tc.Solver.Monad.checkTypeEq`.  Note its orientation: The type family ends up on the left; see-Note [Orienting TyFamLHS/TyFamLHS]d. No special treatment for+Note [Orienting TyFamLHS/TyFamLHS]. No special treatment for CycleBreakerTvs is necessary. This scenario is now easily soluble, by using the first Given to rewrite the Wanted, which can now be solved. @@ -2900,8 +2900,7 @@   type instance F (a, Int) = (Int, G a) where G is injective; and wanted constraints -  [W] TF (alpha, beta) ~ fuv-  [W] fuv ~ (Int, <some type>)+  [W] F (alpha, beta) ~ (Int, <some type>)  The injectivity will give rise to constraints @@ -2917,8 +2916,8 @@ favour of alpha.  If we instead had    [W] alpha ~ gamma1 then we would unify alpha := gamma1; and kick out the wanted-constraint.  But when we grough it back in, it'd look like-   [W] TF (gamma1, beta) ~ fuv+constraint.  But when we substitute it back in, it'd look like+   [W] F (gamma1, beta) ~ fuv and exactly the same thing would happen again!  Infinite loop.  This all seems fragile, and it might seem more robust to avoid@@ -2999,8 +2998,9 @@   | otherwise   = do { fam_envs <- getFamInstEnvs        ; eqns <- improve_top_fun_eqs fam_envs fam_tc args rhs-       ; traceTcS "improveTopFunEqs" (vcat [ ppr fam_tc <+> ppr args <+> ppr rhs-                                           , ppr eqns ])+       ; traceTcS "improveTopFunEqs" (vcat [ text "lhs:" <+> ppr fam_tc <+> ppr args+                                           , text "rhs:" <+> ppr rhs+                                           , text "eqns:" <+> ppr eqns ])        ; unifyFunDeps ev Nominal $ \uenv ->          uPairsTcM (bump_depth uenv) (reverse eqns) }          -- Missing that `reverse` causes T13135 and T13135_simple to loop.@@ -3072,17 +3072,17 @@                      -> ([Type], Subst, [TyCoVar], Maybe CoAxBranch)                      -> TcS [TypeEqn]       injImproveEqns inj_args (ax_args, subst, unsubstTvs, cabr)-        = do { subst <- instFlexiX subst unsubstTvs+        = do { subst1 <- instFlexiX subst unsubstTvs                   -- If the current substitution bind [k -> *], and                   -- one of the un-substituted tyvars is (a::k), we'd better                   -- be sure to apply the current substitution to a's kind.                   -- Hence instFlexiX.   #13135 was an example. -             ; return [ Pair (substTy subst ax_arg) arg+             ; return [ Pair (substTy subst1 ax_arg) arg                         -- NB: the ax_arg part is on the left                         -- see Note [Improvement orientation]                       | case cabr of-                          Just cabr' -> apartnessCheck (substTys subst ax_args) cabr'+                          Just cabr' -> apartnessCheck (substTys subst1 ax_args) cabr'                           _          -> True                       , (ax_arg, arg, True) <- zip3 ax_args args inj_args ] } 
GHC/Tc/Types.hs view
@@ -534,6 +534,10 @@         tcg_dfun_n  :: TcRef OccSet,           -- ^ Allows us to choose unique DFun names. +        tcg_zany_n :: TcRef Integer,+          -- ^ A source of unique identities for ZonkAny instances+          -- See Note [Any types] in GHC.Builtin.Types, wrinkle (Any4)+         tcg_merged :: [(Module, Fingerprint)],           -- ^ The requirements we merged with; we always have to recompile           -- if any of these changed.
GHC/Tc/Types/Constraint.hs view
@@ -83,7 +83,7 @@         ctEvExpr, ctEvTerm, ctEvCoercion, ctEvEvId,         ctEvRewriters, ctEvUnique, tcEvDestUnique,         mkKindEqLoc, toKindLoc, toInvisibleLoc, mkGivenLoc,-        ctEvRole, setCtEvPredType, setCtEvLoc, arisesFromGivens,+        ctEvRole, setCtEvPredType, setCtEvLoc,         tyCoVarsOfCtEvList, tyCoVarsOfCtEv, tyCoVarsOfCtEvsList,          -- RewriterSet@@ -1312,25 +1312,51 @@ insolubleWC :: WantedConstraints -> Bool insolubleWC (WC { wc_impl = implics, wc_simple = simples, wc_errors = errors })   =  anyBag insolubleWantedCt simples+       -- insolubleWantedCt: wanteds only: see Note [Given insolubles]   || anyBag insolubleImplic implics   || anyBag is_insoluble errors--    where+  where       is_insoluble (DE_Hole hole) = isOutOfScopeHole hole -- See Note [Insoluble holes]       is_insoluble (DE_NotConcrete {}) = True  insolubleWantedCt :: Ct -> Bool -- Definitely insoluble, in particular /excluding/ type-hole constraints -- Namely:---   a) an insoluble constraint as per 'insolubleCt', i.e. either+--   a) an insoluble constraint as per 'insolubleIrredCt', i.e. either --        - an insoluble equality constraint (e.g. Int ~ Bool), or --        - a custom type error constraint, TypeError msg :: Constraint --   b) that does not arise from a Given or a Wanted/Wanted fundep interaction+-- See Note [Insoluble Wanteds]+insolubleWantedCt ct+  | CIrredCan ir_ct <- ct+      -- CIrredCan: see (IW1) in Note [Insoluble Wanteds]+  , IrredCt { ir_ev = ev } <- ir_ct+  , CtWanted { ctev_loc = loc, ctev_rewriters = rewriters }  <- ev+      -- It's a Wanted+  , insolubleIrredCt ir_ct+      -- It's insoluble+  , isEmptyRewriterSet rewriters+      -- It has no rewriters; see (IW2) in Note [Insoluble Wanteds]+  , not (isGivenLoc loc)+      -- isGivenLoc: see (IW3) in Note [Insoluble Wanteds]+  , not (isWantedWantedFunDepOrigin (ctLocOrigin loc))+      -- origin check: see (IW4) in Note [Insoluble Wanteds]+  = True++  | otherwise+  = False++-- | Returns True of constraints that are definitely insoluble,+--   as well as TypeError constraints.+-- Can return 'True' for Given constraints, unlike 'insolubleWantedCt'. ----- See Note [Given insolubles].-insolubleWantedCt ct = insolubleCt ct &&-                       not (arisesFromGivens ct) &&-                       not (isWantedWantedFunDepOrigin (ctOrigin ct))+-- The function is tuned for application /after/ constraint solving+--       i.e. assuming canonicalisation has been done+-- That's why it looks only for IrredCt; all insoluble constraints+-- are put into CIrredCan+insolubleCt :: Ct -> Bool+insolubleCt (CIrredCan ir_ct) = insolubleIrredCt ir_ct+insolubleCt _                 = False  insolubleIrredCt :: IrredCt -> Bool -- Returns True of Irred constraints that are /definitely/ insoluble@@ -1360,18 +1386,6 @@   -- >   Assert 'True  _errMsg = ()   -- >   Assert _check errMsg  = errMsg --- | Returns True of constraints that are definitely insoluble,---   as well as TypeError constraints.--- Can return 'True' for Given constraints, unlike 'insolubleWantedCt'.------ The function is tuned for application /after/ constraint solving---       i.e. assuming canonicalisation has been done--- That's why it looks only for IrredCt; all insoluble constraints--- are put into CIrredCan-insolubleCt :: Ct -> Bool-insolubleCt (CIrredCan ir_ct) = insolubleIrredCt ir_ct-insolubleCt _                 = False- -- | Does this hole represent an "out of scope" error? -- See Note [Insoluble holes] isOutOfScopeHole :: Hole -> Bool@@ -1415,6 +1429,31 @@ Bottom line: insolubleWC (called in GHC.Tc.Solver.setImplicationStatus)              should ignore givens even if they are insoluble. +Note [Insoluble Wanteds]+~~~~~~~~~~~~~~~~~~~~~~~~+insolubleWantedCt returns True of a Wanted constraint that definitely+can't be solved.  But not quite all such constraints; see wrinkles.++(IW1) insolubleWantedCt is tuned for application /after/ constraint+   solving i.e. assuming canonicalisation has been done.  That's why+   it looks only for IrredCt; all insoluble constraints are put into+   CIrredCan++(IW2) We only treat it as insoluble if it has an empty rewriter set.  (See Note+   [Wanteds rewrite Wanteds].)  Otherwise #25325 happens: a Wanted constraint A+   that is /not/ insoluble rewrites some other Wanted constraint B, so B has A+   in its rewriter set.  Now B looks insoluble.  The danger is that we'll+   suppress reporting B because of its empty rewriter set; and suppress+   reporting A because there is an insoluble B lying around.  (This suppression+   happens in GHC.Tc.Errors.mkErrorItem.)  Solution: don't treat B as insoluble.++(IW3) If the Wanted arises from a Given (how can that happen?), don't+   treat it as a Wanted insoluble (obviously).++(IW4) If the Wanted came from a  Wanted/Wanted fundep interaction, don't+   treat the constraint as insoluble. See Note [Suppressing confusing errors]+   in GHC.Tc.Errors+ Note [Insoluble holes] ~~~~~~~~~~~~~~~~~~~~~~ Hole constraints that ARE NOT treated as truly insoluble:@@ -2055,9 +2094,6 @@  setCtEvLoc :: CtEvidence -> CtLoc -> CtEvidence setCtEvLoc ctev loc = ctev { ctev_loc = loc }--arisesFromGivens :: Ct -> Bool-arisesFromGivens ct = isGivenCt ct || isGivenLoc (ctLoc ct)  -- | Set the type of CtEvidence. --
GHC/Tc/Types/Evidence.hs view
@@ -7,7 +7,7 @@    -- * HsWrapper   HsWrapper(..),-  (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpVisTyLam,+  (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpForAllCast,   mkWpEvLams, mkWpLet, mkWpFun, mkWpCastN, mkWpCastR, mkWpEta,   collectHsWrapBinders,   idHsWrapper, isIdHsWrapper,@@ -258,20 +258,20 @@ mkWpTyLams :: [TyVar] -> HsWrapper mkWpTyLams ids = mk_co_lam_fn WpTyLam ids --- Construct a type lambda and cast its type--- from `forall tv. res` to `forall tv -> res`.------ (\ @tv -> e )---    `cast` (forall (tv[spec]~[req] :: <*>_N). <res>_R       -- ForAllCo is the evidence that...---              :: (forall tv. res) ~R# (forall tv -> res))   -- invisible and visible foralls are representationally equal+-- mkWpForAllCast [tv{vis}] constructs a cast+--   forall tv. res  ~R#   forall tv{vis} res`.+-- See Note [Required foralls in Core] in GHC.Core.TyCo.Rep ---mkWpVisTyLam :: TyVar -> Type -> HsWrapper-mkWpVisTyLam tv res =-  WpCast (mkForAllCo tv coreTyLamForAllTyFlag Required kind_co body_co)-  <.> WpTyLam tv+-- It's a no-op if all binders are invisible;+-- but in that case we refrain from calling it.+mkWpForAllCast :: [ForAllTyBinder] -> Type -> HsWrapper+mkWpForAllCast bndrs res_ty+  = mkWpCastR (go bndrs)   where-    kind_co = mkNomReflCo (varType tv)-    body_co = mkRepReflCo res+    go []                 = mkRepReflCo res_ty+    go (Bndr tv vis : bs) = mkForAllCo tv coreTyLamForAllTyFlag vis kind_co (go bs)+      where+        kind_co = mkNomReflCo (varType tv)  mkWpEvLams :: [Var] -> HsWrapper mkWpEvLams ids = mk_co_lam_fn WpEvLam ids
GHC/Tc/Types/LclEnv.hs-boot view
@@ -1,3 +1,6 @@ module GHC.Tc.Types.LclEnv where +-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Base ()+ data TcLclEnv
GHC/Tc/Utils/Env.hs view
@@ -28,6 +28,7 @@         tcLookupLocatedClass, tcLookupAxiom,         lookupGlobal, lookupGlobal_maybe,         addTypecheckedBinds,+        failIllegalTyCon, failIllegalTyVal,          -- Local environment         tcExtendKindEnv, tcExtendKindEnvList,@@ -137,6 +138,7 @@ import Control.Monad import GHC.Iface.Errors.Types import GHC.Types.Error+import GHC.Rename.Unbound ( unknownNameSuggestions, WhatLooking(..) )  {- ********************************************************************* *                                                                      *@@ -278,6 +280,7 @@     thing <- tcLookupGlobal name     case thing of         AConLike cl -> return cl+        ATyCon tc   -> failIllegalTyCon WL_Constructor tc         _           -> wrongThingErr WrongThingConLike (AGlobal thing) name  tcLookupRecSelParent :: HsRecUpdParent GhcRn -> TcM RecSelParent@@ -349,6 +352,45 @@ instance MonadThings (IOEnv (Env TcGblEnv TcLclEnv)) where     lookupThing = tcLookupGlobal +-- Illegal term-level use of type things+failIllegalTyCon :: WhatLooking -> TyCon -> TcM a+failIllegalTyVal :: Name -> TcM a+(failIllegalTyCon, failIllegalTyVal) = (fail_tycon, fail_tyvar)+  where+    fail_tycon what_looking tc = do+      gre <- getGlobalRdrEnv+      let nm = tyConName tc+          pprov = case lookupGRE_Name gre nm of+                      Just gre -> nest 2 (pprNameProvenance gre)+                      Nothing  -> empty+          err | isClassTyCon tc = ClassTE+              | otherwise       = TyConTE+      fail_with_msg what_looking dataName nm pprov err++    fail_tyvar nm =+      let pprov = nest 2 (text "bound at" <+> ppr (getSrcLoc nm))+      in fail_with_msg WL_Anything varName nm pprov TyVarTE++    fail_with_msg what_looking whatName nm pprov err = do+      (import_errs, hints) <- get_suggestions what_looking whatName nm+      unit_state <- hsc_units <$> getTopEnv+      let+        -- TODO: unfortunate to have to convert to SDoc here.+        -- This should go away once we refactor ErrInfo.+        hint_msg = vcat $ map ppr hints+        import_err_msg = vcat $ map ppr import_errs+        info = ErrInfo { errInfoContext = pprov, errInfoSupplementary = import_err_msg $$ hint_msg }+      failWithTc $ TcRnMessageWithInfo unit_state (+              mkDetailedMessage info (TcRnIllegalTermLevelUse nm err))++    get_suggestions what_looking ns nm = do+      required_type_arguments <- xoptM LangExt.RequiredTypeArguments+      if required_type_arguments && isVarNameSpace ns+      then return ([], [])  -- See Note [Suppress hints with RequiredTypeArguments]+      else do+        let occ = mkOccNameFS ns (occNameFS (occName nm))+        lcl_env <- getLocalRdrEnv+        unknownNameSuggestions lcl_env what_looking (mkRdrUnqual occ) {- ************************************************************************ *                                                                      *@@ -888,7 +930,7 @@  {- Note [Extended defaults]-~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~ In interactive mode (or with -XExtendedDefaultRules) we add () as the first type we try when defaulting.  This has very little real impact, except in the following case. Consider:
GHC/Tc/Utils/Instantiate.hs view
@@ -11,7 +11,7 @@ -}  module GHC.Tc.Utils.Instantiate (-     topSkolemise,+     topSkolemise, skolemiseRequired,      topInstantiate,      instantiateSigma,      instCall, instDFunType, instStupidTheta, instTyVarsWith,@@ -75,7 +75,7 @@ import GHC.Tc.Zonk.Monad ( ZonkM )  import GHC.Types.Id.Make( mkDictFunId )-import GHC.Types.Basic ( TypeOrKind(..), Arity )+import GHC.Types.Basic ( TypeOrKind(..), Arity, VisArity ) import GHC.Types.Error import GHC.Types.SourceText import GHC.Types.SrcLoc as SrcLoc@@ -145,22 +145,16 @@ Note [Skolemisation] ~~~~~~~~~~~~~~~~~~~~ topSkolemise decomposes and skolemises a type, returning a type-with no top level foralls or (=>)+with no top level foralls or (=>).  Examples:    topSkolemise (forall a. Ord a => a -> a)     =  ( wp, [a], [d:Ord a], a->a )-    where wp = /\a. \(d:Ord a). <hole> a d--  topSkolemise  (forall a. Ord a => forall b. Eq b => a->b->b)-    =  ( wp, [a,b], [d1:Ord a,d2:Eq b], a->b->b )-    where wp = /\a.\(d1:Ord a)./\b.\(d2:Ord b). <hole> a d1 b d2+    where+      wp = /\a. \(d:Ord a). <hole> a d -This second example is the reason for the recursive 'go' function in-topSkolemise: we remove successive layers of foralls and (=>).  This-is really just an optimisation; see wrinkle (SK1) in GHC.Tc.Utils.Unify-Note [Skolemisation overview].+For nested foralls, see Note [Skolemisation en-bloc]  In general,   if      topSkolemise ty = (wrap, tvs, evs, rho)@@ -168,6 +162,41 @@   then    wrap e :: ty     and   'wrap' binds {tvs, evs} +Note [Skolemisation en-bloc]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider this case:++  topSkolemise  (forall a. Ord a => forall b. Eq b => a->b->b)++We /could/ return just+  (wp, [a], [d:Ord a, forall b. Eq b => a -> b -> b)++But in fact we skolemise "en-bloc", looping around (in `topSkolemise` for+example) to skolemise the (forall b. Eq b =>).  So in fact++  topSkolemise  (forall a. Ord a => forall b. Eq b => a->b->b)+    =  ( wp, [a,b], [d1:Ord a,d2:Eq b], a->b->b )+    where+      wp = /\a.\(d1:Ord a)./\b.\(d2:Ord b). <hole> a d1 b d2++This applies regardless of DeepSubsumption.++Why do we do this "en-bloc" loopy thing?  It is /nearly/ just an optimisation.+But not quite!  At the call site of `topSkolemise` (and its cousins) we+use `checkConstraints` to gather constraints and build an implication+constraint.   So skolemising just one level at a time would lead to nested+implication constraints. That is a bit less efficient, but there is /also/ a small+user-visible effect: see Note [Let-bound skolems] in GHC.Tc.Solver.InertSet.+Specifically, consider++   forall a. Eq a => forall b. (a ~ [b]) => blah++If we skolemise en-bloc, the equality (a~[b]) is like a let-binding and we+don't treat it like a GADT pattern match, limiting unification. With nested+implications, the inner one would be treated as having-given-equalities.++This is also relevant when Required foralls are involved; see #24810, and+the loop in `skolemiseRequired`. -}  topSkolemise :: SkolemInfo@@ -182,7 +211,7 @@   where     init_subst = mkEmptySubst (mkInScopeSet (tyCoVarsOfType ty)) -    -- Why recursive?  See Note [Skolemisation]+    -- Why recursive?  See Note [Skolemisation en-bloc]     go subst wrap tv_prs ev_vars ty       | (bndrs, theta, inner_ty) <- tcSplitSigmaTyBndrs ty       , let tvs = binderVars bndrs@@ -200,6 +229,51 @@        | otherwise       = return (wrap, tv_prs, ev_vars, substTy subst ty)+        -- substTy is a quick no-op on an empty substitution++skolemiseRequired :: SkolemInfo -> VisArity -> TcSigmaType+                  -> TcM (VisArity, HsWrapper, [Name], [ForAllTyBinder], [EvVar], TcRhoType)+-- Skolemise up to N required (visible) binders,+--    plus any invisible ones "in the way",+--    /and/ any trailing invisible ones.+-- So the result has no top-level invisible quantifiers.+-- Return the depleted arity.+skolemiseRequired skolem_info n_req sigma+  = go n_req init_subst idHsWrapper [] [] [] sigma+  where+    init_subst = mkEmptySubst (mkInScopeSet (tyCoVarsOfType sigma))++    -- Why recursive?  See Note [Skolemisation en-bloc]+    go n_req subst wrap acc_nms acc_bndrs ev_vars ty+      | (n_req', bndrs, inner_ty) <- tcSplitForAllTyVarsReqTVBindersN n_req ty+      , not (null bndrs)+      = do { (subst', bndrs1) <- tcInstSkolTyVarBndrsX skolem_info subst bndrs+           ; let tvs1 = binderVars bndrs1+                 -- fix_up_vis: see Note [Required foralls in Core]+                 --             in GHC.Core.TyCo.Rep+                 fix_up_vis | n_req == n_req'+                            = idHsWrapper+                            | otherwise+                            = mkWpForAllCast bndrs1 (substTy subst' inner_ty)+           ; go n_req' subst'+                (wrap <.> fix_up_vis <.> mkWpTyLams tvs1)+                (acc_nms   ++ map (tyVarName . binderVar) bndrs)+                (acc_bndrs ++ bndrs1)+                ev_vars+                inner_ty }++      | (theta, inner_ty) <- tcSplitPhiTy ty+      , not (null theta)+      = do { ev_vars1 <- newEvVars (substTheta subst theta)+           ; go n_req subst+                (wrap <.> mkWpEvLams ev_vars1)+                acc_nms+                acc_bndrs+                (ev_vars ++ ev_vars1)+                inner_ty }++      | otherwise+      = return (n_req, wrap, acc_nms, acc_bndrs, ev_vars, substTy subst ty)         -- substTy is a quick no-op on an empty substitution  topInstantiate :: CtOrigin -> TcSigmaType -> TcM (HsWrapper, TcRhoType)
GHC/Tc/Utils/Monad.hs view
@@ -142,7 +142,7 @@   getCCIndexM, getCCIndexTcM,    -- * Zonking-  liftZonkM,+  liftZonkM, newZonkAnyType,    -- * Types etc.   module GHC.Tc.Types,@@ -153,6 +153,7 @@   import GHC.Builtin.Names+import GHC.Builtin.Types( zonkAnyTyCon )  import GHC.Tc.Errors.Types import GHC.Tc.Types     -- Re-export all@@ -175,6 +176,7 @@ import GHC.Core.Multiplicity import GHC.Core.InstEnv import GHC.Core.FamInstEnv+import GHC.Core.Type( mkNumLitTy )  import GHC.Driver.Env import GHC.Driver.Session@@ -254,6 +256,7 @@         infer_var    <- newIORef True ;         infer_reasons_var <- newIORef emptyMessages ;         dfun_n_var   <- newIORef emptyOccSet ;+        zany_n_var   <- newIORef 0 ;         let { type_env_var = hsc_type_env_vars hsc_env };          dependent_files_var <- newIORef [] ;@@ -345,6 +348,7 @@                 tcg_patsyns        = [],                 tcg_merged         = [],                 tcg_dfun_n         = dfun_n_var,+                tcg_zany_n         = zany_n_var,                 tcg_keep           = keep_var,                 tcg_hdr_info        = (Nothing,Nothing),                 tcg_hpc            = False,@@ -1801,6 +1805,18 @@      ; let occ = fn set      ; writeTcRef dfun_n_var (extendOccSet set occ)      ; return occ }++newZonkAnyType :: Kind -> TcM Type+-- Return a type (ZonkAny @k n), where n is fresh+-- Recall  ZonkAny :: forall k. Natural -> k+-- See Note [Any types] in GHC.Builtin.Types, wrinkle (Any4)+newZonkAnyType kind+  = do { env <- getGblEnv+       ; let zany_n_var = tcg_zany_n env+       ; i <- readTcRef zany_n_var+       ; let !i2 = i+1+       ; writeTcRef zany_n_var i2+       ; return (mkTyConApp zonkAnyTyCon [kind, mkNumLitTy i]) }  getConstraintVar :: TcM (TcRef WantedConstraints) getConstraintVar = do { env <- getLclEnv; return (tcl_lie env) }
GHC/Tc/Utils/TcType.hs view
@@ -67,7 +67,7 @@   --------------------------------   -- Splitters   getTyVar, getTyVar_maybe, getCastedTyVar_maybe,-  tcSplitForAllTyVarBinder_maybe,+  tcSplitForAllTyVarBinder_maybe, tcSplitForAllTyVarsReqTVBindersN,   tcSplitForAllTyVars, tcSplitForAllInvisTyVars, tcSplitSomeForAllTyVars,   tcSplitForAllReqTVBinders, tcSplitForAllInvisTVBinders,   tcSplitPiTys, tcSplitPiTy_maybe, tcSplitForAllTyVarBinders,@@ -95,7 +95,7 @@   -- Re-exported from GHC.Core.TyCo.Compare   -- mainly just for back-compat reasons   eqType, eqTypes, nonDetCmpType, nonDetCmpTypes, eqTypeX,-  pickyEqType, tcEqType, tcEqKind, tcEqTypeNoKindCheck, tcEqTypeVis,+  pickyEqType, tcEqType, tcEqKind, tcEqTypeNoKindCheck, mayLookIdentical,   tcEqTyConApps, eqForAllVis, eqVarBndrs,    ---------------------------------@@ -888,7 +888,8 @@ -- to @C@, whereas @F Bool@ is paired with 'False' since it appears an a -- /visible/ argument to @C@. ----- See also @Note [Kind arguments in error messages]@ in "GHC.Tc.Errors".+-- See also Note [Showing invisible bits of types in error messages]+-- in "GHC.Tc.Errors.Ppr". tcTyFamInstsAndVis :: Type -> [(Bool, TyCon, [Type])] tcTyFamInstsAndVis = tcTyFamInstsAndVisX False @@ -1405,6 +1406,18 @@       | argf_pred argf                             = split ty ty (tv:tvs)     split orig_ty ty tvs | Just ty' <- coreView ty = split orig_ty ty' tvs     split orig_ty _                            tvs = (reverse tvs, orig_ty)++tcSplitForAllTyVarsReqTVBindersN :: Arity -> Type -> (Arity, [ForAllTyBinder], Type)+-- Split off at most N /required/ (aka visible) binders, plus any invisible ones+-- in the way, /and/ any trailing invisible ones+tcSplitForAllTyVarsReqTVBindersN n_req ty+  = split n_req ty ty []+  where+    split n_req _orig_ty (ForAllTy b@(Bndr _ argf) ty) bs+      | isVisibleForAllTyFlag argf, n_req > 0           = split (n_req - 1) ty ty (b:bs)+      | otherwise                                       = split n_req       ty ty (b:bs)+    split n_req orig_ty ty bs | Just ty' <- coreView ty = split n_req orig_ty ty' bs+    split n_req orig_ty _ty bs                          = (n_req, reverse bs, orig_ty)  -- | Like 'tcSplitForAllTyVars', but only splits 'ForAllTy's with 'Required' type -- variable binders. All split tyvars are annotated with '()'.
GHC/Tc/Utils/Unify.hs view
@@ -348,9 +348,9 @@       The implication constraint will look like           forall a b. (Eq a, Ord b) => <constraints>       See the loop in GHC.Tc.Utils.Instantiate.topSkolemise.-      This is just an optimisation; it would be fine to generate one implication-      constraint for each nesting layer.+      and Note [Skolemisation en-bloc] in that module + Some examples:  *     f :: forall a b. blah@@ -775,29 +775,40 @@        ; return (mkWpCastN co, result) }  matchExpectedFunTys herald ctx arity (Check top_ty) thing_inside-  = check 0 [] top_ty+  = check arity [] top_ty   where     check :: VisArity -> [ExpPatType] -> TcSigmaType -> TcM (HsWrapper, a)     -- `check` is called only in the Check{} case     -- It collects rev_pat_tys in reversed order-    -- n_so_far is the number of /visible/ arguments seen so far:-    --     i.e. length (filterOut isExpForAllPatTyInvis rev_pat_tys)+    -- n_req is the number of /visible/ arguments still needed -    -- Do shallow skolemisation if there are top-level invisible quantifiers-    check n_so_far rev_pat_tys ty-      | isSigmaTy ty  -- Type has invisible quantifiers-      = do { (wrap_gen, (wrap_res, result))-                 <- tcSkolemiseGeneral Shallow ctx top_ty ty $ \tv_bndrs ty' ->-                    let rev_pat_tys' = reverse (map (mkInvisExpPatType . snd) tv_bndrs)-                                       ++ rev_pat_tys-                    in check n_so_far rev_pat_tys' ty'-           ; return (wrap_gen <.> wrap_res, result) }+    ----------------------------+    -- Skolemise quantifiers, both visible (up to n_req) and invisible+    -- See Note [Visible type application and abstraction] in GHC.Tc.Gen.App+    check n_req rev_pat_tys ty+      | isSigmaTy ty                     -- An invisible quantifier at the top+        || (n_req > 0 && isForAllTy ty)  -- A visible quantifier at top, and we need it+      = do { rec { (n_req', wrap_gen, tv_nms, bndrs, given, inner_ty) <- skolemiseRequired skol_info n_req ty+                 ; let sig_skol = SigSkol ctx top_ty (tv_nms `zip` skol_tvs)+                       skol_tvs = binderVars bndrs+                 ; skol_info <- mkSkolemInfo sig_skol }+             -- rec {..}: see Note [Keeping SkolemInfo inside a SkolemTv]+             --           in GHC.Tc.Utils.TcType+           ; (ev_binds, (wrap_res, result))+                  <- checkConstraints (getSkolemInfo skol_info) skol_tvs given $+                     check n_req'+                           (reverse (map ExpForAllPatTy bndrs) ++ rev_pat_tys)+                           inner_ty+           ; assertPpr (not (null bndrs && null given)) (ppr ty) $+                       -- The guard ensures that we made some progress+             return (wrap_gen <.> mkWpLet ev_binds <.> wrap_res, result) } -    -- (n_so_far == arity): no more args-    -- rho_ty has no top-level quantifiers-    -- If there is deep subsumption, do deep skolemisation-    check n_so_far rev_pat_tys rho_ty-      | n_so_far == arity+    ----------------------------+    -- Base case: (n_req == 0): no more args+    --    The earlier skolemisation ensurs that rho_ty has no top-level invisible quantifiers+    --    If there is deep subsumption, do deep skolemisation now+    check n_req rev_pat_tys rho_ty+      | n_req == 0       = do { let pat_tys = reverse rev_pat_tys            ; ds_flag <- getDeepSubsumptionFlag            ; case ds_flag of@@ -808,53 +819,35 @@                           -- They do not line up with binders in the Match                           thing_inside pat_tys (mkCheckExpType rho_ty) } -    -- NOW do coreView.  We didn't do it before, so that we do not unnecessarily-    -- unwrap a synonym in the returned rho_ty-    check n_so_far rev_pat_tys ty-      | Just ty' <- coreView ty = check n_so_far rev_pat_tys ty'--    -- Decompose /visible/ (forall a -> blah), to give an ExpForAllPat-    -- NB: invisible binders are handled by tcSplitSigmaTy/tcTopSkolemise above-    -- NB: visible foralls "count" for the Arity argument; they correspond-    --     to syntactically visible patterns in the source program-    -- See Note [Visible type application and abstraction] in GHC.Tc.Gen.App-    check n_so_far rev_pat_tys ty-      | Just (Bndr tv vis, body_ty) <- splitForAllForAllTyBinder_maybe ty-      = assertPpr (isVisibleForAllTyFlag vis) (ppr ty) $-        -- isSigmaTy case above has dealt with /invisible/ quantifiers,-        -- so this one must be /visible/ (= Required)-        do { let init_subst = mkEmptySubst (mkInScopeSet (tyCoVarsOfType ty))-             -- rec {..}: see Note [Keeping SkolemInfo inside a SkolemTv]-             --           in GHC.Tc.Utils.TcType-           ; rec { (subst', [tv']) <- tcInstSkolTyVarsX skol_info init_subst [tv]-                 ; let tv_prs = [(tyVarName tv, tv')]-                 ; skol_info <- mkSkolemInfo (SigSkol ctx top_ty tv_prs) }-           ; let body_ty' = substTy subst' body_ty-                 pat_ty   = ExpForAllPatTy (mkForAllTyBinder Required tv')-           ; (ev_binds, (wrap_res, result)) <- checkConstraints (getSkolemInfo skol_info) [tv'] [] $-                                               check (n_so_far+1) (pat_ty : rev_pat_tys) body_ty'-           ; let wrap_gen = mkWpVisTyLam tv' body_ty' <.> mkWpLet ev_binds-           ; return (wrap_gen <.> wrap_res, result) }--    check n_so_far rev_pat_tys (FunTy { ft_af = af, ft_mult = mult-                                      , ft_arg = arg_ty, ft_res = res_ty })+    ----------------------------+    -- Function types+    check n_req rev_pat_tys (FunTy { ft_af = af, ft_mult = mult+                                   , ft_arg = arg_ty, ft_res = res_ty })       = assert (isVisibleFunArg af) $-        do { let arg_pos = n_so_far + 1+        do { let arg_pos = arity - n_req + 1   -- 1 for the first argument etc            ; (arg_co, arg_ty) <- hasFixedRuntimeRep (FRRExpectedFunTy herald arg_pos) arg_ty-           ; (wrap_res, result) <- check arg_pos+           ; (wrap_res, result) <- check (n_req - 1)                                          (mkCheckExpFunPatTy (Scaled mult arg_ty) : rev_pat_tys)                                          res_ty            ; let wrap_arg = mkWpCastN arg_co                  fun_wrap = mkWpFun wrap_arg wrap_res (Scaled mult arg_ty) res_ty            ; return (fun_wrap, result) } -    check n_so_far rev_pat_tys ty@(TyVarTy tv)+    ----------------------------+    -- Type variables+    check n_req rev_pat_tys ty@(TyVarTy tv)       | isMetaTyVar tv       = do { cts <- readMetaTyVar tv            ; case cts of-               Indirect ty' -> check n_so_far rev_pat_tys ty'-               Flexi        -> defer n_so_far rev_pat_tys ty }+               Indirect ty' -> check n_req rev_pat_tys ty'+               Flexi        -> defer n_req rev_pat_tys ty } +    ----------------------------+    -- NOW do coreView.  We didn't do it before, so that we do not unnecessarily+    -- unwrap a synonym in the returned rho_ty+    check n_req rev_pat_tys ty+      | Just ty' <- coreView ty = check n_req rev_pat_tys ty'+        -- In all other cases we bale out into ordinary unification        -- However unlike the meta-tyvar case, we are sure that the        -- number of arguments doesn't match arity of the original@@ -870,14 +863,14 @@        --        -- But in that case we add specialized type into error context        -- anyway, because it may be useful. See also #9605.-    check n_so_far rev_pat_tys res_ty+    check n_req rev_pat_tys res_ty       = addErrCtxtM (mkFunTysMsg herald (arity, top_ty))  $-        defer n_so_far rev_pat_tys res_ty+        defer n_req rev_pat_tys res_ty      ------------     defer :: VisArity -> [ExpPatType] -> TcRhoType -> TcM (HsWrapper, a)-    defer n_so_far rev_pat_tys fun_ty-      = do { more_arg_tys <- mapM (new_check_arg_ty herald) [n_so_far + 1 .. arity]+    defer n_req rev_pat_tys fun_ty+      = do { more_arg_tys <- mapM (new_check_arg_ty herald) [arity - n_req + 1 .. arity]            ; let all_pats = reverse rev_pat_tys ++ map mkCheckExpFunPatTy more_arg_tys            ; res_ty <- newOpenFlexiTyVarTy            ; result <- thing_inside all_pats (mkCheckExpType res_ty)@@ -892,7 +885,7 @@        ; return (mkScaled mult inf_hole) }  new_check_arg_ty :: ExpectedFunTyOrigin -> Int -> TcM (Scaled TcType)-new_check_arg_ty herald arg_pos -- Position for error messages only+new_check_arg_ty herald arg_pos -- Position for error messages only, 1 for first arg   = do { mult   <- newFlexiTyVarTy multiplicityTy        ; arg_ty <- newOpenFlexiFRRTyVarTy (FRRExpectedFunTy herald arg_pos)        ; return (mkScaled mult arg_ty) }@@ -2367,7 +2360,14 @@     do { def_eqs <- readTcRef def_eq_ref  -- Capture current state of def_eqs         -- Attempt to unify kinds-       ; co_k <- uType (mkKindEnv env ty1 ty2) (typeKind ty2) (tyVarKind tv1)+       -- When doing so, be careful to preserve orientation;+       --    see Note [Kind Equality Orientation] in GHC.Tc.Solver.Equality+       --    and wrinkle (W2) in Note [Fundeps with instances, and equality orientation]+       --        in GHC.Tc.Solver.Dict+       -- Failing to preserve orientation led to #25597.+       ; let kind_env = unSwap swapped (mkKindEnv env) ty1 ty2+       ; co_k <- unSwap swapped (uType kind_env) (tyVarKind tv1) (typeKind ty2)+        ; traceTc "uUnfilledVar2 ok" $          vcat [ ppr tv1 <+> dcolon <+> ppr (tyVarKind tv1)               , ppr ty2 <+> dcolon <+> ppr (typeKind  ty2)
GHC/Tc/Zonk/Type.hs view
@@ -54,7 +54,7 @@ import GHC.Tc.TyCl.Build ( TcMethInfo, MethInfo ) import GHC.Tc.Utils.Env ( tcLookupGlobalOnly ) import GHC.Tc.Utils.TcType-import GHC.Tc.Utils.Monad ( setSrcSpanA, liftZonkM, traceTc, addErr )+import GHC.Tc.Utils.Monad ( newZonkAnyType, setSrcSpanA, liftZonkM, traceTc, addErr ) import GHC.Tc.Types.Constraint import GHC.Tc.Types.Evidence import GHC.Tc.Errors.Types@@ -468,8 +468,9 @@            -> do { addErr $ TcRnZonkerMessage (ZonkerCannotDefaultConcrete origin)                  ; return (anyTypeOfKind zonked_kind) }            | otherwise-           -> do { traceTc "Defaulting flexi tyvar to Any:" (pprTyVar tv)-                 ; return (anyTypeOfKind zonked_kind) }+           -> do { traceTc "Defaulting flexi tyvar to ZonkAny:" (pprTyVar tv)+                   -- See Note [Any types] in GHC.Builtin.Types, esp wrinkle (Any4)+                 ; newZonkAnyType zonked_kind }           RuntimeUnkFlexi            -> do { traceTc "Defaulting flexi tyvar to RuntimeUnk:" (pprTyVar tv)
GHC/ThToHs.hs view
@@ -1485,7 +1485,8 @@                             ; return                                    $ ListPat noAnn ps'} cvtp (SigP p t)        = do { p' <- cvtPat p; t' <- cvtType t-                            ; return $ SigPat noAnn p' (mkHsPatSigType noAnn t') }+                            ; let pp = parenthesizePat sigPrec p'+                            ; return $ SigPat noAnn pp (mkHsPatSigType noAnn t') } cvtp (ViewP e p)       = do { e' <- cvtl e; p' <- cvtPat p                             ; return $ ViewPat noAnn e' p'} cvtp (TypeP t)         = do { t' <- cvtType t
− GHC/Types/BreakInfo.hs
@@ -1,12 +0,0 @@--- | A module for the BreakInfo type. Used by both the GHC.Runtime.Eval and--- GHC.Runtime.Interpreter hierarchy, so put here to have a less deep module--- dependency tree-module GHC.Types.BreakInfo (BreakInfo(..)) where--import GHC.Prelude-import GHC.Unit.Module--data BreakInfo = BreakInfo-  { breakInfo_module :: Module-  , breakInfo_number :: Int-  }
+ GHC/Types/Breakpoint.hs view
@@ -0,0 +1,53 @@+-- | Breakpoint related types+module GHC.Types.Breakpoint+  ( BreakpointId (..)+  , InternalBreakpointId (..)+  , toBreakpointId+  )+where++import GHC.Prelude+import GHC.Unit.Module++-- | Breakpoint identifier.+--+-- See Note [Breakpoint identifiers]+data BreakpointId = BreakpointId+  { bi_tick_mod   :: !Module  -- ^ Breakpoint tick module+  , bi_tick_index :: !Int     -- ^ Breakpoint tick index+  }++-- | Internal breakpoint identifier+--+-- See Note [Breakpoint identifiers]+data InternalBreakpointId = InternalBreakpointId+  { ibi_tick_mod   :: !Module  -- ^ Breakpoint tick module+  , ibi_tick_index :: !Int     -- ^ Breakpoint tick index+  , ibi_info_mod   :: !Module  -- ^ Breakpoint info module+  , ibi_info_index :: !Int     -- ^ Breakpoint info index+  }++toBreakpointId :: InternalBreakpointId -> BreakpointId+toBreakpointId ibi = BreakpointId+  { bi_tick_mod   = ibi_tick_mod ibi+  , bi_tick_index = ibi_tick_index ibi+  }+++-- Note [Breakpoint identifiers]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+--+-- Before optimization a breakpoint is identified uniquely with a tick module+-- and a tick index. See BreakpointId. A tick module contains an array, indexed+-- with the tick indexes, which indicates breakpoint status.+--+-- When we generate ByteCode, we collect information for every breakpoint at+-- their *occurrence sites* (see CgBreakInfo in GHC.ByteCode.Types) and these info+-- are stored in the ModIface of the occurrence module. Because of inlining, we+-- can't reuse the tick index to uniquely identify an occurrence; because of+-- cross-module inlining, we can't assume that the occurrence module is the same+-- as the tick module (#24712).+--+-- So every breakpoint occurrence gets assigned a module-unique *info index* and+-- we store it alongside the occurrence module (*info module*) in the+-- InternalBreakpointId datatype.
GHC/Types/Demand.hs view
@@ -37,7 +37,7 @@     -- *** Demands used in PrimOp signatures     lazyApply1Dmd, lazyApply2Dmd, strictOnceApply1Dmd, strictManyApply1Dmd,     -- ** Other @Demand@ operations-    oneifyCard, oneifyDmd, strictifyDmd, strictifyDictDmd, lazifyDmd,+    oneifyCard, oneifyDmd, strictifyDmd, strictifyDictDmd, lazifyDmd, floatifyDmd,     peelCallDmd, peelManyCalls, mkCalledOnceDmd, mkCalledOnceDmds,     mkWorkerDemand, subDemandIfEvaluated,     -- ** Extracting one-shot information@@ -607,22 +607,22 @@ -- -- Examples (using Note [Demand notation]): -----   * 'seq' puts demand @1A@ on its first argument: It evaluates the argument---     strictly (@1@), but not any deeper (@A@).---   * 'fst' puts demand @1P(1L,A)@ on its argument: It evaluates the argument+--   * 'seq' puts demand `1A` on its first argument: It evaluates the argument+--     strictly (`1`), but not any deeper (`A`).+--   * 'fst' puts demand `1P(1L,A)` on its argument: It evaluates the argument --     pair strictly and the first component strictly, but no nested info---     beyond that (@L@). Its second argument is not used at all.---   * '$' puts demand @1C(1,L)@ on its first argument: It calls (@C@) the---     argument function with one argument, exactly once (@1@). No info---     on how the result of that call is evaluated (@L@).---   * 'maybe' puts demand @MC(M,L)@ on its second argument: It evaluates+--     beyond that (`L`). Its second argument is not used at all.+--   * '$' puts demand `1C(1,L)` on its first argument: It calls (`C`) the+--     argument function with one argument, exactly once (`1`). No info+--     on how the result of that call is evaluated (`L`).+--   * 'maybe' puts demand `MC(M,L)` on its second argument: It evaluates --     the argument function at most once ((M)aybe) and calls it once when --     it is evaluated.---   * @fst p + fst p@ puts demand @SP(SL,A)@ on @p@: It's @1P(1L,A)@---     multiplied by two, so we get @S@ (used at least once, possibly multiple+--   * `fst p + fst p` puts demand `SP(SL,A)` on `p`: It's `1P(1L,A)`+--     multiplied by two, so we get `S` (used at least once, possibly multiple --     times). ----- This data type is quite similar to @'Scaled' 'SubDemand'@, but it's scaled+-- This data type is quite similar to `'Scaled' 'SubDemand'`, but it's scaled -- by 'Card', which is an /interval/ on 'Multiplicity', the upper bound of -- which could be used to infer uniqueness types. Also we treat 'AbsDmd' and -- 'BotDmd' specially, as the concept of a 'SubDemand' doesn't apply when there@@ -1012,6 +1012,11 @@ lazifyDmd :: Demand -> Demand lazifyDmd = multDmd C_01 +-- | Adjust the demand on a binding that may float outwards+-- See Note [Floatifying demand info when floating]+floatifyDmd :: Demand -> Demand+floatifyDmd = multDmd C_0N+ -- | Wraps the 'SubDemand' with a one-shot call demand: @d@ -> @C(1,d)@. mkCalledOnceDmd :: SubDemand -> SubDemand mkCalledOnceDmd sd = mkCall C_11 sd@@ -2634,7 +2639,12 @@ but it's always clear from context which "overload" is meant. It's like return-type inference of e.g. 'read'. -Examples are in the haddock for 'Demand'.+Examples are in the haddock for 'Demand'.  Here are some more:+   SA                 Strict, but does not look at subcomponents (`seq`)+   SP(L,L)            Strict boxed pair, components lazy+   S!P(L,L)           Strict unboxed pair, components lazy+   LP(SA,SA)          Lazy pair, but if it is evaluated will evaluated its components+   LC(1C(L))          Lazy, but if called will apply the result exactly once  This is the syntax for demand signatures: 
GHC/Types/Id.hs view
@@ -54,7 +54,7 @@         setIdExported, setIdNotExported,         globaliseId, localiseId,         setIdInfo, lazySetIdInfo, modifyIdInfo, maybeModifyIdInfo,-        zapLamIdInfo, zapIdDemandInfo, zapIdUsageInfo, zapIdUsageEnvInfo,+        zapLamIdInfo, floatifyIdDemandInfo, zapIdUsageInfo, zapIdUsageEnvInfo,         zapIdUsedOnceInfo, zapIdTailCallInfo,         zapFragileIdInfo, zapIdDmdSig, zapStableUnfolding,         transferPolyIdInfo, scaleIdBy, scaleVarBy,@@ -296,26 +296,28 @@ mkGlobalId = Var.mkGlobalVar  -- | Make a global 'Id' without any extra information at all-mkVanillaGlobal :: Name -> Type -> Id+mkVanillaGlobal :: HasDebugCallStack => Name -> Type -> Id mkVanillaGlobal name ty = mkVanillaGlobalWithInfo name ty vanillaIdInfo  -- | Make a global 'Id' with no global information but some generic 'IdInfo'-mkVanillaGlobalWithInfo :: Name -> Type -> IdInfo -> Id-mkVanillaGlobalWithInfo = mkGlobalId VanillaId-+mkVanillaGlobalWithInfo :: HasDebugCallStack => Name -> Type -> IdInfo -> Id+mkVanillaGlobalWithInfo nm =+  assertPpr (not $ isFieldNameSpace $ nameNameSpace nm)+    (text "mkVanillaGlobalWithInfo called on record field:" <+> ppr nm) $+    mkGlobalId VanillaId nm  -- | For an explanation of global vs. local 'Id's, see "GHC.Types.Var#globalvslocal" mkLocalId :: HasDebugCallStack => Name -> Mult -> Type -> Id mkLocalId name w ty = mkLocalIdWithInfo name w (assert (not (isCoVarType ty)) ty) vanillaIdInfo  -- | Make a local CoVar-mkLocalCoVar :: Name -> Type -> CoVar+mkLocalCoVar :: HasDebugCallStack => Name -> Type -> CoVar mkLocalCoVar name ty   = assert (isCoVarType ty) $     Var.mkLocalVar CoVarId name ManyTy ty vanillaIdInfo  -- | Like 'mkLocalId', but checks the type to see if it should make a covar-mkLocalIdOrCoVar :: Name -> Mult -> Type -> Id+mkLocalIdOrCoVar :: HasDebugCallStack => Name -> Mult -> Type -> Id mkLocalIdOrCoVar name w ty   -- We should assert (eqType w Many) in the isCoVarType case.   -- However, currently this assertion does not hold.@@ -339,7 +341,10 @@         -- Note [Free type variables]  mkExportedVanillaId :: Name -> Type -> Id-mkExportedVanillaId name ty = Var.mkExportedLocalVar VanillaId name ty vanillaIdInfo+mkExportedVanillaId name ty =+  assertPpr (not $ isFieldNameSpace $ nameNameSpace name)+    (text "mkExportedVanillaId called on record field:" <+> ppr name) $+    Var.mkExportedLocalVar VanillaId name ty vanillaIdInfo         -- Note [Free type variables]  @@ -958,12 +963,11 @@ updOneShotInfo :: Id -> OneShotInfo -> Id -- Combine the info in the Id with new info updOneShotInfo id one_shot-  | do_upd    = setIdOneShotInfo id one_shot-  | otherwise = id-  where-    do_upd = case (idOneShotInfo id, one_shot) of-                (NoOneShotInfo, _) -> True-                (OneShotLam,    _) -> False+  | OneShotLam <- one_shot+  , NoOneShotInfo <- idOneShotInfo id+  = setIdOneShotInfo id OneShotLam+  | otherwise+  = id  -- The OneShotLambda functions simply fiddle with the IdInfo flag -- But watch out: this may change the type of something else@@ -980,8 +984,9 @@ zapFragileIdInfo :: Id -> Id zapFragileIdInfo = zapInfo zapFragileInfo -zapIdDemandInfo :: Id -> Id-zapIdDemandInfo = zapInfo zapDemandInfo+floatifyIdDemandInfo :: Id -> Id+-- See Note [Floatifying demand info when floating] in GHC.Core.Opt.SetLevels+floatifyIdDemandInfo = zapInfo floatifyDemandInfo  zapIdUsageInfo :: Id -> Id zapIdUsageInfo = zapInfo zapUsageInfo
GHC/Types/Id.hs-boot view
@@ -1,6 +1,5 @@ module GHC.Types.Id where -import GHC.Prelude () import {-# SOURCE #-} GHC.Types.Name import {-# SOURCE #-} GHC.Types.Var 
GHC/Types/Id/Info.hs view
@@ -35,7 +35,8 @@          -- ** Zapping various forms of Info         zapLamInfo, zapFragileInfo,-        zapDemandInfo, zapUsageInfo, zapUsageEnvInfo, zapUsedOnceInfo,+        lazifyDemandInfo, floatifyDemandInfo,+        zapUsageInfo, zapUsageEnvInfo, zapUsedOnceInfo,         zapTailCallInfo, zapCallArityInfo, trimUnfolding,          -- ** The ArityInfo type@@ -855,11 +856,21 @@      is_safe_dmd dmd = not (isStrUsedDmd dmd) --- | Remove all demand info on the 'IdInfo'-zapDemandInfo :: IdInfo -> Maybe IdInfo-zapDemandInfo info = Just (info {demandInfo = topDmd})+-- | Lazify (remove the top-level demand, only) the demand in `IdInfo`+-- Keep nested demands; see Note [Floatifying demand info when floating]+-- in GHC.Core.Opt.SetLevels+lazifyDemandInfo :: IdInfo -> Maybe IdInfo+lazifyDemandInfo info@(IdInfo { demandInfo = dmd })+  = Just (info {demandInfo = lazifyDmd dmd }) --- | Remove usage (but not strictness) info on the 'IdInfo'+-- | Floatify the demand in `IdInfo`+-- But keep /nested/ demands; see Note [Floatifying demand info when floating]+-- in GHC.Core.Opt.SetLevels+floatifyDemandInfo :: IdInfo -> Maybe IdInfo+floatifyDemandInfo info@(IdInfo { demandInfo = dmd })+  = Just (info {demandInfo = floatifyDmd dmd })++-- | Remove usage (but not strictness) info on the `IdInfo` zapUsageInfo :: IdInfo -> Maybe IdInfo zapUsageInfo info = Just (info {demandInfo = zapUsageDemand (demandInfo info)}) 
GHC/Types/Id/Make.hs view
@@ -902,15 +902,25 @@     -- needs a wrapper. This wrapper is injected into the program later in the     -- CoreTidy pass. See Note [Injecting implicit bindings] in GHC.Iface.Tidy,     -- along with the accompanying implementation in getTyConImplicitBinds.-    wrapper_reqd =-        (not new_tycon+    wrapper_reqd+      | isTypeDataTyCon tycon+        -- `type data` declarations never have data-constructor wrappers+        -- Their data constructors only live at the type level, in the+        -- form of PromotedDataCon, and therefore do not need wrappers.+        -- See wrinkle (W0) in Note [Type data declarations] in GHC.Rename.Module.+      = False++      | otherwise+      = (not new_tycon                      -- (Most) newtypes have only a worker, with the exception                      -- of some newtypes written with GADT syntax.                      -- See dataConUserTyVarsNeedWrapper below.          && (any isBanged (ev_ibangs ++ arg_ibangs)))                      -- Some forcing/unboxing (includes eq_spec)+       || isFamInstTyCon tycon -- Cast result-      || (dataConUserTyVarsNeedWrapper data_con++      || dataConUserTyVarsNeedWrapper data_con                      -- If the data type was written with GADT syntax and                      -- orders the type variables differently from what the                      -- worker expects, it needs a data con wrapper to reorder@@ -919,19 +929,7 @@                      --                      -- NB: All GADTs return true from this function, but there                      -- is one exception that we must check below.-         && not (isTypeDataTyCon tycon))-                     -- An exception to this rule is `type data` declarations.-                     -- Their data constructors only live at the type level and-                     -- therefore do not need wrappers.-                     -- See Note [Type data declarations] in GHC.Rename.Module.-                     ---                     -- Note that the other checks in this definition will-                     -- return False for `type data` declarations, as:-                     ---                     -- - They cannot be newtypes-                     -- - They cannot have strict fields-                     -- - They cannot be data family instances-                     -- - They cannot have datatype contexts+       || not (null stupid_theta)                      -- If the data constructor has a datatype context,                      -- we need a wrapper in order to drop the stupid arguments.
GHC/Types/Name/Ppr.hs view
@@ -123,7 +123,8 @@             , fUNTyConName, unrestrictedFunTyConName             , oneDataConName             , listTyConName-            , manyDataConName ]+            , manyDataConName+            , soloDataConName ]           || isJust (isTupleTyOcc_maybe mod occ)           || isJust (isSumTyOcc_maybe mod occ) 
GHC/Types/RepType.hs view
@@ -693,6 +693,9 @@ -- AK: It would be nice to figure out and document the difference -- between this and isFunTy at some point. mightBeFunTy ty+  -- Currently ghc has no unlifted functions.+  | definitelyUnliftedType ty+  = False   | [BoxedRep _] <- typePrimRep ty   , Just tc <- tyConAppTyCon_maybe (unwrapType ty)   , isDataTyCon tc
GHC/Types/Var.hs view
@@ -503,7 +503,7 @@ coreTyLamForAllTyFlag :: ForAllTyFlag -- ^ The ForAllTyFlag on a (Lam a e) term, where `a` is a type variable. -- If you want other ForAllTyFlag, use a cast.--- See Note [ForAllCo] in GHC.Core.TyCo.Rep+-- See Note [Required foralls in Core] in GHC.Core.TyCo.Rep coreTyLamForAllTyFlag = Specified  instance Outputable ForAllTyFlag where
GHC/Types/Var.hs-boot view
@@ -1,13 +1,7 @@ {-# LANGUAGE NoPolyKinds #-} module GHC.Types.Var where -import GHC.Prelude () import {-# SOURCE #-} GHC.Types.Name-  -- We compile this GHC with -XNoImplicitPrelude, so if there are no imports-  -- it does not seem to depend on anything. But it does! We must, for-  -- example, compile GHC.Types in the ghc-prim library first. So this-  -- otherwise-unnecessary import tells the build system that this module-  -- depends on GhcPrelude, which ensures that GHC.Type is built first.  data ForAllTyFlag data FunTyFlag
GHC/Unit/Types.hs view
@@ -104,9 +104,9 @@ import GHC.Utils.Misc import GHC.Settings.Config (cProjectUnitId) -import Control.DeepSeq+import Control.DeepSeq (NFData(..)) import Data.Data-import Data.List (sortBy )+import Data.List (sortBy) import Data.Function import Data.Bifunctor import qualified Data.ByteString as BS
GHC/Utils/Containers/Internal/StrictPair.hs view
@@ -4,6 +4,11 @@  module GHC.Utils.Containers.Internal.StrictPair (StrictPair(..), toPair) where +-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Base ()++default ()+ -- | The same as a regular Haskell pair, but -- -- @
GHC/Utils/Fingerprint.hs view
@@ -19,6 +19,7 @@         fingerprintFingerprints,         fingerprintData,         fingerprintString,+        fingerprintStrings,         getFileHash    ) where @@ -43,3 +44,7 @@ fingerprintByteString :: BS.ByteString -> Fingerprint fingerprintByteString bs = unsafeDupablePerformIO $   BS.unsafeUseAsCStringLen bs $ \(ptr, len) -> fingerprintData (castPtr ptr) len++-- See Note [Repeated -optP hashing]+fingerprintStrings :: [String] -> Fingerprint+fingerprintStrings ss = fingerprintFingerprints $ map fingerprintString ss
GHC/Utils/Outputable.hs view
@@ -1260,7 +1260,7 @@  data JoinPointHood   = JoinPoint {-# UNPACK #-} !Int   -- The JoinArity (but an Int here because-  | NotJoinPoint                    -- synonym JoinArity is defined in Types.Basic+  | NotJoinPoint                    -- synonym JoinArity is defined in Types.Basic)   deriving( Eq )  isJoinPoint :: JoinPointHood -> Bool
GHC/Utils/TmpFs.hs view
@@ -377,18 +377,27 @@  This is ok, as the temporary directory used contains the pid (see getTempDir). -}++manyWithTrace :: Logger -> String -> ([FilePath] -> IO ()) -> [FilePath] -> IO ()+manyWithTrace _ _ _ [] = pure () -- do silent nothing on zero filepaths+manyWithTrace logger phase act paths+  = traceCmd logger phase ("Deleting: " ++ unwords paths) (act paths)+ removeTmpDirs :: Logger -> [FilePath] -> IO ()-removeTmpDirs logger ds-  = traceCmd logger "Deleting temp dirs"-             ("Deleting: " ++ unwords ds)-             (mapM_ (removeWith logger removeDirectory) ds)+removeTmpDirs logger+  = manyWithTrace logger "Deleting temp dirs"+                  (mapM_ (removeWith logger removeDirectory)) +removeTmpSubdirs :: Logger -> [FilePath] -> IO ()+removeTmpSubdirs logger+  = manyWithTrace logger "Deleting temp subdirs"+                  (mapM_ (removeWith logger removeDirectory))+ removeTmpFiles :: Logger -> [FilePath] -> IO () removeTmpFiles logger fs   = warnNon $-    traceCmd logger "Deleting temp files"-             ("Deleting: " ++ unwords deletees)-             (mapM_ (removeWith logger removeFile) deletees)+    manyWithTrace logger "Deleting temp files"+                  (mapM_ (removeWith logger removeFile)) deletees   where      -- Flat out refuse to delete files that are likely to be source input      -- files (is there a worse bug than having a compiler delete your source@@ -404,12 +413,6 @@         act      (non_deletees, deletees) = partition isHaskellUserSrcFilename fs--removeTmpSubdirs :: Logger -> [FilePath] -> IO ()-removeTmpSubdirs logger fs-  = traceCmd logger "Deleting temp subdirs"-             ("Deleting: " ++ unwords fs)-             (mapM_ (removeWith logger removeDirectory) fs)  removeWith :: Logger -> (FilePath -> IO ()) -> FilePath -> IO () removeWith logger remover f = remover f `Exception.catchIO`
cbits/genSym.c view
@@ -9,7 +9,19 @@ // // The CPP is thus about the RTS version GHC is linked against, and not the // version of the GHC being built.-#if !MIN_VERSION_GLASGOW_HASKELL(9,9,0,0)++#if MIN_VERSION_GLASGOW_HASKELL(9,9,0,0)+// Unique64 patch was present in 9.10 and later+#define HAVE_UNIQUE64 1+#elif !MIN_VERSION_GLASGOW_HASKELL(9,9,0,0) && MIN_VERSION_GLASGOW_HASKELL(9,8,4,0)+// Unique64 patch was backported to 9.8.4+#define HAVE_UNIQUE64 1+#elif !MIN_VERSION_GLASGOW_HASKELL(9,7,0,0) && MIN_VERSION_GLASGOW_HASKELL(9,6,7,0)+// Unique64 patch was backported to 9.6.7+#define HAVE_UNIQUE64 1+#endif++#if !defined(HAVE_UNIQUE64) HsWord64 ghc_unique_counter64 = 0; #endif #if !MIN_VERSION_GLASGOW_HASKELL(9,3,0,0)
ghc.cabal view
@@ -3,7 +3,7 @@ -- ./configure.  Make sure you are editing ghc.cabal.in, not ghc.cabal.  Name: ghc-Version: 9.10.1+Version: 9.10.2 License: BSD-3-Clause License-File: LICENSE Author: The GHC Team@@ -109,7 +109,7 @@                    deepseq    >= 1.4 && < 1.6,                    directory  >= 1   && < 1.4,                    process    >= 1   && < 1.7,-                   bytestring >= 0.9 && < 0.13,+                   bytestring >= 0.11 && < 0.13,                    binary     == 0.8.*,                    time       >= 1.4 && < 1.13,                    containers >= 0.6.2.1 && < 0.8,@@ -121,9 +121,9 @@                    exceptions == 0.10.*,                    semaphore-compat,                    stm,-                   ghc-boot   == 9.10.1,-                   ghc-heap   == 9.10.1,-                   ghci == 9.10.1+                   ghc-boot   == 9.10.2,+                   ghc-heap   == 9.10.2,+                   ghci == 9.10.2      if os(windows)         Build-Depends: Win32  >= 2.3 && < 2.15@@ -414,6 +414,7 @@         GHC.Data.FastString         GHC.Data.FastString.Env         GHC.Data.FiniteMap+        GHC.Data.FlatBag         GHC.Data.Graph.Base         GHC.Data.Graph.Color         GHC.Data.Graph.Collapse@@ -828,7 +829,7 @@         GHC.Types.Annotations         GHC.Types.Avail         GHC.Types.Basic-        GHC.Types.BreakInfo+        GHC.Types.Breakpoint         GHC.Types.CompleteMatch         GHC.Types.CostCentre         GHC.Types.CostCentre.State