ghc-lib-parser 0.20221101 → 0.20221201
raw patch · 191 files changed
+13239/−8318 lines, 191 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- GHC.Builtin.Names: dATA_VOID :: Module
- GHC.Builtin.Names: funTyConKey :: Unique
- GHC.Builtin.Names: nonEmptyDataConKey :: Unique
- GHC.Builtin.Types: boxingDataCon_maybe :: TyCon -> Maybe DataCon
- GHC.Builtin.Types: nonEmptyDataCon :: DataCon
- GHC.Builtin.Types: nonEmptyDataConName :: Name
- GHC.Builtin.Types: nonEmptyTyCon :: TyCon
- GHC.Builtin.Types: nonEmptyTyConName :: Name
- GHC.Builtin.Types.Prim: funTyCon :: TyCon
- GHC.Builtin.Types.Prim: funTyConName :: Name
- GHC.Builtin.Types.Prim: functionWithMultiplicity :: Type -> Type
- GHC.Builtin.Types.Prim: mkTYPEapp :: RuntimeRepType -> Type
- GHC.Cmm.CLabel: instance GHC.Utils.Outputable.Outputable GHC.Cmm.CLabel.ModuleLabelKind
- GHC.Cmm.MachOp: MO_U_MulMayOflo :: Width -> MachOp
- GHC.Core: RuleEnv :: [RuleBase] -> ModuleSet -> RuleEnv
- GHC.Core: [re_base] :: RuleEnv -> [RuleBase]
- GHC.Core: [re_visible_orphs] :: RuleEnv -> ModuleSet
- GHC.Core: data RuleEnv
- GHC.Core: emptyRuleEnv :: RuleEnv
- GHC.Core: mkRuleEnv :: RuleBase -> [Module] -> RuleEnv
- GHC.Core: type RuleBase = NameEnv [CoreRule]
- GHC.Core.Coercion: mkFunCo :: Role -> CoercionN -> Coercion -> Coercion -> Coercion
- GHC.Core.Coercion: mkNthCo :: HasDebugCallStack => Role -> Int -> Coercion -> Coercion
- GHC.Core.Coercion: mkNthCoFunCo :: Int -> CoercionN -> Coercion -> Coercion -> Coercion
- GHC.Core.Coercion: nthCoRole :: Int -> Coercion -> Role
- GHC.Core.Coercion: nthRole :: Role -> TyCon -> Int -> Role
- GHC.Core.Coercion: splitTyConAppCo_maybe :: Coercion -> Maybe (TyCon, [Coercion])
- GHC.Core.DataCon: dataConEqSpec :: DataCon -> [EqSpec]
- GHC.Core.DataCon: dataConUserTyVarsArePermuted :: DataCon -> Bool
- GHC.Core.DataCon: filterEqSpec :: [EqSpec] -> [TyVar] -> [TyVar]
- GHC.Core.DataCon: substEqSpec :: Subst -> EqSpec -> EqSpec
- GHC.Core.FVs: expr_fvs :: CoreExpr -> FV
- GHC.Core.Lint: [ep_printUnqual] :: EndPassConfig -> !PrintUnqualified
- GHC.Core.Make: aBSENT_ERROR_ID :: Id
- GHC.Core.Make: mkBigCoreVarTup1 :: [Id] -> CoreExpr
- GHC.Core.Make: mkCoreUbxSum :: Int -> Int -> [Type] -> CoreExpr -> CoreExpr
- GHC.Core.Make: mkCoreUbxTup :: [Type] -> [CoreExpr] -> CoreExpr
- GHC.Core.Make: mkNonEmptyListExpr :: Type -> CoreExpr -> [CoreExpr] -> CoreExpr
- GHC.Core.Make: mkSmallTupleCase :: [Id] -> CoreExpr -> Id -> CoreExpr -> CoreExpr
- GHC.Core.Make: mkSmallTupleSelector :: [Id] -> Id -> Id -> CoreExpr -> CoreExpr
- GHC.Core.Make: mkTupleCase :: UniqSupply -> [Id] -> CoreExpr -> Id -> CoreExpr -> CoreExpr
- GHC.Core.Make: mkTupleSelector :: [Id] -> Id -> Id -> CoreExpr -> CoreExpr
- GHC.Core.Make: mkTupleSelector1 :: [Id] -> Id -> Id -> CoreExpr -> CoreExpr
- GHC.Core.Multiplicity: pattern Many :: Mult
- GHC.Core.Multiplicity: pattern One :: Mult
- GHC.Core.Opt.Monad: getPrintUnqualified :: CoreM PrintUnqualified
- GHC.Core.Opt.Monad: getRuleBase :: CoreM RuleBase
- GHC.Core.Opt.Monad: getVisibleOrphanMods :: CoreM ModuleSet
- GHC.Core.Opt.Simplify: [so_rule_base] :: SimplifyOpts -> !RuleBase
- GHC.Core.Rules: extendRuleEnv :: RuleEnv -> RuleBase -> RuleEnv
- GHC.Core.TyCo.Rep: Anon :: AnonArgFlag -> Scaled Type -> TyCoBinder
- GHC.Core.TyCo.Rep: InvisArg :: AnonArgFlag
- GHC.Core.TyCo.Rep: Named :: TyCoVarBinder -> TyCoBinder
- GHC.Core.TyCo.Rep: NthCo :: Role -> Int -> Coercion -> Coercion
- GHC.Core.TyCo.Rep: VisArg :: AnonArgFlag
- GHC.Core.TyCo.Rep: binderArgFlag :: VarBndr tv argf -> argf
- GHC.Core.TyCo.Rep: binderType :: VarBndr TyCoVar argf -> Type
- GHC.Core.TyCo.Rep: binderVar :: VarBndr tv argf -> tv
- GHC.Core.TyCo.Rep: binderVars :: [VarBndr tv argf] -> [tv]
- GHC.Core.TyCo.Rep: data AnonArgFlag
- GHC.Core.TyCo.Rep: data ArgFlag
- GHC.Core.TyCo.Rep: data TyCoBinder
- GHC.Core.TyCo.Rep: delBinderVar :: VarSet -> TyCoVarBinder -> VarSet
- GHC.Core.TyCo.Rep: instance Data.Data.Data GHC.Core.TyCo.Rep.TyCoBinder
- GHC.Core.TyCo.Rep: instance GHC.Utils.Outputable.Outputable GHC.Core.TyCo.Rep.TyCoBinder
- GHC.Core.TyCo.Rep: isInvisibleArgFlag :: ArgFlag -> Bool
- GHC.Core.TyCo.Rep: isInvisibleBinder :: TyCoBinder -> Bool
- GHC.Core.TyCo.Rep: isNamedBinder :: TyCoBinder -> Bool
- GHC.Core.TyCo.Rep: isTyBinder :: TyCoBinder -> Bool
- GHC.Core.TyCo.Rep: isVisibleArgFlag :: ArgFlag -> Bool
- GHC.Core.TyCo.Rep: isVisibleBinder :: TyCoBinder -> Bool
- GHC.Core.TyCo.Rep: mkFunTyMany :: AnonArgFlag -> Type -> Type -> Type
- GHC.Core.TyCo.Rep: mkInvisFunTyMany :: Type -> Type -> Type
- GHC.Core.TyCo.Rep: mkInvisFunTysMany :: [Type] -> Type -> Type
- GHC.Core.TyCo.Rep: mkScaledFunTy :: AnonArgFlag -> Scaled Type -> Type -> Type
- GHC.Core.TyCo.Rep: mkVisFunTys :: [Scaled Type] -> Type -> Type
- GHC.Core.TyCo.Rep: type TyBinder = TyCoBinder
- GHC.Core.TyCo.Rep: type TyCoVarBinder = VarBndr TyCoVar ArgFlag
- GHC.Core.TyCo.Tidy: tidyTyCoVarBinder :: TidyEnv -> VarBndr TyCoVar vis -> (TidyEnv, VarBndr TyCoVar vis)
- GHC.Core.TyCo.Tidy: tidyTyCoVarBinders :: TidyEnv -> [VarBndr TyCoVar vis] -> (TidyEnv, [VarBndr TyCoVar vis])
- GHC.Core.TyCon: LiftedInfo :: RuntimeRepInfo
- GHC.Core.TyCon: NoRRI :: RuntimeRepInfo
- GHC.Core.TyCon: UnliftedInfo :: RuntimeRepInfo
- GHC.Core.TyCon: data RuntimeRepInfo
- GHC.Core.TyCon: isConstraintKindCon :: TyCon -> Bool
- GHC.Core.TyCon: isFunTyCon :: TyCon -> Bool
- GHC.Core.TyCon: mkFunTyCon :: Name -> [TyConBinder] -> Name -> TyCon
- GHC.Core.TyCon: mustBeSaturated :: TyCon -> Bool
- GHC.Core.TyCon: tyConBinderArgFlag :: TyConBinder -> ArgFlag
- GHC.Core.TyCon: tyConBndrVisArgFlag :: TyConBndrVis -> ArgFlag
- GHC.Core.TyCon: tyConRuntimeRepInfo :: TyCon -> RuntimeRepInfo
- GHC.Core.TyCon: type TyConTyCoBinder = VarBndr TyCoVar TyConBndrVis
- GHC.Core.Type: InvisArg :: AnonArgFlag
- GHC.Core.Type: VisArg :: AnonArgFlag
- GHC.Core.Type: appTyArgFlags :: Type -> [Type] -> [ArgFlag]
- GHC.Core.Type: binderArgFlag :: VarBndr tv argf -> argf
- GHC.Core.Type: binderRelevantType_maybe :: TyCoBinder -> Maybe Type
- GHC.Core.Type: classifiesTypeWithValues :: Kind -> Bool
- GHC.Core.Type: data AnonArgFlag
- GHC.Core.Type: data ArgFlag
- GHC.Core.Type: data TyCoBinder
- GHC.Core.Type: eqType :: Type -> Type -> Bool
- GHC.Core.Type: eqTypeX :: RnEnv2 -> Type -> Type -> Bool
- GHC.Core.Type: eqTypes :: [Type] -> [Type] -> Bool
- GHC.Core.Type: eqVarBndrs :: RnEnv2 -> [Var] -> [Var] -> Maybe RnEnv2
- GHC.Core.Type: funTyCon :: TyCon
- GHC.Core.Type: getLevity_maybe :: HasDebugCallStack => Type -> Maybe Type
- GHC.Core.Type: getRuntimeRep_maybe :: HasDebugCallStack => Type -> Maybe RuntimeRepType
- GHC.Core.Type: instance GHC.Classes.Eq GHC.Core.Type.TypeOrdering
- GHC.Core.Type: instance GHC.Classes.Ord GHC.Core.Type.TypeOrdering
- GHC.Core.Type: instance GHC.Enum.Bounded GHC.Core.Type.TypeOrdering
- GHC.Core.Type: instance GHC.Enum.Enum GHC.Core.Type.TypeOrdering
- GHC.Core.Type: isAnonTyCoBinder :: TyCoBinder -> Bool
- GHC.Core.Type: isConstraintKindCon :: TyCon -> Bool
- GHC.Core.Type: isInvisibleArgFlag :: ArgFlag -> Bool
- GHC.Core.Type: isInvisibleBinder :: TyCoBinder -> Bool
- GHC.Core.Type: isManyDataConTy :: Mult -> Bool
- GHC.Core.Type: isNamedBinder :: TyCoBinder -> Bool
- GHC.Core.Type: isOneDataConTy :: Mult -> Bool
- GHC.Core.Type: isVisibleArgFlag :: ArgFlag -> Bool
- GHC.Core.Type: isVisibleBinder :: TyCoBinder -> Bool
- GHC.Core.Type: mkAnonBinder :: AnonArgFlag -> Scaled Type -> TyCoBinder
- GHC.Core.Type: mkInvisFunTyMany :: Type -> Type -> Type
- GHC.Core.Type: mkInvisFunTysMany :: [Type] -> Type -> Type
- GHC.Core.Type: mkTyCoVarBinder :: vis -> TyCoVar -> VarBndr TyCoVar vis
- GHC.Core.Type: mkTyCoVarBinders :: vis -> [TyCoVar] -> [VarBndr TyCoVar vis]
- GHC.Core.Type: mkVisFunTys :: [Scaled Type] -> Type -> Type
- GHC.Core.Type: nonDetCmpTc :: TyCon -> TyCon -> Ordering
- GHC.Core.Type: nonDetCmpType :: Type -> Type -> Ordering
- GHC.Core.Type: nonDetCmpTypeX :: RnEnv2 -> Type -> Type -> Ordering
- GHC.Core.Type: nonDetCmpTypes :: [Type] -> [Type] -> Ordering
- GHC.Core.Type: nonDetCmpTypesX :: RnEnv2 -> [Type] -> [Type] -> Ordering
- GHC.Core.Type: pattern Many :: Mult
- GHC.Core.Type: pattern One :: Mult
- GHC.Core.Type: repSplitAppTy_maybe :: HasDebugCallStack => Type -> Maybe (Type, Type)
- GHC.Core.Type: repSplitAppTys :: HasDebugCallStack => Type -> (Type, [Type])
- GHC.Core.Type: repSplitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type])
- GHC.Core.Type: sameVis :: ArgFlag -> ArgFlag -> Bool
- GHC.Core.Type: splitForAllInvisTVBinders :: Type -> ([InvisTVBinder], Type)
- GHC.Core.Type: splitForAllReqTVBinders :: Type -> ([ReqTVBinder], Type)
- GHC.Core.Type: splitForAllTyCoVarBinders :: Type -> ([TyCoVarBinder], Type)
- GHC.Core.Type: splitListTyConApp_maybe :: Type -> Maybe Type
- GHC.Core.Type: splitVisVarsOfType :: Type -> Pair TyCoVarSet
- GHC.Core.Type: splitVisVarsOfTypes :: [Type] -> Pair TyCoVarSet
- GHC.Core.Type: tcIsConstraintKind :: Kind -> Bool
- GHC.Core.Type: tcIsRuntimeTypeKind :: Kind -> Bool
- GHC.Core.Type: tcRepSplitAppTy_maybe :: Type -> Maybe (Type, Type)
- GHC.Core.Type: tcRepSplitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type])
- GHC.Core.Type: tcReturnsConstraintKind :: Kind -> Bool
- GHC.Core.Type: tcTypeKind :: HasDebugCallStack => Type -> Kind
- GHC.Core.Type: tcView :: Type -> Maybe Type
- GHC.Core.Type: tidyTyCoVarBinder :: TidyEnv -> VarBndr TyCoVar vis -> (TidyEnv, VarBndr TyCoVar vis)
- GHC.Core.Type: tidyTyCoVarBinders :: TidyEnv -> [VarBndr TyCoVar vis] -> (TidyEnv, [VarBndr TyCoVar vis])
- GHC.Core.Type: tyBinderType :: TyBinder -> Type
- GHC.Core.Type: tyCoBinderType :: TyCoBinder -> Type
- GHC.Core.Type: tyCoBinderVar_maybe :: TyCoBinder -> Maybe TyCoVar
- GHC.Core.Type: tyConAppArgN :: Int -> Type -> Type
- GHC.Core.Type: tyConArgFlags :: TyCon -> [Type] -> [ArgFlag]
- GHC.Core.Type: tyConBindersTyCoBinders :: [TyConBinder] -> [TyCoBinder]
- GHC.Core.Type: type TyCoVarBinder = VarBndr TyCoVar ArgFlag
- GHC.Core.Type: unrestrictedFunTyCon :: TyCon
- GHC.Core.Unify: RM_KnownTc :: Name -> RoughMatchTc
- GHC.Core.Unify: RM_WildCard :: RoughMatchTc
- GHC.Core.Unify: data RoughMatchTc
- GHC.Core.Unify: instanceCantMatch :: [RoughMatchTc] -> [RoughMatchTc] -> Bool
- GHC.Core.Unify: isRoughWildcard :: RoughMatchTc -> Bool
- GHC.Core.Unify: roughMatchTcs :: [Type] -> [RoughMatchTc]
- GHC.Core.Unify: roughMatchTcsLookup :: [Type] -> [RoughMatchLookupTc]
- GHC.CoreToIface: toIfaceTyCoVarBinders :: [VarBndr Var vis] -> [VarBndr IfaceBndr vis]
- GHC.Data.Graph.UnVar: varEnvDom :: VarEnv a -> UnVarSet
- GHC.Hs.Instances: instance Data.Data.Data (GHC.Hs.Expr.HsUntypedSpliceResult (Language.Haskell.Syntax.Expr.HsExpr GHC.Hs.Extension.GhcRn))
- GHC.Hs.Instances: instance Data.Data.Data (GHC.Hs.Expr.HsUntypedSpliceResult (Language.Haskell.Syntax.Pat.Pat GHC.Hs.Extension.GhcRn))
- GHC.Hs.Instances: instance Data.Data.Data (GHC.Hs.Expr.HsUntypedSpliceResult (Language.Haskell.Syntax.Type.HsType GHC.Hs.Extension.GhcRn))
- GHC.Hs.Utils: chunkify :: [a] -> [[a]]
- GHC.Hs.Utils: mkChunkified :: ([a] -> a) -> [a] -> a
- GHC.Iface.Type: IfaceNthCo :: Int -> IfaceCoercion -> IfaceCoercion
- GHC.Iface.Type: InvisArg :: AnonArgFlag
- GHC.Iface.Type: VisArg :: AnonArgFlag
- GHC.Iface.Type: appArgsIfaceTypesArgFlags :: IfaceAppArgs -> [(IfaceType, ArgFlag)]
- GHC.Iface.Type: data AnonArgFlag
- GHC.Iface.Type: data ArgFlag
- GHC.Iface.Type: isIfaceTauType :: IfaceType -> Bool
- GHC.Iface.Type: mulArrow :: (PprPrec -> a -> SDoc) -> a -> SDoc
- GHC.Iface.Type: ppr_fun_arrow :: IfaceMult -> SDoc
- GHC.Prelude: (!!) :: [a] -> Int -> a
- GHC.Prelude: ($!) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
- GHC.Prelude: ($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
- GHC.Prelude: (&&) :: Bool -> Bool -> Bool
- GHC.Prelude: (*) :: Num a => a -> a -> a
- GHC.Prelude: (**) :: Floating a => a -> a -> a
- GHC.Prelude: (*>) :: Applicative f => f a -> f b -> f b
- GHC.Prelude: (+) :: Num a => a -> a -> a
- GHC.Prelude: (++) :: [a] -> [a] -> [a]
- GHC.Prelude: (-) :: Num a => a -> a -> a
- GHC.Prelude: (.&.) :: Bits a => a -> a -> a
- GHC.Prelude: (.) :: (b -> c) -> (a -> b) -> a -> c
- GHC.Prelude: (.|.) :: Bits a => a -> a -> a
- GHC.Prelude: (/) :: Fractional a => a -> a -> a
- GHC.Prelude: (/=) :: Eq a => a -> a -> Bool
- GHC.Prelude: (<$) :: Functor f => a -> f b -> f a
- GHC.Prelude: (<$>) :: Functor f => (a -> b) -> f a -> f b
- GHC.Prelude: (<) :: Ord a => a -> a -> Bool
- GHC.Prelude: (<*) :: Applicative f => f a -> f b -> f a
- GHC.Prelude: (<*>) :: Applicative f => f (a -> b) -> f a -> f b
- GHC.Prelude: (<=) :: Ord a => a -> a -> Bool
- GHC.Prelude: (=<<) :: Monad m => (a -> m b) -> m a -> m b
- GHC.Prelude: (==) :: Eq a => a -> a -> Bool
- GHC.Prelude: (>) :: Ord a => a -> a -> Bool
- GHC.Prelude: (>=) :: Ord a => a -> a -> Bool
- GHC.Prelude: (>>) :: Monad m => m a -> m b -> m b
- GHC.Prelude: (>>=) :: Monad m => m a -> (a -> m b) -> m b
- GHC.Prelude: (^) :: (Num a, Integral b) => a -> b -> a
- GHC.Prelude: (^^) :: (Fractional a, Integral b) => a -> b -> a
- GHC.Prelude: (||) :: Bool -> Bool -> Bool
- GHC.Prelude: EQ :: Ordering
- GHC.Prelude: False :: Bool
- GHC.Prelude: GT :: Ordering
- GHC.Prelude: Just :: a -> Maybe a
- GHC.Prelude: LT :: Ordering
- GHC.Prelude: Left :: a -> Either a b
- GHC.Prelude: Nothing :: Maybe a
- GHC.Prelude: Right :: b -> Either a b
- GHC.Prelude: True :: Bool
- GHC.Prelude: abs :: Num a => a -> a
- GHC.Prelude: acos :: Floating a => a -> a
- GHC.Prelude: acosh :: Floating a => a -> a
- GHC.Prelude: all :: Foldable t => (a -> Bool) -> t a -> Bool
- GHC.Prelude: and :: Foldable t => t Bool -> Bool
- GHC.Prelude: any :: Foldable t => (a -> Bool) -> t a -> Bool
- GHC.Prelude: appendFile :: FilePath -> String -> IO ()
- GHC.Prelude: asTypeOf :: a -> a -> a
- GHC.Prelude: asin :: Floating a => a -> a
- GHC.Prelude: asinh :: Floating a => a -> a
- GHC.Prelude: atan :: Floating a => a -> a
- GHC.Prelude: atan2 :: RealFloat a => a -> a -> a
- GHC.Prelude: atanh :: Floating a => a -> a
- GHC.Prelude: bit :: Bits a => Int -> a
- GHC.Prelude: bitDefault :: (Bits a, Num a) => Int -> a
- GHC.Prelude: bitSize :: Bits a => a -> Int
- GHC.Prelude: bitSizeMaybe :: Bits a => a -> Maybe Int
- GHC.Prelude: break :: (a -> Bool) -> [a] -> ([a], [a])
- GHC.Prelude: ceiling :: (RealFrac a, Integral b) => a -> b
- GHC.Prelude: class Functor f => Applicative (f :: Type -> Type)
- GHC.Prelude: class Eq a => Bits a
- GHC.Prelude: class Bounded a
- GHC.Prelude: class Enum a
- GHC.Prelude: class Eq a
- GHC.Prelude: class Bits b => FiniteBits b
- GHC.Prelude: class Fractional a => Floating a
- GHC.Prelude: class Foldable (t :: TYPE LiftedRep -> Type)
- GHC.Prelude: class Num a => Fractional a
- GHC.Prelude: class Functor (f :: Type -> Type)
- GHC.Prelude: class (Real a, Enum a) => Integral a
- GHC.Prelude: class Applicative m => Monad (m :: Type -> Type)
- GHC.Prelude: class Monad m => MonadFail (m :: Type -> Type)
- GHC.Prelude: class Semigroup a => Monoid a
- GHC.Prelude: class Num a
- GHC.Prelude: class Eq a => Ord a
- GHC.Prelude: class Read a
- GHC.Prelude: class (Num a, Ord a) => Real a
- GHC.Prelude: class (RealFrac a, Floating a) => RealFloat a
- GHC.Prelude: class (Real a, Fractional a) => RealFrac a
- GHC.Prelude: class Semigroup a
- GHC.Prelude: class Show a
- GHC.Prelude: class (Functor t, Foldable t) => Traversable (t :: Type -> Type)
- GHC.Prelude: clearBit :: Bits a => a -> Int -> a
- GHC.Prelude: compare :: Ord a => a -> a -> Ordering
- GHC.Prelude: complement :: Bits a => a -> a
- GHC.Prelude: complementBit :: Bits a => a -> Int -> a
- GHC.Prelude: concat :: Foldable t => t [a] -> [a]
- GHC.Prelude: concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
- GHC.Prelude: const :: a -> b -> a
- GHC.Prelude: cos :: Floating a => a -> a
- GHC.Prelude: cosh :: Floating a => a -> a
- GHC.Prelude: countLeadingZeros :: FiniteBits b => b -> Int
- GHC.Prelude: countTrailingZeros :: FiniteBits b => b -> Int
- GHC.Prelude: curry :: ((a, b) -> c) -> a -> b -> c
- GHC.Prelude: cycle :: [a] -> [a]
- GHC.Prelude: data Bool
- GHC.Prelude: data Char
- GHC.Prelude: data Double
- GHC.Prelude: data Either a b
- GHC.Prelude: data Float
- GHC.Prelude: data IO a
- GHC.Prelude: data Int
- GHC.Prelude: data Integer
- GHC.Prelude: data Maybe a
- GHC.Prelude: data Ordering
- GHC.Prelude: data Word
- GHC.Prelude: decodeFloat :: RealFloat a => a -> (Integer, Int)
- GHC.Prelude: div :: Integral a => a -> a -> a
- GHC.Prelude: divMod :: Integral a => a -> a -> (a, a)
- GHC.Prelude: drop :: Int -> [a] -> [a]
- GHC.Prelude: dropWhile :: (a -> Bool) -> [a] -> [a]
- GHC.Prelude: either :: (a -> c) -> (b -> c) -> Either a b -> c
- GHC.Prelude: elem :: (Foldable t, Eq a) => a -> t a -> Bool
- GHC.Prelude: encodeFloat :: RealFloat a => Integer -> Int -> a
- GHC.Prelude: enumFrom :: Enum a => a -> [a]
- GHC.Prelude: enumFromThen :: Enum a => a -> a -> [a]
- GHC.Prelude: enumFromThenTo :: Enum a => a -> a -> a -> [a]
- GHC.Prelude: enumFromTo :: Enum a => a -> a -> [a]
- GHC.Prelude: error :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => [Char] -> a
- GHC.Prelude: errorWithoutStackTrace :: forall (r :: RuntimeRep) (a :: TYPE r). [Char] -> a
- GHC.Prelude: even :: Integral a => a -> Bool
- GHC.Prelude: exp :: Floating a => a -> a
- GHC.Prelude: exponent :: RealFloat a => a -> Int
- GHC.Prelude: fail :: MonadFail m => String -> m a
- GHC.Prelude: filter :: (a -> Bool) -> [a] -> [a]
- GHC.Prelude: finiteBitSize :: FiniteBits b => b -> Int
- GHC.Prelude: flip :: (a -> b -> c) -> b -> a -> c
- GHC.Prelude: floatDigits :: RealFloat a => a -> Int
- GHC.Prelude: floatRadix :: RealFloat a => a -> Integer
- GHC.Prelude: floatRange :: RealFloat a => a -> (Int, Int)
- GHC.Prelude: floor :: (RealFrac a, Integral b) => a -> b
- GHC.Prelude: fmap :: Functor f => (a -> b) -> f a -> f b
- GHC.Prelude: foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
- GHC.Prelude: foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
- GHC.Prelude: foldl' :: Foldable t => (b -> a -> b) -> b -> t a -> b
- GHC.Prelude: foldl1 :: Foldable t => (a -> a -> a) -> t a -> a
- GHC.Prelude: foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
- GHC.Prelude: foldr1 :: Foldable t => (a -> a -> a) -> t a -> a
- GHC.Prelude: fromEnum :: Enum a => a -> Int
- GHC.Prelude: fromInteger :: Num a => Integer -> a
- GHC.Prelude: fromIntegral :: (Integral a, Num b) => a -> b
- GHC.Prelude: fromRational :: Fractional a => Rational -> a
- GHC.Prelude: fst :: (a, b) -> a
- GHC.Prelude: gcd :: Integral a => a -> a -> a
- GHC.Prelude: getChar :: IO Char
- GHC.Prelude: getContents :: IO String
- GHC.Prelude: getLine :: IO String
- GHC.Prelude: head :: [a] -> a
- GHC.Prelude: id :: a -> a
- GHC.Prelude: infix 4 `notElem`
- GHC.Prelude: infixl 1 >>=
- GHC.Prelude: infixl 4 <*
- GHC.Prelude: infixl 5 .|.
- GHC.Prelude: infixl 6 `xor`
- GHC.Prelude: infixl 7 .&.
- GHC.Prelude: infixl 8 `rotate`
- GHC.Prelude: infixl 9 !!
- GHC.Prelude: infixr 0 $!
- GHC.Prelude: infixr 1 =<<
- GHC.Prelude: infixr 2 ||
- GHC.Prelude: infixr 3 &&
- GHC.Prelude: infixr 5 ++
- GHC.Prelude: infixr 8 ^
- GHC.Prelude: infixr 9 .
- GHC.Prelude: init :: [a] -> [a]
- GHC.Prelude: interact :: (String -> String) -> IO ()
- GHC.Prelude: ioError :: IOError -> IO a
- GHC.Prelude: isDenormalized :: RealFloat a => a -> Bool
- GHC.Prelude: isIEEE :: RealFloat a => a -> Bool
- GHC.Prelude: isInfinite :: RealFloat a => a -> Bool
- GHC.Prelude: isNaN :: RealFloat a => a -> Bool
- GHC.Prelude: isNegativeZero :: RealFloat a => a -> Bool
- GHC.Prelude: isSigned :: Bits a => a -> Bool
- GHC.Prelude: iterate :: (a -> a) -> a -> [a]
- GHC.Prelude: last :: [a] -> a
- GHC.Prelude: lcm :: Integral a => a -> a -> a
- GHC.Prelude: length :: Foldable t => t a -> Int
- GHC.Prelude: lex :: ReadS String
- GHC.Prelude: liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
- GHC.Prelude: lines :: String -> [String]
- GHC.Prelude: log :: Floating a => a -> a
- GHC.Prelude: logBase :: Floating a => a -> a -> a
- GHC.Prelude: lookup :: Eq a => a -> [(a, b)] -> Maybe b
- GHC.Prelude: map :: (a -> b) -> [a] -> [b]
- GHC.Prelude: mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
- GHC.Prelude: mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
- GHC.Prelude: mappend :: Monoid a => a -> a -> a
- GHC.Prelude: max :: Ord a => a -> a -> a
- GHC.Prelude: maxBound :: Bounded a => a
- GHC.Prelude: maximum :: (Foldable t, Ord a) => t a -> a
- GHC.Prelude: maybe :: b -> (a -> b) -> Maybe a -> b
- GHC.Prelude: mconcat :: Monoid a => [a] -> a
- GHC.Prelude: mempty :: Monoid a => a
- GHC.Prelude: min :: Ord a => a -> a -> a
- GHC.Prelude: minBound :: Bounded a => a
- GHC.Prelude: minimum :: (Foldable t, Ord a) => t a -> a
- GHC.Prelude: mod :: Integral a => a -> a -> a
- GHC.Prelude: negate :: Num a => a -> a
- GHC.Prelude: not :: Bool -> Bool
- GHC.Prelude: notElem :: (Foldable t, Eq a) => a -> t a -> Bool
- GHC.Prelude: null :: Foldable t => t a -> Bool
- GHC.Prelude: odd :: Integral a => a -> Bool
- GHC.Prelude: or :: Foldable t => t Bool -> Bool
- GHC.Prelude: otherwise :: Bool
- GHC.Prelude: pi :: Floating a => a
- GHC.Prelude: popCount :: Bits a => a -> Int
- GHC.Prelude: popCountDefault :: (Bits a, Num a) => a -> Int
- GHC.Prelude: pred :: Enum a => a -> a
- GHC.Prelude: print :: Show a => a -> IO ()
- GHC.Prelude: product :: (Foldable t, Num a) => t a -> a
- GHC.Prelude: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
- GHC.Prelude: pure :: Applicative f => a -> f a
- GHC.Prelude: putChar :: Char -> IO ()
- GHC.Prelude: putStr :: String -> IO ()
- GHC.Prelude: putStrLn :: String -> IO ()
- GHC.Prelude: quot :: Integral a => a -> a -> a
- GHC.Prelude: quotRem :: Integral a => a -> a -> (a, a)
- GHC.Prelude: read :: Read a => String -> a
- GHC.Prelude: readFile :: FilePath -> IO String
- GHC.Prelude: readIO :: Read a => String -> IO a
- GHC.Prelude: readList :: Read a => ReadS [a]
- GHC.Prelude: readLn :: Read a => IO a
- GHC.Prelude: readParen :: Bool -> ReadS a -> ReadS a
- GHC.Prelude: reads :: Read a => ReadS a
- GHC.Prelude: readsPrec :: Read a => Int -> ReadS a
- GHC.Prelude: realToFrac :: (Real a, Fractional b) => a -> b
- GHC.Prelude: recip :: Fractional a => a -> a
- GHC.Prelude: rem :: Integral a => a -> a -> a
- GHC.Prelude: repeat :: a -> [a]
- GHC.Prelude: replicate :: Int -> a -> [a]
- GHC.Prelude: return :: Monad m => a -> m a
- GHC.Prelude: reverse :: [a] -> [a]
- GHC.Prelude: rotate :: Bits a => a -> Int -> a
- GHC.Prelude: rotateL :: Bits a => a -> Int -> a
- GHC.Prelude: rotateR :: Bits a => a -> Int -> a
- GHC.Prelude: round :: (RealFrac a, Integral b) => a -> b
- GHC.Prelude: scaleFloat :: RealFloat a => Int -> a -> a
- GHC.Prelude: scanl :: (b -> a -> b) -> b -> [a] -> [b]
- GHC.Prelude: scanl1 :: (a -> a -> a) -> [a] -> [a]
- GHC.Prelude: scanr :: (a -> b -> b) -> b -> [a] -> [b]
- GHC.Prelude: scanr1 :: (a -> a -> a) -> [a] -> [a]
- GHC.Prelude: seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b
- GHC.Prelude: sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
- GHC.Prelude: sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
- GHC.Prelude: sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
- GHC.Prelude: setBit :: Bits a => a -> Int -> a
- GHC.Prelude: shift :: Bits a => a -> Int -> a
- GHC.Prelude: shiftL :: Bits a => a -> Int -> a
- GHC.Prelude: shiftR :: Bits a => a -> Int -> a
- GHC.Prelude: show :: Show a => a -> String
- GHC.Prelude: showChar :: Char -> ShowS
- GHC.Prelude: showList :: Show a => [a] -> ShowS
- GHC.Prelude: showParen :: Bool -> ShowS -> ShowS
- GHC.Prelude: showString :: String -> ShowS
- GHC.Prelude: shows :: Show a => a -> ShowS
- GHC.Prelude: showsPrec :: Show a => Int -> a -> ShowS
- GHC.Prelude: significand :: RealFloat a => a -> a
- GHC.Prelude: signum :: Num a => a -> a
- GHC.Prelude: sin :: Floating a => a -> a
- GHC.Prelude: sinh :: Floating a => a -> a
- GHC.Prelude: snd :: (a, b) -> b
- GHC.Prelude: span :: (a -> Bool) -> [a] -> ([a], [a])
- GHC.Prelude: splitAt :: Int -> [a] -> ([a], [a])
- GHC.Prelude: sqrt :: Floating a => a -> a
- GHC.Prelude: subtract :: Num a => a -> a -> a
- GHC.Prelude: succ :: Enum a => a -> a
- GHC.Prelude: sum :: (Foldable t, Num a) => t a -> a
- GHC.Prelude: tail :: [a] -> [a]
- GHC.Prelude: take :: Int -> [a] -> [a]
- GHC.Prelude: takeWhile :: (a -> Bool) -> [a] -> [a]
- GHC.Prelude: tan :: Floating a => a -> a
- GHC.Prelude: tanh :: Floating a => a -> a
- GHC.Prelude: testBit :: Bits a => a -> Int -> Bool
- GHC.Prelude: testBitDefault :: (Bits a, Num a) => a -> Int -> Bool
- GHC.Prelude: toEnum :: Enum a => Int -> a
- GHC.Prelude: toInteger :: Integral a => a -> Integer
- GHC.Prelude: toIntegralSized :: (Integral a, Integral b, Bits a, Bits b) => a -> Maybe b
- GHC.Prelude: toRational :: Real a => a -> Rational
- GHC.Prelude: traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
- GHC.Prelude: truncate :: (RealFrac a, Integral b) => a -> b
- GHC.Prelude: type FilePath = String
- GHC.Prelude: type IOError = IOException
- GHC.Prelude: type Rational = Ratio Integer
- GHC.Prelude: type ReadS a = String -> [(a, String)]
- GHC.Prelude: type ShowS = String -> String
- GHC.Prelude: type String = [Char]
- GHC.Prelude: uncurry :: (a -> b -> c) -> (a, b) -> c
- GHC.Prelude: undefined :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a
- GHC.Prelude: unlines :: [String] -> String
- GHC.Prelude: unsafeShiftL :: Bits a => a -> Int -> a
- GHC.Prelude: unsafeShiftR :: Bits a => a -> Int -> a
- GHC.Prelude: until :: (a -> Bool) -> (a -> a) -> a -> a
- GHC.Prelude: unwords :: [String] -> String
- GHC.Prelude: unzip :: [(a, b)] -> ([a], [b])
- GHC.Prelude: unzip3 :: [(a, b, c)] -> ([a], [b], [c])
- GHC.Prelude: userError :: String -> IOError
- GHC.Prelude: words :: String -> [String]
- GHC.Prelude: writeFile :: FilePath -> String -> IO ()
- GHC.Prelude: xor :: Bits a => a -> a -> a
- GHC.Prelude: zeroBits :: Bits a => a
- GHC.Prelude: zip :: [a] -> [b] -> [(a, b)]
- GHC.Prelude: zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
- GHC.Prelude: zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
- GHC.Prelude: zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
- GHC.Runtime.Context: icPrintUnqual :: UnitEnv -> InteractiveContext -> PrintUnqualified
- GHC.Tc.Solver.InertSet: matchableGivens :: CtLoc -> PredType -> InertSet -> Cts
- GHC.Tc.Types.Constraint: [cc_fundeps] :: Ct -> Bool
- GHC.Tc.Types.Constraint: isPendingScInst :: QCInst -> Maybe QCInst
- GHC.Tc.Types.Evidence: isTcReflCo :: TcCoercion -> Bool
- GHC.Tc.Types.Evidence: isTcReflexiveCo :: TcCoercion -> Bool
- GHC.Tc.Types.Evidence: maybeTcSubCo :: HasDebugCallStack => EqRel -> TcCoercionN -> TcCoercion
- GHC.Tc.Types.Evidence: maybeTcSymCo :: SwapFlag -> TcCoercion -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcAppCo :: TcCoercion -> TcCoercionN -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcAxInstCo :: Role -> CoAxiom br -> BranchIndex -> [TcType] -> [TcCoercion] -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcAxiomRuleCo :: CoAxiomRule -> [TcCoercion] -> TcCoercionR
- GHC.Tc.Types.Evidence: mkTcCoVarCo :: CoVar -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcCoherenceLeftCo :: Role -> TcType -> TcCoercionN -> TcCoercion -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcCoherenceRightCo :: Role -> TcType -> TcCoercionN -> TcCoercion -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcForAllCo :: TyVar -> TcCoercionN -> TcCoercion -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcForAllCos :: [(TyVar, TcCoercionN)] -> TcCoercion -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcFunCo :: Role -> TcCoercion -> TcCoercion -> TcCoercion -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcGReflLeftCo :: Role -> TcType -> TcCoercionN -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcGReflLeftMCo :: Role -> TcType -> TcMCoercionN -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcGReflRightCo :: Role -> TcType -> TcCoercionN -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcGReflRightMCo :: Role -> TcType -> TcMCoercionN -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcKindCo :: TcCoercion -> TcCoercionN
- GHC.Tc.Types.Evidence: mkTcLRCo :: LeftOrRight -> TcCoercion -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcNomReflCo :: TcType -> TcCoercionN
- GHC.Tc.Types.Evidence: mkTcNthCo :: Role -> Int -> TcCoercion -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcPhantomCo :: TcCoercionN -> TcType -> TcType -> TcCoercionP
- GHC.Tc.Types.Evidence: mkTcReflCo :: Role -> TcType -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcRepReflCo :: TcType -> TcCoercionR
- GHC.Tc.Types.Evidence: mkTcSubCo :: HasDebugCallStack => TcCoercionN -> TcCoercionR
- GHC.Tc.Types.Evidence: mkTcSymCo :: TcCoercion -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcSymMCo :: TcMCoercion -> TcMCoercion
- GHC.Tc.Types.Evidence: mkTcTransCo :: TcCoercion -> TcCoercion -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcTyConAppCo :: Role -> TyCon -> [TcCoercion] -> TcCoercion
- GHC.Tc.Types.Evidence: mkTcUnbranchedAxInstCo :: CoAxiom Unbranched -> [TcType] -> [TcCoercion] -> TcCoercionR
- GHC.Tc.Types.Evidence: mkWpLams :: [Var] -> HsWrapper
- GHC.Tc.Types.Evidence: tcCoercionKind :: TcCoercion -> Pair TcType
- GHC.Tc.Types.Evidence: tcCoercionRole :: TcCoercion -> Role
- GHC.Tc.Types.Evidence: tcDowngradeRole :: Role -> Role -> TcCoercion -> TcCoercion
- GHC.Tc.Utils.TcType: InvisArg :: AnonArgFlag
- GHC.Tc.Utils.TcType: VisArg :: AnonArgFlag
- GHC.Tc.Utils.TcType: classifiesTypeWithValues :: Kind -> Bool
- GHC.Tc.Utils.TcType: data AnonArgFlag
- GHC.Tc.Utils.TcType: data ArgFlag
- GHC.Tc.Utils.TcType: data TyCoBinder
- GHC.Tc.Utils.TcType: isInvisibleBinder :: TyCoBinder -> Bool
- GHC.Tc.Utils.TcType: isVisibleBinder :: TyCoBinder -> Bool
- GHC.Tc.Utils.TcType: mkInvisFunTyMany :: Type -> Type -> Type
- GHC.Tc.Utils.TcType: mkInvisFunTysMany :: [Type] -> Type -> Type
- GHC.Tc.Utils.TcType: mkTcAppTy :: Type -> Type -> Type
- GHC.Tc.Utils.TcType: mkTcAppTys :: Type -> [Type] -> Type
- GHC.Tc.Utils.TcType: mkTcCastTy :: Type -> Coercion -> Type
- GHC.Tc.Utils.TcType: mkVisFunTys :: [Scaled Type] -> Type -> Type
- GHC.Tc.Utils.TcType: tcGetCastedTyVar_maybe :: Type -> Maybe (TyVar, CoercionN)
- GHC.Tc.Utils.TcType: tcGetTyVar :: String -> Type -> TyVar
- GHC.Tc.Utils.TcType: tcGetTyVar_maybe :: Type -> Maybe TyVar
- GHC.Tc.Utils.TcType: tcIsForAllTy :: Type -> Bool
- GHC.Tc.Utils.TcType: tcRepGetNumAppTys :: Type -> Arity
- GHC.Tc.Utils.TcType: tcRepSplitAppTy_maybe :: Type -> Maybe (Type, Type)
- GHC.Tc.Utils.TcType: tcTypeKind :: HasDebugCallStack => Type -> Kind
- GHC.Tc.Utils.TcType: tcView :: Type -> Maybe Type
- GHC.Types.Id.Make: mkDictFunTy :: [TyVar] -> ThetaType -> Class -> [Type] -> Type
- GHC.Types.Name.Ppr: mkPrintUnqualified :: UnitEnv -> GlobalRdrEnv -> PrintUnqualified
- GHC.Types.Var: InvisArg :: AnonArgFlag
- GHC.Types.Var: VisArg :: AnonArgFlag
- GHC.Types.Var: binderArgFlag :: VarBndr tv argf -> argf
- GHC.Types.Var: data AnonArgFlag
- GHC.Types.Var: data ArgFlag
- GHC.Types.Var: instance Data.Data.Data GHC.Types.Var.AnonArgFlag
- GHC.Types.Var: instance Data.Data.Data GHC.Types.Var.ArgFlag
- GHC.Types.Var: instance GHC.Classes.Eq GHC.Types.Var.AnonArgFlag
- GHC.Types.Var: instance GHC.Classes.Eq GHC.Types.Var.ArgFlag
- GHC.Types.Var: instance GHC.Classes.Ord GHC.Types.Var.AnonArgFlag
- GHC.Types.Var: instance GHC.Classes.Ord GHC.Types.Var.ArgFlag
- GHC.Types.Var: instance GHC.Utils.Binary.Binary GHC.Types.Var.AnonArgFlag
- GHC.Types.Var: instance GHC.Utils.Binary.Binary GHC.Types.Var.ArgFlag
- GHC.Types.Var: instance GHC.Utils.Outputable.Outputable GHC.Types.Var.AnonArgFlag
- GHC.Types.Var: instance GHC.Utils.Outputable.Outputable GHC.Types.Var.ArgFlag
- GHC.Types.Var: instance GHC.Utils.Outputable.Outputable tv => GHC.Utils.Outputable.Outputable (GHC.Types.Var.VarBndr tv GHC.Types.Var.ArgFlag)
- GHC.Types.Var: isInferredArgFlag :: ArgFlag -> Bool
- GHC.Types.Var: isInvisibleArgFlag :: ArgFlag -> Bool
- GHC.Types.Var: isVisibleArgFlag :: ArgFlag -> Bool
- GHC.Types.Var: mkTyCoVarBinder :: vis -> TyCoVar -> VarBndr TyCoVar vis
- GHC.Types.Var: mkTyCoVarBinders :: vis -> [TyCoVar] -> [VarBndr TyCoVar vis]
- GHC.Types.Var: sameVis :: ArgFlag -> ArgFlag -> Bool
- GHC.Types.Var: type TyCoVarBinder = VarBndr TyCoVar ArgFlag
- GHC.Utils.Misc: zipLazy :: [a] -> [b] -> [(a, b)]
- GHC.Utils.Misc: zipWith3Lazy :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
- GHC.Utils.Misc: zipWithLazy :: (a -> b -> c) -> [a] -> [b] -> [c]
- GHC.Utils.Outputable: data PrintUnqualified
+ GHC.Builtin.Names: absentConstraintErrorIdKey :: Unique
+ GHC.Builtin.Names: allNameStringList :: [String]
+ GHC.Builtin.Names: cONSTRAINTTyConKey :: Unique
+ GHC.Builtin.Names: ccArrowTyConKey :: Unique
+ GHC.Builtin.Names: constPtrConName :: Name
+ GHC.Builtin.Names: constPtrTyConKey :: Unique
+ GHC.Builtin.Names: constraintKindRepKey :: Unique
+ GHC.Builtin.Names: constraintKindRepName :: Name
+ GHC.Builtin.Names: ctArrowTyConKey :: Unique
+ GHC.Builtin.Names: dictTyConKey :: Unique
+ GHC.Builtin.Names: fOREIGN_C_TYPES :: Module
+ GHC.Builtin.Names: fUNTyConKey :: Unique
+ GHC.Builtin.Names: mkDictDataConKey :: Unique
+ GHC.Builtin.Names: noinlineConstraintIdKey :: Unique
+ GHC.Builtin.Names: nonEmptyTyConName :: Name
+ GHC.Builtin.Names: tcArrowTyConKey :: Unique
+ GHC.Builtin.PrimOps: pprPrimOp :: IsLine doc => PrimOp -> doc
+ GHC.Builtin.PrimOps: primOpIsReallyInline :: PrimOp -> Bool
+ GHC.Builtin.Types: BI_Box :: DataCon -> Expr b -> Type -> BoxingInfo b
+ GHC.Builtin.Types: BI_NoBoxAvailable :: BoxingInfo b
+ GHC.Builtin.Types: BI_NoBoxNeeded :: BoxingInfo b
+ GHC.Builtin.Types: [bi_boxed_type] :: BoxingInfo b -> Type
+ GHC.Builtin.Types: [bi_data_con] :: BoxingInfo b -> DataCon
+ GHC.Builtin.Types: [bi_inst_con] :: BoxingInfo b -> Expr b
+ GHC.Builtin.Types: boxingDataCon :: Type -> BoxingInfo b
+ GHC.Builtin.Types: cONSTRAINTKind :: Type
+ GHC.Builtin.Types: cONSTRAINTTyCon :: TyCon
+ GHC.Builtin.Types: cONSTRAINTTyConName :: Name
+ GHC.Builtin.Types: data BoxingInfo b
+ GHC.Builtin.Types: mkConstraintTupleTy :: [Type] -> Type
+ GHC.Builtin.Types: tYPEKind :: Type
+ GHC.Builtin.Types: tYPETyCon :: TyCon
+ GHC.Builtin.Types: tYPETyConName :: Name
+ GHC.Builtin.Types.Prim: alphaConstraintTy :: Type
+ GHC.Builtin.Types.Prim: alphaConstraintTyVar :: TyVar
+ GHC.Builtin.Types.Prim: cONSTRAINTKind :: Type
+ GHC.Builtin.Types.Prim: cONSTRAINTTyCon :: TyCon
+ GHC.Builtin.Types.Prim: cONSTRAINTTyConName :: Name
+ GHC.Builtin.Types.Prim: ccArrowTyCon :: TyCon
+ GHC.Builtin.Types.Prim: ccArrowTyConName :: Name
+ GHC.Builtin.Types.Prim: ctArrowTyCon :: TyCon
+ GHC.Builtin.Types.Prim: ctArrowTyConName :: Name
+ GHC.Builtin.Types.Prim: fUNTyCon :: TyCon
+ GHC.Builtin.Types.Prim: fUNTyConName :: Name
+ GHC.Builtin.Types.Prim: funTyFlagTyCon :: FunTyFlag -> TyCon
+ GHC.Builtin.Types.Prim: isArrowTyCon :: TyCon -> Bool
+ GHC.Builtin.Types.Prim: tYPEKind :: Type
+ GHC.Builtin.Types.Prim: tcArrowTyCon :: TyCon
+ GHC.Builtin.Types.Prim: tcArrowTyConName :: Name
+ GHC.Builtin.Uniques: boxingDataConUnique :: Unique -> Unique
+ GHC.Builtin.Uniques: mkBoxingTyConUnique :: Int -> Unique
+ GHC.Cmm.Reg: pprGlobalReg :: IsLine doc => GlobalReg -> doc
+ GHC.Core.Coercion: SelArg :: FunSel
+ GHC.Core.Coercion: SelForAll :: CoSel
+ GHC.Core.Coercion: SelFun :: FunSel -> CoSel
+ GHC.Core.Coercion: SelMult :: FunSel
+ GHC.Core.Coercion: SelRes :: FunSel
+ GHC.Core.Coercion: SelTyCon :: Int -> Role -> CoSel
+ GHC.Core.Coercion: data CoSel
+ GHC.Core.Coercion: data FunSel
+ GHC.Core.Coercion: funRole :: Role -> FunSel -> Role
+ GHC.Core.Coercion: getNthFromType :: HasDebugCallStack => CoSel -> Type -> Type
+ GHC.Core.Coercion: getNthFun :: FunSel -> a -> a -> a -> a
+ GHC.Core.Coercion: mkFunCo1 :: HasDebugCallStack => Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion
+ GHC.Core.Coercion: mkFunCo2 :: HasDebugCallStack => Role -> FunTyFlag -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion
+ GHC.Core.Coercion: mkFunCoNoFTF :: HasDebugCallStack => Role -> CoercionN -> Coercion -> Coercion -> Coercion
+ GHC.Core.Coercion: mkNakedFunCo1 :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion
+ GHC.Core.Coercion: mkNakedFunCo2 :: Role -> FunTyFlag -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion
+ GHC.Core.Coercion: mkRuntimeRepCo :: HasDebugCallStack => Coercion -> Coercion
+ GHC.Core.Coercion: mkSelCo :: HasDebugCallStack => CoSel -> Coercion -> Coercion
+ GHC.Core.Coercion: tyConRole :: Role -> TyCon -> Int -> Role
+ GHC.Core.Coercion: tyConRoleListRepresentational :: TyCon -> [Role]
+ GHC.Core.Coercion: tyConRoleListX :: Role -> TyCon -> [Role]
+ GHC.Core.DataCon: checkDataConTyVars :: DataCon -> Bool
+ GHC.Core.DataCon: dataConResRepTyArgs :: DataCon -> [Type]
+ GHC.Core.DataCon: dataConUserTyVarsNeedWrapper :: DataCon -> Bool
+ GHC.Core.DataCon: isCovertGadtDataCon :: DataCon -> Bool
+ GHC.Core.FVs: exprFVs :: CoreExpr -> FV
+ GHC.Core.Lint: [ep_namePprCtx] :: EndPassConfig -> !NamePprCtx
+ GHC.Core.Make: chunkify :: [a] -> [[a]]
+ GHC.Core.Make: mkBigCoreVarTupSolo :: [Id] -> CoreExpr
+ GHC.Core.Make: mkBigTupleCase :: UniqSupply -> [Id] -> CoreExpr -> CoreExpr -> CoreExpr
+ GHC.Core.Make: mkBigTupleSelector :: [Id] -> Id -> Id -> CoreExpr -> CoreExpr
+ GHC.Core.Make: mkBigTupleSelectorSolo :: [Id] -> Id -> Id -> CoreExpr -> CoreExpr
+ GHC.Core.Make: mkChunkified :: ([a] -> a) -> [a] -> a
+ GHC.Core.Make: mkCoreUnboxedSum :: Int -> Int -> [Type] -> CoreExpr -> CoreExpr
+ GHC.Core.Make: mkCoreUnboxedTuple :: [CoreExpr] -> CoreExpr
+ GHC.Core.Multiplicity: pattern ManyTy :: Mult
+ GHC.Core.Multiplicity: pattern OneTy :: Mult
+ GHC.Core.Multiplicity: pprArrowWithMultiplicity :: FunTyFlag -> Either Bool SDoc -> SDoc
+ GHC.Core.Opt.Monad: getNamePprCtx :: CoreM NamePprCtx
+ GHC.Core.Opt.Monad: initRuleEnv :: ModGuts -> CoreM RuleEnv
+ GHC.Core.Opt.Simplify: [so_hpt_rules] :: SimplifyOpts -> !RuleBase
+ GHC.Core.RoughMap: instanceCantMatch :: [RoughMatchTc] -> [RoughMatchTc] -> Bool
+ GHC.Core.RoughMap: roughMatchTcs :: [Type] -> [RoughMatchTc]
+ GHC.Core.RoughMap: roughMatchTcsLookup :: [Type] -> [RoughMatchLookupTc]
+ GHC.Core.Rules: RuleEnv :: !RuleBase -> !RuleBase -> !RuleBase -> !ModuleSet -> RuleEnv
+ GHC.Core.Rules: [re_eps_rules] :: RuleEnv -> !RuleBase
+ GHC.Core.Rules: [re_home_rules] :: RuleEnv -> !RuleBase
+ GHC.Core.Rules: [re_local_rules] :: RuleEnv -> !RuleBase
+ GHC.Core.Rules: [re_visible_orphs] :: RuleEnv -> !ModuleSet
+ GHC.Core.Rules: addLocalRules :: RuleEnv -> [CoreRule] -> RuleEnv
+ GHC.Core.Rules: data RuleEnv
+ GHC.Core.Rules: emptyRuleEnv :: RuleEnv
+ GHC.Core.Rules: mkRuleEnv :: ModGuts -> RuleBase -> RuleBase -> RuleEnv
+ GHC.Core.Rules: type RuleBase = NameEnv [CoreRule]
+ GHC.Core.Rules: updExternalPackageRules :: RuleEnv -> RuleBase -> RuleEnv
+ GHC.Core.Rules: updLocalRules :: RuleEnv -> [CoreRule] -> RuleEnv
+ GHC.Core.TyCo.Compare: cmpForAllVis :: ForAllTyFlag -> ForAllTyFlag -> Ordering
+ GHC.Core.TyCo.Compare: eqForAllVis :: ForAllTyFlag -> ForAllTyFlag -> Bool
+ GHC.Core.TyCo.Compare: eqType :: Type -> Type -> Bool
+ GHC.Core.TyCo.Compare: eqTypeX :: RnEnv2 -> Type -> Type -> Bool
+ GHC.Core.TyCo.Compare: eqTypes :: [Type] -> [Type] -> Bool
+ GHC.Core.TyCo.Compare: eqVarBndrs :: RnEnv2 -> [Var] -> [Var] -> Maybe RnEnv2
+ GHC.Core.TyCo.Compare: instance GHC.Classes.Eq GHC.Core.TyCo.Compare.TypeOrdering
+ GHC.Core.TyCo.Compare: instance GHC.Classes.Ord GHC.Core.TyCo.Compare.TypeOrdering
+ GHC.Core.TyCo.Compare: instance GHC.Enum.Bounded GHC.Core.TyCo.Compare.TypeOrdering
+ GHC.Core.TyCo.Compare: instance GHC.Enum.Enum GHC.Core.TyCo.Compare.TypeOrdering
+ GHC.Core.TyCo.Compare: nonDetCmpTc :: TyCon -> TyCon -> Ordering
+ GHC.Core.TyCo.Compare: nonDetCmpType :: Type -> Type -> Ordering
+ GHC.Core.TyCo.Compare: nonDetCmpTypeX :: RnEnv2 -> Type -> Type -> Ordering
+ GHC.Core.TyCo.Compare: nonDetCmpTypes :: [Type] -> [Type] -> Ordering
+ GHC.Core.TyCo.Compare: nonDetCmpTypesX :: RnEnv2 -> [Type] -> [Type] -> Ordering
+ GHC.Core.TyCo.Compare: pickyEqType :: Type -> Type -> Bool
+ GHC.Core.TyCo.Compare: tcEqKind :: HasDebugCallStack => Kind -> Kind -> Bool
+ GHC.Core.TyCo.Compare: tcEqTyConApps :: TyCon -> [Type] -> TyCon -> [Type] -> Bool
+ GHC.Core.TyCo.Compare: tcEqType :: HasDebugCallStack => Type -> Type -> Bool
+ GHC.Core.TyCo.Compare: tcEqTypeNoKindCheck :: Type -> Type -> Bool
+ GHC.Core.TyCo.Compare: tcEqTypeVis :: Type -> Type -> Bool
+ GHC.Core.TyCo.FVs: occCheckExpand :: [Var] -> Type -> Maybe Type
+ GHC.Core.TyCo.FVs: tyConsOfType :: Type -> UniqSet TyCon
+ GHC.Core.TyCo.FVs: visVarsOfType :: Type -> Pair TyCoVarSet
+ GHC.Core.TyCo.FVs: visVarsOfTypes :: [Type] -> Pair TyCoVarSet
+ GHC.Core.TyCo.Rep: FTF_C_C :: FunTyFlag
+ GHC.Core.TyCo.Rep: FTF_C_T :: FunTyFlag
+ GHC.Core.TyCo.Rep: FTF_T_C :: FunTyFlag
+ GHC.Core.TyCo.Rep: FTF_T_T :: FunTyFlag
+ GHC.Core.TyCo.Rep: SelArg :: FunSel
+ GHC.Core.TyCo.Rep: SelCo :: CoSel -> Coercion -> Coercion
+ GHC.Core.TyCo.Rep: SelForAll :: CoSel
+ GHC.Core.TyCo.Rep: SelFun :: FunSel -> CoSel
+ GHC.Core.TyCo.Rep: SelMult :: FunSel
+ GHC.Core.TyCo.Rep: SelRes :: FunSel
+ GHC.Core.TyCo.Rep: SelTyCon :: Int -> Role -> CoSel
+ GHC.Core.TyCo.Rep: [fco_afl] :: Coercion -> FunTyFlag
+ GHC.Core.TyCo.Rep: [fco_afr] :: Coercion -> FunTyFlag
+ GHC.Core.TyCo.Rep: [fco_arg, fco_res] :: Coercion -> Coercion
+ GHC.Core.TyCo.Rep: [fco_mult] :: Coercion -> CoercionN
+ GHC.Core.TyCo.Rep: [fco_role] :: Coercion -> Role
+ GHC.Core.TyCo.Rep: data CoSel
+ GHC.Core.TyCo.Rep: data ForAllTyFlag
+ GHC.Core.TyCo.Rep: data FunSel
+ GHC.Core.TyCo.Rep: data FunTyFlag
+ GHC.Core.TyCo.Rep: instance Control.DeepSeq.NFData GHC.Core.TyCo.Rep.CoSel
+ GHC.Core.TyCo.Rep: instance Data.Data.Data GHC.Core.TyCo.Rep.CoSel
+ GHC.Core.TyCo.Rep: instance Data.Data.Data GHC.Core.TyCo.Rep.FunSel
+ GHC.Core.TyCo.Rep: instance GHC.Classes.Eq GHC.Core.TyCo.Rep.CoSel
+ GHC.Core.TyCo.Rep: instance GHC.Classes.Eq GHC.Core.TyCo.Rep.FunSel
+ GHC.Core.TyCo.Rep: instance GHC.Utils.Binary.Binary GHC.Core.TyCo.Rep.CoSel
+ GHC.Core.TyCo.Rep: instance GHC.Utils.Outputable.Outputable GHC.Core.TyCo.Rep.CoSel
+ GHC.Core.TyCo.Rep: instance GHC.Utils.Outputable.Outputable GHC.Core.TyCo.Rep.FunSel
+ GHC.Core.TyCo.Rep: mkInvisFunTys :: HasDebugCallStack => [Type] -> Type -> Type
+ GHC.Core.TyCo.Rep: mkNakedFunTy :: FunTyFlag -> Kind -> Kind -> Kind
+ GHC.Core.TyCo.Rep: mkScaledFunTys :: HasDebugCallStack => [Scaled Type] -> Type -> Type
+ GHC.Core.TyCo.Rep: tcMkInvisFunTy :: TypeOrConstraint -> Type -> Type -> Type
+ GHC.Core.TyCo.Rep: tcMkScaledFunTys :: [Scaled Type] -> Type -> Type
+ GHC.Core.TyCo.Rep: tcMkVisFunTy :: Mult -> Type -> Type -> Type
+ GHC.Core.TyCo.Rep: type LevityType = Type
+ GHC.Core.TyCo.Subst: substTyVarToTyVar :: HasDebugCallStack => Subst -> TyVar -> TyVar
+ GHC.Core.TyCo.Tidy: tidyForAllTyBinder :: TidyEnv -> VarBndr TyCoVar vis -> (TidyEnv, VarBndr TyCoVar vis)
+ GHC.Core.TyCo.Tidy: tidyForAllTyBinders :: TidyEnv -> [VarBndr TyCoVar vis] -> (TidyEnv, [VarBndr TyCoVar vis])
+ GHC.Core.TyCon: Levity :: Levity -> PromDataConInfo
+ GHC.Core.TyCon: NoPromInfo :: PromDataConInfo
+ GHC.Core.TyCon: [is_type_data] :: AlgTyConRhs -> Bool
+ GHC.Core.TyCon: data PromDataConInfo
+ GHC.Core.TyCon: isDataKindsPromotedDataCon :: TyCon -> Bool
+ GHC.Core.TyCon: isTypeDataTyCon :: TyCon -> Bool
+ GHC.Core.TyCon: mkInvisAnonTyConBinder :: TyVar -> TyConBinder
+ GHC.Core.TyCon: mkTyConTy :: TyCon -> Type
+ GHC.Core.TyCon: primRepIsInt :: PrimRep -> Bool
+ GHC.Core.TyCon: primRepIsWord :: PrimRep -> Bool
+ GHC.Core.TyCon: tyConBinderForAllTyFlag :: TyConBinder -> ForAllTyFlag
+ GHC.Core.TyCon: tyConBndrVisForAllTyFlag :: TyConBndrVis -> ForAllTyFlag
+ GHC.Core.TyCon: tyConMustBeSaturated :: TyCon -> Bool
+ GHC.Core.TyCon: tyConPromDataConInfo :: TyCon -> PromDataConInfo
+ GHC.Core.TyCon: type TyConPiTyBinder = VarBndr TyCoVar TyConBndrVis
+ GHC.Core.Type: FTF_C_C :: FunTyFlag
+ GHC.Core.Type: FTF_C_T :: FunTyFlag
+ GHC.Core.Type: FTF_T_C :: FunTyFlag
+ GHC.Core.Type: FTF_T_T :: FunTyFlag
+ GHC.Core.Type: anonPiTyBinderType_maybe :: PiTyBinder -> Maybe Type
+ GHC.Core.Type: appTyForAllTyFlags :: Type -> [Type] -> [ForAllTyFlag]
+ GHC.Core.Type: binderFlag :: VarBndr tv argf -> argf
+ GHC.Core.Type: binderFlags :: [VarBndr tv argf] -> [argf]
+ GHC.Core.Type: chooseFunTyFlag :: HasDebugCallStack => Type -> Type -> FunTyFlag
+ GHC.Core.Type: data ForAllTyFlag
+ GHC.Core.Type: data FunTyFlag
+ GHC.Core.Type: data PiTyBinder
+ GHC.Core.Type: funTyConAppTy_maybe :: FunTyFlag -> Type -> Type -> Type -> Maybe (TyCon, [Type])
+ GHC.Core.Type: funTyFlagTyCon :: FunTyFlag -> TyCon
+ GHC.Core.Type: isAnonPiTyBinder :: PiTyBinder -> Bool
+ GHC.Core.Type: isConstraintKind :: Kind -> Bool
+ GHC.Core.Type: isConstraintLikeKind :: Kind -> Bool
+ GHC.Core.Type: isInvisibleForAllTyFlag :: ForAllTyFlag -> Bool
+ GHC.Core.Type: isInvisiblePiTyBinder :: PiTyBinder -> Bool
+ GHC.Core.Type: isManyTy :: Mult -> Bool
+ GHC.Core.Type: isNamedPiTyBinder :: PiTyBinder -> Bool
+ GHC.Core.Type: isOneTy :: Mult -> Bool
+ GHC.Core.Type: isTYPEorCONSTRAINT :: Kind -> Bool
+ GHC.Core.Type: isTypeLikeKind :: Kind -> Bool
+ GHC.Core.Type: isVisibleForAllTyFlag :: ForAllTyFlag -> Bool
+ GHC.Core.Type: isVisiblePiTyBinder :: PiTyBinder -> Bool
+ GHC.Core.Type: levityType_maybe :: LevityType -> Maybe Levity
+ GHC.Core.Type: mkBoxedRepApp_maybe :: LevityType -> Maybe Type
+ GHC.Core.Type: mkCONSTRAINTapp :: RuntimeRepType -> Type
+ GHC.Core.Type: mkCONSTRAINTapp_maybe :: RuntimeRepType -> Maybe Type
+ GHC.Core.Type: mkForAllTyBinder :: vis -> TyCoVar -> VarBndr TyCoVar vis
+ GHC.Core.Type: mkForAllTyBinders :: vis -> [TyCoVar] -> [VarBndr TyCoVar vis]
+ GHC.Core.Type: mkFunctionType :: Mult -> Type -> Type -> Type
+ GHC.Core.Type: mkInvisFunTys :: HasDebugCallStack => [Type] -> Type -> Type
+ GHC.Core.Type: mkScaledFunTys :: HasDebugCallStack => [Scaled Type] -> Type -> Type
+ GHC.Core.Type: mkScaledFunctionTys :: [Scaled Type] -> Type -> Type
+ GHC.Core.Type: mkTYPEapp_maybe :: RuntimeRepType -> Maybe Type
+ GHC.Core.Type: mkTupleRepApp_maybe :: Type -> Maybe Type
+ GHC.Core.Type: namedPiTyBinder_maybe :: PiTyBinder -> Maybe TyCoVar
+ GHC.Core.Type: pattern ManyTy :: Mult
+ GHC.Core.Type: pattern OneTy :: Mult
+ GHC.Core.Type: piTyBinderType :: PiTyBinder -> Type
+ GHC.Core.Type: returnsConstraintKind :: Kind -> Bool
+ GHC.Core.Type: sORTKind_maybe :: Kind -> Maybe (TypeOrConstraint, Type)
+ GHC.Core.Type: splitAppTyNoView_maybe :: HasDebugCallStack => Type -> Maybe (Type, Type)
+ GHC.Core.Type: splitAppTysNoView :: HasDebugCallStack => Type -> (Type, [Type])
+ GHC.Core.Type: splitForAllForAllTyBinders :: Type -> ([ForAllTyBinder], Type)
+ GHC.Core.Type: splitForAllInvisTyBinders :: Type -> ([InvisTyBinder], Type)
+ GHC.Core.Type: splitForAllReqTyBinders :: Type -> ([ReqTyBinder], Type)
+ GHC.Core.Type: splitRuntimeRep_maybe :: RuntimeRepType -> Maybe (TyCon, [Type])
+ GHC.Core.Type: splitTyConAppNoView_maybe :: Type -> Maybe (TyCon, [Type])
+ GHC.Core.Type: substTyVarToTyVar :: HasDebugCallStack => Subst -> TyVar -> TyVar
+ GHC.Core.Type: tcMkInvisFunTy :: TypeOrConstraint -> Type -> Type -> Type
+ GHC.Core.Type: tcMkScaledFunTys :: [Scaled Type] -> Type -> Type
+ GHC.Core.Type: tcMkVisFunTy :: Mult -> Type -> Type -> Type
+ GHC.Core.Type: tcSplitAppTyNoView_maybe :: Type -> Maybe (Type, Type)
+ GHC.Core.Type: tcSplitTyConApp :: Type -> (TyCon, [Type])
+ GHC.Core.Type: tidyForAllTyBinder :: TidyEnv -> VarBndr TyCoVar vis -> (TidyEnv, VarBndr TyCoVar vis)
+ GHC.Core.Type: tidyForAllTyBinders :: TidyEnv -> [VarBndr TyCoVar vis] -> (TidyEnv, [VarBndr TyCoVar vis])
+ GHC.Core.Type: tyConAppFunCo_maybe :: HasDebugCallStack => Role -> TyCon -> [Coercion] -> Maybe Coercion
+ GHC.Core.Type: tyConAppFunTy_maybe :: HasDebugCallStack => TyCon -> [Type] -> Maybe Type
+ GHC.Core.Type: tyConBindersPiTyBinders :: [TyConBinder] -> [PiTyBinder]
+ GHC.Core.Type: tyConForAllTyFlags :: TyCon -> [Type] -> [ForAllTyFlag]
+ GHC.Core.Type: type ForAllTyBinder = VarBndr TyCoVar ForAllTyFlag
+ GHC.Core.Type: type RuntimeRepType = Type
+ GHC.Core.Type: typeOrConstraintKind :: TypeOrConstraint -> RuntimeRepType -> Kind
+ GHC.Core.Type: typeTypeOrConstraint :: HasDebugCallStack => Type -> TypeOrConstraint
+ GHC.Core.Unify: typesAreApart :: Type -> Type -> Bool
+ GHC.CoreToIface: toIfaceForAllBndrs :: [VarBndr TyCoVar vis] -> [VarBndr IfaceBndr vis]
+ GHC.Data.FastString: unpackPtrStringTakeN :: Int -> PtrString -> String
+ GHC.Data.FastString: zStringTakeN :: Int -> FastZString -> String
+ GHC.Data.Graph.Directed: graphFromVerticesAndAdjacency :: Ord key => [Node key payload] -> [(key, key)] -> Graph (Node key payload)
+ GHC.Data.Graph.UnVar: domUFMUnVarSet :: UniqFM key elt -> UnVarSet
+ GHC.Data.List.Infinite: (!!) :: Infinite a -> Int -> a
+ GHC.Data.List.Infinite: (++) :: Foldable f => f a -> Infinite a -> Infinite a
+ GHC.Data.List.Infinite: Inf :: a -> Infinite a -> Infinite a
+ GHC.Data.List.Infinite: allListsOf :: [a] -> Infinite [a]
+ GHC.Data.List.Infinite: concatMap :: Foldable f => (a -> f b) -> Infinite a -> Infinite b
+ GHC.Data.List.Infinite: data Infinite a
+ GHC.Data.List.Infinite: dropList :: [a] -> Infinite b -> Infinite b
+ GHC.Data.List.Infinite: filter :: (a -> Bool) -> Infinite a -> Infinite a
+ GHC.Data.List.Infinite: groupBy :: (a -> a -> Bool) -> Infinite a -> Infinite (NonEmpty a)
+ GHC.Data.List.Infinite: head :: Infinite a -> a
+ GHC.Data.List.Infinite: infixr 5 ++
+ GHC.Data.List.Infinite: instance Data.Foldable.Foldable GHC.Data.List.Infinite.Infinite
+ GHC.Data.List.Infinite: instance Data.Traversable.Traversable GHC.Data.List.Infinite.Infinite
+ GHC.Data.List.Infinite: instance GHC.Base.Applicative GHC.Data.List.Infinite.Infinite
+ GHC.Data.List.Infinite: instance GHC.Base.Functor GHC.Data.List.Infinite.Infinite
+ GHC.Data.List.Infinite: iterate :: (a -> a) -> a -> Infinite a
+ GHC.Data.List.Infinite: repeat :: a -> Infinite a
+ GHC.Data.List.Infinite: tail :: Infinite a -> Infinite a
+ GHC.Data.List.Infinite: toList :: Infinite a -> [a]
+ GHC.Data.List.Infinite: unfoldr :: (b -> (a, b)) -> b -> Infinite a
+ GHC.Data.ShortText: singleton :: Char -> ShortText
+ GHC.Driver.Backend: JSAssemblerInfoGetter :: DefunctionalizedAssemblerInfoGetter
+ GHC.Driver.Backend: JSAssemblerProg :: DefunctionalizedAssemblerProg
+ GHC.Driver.Backend: JSCodeOutput :: DefunctionalizedCodeOutput
+ GHC.Driver.Backend: JSPostHscPipeline :: DefunctionalizedPostHscPipeline
+ GHC.Driver.Backend: JSPrimitives :: PrimitiveImplementation
+ GHC.Driver.Backend: backendUseJSLinker :: Backend -> Bool
+ GHC.Driver.Backend: jsBackend :: Backend
+ GHC.Driver.Backend.Internal: JavaScript :: BackendName
+ GHC.Driver.Flags: Opt_D_dump_js :: DumpFlag
+ GHC.Driver.Flags: Opt_PrintRedundantPromotionTicks :: GeneralFlag
+ GHC.Driver.Flags: Opt_SuppressStgReps :: GeneralFlag
+ GHC.Driver.Phases: Js :: Phase
+ GHC.Driver.Pipeline.Phases: [T_Js] :: PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> TPhase FilePath
+ GHC.Driver.Session: Emscripten :: CompilerInfo
+ GHC.Driver.Session: Opt_D_dump_js :: DumpFlag
+ GHC.Driver.Session: Opt_PrintRedundantPromotionTicks :: GeneralFlag
+ GHC.Driver.Session: Opt_SuppressStgReps :: GeneralFlag
+ GHC.Driver.Session: initPromotionTickContext :: DynFlags -> PromotionTickContext
+ GHC.ForeignSrcLang.Type: LangJs :: ForeignSrcLang
+ GHC.Hs.Expr: pprStmtCat :: Stmt (GhcPass p) body -> SDoc
+ GHC.Hs.Instances: instance Data.Data.Data a => Data.Data.Data (GHC.Hs.Expr.HsUntypedSpliceResult a)
+ GHC.Iface.Type: FTF_C_C :: FunTyFlag
+ GHC.Iface.Type: FTF_C_T :: FunTyFlag
+ GHC.Iface.Type: FTF_T_C :: FunTyFlag
+ GHC.Iface.Type: FTF_T_T :: FunTyFlag
+ GHC.Iface.Type: IfaceSelCo :: CoSel -> IfaceCoercion -> IfaceCoercion
+ GHC.Iface.Type: appArgsIfaceTypesForAllTyFlags :: IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]
+ GHC.Iface.Type: data ForAllTyFlag
+ GHC.Iface.Type: data FunTyFlag
+ GHC.Iface.Type: isIfaceRhoType :: IfaceType -> Bool
+ GHC.Iface.Type: pprTypeArrow :: FunTyFlag -> IfaceMult -> SDoc
+ GHC.Parser.Errors.Types: PsErrUnicodeCharLooksLike :: Char -> Char -> String -> PsMessage
+ GHC.Platform: ArchWasm32 :: Arch
+ GHC.Platform: OSWasi :: OS
+ GHC.Platform.ArchOS: ArchWasm32 :: Arch
+ GHC.Platform.ArchOS: OSWasi :: OS
+ GHC.Platform.Wasm32: activeStgRegs :: [GlobalReg]
+ GHC.Platform.Wasm32: callerSaves :: GlobalReg -> Bool
+ GHC.Platform.Wasm32: freeReg :: RegNo -> Bool
+ GHC.Platform.Wasm32: globalRegMaybe :: GlobalReg -> Maybe RealReg
+ GHC.Platform.Wasm32: haveRegBase :: Bool
+ GHC.Prelude: pprSTrace :: HasCallStack => SDoc -> a -> a
+ GHC.Prelude: pprTrace :: String -> SDoc -> a -> a
+ GHC.Prelude: pprTraceDebug :: String -> SDoc -> a -> a
+ GHC.Prelude: pprTraceException :: ExceptionMonad m => String -> SDoc -> m a -> m a
+ GHC.Prelude: pprTraceIt :: Outputable a => String -> a -> a
+ GHC.Prelude: pprTraceM :: Applicative f => String -> SDoc -> f ()
+ GHC.Prelude: pprTraceUserWarning :: HasCallStack => SDoc -> a -> a
+ GHC.Prelude: pprTraceWith :: String -> (a -> SDoc) -> a -> a
+ GHC.Prelude: warnPprTrace :: HasCallStack => Bool -> String -> SDoc -> a -> a
+ GHC.Prelude.Basic: (!!) :: [a] -> Int -> a
+ GHC.Prelude.Basic: ($!) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
+ GHC.Prelude.Basic: ($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
+ GHC.Prelude.Basic: (&&) :: Bool -> Bool -> Bool
+ GHC.Prelude.Basic: (*) :: Num a => a -> a -> a
+ GHC.Prelude.Basic: (**) :: Floating a => a -> a -> a
+ GHC.Prelude.Basic: (*>) :: Applicative f => f a -> f b -> f b
+ GHC.Prelude.Basic: (+) :: Num a => a -> a -> a
+ GHC.Prelude.Basic: (++) :: [a] -> [a] -> [a]
+ GHC.Prelude.Basic: (-) :: Num a => a -> a -> a
+ GHC.Prelude.Basic: (.&.) :: Bits a => a -> a -> a
+ GHC.Prelude.Basic: (.) :: (b -> c) -> (a -> b) -> a -> c
+ GHC.Prelude.Basic: (.|.) :: Bits a => a -> a -> a
+ GHC.Prelude.Basic: (/) :: Fractional a => a -> a -> a
+ GHC.Prelude.Basic: (/=) :: Eq a => a -> a -> Bool
+ GHC.Prelude.Basic: (<$) :: Functor f => a -> f b -> f a
+ GHC.Prelude.Basic: (<$>) :: Functor f => (a -> b) -> f a -> f b
+ GHC.Prelude.Basic: (<) :: Ord a => a -> a -> Bool
+ GHC.Prelude.Basic: (<*) :: Applicative f => f a -> f b -> f a
+ GHC.Prelude.Basic: (<*>) :: Applicative f => f (a -> b) -> f a -> f b
+ GHC.Prelude.Basic: (<=) :: Ord a => a -> a -> Bool
+ GHC.Prelude.Basic: (=<<) :: Monad m => (a -> m b) -> m a -> m b
+ GHC.Prelude.Basic: (==) :: Eq a => a -> a -> Bool
+ GHC.Prelude.Basic: (>) :: Ord a => a -> a -> Bool
+ GHC.Prelude.Basic: (>=) :: Ord a => a -> a -> Bool
+ GHC.Prelude.Basic: (>>) :: Monad m => m a -> m b -> m b
+ GHC.Prelude.Basic: (>>=) :: Monad m => m a -> (a -> m b) -> m b
+ GHC.Prelude.Basic: (^) :: (Num a, Integral b) => a -> b -> a
+ GHC.Prelude.Basic: (^^) :: (Fractional a, Integral b) => a -> b -> a
+ GHC.Prelude.Basic: (||) :: Bool -> Bool -> Bool
+ GHC.Prelude.Basic: EQ :: Ordering
+ GHC.Prelude.Basic: False :: Bool
+ GHC.Prelude.Basic: GT :: Ordering
+ GHC.Prelude.Basic: Just :: a -> Maybe a
+ GHC.Prelude.Basic: LT :: Ordering
+ GHC.Prelude.Basic: Left :: a -> Either a b
+ GHC.Prelude.Basic: Nothing :: Maybe a
+ GHC.Prelude.Basic: Right :: b -> Either a b
+ GHC.Prelude.Basic: True :: Bool
+ GHC.Prelude.Basic: abs :: Num a => a -> a
+ GHC.Prelude.Basic: acos :: Floating a => a -> a
+ GHC.Prelude.Basic: acosh :: Floating a => a -> a
+ GHC.Prelude.Basic: all :: Foldable t => (a -> Bool) -> t a -> Bool
+ GHC.Prelude.Basic: and :: Foldable t => t Bool -> Bool
+ GHC.Prelude.Basic: any :: Foldable t => (a -> Bool) -> t a -> Bool
+ GHC.Prelude.Basic: appendFile :: FilePath -> String -> IO ()
+ GHC.Prelude.Basic: asTypeOf :: a -> a -> a
+ GHC.Prelude.Basic: asin :: Floating a => a -> a
+ GHC.Prelude.Basic: asinh :: Floating a => a -> a
+ GHC.Prelude.Basic: atan :: Floating a => a -> a
+ GHC.Prelude.Basic: atan2 :: RealFloat a => a -> a -> a
+ GHC.Prelude.Basic: atanh :: Floating a => a -> a
+ GHC.Prelude.Basic: bit :: Bits a => Int -> a
+ GHC.Prelude.Basic: bitDefault :: (Bits a, Num a) => Int -> a
+ GHC.Prelude.Basic: bitSize :: Bits a => a -> Int
+ GHC.Prelude.Basic: bitSizeMaybe :: Bits a => a -> Maybe Int
+ GHC.Prelude.Basic: break :: (a -> Bool) -> [a] -> ([a], [a])
+ GHC.Prelude.Basic: ceiling :: (RealFrac a, Integral b) => a -> b
+ GHC.Prelude.Basic: class Functor f => Applicative (f :: Type -> Type)
+ GHC.Prelude.Basic: class Eq a => Bits a
+ GHC.Prelude.Basic: class Bounded a
+ GHC.Prelude.Basic: class Enum a
+ GHC.Prelude.Basic: class Eq a
+ GHC.Prelude.Basic: class Bits b => FiniteBits b
+ GHC.Prelude.Basic: class Fractional a => Floating a
+ GHC.Prelude.Basic: class Foldable (t :: TYPE LiftedRep -> Type)
+ GHC.Prelude.Basic: class Num a => Fractional a
+ GHC.Prelude.Basic: class Functor (f :: Type -> Type)
+ GHC.Prelude.Basic: class (Real a, Enum a) => Integral a
+ GHC.Prelude.Basic: class Applicative m => Monad (m :: Type -> Type)
+ GHC.Prelude.Basic: class Monad m => MonadFail (m :: Type -> Type)
+ GHC.Prelude.Basic: class Semigroup a => Monoid a
+ GHC.Prelude.Basic: class Num a
+ GHC.Prelude.Basic: class Eq a => Ord a
+ GHC.Prelude.Basic: class Read a
+ GHC.Prelude.Basic: class (Num a, Ord a) => Real a
+ GHC.Prelude.Basic: class (RealFrac a, Floating a) => RealFloat a
+ GHC.Prelude.Basic: class (Real a, Fractional a) => RealFrac a
+ GHC.Prelude.Basic: class Semigroup a
+ GHC.Prelude.Basic: class Show a
+ GHC.Prelude.Basic: class (Functor t, Foldable t) => Traversable (t :: Type -> Type)
+ GHC.Prelude.Basic: clearBit :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: compare :: Ord a => a -> a -> Ordering
+ GHC.Prelude.Basic: complement :: Bits a => a -> a
+ GHC.Prelude.Basic: complementBit :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: concat :: Foldable t => t [a] -> [a]
+ GHC.Prelude.Basic: concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
+ GHC.Prelude.Basic: const :: a -> b -> a
+ GHC.Prelude.Basic: cos :: Floating a => a -> a
+ GHC.Prelude.Basic: cosh :: Floating a => a -> a
+ GHC.Prelude.Basic: countLeadingZeros :: FiniteBits b => b -> Int
+ GHC.Prelude.Basic: countTrailingZeros :: FiniteBits b => b -> Int
+ GHC.Prelude.Basic: curry :: ((a, b) -> c) -> a -> b -> c
+ GHC.Prelude.Basic: cycle :: [a] -> [a]
+ GHC.Prelude.Basic: data Bool
+ GHC.Prelude.Basic: data Char
+ GHC.Prelude.Basic: data Double
+ GHC.Prelude.Basic: data Either a b
+ GHC.Prelude.Basic: data Float
+ GHC.Prelude.Basic: data IO a
+ GHC.Prelude.Basic: data Int
+ GHC.Prelude.Basic: data Integer
+ GHC.Prelude.Basic: data Maybe a
+ GHC.Prelude.Basic: data Ordering
+ GHC.Prelude.Basic: data Word
+ GHC.Prelude.Basic: decodeFloat :: RealFloat a => a -> (Integer, Int)
+ GHC.Prelude.Basic: div :: Integral a => a -> a -> a
+ GHC.Prelude.Basic: divMod :: Integral a => a -> a -> (a, a)
+ GHC.Prelude.Basic: drop :: Int -> [a] -> [a]
+ GHC.Prelude.Basic: dropWhile :: (a -> Bool) -> [a] -> [a]
+ GHC.Prelude.Basic: either :: (a -> c) -> (b -> c) -> Either a b -> c
+ GHC.Prelude.Basic: elem :: (Foldable t, Eq a) => a -> t a -> Bool
+ GHC.Prelude.Basic: encodeFloat :: RealFloat a => Integer -> Int -> a
+ GHC.Prelude.Basic: enumFrom :: Enum a => a -> [a]
+ GHC.Prelude.Basic: enumFromThen :: Enum a => a -> a -> [a]
+ GHC.Prelude.Basic: enumFromThenTo :: Enum a => a -> a -> a -> [a]
+ GHC.Prelude.Basic: enumFromTo :: Enum a => a -> a -> [a]
+ GHC.Prelude.Basic: error :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => [Char] -> a
+ GHC.Prelude.Basic: errorWithoutStackTrace :: forall (r :: RuntimeRep) (a :: TYPE r). [Char] -> a
+ GHC.Prelude.Basic: even :: Integral a => a -> Bool
+ GHC.Prelude.Basic: exp :: Floating a => a -> a
+ GHC.Prelude.Basic: exponent :: RealFloat a => a -> Int
+ GHC.Prelude.Basic: fail :: MonadFail m => String -> m a
+ GHC.Prelude.Basic: filter :: (a -> Bool) -> [a] -> [a]
+ GHC.Prelude.Basic: finiteBitSize :: FiniteBits b => b -> Int
+ GHC.Prelude.Basic: flip :: (a -> b -> c) -> b -> a -> c
+ GHC.Prelude.Basic: floatDigits :: RealFloat a => a -> Int
+ GHC.Prelude.Basic: floatRadix :: RealFloat a => a -> Integer
+ GHC.Prelude.Basic: floatRange :: RealFloat a => a -> (Int, Int)
+ GHC.Prelude.Basic: floor :: (RealFrac a, Integral b) => a -> b
+ GHC.Prelude.Basic: fmap :: Functor f => (a -> b) -> f a -> f b
+ GHC.Prelude.Basic: foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
+ GHC.Prelude.Basic: foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
+ GHC.Prelude.Basic: foldl' :: Foldable t => (b -> a -> b) -> b -> t a -> b
+ GHC.Prelude.Basic: foldl1 :: Foldable t => (a -> a -> a) -> t a -> a
+ GHC.Prelude.Basic: foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
+ GHC.Prelude.Basic: foldr1 :: Foldable t => (a -> a -> a) -> t a -> a
+ GHC.Prelude.Basic: fromEnum :: Enum a => a -> Int
+ GHC.Prelude.Basic: fromInteger :: Num a => Integer -> a
+ GHC.Prelude.Basic: fromIntegral :: (Integral a, Num b) => a -> b
+ GHC.Prelude.Basic: fromRational :: Fractional a => Rational -> a
+ GHC.Prelude.Basic: fst :: (a, b) -> a
+ GHC.Prelude.Basic: gcd :: Integral a => a -> a -> a
+ GHC.Prelude.Basic: getChar :: IO Char
+ GHC.Prelude.Basic: getContents :: IO String
+ GHC.Prelude.Basic: getLine :: IO String
+ GHC.Prelude.Basic: head :: [a] -> a
+ GHC.Prelude.Basic: id :: a -> a
+ GHC.Prelude.Basic: infix 4 `notElem`
+ GHC.Prelude.Basic: infixl 1 >>=
+ GHC.Prelude.Basic: infixl 4 <*
+ GHC.Prelude.Basic: infixl 5 .|.
+ GHC.Prelude.Basic: infixl 6 `xor`
+ GHC.Prelude.Basic: infixl 7 .&.
+ GHC.Prelude.Basic: infixl 8 `rotate`
+ GHC.Prelude.Basic: infixl 9 !!
+ GHC.Prelude.Basic: infixr 0 $!
+ GHC.Prelude.Basic: infixr 1 =<<
+ GHC.Prelude.Basic: infixr 2 ||
+ GHC.Prelude.Basic: infixr 3 &&
+ GHC.Prelude.Basic: infixr 5 ++
+ GHC.Prelude.Basic: infixr 8 ^
+ GHC.Prelude.Basic: infixr 9 .
+ GHC.Prelude.Basic: init :: [a] -> [a]
+ GHC.Prelude.Basic: interact :: (String -> String) -> IO ()
+ GHC.Prelude.Basic: ioError :: IOError -> IO a
+ GHC.Prelude.Basic: isDenormalized :: RealFloat a => a -> Bool
+ GHC.Prelude.Basic: isIEEE :: RealFloat a => a -> Bool
+ GHC.Prelude.Basic: isInfinite :: RealFloat a => a -> Bool
+ GHC.Prelude.Basic: isNaN :: RealFloat a => a -> Bool
+ GHC.Prelude.Basic: isNegativeZero :: RealFloat a => a -> Bool
+ GHC.Prelude.Basic: isSigned :: Bits a => a -> Bool
+ GHC.Prelude.Basic: iterate :: (a -> a) -> a -> [a]
+ GHC.Prelude.Basic: last :: [a] -> a
+ GHC.Prelude.Basic: lcm :: Integral a => a -> a -> a
+ GHC.Prelude.Basic: length :: Foldable t => t a -> Int
+ GHC.Prelude.Basic: lex :: ReadS String
+ GHC.Prelude.Basic: liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
+ GHC.Prelude.Basic: lines :: String -> [String]
+ GHC.Prelude.Basic: log :: Floating a => a -> a
+ GHC.Prelude.Basic: logBase :: Floating a => a -> a -> a
+ GHC.Prelude.Basic: lookup :: Eq a => a -> [(a, b)] -> Maybe b
+ GHC.Prelude.Basic: map :: (a -> b) -> [a] -> [b]
+ GHC.Prelude.Basic: mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
+ GHC.Prelude.Basic: mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
+ GHC.Prelude.Basic: mappend :: Monoid a => a -> a -> a
+ GHC.Prelude.Basic: max :: Ord a => a -> a -> a
+ GHC.Prelude.Basic: maxBound :: Bounded a => a
+ GHC.Prelude.Basic: maximum :: (Foldable t, Ord a) => t a -> a
+ GHC.Prelude.Basic: maybe :: b -> (a -> b) -> Maybe a -> b
+ GHC.Prelude.Basic: mconcat :: Monoid a => [a] -> a
+ GHC.Prelude.Basic: mempty :: Monoid a => a
+ GHC.Prelude.Basic: min :: Ord a => a -> a -> a
+ GHC.Prelude.Basic: minBound :: Bounded a => a
+ GHC.Prelude.Basic: minimum :: (Foldable t, Ord a) => t a -> a
+ GHC.Prelude.Basic: mod :: Integral a => a -> a -> a
+ GHC.Prelude.Basic: negate :: Num a => a -> a
+ GHC.Prelude.Basic: not :: Bool -> Bool
+ GHC.Prelude.Basic: notElem :: (Foldable t, Eq a) => a -> t a -> Bool
+ GHC.Prelude.Basic: null :: Foldable t => t a -> Bool
+ GHC.Prelude.Basic: odd :: Integral a => a -> Bool
+ GHC.Prelude.Basic: or :: Foldable t => t Bool -> Bool
+ GHC.Prelude.Basic: otherwise :: Bool
+ GHC.Prelude.Basic: pi :: Floating a => a
+ GHC.Prelude.Basic: popCount :: Bits a => a -> Int
+ GHC.Prelude.Basic: popCountDefault :: (Bits a, Num a) => a -> Int
+ GHC.Prelude.Basic: pred :: Enum a => a -> a
+ GHC.Prelude.Basic: print :: Show a => a -> IO ()
+ GHC.Prelude.Basic: product :: (Foldable t, Num a) => t a -> a
+ GHC.Prelude.Basic: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
+ GHC.Prelude.Basic: pure :: Applicative f => a -> f a
+ GHC.Prelude.Basic: putChar :: Char -> IO ()
+ GHC.Prelude.Basic: putStr :: String -> IO ()
+ GHC.Prelude.Basic: putStrLn :: String -> IO ()
+ GHC.Prelude.Basic: quot :: Integral a => a -> a -> a
+ GHC.Prelude.Basic: quotRem :: Integral a => a -> a -> (a, a)
+ GHC.Prelude.Basic: read :: Read a => String -> a
+ GHC.Prelude.Basic: readFile :: FilePath -> IO String
+ GHC.Prelude.Basic: readIO :: Read a => String -> IO a
+ GHC.Prelude.Basic: readList :: Read a => ReadS [a]
+ GHC.Prelude.Basic: readLn :: Read a => IO a
+ GHC.Prelude.Basic: readParen :: Bool -> ReadS a -> ReadS a
+ GHC.Prelude.Basic: reads :: Read a => ReadS a
+ GHC.Prelude.Basic: readsPrec :: Read a => Int -> ReadS a
+ GHC.Prelude.Basic: realToFrac :: (Real a, Fractional b) => a -> b
+ GHC.Prelude.Basic: recip :: Fractional a => a -> a
+ GHC.Prelude.Basic: rem :: Integral a => a -> a -> a
+ GHC.Prelude.Basic: repeat :: a -> [a]
+ GHC.Prelude.Basic: replicate :: Int -> a -> [a]
+ GHC.Prelude.Basic: return :: Monad m => a -> m a
+ GHC.Prelude.Basic: reverse :: [a] -> [a]
+ GHC.Prelude.Basic: rotate :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: rotateL :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: rotateR :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: round :: (RealFrac a, Integral b) => a -> b
+ GHC.Prelude.Basic: scaleFloat :: RealFloat a => Int -> a -> a
+ GHC.Prelude.Basic: scanl :: (b -> a -> b) -> b -> [a] -> [b]
+ GHC.Prelude.Basic: scanl1 :: (a -> a -> a) -> [a] -> [a]
+ GHC.Prelude.Basic: scanr :: (a -> b -> b) -> b -> [a] -> [b]
+ GHC.Prelude.Basic: scanr1 :: (a -> a -> a) -> [a] -> [a]
+ GHC.Prelude.Basic: seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b
+ GHC.Prelude.Basic: sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
+ GHC.Prelude.Basic: sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
+ GHC.Prelude.Basic: sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
+ GHC.Prelude.Basic: setBit :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: shift :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: shiftL :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: shiftR :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: show :: Show a => a -> String
+ GHC.Prelude.Basic: showChar :: Char -> ShowS
+ GHC.Prelude.Basic: showList :: Show a => [a] -> ShowS
+ GHC.Prelude.Basic: showParen :: Bool -> ShowS -> ShowS
+ GHC.Prelude.Basic: showString :: String -> ShowS
+ GHC.Prelude.Basic: shows :: Show a => a -> ShowS
+ GHC.Prelude.Basic: showsPrec :: Show a => Int -> a -> ShowS
+ GHC.Prelude.Basic: significand :: RealFloat a => a -> a
+ GHC.Prelude.Basic: signum :: Num a => a -> a
+ GHC.Prelude.Basic: sin :: Floating a => a -> a
+ GHC.Prelude.Basic: sinh :: Floating a => a -> a
+ GHC.Prelude.Basic: snd :: (a, b) -> b
+ GHC.Prelude.Basic: span :: (a -> Bool) -> [a] -> ([a], [a])
+ GHC.Prelude.Basic: splitAt :: Int -> [a] -> ([a], [a])
+ GHC.Prelude.Basic: sqrt :: Floating a => a -> a
+ GHC.Prelude.Basic: subtract :: Num a => a -> a -> a
+ GHC.Prelude.Basic: succ :: Enum a => a -> a
+ GHC.Prelude.Basic: sum :: (Foldable t, Num a) => t a -> a
+ GHC.Prelude.Basic: tail :: [a] -> [a]
+ GHC.Prelude.Basic: take :: Int -> [a] -> [a]
+ GHC.Prelude.Basic: takeWhile :: (a -> Bool) -> [a] -> [a]
+ GHC.Prelude.Basic: tan :: Floating a => a -> a
+ GHC.Prelude.Basic: tanh :: Floating a => a -> a
+ GHC.Prelude.Basic: testBit :: Bits a => a -> Int -> Bool
+ GHC.Prelude.Basic: testBitDefault :: (Bits a, Num a) => a -> Int -> Bool
+ GHC.Prelude.Basic: toEnum :: Enum a => Int -> a
+ GHC.Prelude.Basic: toInteger :: Integral a => a -> Integer
+ GHC.Prelude.Basic: toIntegralSized :: (Integral a, Integral b, Bits a, Bits b) => a -> Maybe b
+ GHC.Prelude.Basic: toRational :: Real a => a -> Rational
+ GHC.Prelude.Basic: traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
+ GHC.Prelude.Basic: truncate :: (RealFrac a, Integral b) => a -> b
+ GHC.Prelude.Basic: type FilePath = String
+ GHC.Prelude.Basic: type IOError = IOException
+ GHC.Prelude.Basic: type Rational = Ratio Integer
+ GHC.Prelude.Basic: type ReadS a = String -> [(a, String)]
+ GHC.Prelude.Basic: type ShowS = String -> String
+ GHC.Prelude.Basic: type String = [Char]
+ GHC.Prelude.Basic: uncurry :: (a -> b -> c) -> (a, b) -> c
+ GHC.Prelude.Basic: undefined :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a
+ GHC.Prelude.Basic: unlines :: [String] -> String
+ GHC.Prelude.Basic: unsafeShiftL :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: unsafeShiftR :: Bits a => a -> Int -> a
+ GHC.Prelude.Basic: until :: (a -> Bool) -> (a -> a) -> a -> a
+ GHC.Prelude.Basic: unwords :: [String] -> String
+ GHC.Prelude.Basic: unzip :: [(a, b)] -> ([a], [b])
+ GHC.Prelude.Basic: unzip3 :: [(a, b, c)] -> ([a], [b], [c])
+ GHC.Prelude.Basic: userError :: String -> IOError
+ GHC.Prelude.Basic: words :: String -> [String]
+ GHC.Prelude.Basic: writeFile :: FilePath -> String -> IO ()
+ GHC.Prelude.Basic: xor :: Bits a => a -> a -> a
+ GHC.Prelude.Basic: zeroBits :: Bits a => a
+ GHC.Prelude.Basic: zip :: [a] -> [b] -> [(a, b)]
+ GHC.Prelude.Basic: zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
+ GHC.Prelude.Basic: zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
+ GHC.Prelude.Basic: zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
+ GHC.Runtime.Context: icNamePprCtx :: UnitEnv -> InteractiveContext -> NamePprCtx
+ GHC.Stg.Syntax: pprStgAlt :: OutputablePass pass => StgPprOpts -> Bool -> GenStgAlt pass -> SDoc
+ GHC.Tc.Errors.Types: EmptyStmtsGroupInArrowNotation :: EmptyStatementGroupErrReason
+ GHC.Tc.Errors.Types: EmptyStmtsGroupInDoNotation :: HsDoFlavour -> EmptyStatementGroupErrReason
+ GHC.Tc.Errors.Types: EmptyStmtsGroupInParallelComp :: EmptyStatementGroupErrReason
+ GHC.Tc.Errors.Types: EmptyStmtsGroupInTransformListComp :: EmptyStatementGroupErrReason
+ GHC.Tc.Errors.Types: [TcRnBadBootFamInstDecl] :: TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnBadFamInstDecl] :: TyCon -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnEmptyStmtsGroup] :: EmptyStatementGroupErrReason -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalFamilyInstance] :: TyCon -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalImplicitParameterBindings] :: Either (HsLocalBindsLR GhcPs GhcPs) (HsLocalBindsLR GhcRn GhcPs) -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalStaticExpression] :: HsExpr GhcPs -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalStaticFormInSplice] :: HsExpr GhcPs -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnIllegalTupleSection] :: TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnLastStmtNotExpr] :: HsStmtContext GhcRn -> UnexpectedStatement -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnListComprehensionDuplicateBinding] :: Name -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnMisplacedInstSig] :: Name -> LHsSigType GhcRn -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnMissingClassAssoc] :: TyCon -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnNoFieldPunsRecordDot] :: TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnNoRebindableSyntaxRecordDot] :: TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnNotOpenFamily] :: TyCon -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnSectionWithoutParentheses] :: HsExpr GhcPs -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUnexpectedStatementInContext] :: HsStmtContext GhcRn -> UnexpectedStatement -> Maybe Extension -> TcRnMessage
+ GHC.Tc.Errors.Types: [TcRnUnsatisfiedMinimalDef] :: ClassMinimalDef -> TcRnMessage
+ GHC.Tc.Errors.Types: [UnexpectedStatement] :: Outputable (StmtLR GhcPs GhcPs body) => StmtLR GhcPs GhcPs body -> UnexpectedStatement
+ GHC.Tc.Errors.Types: data EmptyStatementGroupErrReason
+ GHC.Tc.Errors.Types: data UnexpectedStatement
+ GHC.Tc.Errors.Types: instance GHC.Generics.Generic GHC.Tc.Errors.Types.EmptyStatementGroupErrReason
+ GHC.Tc.Solver.InertSet: noGivenIrreds :: InertSet -> Bool
+ GHC.Tc.Solver.InertSet: noMatchableGivenDicts :: InertSet -> CtLoc -> Class -> [TcType] -> Bool
+ GHC.Tc.Types: LangJs :: ForeignSrcLang
+ GHC.Tc.Types.Constraint: pendingScDict_maybe :: Ct -> Maybe Ct
+ GHC.Tc.Types.Constraint: pendingScInst_maybe :: QCInst -> Maybe QCInst
+ GHC.Tc.Types.Evidence: maybeSymCo :: SwapFlag -> TcCoercion -> TcCoercion
+ GHC.Tc.Types.Evidence: mkWpEta :: [Id] -> HsWrapper -> HsWrapper
+ GHC.Tc.Types.Evidence: mkWpEvLams :: [Var] -> HsWrapper
+ GHC.Tc.Utils.TcType: FTF_C_C :: FunTyFlag
+ GHC.Tc.Utils.TcType: FTF_C_T :: FunTyFlag
+ GHC.Tc.Utils.TcType: FTF_T_C :: FunTyFlag
+ GHC.Tc.Utils.TcType: FTF_T_T :: FunTyFlag
+ GHC.Tc.Utils.TcType: data ForAllTyFlag
+ GHC.Tc.Utils.TcType: data FunTyFlag
+ GHC.Tc.Utils.TcType: data PiTyBinder
+ GHC.Tc.Utils.TcType: eqForAllVis :: ForAllTyFlag -> ForAllTyFlag -> Bool
+ GHC.Tc.Utils.TcType: eqVarBndrs :: RnEnv2 -> [Var] -> [Var] -> Maybe RnEnv2
+ GHC.Tc.Utils.TcType: getCastedTyVar_maybe :: Type -> Maybe (TyVar, CoercionN)
+ GHC.Tc.Utils.TcType: getTyVar_maybe :: Type -> Maybe TyVar
+ GHC.Tc.Utils.TcType: isInvisiblePiTyBinder :: PiTyBinder -> Bool
+ GHC.Tc.Utils.TcType: isTYPEorCONSTRAINT :: Kind -> Bool
+ GHC.Tc.Utils.TcType: isVisiblePiTyBinder :: PiTyBinder -> Bool
+ GHC.Tc.Utils.TcType: mkInvisFunTys :: HasDebugCallStack => [Type] -> Type -> Type
+ GHC.Tc.Utils.TcType: mkScaledFunTys :: HasDebugCallStack => [Scaled Type] -> Type -> Type
+ GHC.Tc.Utils.TcType: tcMkDFunPhiTy :: HasDebugCallStack => [PredType] -> Type -> Type
+ GHC.Tc.Utils.TcType: tcMkDFunSigmaTy :: [TyVar] -> ThetaType -> Type -> Type
+ GHC.Tc.Utils.TcType: tcMkPhiTy :: HasDebugCallStack => [PredType] -> Type -> Type
+ GHC.Tc.Utils.TcType: tcSplitAppTyNoView_maybe :: Type -> Maybe (Type, Type)
+ GHC.Types.Basic: ConstraintLike :: TypeOrConstraint
+ GHC.Types.Basic: LangJs :: ForeignSrcLang
+ GHC.Types.Basic: TypeLike :: TypeOrConstraint
+ GHC.Types.Basic: data TypeOrConstraint
+ GHC.Types.Basic: instance Data.Data.Data GHC.Types.Basic.TypeOrConstraint
+ GHC.Types.Basic: instance GHC.Classes.Eq GHC.Types.Basic.TypeOrConstraint
+ GHC.Types.Basic: instance GHC.Classes.Ord GHC.Types.Basic.TypeOrConstraint
+ GHC.Types.Basic: maxPrec :: PprPrec
+ GHC.Types.CostCentre: pprCostCentre :: IsLine doc => CostCentre -> doc
+ GHC.Types.CostCentre: pprCostCentreStack :: IsLine doc => CostCentreStack -> doc
+ GHC.Types.Id.Make: noinlineConstraintId :: Id
+ GHC.Types.Id.Make: noinlineConstraintIdName :: Name
+ GHC.Types.Name: pprName :: forall doc. IsLine doc => Name -> doc
+ GHC.Types.Name.Ppr: mkNamePprCtx :: PromotionTickContext -> UnitEnv -> GlobalRdrEnv -> NamePprCtx
+ GHC.Types.Unique.FM: addToUFM_L :: Uniquable key => (key -> elt -> elt -> elt) -> key -> elt -> UniqFM key elt -> (Maybe elt, UniqFM key elt)
+ GHC.Types.Unique.Map: [getUniqMap] :: UniqMap k a -> UniqFM k (k, a)
+ GHC.Types.Unique.Map: addToUniqMap_L :: Uniquable k => (k -> a -> a -> a) -> k -> a -> UniqMap k a -> (Maybe a, UniqMap k a)
+ GHC.Types.Unique.Map: intersectUniqMap_C :: (a -> b -> c) -> UniqMap k a -> UniqMap k b -> UniqMap k c
+ GHC.Types.Var: Anon :: Scaled Type -> FunTyFlag -> PiTyBinder
+ GHC.Types.Var: ConstraintLike :: TypeOrConstraint
+ GHC.Types.Var: FTF_C_C :: FunTyFlag
+ GHC.Types.Var: FTF_C_T :: FunTyFlag
+ GHC.Types.Var: FTF_T_C :: FunTyFlag
+ GHC.Types.Var: FTF_T_T :: FunTyFlag
+ GHC.Types.Var: Named :: ForAllTyBinder -> PiTyBinder
+ GHC.Types.Var: TypeLike :: TypeOrConstraint
+ GHC.Types.Var: anonPiTyBinderType_maybe :: PiTyBinder -> Maybe Type
+ GHC.Types.Var: binderFlag :: VarBndr tv argf -> argf
+ GHC.Types.Var: binderFlags :: [VarBndr tv argf] -> [argf]
+ GHC.Types.Var: data ForAllTyFlag
+ GHC.Types.Var: data FunTyFlag
+ GHC.Types.Var: data PiTyBinder
+ GHC.Types.Var: data TypeOrConstraint
+ GHC.Types.Var: funTyFlagResultTypeOrConstraint :: FunTyFlag -> TypeOrConstraint
+ GHC.Types.Var: instance Data.Data.Data GHC.Types.Var.ForAllTyFlag
+ GHC.Types.Var: instance Data.Data.Data GHC.Types.Var.FunTyFlag
+ GHC.Types.Var: instance Data.Data.Data GHC.Types.Var.PiTyBinder
+ GHC.Types.Var: instance GHC.Classes.Eq GHC.Types.Var.ForAllTyFlag
+ GHC.Types.Var: instance GHC.Classes.Eq GHC.Types.Var.FunTyFlag
+ GHC.Types.Var: instance GHC.Classes.Ord GHC.Types.Var.ForAllTyFlag
+ GHC.Types.Var: instance GHC.Classes.Ord GHC.Types.Var.FunTyFlag
+ GHC.Types.Var: instance GHC.Utils.Binary.Binary GHC.Types.Var.ForAllTyFlag
+ GHC.Types.Var: instance GHC.Utils.Binary.Binary GHC.Types.Var.FunTyFlag
+ GHC.Types.Var: instance GHC.Utils.Outputable.Outputable GHC.Types.Var.ForAllTyFlag
+ GHC.Types.Var: instance GHC.Utils.Outputable.Outputable GHC.Types.Var.FunTyFlag
+ GHC.Types.Var: instance GHC.Utils.Outputable.Outputable GHC.Types.Var.PiTyBinder
+ GHC.Types.Var: instance GHC.Utils.Outputable.Outputable tv => GHC.Utils.Outputable.Outputable (GHC.Types.Var.VarBndr tv GHC.Types.Var.ForAllTyFlag)
+ GHC.Types.Var: invisArg :: TypeOrConstraint -> FunTyFlag
+ GHC.Types.Var: invisArgConstraintLike :: FunTyFlag
+ GHC.Types.Var: invisArgTypeLike :: FunTyFlag
+ GHC.Types.Var: isAnonPiTyBinder :: PiTyBinder -> Bool
+ GHC.Types.Var: isFUNArg :: FunTyFlag -> Bool
+ GHC.Types.Var: isInferredForAllTyFlag :: ForAllTyFlag -> Bool
+ GHC.Types.Var: isInvisibleForAllTyFlag :: ForAllTyFlag -> Bool
+ GHC.Types.Var: isInvisibleFunArg :: FunTyFlag -> Bool
+ GHC.Types.Var: isInvisiblePiTyBinder :: PiTyBinder -> Bool
+ GHC.Types.Var: isNamedPiTyBinder :: PiTyBinder -> Bool
+ GHC.Types.Var: isTyBinder :: PiTyBinder -> Bool
+ GHC.Types.Var: isVisibleForAllTyFlag :: ForAllTyFlag -> Bool
+ GHC.Types.Var: isVisibleFunArg :: FunTyFlag -> Bool
+ GHC.Types.Var: isVisiblePiTyBinder :: PiTyBinder -> Bool
+ GHC.Types.Var: mkForAllTyBinder :: vis -> TyCoVar -> VarBndr TyCoVar vis
+ GHC.Types.Var: mkForAllTyBinders :: vis -> [TyCoVar] -> [VarBndr TyCoVar vis]
+ GHC.Types.Var: mkFunTyFlag :: TypeOrConstraint -> TypeOrConstraint -> FunTyFlag
+ GHC.Types.Var: namedPiTyBinder_maybe :: PiTyBinder -> Maybe TyCoVar
+ GHC.Types.Var: piTyBinderType :: PiTyBinder -> Type
+ GHC.Types.Var: type ForAllTyBinder = VarBndr TyCoVar ForAllTyFlag
+ GHC.Types.Var: type InvisTyBinder = VarBndr TyCoVar Specificity
+ GHC.Types.Var: type PiTyVarBinder = PiTyBinder
+ GHC.Types.Var: type ReqTyBinder = VarBndr TyCoVar ()
+ GHC.Types.Var: visArg :: TypeOrConstraint -> FunTyFlag
+ GHC.Types.Var: visArgConstraintLike :: FunTyFlag
+ GHC.Types.Var: visArgTypeLike :: FunTyFlag
+ GHC.Types.Var.Env: varEnvDomain :: VarEnv elt -> UnVarSet
+ GHC.Unit.Types: pprUnit :: IsLine doc => Unit -> doc
+ GHC.Utils.Binary: data FSTable
+ GHC.Utils.Binary: forwardGet :: BinHandle -> IO a -> IO a
+ GHC.Utils.Binary: forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a, b)
+ GHC.Utils.Binary: forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO ()
+ GHC.Utils.Binary: getDictFastString :: Dictionary -> BinHandle -> IO FastString
+ GHC.Utils.Binary: initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int)
+ GHC.Utils.Binary: instance GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Utils.Binary.FixedLengthEncoding a)
+ GHC.Utils.Binary: instance GHC.Classes.Ord a => GHC.Classes.Ord (GHC.Utils.Binary.FixedLengthEncoding a)
+ GHC.Utils.Binary: instance GHC.Show.Show a => GHC.Show.Show (GHC.Utils.Binary.FixedLengthEncoding a)
+ GHC.Utils.Binary: noUserData :: UserData
+ GHC.Utils.Binary: putDictFastString :: FSTable -> BinHandle -> FastString -> IO ()
+ GHC.Utils.Binary: readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle)
+ GHC.Utils.Binary: unsafeUnpackBinBuffer :: ByteString -> IO BinHandle
+ GHC.Utils.Logger: FormatJS :: DumpFormat
+ GHC.Utils.Monad: filterOutM :: Applicative m => (a -> m Bool) -> [a] -> m [a]
+ GHC.Utils.Monad: partitionM :: Monad m => (a -> m Bool) -> [a] -> m ([a], [a])
+ GHC.Utils.Outputable: IsEmptyOrSingleton :: Bool -> IsEmptyOrSingleton
+ GHC.Utils.Outputable: PromTickCtx :: !Bool -> !Bool -> PromotionTickContext
+ GHC.Utils.Outputable: PromotedItemDataCon :: OccName -> PromotedItem
+ GHC.Utils.Outputable: PromotedItemListSyntax :: IsEmptyOrSingleton -> PromotedItem
+ GHC.Utils.Outputable: PromotedItemTupleSyntax :: PromotedItem
+ GHC.Utils.Outputable: [ptcListTuplePuns] :: PromotionTickContext -> !Bool
+ GHC.Utils.Outputable: [ptcPrintRedundantPromTicks] :: PromotionTickContext -> !Bool
+ GHC.Utils.Outputable: [queryPromotionTick] :: NamePprCtx -> QueryPromotionTick
+ GHC.Utils.Outputable: [sdocSuppressStgReps] :: SDocContext -> !Bool
+ GHC.Utils.Outputable: alwaysPrintPromTick :: QueryPromotionTick
+ GHC.Utils.Outputable: bPutHDoc :: BufHandle -> SDocContext -> HDoc -> IO ()
+ GHC.Utils.Outputable: class (IsOutput doc, IsLine (Line doc)) => IsDoc doc where {
+ GHC.Utils.Outputable: class IsOutput doc => IsLine doc
+ GHC.Utils.Outputable: class IsOutput doc
+ GHC.Utils.Outputable: data HDoc
+ GHC.Utils.Outputable: data HLine
+ GHC.Utils.Outputable: data NamePprCtx
+ GHC.Utils.Outputable: data PromotedItem
+ GHC.Utils.Outputable: data PromotionTickContext
+ GHC.Utils.Outputable: docWithContext :: IsOutput doc => (SDocContext -> doc) -> doc
+ GHC.Utils.Outputable: dualDoc :: IsDoc doc => SDoc -> HDoc -> doc
+ GHC.Utils.Outputable: dualLine :: IsLine doc => SDoc -> HLine -> doc
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.IsDoc GHC.Utils.Outputable.HDoc
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.IsDoc GHC.Utils.Outputable.SDoc
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.IsLine GHC.Utils.Outputable.HLine
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.IsLine GHC.Utils.Outputable.SDoc
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.IsOutput GHC.Utils.Outputable.HDoc
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.IsOutput GHC.Utils.Outputable.HLine
+ GHC.Utils.Outputable: instance GHC.Utils.Outputable.IsOutput GHC.Utils.Outputable.SDoc
+ GHC.Utils.Outputable: isListEmptyOrSingleton :: [a] -> IsEmptyOrSingleton
+ GHC.Utils.Outputable: line :: IsDoc doc => Line doc -> doc
+ GHC.Utils.Outputable: lines_ :: IsDoc doc => [Line doc] -> doc
+ GHC.Utils.Outputable: newtype IsEmptyOrSingleton
+ GHC.Utils.Outputable: promTick :: PprStyle -> QueryPromotionTick
+ GHC.Utils.Outputable: spaceIfSingleQuote :: SDoc -> SDoc
+ GHC.Utils.Outputable: type Line doc = r | r -> doc;
+ GHC.Utils.Outputable: type QueryPromotionTick = PromotedItem -> Bool
+ GHC.Utils.Outputable: }
+ GHC.Utils.Panic: assertPprMaybe :: HasCallStack => Maybe SDoc -> a -> a
+ GHC.Utils.Ppr: docHead :: Doc -> (Maybe Char, Doc)
+ GHC.Utils.Ppr: printLeftRender :: Handle -> Doc -> IO ()
+ GHC.Utils.Ppr: squotes :: Doc -> Doc
+ Language.Haskell.TH.Syntax: LangJs :: ForeignSrcLang
- GHC.Builtin.Names: allNameStrings :: [String]
+ GHC.Builtin.Names: allNameStrings :: Infinite String
- GHC.Builtin.Types: typeToTypeKind :: Kind
+ GHC.Builtin.Types: typeToTypeKind :: Type
- GHC.Cmm: CmmFileEmbed :: FilePath -> CmmStatic
+ GHC.Cmm: CmmFileEmbed :: FilePath -> Int -> CmmStatic
- GHC.Cmm.CLabel: mkFinalizerStubLabel :: Module -> String -> CLabel
+ GHC.Cmm.CLabel: mkFinalizerStubLabel :: Module -> FastString -> CLabel
- GHC.Cmm.CLabel: mkInitializerStubLabel :: Module -> String -> CLabel
+ GHC.Cmm.CLabel: mkInitializerStubLabel :: Module -> FastString -> CLabel
- GHC.Cmm.CLabel: ppInternalProcLabel :: Module -> CLabel -> Maybe SDoc
+ GHC.Cmm.CLabel: ppInternalProcLabel :: IsLine doc => Module -> CLabel -> Maybe doc
- GHC.Cmm.CLabel: pprAsmLabel :: Platform -> CLabel -> SDoc
+ GHC.Cmm.CLabel: pprAsmLabel :: IsLine doc => Platform -> CLabel -> doc
- GHC.Cmm.CLabel: pprCLabel :: Platform -> CLabel -> SDoc
+ GHC.Cmm.CLabel: pprCLabel :: IsLine doc => Platform -> CLabel -> doc
- GHC.Core.Coercion: decomposeCo :: Arity -> Coercion -> [Role] -> [Coercion]
+ GHC.Core.Coercion: decomposeCo :: Arity -> Coercion -> Infinite Role -> [Coercion]
- GHC.Core.Coercion: decomposeFunCo :: HasDebugCallStack => Role -> Coercion -> (CoercionN, Coercion, Coercion)
+ GHC.Core.Coercion: decomposeFunCo :: HasDebugCallStack => Coercion -> (CoercionN, Coercion, Coercion)
- GHC.Core.Coercion: mkFunResCo :: Role -> Scaled Type -> Coercion -> Coercion
+ GHC.Core.Coercion: mkFunResCo :: Role -> Id -> Coercion -> Coercion
- GHC.Core.Coercion: mkFunResMCo :: Scaled Type -> MCoercionR -> MCoercionR
+ GHC.Core.Coercion: mkFunResMCo :: Id -> MCoercionR -> MCoercionR
- GHC.Core.Coercion: mkInstCo :: Coercion -> Coercion -> Coercion
+ GHC.Core.Coercion: mkInstCo :: Coercion -> CoercionN -> Coercion
- GHC.Core.Coercion: tyConRolesRepresentational :: TyCon -> [Role]
+ GHC.Core.Coercion: tyConRolesRepresentational :: TyCon -> Infinite Role
- GHC.Core.Coercion: tyConRolesX :: Role -> TyCon -> [Role]
+ GHC.Core.Coercion: tyConRolesX :: Role -> TyCon -> Infinite Role
- GHC.Core.DataCon: mkDataCon :: Name -> Bool -> TyConRepName -> [HsSrcBang] -> [FieldLabel] -> [TyVar] -> [TyCoVar] -> [InvisTVBinder] -> [EqSpec] -> KnotTied ThetaType -> [KnotTied (Scaled Type)] -> KnotTied Type -> RuntimeRepInfo -> KnotTied TyCon -> ConTag -> ThetaType -> Id -> DataConRep -> DataCon
+ GHC.Core.DataCon: mkDataCon :: Name -> Bool -> TyConRepName -> [HsSrcBang] -> [FieldLabel] -> [TyVar] -> [TyCoVar] -> [InvisTVBinder] -> [EqSpec] -> KnotTied ThetaType -> [KnotTied (Scaled Type)] -> KnotTied Type -> PromDataConInfo -> KnotTied TyCon -> ConTag -> ThetaType -> Id -> DataConRep -> DataCon
- GHC.Core.Lint: EndPassConfig :: !Bool -> !Maybe LintPassResultConfig -> !PrintUnqualified -> !Maybe DumpFlag -> !SDoc -> !SDoc -> EndPassConfig
+ GHC.Core.Lint: EndPassConfig :: !Bool -> !Maybe LintPassResultConfig -> !NamePprCtx -> !Maybe DumpFlag -> !SDoc -> !SDoc -> EndPassConfig
- GHC.Core.Lint: dumpPassResult :: Logger -> Bool -> PrintUnqualified -> Maybe DumpFlag -> String -> SDoc -> CoreProgram -> [CoreRule] -> IO ()
+ GHC.Core.Lint: dumpPassResult :: Logger -> Bool -> NamePprCtx -> Maybe DumpFlag -> String -> SDoc -> CoreProgram -> [CoreRule] -> IO ()
- GHC.Core.Opt.Monad: runCoreM :: HscEnv -> RuleBase -> Char -> Module -> ModuleSet -> PrintUnqualified -> SrcSpan -> CoreM a -> IO (a, SimplCount)
+ GHC.Core.Opt.Monad: runCoreM :: HscEnv -> RuleBase -> Char -> Module -> NamePprCtx -> SrcSpan -> CoreM a -> IO (a, SimplCount)
- GHC.Core.Opt.Simplify: simplifyPgm :: Logger -> UnitEnv -> SimplifyOpts -> ModGuts -> IO (SimplCount, ModGuts)
+ GHC.Core.Opt.Simplify: simplifyPgm :: Logger -> UnitEnv -> NamePprCtx -> SimplifyOpts -> ModGuts -> IO (SimplCount, ModGuts)
- GHC.Core.Reduction: mkForAllRedn :: ArgFlag -> TyVar -> ReductionN -> Reduction -> Reduction
+ GHC.Core.Reduction: mkForAllRedn :: ForAllTyFlag -> TyVar -> ReductionN -> Reduction -> Reduction
- GHC.Core.Reduction: mkFunRedn :: Role -> AnonArgFlag -> ReductionN -> Reduction -> Reduction -> Reduction
+ GHC.Core.Reduction: mkFunRedn :: Role -> FunTyFlag -> ReductionN -> Reduction -> Reduction -> Reduction
- GHC.Core.Reduction: simplifyArgsWorker :: HasDebugCallStack => [TyCoBinder] -> Kind -> TyCoVarSet -> [Role] -> [Reduction] -> ArgsReductions
+ GHC.Core.Reduction: simplifyArgsWorker :: HasDebugCallStack => [PiTyBinder] -> Kind -> TyCoVarSet -> Infinite Role -> [Reduction] -> ArgsReductions
- GHC.Core.Subst: substBndrs :: Subst -> [Var] -> (Subst, [Var])
+ GHC.Core.Subst: substBndrs :: Traversable f => Subst -> f Var -> (Subst, f Var)
- GHC.Core.Subst: substRecBndrs :: Subst -> [Id] -> (Subst, [Id])
+ GHC.Core.Subst: substRecBndrs :: Traversable f => Subst -> f Id -> (Subst, f Id)
- GHC.Core.TyCo.FVs: tyCoFVsBndr :: TyCoVarBinder -> FV -> FV
+ GHC.Core.TyCo.FVs: tyCoFVsBndr :: ForAllTyBinder -> FV -> FV
- GHC.Core.TyCo.Ppr: pprForAll :: [TyCoVarBinder] -> SDoc
+ GHC.Core.TyCo.Ppr: pprForAll :: [ForAllTyBinder] -> SDoc
- GHC.Core.TyCo.Ppr: pprTCvBndr :: TyCoVarBinder -> SDoc
+ GHC.Core.TyCo.Ppr: pprTCvBndr :: ForAllTyBinder -> SDoc
- GHC.Core.TyCo.Ppr: pprTCvBndrs :: [TyCoVarBinder] -> SDoc
+ GHC.Core.TyCo.Ppr: pprTCvBndrs :: [ForAllTyBinder] -> SDoc
- GHC.Core.TyCo.Ppr: pprUserForAll :: [TyCoVarBinder] -> SDoc
+ GHC.Core.TyCo.Ppr: pprUserForAll :: [ForAllTyBinder] -> SDoc
- GHC.Core.TyCo.Rep: ForAllTy :: {-# UNPACK #-} !TyCoVarBinder -> Type -> Type
+ GHC.Core.TyCo.Rep: ForAllTy :: {-# UNPACK #-} !ForAllTyBinder -> Type -> Type
- GHC.Core.TyCo.Rep: FunCo :: Role -> CoercionN -> Coercion -> Coercion -> Coercion
+ GHC.Core.TyCo.Rep: FunCo :: Role -> FunTyFlag -> FunTyFlag -> CoercionN -> Coercion -> Coercion
- GHC.Core.TyCo.Rep: FunTy :: AnonArgFlag -> Mult -> Type -> Type -> Type
+ GHC.Core.TyCo.Rep: FunTy :: FunTyFlag -> Mult -> Type -> Type -> Type
- GHC.Core.TyCo.Rep: Invisible :: Specificity -> ArgFlag
+ GHC.Core.TyCo.Rep: Invisible :: Specificity -> ForAllTyFlag
- GHC.Core.TyCo.Rep: Required :: ArgFlag
+ GHC.Core.TyCo.Rep: Required :: ForAllTyFlag
- GHC.Core.TyCo.Rep: TyCoFolder :: (Type -> Maybe Type) -> (env -> TyVar -> a) -> (env -> CoVar -> a) -> (env -> CoercionHole -> a) -> (env -> TyCoVar -> ArgFlag -> env) -> TyCoFolder env a
+ GHC.Core.TyCo.Rep: TyCoFolder :: (Type -> Maybe Type) -> (env -> TyVar -> a) -> (env -> CoVar -> a) -> (env -> CoercionHole -> a) -> (env -> TyCoVar -> ForAllTyFlag -> env) -> TyCoFolder env a
- GHC.Core.TyCo.Rep: [ft_af] :: Type -> AnonArgFlag
+ GHC.Core.TyCo.Rep: [ft_af] :: Type -> FunTyFlag
- GHC.Core.TyCo.Rep: [tcf_tycobinder] :: TyCoFolder env a -> env -> TyCoVar -> ArgFlag -> env
+ GHC.Core.TyCo.Rep: [tcf_tycobinder] :: TyCoFolder env a -> env -> TyCoVar -> ForAllTyFlag -> env
- GHC.Core.TyCo.Rep: infixr 3 `mkInvisFunTyMany`
+ GHC.Core.TyCo.Rep: infixr 3 `mkVisFunTyMany`
- GHC.Core.TyCo.Rep: mkForAllTy :: TyCoVar -> ArgFlag -> Type -> Type
+ GHC.Core.TyCo.Rep: mkForAllTy :: ForAllTyBinder -> Type -> Type
- GHC.Core.TyCo.Rep: mkForAllTys :: [TyCoVarBinder] -> Type -> Type
+ GHC.Core.TyCo.Rep: mkForAllTys :: [ForAllTyBinder] -> Type -> Type
- GHC.Core.TyCo.Rep: mkFunTy :: AnonArgFlag -> Mult -> Type -> Type -> Type
+ GHC.Core.TyCo.Rep: mkFunTy :: HasDebugCallStack => FunTyFlag -> Mult -> Type -> Type -> Type
- GHC.Core.TyCo.Rep: mkInvisFunTy :: Mult -> Type -> Type -> Type
+ GHC.Core.TyCo.Rep: mkInvisFunTy :: HasDebugCallStack => Type -> Type -> Type
- GHC.Core.TyCo.Rep: mkPiTy :: TyCoBinder -> Type -> Type
+ GHC.Core.TyCo.Rep: mkPiTy :: PiTyBinder -> Type -> Type
- GHC.Core.TyCo.Rep: mkPiTys :: [TyCoBinder] -> Type -> Type
+ GHC.Core.TyCo.Rep: mkPiTys :: [PiTyBinder] -> Type -> Type
- GHC.Core.TyCo.Rep: mkVisFunTy :: Mult -> Type -> Type -> Type
+ GHC.Core.TyCo.Rep: mkVisFunTy :: HasDebugCallStack => Mult -> Type -> Type -> Type
- GHC.Core.TyCo.Rep: mkVisFunTyMany :: Type -> Type -> Type
+ GHC.Core.TyCo.Rep: mkVisFunTyMany :: HasDebugCallStack => Type -> Type -> Type
- GHC.Core.TyCo.Rep: pattern Inferred :: ArgFlag
+ GHC.Core.TyCo.Rep: pattern Inferred :: ForAllTyFlag
- GHC.Core.TyCo.Rep: pattern Specified :: ArgFlag
+ GHC.Core.TyCo.Rep: pattern Specified :: ForAllTyFlag
- GHC.Core.TyCo.Subst: extendTvSubstBinderAndInScope :: Subst -> TyCoBinder -> Type -> Subst
+ GHC.Core.TyCo.Subst: extendTvSubstBinderAndInScope :: Subst -> PiTyBinder -> Type -> Subst
- GHC.Core.TyCo.Subst: substTyCoBndr :: Subst -> TyCoBinder -> (Subst, TyCoBinder)
+ GHC.Core.TyCo.Subst: substTyCoBndr :: Subst -> PiTyBinder -> (Subst, PiTyBinder)
- GHC.Core.TyCon: AnonTCB :: AnonArgFlag -> TyConBndrVis
+ GHC.Core.TyCon: AnonTCB :: FunTyFlag -> TyConBndrVis
- GHC.Core.TyCon: DataTyCon :: [DataCon] -> Int -> Bool -> Bool -> AlgTyConRhs
+ GHC.Core.TyCon: DataTyCon :: [DataCon] -> Int -> Bool -> Bool -> Bool -> AlgTyConRhs
- GHC.Core.TyCon: NamedTCB :: ArgFlag -> TyConBndrVis
+ GHC.Core.TyCon: NamedTCB :: ForAllTyFlag -> TyConBndrVis
- GHC.Core.TyCon: RuntimeRep :: ([Type] -> [PrimRep]) -> RuntimeRepInfo
+ GHC.Core.TyCon: RuntimeRep :: ([Type] -> [PrimRep]) -> PromDataConInfo
- GHC.Core.TyCon: VecCount :: Int -> RuntimeRepInfo
+ GHC.Core.TyCon: VecCount :: Int -> PromDataConInfo
- GHC.Core.TyCon: VecElem :: PrimElemRep -> RuntimeRepInfo
+ GHC.Core.TyCon: VecElem :: PrimElemRep -> PromDataConInfo
- GHC.Core.TyCon: mkAnonTyConBinder :: AnonArgFlag -> TyVar -> TyConBinder
+ GHC.Core.TyCon: mkAnonTyConBinder :: TyVar -> TyConBinder
- GHC.Core.TyCon: mkAnonTyConBinders :: AnonArgFlag -> [TyVar] -> [TyConBinder]
+ GHC.Core.TyCon: mkAnonTyConBinders :: [TyVar] -> [TyConBinder]
- GHC.Core.TyCon: mkLevPolyDataTyConRhs :: Bool -> [DataCon] -> AlgTyConRhs
+ GHC.Core.TyCon: mkLevPolyDataTyConRhs :: Bool -> Bool -> [DataCon] -> AlgTyConRhs
- GHC.Core.TyCon: mkNamedTyConBinder :: ArgFlag -> TyVar -> TyConBinder
+ GHC.Core.TyCon: mkNamedTyConBinder :: ForAllTyFlag -> TyVar -> TyConBinder
- GHC.Core.TyCon: mkNamedTyConBinders :: ArgFlag -> [TyVar] -> [TyConBinder]
+ GHC.Core.TyCon: mkNamedTyConBinders :: ForAllTyFlag -> [TyVar] -> [TyConBinder]
- GHC.Core.TyCon: mkPromotedDataCon :: DataCon -> Name -> TyConRepName -> [TyConTyCoBinder] -> Kind -> [Role] -> RuntimeRepInfo -> TyCon
+ GHC.Core.TyCon: mkPromotedDataCon :: DataCon -> Name -> TyConRepName -> [TyConPiTyBinder] -> Kind -> [Role] -> PromDataConInfo -> TyCon
- GHC.Core.Type: Invisible :: Specificity -> ArgFlag
+ GHC.Core.Type: Invisible :: Specificity -> ForAllTyFlag
- GHC.Core.Type: Required :: ArgFlag
+ GHC.Core.Type: Required :: ForAllTyFlag
- GHC.Core.Type: TyCoFolder :: (Type -> Maybe Type) -> (env -> TyVar -> a) -> (env -> CoVar -> a) -> (env -> CoercionHole -> a) -> (env -> TyCoVar -> ArgFlag -> env) -> TyCoFolder env a
+ GHC.Core.Type: TyCoFolder :: (Type -> Maybe Type) -> (env -> TyVar -> a) -> (env -> CoVar -> a) -> (env -> CoercionHole -> a) -> (env -> TyCoVar -> ForAllTyFlag -> env) -> TyCoFolder env a
- GHC.Core.Type: TyCoMapper :: (env -> TyVar -> m Type) -> (env -> CoVar -> m Coercion) -> (env -> CoercionHole -> m Coercion) -> (env -> TyCoVar -> ArgFlag -> m (env, TyCoVar)) -> (TyCon -> m TyCon) -> TyCoMapper env m
+ GHC.Core.Type: TyCoMapper :: (env -> TyVar -> m Type) -> (env -> CoVar -> m Coercion) -> (env -> CoercionHole -> m Coercion) -> (env -> TyCoVar -> ForAllTyFlag -> m (env, TyCoVar)) -> (TyCon -> m TyCon) -> TyCoMapper env m
- GHC.Core.Type: [tcf_tycobinder] :: TyCoFolder env a -> env -> TyCoVar -> ArgFlag -> env
+ GHC.Core.Type: [tcf_tycobinder] :: TyCoFolder env a -> env -> TyCoVar -> ForAllTyFlag -> env
- GHC.Core.Type: [tcm_tycobinder] :: TyCoMapper env m -> env -> TyCoVar -> ArgFlag -> m (env, TyCoVar)
+ GHC.Core.Type: [tcm_tycobinder] :: TyCoMapper env m -> env -> TyCoVar -> ForAllTyFlag -> m (env, TyCoVar)
- GHC.Core.Type: extendTvSubstBinderAndInScope :: Subst -> TyCoBinder -> Type -> Subst
+ GHC.Core.Type: extendTvSubstBinderAndInScope :: Subst -> PiTyBinder -> Type -> Subst
- GHC.Core.Type: funResultTy :: Type -> Type
+ GHC.Core.Type: funResultTy :: HasDebugCallStack => Type -> Type
- GHC.Core.Type: getRuntimeArgTys :: Type -> [(Scaled Type, AnonArgFlag)]
+ GHC.Core.Type: getRuntimeArgTys :: Type -> [(Scaled Type, FunTyFlag)]
- GHC.Core.Type: getTyVar :: String -> Type -> TyVar
+ GHC.Core.Type: getTyVar :: HasDebugCallStack => Type -> TyVar
- GHC.Core.Type: infixr 3 `mkInvisFunTyMany`
+ GHC.Core.Type: infixr 3 `mkInvisFunTy`
- GHC.Core.Type: isBoxedRuntimeRep :: Type -> Bool
+ GHC.Core.Type: isBoxedRuntimeRep :: RuntimeRepType -> Bool
- GHC.Core.Type: isLiftedRuntimeRep :: Type -> Bool
+ GHC.Core.Type: isLiftedRuntimeRep :: RuntimeRepType -> Bool
- GHC.Core.Type: isUnliftedRuntimeRep :: Type -> Bool
+ GHC.Core.Type: isUnliftedRuntimeRep :: RuntimeRepType -> Bool
- GHC.Core.Type: mkForAllTy :: TyCoVar -> ArgFlag -> Type -> Type
+ GHC.Core.Type: mkForAllTy :: ForAllTyBinder -> Type -> Type
- GHC.Core.Type: mkForAllTys :: [TyCoVarBinder] -> Type -> Type
+ GHC.Core.Type: mkForAllTys :: [ForAllTyBinder] -> Type -> Type
- GHC.Core.Type: mkFunTy :: AnonArgFlag -> Mult -> Type -> Type -> Type
+ GHC.Core.Type: mkFunTy :: HasDebugCallStack => FunTyFlag -> Mult -> Type -> Type -> Type
- GHC.Core.Type: mkInvisFunTy :: Mult -> Type -> Type -> Type
+ GHC.Core.Type: mkInvisFunTy :: HasDebugCallStack => Type -> Type -> Type
- GHC.Core.Type: mkPiTy :: TyCoBinder -> Type -> Type
+ GHC.Core.Type: mkPiTy :: PiTyBinder -> Type -> Type
- GHC.Core.Type: mkPiTys :: [TyCoBinder] -> Type -> Type
+ GHC.Core.Type: mkPiTys :: [PiTyBinder] -> Type -> Type
- GHC.Core.Type: mkVisFunTy :: Mult -> Type -> Type -> Type
+ GHC.Core.Type: mkVisFunTy :: HasDebugCallStack => Mult -> Type -> Type -> Type
- GHC.Core.Type: mkVisFunTyMany :: Type -> Type -> Type
+ GHC.Core.Type: mkVisFunTyMany :: HasDebugCallStack => Type -> Type -> Type
- GHC.Core.Type: partitionInvisibles :: [(a, ArgFlag)] -> ([a], [a])
+ GHC.Core.Type: partitionInvisibles :: [(a, ForAllTyFlag)] -> ([a], [a])
- GHC.Core.Type: pattern Inferred :: ArgFlag
+ GHC.Core.Type: pattern Inferred :: ForAllTyFlag
- GHC.Core.Type: pattern Specified :: ArgFlag
+ GHC.Core.Type: pattern Specified :: ForAllTyFlag
- GHC.Core.Type: runtimeRepLevity_maybe :: Type -> Maybe Levity
+ GHC.Core.Type: runtimeRepLevity_maybe :: RuntimeRepType -> Maybe Levity
- GHC.Core.Type: splitForAllCoVar_maybe :: Type -> Maybe (TyCoVar, Type)
+ GHC.Core.Type: splitForAllCoVar_maybe :: Type -> Maybe (CoVar, Type)
- GHC.Core.Type: splitForAllTyVar_maybe :: Type -> Maybe (TyCoVar, Type)
+ GHC.Core.Type: splitForAllTyVar_maybe :: Type -> Maybe (TyVar, Type)
- GHC.Core.Type: splitFunTy_maybe :: Type -> Maybe (Mult, Type, Type)
+ GHC.Core.Type: splitFunTy_maybe :: Type -> Maybe (FunTyFlag, Mult, Type, Type)
- GHC.Core.Type: splitInvisPiTys :: Type -> ([TyCoBinder], Type)
+ GHC.Core.Type: splitInvisPiTys :: Type -> ([PiTyBinder], Type)
- GHC.Core.Type: splitInvisPiTysN :: Int -> Type -> ([TyCoBinder], Type)
+ GHC.Core.Type: splitInvisPiTysN :: Int -> Type -> ([PiTyBinder], Type)
- GHC.Core.Type: splitPiTy :: Type -> (TyCoBinder, Type)
+ GHC.Core.Type: splitPiTy :: Type -> (PiTyBinder, Type)
- GHC.Core.Type: splitPiTy_maybe :: Type -> Maybe (TyCoBinder, Type)
+ GHC.Core.Type: splitPiTy_maybe :: Type -> Maybe (PiTyBinder, Type)
- GHC.Core.Type: splitPiTys :: Type -> ([TyCoBinder], Type)
+ GHC.Core.Type: splitPiTys :: Type -> ([PiTyBinder], Type)
- GHC.Core.Type: substTyCoBndr :: Subst -> TyCoBinder -> (Subst, TyCoBinder)
+ GHC.Core.Type: substTyCoBndr :: Subst -> PiTyBinder -> (Subst, PiTyBinder)
- GHC.Core.Type: tyCoFVsBndr :: TyCoVarBinder -> FV -> FV
+ GHC.Core.Type: tyCoFVsBndr :: ForAllTyBinder -> FV -> FV
- GHC.Core.Type: tyVarSpecToBinders :: [VarBndr a Specificity] -> [VarBndr a ArgFlag]
+ GHC.Core.Type: tyVarSpecToBinders :: [VarBndr a Specificity] -> [VarBndr a ForAllTyFlag]
- GHC.Core.Type: type TyVarBinder = VarBndr TyVar ArgFlag
+ GHC.Core.Type: type TyVarBinder = VarBndr TyVar ForAllTyFlag
- GHC.Core.Type: typeHasFixedRuntimeRep :: Type -> Bool
+ GHC.Core.Type: typeHasFixedRuntimeRep :: HasDebugCallStack => Type -> Bool
- GHC.Driver.Config.Core.Lint: endPassHscEnvIO :: HscEnv -> PrintUnqualified -> CoreToDo -> CoreProgram -> [CoreRule] -> IO ()
+ GHC.Driver.Config.Core.Lint: endPassHscEnvIO :: HscEnv -> NamePprCtx -> CoreToDo -> CoreProgram -> [CoreRule] -> IO ()
- GHC.Driver.Config.Core.Lint: initEndPassConfig :: DynFlags -> [Var] -> PrintUnqualified -> CoreToDo -> EndPassConfig
+ GHC.Driver.Config.Core.Lint: initEndPassConfig :: DynFlags -> [Var] -> NamePprCtx -> CoreToDo -> EndPassConfig
- GHC.Driver.Ppr: printForUser :: DynFlags -> Handle -> PrintUnqualified -> Depth -> SDoc -> IO ()
+ GHC.Driver.Ppr: printForUser :: DynFlags -> Handle -> NamePprCtx -> Depth -> SDoc -> IO ()
- GHC.Driver.Ppr: showSDocForUser :: DynFlags -> UnitState -> PrintUnqualified -> SDoc -> String
+ GHC.Driver.Ppr: showSDocForUser :: DynFlags -> UnitState -> NamePprCtx -> SDoc -> String
- GHC.Iface.Syntax: IfDataTyCon :: [IfaceConDecl] -> IfaceConDecls
+ GHC.Iface.Syntax: IfDataTyCon :: !Bool -> [IfaceConDecl] -> IfaceConDecls
- GHC.Iface.Syntax: IfaceLitRubbish :: IfaceType -> IfaceExpr
+ GHC.Iface.Syntax: IfaceLitRubbish :: TypeOrConstraint -> IfaceType -> IfaceExpr
- GHC.Iface.Type: IA_Arg :: IfaceType -> ArgFlag -> IfaceAppArgs -> IfaceAppArgs
+ GHC.Iface.Type: IA_Arg :: IfaceType -> ForAllTyFlag -> IfaceAppArgs -> IfaceAppArgs
- GHC.Iface.Type: IfaceFunTy :: AnonArgFlag -> IfaceMult -> IfaceType -> IfaceType -> IfaceType
+ GHC.Iface.Type: IfaceFunTy :: FunTyFlag -> IfaceMult -> IfaceType -> IfaceType -> IfaceType
- GHC.Iface.Type: Invisible :: Specificity -> ArgFlag
+ GHC.Iface.Type: Invisible :: Specificity -> ForAllTyFlag
- GHC.Iface.Type: Required :: ArgFlag
+ GHC.Iface.Type: Required :: ForAllTyFlag
- GHC.Iface.Type: mkIfaceForAllTvBndr :: ArgFlag -> IfaceTvBndr -> IfaceForAllBndr
+ GHC.Iface.Type: mkIfaceForAllTvBndr :: ForAllTyFlag -> IfaceTvBndr -> IfaceForAllBndr
- GHC.Iface.Type: pattern Inferred :: ArgFlag
+ GHC.Iface.Type: pattern Inferred :: ForAllTyFlag
- GHC.Iface.Type: pattern Specified :: ArgFlag
+ GHC.Iface.Type: pattern Specified :: ForAllTyFlag
- GHC.Iface.Type: type IfaceForAllBndr = VarBndr IfaceBndr ArgFlag
+ GHC.Iface.Type: type IfaceForAllBndr = VarBndr IfaceBndr ForAllTyFlag
- GHC.Linker.Static.Utils: exeFileName :: Platform -> Bool -> Maybe FilePath -> FilePath
+ GHC.Linker.Static.Utils: exeFileName :: ArchOS -> Bool -> Maybe FilePath -> FilePath
- GHC.Tc.Types: getPlatform :: TcM Platform
+ GHC.Tc.Types: getPlatform :: TcRnIf a b Platform
- GHC.Tc.Types.Constraint: CDictCan :: CtEvidence -> Class -> [Xi] -> Bool -> Bool -> Ct
+ GHC.Tc.Types.Constraint: CDictCan :: CtEvidence -> Class -> [Xi] -> Bool -> Ct
- GHC.Tc.Types.Constraint: ContainsForall :: TyCoVarBinder -> TcType -> NotConcreteReason
+ GHC.Tc.Types.Constraint: ContainsForall :: ForAllTyBinder -> TcType -> NotConcreteReason
- GHC.Tc.Types.Constraint: isPendingScDict :: Ct -> Maybe Ct
+ GHC.Tc.Types.Constraint: isPendingScDict :: Ct -> Bool
- GHC.Tc.Utils.TcType: Invisible :: Specificity -> ArgFlag
+ GHC.Tc.Utils.TcType: Invisible :: Specificity -> ForAllTyFlag
- GHC.Tc.Utils.TcType: Required :: ArgFlag
+ GHC.Tc.Utils.TcType: Required :: ForAllTyFlag
- GHC.Tc.Utils.TcType: getTyVar :: String -> Type -> TyVar
+ GHC.Tc.Utils.TcType: getTyVar :: HasDebugCallStack => Type -> TyVar
- GHC.Tc.Utils.TcType: infixr 3 `mkVisFunTyMany`
+ GHC.Tc.Utils.TcType: infixr 3 `mkInvisFunTy`
- GHC.Tc.Utils.TcType: mkForAllTy :: TyCoVar -> ArgFlag -> Type -> Type
+ GHC.Tc.Utils.TcType: mkForAllTy :: ForAllTyBinder -> Type -> Type
- GHC.Tc.Utils.TcType: mkForAllTys :: [TyCoVarBinder] -> Type -> Type
+ GHC.Tc.Utils.TcType: mkForAllTys :: [ForAllTyBinder] -> Type -> Type
- GHC.Tc.Utils.TcType: mkInfSigmaTy :: [TyCoVar] -> [PredType] -> Type -> Type
+ GHC.Tc.Utils.TcType: mkInfSigmaTy :: HasDebugCallStack => [TyCoVar] -> [PredType] -> Type -> Type
- GHC.Tc.Utils.TcType: mkInvisFunTy :: Mult -> Type -> Type -> Type
+ GHC.Tc.Utils.TcType: mkInvisFunTy :: HasDebugCallStack => Type -> Type -> Type
- GHC.Tc.Utils.TcType: mkPhiTy :: [PredType] -> Type -> Type
+ GHC.Tc.Utils.TcType: mkPhiTy :: HasDebugCallStack => [PredType] -> Type -> Type
- GHC.Tc.Utils.TcType: mkSigmaTy :: [TyCoVarBinder] -> [PredType] -> Type -> Type
+ GHC.Tc.Utils.TcType: mkSigmaTy :: HasDebugCallStack => [ForAllTyBinder] -> [PredType] -> Type -> Type
- GHC.Tc.Utils.TcType: mkSpecSigmaTy :: [TyVar] -> [PredType] -> Type -> Type
+ GHC.Tc.Utils.TcType: mkSpecSigmaTy :: HasDebugCallStack => [TyVar] -> [PredType] -> Type -> Type
- GHC.Tc.Utils.TcType: mkVisFunTy :: Mult -> Type -> Type -> Type
+ GHC.Tc.Utils.TcType: mkVisFunTy :: HasDebugCallStack => Mult -> Type -> Type -> Type
- GHC.Tc.Utils.TcType: mkVisFunTyMany :: Type -> Type -> Type
+ GHC.Tc.Utils.TcType: mkVisFunTyMany :: HasDebugCallStack => Type -> Type -> Type
- GHC.Tc.Utils.TcType: pattern Inferred :: ArgFlag
+ GHC.Tc.Utils.TcType: pattern Inferred :: ForAllTyFlag
- GHC.Tc.Utils.TcType: pattern Specified :: ArgFlag
+ GHC.Tc.Utils.TcType: pattern Specified :: ForAllTyFlag
- GHC.Tc.Utils.TcType: pickyEqType :: TcType -> TcType -> Bool
+ GHC.Tc.Utils.TcType: pickyEqType :: Type -> Type -> Bool
- GHC.Tc.Utils.TcType: pprTCvBndr :: TyCoVarBinder -> SDoc
+ GHC.Tc.Utils.TcType: pprTCvBndr :: ForAllTyBinder -> SDoc
- GHC.Tc.Utils.TcType: pprTCvBndrs :: [TyCoVarBinder] -> SDoc
+ GHC.Tc.Utils.TcType: pprTCvBndrs :: [ForAllTyBinder] -> SDoc
- GHC.Tc.Utils.TcType: tcEqKind :: HasDebugCallStack => TcKind -> TcKind -> Bool
+ GHC.Tc.Utils.TcType: tcEqKind :: HasDebugCallStack => Kind -> Kind -> Bool
- GHC.Tc.Utils.TcType: tcEqType :: HasDebugCallStack => TcType -> TcType -> Bool
+ GHC.Tc.Utils.TcType: tcEqType :: HasDebugCallStack => Type -> Type -> Bool
- GHC.Tc.Utils.TcType: tcEqTypeNoKindCheck :: TcType -> TcType -> Bool
+ GHC.Tc.Utils.TcType: tcEqTypeNoKindCheck :: Type -> Type -> Bool
- GHC.Tc.Utils.TcType: tcEqTypeVis :: TcType -> TcType -> Bool
+ GHC.Tc.Utils.TcType: tcEqTypeVis :: Type -> Type -> Bool
- GHC.Tc.Utils.TcType: tcSplitPiTy_maybe :: Type -> Maybe (TyBinder, Type)
+ GHC.Tc.Utils.TcType: tcSplitPiTy_maybe :: Type -> Maybe (PiTyVarBinder, Type)
- GHC.Tc.Utils.TcType: tcSplitPiTys :: Type -> ([TyBinder], Type)
+ GHC.Tc.Utils.TcType: tcSplitPiTys :: Type -> ([PiTyVarBinder], Type)
- GHC.Tc.Utils.TcType: tcSplitSomeForAllTyVars :: (ArgFlag -> Bool) -> Type -> ([TyVar], Type)
+ GHC.Tc.Utils.TcType: tcSplitSomeForAllTyVars :: (ForAllTyFlag -> Bool) -> Type -> ([TyVar], Type)
- GHC.Types.Demand: dmdTransformDataConSig :: Arity -> DmdTransformer
+ GHC.Types.Demand: dmdTransformDataConSig :: [StrictnessMark] -> DmdTransformer
- GHC.Types.Demand: peelManyCalls :: Int -> SubDemand -> Card
+ GHC.Types.Demand: peelManyCalls :: Arity -> SubDemand -> (Card, SubDemand)
- GHC.Types.Error: MsgEnvelope :: SrcSpan -> PrintUnqualified -> e -> Severity -> MsgEnvelope e
+ GHC.Types.Error: MsgEnvelope :: SrcSpan -> NamePprCtx -> e -> Severity -> MsgEnvelope e
- GHC.Types.Error: [errMsgContext] :: MsgEnvelope e -> PrintUnqualified
+ GHC.Types.Error: [errMsgContext] :: MsgEnvelope e -> NamePprCtx
- GHC.Types.Literal: LitRubbish :: RuntimeRepType -> Literal
+ GHC.Types.Literal: LitRubbish :: TypeOrConstraint -> RuntimeRepType -> Literal
- GHC.Types.Name: mkFCallName :: Unique -> String -> Name
+ GHC.Types.Name: mkFCallName :: Unique -> FastString -> Name
- GHC.Types.Name: pprModulePrefix :: PprStyle -> Module -> OccName -> SDoc
+ GHC.Types.Name: pprModulePrefix :: IsLine doc => PprStyle -> Module -> OccName -> doc
- GHC.Types.Name.Occurrence: pprNameSpaceBrief :: NameSpace -> SDoc
+ GHC.Types.Name.Occurrence: pprNameSpaceBrief :: IsLine doc => NameSpace -> doc
- GHC.Types.Name.Occurrence: pprOccName :: OccName -> SDoc
+ GHC.Types.Name.Occurrence: pprOccName :: IsLine doc => OccName -> doc
- GHC.Types.Name.Ppr: pkgQual :: UnitState -> PrintUnqualified
+ GHC.Types.Name.Ppr: pkgQual :: UnitState -> NamePprCtx
- GHC.Types.RepType: layoutUbxSum :: SortedSlotTys -> [SlotTy] -> [Int]
+ GHC.Types.RepType: layoutUbxSum :: HasDebugCallStack => SortedSlotTys -> [SlotTy] -> [Int]
- GHC.Types.RepType: ubxSumRepType :: [[PrimRep]] -> [SlotTy]
+ GHC.Types.RepType: ubxSumRepType :: [[PrimRep]] -> NonEmpty SlotTy
- GHC.Types.Unique: pprUniqueAlways :: Unique -> SDoc
+ GHC.Types.Unique: pprUniqueAlways :: IsLine doc => Unique -> doc
- GHC.Types.Var: Invisible :: Specificity -> ArgFlag
+ GHC.Types.Var: Invisible :: Specificity -> ForAllTyFlag
- GHC.Types.Var: Required :: ArgFlag
+ GHC.Types.Var: Required :: ForAllTyFlag
- GHC.Types.Var: isTyVarBinder :: TyCoVarBinder -> Bool
+ GHC.Types.Var: isTyVarBinder :: VarBndr TyCoVar vis -> Bool
- GHC.Types.Var: pattern Inferred :: ArgFlag
+ GHC.Types.Var: pattern Inferred :: ForAllTyFlag
- GHC.Types.Var: pattern Specified :: ArgFlag
+ GHC.Types.Var: pattern Specified :: ForAllTyFlag
- GHC.Types.Var: tyVarReqToBinder :: VarBndr a () -> VarBndr a ArgFlag
+ GHC.Types.Var: tyVarReqToBinder :: VarBndr a () -> VarBndr a ForAllTyFlag
- GHC.Types.Var: tyVarReqToBinders :: [VarBndr a ()] -> [VarBndr a ArgFlag]
+ GHC.Types.Var: tyVarReqToBinders :: [VarBndr a ()] -> [VarBndr a ForAllTyFlag]
- GHC.Types.Var: tyVarSpecToBinder :: VarBndr a Specificity -> VarBndr a ArgFlag
+ GHC.Types.Var: tyVarSpecToBinder :: VarBndr a Specificity -> VarBndr a ForAllTyFlag
- GHC.Types.Var: tyVarSpecToBinders :: [VarBndr a Specificity] -> [VarBndr a ArgFlag]
+ GHC.Types.Var: tyVarSpecToBinders :: [VarBndr a Specificity] -> [VarBndr a ForAllTyFlag]
- GHC.Types.Var: type TyVarBinder = VarBndr TyVar ArgFlag
+ GHC.Types.Var: type TyVarBinder = VarBndr TyVar ForAllTyFlag
- GHC.Unit.Types: pprModule :: Module -> SDoc
+ GHC.Unit.Types: pprModule :: IsLine doc => Module -> doc
- GHC.Utils.Error: MsgEnvelope :: SrcSpan -> PrintUnqualified -> e -> Severity -> MsgEnvelope e
+ GHC.Utils.Error: MsgEnvelope :: SrcSpan -> NamePprCtx -> e -> Severity -> MsgEnvelope e
- GHC.Utils.Error: [errMsgContext] :: MsgEnvelope e -> PrintUnqualified
+ GHC.Utils.Error: [errMsgContext] :: MsgEnvelope e -> NamePprCtx
- GHC.Utils.Error: mkErrorMsgEnvelope :: Diagnostic e => SrcSpan -> PrintUnqualified -> e -> MsgEnvelope e
+ GHC.Utils.Error: mkErrorMsgEnvelope :: Diagnostic e => SrcSpan -> NamePprCtx -> e -> MsgEnvelope e
- GHC.Utils.Error: mkMsgEnvelope :: Diagnostic e => DiagOpts -> SrcSpan -> PrintUnqualified -> e -> MsgEnvelope e
+ GHC.Utils.Error: mkMsgEnvelope :: Diagnostic e => DiagOpts -> SrcSpan -> NamePprCtx -> e -> MsgEnvelope e
- GHC.Utils.Error: printInfoForUser :: Logger -> PrintUnqualified -> SDoc -> IO ()
+ GHC.Utils.Error: printInfoForUser :: Logger -> NamePprCtx -> SDoc -> IO ()
- GHC.Utils.Error: printOutputForUser :: Logger -> PrintUnqualified -> SDoc -> IO ()
+ GHC.Utils.Error: printOutputForUser :: Logger -> NamePprCtx -> SDoc -> IO ()
- GHC.Utils.Logger: putDumpFileMaybe' :: Logger -> PrintUnqualified -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
+ GHC.Utils.Logger: putDumpFileMaybe' :: Logger -> NamePprCtx -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
- GHC.Utils.Misc: zipEqual :: String -> [a] -> [b] -> [(a, b)]
+ GHC.Utils.Misc: zipEqual :: HasDebugCallStack => String -> [a] -> [b] -> [(a, b)]
- GHC.Utils.Misc: zipWith3Equal :: String -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
+ GHC.Utils.Misc: zipWith3Equal :: HasDebugCallStack => String -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
- GHC.Utils.Misc: zipWith4Equal :: String -> (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
+ GHC.Utils.Misc: zipWith4Equal :: HasDebugCallStack => String -> (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
- GHC.Utils.Misc: zipWithEqual :: String -> (a -> b -> c) -> [a] -> [b] -> [c]
+ GHC.Utils.Misc: zipWithEqual :: HasDebugCallStack => String -> (a -> b -> c) -> [a] -> [b] -> [c]
- GHC.Utils.Outputable: ($$) :: SDoc -> SDoc -> SDoc
+ GHC.Utils.Outputable: ($$) :: IsDoc doc => doc -> doc -> doc
- GHC.Utils.Outputable: (<+>) :: SDoc -> SDoc -> SDoc
+ GHC.Utils.Outputable: (<+>) :: IsLine doc => doc -> doc -> doc
- GHC.Utils.Outputable: (<>) :: SDoc -> SDoc -> SDoc
+ GHC.Utils.Outputable: (<>) :: IsLine doc => doc -> doc -> doc
- GHC.Utils.Outputable: PprDump :: PrintUnqualified -> PprStyle
+ GHC.Utils.Outputable: PprDump :: NamePprCtx -> PprStyle
- GHC.Utils.Outputable: PprUser :: PrintUnqualified -> Depth -> Coloured -> PprStyle
+ GHC.Utils.Outputable: PprUser :: NamePprCtx -> Depth -> Coloured -> PprStyle
- GHC.Utils.Outputable: QueryQualify :: QueryQualifyName -> QueryQualifyModule -> QueryQualifyPackage -> PrintUnqualified
+ GHC.Utils.Outputable: QueryQualify :: QueryQualifyName -> QueryQualifyModule -> QueryQualifyPackage -> QueryPromotionTick -> NamePprCtx
- GHC.Utils.Outputable: SDC :: !PprStyle -> !Scheme -> !PprColour -> !Bool -> !Int -> !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 -> !FastString -> SDoc -> SDocContext
+ GHC.Utils.Outputable: SDC :: !PprStyle -> !Scheme -> !PprColour -> !Bool -> !Int -> !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 -> !Bool -> !FastString -> SDoc -> SDocContext
- GHC.Utils.Outputable: [queryQualifyModule] :: PrintUnqualified -> QueryQualifyModule
+ GHC.Utils.Outputable: [queryQualifyModule] :: NamePprCtx -> QueryQualifyModule
- GHC.Utils.Outputable: [queryQualifyName] :: PrintUnqualified -> QueryQualifyName
+ GHC.Utils.Outputable: [queryQualifyName] :: NamePprCtx -> QueryQualifyName
- GHC.Utils.Outputable: [queryQualifyPackage] :: PrintUnqualified -> QueryQualifyPackage
+ GHC.Utils.Outputable: [queryQualifyPackage] :: NamePprCtx -> QueryQualifyPackage
- GHC.Utils.Outputable: alwaysQualify :: PrintUnqualified
+ GHC.Utils.Outputable: alwaysQualify :: NamePprCtx
- GHC.Utils.Outputable: angleBrackets :: SDoc -> SDoc
+ GHC.Utils.Outputable: angleBrackets :: IsLine doc => doc -> doc
- GHC.Utils.Outputable: braces :: SDoc -> SDoc
+ GHC.Utils.Outputable: braces :: IsLine doc => doc -> doc
- GHC.Utils.Outputable: brackets :: SDoc -> SDoc
+ GHC.Utils.Outputable: brackets :: IsLine doc => doc -> doc
- GHC.Utils.Outputable: char :: Char -> SDoc
+ GHC.Utils.Outputable: char :: IsLine doc => Char -> doc
- GHC.Utils.Outputable: colon :: SDoc
+ GHC.Utils.Outputable: colon :: IsLine doc => doc
- GHC.Utils.Outputable: comma :: SDoc
+ GHC.Utils.Outputable: comma :: IsLine doc => doc
- GHC.Utils.Outputable: dot :: SDoc
+ GHC.Utils.Outputable: dot :: IsLine doc => doc
- GHC.Utils.Outputable: double :: Double -> SDoc
+ GHC.Utils.Outputable: double :: IsLine doc => Double -> doc
- GHC.Utils.Outputable: doubleQuotes :: SDoc -> SDoc
+ GHC.Utils.Outputable: doubleQuotes :: IsLine doc => doc -> doc
- GHC.Utils.Outputable: empty :: SDoc
+ GHC.Utils.Outputable: empty :: IsOutput doc => doc
- GHC.Utils.Outputable: equals :: SDoc
+ GHC.Utils.Outputable: equals :: IsLine doc => doc
- GHC.Utils.Outputable: float :: Float -> SDoc
+ GHC.Utils.Outputable: float :: IsLine doc => Float -> doc
- GHC.Utils.Outputable: fsep :: [SDoc] -> SDoc
+ GHC.Utils.Outputable: fsep :: IsLine doc => [doc] -> doc
- GHC.Utils.Outputable: ftext :: FastString -> SDoc
+ GHC.Utils.Outputable: ftext :: IsLine doc => FastString -> doc
- GHC.Utils.Outputable: getPprDebug :: (Bool -> SDoc) -> SDoc
+ GHC.Utils.Outputable: getPprDebug :: IsOutput doc => (Bool -> doc) -> doc
- GHC.Utils.Outputable: hcat :: [SDoc] -> SDoc
+ GHC.Utils.Outputable: hcat :: IsLine doc => [doc] -> doc
- GHC.Utils.Outputable: hsep :: [SDoc] -> SDoc
+ GHC.Utils.Outputable: hsep :: IsLine doc => [doc] -> doc
- GHC.Utils.Outputable: ifPprDebug :: SDoc -> SDoc -> SDoc
+ GHC.Utils.Outputable: ifPprDebug :: IsOutput doc => doc -> doc -> doc
- GHC.Utils.Outputable: int :: Int -> SDoc
+ GHC.Utils.Outputable: int :: IsLine doc => Int -> doc
- GHC.Utils.Outputable: integer :: Integer -> SDoc
+ GHC.Utils.Outputable: integer :: IsLine doc => Integer -> doc
- GHC.Utils.Outputable: lbrace :: SDoc
+ GHC.Utils.Outputable: lbrace :: IsLine doc => doc
- GHC.Utils.Outputable: lbrack :: SDoc
+ GHC.Utils.Outputable: lbrack :: IsLine doc => doc
- GHC.Utils.Outputable: lparen :: SDoc
+ GHC.Utils.Outputable: lparen :: IsLine doc => doc
- GHC.Utils.Outputable: mkDumpStyle :: PrintUnqualified -> PprStyle
+ GHC.Utils.Outputable: mkDumpStyle :: NamePprCtx -> PprStyle
- GHC.Utils.Outputable: mkErrStyle :: PrintUnqualified -> PprStyle
+ GHC.Utils.Outputable: mkErrStyle :: NamePprCtx -> PprStyle
- GHC.Utils.Outputable: mkUserStyle :: PrintUnqualified -> Depth -> PprStyle
+ GHC.Utils.Outputable: mkUserStyle :: NamePprCtx -> Depth -> PprStyle
- GHC.Utils.Outputable: neverQualify :: PrintUnqualified
+ GHC.Utils.Outputable: neverQualify :: NamePprCtx
- GHC.Utils.Outputable: parens :: SDoc -> SDoc
+ GHC.Utils.Outputable: parens :: IsLine doc => doc -> doc
- GHC.Utils.Outputable: ppUnless :: Bool -> SDoc -> SDoc
+ GHC.Utils.Outputable: ppUnless :: IsOutput doc => Bool -> doc -> doc
- GHC.Utils.Outputable: ppUnlessOption :: (SDocContext -> Bool) -> SDoc -> SDoc
+ GHC.Utils.Outputable: ppUnlessOption :: IsLine doc => (SDocContext -> Bool) -> doc -> doc
- GHC.Utils.Outputable: ppWhen :: Bool -> SDoc -> SDoc
+ GHC.Utils.Outputable: ppWhen :: IsOutput doc => Bool -> doc -> doc
- GHC.Utils.Outputable: pprFilePathString :: FilePath -> SDoc
+ GHC.Utils.Outputable: pprFilePathString :: IsLine doc => FilePath -> doc
- GHC.Utils.Outputable: pprModuleName :: ModuleName -> SDoc
+ GHC.Utils.Outputable: pprModuleName :: IsLine doc => ModuleName -> doc
- GHC.Utils.Outputable: punctuate :: SDoc -> [SDoc] -> [SDoc]
+ GHC.Utils.Outputable: punctuate :: IsLine doc => doc -> [doc] -> [doc]
- GHC.Utils.Outputable: queryQual :: PprStyle -> PrintUnqualified
+ GHC.Utils.Outputable: queryQual :: PprStyle -> NamePprCtx
- GHC.Utils.Outputable: rbrace :: SDoc
+ GHC.Utils.Outputable: rbrace :: IsLine doc => doc
- GHC.Utils.Outputable: rbrack :: SDoc
+ GHC.Utils.Outputable: rbrack :: IsLine doc => doc
- GHC.Utils.Outputable: reallyAlwaysQualify :: PrintUnqualified
+ GHC.Utils.Outputable: reallyAlwaysQualify :: NamePprCtx
- GHC.Utils.Outputable: rparen :: SDoc
+ GHC.Utils.Outputable: rparen :: IsLine doc => doc
- GHC.Utils.Outputable: semi :: SDoc
+ GHC.Utils.Outputable: semi :: IsLine doc => doc
- GHC.Utils.Outputable: sep :: [SDoc] -> SDoc
+ GHC.Utils.Outputable: sep :: IsLine doc => [doc] -> doc
- GHC.Utils.Outputable: space :: SDoc
+ GHC.Utils.Outputable: space :: IsLine doc => doc
- GHC.Utils.Outputable: text :: String -> SDoc
+ GHC.Utils.Outputable: text :: IsLine doc => String -> doc
- GHC.Utils.Outputable: underscore :: SDoc
+ GHC.Utils.Outputable: underscore :: IsLine doc => doc
- GHC.Utils.Outputable: vbar :: SDoc
+ GHC.Utils.Outputable: vbar :: IsLine doc => doc
- GHC.Utils.Outputable: vcat :: [SDoc] -> SDoc
+ GHC.Utils.Outputable: vcat :: IsDoc doc => [doc] -> doc
- GHC.Utils.Outputable: whenPprDebug :: SDoc -> SDoc
+ GHC.Utils.Outputable: whenPprDebug :: IsOutput doc => doc -> doc
- GHC.Utils.Outputable: withErrStyle :: PrintUnqualified -> SDoc -> SDoc
+ GHC.Utils.Outputable: withErrStyle :: NamePprCtx -> SDoc -> SDoc
- GHC.Utils.Outputable: withUserStyle :: PrintUnqualified -> Depth -> SDoc -> SDoc
+ GHC.Utils.Outputable: withUserStyle :: NamePprCtx -> Depth -> SDoc -> SDoc
- GHC.Utils.Outputable: ztext :: FastZString -> SDoc
+ GHC.Utils.Outputable: ztext :: IsLine doc => FastZString -> doc
- GHC.Utils.Panic: panic :: String -> a
+ GHC.Utils.Panic: panic :: HasCallStack => String -> a
- GHC.Utils.Panic: pgmError :: String -> a
+ GHC.Utils.Panic: pgmError :: HasCallStack => String -> a
- GHC.Utils.Panic: sorry :: String -> a
+ GHC.Utils.Panic: sorry :: HasCallStack => String -> a
- GHC.Utils.Panic.Plain: panic :: String -> a
+ GHC.Utils.Panic.Plain: panic :: HasCallStack => String -> a
- GHC.Utils.Panic.Plain: pgmError :: String -> a
+ GHC.Utils.Panic.Plain: pgmError :: HasCallStack => String -> a
- GHC.Utils.Panic.Plain: sorry :: String -> a
+ GHC.Utils.Panic.Plain: sorry :: HasCallStack => String -> a
Files
- compiler/CodeGen.Platform.h +2/−1
- compiler/GHC/Builtin/Names.hs +66/−33
- compiler/GHC/Builtin/PrimOps.hs +15/−2
- compiler/GHC/Builtin/Types.hs +440/−280
- compiler/GHC/Builtin/Types.hs-boot +1/−1
- compiler/GHC/Builtin/Types/Prim.hs +407/−156
- compiler/GHC/Builtin/Types/Prim.hs-boot +0/−5
- compiler/GHC/Builtin/Uniques.hs +59/−15
- compiler/GHC/ByteCode/Types.hs +2/−1
- compiler/GHC/Cmm.hs +4/−4
- compiler/GHC/Cmm/BlockId.hs +2/−1
- compiler/GHC/Cmm/CLabel.hs +54/−39
- compiler/GHC/Cmm/CLabel.hs-boot +1/−1
- compiler/GHC/Cmm/Expr.hs +0/−1
- compiler/GHC/Cmm/MachOp.hs +0/−4
- compiler/GHC/Cmm/Node.hs +2/−4
- compiler/GHC/Cmm/Reg.hs +4/−1
- compiler/GHC/Core.hs +21/−55
- compiler/GHC/Core/Coercion.hs +345/−329
- compiler/GHC/Core/Coercion.hs-boot +4/−2
- compiler/GHC/Core/Coercion/Opt.hs +89/−71
- compiler/GHC/Core/ConLike.hs +6/−2
- compiler/GHC/Core/DataCon.hs +309/−109
- compiler/GHC/Core/DataCon.hs-boot +1/−0
- compiler/GHC/Core/FVs.hs +25/−14
- compiler/GHC/Core/FamInstEnv.hs +8/−5
- compiler/GHC/Core/InstEnv.hs +6/−3
- compiler/GHC/Core/Lint.hs +182/−87
- compiler/GHC/Core/Make.hs +277/−128
- compiler/GHC/Core/Map/Expr.hs +2/−6
- compiler/GHC/Core/Map/Type.hs +24/−60
- compiler/GHC/Core/Multiplicity.hs +97/−36
- compiler/GHC/Core/Opt/Arity.hs +25/−26
- compiler/GHC/Core/Opt/ConstantFold.hs +26/−33
- compiler/GHC/Core/Opt/Monad.hs +23/−25
- compiler/GHC/Core/Opt/OccurAnal.hs +0/−1
- compiler/GHC/Core/Opt/Simplify.hs +40/−36
- compiler/GHC/Core/Opt/Simplify/Env.hs +2/−3
- compiler/GHC/Core/Opt/Simplify/Iteration.hs +40/−15
- compiler/GHC/Core/Opt/Simplify/Monad.hs +3/−3
- compiler/GHC/Core/Opt/Simplify/Utils.hs +183/−37
- compiler/GHC/Core/PatSyn.hs +2/−2
- compiler/GHC/Core/Reduction.hs +21/−35
- compiler/GHC/Core/RoughMap.hs +143/−48
- compiler/GHC/Core/Rules.hs +123/−33
- compiler/GHC/Core/SimpleOpt.hs +1/−1
- compiler/GHC/Core/Subst.hs +8/−6
- compiler/GHC/Core/Tidy.hs +0/−2
- compiler/GHC/Core/TyCo/Compare.hs +584/−0
- compiler/GHC/Core/TyCo/FVs.hs +332/−9
- compiler/GHC/Core/TyCo/Ppr.hs +19/−22
- compiler/GHC/Core/TyCo/Ppr.hs-boot +1/−0
- compiler/GHC/Core/TyCo/Rep.hs +281/−365
- compiler/GHC/Core/TyCo/Rep.hs-boot +16/−6
- compiler/GHC/Core/TyCo/Subst.hs +21/−12
- compiler/GHC/Core/TyCo/Tidy.hs +13/−13
- compiler/GHC/Core/TyCon.hs +190/−177
- compiler/GHC/Core/TyCon.hs-boot +0/−1
- compiler/GHC/Core/Type.hs +3305/−3937
- compiler/GHC/Core/Type.hs-boot +10/−4
- compiler/GHC/Core/Unfold.hs +5/−2
- compiler/GHC/Core/Unify.hs +97/−152
- compiler/GHC/Core/UsageEnv.hs +8/−8
- compiler/GHC/Core/Utils.hs +8/−21
- compiler/GHC/Core/Utils.hs-boot +0/−6
- compiler/GHC/CoreToIface.hs +39/−35
- compiler/GHC/CoreToIface.hs-boot +1/−1
- compiler/GHC/Data/Bool.hs +1/−1
- compiler/GHC/Data/FastMutInt.hs +1/−1
- compiler/GHC/Data/FastString.hs +20/−2
- compiler/GHC/Data/Graph/Directed.hs +19/−0
- compiler/GHC/Data/Graph/UnVar.hs +7/−7
- compiler/GHC/Data/List/Infinite.hs +194/−0
- compiler/GHC/Data/List/SetOps.hs +0/−1
- compiler/GHC/Driver/Backend.hs +183/−123
- compiler/GHC/Driver/Backend/Internal.hs +1/−0
- compiler/GHC/Driver/Config/Core/Lint.hs +8/−8
- compiler/GHC/Driver/Env.hs +0/−1
- compiler/GHC/Driver/Errors.hs +5/−5
- compiler/GHC/Driver/Errors/Ppr.hs +0/−0
- compiler/GHC/Driver/Flags.hs +3/−0
- compiler/GHC/Driver/Phases.hs +12/−3
- compiler/GHC/Driver/Pipeline/Phases.hs +1/−0
- compiler/GHC/Driver/Ppr.hs +7/−7
- compiler/GHC/Driver/Session.hs +17/−2
- compiler/GHC/Hs/Decls.hs +0/−3
- compiler/GHC/Hs/Expr.hs +12/−5
- compiler/GHC/Hs/Instances.hs +1/−5
- compiler/GHC/Hs/Type.hs +6/−6
- compiler/GHC/Hs/Utils.hs +12/−53
- compiler/GHC/HsToCore/Errors/Ppr.hs +1/−1
- compiler/GHC/HsToCore/Pmc/Ppr.hs +6/−6
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs +1/−0
- compiler/GHC/Iface/Syntax.hs +64/−40
- compiler/GHC/Iface/Type.hs +226/−156
- compiler/GHC/Linker/Static/Utils.hs +14/−14
- compiler/GHC/Linker/Types.hs +2/−2
- compiler/GHC/Parser.y +6/−6
- compiler/GHC/Parser/Errors/Ppr.hs +14/−2
- compiler/GHC/Parser/Errors/Types.hs +5/−0
- compiler/GHC/Parser/Lexer.x +81/−16
- compiler/GHC/Parser/PostProcess.hs +4/−5
- compiler/GHC/Platform.hs +1/−0
- compiler/GHC/Platform/Regs.hs +6/−0
- compiler/GHC/Platform/Wasm32.hs +10/−0
- compiler/GHC/Prelude.hs +5/−55
- compiler/GHC/Prelude/Basic.hs +104/−0
- compiler/GHC/Runtime/Context.hs +5/−4
- compiler/GHC/Settings/Constants.hs +2/−2
- compiler/GHC/Stg/Syntax.hs +15/−4
- compiler/GHC/Tc/Errors/Ppr.hs +267/−65
- compiler/GHC/Tc/Errors/Types.hs +259/−3
- compiler/GHC/Tc/Solver/InertSet.hs +17/−20
- compiler/GHC/Tc/Solver/Types.hs +0/−2
- compiler/GHC/Tc/Types.hs +1/−1
- compiler/GHC/Tc/Types/Constraint.hs +36/−45
- compiler/GHC/Tc/Types/Evidence.hs +52/−127
- compiler/GHC/Tc/Types/Origin.hs +0/−3
- compiler/GHC/Tc/Utils/TcType.hs +107/−327
- compiler/GHC/Tc/Utils/TcType.hs-boot +0/−4
- compiler/GHC/Types/Basic.hs +26/−15
- compiler/GHC/Types/CostCentre.hs +33/−16
- compiler/GHC/Types/Demand.hs +61/−17
- compiler/GHC/Types/Error.hs +1/−1
- compiler/GHC/Types/Error/Codes.hs +26/−0
- compiler/GHC/Types/ForeignStubs.hs +3/−2
- compiler/GHC/Types/Id.hs +2/−3
- compiler/GHC/Types/Id/Make.hs +324/−94
- compiler/GHC/Types/Literal.hs +26/−20
- compiler/GHC/Types/Name.hs +27/−23
- compiler/GHC/Types/Name/Occurrence.hs +10/−11
- compiler/GHC/Types/Name/Occurrence.hs-boot +1/−1
- compiler/GHC/Types/Name/Ppr.hs +45/−9
- compiler/GHC/Types/RepType.hs +23/−27
- compiler/GHC/Types/TyThing.hs +11/−5
- compiler/GHC/Types/Unique.hs +3/−1
- compiler/GHC/Types/Unique/DFM.hs +6/−2
- compiler/GHC/Types/Unique/FM.hs +19/−1
- compiler/GHC/Types/Unique/Map.hs +23/−1
- compiler/GHC/Types/Var.hs +431/−98
- compiler/GHC/Types/Var.hs-boot +2/−2
- compiler/GHC/Types/Var/Env.hs +6/−2
- compiler/GHC/Unit/External.hs +1/−2
- compiler/GHC/Unit/Module/Graph.hs +5/−4
- compiler/GHC/Unit/Module/WholeCoreBindings.hs +3/−3
- compiler/GHC/Unit/Types.hs +28/−12
- compiler/GHC/Unit/Types.hs-boot +1/−1
- compiler/GHC/Utils/Binary.hs +143/−12
- compiler/GHC/Utils/BufHandle.hs +22/−1
- compiler/GHC/Utils/Constants.hs +1/−1
- compiler/GHC/Utils/Error.hs +17/−17
- compiler/GHC/Utils/Exception.hs +1/−1
- compiler/GHC/Utils/Fingerprint.hs +1/−1
- compiler/GHC/Utils/GlobalVars.hs +1/−1
- compiler/GHC/Utils/IO/Unsafe.hs +1/−1
- compiler/GHC/Utils/Json.hs +1/−1
- compiler/GHC/Utils/Lexeme.hs +9/−9
- compiler/GHC/Utils/Logger.hs +8/−7
- compiler/GHC/Utils/Misc.hs +6/−29
- compiler/GHC/Utils/Monad.hs +15/−0
- compiler/GHC/Utils/Outputable.hs +507/−145
- compiler/GHC/Utils/Panic.hs +8/−1
- compiler/GHC/Utils/Panic/Plain.hs +4/−3
- compiler/GHC/Utils/Ppr.hs +43/−10
- compiler/GHC/Utils/Ppr/Colour.hs +1/−1
- compiler/GHC/Utils/Trace.hs +12/−1
- compiler/Language/Haskell/Syntax/Decls.hs +0/−3
- compiler/Language/Haskell/Syntax/Expr.hs +0/−2
- compiler/Language/Haskell/Syntax/Type.hs +2/−0
- compiler/MachRegs.h +35/−0
- compiler/ghc-llvm-version.h +1/−1
- compiler/ghc.cabal +883/−0
- ghc-lib-parser.cabal +12/−1
- ghc-lib/stage0/compiler/build/GHC/Settings/Config.hs +2/−2
- ghc-lib/stage0/lib/settings +1/−1
- ghc-lib/stage0/libraries/ghc-boot/build/GHC/Version.hs +4/−4
- ghc-lib/stage0/rts/build/include/ghcautoconf.h +14/−1
- ghc/ghc-bin.cabal +98/−0
- libraries/ghc-boot-th/GHC/ForeignSrcLang/Type.hs +1/−0
- libraries/ghc-boot-th/ghc-boot-th.cabal +39/−0
- libraries/ghc-boot/GHC/BaseDir.hs +2/−1
- libraries/ghc-boot/GHC/Data/ShortText.hs +9/−2
- libraries/ghc-boot/GHC/Platform/ArchOS.hs +4/−0
- libraries/ghc-boot/GHC/Utils/Encoding.hs +4/−2
- libraries/ghc-boot/ghc-boot.cabal +83/−0
- libraries/ghc-heap/ghc-heap.cabal +50/−0
- libraries/ghci/GHCi/FFI.hsc +37/−4
- libraries/ghci/GHCi/Message.hs +1/−1
- libraries/ghci/ghci.cabal +86/−0
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs +4/−2
- libraries/template-haskell/template-haskell.cabal +73/−0
compiler/CodeGen.Platform.h view
@@ -664,7 +664,8 @@ #if defined(MACHREGS_i386) || defined(MACHREGS_x86_64) \ || defined(MACHREGS_powerpc) \ || defined(MACHREGS_arm) || defined(MACHREGS_aarch64) \- || defined(MACHREGS_s390x) || defined(MACHREGS_riscv64)+ || defined(MACHREGS_s390x) || defined(MACHREGS_riscv64) \+ || defined(MACHREGS_wasm32) # if defined(REG_Base) globalRegMaybe BaseReg = Just (RealRegSingle REG_Base) # endif
compiler/GHC/Builtin/Names.hs view
@@ -119,7 +119,6 @@ -} {-# LANGUAGE CPP #-}-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module GHC.Builtin.Names ( Unique, Uniquable(..), hasKey, -- Re-exported for convenience@@ -143,6 +142,8 @@ import GHC.Types.Name import GHC.Types.SrcLoc import GHC.Data.FastString+import GHC.Data.List.Infinite (Infinite (..))+import qualified GHC.Data.List.Infinite as Inf import Language.Haskell.Syntax.Module.Name @@ -154,10 +155,14 @@ ************************************************************************ -} -allNameStrings :: [String]+allNameStrings :: Infinite String -- Infinite list of a,b,c...z, aa, ab, ac, ... etc-allNameStrings = [ c:cs | cs <- "" : allNameStrings, c <- ['a'..'z'] ]+allNameStrings = Inf.allListsOf ['a'..'z'] +allNameStringList :: [String]+-- Infinite list of a,b,c...z, aa, ab, ac, ... etc+allNameStringList = Inf.toList allNameStrings+ {- ************************************************************************ * *@@ -258,6 +263,7 @@ starKindRepName, starArrStarKindRepName, starArrStarArrStarKindRepName,+ constraintKindRepName, -- WithDict withDictClassName,@@ -333,6 +339,9 @@ fromListNName, toListName, + -- Non-empty lists+ nonEmptyTyConName,+ -- Overloaded record dot, record update getFieldName, setFieldName, @@ -341,7 +350,7 @@ zipName, foldrName, buildName, augmentName, appendName, -- FFI primitive types that are not wired-in.- stablePtrTyConName, ptrTyConName, funPtrTyConName,+ stablePtrTyConName, ptrTyConName, funPtrTyConName, constPtrConName, int8TyConName, int16TyConName, int32TyConName, int64TyConName, word8TyConName, word16TyConName, word32TyConName, word64TyConName, @@ -538,7 +547,7 @@ gHC_GHCI, gHC_GHCI_HELPERS, gHC_CSTRING, gHC_SHOW, gHC_READ, gHC_NUM, gHC_MAYBE, gHC_NUM_INTEGER, gHC_NUM_NATURAL, gHC_NUM_BIGNAT,- gHC_LIST, gHC_TUPLE, gHC_TUPLE_PRIM, dATA_EITHER, dATA_VOID, dATA_LIST, dATA_STRING,+ gHC_LIST, gHC_TUPLE, gHC_TUPLE_PRIM, dATA_EITHER, dATA_LIST, dATA_STRING, dATA_FOLDABLE, dATA_TRAVERSABLE, gHC_CONC, gHC_IO, gHC_IO_Exception, gHC_ST, gHC_IX, gHC_STABLE, gHC_PTR, gHC_ERR, gHC_REAL,@@ -548,7 +557,7 @@ aRROW, gHC_DESUGAR, rANDOM, gHC_EXTS, gHC_IS_LIST, cONTROL_EXCEPTION_BASE, gHC_TYPEERROR, gHC_TYPELITS, gHC_TYPELITS_INTERNAL, gHC_TYPENATS, gHC_TYPENATS_INTERNAL,- dATA_COERCE, dEBUG_TRACE, uNSAFE_COERCE :: Module+ dATA_COERCE, dEBUG_TRACE, uNSAFE_COERCE, fOREIGN_C_TYPES :: Module gHC_PRIM = mkPrimModule (fsLit "GHC.Prim") -- Primitive types and values gHC_PRIM_PANIC = mkPrimModule (fsLit "GHC.Prim.Panic")@@ -574,7 +583,6 @@ gHC_TUPLE = mkPrimModule (fsLit "GHC.Tuple") gHC_TUPLE_PRIM = mkPrimModule (fsLit "GHC.Tuple.Prim") dATA_EITHER = mkBaseModule (fsLit "Data.Either")-dATA_VOID = mkBaseModule (fsLit "Data.Void") dATA_LIST = mkBaseModule (fsLit "Data.List") dATA_STRING = mkBaseModule (fsLit "Data.String") dATA_FOLDABLE = mkBaseModule (fsLit "Data.Foldable")@@ -618,6 +626,7 @@ dATA_COERCE = mkBaseModule (fsLit "Data.Coerce") dEBUG_TRACE = mkBaseModule (fsLit "Debug.Trace") uNSAFE_COERCE = mkBaseModule (fsLit "Unsafe.Coerce")+fOREIGN_C_TYPES = mkBaseModule (fsLit "Foreign.C.Types") gHC_SRCLOC :: Module gHC_SRCLOC = mkBaseModule (fsLit "GHC.SrcLoc")@@ -954,7 +963,7 @@ rightDataConName = dcQual dATA_EITHER (fsLit "Right") rightDataConKey voidTyConName :: Name-voidTyConName = tcQual dATA_VOID (fsLit "Void") voidTyConKey+voidTyConName = tcQual gHC_BASE (fsLit "Void") voidTyConKey -- Generics (types) v1TyConName, u1TyConName, par1TyConName, rec1TyConName,@@ -1401,15 +1410,20 @@ trGhcPrimModuleName = varQual gHC_TYPES (fsLit "tr$ModuleGHCPrim") trGhcPrimModuleKey -- Typeable KindReps for some common cases-starKindRepName, starArrStarKindRepName, starArrStarArrStarKindRepName :: Name-starKindRepName = varQual gHC_TYPES (fsLit "krep$*") starKindRepKey-starArrStarKindRepName = varQual gHC_TYPES (fsLit "krep$*Arr*") starArrStarKindRepKey-starArrStarArrStarKindRepName = varQual gHC_TYPES (fsLit "krep$*->*->*") starArrStarArrStarKindRepKey+starKindRepName, starArrStarKindRepName,+ starArrStarArrStarKindRepName, constraintKindRepName :: Name+starKindRepName = varQual gHC_TYPES (fsLit "krep$*") starKindRepKey+starArrStarKindRepName = varQual gHC_TYPES (fsLit "krep$*Arr*") starArrStarKindRepKey+starArrStarArrStarKindRepName = varQual gHC_TYPES (fsLit "krep$*->*->*") starArrStarArrStarKindRepKey+constraintKindRepName = varQual gHC_TYPES (fsLit "krep$Constraint") constraintKindRepKey -- WithDict withDictClassName :: Name-withDictClassName = clsQual gHC_MAGIC_DICT (fsLit "WithDict") withDictClassKey+withDictClassName = clsQual gHC_MAGIC_DICT (fsLit "WithDict") withDictClassKey +nonEmptyTyConName :: Name+nonEmptyTyConName = tcQual gHC_BASE (fsLit "NonEmpty") nonEmptyTyConKey+ -- Custom type errors errorMessageTypeErrorFamName , typeErrorTextDataConName@@ -1651,6 +1665,10 @@ fingerprintDataConName = dcQual gHC_FINGERPRINT_TYPE (fsLit "Fingerprint") fingerprintDataConKey +constPtrConName :: Name+constPtrConName =+ tcQual fOREIGN_C_TYPES (fsLit "ConstPtr") constPtrTyConKey+ {- ************************************************************************ * *@@ -1783,7 +1801,7 @@ addrPrimTyConKey, arrayPrimTyConKey, boolTyConKey, byteArrayPrimTyConKey, charPrimTyConKey, charTyConKey, doublePrimTyConKey,- doubleTyConKey, floatPrimTyConKey, floatTyConKey, funTyConKey,+ doubleTyConKey, floatPrimTyConKey, floatTyConKey, fUNTyConKey, intPrimTyConKey, intTyConKey, int8TyConKey, int16TyConKey, int8PrimTyConKey, int16PrimTyConKey, int32PrimTyConKey, int32TyConKey, int64PrimTyConKey, int64TyConKey,@@ -1794,7 +1812,8 @@ ratioTyConKey, rationalTyConKey, realWorldTyConKey, stablePtrPrimTyConKey, stablePtrTyConKey, eqTyConKey, heqTyConKey, ioPortPrimTyConKey, smallArrayPrimTyConKey, smallMutableArrayPrimTyConKey,- stringTyConKey :: Unique+ stringTyConKey,+ ccArrowTyConKey, ctArrowTyConKey, tcArrowTyConKey :: Unique addrPrimTyConKey = mkPreludeTyConUnique 1 arrayPrimTyConKey = mkPreludeTyConUnique 3 boolTyConKey = mkPreludeTyConUnique 4@@ -1806,7 +1825,7 @@ doubleTyConKey = mkPreludeTyConUnique 10 floatPrimTyConKey = mkPreludeTyConUnique 11 floatTyConKey = mkPreludeTyConUnique 12-funTyConKey = mkPreludeTyConUnique 13+fUNTyConKey = mkPreludeTyConUnique 13 intPrimTyConKey = mkPreludeTyConUnique 14 intTyConKey = mkPreludeTyConUnique 15 int8PrimTyConKey = mkPreludeTyConUnique 16@@ -1837,6 +1856,10 @@ eqTyConKey = mkPreludeTyConUnique 40 heqTyConKey = mkPreludeTyConUnique 41 +ctArrowTyConKey = mkPreludeTyConUnique 42+ccArrowTyConKey = mkPreludeTyConUnique 43+tcArrowTyConKey = mkPreludeTyConUnique 44+ statePrimTyConKey, stableNamePrimTyConKey, stableNameTyConKey, mutVarPrimTyConKey, ioTyConKey, wordPrimTyConKey, wordTyConKey, word8PrimTyConKey, word8TyConKey,@@ -1847,7 +1870,7 @@ funPtrTyConKey, tVarPrimTyConKey, eqPrimTyConKey, eqReprPrimTyConKey, eqPhantPrimTyConKey, compactPrimTyConKey, stackSnapshotPrimTyConKey,- promptTagPrimTyConKey :: Unique+ promptTagPrimTyConKey, constPtrTyConKey :: Unique statePrimTyConKey = mkPreludeTyConUnique 50 stableNamePrimTyConKey = mkPreludeTyConUnique 51 stableNameTyConKey = mkPreludeTyConUnique 52@@ -1887,16 +1910,21 @@ nonEmptyTyConKey :: Unique nonEmptyTyConKey = mkPreludeTyConUnique 86 +dictTyConKey :: Unique+dictTyConKey = mkPreludeTyConUnique 87+ -- Kind constructors liftedTypeKindTyConKey, unliftedTypeKindTyConKey,- tYPETyConKey, liftedRepTyConKey, unliftedRepTyConKey,+ tYPETyConKey, cONSTRAINTTyConKey,+ liftedRepTyConKey, unliftedRepTyConKey, constraintKindTyConKey, levityTyConKey, runtimeRepTyConKey, vecCountTyConKey, vecElemTyConKey, zeroBitRepTyConKey, zeroBitTypeTyConKey :: Unique liftedTypeKindTyConKey = mkPreludeTyConUnique 88 unliftedTypeKindTyConKey = mkPreludeTyConUnique 89-tYPETyConKey = mkPreludeTyConUnique 90-constraintKindTyConKey = mkPreludeTyConUnique 92+tYPETyConKey = mkPreludeTyConUnique 91+cONSTRAINTTyConKey = mkPreludeTyConUnique 92+constraintKindTyConKey = mkPreludeTyConUnique 93 levityTyConKey = mkPreludeTyConUnique 94 runtimeRepTyConKey = mkPreludeTyConUnique 95 vecCountTyConKey = mkPreludeTyConUnique 96@@ -1918,7 +1946,6 @@ kindRepTyConKey = mkPreludeTyConUnique 107 typeLitSortTyConKey = mkPreludeTyConUnique 108 - -- Generics (Unique keys) v1TyConKey, u1TyConKey, par1TyConKey, rec1TyConKey, k1TyConKey, m1TyConKey, sumTyConKey, prodTyConKey,@@ -2054,6 +2081,7 @@ typeUnconsSymbolTyFamNameKey = mkPreludeTyConUnique 414 typeCharToNatTyFamNameKey = mkPreludeTyConUnique 415 typeNatToCharTyFamNameKey = mkPreludeTyConUnique 416+constPtrTyConKey = mkPreludeTyConUnique 417 {- ************************************************************************@@ -2067,8 +2095,7 @@ floatDataConKey, intDataConKey, nilDataConKey, ratioDataConKey, stableNameDataConKey, trueDataConKey, wordDataConKey, word8DataConKey, ioDataConKey, heqDataConKey,- coercibleDataConKey, eqDataConKey, nothingDataConKey, justDataConKey,- nonEmptyDataConKey :: Unique+ eqDataConKey, nothingDataConKey, justDataConKey :: Unique charDataConKey = mkPreludeDataConUnique 1 consDataConKey = mkPreludeDataConUnique 2@@ -2087,7 +2114,6 @@ wordDataConKey = mkPreludeDataConUnique 15 ioDataConKey = mkPreludeDataConUnique 16 heqDataConKey = mkPreludeDataConUnique 18-nonEmptyDataConKey = mkPreludeDataConUnique 19 -- Generic data constructors crossDataConKey, inlDataConKey, inrDataConKey, genUnitDataConKey :: Unique@@ -2105,7 +2131,10 @@ ordEQDataConKey = mkPreludeDataConUnique 28 ordGTDataConKey = mkPreludeDataConUnique 29 +mkDictDataConKey :: Unique+mkDictDataConKey = mkPreludeDataConUnique 30 +coercibleDataConKey :: Unique coercibleDataConKey = mkPreludeDataConUnique 32 staticPtrDataConKey :: Unique@@ -2249,7 +2278,7 @@ ************************************************************************ -} -wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey,+wildCardKey, absentErrorIdKey, absentConstraintErrorIdKey, augmentIdKey, appendIdKey, buildIdKey, foldrIdKey, recSelErrorIdKey, seqIdKey, eqStringIdKey, noMethodBindingErrorIdKey, nonExhaustiveGuardsErrorIdKey,@@ -2266,6 +2295,7 @@ augmentIdKey = mkPreludeMiscIdUnique 2 appendIdKey = mkPreludeMiscIdUnique 3 buildIdKey = mkPreludeMiscIdUnique 4+absentConstraintErrorIdKey = mkPreludeMiscIdUnique 5 foldrIdKey = mkPreludeMiscIdUnique 6 recSelErrorIdKey = mkPreludeMiscIdUnique 7 seqIdKey = mkPreludeMiscIdUnique 8@@ -2330,7 +2360,7 @@ nospecIdKey :: Unique nospecIdKey = mkPreludeMiscIdUnique 109 -inlineIdKey, noinlineIdKey :: Unique+inlineIdKey, noinlineIdKey, noinlineConstraintIdKey :: Unique inlineIdKey = mkPreludeMiscIdUnique 120 -- see below @@ -2338,8 +2368,9 @@ mapIdKey = mkPreludeMiscIdUnique 121 dollarIdKey = mkPreludeMiscIdUnique 123 coercionTokenIdKey = mkPreludeMiscIdUnique 124-noinlineIdKey = mkPreludeMiscIdUnique 125-considerAccessibleIdKey = mkPreludeMiscIdUnique 126+considerAccessibleIdKey = mkPreludeMiscIdUnique 125+noinlineIdKey = mkPreludeMiscIdUnique 126+noinlineConstraintIdKey = mkPreludeMiscIdUnique 127 integerToFloatIdKey, integerToDoubleIdKey, naturalToFloatIdKey, naturalToDoubleIdKey :: Unique integerToFloatIdKey = mkPreludeMiscIdUnique 128@@ -2479,14 +2510,15 @@ trLiftedRepKey = mkPreludeMiscIdUnique 516 -- KindReps for common cases-starKindRepKey, starArrStarKindRepKey, starArrStarArrStarKindRepKey :: Unique-starKindRepKey = mkPreludeMiscIdUnique 520-starArrStarKindRepKey = mkPreludeMiscIdUnique 521+starKindRepKey, starArrStarKindRepKey, starArrStarArrStarKindRepKey, constraintKindRepKey :: Unique+starKindRepKey = mkPreludeMiscIdUnique 520+starArrStarKindRepKey = mkPreludeMiscIdUnique 521 starArrStarArrStarKindRepKey = mkPreludeMiscIdUnique 522+constraintKindRepKey = mkPreludeMiscIdUnique 523 -- Dynamic toDynIdKey :: Unique-toDynIdKey = mkPreludeMiscIdUnique 523+toDynIdKey = mkPreludeMiscIdUnique 530 bitIntegerIdKey :: Unique@@ -2780,9 +2812,10 @@ [ liftedTypeKindTyConKey, unliftedTypeKindTyConKey , liftedDataConKey, unliftedDataConKey , tYPETyConKey+ , cONSTRAINTTyConKey , runtimeRepTyConKey, boxedRepDataConKey , eqTyConKey , listTyConKey , oneDataConKey , manyDataConKey- , funTyConKey ]+ , fUNTyConKey, unrestrictedFunTyConKey ]
compiler/GHC/Builtin/PrimOps.hs view
@@ -5,19 +5,21 @@ -} {-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-} module GHC.Builtin.PrimOps ( PrimOp(..), PrimOpVecCat(..), allThePrimOps, primOpType, primOpSig, primOpResultType, primOpTag, maxPrimOpTag, primOpOcc, primOpWrapperId,+ pprPrimOp, tagToEnumKey, primOpOutOfLine, primOpCodeSize, primOpOkForSpeculation, primOpOkForSideEffects, primOpIsCheap, primOpFixity, primOpDocs,- primOpIsDiv,+ primOpIsDiv, primOpIsReallyInline, getPrimOpResultInfo, isComparisonPrimOp, PrimOpResultInfo(..), @@ -788,8 +790,10 @@ -- Output stuff: -pprPrimOp :: PrimOp -> SDoc+pprPrimOp :: IsLine doc => PrimOp -> doc pprPrimOp other_op = pprOccName (primOpOcc other_op)+{-# SPECIALIZE pprPrimOp :: PrimOp -> SDoc #-}+{-# SPECIALIZE pprPrimOp :: PrimOp -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable {- ************************************************************************@@ -804,3 +808,12 @@ instance Outputable PrimCall where ppr (PrimCall lbl pkgId) = text "__primcall" <+> ppr pkgId <+> ppr lbl++-- | Indicate if a primop is really inline: that is, it isn't out-of-line and it+-- isn't SeqOp/DataToTagOp which are two primops that evaluate their argument+-- hence induce thread/stack/heap changes.+primOpIsReallyInline :: PrimOp -> Bool+primOpIsReallyInline = \case+ SeqOp -> False+ DataToTagOp -> False+ p -> not (primOpOutOfLine p)
compiler/GHC/Builtin/Types.hs view
@@ -34,7 +34,7 @@ promotedLTDataCon, promotedEQDataCon, promotedGTDataCon, -- * Boxing primitive types- boxingDataCon_maybe,+ boxingDataCon, BoxingInfo(..), -- * Char charTyCon, charDataCon, charTyCon_RDR,@@ -63,10 +63,6 @@ promotedNilDataCon, promotedConsDataCon, mkListTy, mkPromotedListTy, - -- * NonEmpty- nonEmptyTyCon, nonEmptyTyConName,- nonEmptyDataCon, nonEmptyDataConName,- -- * Maybe maybeTyCon, maybeTyConName, nothingDataCon, nothingDataConName, promotedNothingDataCon,@@ -83,7 +79,7 @@ unboxedUnitTy, unboxedUnitTyCon, unboxedUnitDataCon, unboxedTupleKind, unboxedSumKind,- filterCTuple,+ filterCTuple, mkConstraintTupleTy, -- ** Constraint tuples cTupleTyCon, cTupleTyConName, cTupleTyConNames, isCTupleTyConName,@@ -105,6 +101,8 @@ isLiftedTypeKindTyConName, typeToTypeKind, liftedRepTyCon, unliftedRepTyCon,+ tYPETyCon, tYPETyConName, tYPEKind,+ cONSTRAINTTyCon, cONSTRAINTTyConName, cONSTRAINTKind, constraintKind, liftedTypeKind, unliftedTypeKind, zeroBitTypeKind, constraintKindTyCon, liftedTypeKindTyCon, unliftedTypeKindTyCon, constraintKindTyConName, liftedTypeKindTyConName, unliftedTypeKindTyConName,@@ -116,15 +114,17 @@ coercibleTyCon, coercibleTyConName, coercibleDataCon, coercibleClass, -- * RuntimeRep and friends- runtimeRepTyCon, levityTyCon, vecCountTyCon, vecElemTyCon,+ runtimeRepTyCon, vecCountTyCon, vecElemTyCon, boxedRepDataConTyCon,- runtimeRepTy, levityTy, liftedRepTy, unliftedRepTy, zeroBitRepTy,+ runtimeRepTy, liftedRepTy, unliftedRepTy, zeroBitRepTy, vecRepDataConTyCon, tupleRepDataConTyCon, sumRepDataConTyCon, + -- * Levity+ levityTyCon, levityTy, liftedDataConTyCon, unliftedDataConTyCon,- liftedDataConTy, unliftedDataConTy,+ liftedDataConTy, unliftedDataConTy, intRepDataConTy, int8RepDataConTy, int16RepDataConTy, int32RepDataConTy, int64RepDataConTy,@@ -170,27 +170,32 @@ import GHC.Builtin.Uniques -- others:+import GHC.Core( Expr(Type), mkConApp ) import GHC.Core.Coercion.Axiom-import GHC.Types.Id-import GHC.Types.TyThing-import GHC.Types.SourceText-import GHC.Types.Var (VarBndr (Bndr))-import GHC.Settings.Constants ( mAX_TUPLE_SIZE, mAX_CTUPLE_SIZE, mAX_SUM_SIZE )-import GHC.Unit.Module ( Module ) import GHC.Core.Type-import qualified GHC.Core.TyCo.Rep as TyCoRep (Type(TyConApp))-import GHC.Core.TyCo.Rep (RuntimeRepType)-import GHC.Types.RepType+import GHC.Types.Id import GHC.Core.DataCon import GHC.Core.ConLike 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 GHC.Types.TyThing+import GHC.Types.SourceText+import GHC.Types.Var ( VarBndr (Bndr) )+import GHC.Types.RepType import GHC.Types.Name.Reader import GHC.Types.Name as Name-import GHC.Types.Name.Env ( NameEnv, mkNameEnv, lookupNameEnv, lookupNameEnv_NF )+import GHC.Types.Name.Env ( lookupNameEnv_NF ) import GHC.Types.Basic import GHC.Types.ForeignCall import GHC.Types.Unique.Set+++import GHC.Settings.Constants ( mAX_TUPLE_SIZE, mAX_CTUPLE_SIZE, mAX_SUM_SIZE )+import GHC.Unit.Module ( Module )+ import Data.Array import GHC.Data.FastString import GHC.Data.BooleanFormula ( mkAnd )@@ -202,6 +207,7 @@ import qualified Data.ByteString.Char8 as BS +import Data.Foldable import Data.List ( elemIndex, intersperse ) alpha_tyvar :: [TyVar]@@ -274,7 +280,8 @@ -- See also Note [Known-key names] wiredInTyCons :: [TyCon] -wiredInTyCons = [ -- Units are not treated like other tuples, because they+wiredInTyCons = map (dataConTyCon . snd) boxingDataCons+ ++ [ -- Units are not treated like other tuples, because they -- are defined in GHC.Base, and there's only a few of them. We -- put them in wiredInTyCons so that they will pre-populate -- the name cache, so the parser in isBuiltInOcc_maybe doesn't@@ -318,7 +325,6 @@ , unliftedRepTyCon , zeroBitRepTyCon , zeroBitTypeTyCon- , nonEmptyTyCon ] mkWiredInTyConName :: BuiltInSyntax -> Module -> FastString -> Unique -> TyCon -> Name@@ -377,10 +383,6 @@ nilDataConName = mkWiredInDataConName BuiltInSyntax gHC_TYPES (fsLit "[]") nilDataConKey nilDataCon consDataConName = mkWiredInDataConName BuiltInSyntax gHC_TYPES (fsLit ":") consDataConKey consDataCon -nonEmptyTyConName, nonEmptyDataConName :: Name-nonEmptyTyConName = mkWiredInTyConName UserSyntax gHC_BASE (fsLit "NonEmpty") nonEmptyTyConKey nonEmptyTyCon-nonEmptyDataConName = mkWiredInDataConName UserSyntax gHC_BASE (fsLit ":|") nonEmptyDataConKey nonEmptyDataCon- maybeTyConName, nothingDataConName, justDataConName :: Name maybeTyConName = mkWiredInTyConName UserSyntax gHC_MAYBE (fsLit "Maybe") maybeTyConKey maybeTyCon@@ -509,81 +511,7 @@ typeSymbolKindConName :: Name typeSymbolKindConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Symbol") typeSymbolKindConNameKey typeSymbolKindCon -constraintKindTyConName :: Name-constraintKindTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Constraint") constraintKindTyConKey constraintKindTyCon -liftedTypeKindTyConName, unliftedTypeKindTyConName, zeroBitTypeTyConName :: Name-liftedTypeKindTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Type") liftedTypeKindTyConKey liftedTypeKindTyCon-unliftedTypeKindTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "UnliftedType") unliftedTypeKindTyConKey unliftedTypeKindTyCon-zeroBitTypeTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "ZeroBitType") zeroBitTypeTyConKey zeroBitTypeTyCon--liftedRepTyConName, unliftedRepTyConName, zeroBitRepTyConName :: Name-liftedRepTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "LiftedRep") liftedRepTyConKey liftedRepTyCon-unliftedRepTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "UnliftedRep") unliftedRepTyConKey unliftedRepTyCon-zeroBitRepTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "ZeroBitRep") zeroBitRepTyConKey zeroBitRepTyCon--multiplicityTyConName :: Name-multiplicityTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Multiplicity")- multiplicityTyConKey multiplicityTyCon--oneDataConName, manyDataConName :: Name-oneDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "One") oneDataConKey oneDataCon-manyDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "Many") manyDataConKey manyDataCon--runtimeRepTyConName, vecRepDataConName, tupleRepDataConName, sumRepDataConName, boxedRepDataConName :: Name-runtimeRepTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "RuntimeRep") runtimeRepTyConKey runtimeRepTyCon-vecRepDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "VecRep") vecRepDataConKey vecRepDataCon-tupleRepDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "TupleRep") tupleRepDataConKey tupleRepDataCon-sumRepDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "SumRep") sumRepDataConKey sumRepDataCon-boxedRepDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "BoxedRep") boxedRepDataConKey boxedRepDataCon--levityTyConName, liftedDataConName, unliftedDataConName :: Name-levityTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Levity") levityTyConKey levityTyCon-liftedDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "Lifted") liftedDataConKey liftedDataCon-unliftedDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "Unlifted") unliftedDataConKey unliftedDataCon----- See Note [Wiring in RuntimeRep]-runtimeRepSimpleDataConNames :: [Name]-runtimeRepSimpleDataConNames- = zipWith3Lazy mk_special_dc_name- [ fsLit "IntRep"- , fsLit "Int8Rep", fsLit "Int16Rep", fsLit "Int32Rep", fsLit "Int64Rep"- , fsLit "WordRep"- , fsLit "Word8Rep", fsLit "Word16Rep", fsLit "Word32Rep", fsLit "Word64Rep"- , fsLit "AddrRep"- , fsLit "FloatRep", fsLit "DoubleRep"- ]- runtimeRepSimpleDataConKeys- runtimeRepSimpleDataCons--vecCountTyConName :: Name-vecCountTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "VecCount") vecCountTyConKey vecCountTyCon---- See Note [Wiring in RuntimeRep]-vecCountDataConNames :: [Name]-vecCountDataConNames = zipWith3Lazy mk_special_dc_name- [ fsLit "Vec2", fsLit "Vec4", fsLit "Vec8"- , fsLit "Vec16", fsLit "Vec32", fsLit "Vec64" ]- vecCountDataConKeys- vecCountDataCons--vecElemTyConName :: Name-vecElemTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "VecElem") vecElemTyConKey vecElemTyCon---- See Note [Wiring in RuntimeRep]-vecElemDataConNames :: [Name]-vecElemDataConNames = zipWith3Lazy mk_special_dc_name- [ fsLit "Int8ElemRep", fsLit "Int16ElemRep", fsLit "Int32ElemRep"- , fsLit "Int64ElemRep", fsLit "Word8ElemRep", fsLit "Word16ElemRep"- , fsLit "Word32ElemRep", fsLit "Word64ElemRep"- , fsLit "FloatElemRep", fsLit "DoubleElemRep" ]- vecElemDataConKeys- vecElemDataCons--mk_special_dc_name :: FastString -> Unique -> DataCon -> Name-mk_special_dc_name fs u dc = mkWiredInDataConName UserSyntax gHC_TYPES fs u dc- boolTyCon_RDR, false_RDR, true_RDR, intTyCon_RDR, charTyCon_RDR, stringTyCon_RDR, intDataCon_RDR, listTyCon_RDR, consDataCon_RDR :: RdrName boolTyCon_RDR = nameRdrName boolTyConName@@ -609,7 +537,7 @@ pcTyCon :: Name -> Maybe CType -> [TyVar] -> [DataCon] -> TyCon pcTyCon name cType tyvars cons = mkAlgTyCon name- (mkAnonTyConBinders VisArg tyvars)+ (mkAnonTyConBinders tyvars) liftedTypeKind (map (const Representational) tyvars) cType@@ -619,24 +547,41 @@ False -- Not in GADT syntax pcDataCon :: Name -> [TyVar] -> [Type] -> TyCon -> DataCon-pcDataCon n univs tys = pcDataConW n univs (map linear tys)--pcDataConW :: Name -> [TyVar] -> [Scaled Type] -> TyCon -> DataCon-pcDataConW n univs tys = pcDataConWithFixity False n univs+pcDataCon n univs tys+ = pcDataConWithFixity False n univs [] -- no ex_tvs univs -- the univs are precisely the user-written tyvars- tys+ [] -- No theta+ (map linear tys) +pcDataConConstraint :: Name -> [TyVar] -> ThetaType -> TyCon -> DataCon+-- Used for data constructors whose arguments are all constraints.+-- Notably constraint tuples, Eq# etc.+pcDataConConstraint n univs theta+ = pcDataConWithFixity False n univs+ [] -- No ex_tvs+ univs -- The univs are precisely the user-written tyvars+ theta -- All constraint arguments+ [] -- No value arguments++-- Used for RuntimeRep and friends; things with PromDataConInfo+pcSpecialDataCon :: Name -> [Type] -> TyCon -> PromDataConInfo -> DataCon+pcSpecialDataCon dc_name arg_tys tycon rri+ = pcDataConWithFixity' False dc_name+ (dataConWorkerUnique (nameUnique dc_name)) rri+ [] [] [] [] (map linear arg_tys) tycon+ pcDataConWithFixity :: Bool -- ^ declared infix? -> Name -- ^ datacon name -> [TyVar] -- ^ univ tyvars -> [TyCoVar] -- ^ ex tycovars -> [TyCoVar] -- ^ user-written tycovars+ -> ThetaType -> [Scaled Type] -- ^ args -> TyCon -> DataCon-pcDataConWithFixity infx n = pcDataConWithFixity' infx n (dataConWorkerUnique (nameUnique n))- NoRRI+pcDataConWithFixity infx n = pcDataConWithFixity' infx n+ (dataConWorkerUnique (nameUnique n)) NoPromInfo -- The Name's unique is the first of two free uniques; -- the first is used for the datacon itself, -- the second is used for the "worker name"@@ -644,9 +589,9 @@ -- To support this the mkPreludeDataConUnique function "allocates" -- one DataCon unique per pair of Ints. -pcDataConWithFixity' :: Bool -> Name -> Unique -> RuntimeRepInfo+pcDataConWithFixity' :: Bool -> Name -> Unique -> PromDataConInfo -> [TyVar] -> [TyCoVar] -> [TyCoVar]- -> [Scaled Type] -> TyCon -> DataCon+ -> ThetaType -> [Scaled Type] -> TyCon -> DataCon -- The Name should be in the DataName name space; it's the name -- of the DataCon itself. --@@ -658,7 +603,7 @@ -- to regret doing so (we do). pcDataConWithFixity' declared_infix dc_name wrk_key rri- tyvars ex_tyvars user_tyvars arg_tys tycon+ tyvars ex_tyvars user_tyvars theta arg_tys tycon = data_con where tag_map = mkTyConTagMap tycon@@ -674,7 +619,7 @@ tyvars ex_tyvars (mkTyVarBinders SpecifiedSpec user_tyvars) [] -- No equality spec- [] -- No theta+ theta arg_tys (mkTyConApp tycon (mkTyVarTys tyvars)) rri tycon@@ -700,16 +645,11 @@ dc_occ = nameOccName dc_name wrk_occ = mkDataConWorkerOcc dc_occ --- used for RuntimeRep and friends-pcSpecialDataCon :: Name -> [Type] -> TyCon -> RuntimeRepInfo -> DataCon-pcSpecialDataCon dc_name arg_tys tycon rri- = pcDataConWithFixity' False dc_name (dataConWorkerUnique (nameUnique dc_name)) rri- [] [] [] (map linear arg_tys) tycon {- ************************************************************************ * *- Kinds+ Symbol * * ************************************************************************ -}@@ -721,14 +661,7 @@ typeSymbolKind :: Kind typeSymbolKind = mkTyConTy typeSymbolKindCon -constraintKindTyCon :: TyCon--- 'TyCon.isConstraintKindCon' assumes that this is an AlgTyCon!-constraintKindTyCon = pcTyCon constraintKindTyConName Nothing [] [] -typeToTypeKind, constraintKind :: Kind-typeToTypeKind = liftedTypeKind `mkVisFunTyMany` liftedTypeKind-constraintKind = mkTyConTy constraintKindTyCon- {- ************************************************************************ * *@@ -868,7 +801,7 @@ ":" -> Just consDataConName -- function tycon- "FUN" -> Just funTyConName+ "FUN" -> Just fUNTyConName "->" -> Just unrestrictedFunTyConName -- boxed tuple data/tycon@@ -1162,7 +1095,7 @@ (mkPrelTyConRepName tc_name) klass = mk_ctuple_class tycon sc_theta sc_sel_ids- tuple_con = pcDataConW dc_name tvs (map unrestricted sc_theta) tycon+ tuple_con = pcDataConConstraint dc_name tvs sc_theta tycon binders = mkTemplateAnonTyConBinders (replicate arity constraintKind) roles = replicate arity Nominal@@ -1220,7 +1153,6 @@ unboxedUnitDataCon :: DataCon unboxedUnitDataCon = tupleDataCon Unboxed 0 - {- ********************************************************************* * * Unboxed sums@@ -1349,7 +1281,7 @@ rhs klass (mkPrelTyConRepName eqTyConName) klass = mk_class tycon sc_pred sc_sel_id- datacon = pcDataConW eqDataConName tvs [unrestricted sc_pred] tycon+ datacon = pcDataConConstraint eqDataConName tvs [sc_pred] tycon -- Kind: forall k. k -> k -> Constraint binders = mkTemplateTyConBinders [liftedTypeKind] (\[k] -> [k,k])@@ -1367,7 +1299,7 @@ rhs klass (mkPrelTyConRepName heqTyConName) klass = mk_class tycon sc_pred sc_sel_id- datacon = pcDataConW heqDataConName tvs [unrestricted sc_pred] tycon+ datacon = pcDataConConstraint heqDataConName tvs [sc_pred] tycon -- Kind: forall k1 k2. k1 -> k2 -> Constraint binders = mkTemplateTyConBinders [liftedTypeKind, liftedTypeKind] id@@ -1385,7 +1317,7 @@ rhs klass (mkPrelTyConRepName coercibleTyConName) klass = mk_class tycon sc_pred sc_sel_id- datacon = pcDataConW coercibleDataConName tvs [unrestricted sc_pred] tycon+ datacon = pcDataConConstraint coercibleDataConName tvs [sc_pred] tycon -- Kind: forall k. k -> k -> Constraint binders = mkTemplateTyConBinders [liftedTypeKind] (\[k] -> [k,k])@@ -1419,12 +1351,20 @@ data Multiplicity = One | Many -} +multiplicityTyConName :: Name+multiplicityTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Multiplicity")+ multiplicityTyConKey multiplicityTyCon++oneDataConName, manyDataConName :: Name+oneDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "One") oneDataConKey oneDataCon+manyDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "Many") manyDataConKey manyDataCon+ multiplicityTy :: Type multiplicityTy = mkTyConTy multiplicityTyCon multiplicityTyCon :: TyCon multiplicityTyCon = pcTyCon multiplicityTyConName Nothing []- [oneDataCon, manyDataCon]+ [oneDataCon, manyDataCon] oneDataCon, manyDataCon :: DataCon oneDataCon = pcDataCon oneDataConName [] [] multiplicityTyCon@@ -1450,19 +1390,21 @@ where binders = mkTemplateAnonTyConBinders [multiplicityTy, multiplicityTy] -unrestrictedFunTy :: Type-unrestrictedFunTy = functionWithMultiplicity manyDataConTy-+------------------------+-- type (->) :: forall (rep1 :: RuntimeRep) (rep2 :: RuntimeRep).+-- TYPE rep1 -> TYPE rep2 -> Type+-- type (->) = FUN 'Many unrestrictedFunTyCon :: TyCon-unrestrictedFunTyCon = buildSynTyCon unrestrictedFunTyConName [] arrowKind [] unrestrictedFunTy- where arrowKind = mkTyConKind binders liftedTypeKind- -- See also funTyCon- binders = [ Bndr runtimeRep1TyVar (NamedTCB Inferred)- , Bndr runtimeRep2TyVar (NamedTCB Inferred)- ]- ++ mkTemplateAnonTyConBinders [ mkTYPEapp runtimeRep1Ty- , mkTYPEapp runtimeRep2Ty- ]+unrestrictedFunTyCon+ = buildSynTyCon unrestrictedFunTyConName [] arrowKind []+ (TyCoRep.TyConApp fUNTyCon [manyDataConTy])+ where+ arrowKind = mkTyConKind binders liftedTypeKind+ -- See also funTyCon+ binders = [ Bndr runtimeRep1TyVar (NamedTCB Inferred)+ , Bndr runtimeRep2TyVar (NamedTCB Inferred) ]+ ++ mkTemplateAnonTyConBinders [ mkTYPEapp runtimeRep1Ty+ , mkTYPEapp runtimeRep2Ty ] unrestrictedFunTyConName :: Name unrestrictedFunTyConName = mkWiredInTyConName BuiltInSyntax gHC_TYPES (fsLit "->")@@ -1473,91 +1415,94 @@ * * Type synonyms (all declared in ghc-prim:GHC.Types) - type Type = TYPE LiftedRep -- liftedTypeKind- type UnliftedType = TYPE UnliftedRep -- unliftedTypeKind- type LiftedRep = BoxedRep Lifted -- liftedRepTy- type UnliftedRep = BoxedRep Unlifted -- unliftedRepTy+ type CONSTRAINT :: RuntimeRep -> Type -- primitive; cONSTRAINTKind+ type Constraint = CONSTRAINT LiftedRep :: Type -- constraintKind + type TYPE :: RuntimeRep -> Type -- primitive; tYPEKind+ type Type = TYPE LiftedRep :: Type -- liftedTypeKind+ type UnliftedType = TYPE UnliftedRep :: Type -- unliftedTypeKind++ type LiftedRep = BoxedRep Lifted :: RuntimeRep -- liftedRepTy+ type UnliftedRep = BoxedRep Unlifted :: RuntimeRep -- unliftedRepTy+ * * ********************************************************************* -} -- For these synonyms, see--- Note [TYPE and RuntimeRep] in GHC.Builtin.Types.Prim, and+-- Note [TYPE and CONSTRAINT] in GHC.Builtin.Types.Prim, and -- Note [Using synonyms to compress types] in GHC.Core.Type +{- Note [Naked FunTy]+~~~~~~~~~~~~~~~~~~~~~+GHC.Core.TyCo.Rep.mkFunTy has assertions about the consistency of the argument+flag and arg/res types. But when constructing the kinds of tYPETyCon and+cONSTRAINTTyCon we don't want to make these checks because+ TYPE :: RuntimeRep -> Type+i.e. TYPE :: RuntimeRep -> TYPE LiftedRep++so the check will loop infinitely. Hence the use of a naked FunTy+constructor in tTYPETyCon and cONSTRAINTTyCon.+-}++ ------------------------- @type Type = TYPE ('BoxedRep 'Lifted)@+-- type Constraint = CONSTRAINT LiftedRep+constraintKindTyCon :: TyCon+constraintKindTyCon+ = buildSynTyCon constraintKindTyConName [] liftedTypeKind [] rhs+ where+ rhs = TyCoRep.TyConApp cONSTRAINTTyCon [liftedRepTy]++constraintKindTyConName :: Name+constraintKindTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Constraint")+ constraintKindTyConKey constraintKindTyCon++constraintKind :: Kind+constraintKind = mkTyConTy constraintKindTyCon++----------------------+-- type Type = TYPE LiftedRep liftedTypeKindTyCon :: TyCon liftedTypeKindTyCon = buildSynTyCon liftedTypeKindTyConName [] liftedTypeKind [] rhs where rhs = TyCoRep.TyConApp tYPETyCon [liftedRepTy] -liftedTypeKind :: Type+liftedTypeKindTyConName :: Name+liftedTypeKindTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Type")+ liftedTypeKindTyConKey liftedTypeKindTyCon++liftedTypeKind, typeToTypeKind :: Type liftedTypeKind = mkTyConTy liftedTypeKindTyCon+typeToTypeKind = liftedTypeKind `mkVisFunTyMany` liftedTypeKind ------------------------- | @type UnliftedType = TYPE ('BoxedRep 'Unlifted)@+-- type UnliftedType = TYPE ('BoxedRep 'Unlifted) unliftedTypeKindTyCon :: TyCon unliftedTypeKindTyCon = buildSynTyCon unliftedTypeKindTyConName [] liftedTypeKind [] rhs where rhs = TyCoRep.TyConApp tYPETyCon [unliftedRepTy] +unliftedTypeKindTyConName :: Name+unliftedTypeKindTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "UnliftedType")+ unliftedTypeKindTyConKey unliftedTypeKindTyCon+ unliftedTypeKind :: Type unliftedTypeKind = mkTyConTy unliftedTypeKindTyCon -------------------------- @type ZeroBitType = TYPE ZeroBitRep-zeroBitTypeTyCon :: TyCon-zeroBitTypeTyCon- = buildSynTyCon zeroBitTypeTyConName [] liftedTypeKind [] rhs- where- rhs = TyCoRep.TyConApp tYPETyCon [zeroBitRepTy] -zeroBitTypeKind :: Type-zeroBitTypeKind = mkTyConTy zeroBitTypeTyCon--------------------------- | @type LiftedRep = 'BoxedRep 'Lifted@-liftedRepTyCon :: TyCon-liftedRepTyCon- = buildSynTyCon liftedRepTyConName [] runtimeRepTy [] rhs- where- rhs = TyCoRep.TyConApp boxedRepDataConTyCon [liftedDataConTy]--liftedRepTy :: RuntimeRepType-liftedRepTy = mkTyConTy liftedRepTyCon--------------------------- | @type UnliftedRep = 'BoxedRep 'Unlifted@-unliftedRepTyCon :: TyCon-unliftedRepTyCon- = buildSynTyCon unliftedRepTyConName [] runtimeRepTy [] rhs- where- rhs = TyCoRep.TyConApp boxedRepDataConTyCon [unliftedDataConTy]--unliftedRepTy :: RuntimeRepType-unliftedRepTy = mkTyConTy unliftedRepTyCon--------------------------- | @type ZeroBitRep = 'Tuple '[]-zeroBitRepTyCon :: TyCon-zeroBitRepTyCon- = buildSynTyCon zeroBitRepTyConName [] runtimeRepTy [] rhs- where- rhs = TyCoRep.TyConApp tupleRepDataConTyCon [mkPromotedListTy runtimeRepTy []]--zeroBitRepTy :: RuntimeRepType-zeroBitRepTy = mkTyConTy zeroBitRepTyCon-- {- ********************************************************************* * * data Levity = Lifted | Unlifted * * ********************************************************************* -} +levityTyConName, liftedDataConName, unliftedDataConName :: Name+levityTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Levity") levityTyConKey levityTyCon+liftedDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "Lifted") liftedDataConKey liftedDataCon+unliftedDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "Unlifted") unliftedDataConKey unliftedDataCon+ levityTyCon :: TyCon levityTyCon = pcTyCon levityTyConName Nothing [] [liftedDataCon,unliftedDataCon] @@ -1566,9 +1511,9 @@ liftedDataCon, unliftedDataCon :: DataCon liftedDataCon = pcSpecialDataCon liftedDataConName- [] levityTyCon LiftedInfo+ [] levityTyCon (Levity Lifted) unliftedDataCon = pcSpecialDataCon unliftedDataConName- [] levityTyCon UnliftedInfo+ [] levityTyCon (Levity Unlifted) liftedDataConTyCon :: TyCon liftedDataConTyCon = promoteDataCon liftedDataCon@@ -1608,21 +1553,35 @@ runtimeRepTyCon :: TyCon runtimeRepTyCon = pcTyCon runtimeRepTyConName Nothing []+ -- Here we list all the data constructors+ -- of the RuntimeRep data type (vecRepDataCon : tupleRepDataCon :- sumRepDataCon : boxedRepDataCon : runtimeRepSimpleDataCons)+ sumRepDataCon : boxedRepDataCon :+ runtimeRepSimpleDataCons) runtimeRepTy :: Type runtimeRepTy = mkTyConTy runtimeRepTyCon +runtimeRepTyConName, vecRepDataConName, tupleRepDataConName, sumRepDataConName, boxedRepDataConName :: Name+runtimeRepTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "RuntimeRep") runtimeRepTyConKey runtimeRepTyCon++vecRepDataConName = mk_runtime_rep_dc_name (fsLit "VecRep") vecRepDataConKey vecRepDataCon+tupleRepDataConName = mk_runtime_rep_dc_name (fsLit "TupleRep") tupleRepDataConKey tupleRepDataCon+sumRepDataConName = mk_runtime_rep_dc_name (fsLit "SumRep") sumRepDataConKey sumRepDataCon+boxedRepDataConName = mk_runtime_rep_dc_name (fsLit "BoxedRep") boxedRepDataConKey boxedRepDataCon++mk_runtime_rep_dc_name :: FastString -> Unique -> DataCon -> Name+mk_runtime_rep_dc_name fs u dc = mkWiredInDataConName UserSyntax gHC_TYPES fs u dc+ boxedRepDataCon :: DataCon boxedRepDataCon = pcSpecialDataCon boxedRepDataConName [ levityTy ] runtimeRepTyCon (RuntimeRep prim_rep_fun) where -- See Note [Getting from RuntimeRep to PrimRep] in RepType prim_rep_fun [lev]- = case tyConRuntimeRepInfo (tyConAppTyCon lev) of- LiftedInfo -> [LiftedRep]- UnliftedInfo -> [UnliftedRep]+ = case tyConPromDataConInfo (tyConAppTyCon lev) of+ Levity Lifted -> [LiftedRep]+ Levity Unlifted -> [UnliftedRep] _ -> pprPanic "boxedRepDataCon" (ppr lev) prim_rep_fun args = pprPanic "boxedRepDataCon" (ppr args)@@ -1631,23 +1590,6 @@ boxedRepDataConTyCon :: TyCon boxedRepDataConTyCon = promoteDataCon boxedRepDataCon -vecRepDataCon :: DataCon-vecRepDataCon = pcSpecialDataCon vecRepDataConName [ mkTyConTy vecCountTyCon- , mkTyConTy vecElemTyCon ]- runtimeRepTyCon- (RuntimeRep prim_rep_fun)- where- -- See Note [Getting from RuntimeRep to PrimRep] in GHC.Types.RepType- prim_rep_fun [count, elem]- | VecCount n <- tyConRuntimeRepInfo (tyConAppTyCon count)- , VecElem e <- tyConRuntimeRepInfo (tyConAppTyCon elem)- = [VecRep n e]- prim_rep_fun args- = pprPanic "vecRepDataCon" (ppr args)--vecRepDataConTyCon :: TyCon-vecRepDataConTyCon = promoteDataCon vecRepDataCon- tupleRepDataCon :: DataCon tupleRepDataCon = pcSpecialDataCon tupleRepDataConName [ mkListTy runtimeRepTy ] runtimeRepTyCon (RuntimeRep prim_rep_fun)@@ -1670,7 +1612,7 @@ where -- See Note [Getting from RuntimeRep to PrimRep] in GHC.Types.RepType prim_rep_fun [rr_ty_list]- = map slotPrimRep (ubxSumRepType prim_repss)+ = map slotPrimRep (toList (ubxSumRepType prim_repss)) where rr_tys = extractPromotedList rr_ty_list doc = text "sumRepDataCon" <+> ppr rr_tys@@ -1685,18 +1627,27 @@ -- See Note [Getting from RuntimeRep to PrimRep] in GHC.Types.RepType runtimeRepSimpleDataCons :: [DataCon] runtimeRepSimpleDataCons- = zipWithLazy mk_runtime_rep_dc- [ IntRep- , Int8Rep, Int16Rep, Int32Rep, Int64Rep- , WordRep- , Word8Rep, Word16Rep, Word32Rep, Word64Rep- , AddrRep- , FloatRep, DoubleRep- ]- runtimeRepSimpleDataConNames+ = zipWith mk_runtime_rep_dc runtimeRepSimpleDataConKeys+ [ (fsLit "IntRep", IntRep)+ , (fsLit "Int8Rep", Int8Rep)+ , (fsLit "Int16Rep", Int16Rep)+ , (fsLit "Int32Rep", Int32Rep)+ , (fsLit "Int64Rep", Int64Rep)+ , (fsLit "WordRep", WordRep)+ , (fsLit "Word8Rep", Word8Rep)+ , (fsLit "Word16Rep", Word16Rep)+ , (fsLit "Word32Rep", Word32Rep)+ , (fsLit "Word64Rep", Word64Rep)+ , (fsLit "AddrRep", AddrRep)+ , (fsLit "FloatRep", FloatRep)+ , (fsLit "DoubleRep", DoubleRep) ] where- mk_runtime_rep_dc primrep name- = pcSpecialDataCon name [] runtimeRepTyCon (RuntimeRep (\_ -> [primrep]))+ mk_runtime_rep_dc :: Unique -> (FastString, PrimRep) -> DataCon+ mk_runtime_rep_dc uniq (fs, primrep)+ = data_con+ where+ data_con = pcSpecialDataCon dc_name [] runtimeRepTyCon (RuntimeRep (\_ -> [primrep]))+ dc_name = mk_runtime_rep_dc_name fs uniq data_con -- See Note [Wiring in RuntimeRep] intRepDataConTy,@@ -1714,17 +1665,108 @@ ] = map (mkTyConTy . promoteDataCon) runtimeRepSimpleDataCons +----------------------+-- | @type ZeroBitRep = 'Tuple '[]+zeroBitRepTyCon :: TyCon+zeroBitRepTyCon+ = buildSynTyCon zeroBitRepTyConName [] runtimeRepTy [] rhs+ where+ rhs = TyCoRep.TyConApp tupleRepDataConTyCon [mkPromotedListTy runtimeRepTy []]++zeroBitRepTyConName :: Name+zeroBitRepTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "ZeroBitRep")+ zeroBitRepTyConKey zeroBitRepTyCon++zeroBitRepTy :: RuntimeRepType+zeroBitRepTy = mkTyConTy zeroBitRepTyCon++----------------------+-- @type ZeroBitType = TYPE ZeroBitRep+zeroBitTypeTyCon :: TyCon+zeroBitTypeTyCon+ = buildSynTyCon zeroBitTypeTyConName [] liftedTypeKind [] rhs+ where+ rhs = TyCoRep.TyConApp tYPETyCon [zeroBitRepTy]++zeroBitTypeTyConName :: Name+zeroBitTypeTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "ZeroBitType")+ zeroBitTypeTyConKey zeroBitTypeTyCon++zeroBitTypeKind :: Type+zeroBitTypeKind = mkTyConTy zeroBitTypeTyCon++----------------------+-- | @type LiftedRep = 'BoxedRep 'Lifted@+liftedRepTyCon :: TyCon+liftedRepTyCon+ = buildSynTyCon liftedRepTyConName [] runtimeRepTy [] rhs+ where+ rhs = TyCoRep.TyConApp boxedRepDataConTyCon [liftedDataConTy]++liftedRepTyConName :: Name+liftedRepTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "LiftedRep")+ liftedRepTyConKey liftedRepTyCon++liftedRepTy :: RuntimeRepType+liftedRepTy = mkTyConTy liftedRepTyCon++----------------------+-- | @type UnliftedRep = 'BoxedRep 'Unlifted@+unliftedRepTyCon :: TyCon+unliftedRepTyCon+ = buildSynTyCon unliftedRepTyConName [] runtimeRepTy [] rhs+ where+ rhs = TyCoRep.TyConApp boxedRepDataConTyCon [unliftedDataConTy]++unliftedRepTyConName :: Name+unliftedRepTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "UnliftedRep")+ unliftedRepTyConKey unliftedRepTyCon++unliftedRepTy :: RuntimeRepType+unliftedRepTy = mkTyConTy unliftedRepTyCon+++{- *********************************************************************+* *+ VecCount, VecElem+* *+********************************************************************* -}++vecCountTyConName :: Name+vecCountTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "VecCount") vecCountTyConKey vecCountTyCon++vecElemTyConName :: Name+vecElemTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "VecElem") vecElemTyConKey vecElemTyCon++vecRepDataCon :: DataCon+vecRepDataCon = pcSpecialDataCon vecRepDataConName [ mkTyConTy vecCountTyCon+ , mkTyConTy vecElemTyCon ]+ runtimeRepTyCon+ (RuntimeRep prim_rep_fun)+ where+ -- See Note [Getting from RuntimeRep to PrimRep] in GHC.Types.RepType+ prim_rep_fun [count, elem]+ | VecCount n <- tyConPromDataConInfo (tyConAppTyCon count)+ , VecElem e <- tyConPromDataConInfo (tyConAppTyCon elem)+ = [VecRep n e]+ prim_rep_fun args+ = pprPanic "vecRepDataCon" (ppr args)++vecRepDataConTyCon :: TyCon+vecRepDataConTyCon = promoteDataCon vecRepDataCon+ vecCountTyCon :: TyCon vecCountTyCon = pcTyCon vecCountTyConName Nothing [] vecCountDataCons -- See Note [Wiring in RuntimeRep] vecCountDataCons :: [DataCon]-vecCountDataCons = zipWithLazy mk_vec_count_dc- [ 2, 4, 8, 16, 32, 64 ]- vecCountDataConNames+vecCountDataCons = zipWith mk_vec_count_dc [1..6] vecCountDataConKeys where- mk_vec_count_dc n name- = pcSpecialDataCon name [] vecCountTyCon (VecCount n)+ mk_vec_count_dc logN key = con+ where+ n = 2^(logN :: Int)+ name = mk_runtime_rep_dc_name (fsLit ("Vec" ++ show n)) key con+ con = pcSpecialDataCon name [] vecCountTyCon (VecCount n) -- See Note [Wiring in RuntimeRep] vec2DataConTy, vec4DataConTy, vec8DataConTy, vec16DataConTy, vec32DataConTy,@@ -1737,14 +1779,19 @@ -- See Note [Wiring in RuntimeRep] vecElemDataCons :: [DataCon]-vecElemDataCons = zipWithLazy mk_vec_elem_dc- [ Int8ElemRep, Int16ElemRep, Int32ElemRep, Int64ElemRep- , Word8ElemRep, Word16ElemRep, Word32ElemRep, Word64ElemRep- , FloatElemRep, DoubleElemRep ]- vecElemDataConNames+vecElemDataCons = zipWith3 mk_vec_elem_dc+ [ fsLit "Int8ElemRep", fsLit "Int16ElemRep", fsLit "Int32ElemRep", fsLit "Int64ElemRep"+ , fsLit "Word8ElemRep", fsLit "Word16ElemRep", fsLit "Word32ElemRep", fsLit "Word64ElemRep"+ , fsLit "FloatElemRep", fsLit "DoubleElemRep" ]+ [ Int8ElemRep, Int16ElemRep, Int32ElemRep, Int64ElemRep+ , Word8ElemRep, Word16ElemRep, Word32ElemRep, Word64ElemRep+ , FloatElemRep, DoubleElemRep ]+ vecElemDataConKeys where- mk_vec_elem_dc elem name- = pcSpecialDataCon name [] vecElemTyCon (VecElem elem)+ mk_vec_elem_dc nameFs elemRep key = con+ where+ name = mk_runtime_rep_dc_name nameFs key con+ con = pcSpecialDataCon name [] vecElemTyCon (VecElem elemRep) -- See Note [Wiring in RuntimeRep] int8ElemRepDataConTy, int16ElemRepDataConTy, int32ElemRepDataConTy,@@ -1763,30 +1810,6 @@ * * ********************************************************************* -} -boxingDataCon_maybe :: TyCon -> Maybe DataCon--- boxingDataCon_maybe Char# = C#--- boxingDataCon_maybe Int# = I#--- ... etc ...--- See Note [Boxing primitive types]-boxingDataCon_maybe tc- = lookupNameEnv boxing_constr_env (tyConName tc)--boxing_constr_env :: NameEnv DataCon-boxing_constr_env- = mkNameEnv [(charPrimTyConName , charDataCon )- ,(intPrimTyConName , intDataCon )- ,(wordPrimTyConName , wordDataCon )- ,(floatPrimTyConName , floatDataCon )- ,(doublePrimTyConName, doubleDataCon) ]--{- Note [Boxing primitive types]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-For a handful of primitive types (Int, Char, Word, Float, Double),-we can readily box and an unboxed version (Int#, Char# etc) using-the corresponding data constructor. This is useful in a couple-of places, notably let-floating -}-- charTy :: Type charTy = mkTyConTy charTyCon @@ -1863,6 +1886,140 @@ doubleDataCon :: DataCon doubleDataCon = pcDataCon doubleDataConName [] [doublePrimTy] doubleTyCon +{- *********************************************************************+* *+ Boxing data constructors+* *+********************************************************************* -}++{- Note [Boxing constructors]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In ghc-prim:GHC.Types we have a family of data types, one for each RuntimeRep+that "box" unlifted values into a (boxed, lifted) value of kind Type. For example++ type Int8Box :: TYPE Int8Rep -> Type+ data Int8Box (a :: TYPE Int8Rep) = MkInt8Box a+ -- MkInt8Box :: forall (a :: TYPE Int8Rep). a -> Int8Box a++Then we can package an `Int8#` into an `Int8Box` with `MkInt8Box`. We can also+package up a (lifted) Constraint as a value of kind Type.++There are a fixed number of RuntimeReps, so we only need a fixed number+of boxing types. (For TupleRep we need to box recursively; not yet done,+see #22336.)++This is used:++* In desugaring, when we need to package up a bunch of values into a tuple,+ for example when desugaring arrows. See Note [Big tuples] in GHC.Core.Make.++* In let-floating when we want to float an unlifted sub-expression.+ See Note [Floating MFEs of unlifted type] in GHC.Core.Opt.SetLevels++In this module we make wired-in data type declarations for all of+these boxing functions. The goal is to define boxingDataCon_maybe.++Wrinkles+(W1) The runtime system has special treatment (e.g. commoning up during GC)+ for Int and Char values. See Note [CHARLIKE and INTLIKE closures] and+ Note [Precomputed static closures] in the RTS.++ So we treat Int# and Char# specially, in specialBoxingDataCon_maybe+-}++data BoxingInfo b+ = BI_NoBoxNeeded -- The type has kind Type, so there is nothing to do++ | BI_NoBoxAvailable -- The type does not have kind Type, but sadly we+ -- don't have a boxing data constructor either++ | BI_Box -- The type does not have kind Type, and we do have a+ -- boxing data constructor; here it is+ { bi_data_con :: DataCon+ , bi_inst_con :: Expr b+ , bi_boxed_type :: Type }+ -- e.g. BI_Box { bi_data_con = I#, bi_inst_con = I#, bi_boxed_type = Int }+ -- recall: data Int = I# Int#+ --+ -- BI_Box { bi_data_con = MkInt8Box, bi_inst_con = MkInt8Box @ty+ -- , bi_boxed_type = Int8Box ty }A+ -- recall: data Int8Box (a :: TYPE Int8Rep) = MkIntBox a++boxingDataCon :: Type -> BoxingInfo b+-- ^ Given a type 'ty', if 'ty' is not of kind Type, return a data constructor that+-- will box it, and the type of the boxed thing, which /does/ now have kind Type.+-- See Note [Boxing constructors]+boxingDataCon ty+ | tcIsLiftedTypeKind kind+ = BI_NoBoxNeeded -- Fast path for Type++ | Just box_con <- specialBoxingDataCon_maybe ty+ = BI_Box { bi_data_con = box_con, bi_inst_con = mkConApp box_con []+ , bi_boxed_type = tyConNullaryTy (dataConTyCon box_con) }++ | Just box_con <- lookupTypeMap boxingDataConMap kind+ = BI_Box { bi_data_con = box_con, bi_inst_con = mkConApp box_con [Type ty]+ , bi_boxed_type = mkTyConApp (dataConTyCon box_con) [ty] }++ | otherwise+ = BI_NoBoxAvailable++ where+ kind = typeKind ty++specialBoxingDataCon_maybe :: Type -> Maybe DataCon+-- ^ See Note [Boxing constructors] wrinkle (W1)+specialBoxingDataCon_maybe ty+ = case splitTyConApp_maybe ty of+ Just (tc, _) | tc `hasKey` intPrimTyConKey -> Just intDataCon+ | tc `hasKey` charPrimTyConKey -> Just charDataCon+ _ -> Nothing++boxingDataConMap :: TypeMap DataCon+-- See Note [Boxing constructors]+boxingDataConMap = foldl add emptyTypeMap boxingDataCons+ where+ add bdcm (kind, boxing_con) = extendTypeMap bdcm kind boxing_con++boxingDataCons :: [(Kind, DataCon)]+-- The Kind is the kind of types for which the DataCon is the right boxing+boxingDataCons = zipWith mkBoxingDataCon+ (map mkBoxingTyConUnique [1..])+ [ (mkTYPEapp wordRepDataConTy, fsLit "WordBox", fsLit "MkWordBox")+ , (mkTYPEapp intRepDataConTy, fsLit "IntBox", fsLit "MkIntBox")++ , (mkTYPEapp floatRepDataConTy, fsLit "FloatBox", fsLit "MkFloatBox")+ , (mkTYPEapp doubleRepDataConTy, fsLit "DoubleBox", fsLit "MkDoubleBox")++ , (mkTYPEapp int8RepDataConTy, fsLit "Int8Box", fsLit "MkInt8Box")+ , (mkTYPEapp int16RepDataConTy, fsLit "Int16Box", fsLit "MkInt16Box")+ , (mkTYPEapp int32RepDataConTy, fsLit "Int32Box", fsLit "MkInt32Box")+ , (mkTYPEapp int64RepDataConTy, fsLit "Int64Box", fsLit "MkInt64Box")++ , (mkTYPEapp word8RepDataConTy, fsLit "Word8Box", fsLit "MkWord8Box")+ , (mkTYPEapp word16RepDataConTy, fsLit "Word16Box", fsLit "MkWord16Box")+ , (mkTYPEapp word32RepDataConTy, fsLit "Word32Box", fsLit "MkWord32Box")+ , (mkTYPEapp word64RepDataConTy, fsLit "Word64Box", fsLit "MkWord64Box")++ , (unliftedTypeKind, fsLit "LiftBox", fsLit "MkLiftBox")+ , (constraintKind, fsLit "DictBox", fsLit "MkDictBox") ]++mkBoxingDataCon :: Unique -> (Kind, FastString, FastString) -> (Kind, DataCon)+mkBoxingDataCon uniq_tc (kind, fs_tc, fs_dc)+ = (kind, dc)+ where+ uniq_dc = boxingDataConUnique uniq_tc++ (tv:_) = mkTemplateTyVars (repeat kind)+ tc = pcTyCon tc_name Nothing [tv] [dc]+ tc_name = mkWiredInTyConName UserSyntax gHC_TYPES fs_tc uniq_tc tc++ dc | isConstraintKind kind+ = pcDataConConstraint dc_name [tv] [mkTyVarTy tv] tc+ | otherwise+ = pcDataCon dc_name [tv] [mkTyVarTy tv] tc+ dc_name = mkWiredInDataConName UserSyntax gHC_TYPES fs_dc uniq_dc dc+ {- ************************************************************************ * *@@ -1969,23 +2126,14 @@ consDataCon :: DataCon consDataCon = pcDataConWithFixity True {- Declared infix -} consDataConName- alpha_tyvar [] alpha_tyvar- (map linear [alphaTy, mkTyConApp listTyCon alpha_ty]) listTyCon+ alpha_tyvar [] alpha_tyvar []+ (map linear [alphaTy, mkTyConApp listTyCon alpha_ty])+ listTyCon+ -- Interesting: polymorphic recursion would help here. -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy -- gets the over-specific type (Type -> Type) --- NonEmpty lists (used for 'ProjectionE')-nonEmptyTyCon :: TyCon-nonEmptyTyCon = pcTyCon nonEmptyTyConName Nothing [alphaTyVar] [nonEmptyDataCon]--nonEmptyDataCon :: DataCon-nonEmptyDataCon = pcDataConWithFixity True {- Declared infix -}- nonEmptyDataConName- alpha_tyvar [] alpha_tyvar- (map linear [alphaTy, mkTyConApp listTyCon alpha_ty])- nonEmptyTyCon- -- Wired-in type Maybe maybeTyCon :: TyCon@@ -2075,7 +2223,7 @@ mkTupleTy1 :: Boxity -> [Type] -> Type mkTupleTy1 Boxed tys = mkTyConApp (tupleTyCon Boxed (length tys)) tys mkTupleTy1 Unboxed tys = mkTyConApp (tupleTyCon Unboxed (length tys))- (map getRuntimeRep tys ++ tys)+ (map getRuntimeRep tys ++ tys) -- | Build the type of a small tuple that holds the specified type of thing -- Flattens 1-tuples. See Note [One-tuples].@@ -2084,6 +2232,18 @@ unitTy :: Type unitTy = mkTupleTy Boxed []++-- Make a constraint tuple, flattening a 1-tuple as usual+-- If we get a constraint tuple that is bigger than the pre-built+-- ones (in ghc-prim:GHC.Tuple), then just make one up anyway; it won't+-- have an info table in the RTS, so we can't use it at runtime. But+-- this is used only in filling in extra-constraint wildcards, so it+-- never is used at runtime anyway+-- See GHC.Tc.Gen.HsType Note [Extra-constraint holes in partial type signatures]+mkConstraintTupleTy :: [Type] -> Type+mkConstraintTupleTy [ty] = ty+mkConstraintTupleTy tys = mkTyConApp (cTupleTyCon (length tys)) tys+ {- ********************************************************************* * *
compiler/GHC/Builtin/Types.hs-boot view
@@ -16,8 +16,8 @@ unitTy :: Type - liftedTypeKindTyConName :: Name+constraintKindTyConName :: Name liftedTypeKind, unliftedTypeKind, zeroBitTypeKind :: Kind
compiler/GHC/Builtin/Types/Prim.hs view
@@ -30,6 +30,8 @@ levity1TyVarInf, levity2TyVarInf, levity1Ty, levity2Ty, + alphaConstraintTyVar, alphaConstraintTy,+ openAlphaTyVar, openBetaTyVar, openGammaTyVar, openAlphaTyVarSpec, openBetaTyVarSpec, openGammaTyVarSpec, openAlphaTy, openBetaTy, openGammaTy,@@ -41,13 +43,16 @@ multiplicityTyVar1, multiplicityTyVar2, -- Kind constructors...- tYPETyCon, tYPETyConName,+ tYPETyCon, tYPETyConName, tYPEKind,+ cONSTRAINTTyCon, cONSTRAINTTyConName, cONSTRAINTKind, - -- Kinds- mkTYPEapp,+ -- Arrows+ funTyFlagTyCon, isArrowTyCon,+ fUNTyCon, fUNTyConName,+ ctArrowTyCon, ctArrowTyConName,+ ccArrowTyCon, ccArrowTyConName,+ tcArrowTyCon, tcArrowTyConName, - functionWithMultiplicity,- funTyCon, funTyConName, unexposedPrimTyCons, exposedPrimTyCons, primTyCons, charPrimTyCon, charPrimTy, charPrimTyConName,@@ -121,45 +126,134 @@ , int64ElemRepDataConTy, word8ElemRepDataConTy, word16ElemRepDataConTy , word32ElemRepDataConTy, word64ElemRepDataConTy, floatElemRepDataConTy , doubleElemRepDataConTy- , multiplicityTy )+ , multiplicityTy+ , constraintKind ) -import GHC.Types.Var ( TyVarBinder, TyVar+import {-# SOURCE #-} GHC.Types.TyThing( mkATyCon )+import {-# SOURCE #-} GHC.Core.Type ( mkTyConApp, getLevity )++import GHC.Core.TyCon+import GHC.Core.TyCo.Rep -- Doesn't need special access, but this is easier to avoid+ -- import loops which show up if you import Type instead++import GHC.Types.Var ( TyVarBinder, TyVar,binderVar, binderVars , mkTyVar, mkTyVarBinder, mkTyVarBinders ) import GHC.Types.Name-import {-# SOURCE #-} GHC.Types.TyThing-import GHC.Core.TyCon import GHC.Types.SrcLoc import GHC.Types.Unique+ import GHC.Builtin.Uniques import GHC.Builtin.Names-import GHC.Data.FastString import GHC.Utils.Misc ( changeLast )-import GHC.Core.TyCo.Rep -- Doesn't need special access, but this is easier to avoid- -- import loops which show up if you import Type instead-import {-# SOURCE #-} GHC.Core.Type ( mkTyConTy, mkTyConApp, mkTYPEapp, getLevity )+import GHC.Utils.Panic ( assertPpr )+import GHC.Utils.Outputable +import GHC.Data.FastString import Data.Char -{--************************************************************************+{- ********************************************************************* * *-\subsection{Primitive type constructors}+ Building blocks * *-************************************************************************+********************************************************************* -}++mk_TYPE_app :: Type -> Type+mk_TYPE_app rep = mkTyConApp tYPETyCon [rep]++mk_CONSTRAINT_app :: Type -> Type+mk_CONSTRAINT_app rep = mkTyConApp cONSTRAINTTyCon [rep]++mkPrimTc :: FastString -> Unique -> TyCon -> Name+mkPrimTc = mkGenPrimTc UserSyntax++mkBuiltInPrimTc :: FastString -> Unique -> TyCon -> Name+mkBuiltInPrimTc = mkGenPrimTc BuiltInSyntax++mkGenPrimTc :: BuiltInSyntax -> FastString -> Unique -> TyCon -> Name+mkGenPrimTc built_in_syntax occ key tycon+ = mkWiredInName gHC_PRIM (mkTcOccFS occ)+ key+ (mkATyCon tycon)+ built_in_syntax++-- | Create a primitive 'TyCon' with the given 'Name',+-- arguments of kind 'Type` with the given 'Role's,+-- and the given result kind representation.+--+-- Only use this in "GHC.Builtin.Types.Prim".+pcPrimTyCon :: Name+ -> [Role] -> RuntimeRepType -> TyCon+pcPrimTyCon name roles res_rep+ = mkPrimTyCon name binders result_kind roles+ where+ bndr_kis = liftedTypeKind <$ roles+ binders = mkTemplateAnonTyConBinders bndr_kis+ result_kind = mk_TYPE_app res_rep++-- | Create a primitive nullary 'TyCon' with the given 'Name'+-- and result kind representation.+--+-- Only use this in "GHC.Builtin.Types.Prim".+pcPrimTyCon0 :: Name -> RuntimeRepType -> TyCon+pcPrimTyCon0 name res_rep+ = pcPrimTyCon name [] res_rep++-- | Create a primitive 'TyCon' like 'pcPrimTyCon', except the last+-- argument is levity-polymorphic, where the levity argument is+-- implicit and comes before other arguments+--+-- Only use this in "GHC.Builtin.Types.Prim".+pcPrimTyCon_LevPolyLastArg :: Name+ -> [Role] -- ^ roles of the arguments (must be non-empty),+ -- not including the implicit argument of kind 'Levity',+ -- which always has 'Nominal' role+ -> RuntimeRepType -- ^ representation of the fully-applied type+ -> TyCon+pcPrimTyCon_LevPolyLastArg name roles res_rep+ = mkPrimTyCon name binders result_kind (Nominal : roles)+ where+ result_kind = mk_TYPE_app res_rep+ lev_bndr = mkNamedTyConBinder Inferred levity1TyVar+ binders = lev_bndr : mkTemplateAnonTyConBinders anon_bndr_kis+ lev_tv = mkTyVarTy (binderVar lev_bndr)++ -- [ Type, ..., Type, TYPE (BoxedRep l) ]+ anon_bndr_kis = changeLast (liftedTypeKind <$ roles) $+ mk_TYPE_app $+ mkTyConApp boxedRepDataConTyCon [lev_tv]+++{- *********************************************************************+* *+ Primitive type constructors+* *+********************************************************************* -}++{- Note Note [Unexposed TyCons]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+A few primitive TyCons are "unexposed", meaning:+* We don't want users to be able to write them (see #15209);+ i.e. they aren't in scope, ever. In particular they do not+ appear in the exports of GHC.Prim: see GHC.Builtin.Utils.ghcPrimExports++* We don't want users to see them in GHCi's @:browse@ output (see #12023). -} primTyCons :: [TyCon] primTyCons = unexposedPrimTyCons ++ exposedPrimTyCons --- | Primitive 'TyCon's that are defined in GHC.Prim but not exposed.--- It's important to keep these separate as we don't want users to be able to--- write them (see #15209) or see them in GHCi's @:browse@ output--- (see #12023).+-- | Primitive 'TyCon's that are defined in GHC.Prim but not "exposed".+-- See Note [Unexposed TyCons] unexposedPrimTyCons :: [TyCon] unexposedPrimTyCons- = [ eqPrimTyCon- , eqReprPrimTyCon- , eqPhantPrimTyCon+ = [ eqPrimTyCon -- (~#)+ , eqReprPrimTyCon -- (~R#)+ , eqPhantPrimTyCon -- (~P#)++ -- These arrows are un-exposed for now+ , ctArrowTyCon -- (=>)+ , ccArrowTyCon -- (==>)+ , tcArrowTyCon -- (-=>) ] -- | Primitive 'TyCon's that are defined in, and exported from, GHC.Prim.@@ -201,27 +295,13 @@ , stackSnapshotPrimTyCon , promptTagPrimTyCon + , fUNTyCon , tYPETyCon- , funTyCon+ , cONSTRAINTTyCon #include "primop-vector-tycons.hs-incl" ] -mkPrimTc :: FastString -> Unique -> TyCon -> Name-mkPrimTc fs unique tycon- = mkWiredInName gHC_PRIM (mkTcOccFS fs)- unique- (mkATyCon tycon) -- Relevant TyCon- UserSyntax--mkBuiltInPrimTc :: FastString -> Unique -> TyCon -> Name-mkBuiltInPrimTc fs unique tycon- = mkWiredInName gHC_PRIM (mkTcOccFS fs)- unique- (mkATyCon tycon) -- Relevant TyCon- BuiltInSyntax-- charPrimTyConName, intPrimTyConName, int8PrimTyConName, int16PrimTyConName, int32PrimTyConName, int64PrimTyConName, wordPrimTyConName, word32PrimTyConName, word8PrimTyConName, word16PrimTyConName, word64PrimTyConName, addrPrimTyConName, floatPrimTyConName, doublePrimTyConName,@@ -279,13 +359,13 @@ threadIdPrimTyConName = mkPrimTc (fsLit "ThreadId#") threadIdPrimTyConKey threadIdPrimTyCon promptTagPrimTyConName = mkPrimTc (fsLit "PromptTag#") promptTagPrimTyConKey promptTagPrimTyCon -{--************************************************************************+{- ********************************************************************* * *-\subsection{Support code}+ Type variables * *-************************************************************************+********************************************************************* -} +{- alphaTyVars is a list of type variables for use in templates: ["a", "b", ..., "z", "t1", "t2", ... ] -}@@ -372,13 +452,16 @@ mkTemplateKindTyConBinders :: [Kind] -> [TyConBinder] -- Makes named, Specified binders-mkTemplateKindTyConBinders kinds = [mkNamedTyConBinder Specified tv | tv <- mkTemplateKindVars kinds]+mkTemplateKindTyConBinders kinds+ = [mkNamedTyConBinder Specified tv | tv <- mkTemplateKindVars kinds] mkTemplateAnonTyConBinders :: [Kind] -> [TyConBinder]-mkTemplateAnonTyConBinders kinds = mkAnonTyConBinders VisArg (mkTemplateTyVars kinds)+mkTemplateAnonTyConBinders kinds+ = mkAnonTyConBinders (mkTemplateTyVars kinds) mkTemplateAnonTyConBindersFrom :: Int -> [Kind] -> [TyConBinder]-mkTemplateAnonTyConBindersFrom n kinds = mkAnonTyConBinders VisArg (mkTemplateTyVarsFrom n kinds)+mkTemplateAnonTyConBindersFrom n kinds+ = mkAnonTyConBinders (mkTemplateTyVarsFrom n kinds) alphaTyVars :: [TyVar] alphaTyVars = mkTemplateTyVars $ repeat liftedTypeKind@@ -389,6 +472,15 @@ alphaTyVarSpec, betaTyVarSpec, gammaTyVarSpec, deltaTyVarSpec :: TyVarBinder (alphaTyVarSpec:betaTyVarSpec:gammaTyVarSpec:deltaTyVarSpec:_) = mkTyVarBinders Specified alphaTyVars +alphaConstraintTyVars :: [TyVar]+alphaConstraintTyVars = mkTemplateTyVars $ repeat constraintKind++alphaConstraintTyVar :: TyVar+(alphaConstraintTyVar:_) = alphaConstraintTyVars++alphaConstraintTy :: Type+alphaConstraintTy = mkTyVarTy alphaConstraintTyVar+ alphaTys :: [Type] alphaTys = mkTyVarTys alphaTyVars alphaTy, betaTy, gammaTy, deltaTy :: Type@@ -422,7 +514,9 @@ -- beta :: TYPE r2 -- gamma :: TYPE r3 [openAlphaTyVar,openBetaTyVar,openGammaTyVar]- = mkTemplateTyVars [mkTYPEapp runtimeRep1Ty, mkTYPEapp runtimeRep2Ty, mkTYPEapp runtimeRep3Ty]+ = mkTemplateTyVars [ mk_TYPE_app runtimeRep1Ty+ , mk_TYPE_app runtimeRep2Ty+ , mk_TYPE_app runtimeRep3Ty] openAlphaTyVarSpec, openBetaTyVarSpec, openGammaTyVarSpec :: TyVarBinder openAlphaTyVarSpec = mkTyVarBinder Specified openAlphaTyVar@@ -451,8 +545,8 @@ levPolyAlphaTyVar, levPolyBetaTyVar :: TyVar [levPolyAlphaTyVar, levPolyBetaTyVar] = mkTemplateTyVars- [mkTYPEapp (mkTyConApp boxedRepDataConTyCon [levity1Ty])- ,mkTYPEapp (mkTyConApp boxedRepDataConTyCon [levity2Ty])]+ [ mk_TYPE_app (mkTyConApp boxedRepDataConTyCon [levity1Ty])+ , mk_TYPE_app (mkTyConApp boxedRepDataConTyCon [levity2Ty])] -- alpha :: TYPE ('BoxedRep l) -- beta :: TYPE ('BoxedRep k) @@ -477,80 +571,280 @@ ************************************************************************ -} -funTyConName :: Name-funTyConName = mkPrimTcName UserSyntax (fsLit "FUN") funTyConKey funTyCon+{- Note [Function type constructors and FunTy]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We have four distinct function type constructors, and a type synonym + FUN :: forall (m :: Multiplicity) ->+ forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.+ TYPE rep1 -> TYPE rep2 -> Type++ (=>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.+ CONSTRAINT rep1 -> TYPE rep2 -> Type++ (==>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.+ CONSTRAINT rep1 -> CONSTRAINT rep2 -> Constraint++ (-=>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.+ TYPE rep1 -> CONSTRAINT rep2 -> Constraint++ type (->) = FUN Many++For efficiency, all four are always represented by+ FunTy { ft_af :: FunTyFlag, ft_mult :: Mult+ , ft_arg :: Type, ft_res :: Type }+rather than by using a TyConApp.++* The four TyCons FUN, (=>), (==>), (-=>) are all wired in.+ But (->) is just a regular synonym, with no special treatment;+ in particular it is not wired-in.++* The ft_af :: FunTyFlag distinguishes the four cases.+ See Note [FunTyFlag] in GHC.Types.Var.++* The ft_af field is redundant: it can always be gleaned from+ the kinds of ft_arg and ft_res. See Note [FunTyFlag] in GHC.Types.Var.++* The ft_mult :: Mult field gives the first argument for FUN+ For the other three cases ft_mult is redundant; it is always Many.+ Note that of the four type constructors, only `FUN` takes a Multiplicity.++* Functions in GHC.Core.Type help to build and decompose `FunTy`.+ * funTyConAppTy_maybe+ * funTyFlagTyCon+ * tyConAppFun_maybe+ * splitFunTy_maybe+ Use them!+-}++funTyFlagTyCon :: FunTyFlag -> TyCon+-- `anonArgTyCon af` gets the TyCon that corresponds to the `FunTyFlag`+-- But be careful: fUNTyCon has a different kind to the others!+-- See Note [Function type constructors and FunTy]+funTyFlagTyCon FTF_T_T = fUNTyCon+funTyFlagTyCon FTF_T_C = tcArrowTyCon+funTyFlagTyCon FTF_C_T = ctArrowTyCon+funTyFlagTyCon FTF_C_C = ccArrowTyCon++isArrowTyCon :: TyCon -> Bool+-- We don't bother to look for plain (->), because this function+-- should only be used after unwrapping synonyms+isArrowTyCon tc+ = assertPpr (not (isTypeSynonymTyCon tc)) (ppr tc)+ getUnique tc `elem`+ [fUNTyConKey, ctArrowTyConKey, ccArrowTyConKey, tcArrowTyConKey]++fUNTyConName, ctArrowTyConName, ccArrowTyConName, tcArrowTyConName :: Name+fUNTyConName = mkPrimTc (fsLit "FUN") fUNTyConKey fUNTyCon+ctArrowTyConName = mkBuiltInPrimTc (fsLit "=>") ctArrowTyConKey ctArrowTyCon+ccArrowTyConName = mkBuiltInPrimTc (fsLit "==>") ccArrowTyConKey ccArrowTyCon+tcArrowTyConName = mkBuiltInPrimTc (fsLit "-=>") tcArrowTyConKey tcArrowTyCon+ -- | The @FUN@ type constructor. -- -- @ -- FUN :: forall (m :: Multiplicity) -> -- forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.--- TYPE rep1 -> TYPE rep2 -> *+-- TYPE rep1 -> TYPE rep2 -> Type -- @ -- -- The runtime representations quantification is left inferred. This -- means they cannot be specified with @-XTypeApplications@. -- -- This is a deliberate choice to allow future extensions to the--- function arrow. To allow visible application a type synonym can be--- defined:------ @--- type Arr :: forall (rep1 :: RuntimeRep) (rep2 :: RuntimeRep).--- TYPE rep1 -> TYPE rep2 -> Type--- type Arr = FUN 'Many--- @----funTyCon :: TyCon-funTyCon = mkFunTyCon funTyConName tc_bndrs tc_rep_nm+-- function arrow.+fUNTyCon :: TyCon+fUNTyCon = mkPrimTyCon fUNTyConName tc_bndrs liftedTypeKind tc_roles where -- See also unrestrictedFunTyCon tc_bndrs = [ mkNamedTyConBinder Required multiplicityTyVar1 , mkNamedTyConBinder Inferred runtimeRep1TyVar , mkNamedTyConBinder Inferred runtimeRep2TyVar ]- ++ mkTemplateAnonTyConBinders [ mkTYPEapp runtimeRep1Ty- , mkTYPEapp runtimeRep2Ty- ]- tc_rep_nm = mkPrelTyConRepName funTyConName+ ++ mkTemplateAnonTyConBinders [ mk_TYPE_app runtimeRep1Ty+ , mk_TYPE_app runtimeRep2Ty ]+ tc_roles = [Nominal, Nominal, Nominal, Representational, Representational] +-- (=>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.+-- CONSTRAINT rep1 -> TYPE rep2 -> Type+ctArrowTyCon :: TyCon+ctArrowTyCon = mkPrimTyCon ctArrowTyConName tc_bndrs liftedTypeKind tc_roles+ where+ -- See also unrestrictedFunTyCon+ tc_bndrs = [ mkNamedTyConBinder Inferred runtimeRep1TyVar+ , mkNamedTyConBinder Inferred runtimeRep2TyVar ]+ ++ mkTemplateAnonTyConBinders [ mk_CONSTRAINT_app runtimeRep1Ty+ , mk_TYPE_app runtimeRep2Ty ]+ tc_roles = [Nominal, Nominal, Representational, Representational]++-- (==>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.+-- CONSTRAINT rep1 -> CONSTRAINT rep2 -> Constraint+ccArrowTyCon :: TyCon+ccArrowTyCon = mkPrimTyCon ccArrowTyConName tc_bndrs constraintKind tc_roles+ where+ -- See also unrestrictedFunTyCon+ tc_bndrs = [ mkNamedTyConBinder Inferred runtimeRep1TyVar+ , mkNamedTyConBinder Inferred runtimeRep2TyVar ]+ ++ mkTemplateAnonTyConBinders [ mk_CONSTRAINT_app runtimeRep1Ty+ , mk_CONSTRAINT_app runtimeRep2Ty ]+ tc_roles = [Nominal, Nominal, Representational, Representational]++-- (-=>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.+-- TYPE rep1 -> CONSTRAINT rep2 -> Constraint+tcArrowTyCon :: TyCon+tcArrowTyCon = mkPrimTyCon tcArrowTyConName tc_bndrs constraintKind tc_roles+ where+ -- See also unrestrictedFunTyCon+ tc_bndrs = [ mkNamedTyConBinder Inferred runtimeRep1TyVar+ , mkNamedTyConBinder Inferred runtimeRep2TyVar ]+ ++ mkTemplateAnonTyConBinders [ mk_TYPE_app runtimeRep1Ty+ , mk_CONSTRAINT_app runtimeRep2Ty ]+ tc_roles = [Nominal, Nominal, Representational, Representational]+ {- ************************************************************************ * *- Kinds+ Type and Constraint * * ************************************************************************ -Note [TYPE and RuntimeRep]+Note [TYPE and CONSTRAINT] aka Note [Type vs Constraint] ~~~~~~~~~~~~~~~~~~~~~~~~~~-All types that classify values have a kind of the form (TYPE rr), where+GHC distinguishes Type from Constraint throughout the compiler.+See GHC Proposal #518, and tickets #21623 and #11715. - data RuntimeRep -- Defined in ghc-prim:GHC.Types+All types that classify values have a kind of the form+ (TYPE rr) or (CONSTRAINT rr)+where the `RuntimeRep` parameter, rr, tells us how the value is represented+at runtime. TYPE and CONSTRAINT are primitive type constructors.++See Note [RuntimeRep polymorphism] about the `rr` parameter.++There are a bunch of type synonyms and data types defined in the+library ghc-prim:GHC.Types. All of them are also wired in to GHC, in+GHC.Builtin.Types++ type Constraint = CONSTRAINT LiftedRep :: Type++ type Type = TYPE LiftedRep :: Type+ type UnliftedType = TYPE UnliftedRep :: Type++ type LiftedRep = BoxedRep Lifted :: RuntimeRep+ type UnliftedRep = BoxedRep Unlifted :: RuntimeRep++ data RuntimeRep -- Defined in ghc-prim:GHC.Types = BoxedRep Levity | IntRep | FloatRep .. etc .. - data Levity = Lifted | Unlifted-- rr :: RuntimeRep+ data Levity = Lifted | Unlifted - TYPE :: RuntimeRep -> TYPE 'LiftedRep -- Built in+We abbreviate '*' specially (with -XStarIsType), as if we had this:+ type * = Type So for example:- Int :: TYPE ('BoxedRep 'Lifted)- Array# Int :: TYPE ('BoxedRep 'Unlifted)- Int# :: TYPE 'IntRep- Float# :: TYPE 'FloatRep- Maybe :: TYPE ('BoxedRep 'Lifted) -> TYPE ('BoxedRep 'Lifted)+ Int :: TYPE (BoxedRep Lifted)+ Array# Int :: TYPE (BoxedRep Unlifted)+ Int# :: TYPE IntRep+ Float# :: TYPE FloatRep+ Maybe :: TYPE (BoxedRep Lifted) -> TYPE (BoxedRep Lifted) (# , #) :: TYPE r1 -> TYPE r2 -> TYPE (TupleRep [r1, r2]) -We abbreviate '*' specially:- type LiftedRep = 'BoxedRep 'Lifted- type * = TYPE LiftedRep+ Eq Int :: CONSTRAINT (BoxedRep Lifted)+ IP "foo" Int :: CONSTRAINT (BoxedRep Lifted)+ a ~ b :: CONSTRAINT (BoxedRep Lifted)+ a ~# b :: CONSTRAINT (TupleRep []) -The 'rr' parameter tells us how the value is represented at runtime.+Constraints are mostly lifted, but unlifted ones are useful too.+Specifically (a ~# b) :: CONSTRAINT (TupleRep []) -Generally speaking, you can't be polymorphic in 'rr'. E.g+Wrinkles++(W1) Type and Constraint are considered distinct throughout GHC. But they+ are not /apart/: see Note [Type and Constraint are not apart]++(W2) We need two absent-error Ids, aBSENT_ERROR_ID for types of kind Type, and+ aBSENT_CONSTRAINT_ERROR_ID for vaues of kind Constraint. Ditto noInlineId+ vs noInlieConstraintId in GHC.Types.Id.Make; see Note [inlineId magic].++(W3) We need a TypeOrConstraint flag in LitRubbish.++Note [Type and Constraint are not apart]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Type and Constraint are not equal (eqType) but they are not /apart/+either. Reason (c.f. #7451):++* We want to allow newtype classes, where+ class C a where { op :: a -> a }++* The axiom for such a class will look like+ axiom axC a :: (C a :: Constraint) ~# (a->a :: Type)++* This axiom connects a type of kind Type with one of kind Constraint+ That is dangerous: kindCo (axC Int) :: Type ~N Constraint+ And /that/ is bad because we could have+ type family F a where+ F Type = Int+ F Constraint = Bool+ So now we can prove Int ~N Bool, and all is lost. We prevent this+ by saying that Type and Constraint are not Apart, which makes the+ above type family instances illegal.++So we ensure that Type and Constraint are not apart; or, more+precisely, that TYPE and CONSTRAINT are not apart. This+non-apart-ness check is implemented in GHC.Core.Unify.unify_ty: look+for `maybeApart MARTypeVsConstraint`.++Note that, as before, nothing prevents writing instances like:++ instance C (Proxy @Type a) where ...++In particular, TYPE and CONSTRAINT (and the synonyms Type, Constraint+etc) are all allowed in instance heads. It's just that TYPE is not+apart from CONSTRAINT, which means that the above instance would+irretrievably overlap with:++ instance C (Proxy @Constraint a) where ...++Wrinkles++(W1) In GHC.Core.RoughMap.roughMtchTyConName we are careful to map+ TYPE and CONSTRAINT to the same rough-map key. Reason:+ If we insert (F @Constraint tys) into a FamInstEnv, and look+ up (F @Type tys'), we /must/ ensure that the (C @Constraint tys)+ appears among the unifiables when we do the lookupRM' in+ GHC.Core.FamInstEnv.lookup_fam_inst_env'. So for the RoughMap we+ simply pretend that they are the same type constructor. If we+ don't, we'll treat them as fully apart, which is unsound.++(W2) We must extend this treatment to the different arrow types (see+ Note [Function type constructors and FunTy]): if we have+ FunCo (axC Int) <Int> :: (C Int => Int) ~ ((Int -> Int) -> Int),+ then we could extract an equality between (=>) and (->). We thus+ must ensure that (=>) and (->) (among the other arrow combinations)+ are not Apart. See the FunTy/FunTy case in GHC.Core.Unify.unify_ty.++(W3) Are (TYPE IntRep) and (CONSTRAINT WordRep) apart? In truth yes,+ they are. But it's easier to say that htey are not apart, by+ reporting "maybeApart" (which is always safe), rather than+ recurse into the arguments (whose kinds may be utterly different)+ to look for apartness inside them. Again this is in+ GHC.Core.Unify.unify_ty.++(W4) We give a different Typeable instance for Type than for Constraint.+ For type classes instances (unlike type family instances) it is not+ /unsound/ for Type and Constraint to treated as fully distinct; and+ for Typeable is desirable to give them different TypeReps.+ Certainly,+ - both Type and Constraint must /have/ a TypeRep, and+ - they had better not be the same (else eqTypeRep would give us+ a proof Type ~N Constraint, which we do not want+ So in GHC.Tc.Instance.Class.matchTypeable, Type and Constraint are+ treated as separate TyCons; i.e. given no special treatment.++Note [RuntimeRep polymorphism]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Generally speaking, you can't be polymorphic in `RuntimeRep`. E.g f :: forall (rr:RuntimeRep) (a:TYPE rr). a -> [a] f = /\(rr:RuntimeRep) (a:rr) \(a:rr). ... This is no good: we could not generate code for 'f', because the@@ -575,85 +869,40 @@ (#,#) :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep) (a :: TYPE r1) (b :: TYPE r2). a -> b -> TYPE ('TupleRep '[r1, r2])- -} +---------------------- tYPETyCon :: TyCon-tYPETyConName :: Name- tYPETyCon = mkPrimTyCon tYPETyConName (mkTemplateAnonTyConBinders [runtimeRepTy]) liftedTypeKind [Nominal] ------------------------------ ... and now their names+tYPETyConName :: Name+tYPETyConName = mkPrimTc (fsLit "TYPE") tYPETyConKey tYPETyCon --- If you edit these, you may need to update the GHC formalism--- See Note [GHC Formalism] in GHC.Core.Lint-tYPETyConName = mkPrimTcName UserSyntax (fsLit "TYPE") tYPETyConKey tYPETyCon+tYPEKind :: Type+tYPEKind = mkTyConTy tYPETyCon -mkPrimTcName :: BuiltInSyntax -> FastString -> Unique -> TyCon -> Name-mkPrimTcName built_in_syntax occ key tycon- = mkWiredInName gHC_PRIM (mkTcOccFS occ) key (mkATyCon tycon) built_in_syntax+----------------------+cONSTRAINTTyCon :: TyCon+cONSTRAINTTyCon = mkPrimTyCon cONSTRAINTTyConName+ (mkTemplateAnonTyConBinders [runtimeRepTy])+ liftedTypeKind+ [Nominal] ------------------------------+cONSTRAINTTyConName :: Name+cONSTRAINTTyConName = mkPrimTc (fsLit "CONSTRAINT") cONSTRAINTTyConKey cONSTRAINTTyCon --- Given a Multiplicity, applies FUN to it.-functionWithMultiplicity :: Type -> Type-functionWithMultiplicity mul = TyConApp funTyCon [mul]+cONSTRAINTKind :: Type+cONSTRAINTKind = mkTyConTy cONSTRAINTTyCon -{--************************************************************************++{- ********************************************************************* * *- Basic primitive types (@Char#@, @Int#@, etc.)+ Basic primitive types (Char#, Int#, etc.) * *-************************************************************************--}---- | Create a primitive 'TyCon' with the given 'Name',--- arguments of kind 'Type` with the given 'Role's,--- and the given result kind representation.------ Only use this in "GHC.Builtin.Types.Prim".-pcPrimTyCon :: Name- -> [Role] -> RuntimeRepType -> TyCon-pcPrimTyCon name roles res_rep- = mkPrimTyCon name binders result_kind roles- where- bndr_kis = liftedTypeKind <$ roles- binders = mkTemplateAnonTyConBinders bndr_kis- result_kind = mkTYPEapp res_rep---- | Create a primitive nullary 'TyCon' with the given 'Name'--- and result kind representation.------ Only use this in "GHC.Builtin.Types.Prim".-pcPrimTyCon0 :: Name -> RuntimeRepType -> TyCon-pcPrimTyCon0 name res_rep- = pcPrimTyCon name [] res_rep---- | Create a primitive 'TyCon' like 'pcPrimTyCon', except the last--- argument is levity-polymorphic.------ Only use this in "GHC.Builtin.Types.Prim".-pcPrimTyCon_LevPolyLastArg :: Name- -> [Role] -- ^ roles of the arguments (must be non-empty),- -- not including the implicit argument of kind 'Levity',- -- which always has 'Nominal' role- -> RuntimeRepType -- ^ representation of the fully-applied type- -> TyCon-pcPrimTyCon_LevPolyLastArg name roles res_rep- = mkPrimTyCon name binders result_kind (Nominal : roles)- where- result_kind = mkTYPEapp res_rep- lev_bndr = mkNamedTyConBinder Inferred levity1TyVar- binders = lev_bndr : mkTemplateAnonTyConBinders anon_bndr_kis- lev_tv = mkTyVarTy (binderVar lev_bndr)-- -- [ Type, ..., Type, TYPE (BoxedRep l) ]- anon_bndr_kis = changeLast (liftedTypeKind <$ roles)- (mkTYPEapp $ mkTyConApp boxedRepDataConTyCon [lev_tv])+********************************************************************* -} charPrimTy :: Type charPrimTy = mkTyConTy charPrimTyCon@@ -824,6 +1073,8 @@ * In addition (~) is magical syntax, as ~ is a reserved symbol. It cannot be exported or imported. + * The data constructor of the class is "Eq#", not ":C~"+ Within GHC, ~ is called eqTyCon, and it is defined in GHC.Builtin.Types. Historical note: prior to July 18 (~) was defined as a@@ -950,9 +1201,9 @@ -- See Note [The equality types story] eqPrimTyCon = mkPrimTyCon eqPrimTyConName binders res_kind roles where- -- Kind :: forall k1 k2. k1 -> k2 -> TYPE (TupleRep '[])+ -- Kind :: forall k1 k2. k1 -> k2 -> CONSTRAINT ZeroBitRep binders = mkTemplateTyConBinders [liftedTypeKind, liftedTypeKind] id- res_kind = unboxedTupleKind []+ res_kind = TyConApp cONSTRAINTTyCon [zeroBitRepTy] roles = [Nominal, Nominal, Nominal, Nominal] -- like eqPrimTyCon, but the type for *Representational* coercions@@ -961,9 +1212,9 @@ eqReprPrimTyCon :: TyCon -- See Note [The equality types story] eqReprPrimTyCon = mkPrimTyCon eqReprPrimTyConName binders res_kind roles where- -- Kind :: forall k1 k2. k1 -> k2 -> TYPE (TupleRep '[])+ -- Kind :: forall k1 k2. k1 -> k2 -> CONSTRAINT ZeroBitRep binders = mkTemplateTyConBinders [liftedTypeKind, liftedTypeKind] id- res_kind = unboxedTupleKind []+ res_kind = TyConApp cONSTRAINTTyCon [zeroBitRepTy] roles = [Nominal, Nominal, Representational, Representational] -- like eqPrimTyCon, but the type for *Phantom* coercions.@@ -972,9 +1223,9 @@ eqPhantPrimTyCon :: TyCon eqPhantPrimTyCon = mkPrimTyCon eqPhantPrimTyConName binders res_kind roles where- -- Kind :: forall k1 k2. k1 -> k2 -> TYPE (TupleRep '[])+ -- Kind :: forall k1 k2. k1 -> k2 -> CONSTRAINT ZeroBitRep binders = mkTemplateTyConBinders [liftedTypeKind, liftedTypeKind] id- res_kind = unboxedTupleKind []+ res_kind = TyConApp cONSTRAINTTyCon [zeroBitRepTy] roles = [Nominal, Nominal, Phantom, Phantom] -- | Given a Role, what TyCon is the type of equality predicates at that role?
− compiler/GHC/Builtin/Types/Prim.hs-boot
@@ -1,5 +0,0 @@-module GHC.Builtin.Types.Prim where--import GHC.Core.TyCon--tYPETyCon :: TyCon
compiler/GHC/Builtin/Uniques.hs view
@@ -13,8 +13,8 @@ -- * Getting the 'Unique's of 'Name's -- ** Anonymous sums- , mkSumTyConUnique- , mkSumDataConUnique+ , mkSumTyConUnique, mkSumDataConUnique+ -- ** Tuples -- *** Vanilla , mkTupleTyConUnique@@ -45,6 +45,9 @@ , initExitJoinUnique + -- Boxing data types+ , mkBoxingTyConUnique, boxingDataConUnique+ ) where import GHC.Prelude@@ -60,7 +63,6 @@ import GHC.Utils.Outputable import GHC.Utils.Panic-import GHC.Utils.Panic.Plain import Data.Maybe @@ -107,8 +109,9 @@ mkSumTyConUnique :: Arity -> Unique mkSumTyConUnique arity =- assert (arity < 0x3f) $ -- 0x3f since we only have 6 bits to encode the- -- alternative+ assertPpr (arity <= 0x3f) (ppr arity) $+ -- 0x3f since we only have 6 bits to encode the+ -- alternative mkUnique 'z' (arity `shiftL` 8 .|. 0xfc) mkSumDataConUnique :: ConTagZ -> Arity -> Unique@@ -297,6 +300,7 @@ other a-z: lower case chars for unique supplies. Used so far: a TypeChecking?+ b Boxing tycons & datacons c StgToCmm/Renamer d desugarer f AbsC flattener@@ -310,6 +314,27 @@ u Cmm pipeline y GHCi bytecode generator z anonymous sums++Note [Related uniques for wired-in things]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+* All wired in tycons actually use *two* uniques:+ * u: the TyCon itself+ * u+1: the TyConRepName of the TyCon (for use with TypeRep)+ The "+1" is implemented in tyConRepNameUnique.+ If this ever changes, make sure to also change the treatment for boxing tycons.++* All wired in datacons use *three* uniques:+ * u: the DataCon itself+ * u+1: its worker Id+ * u+2: the TyConRepName of the promoted TyCon+ No wired-in datacons have wrappers.+ The "+1" is implemented in dataConWorkerUnique and the "+2" is in dataConTyRepNameUnique.+ If this ever changes, make sure to also change the treatment for boxing tycons.++* Because boxing tycons (see Note [Boxing constructors] in GHC.Builtin.Types)+ come with both a tycon and a datacon, each one takes up five slots, combining+ the two cases above. Getting from the tycon to the datacon (by adding 2)+ is implemented in boxingDataConUnique. -} mkAlphaTyVarUnique :: Int -> Unique@@ -351,29 +376,48 @@ initExitJoinUnique :: Unique initExitJoinUnique = mkUnique 's' 0 - -------------------------------------------------- -- Wired-in type constructor keys occupy *two* slots:--- * u: the TyCon itself--- * u+1: the TyConRepName of the TyCon+-- See Note [Related uniques for wired-in things] mkPreludeTyConUnique :: Int -> Unique-mkPreludeTyConUnique i = mkUnique '3' (2*i)+mkPreludeTyConUnique i = mkUnique '3' (2*i) tyConRepNameUnique :: Unique -> Unique tyConRepNameUnique u = incrUnique u -------------------------------------------------- -- Wired-in data constructor keys occupy *three* slots:--- * u: the DataCon itself--- * u+1: its worker Id--- * u+2: the TyConRepName of the promoted TyCon--- Prelude data constructors are too simple to need wrappers.+-- See Note [Related uniques for wired-in things] mkPreludeDataConUnique :: Int -> Unique-mkPreludeDataConUnique i = mkUnique '6' (3*i) -- Must be alphabetic+mkPreludeDataConUnique i = mkUnique '6' (3*i) -- Must be alphabetic --------------------------------------------------- dataConTyRepNameUnique, dataConWorkerUnique :: Unique -> Unique dataConWorkerUnique u = incrUnique u dataConTyRepNameUnique u = stepUnique u 2++--------------------------------------------------+-- The data constructors of RuntimeRep occupy *five* slots:+-- See Note [Related uniques for wired-in things]+--+-- Example: WordRep+--+-- * u: the TyCon of the boxing data type WordBox+-- * u+1: the TyConRepName of the boxing data type+-- * u+2: the DataCon for MkWordBox+-- * u+3: the worker id for MkWordBox+-- * u+4: the TyConRepName of the promoted TyCon 'MkWordBox+--+-- Note carefully that+-- * u,u+1 are in sync with the conventions for+-- wired-in type constructors, above+-- * u+2,u+3,u+4 are in sync with the conventions for+-- wired-in data constructors, above+-- A little delicate!++mkBoxingTyConUnique :: Int -> Unique+mkBoxingTyConUnique i = mkUnique 'b' (5*i)++boxingDataConUnique :: Unique -> Unique+boxingDataConUnique u = stepUnique u 2
compiler/GHC/ByteCode/Types.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TypeApplications #-} -- -- (c) The University of Glasgow 2002-2006 --@@ -115,7 +116,7 @@ ppr TupleInfo{..} = text "<size" <+> ppr tupleSize <+> text "stack" <+> ppr tupleNativeStackSize <+> text "regs" <+>- ppr (map (text.show) $ regSetToList tupleRegs) <>+ ppr (map (text @SDoc . show) $ regSetToList tupleRegs) <> char '>' voidTupleInfo :: TupleInfo
compiler/GHC/Cmm.hs view
@@ -282,8 +282,8 @@ -- ^ uninitialised data, N bytes long | CmmString ByteString -- ^ string of 8-bit values only, not zero terminated.- | CmmFileEmbed FilePath- -- ^ an embedded binary file+ | CmmFileEmbed FilePath Int+ -- ^ an embedded binary file and its byte length instance OutputableP Platform CmmStatic where pdoc = pprStatic@@ -292,7 +292,7 @@ ppr (CmmStaticLit lit) = text "CmmStaticLit" <+> ppr lit ppr (CmmUninitialised n) = text "CmmUninitialised" <+> ppr n ppr (CmmString _) = text "CmmString"- ppr (CmmFileEmbed fp) = text "CmmFileEmbed" <+> text fp+ ppr (CmmFileEmbed fp _) = text "CmmFileEmbed" <+> text fp -- Static data before SRT generation data GenCmmStatics (rawOnly :: Bool) where@@ -444,7 +444,7 @@ CmmStaticLit lit -> nest 4 $ text "const" <+> pdoc platform lit <> semi CmmUninitialised i -> nest 4 $ text "I8" <> brackets (int i) CmmString s' -> nest 4 $ text "I8[]" <+> text (show s')- CmmFileEmbed path -> nest 4 $ text "incbin " <+> text (show path)+ CmmFileEmbed path _ -> nest 4 $ text "incbin " <+> text (show path) -- -------------------------------------------------------------------------- -- data sections
compiler/GHC/Cmm/BlockId.hs view
@@ -11,6 +11,7 @@ import GHC.Prelude import GHC.Cmm.CLabel+import GHC.Data.FastString import GHC.Types.Id.Info import GHC.Types.Name import GHC.Types.Unique@@ -43,4 +44,4 @@ infoTblLbl :: BlockId -> CLabel infoTblLbl label- = mkBlockInfoTableLabel (mkFCallName (getUnique label) "block") NoCafRefs+ = mkBlockInfoTableLabel (mkFCallName (getUnique label) (fsLit "block")) NoCafRefs
compiler/GHC/Cmm/CLabel.hs view
@@ -300,19 +300,21 @@ show = showPprUnsafe . pprDebugCLabel genericPlatform data ModuleLabelKind- = MLK_Initializer String+ = MLK_Initializer LexicalFastString | MLK_InitializerArray- | MLK_Finalizer String+ | MLK_Finalizer LexicalFastString | MLK_FinalizerArray | MLK_IPEBuffer deriving (Eq, Ord) -instance Outputable ModuleLabelKind where- ppr MLK_InitializerArray = text "init_arr"- ppr (MLK_Initializer s) = text ("init__" ++ s)- ppr MLK_FinalizerArray = text "fini_arr"- ppr (MLK_Finalizer s) = text ("fini__" ++ s)- ppr MLK_IPEBuffer = text "ipe_buf"+pprModuleLabelKind :: IsLine doc => ModuleLabelKind -> doc+pprModuleLabelKind MLK_InitializerArray = text "init_arr"+pprModuleLabelKind (MLK_Initializer (LexicalFastString s)) = text "init__" <> ftext s+pprModuleLabelKind MLK_FinalizerArray = text "fini_arr"+pprModuleLabelKind (MLK_Finalizer (LexicalFastString s)) = text "fini__" <> ftext s+pprModuleLabelKind MLK_IPEBuffer = text "ipe_buf"+{-# SPECIALIZE pprModuleLabelKind :: ModuleLabelKind -> SDoc #-}+{-# SPECIALIZE pprModuleLabelKind :: ModuleLabelKind -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable isIdLabel :: CLabel -> Bool isIdLabel IdLabel{} = True@@ -885,15 +887,15 @@ mkStringLitLabel :: Unique -> CLabel mkStringLitLabel = StringLitLabel -mkInitializerStubLabel :: Module -> String -> CLabel-mkInitializerStubLabel mod s = ModuleLabel mod (MLK_Initializer s)+mkInitializerStubLabel :: Module -> FastString -> CLabel+mkInitializerStubLabel mod s = ModuleLabel mod (MLK_Initializer (LexicalFastString s)) mkInitializerArrayLabel :: Module -> CLabel mkInitializerArrayLabel mod = ModuleLabel mod MLK_InitializerArray -mkFinalizerStubLabel :: Module -> String -> CLabel-mkFinalizerStubLabel mod s = ModuleLabel mod (MLK_Finalizer s)+mkFinalizerStubLabel :: Module -> FastString -> CLabel+mkFinalizerStubLabel mod s = ModuleLabel mod (MLK_Finalizer (LexicalFastString s)) mkFinalizerArrayLabel :: Module -> CLabel mkFinalizerArrayLabel mod = ModuleLabel mod MLK_FinalizerArray@@ -1204,12 +1206,15 @@ labelType (CmmLabel _ _ _ CmmRetInfo) = DataLabel labelType (CmmLabel _ _ _ CmmRet) = CodeLabel labelType (RtsLabel (RtsSelectorInfoTable _ _)) = DataLabel+labelType (RtsLabel (RtsSelectorEntry _ _)) = CodeLabel labelType (RtsLabel (RtsApInfoTable _ _)) = DataLabel+labelType (RtsLabel (RtsApEntry _ _)) = CodeLabel labelType (RtsLabel (RtsApFast _)) = CodeLabel-labelType (RtsLabel RtsUnpackCStringInfoTable) = CodeLabel+labelType (RtsLabel RtsUnpackCStringInfoTable) = DataLabel labelType (RtsLabel RtsUnpackCStringUtf8InfoTable)- = CodeLabel-labelType (RtsLabel _) = DataLabel+ = DataLabel+labelType (RtsLabel (RtsPrimOp _)) = CodeLabel+labelType (RtsLabel (RtsSlowFastTickyCtr _)) = DataLabel labelType (LocalBlockLabel _) = CodeLabel labelType (SRTLabel _) = DataLabel labelType (ForeignLabel _ _ _ IsFunction) = CodeLabel@@ -1428,32 +1433,37 @@ = CStyle -- ^ C label style (used by C and LLVM backends) | AsmStyle -- ^ Asm label style (used by NCG backend) -pprAsmLabel :: Platform -> CLabel -> SDoc+pprAsmLabel :: IsLine doc => Platform -> CLabel -> doc pprAsmLabel platform lbl = pprCLabelStyle platform AsmStyle lbl+{-# SPECIALIZE pprAsmLabel :: Platform -> CLabel -> SDoc #-}+{-# SPECIALIZE pprAsmLabel :: Platform -> CLabel -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -pprCLabel :: Platform -> CLabel -> SDoc+pprCLabel :: IsLine doc => Platform -> CLabel -> doc pprCLabel platform lbl = pprCLabelStyle platform CStyle lbl+{-# SPECIALIZE pprCLabel :: Platform -> CLabel -> SDoc #-}+{-# SPECIALIZE pprCLabel :: Platform -> CLabel -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable instance OutputableP Platform CLabel where {-# INLINE pdoc #-} -- see Note [Bangs in CLabel] pdoc !platform lbl = getPprStyle $ \pp_sty -> case pp_sty of PprDump{} -> pprCLabel platform lbl- _ -> pprPanic "Labels in code should be printed with pprCLabel or pprAsmLabel" (pprCLabel platform lbl)+ _ -> let lbl_doc = (pprCLabel platform lbl)+ in pprTraceUserWarning (text "Labels in code should be printed with pprCLabel or pprAsmLabel" <> lbl_doc) lbl_doc -pprCLabelStyle :: Platform -> LabelStyle -> CLabel -> SDoc+pprCLabelStyle :: forall doc. IsLine doc => Platform -> LabelStyle -> CLabel -> doc pprCLabelStyle !platform !sty lbl = -- see Note [Bangs in CLabel] let !use_leading_underscores = platformLeadingUnderscore platform -- some platform (e.g. Darwin) require a leading "_" for exported asm -- symbols- maybe_underscore :: SDoc -> SDoc+ maybe_underscore :: doc -> doc maybe_underscore doc = case sty of AsmStyle | use_leading_underscores -> pp_cSEP <> doc _ -> doc - tempLabelPrefixOrUnderscore :: SDoc+ tempLabelPrefixOrUnderscore :: doc tempLabelPrefixOrUnderscore = case sty of AsmStyle -> asmTempLabelPrefix platform CStyle -> char '_'@@ -1505,14 +1515,14 @@ IdLabel name _cafs flavor -> case sty of- AsmStyle -> maybe_underscore $ internalNamePrefix <> ppr name <> ppIdFlavor flavor+ AsmStyle -> maybe_underscore $ internalNamePrefix <> pprName name <> ppIdFlavor flavor where isRandomGenerated = not (isExternalName name) internalNamePrefix = if isRandomGenerated then asmTempLabelPrefix platform else empty- CStyle -> ppr name <> ppIdFlavor flavor+ CStyle -> pprName name <> ppIdFlavor flavor SRTLabel u -> maybe_underscore $ tempLabelPrefixOrUnderscore <> pprUniqueAlways u <> pp_cSEP <> text "srt"@@ -1549,7 +1559,7 @@ ] RtsLabel (RtsPrimOp primop)- -> maybe_underscore $ text "stg_" <> ppr primop+ -> maybe_underscore $ text "stg_" <> pprPrimOp primop RtsLabel (RtsSlowFastTickyCtr pat) -> maybe_underscore $ text "SLOW_CALL_fast_" <> text pat <> text "_ctr"@@ -1567,12 +1577,12 @@ -- with a letter so the label will be legal assembly code. HpcTicksLabel mod- -> maybe_underscore $ text "_hpc_tickboxes_" <> ppr mod <> text "_hpc"+ -> maybe_underscore $ text "_hpc_tickboxes_" <> pprModule mod <> text "_hpc" - CC_Label cc -> maybe_underscore $ ppr cc- CCS_Label ccs -> maybe_underscore $ ppr ccs- IPE_Label (InfoProvEnt l _ _ m _) -> maybe_underscore $ (pprCLabel platform l <> text "_" <> ppr m <> text "_ipe")- ModuleLabel mod kind -> maybe_underscore $ ppr mod <> text "_" <> ppr kind+ CC_Label cc -> maybe_underscore $ pprCostCentre cc+ CCS_Label ccs -> maybe_underscore $ pprCostCentreStack ccs+ IPE_Label (InfoProvEnt l _ _ m _) -> maybe_underscore $ (pprCLabel platform l <> text "_" <> pprModule m <> text "_ipe")+ ModuleLabel mod kind -> maybe_underscore $ pprModule mod <> text "_" <> pprModuleLabelKind kind CmmLabel _ _ fs CmmCode -> maybe_underscore $ ftext fs CmmLabel _ _ fs CmmData -> maybe_underscore $ ftext fs@@ -1582,6 +1592,8 @@ CmmLabel _ _ fs CmmRetInfo -> maybe_underscore $ ftext fs <> text "_info" CmmLabel _ _ fs CmmRet -> maybe_underscore $ ftext fs <> text "_ret" CmmLabel _ _ fs CmmClosure -> maybe_underscore $ ftext fs <> text "_closure"+{-# SPECIALIZE pprCLabelStyle :: Platform -> LabelStyle -> CLabel -> SDoc #-}+{-# SPECIALIZE pprCLabelStyle :: Platform -> LabelStyle -> CLabel -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -- Note [Internal proc labels] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -1602,21 +1614,24 @@ -- | Generate a label for a procedure internal to a module (if -- 'Opt_ExposeAllSymbols' is enabled). -- See Note [Internal proc labels].-ppInternalProcLabel :: Module -- ^ the current module+ppInternalProcLabel :: IsLine doc+ => Module -- ^ the current module -> CLabel- -> Maybe SDoc -- ^ the internal proc label+ -> Maybe doc -- ^ the internal proc label ppInternalProcLabel this_mod (IdLabel nm _ flavour) | isInternalName nm = Just- $ text "_" <> ppr this_mod+ $ text "_" <> pprModule this_mod <> char '_' <> ztext (zEncodeFS (occNameFS (occName nm))) <> char '_' <> pprUniqueAlways (getUnique nm) <> ppIdFlavor flavour ppInternalProcLabel _ _ = Nothing+{-# SPECIALIZE ppInternalProcLabel :: Module -> CLabel -> Maybe SDoc #-}+{-# SPECIALIZE ppInternalProcLabel :: Module -> CLabel -> Maybe HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -ppIdFlavor :: IdLabelInfo -> SDoc+ppIdFlavor :: IsLine doc => IdLabelInfo -> doc ppIdFlavor x = pp_cSEP <> case x of Closure -> text "closure" InfoTable -> text "info"@@ -1627,22 +1642,22 @@ IdTickyInfo TickyRednCounts -> text "ct" IdTickyInfo (TickyInferedTag unique)- -> text "ct_inf_tag" <> char '_' <> ppr unique+ -> text "ct_inf_tag" <> char '_' <> pprUniqueAlways unique ConEntry loc -> case loc of DefinitionSite -> text "con_entry" UsageSite m n ->- ppr m <> pp_cSEP <> ppr n <> pp_cSEP <> text "con_entry"+ pprModule m <> pp_cSEP <> int n <> pp_cSEP <> text "con_entry" ConInfoTable k -> case k of DefinitionSite -> text "con_info" UsageSite m n ->- ppr m <> pp_cSEP <> ppr n <> pp_cSEP <> text "con_info"+ pprModule m <> pp_cSEP <> int n <> pp_cSEP <> text "con_info" ClosureTable -> text "closure_tbl" Bytes -> text "bytes" BlockInfoTable -> text "info" -pp_cSEP :: SDoc+pp_cSEP :: IsLine doc => doc pp_cSEP = char '_' @@ -1656,13 +1671,13 @@ -- ----------------------------------------------------------------------------- -- Machine-dependent knowledge about labels. -asmTempLabelPrefix :: Platform -> SDoc -- for formatting labels+asmTempLabelPrefix :: IsLine doc => Platform -> doc -- for formatting labels asmTempLabelPrefix !platform = case platformOS platform of OSDarwin -> text "L" OSAIX -> text "__L" -- follow IBM XL C's convention _ -> text ".L" -pprDynamicLinkerAsmLabel :: Platform -> DynamicLinkerLabelInfo -> SDoc -> SDoc+pprDynamicLinkerAsmLabel :: IsLine doc => Platform -> DynamicLinkerLabelInfo -> doc -> doc pprDynamicLinkerAsmLabel !platform dllInfo ppLbl = case platformOS platform of OSDarwin
compiler/GHC/Cmm/CLabel.hs-boot view
@@ -5,4 +5,4 @@ data CLabel -pprCLabel :: Platform -> CLabel -> SDoc+pprCLabel :: IsLine doc => Platform -> CLabel -> doc
compiler/GHC/Cmm/Expr.hs view
@@ -46,7 +46,6 @@ import GHC.Cmm.MachOp import GHC.Cmm.Type import GHC.Cmm.Reg-import GHC.Utils.Trace (pprTrace) import GHC.Utils.Panic (panic) import GHC.Utils.Outputable
compiler/GHC/Cmm/MachOp.hs view
@@ -65,7 +65,6 @@ | MO_S_Neg Width -- unary - -- Unsigned multiply/divide- | MO_U_MulMayOflo Width -- nonzero if unsigned multiply overflows | MO_U_Quot Width -- unsigned / (same semantics as WordQuotOp) | MO_U_Rem Width -- unsigned % (same semantics as WordRemOp) @@ -251,7 +250,6 @@ MO_Ne _ -> True MO_Mul _ -> True MO_S_MulMayOflo _ -> True- MO_U_MulMayOflo _ -> True MO_And _ -> True MO_Or _ -> True MO_Xor _ -> True@@ -379,7 +377,6 @@ MO_S_Quot r -> cmmBits r MO_S_Rem r -> cmmBits r MO_S_Neg r -> cmmBits r- MO_U_MulMayOflo r -> cmmBits r MO_U_Quot r -> cmmBits r MO_U_Rem r -> cmmBits r @@ -473,7 +470,6 @@ MO_S_Quot r -> [r,r] MO_S_Rem r -> [r,r] MO_S_Neg r -> [r]- MO_U_MulMayOflo r -> [r,r] MO_U_Quot r -> [r,r] MO_U_Rem r -> [r,r]
compiler/GHC/Cmm/Node.hs view
@@ -9,9 +9,6 @@ {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE LambdaCase #-} -{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- -- CmmNode type for representation using Hoopl graphs. module GHC.Cmm.Node (@@ -33,6 +30,7 @@ import GHC.Cmm.Expr import GHC.Cmm.Switch import GHC.Data.FastString+import GHC.Data.Pair import GHC.Types.ForeignCall import GHC.Utils.Outputable import GHC.Runtime.Heap.Layout@@ -725,7 +723,7 @@ mapExpM _ (CmmTick _) = Nothing mapExpM f (CmmUnwind regs) = CmmUnwind `fmap` mapM (\(r,e) -> mapM f e >>= \e' -> pure (r,e')) regs mapExpM f (CmmAssign r e) = CmmAssign r `fmap` f e-mapExpM f (CmmStore addr e align) = (\[addr', e'] -> CmmStore addr' e' align) `fmap` mapListM f [addr, e]+mapExpM f (CmmStore addr e align) = (\ (Pair addr' e') -> CmmStore addr' e' align) `fmap` traverse f (Pair addr e) mapExpM _ (CmmBranch _) = Nothing mapExpM f (CmmCondBranch e ti fi l) = (\x -> CmmCondBranch x ti fi l) `fmap` f e mapExpM f (CmmSwitch e tbl) = (\x -> CmmSwitch x tbl) `fmap` f e
compiler/GHC/Cmm/Reg.hs view
@@ -12,6 +12,7 @@ , localRegType -- * Global registers , GlobalReg(..), isArgReg, globalRegType+ , pprGlobalReg , spReg, hpReg, spLimReg, hpLimReg, nodeReg , currentTSOReg, currentNurseryReg, hpAllocReg, cccsReg , node, baseReg@@ -296,7 +297,7 @@ instance OutputableP env GlobalReg where pdoc _ = ppr -pprGlobalReg :: GlobalReg -> SDoc+pprGlobalReg :: IsLine doc => GlobalReg -> doc pprGlobalReg gr = case gr of VanillaReg n _ -> char 'R' <> int n@@ -324,6 +325,8 @@ GCFun -> text "stg_gc_fun" BaseReg -> text "BaseReg" PicBaseReg -> text "PicBaseReg"+{-# SPECIALIZE pprGlobalReg :: GlobalReg -> SDoc #-}+{-# SPECIALIZE pprGlobalReg :: GlobalReg -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -- convenient aliases
compiler/GHC/Core.hs view
@@ -7,9 +7,6 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE BangPatterns #-} -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}-{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}- -- | GHC.Core holds all the main data types for use by for the Glasgow Haskell Compiler midsection module GHC.Core ( -- * Main data types@@ -85,9 +82,8 @@ IsOrphan(..), isOrphan, notOrphan, chooseOrphanAnchor, -- * Core rule data types- CoreRule(..), RuleBase,- RuleName, RuleFun, IdUnfoldingFun, InScopeEnv,- RuleEnv(..), RuleOpts, mkRuleEnv, emptyRuleEnv,+ CoreRule(..),+ RuleName, RuleFun, IdUnfoldingFun, InScopeEnv, RuleOpts, -- ** Operations on 'CoreRule's ruleArity, ruleName, ruleIdName, ruleActivation,@@ -105,7 +101,6 @@ import GHC.Core.Rules.Config ( RuleOpts ) import GHC.Types.Name import GHC.Types.Name.Set-import GHC.Types.Name.Env( NameEnv ) import GHC.Types.Literal import GHC.Types.Tickish import GHC.Core.DataCon@@ -1062,6 +1057,12 @@ M. But it's painful, because it means we need to keep track of all the orphan modules below us. + * The "visible orphan modules" are all the orphan module in the transitive+ closure of the imports of this module.++ * During instance lookup, we filter orphan instances depending on+ whether or not the instance is in a visible orphan module.+ * A non-orphan is not finger-printed separately. Instead, for fingerprinting purposes it is treated as part of the entity it mentions on the LHS. For example@@ -1076,12 +1077,20 @@ Orphan-hood is computed * For class instances:- when we make a ClsInst- (because it is needed during instance lookup)+ when we make a ClsInst in GHC.Core.InstEnv.mkLocalInstance+ (because it is needed during instance lookup)+ See Note [When exactly is an instance decl an orphan?]+ in GHC.Core.InstEnv - * For rules and family instances:- when we generate an IfaceRule (GHC.Iface.Make.coreRuleToIfaceRule)- or IfaceFamInst (GHC.Iface.Make.instanceToIfaceInst)+ * For rules+ when we generate a CoreRule (GHC.Core.Rules.mkRule)++ * For family instances:+ when we generate an IfaceFamInst (GHC.Iface.Make.instanceToIfaceInst)++Orphan-hood is persisted into interface files, in ClsInst, FamInst,+and CoreRules.+ -} {-@@ -1096,49 +1105,6 @@ representation. -} --- | Gathers a collection of 'CoreRule's. Maps (the name of) an 'Id' to its rules-type RuleBase = NameEnv [CoreRule]- -- The rules are unordered;- -- we sort out any overlaps on lookup---- | A full rule environment which we can apply rules from. Like a 'RuleBase',--- but it also includes the set of visible orphans we use to filter out orphan--- rules which are not visible (even though we can see them...)-data RuleEnv- = RuleEnv { re_base :: [RuleBase] -- See Note [Why re_base is a list]- , re_visible_orphs :: ModuleSet- }--mkRuleEnv :: RuleBase -> [Module] -> RuleEnv-mkRuleEnv rules vis_orphs = RuleEnv [rules] (mkModuleSet vis_orphs)--emptyRuleEnv :: RuleEnv-emptyRuleEnv = RuleEnv [] emptyModuleSet--{--Note [Why re_base is a list]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~--In Note [Overall plumbing for rules], it is explained that the final-RuleBase which we must consider is combined from 4 different sources.--During simplifier runs, the fourth source of rules is constantly being updated-as new interfaces are loaded into the EPS. Therefore just before we check to see-if any rules match we get the EPS RuleBase and combine it with the existing RuleBase-and then perform exactly 1 lookup into the new map.--It is more efficient to avoid combining the environments and store the uncombined-environments as we can instead perform 1 lookup into each environment and then combine-the results.--Essentially we use the identity:--> lookupNameEnv n (plusNameEnv_C (++) rb1 rb2)-> = lookupNameEnv n rb1 ++ lookupNameEnv n rb2--The latter being more efficient as we don't construct an intermediate-map.--} -- | A 'CoreRule' is: --
compiler/GHC/Core/Coercion.hs view
@@ -13,7 +13,9 @@ -- module GHC.Core.Coercion ( -- * Main data type- Coercion, CoercionN, CoercionR, CoercionP, MCoercion(..), MCoercionN, MCoercionR,+ Coercion, CoercionN, CoercionR, CoercionP,+ MCoercion(..), MCoercionN, MCoercionR,+ CoSel(..), FunSel(..), UnivCoProvenance, CoercionHole(..), coHoleCoVar, setCoHoleCoVar, LeftOrRight(..),@@ -35,8 +37,10 @@ mkAxInstLHS, mkUnbranchedAxInstLHS, mkPiCo, mkPiCos, mkCoCast, mkSymCo, mkTransCo,- mkNthCo, mkNthCoFunCo, nthCoRole, mkLRCo,- mkInstCo, mkAppCo, mkAppCos, mkTyConAppCo, mkFunCo, mkFunResCo,+ mkSelCo, getNthFun, getNthFromType, mkLRCo,+ mkInstCo, mkAppCo, mkAppCos, mkTyConAppCo,+ mkFunCo1, mkFunCo2, mkFunCoNoFTF, mkFunResCo,+ mkNakedFunCo1, mkNakedFunCo2, mkForAllCo, mkForAllCos, mkHomoForAllCos, mkPhantomCo, mkHoleCo, mkUnivCo, mkSubCo,@@ -56,14 +60,13 @@ topNormaliseNewType_maybe, topNormaliseTypeX, decomposeCo, decomposeFunCo, decomposePiCos, getCoVar_maybe,- splitTyConAppCo_maybe, splitAppCo_maybe, splitFunCo_maybe, splitForAllCo_maybe, splitForAllCo_ty_maybe, splitForAllCo_co_maybe, - nthRole, tyConRolesX, tyConRolesRepresentational, setNominalRole_maybe,-+ tyConRole, tyConRolesX, tyConRolesRepresentational, setNominalRole_maybe,+ tyConRoleListX, tyConRoleListRepresentational, funRole, pickLR, isGReflCo, isReflCo, isReflCo_maybe, isGReflCo_maybe, isReflexiveCo, isReflexiveCo_maybe,@@ -118,7 +121,7 @@ -- * Other promoteCoercion, buildCoercion, - multToCo,+ multToCo, mkRuntimeRepCo, hasCoercionHoleTy, hasCoercionHoleCo, hasThisCoercionHoleTy, @@ -135,17 +138,18 @@ import GHC.Core.TyCo.Ppr import GHC.Core.TyCo.Subst import GHC.Core.TyCo.Tidy+import GHC.Core.TyCo.Compare( eqType, eqTypeX ) import GHC.Core.Type import GHC.Core.TyCon import GHC.Core.TyCon.RecWalk import GHC.Core.Coercion.Axiom-import {-# SOURCE #-} GHC.Core.Utils ( mkFunctionType ) import GHC.Types.Var import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Types.Name hiding ( varName ) import GHC.Types.Basic import GHC.Types.Unique+import GHC.Data.FastString import GHC.Data.Pair import GHC.Types.SrcLoc import GHC.Builtin.Names@@ -153,6 +157,8 @@ import GHC.Data.List.SetOps import GHC.Data.Maybe import GHC.Types.Unique.FM+import GHC.Data.List.Infinite (Infinite (..))+import qualified GHC.Data.List.Infinite as Inf import GHC.Utils.Misc import GHC.Utils.Outputable@@ -245,7 +251,7 @@ -> TyCon -> CoAxBranch -> SDoc ppr_co_ax_branch ppr_rhs fam_tc branch = foldr1 (flip hangNotEmpty 2)- [ pprUserForAll (mkTyCoVarBinders Inferred bndrs')+ [ pprUserForAll (mkForAllTyBinders Inferred bndrs') -- See Note [Printing foralls in type family instances] in GHC.Iface.Type , pp_lhs <+> ppr_rhs tidy_env ee_rhs , text "-- Defined" <+> pp_loc ]@@ -286,7 +292,7 @@ (env', bndr') = tidyVarBndr env bndr env_wild = (occ_env, extendVarEnv subst bndr wild_bndr) wild_bndr = setVarName bndr $- tidyNameOcc (varName bndr) (mkTyVarOcc "_")+ tidyNameOcc (varName bndr) (mkTyVarOccFS (fsLit "_")) -- Tidy the binder to "_" is_wildcard :: Var -> Bool@@ -359,9 +365,9 @@ mkPiMCos _ MRefl = MRefl mkPiMCos vs (MCo co) = MCo (mkPiCos Representational vs co) -mkFunResMCo :: Scaled Type -> MCoercionR -> MCoercionR+mkFunResMCo :: Id -> MCoercionR -> MCoercionR mkFunResMCo _ MRefl = MRefl-mkFunResMCo arg_ty (MCo co) = MCo (mkFunResCo Representational arg_ty co)+mkFunResMCo arg_id (MCo co) = MCo (mkFunResCo Representational arg_id co) mkGReflLeftMCo :: Role -> Type -> MCoercionN -> Coercion mkGReflLeftMCo r ty MRefl = mkReflCo r ty@@ -386,48 +392,35 @@ Destructing coercions %* * %************************************************************************--Note [Function coercions]-~~~~~~~~~~~~~~~~~~~~~~~~~-Remember that- (->) :: forall {r1} {r2}. TYPE r1 -> TYPE r2 -> TYPE LiftedRep-whose `RuntimeRep' arguments are intentionally marked inferred to-avoid type application.--Hence- FunCo r mult co1 co2 :: (s1->t1) ~r (s2->t2)-is short for- TyConAppCo (->) mult co_rep1 co_rep2 co1 co2-where co_rep1, co_rep2 are the coercions on the representations. -} - -- | This breaks a 'Coercion' with type @T A B C ~ T D E F@ into -- a list of 'Coercion's of kinds @A ~ D@, @B ~ E@ and @E ~ F@. Hence: -- -- > decomposeCo 3 c [r1, r2, r3] = [nth r1 0 c, nth r2 1 c, nth r3 2 c] decomposeCo :: Arity -> Coercion- -> [Role] -- the roles of the output coercions- -- this must have at least as many- -- entries as the Arity provided+ -> Infinite Role -- the roles of the output coercions -> [Coercion] decomposeCo arity co rs- = [mkNthCo r n co | (n,r) <- [0..(arity-1)] `zip` rs ]- -- Remember, Nth is zero-indexed+ = [mkSelCo (SelTyCon n r) co | (n,r) <- [0..(arity-1)] `zip` Inf.toList rs ]+ -- Remember, SelTyCon is zero-indexed decomposeFunCo :: HasDebugCallStack- => Role -- Role of the input coercion- -> Coercion -- Input coercion+ => Coercion -- Input coercion -> (CoercionN, Coercion, Coercion)--- Expects co :: (s1 -> t1) ~ (s2 -> t2)--- Returns (co1 :: s1~s2, co2 :: t1~t2)--- See Note [Function coercions] for the "3" and "4"+-- Expects co :: (s1 %m1-> t1) ~ (s2 %m2-> t2)+-- Returns (cow :: m1 ~N m2, co1 :: s1~s2, co2 :: t1~t2)+-- actually cow will be a Phantom coercion if the input is a Phantom coercion -decomposeFunCo _ (FunCo _ w co1 co2) = (w, co1, co2)- -- Short-circuits the calls to mkNthCo+decomposeFunCo (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 })+ = (w, co1, co2)+ -- Short-circuits the calls to mkSelCo -decomposeFunCo r co = assertPpr all_ok (ppr co)- (mkNthCo Nominal 0 co, mkNthCo r 3 co, mkNthCo r 4 co)+decomposeFunCo co+ = assertPpr all_ok (ppr co) $+ ( mkSelCo (SelFun SelMult) co+ , mkSelCo (SelFun SelArg) co+ , mkSelCo (SelFun SelRes) co ) where Pair s1t1 s2t2 = coercionKind co all_ok = isFunTy s1t1 && isFunTy s2t2@@ -488,24 +481,25 @@ -- ty :: s2 -- need arg_co :: s2 ~ s1 -- res_co :: t1[ty |> arg_co / a] ~ t2[ty / b]- = let arg_co = mkNthCo Nominal 0 (mkSymCo co)+ = let arg_co = mkSelCo SelForAll (mkSymCo co) res_co = mkInstCo co (mkGReflLeftCo Nominal ty arg_co) subst1' = extendTCvSubst subst1 a (ty `CastTy` arg_co) subst2' = extendTCvSubst subst2 b ty in go (arg_co : acc_arg_cos) (subst1', t1) res_co (subst2', t2) tys - | Just (_w1, _s1, t1) <- splitFunTy_maybe k1- , Just (_w1, _s2, t2) <- splitFunTy_maybe k2+ | Just (af1, _w1, _s1, t1) <- splitFunTy_maybe k1+ , Just (af2, _w1, _s2, t2) <- splitFunTy_maybe k2+ , af1 == af2 -- Same sort of arrow -- know co :: (s1 -> t1) ~ (s2 -> t2) -- function :: s1 -> t1 -- ty :: s2 -- need arg_co :: s2 ~ s1 -- res_co :: t1 ~ t2- = let (_, sym_arg_co, res_co) = decomposeFunCo Nominal co- -- It should be fine to ignore the multiplicity bit of the coercion- -- for a Nominal coercion.- arg_co = mkSymCo sym_arg_co+ = let (_, sym_arg_co, res_co) = decomposeFunCo co+ -- It should be fine to ignore the multiplicity bit+ -- of the coercion for a Nominal coercion.+ arg_co = mkSymCo sym_arg_co in go (arg_co : acc_arg_cos) (subst1,t1) res_co (subst2,t2) tys @@ -526,19 +520,6 @@ getCoVar_maybe (CoVarCo cv) = Just cv getCoVar_maybe _ = Nothing --- | Attempts to tease a coercion apart into a type constructor and the application--- of a number of coercion arguments to that constructor-splitTyConAppCo_maybe :: Coercion -> Maybe (TyCon, [Coercion])-splitTyConAppCo_maybe co- | Just (ty, r) <- isReflCo_maybe co- = do { (tc, tys) <- splitTyConApp_maybe ty- ; let args = zipWith mkReflCo (tyConRolesX r tc) tys- ; return (tc, args) }-splitTyConAppCo_maybe (TyConAppCo _ tc cos) = Just (tc, cos)-splitTyConAppCo_maybe (FunCo _ w arg res) = Just (funTyCon, cos)- where cos = [w, mkRuntimeRepCo arg, mkRuntimeRepCo res, arg, res]-splitTyConAppCo_maybe _ = Nothing- multToCo :: Mult -> Coercion multToCo r = mkNomReflCo r @@ -551,10 +532,10 @@ , Just (args', arg') <- snocView args = Just ( mkTyConAppCo r tc args', arg' ) - | not (mustBeSaturated tc)+ | not (tyConMustBeSaturated tc) -- Never create unsaturated type family apps! , Just (args', arg') <- snocView args- , Just arg'' <- setNominalRole_maybe (nthRole r tc (length args')) arg'+ , Just arg'' <- setNominalRole_maybe (tyConRole r tc (length args')) arg' = Just ( mkTyConAppCo r tc args', arg'' ) -- Use mkTyConAppCo to preserve the invariant -- that identity coercions are always represented by Refl@@ -567,7 +548,7 @@ -- Only used in specialise/Rules splitFunCo_maybe :: Coercion -> Maybe (Coercion, Coercion)-splitFunCo_maybe (FunCo _ _ arg res) = Just (arg, res)+splitFunCo_maybe (FunCo { fco_arg = arg, fco_res = res }) = Just (arg, res) splitFunCo_maybe _ = Nothing splitForAllCo_maybe :: Coercion -> Maybe (TyCoVar, Coercion, Coercion)@@ -628,13 +609,13 @@ = pprPanic "eqTyConRole: unknown tycon" (ppr tc) -- | Given a coercion @co1 :: (a :: TYPE r1) ~ (b :: TYPE r2)@,+-- (or CONSTRAINT instead of TYPE) -- produce a coercion @rep_co :: r1 ~ r2@. mkRuntimeRepCo :: HasDebugCallStack => Coercion -> Coercion mkRuntimeRepCo co- = mkNthCo Nominal 0 kind_co+ = mkSelCo (SelTyCon 0 Nominal) kind_co where kind_co = mkKindCo co -- kind_co :: TYPE r1 ~ TYPE r2- -- (up to silliness with Constraint) isReflCoVar_maybe :: Var -> Maybe Coercion -- If cv :: t~t then isReflCoVar_maybe cv = Just (Refl t)@@ -707,7 +688,6 @@ Note [Role twiddling functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~- There are a plethora of functions for twiddling roles: mkSubCo: Requires a nominal input coercion and always produces a@@ -773,14 +753,10 @@ -- caller's responsibility to get the roles correct on argument coercions. mkTyConAppCo :: HasDebugCallStack => Role -> TyCon -> [Coercion] -> Coercion mkTyConAppCo r tc cos- | [w, _rep1, _rep2, co1, co2] <- cos -- See Note [Function coercions]- , isFunTyCon tc- = -- (a :: TYPE ra) -> (b :: TYPE rb) ~ (c :: TYPE rc) -> (d :: TYPE rd)- -- rep1 :: ra ~ rc rep2 :: rb ~ rd- -- co1 :: a ~ c co2 :: b ~ d- mkFunCo r w co1 co2+ | Just co <- tyConAppFunCo_maybe r tc cos+ = co - -- Expand type synonyms+ -- Expand type synonyms | ExpandsSyn tv_co_prs rhs_ty leftover_cos <- expandSynTyCon_maybe tc cos = mkAppCos (liftCoSubst r (mkLiftingContext tv_co_prs) rhs_ty) leftover_cos @@ -790,18 +766,86 @@ | otherwise = TyConAppCo r tc cos +mkFunCoNoFTF :: HasDebugCallStack => Role -> CoercionN -> Coercion -> Coercion -> Coercion+-- This version of mkFunCo takes no FunTyFlags; it works them out+mkFunCoNoFTF r w arg_co res_co+ = mkFunCo2 r afl afr w arg_co res_co+ where+ afl = chooseFunTyFlag argl_ty resl_ty+ afr = chooseFunTyFlag argr_ty resr_ty+ Pair argl_ty argr_ty = coercionKind arg_co+ Pair resl_ty resr_ty = coercionKind res_co+ -- | Build a function 'Coercion' from two other 'Coercion's. That is, -- given @co1 :: a ~ b@ and @co2 :: x ~ y@ produce @co :: (a -> x) ~ (b -> y)@ -- or @(a => x) ~ (b => y)@, depending on the kind of @a@/@b@.-mkFunCo :: Role -> CoercionN -> Coercion -> Coercion -> Coercion-mkFunCo r w co1 co2- -- See Note [Refl invariant]- | Just (ty1, _) <- isReflCo_maybe co1- , Just (ty2, _) <- isReflCo_maybe co2- , Just (w, _) <- isReflCo_maybe w- = mkReflCo r (mkFunctionType w ty1 ty2)- | otherwise = FunCo r w co1 co2+-- This (most common) version takes a single FunTyFlag, which is used+-- for both fco_afl and ftf_afr of the FunCo+mkFunCo1 :: HasDebugCallStack => Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion+mkFunCo1 r af w arg_co res_co+ = mkFunCo2 r af af w arg_co res_co +mkNakedFunCo1 :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion+-- This version of mkFunCo1 does not check FunCo invariants (checkFunCo)+-- It is called during typechecking on un-zonked types;+-- in particular there may be un-zonked coercion variables.+mkNakedFunCo1 r af w arg_co res_co+ = mkNakedFunCo2 r af af w arg_co res_co++mkFunCo2 :: HasDebugCallStack => Role -> FunTyFlag -> FunTyFlag+ -> CoercionN -> Coercion -> Coercion -> Coercion+-- This is the smart constructor for FunCo; it checks invariants+mkFunCo2 r afl afr w arg_co res_co+ = assertPprMaybe (checkFunCo r afl afr w arg_co res_co) $+ mkNakedFunCo2 r afl afr w arg_co res_co++mkNakedFunCo2 :: Role -> FunTyFlag -> FunTyFlag+ -> CoercionN -> Coercion -> Coercion -> Coercion+-- This is the smart constructor for FunCo+-- "Naked"; it does not check invariants+mkNakedFunCo2 r afl afr w arg_co res_co+ | Just (ty1, _) <- isReflCo_maybe arg_co+ , Just (ty2, _) <- isReflCo_maybe res_co+ , Just (w, _) <- isReflCo_maybe w+ = mkReflCo r (mkFunTy afl w ty1 ty2) -- See Note [Refl invariant]++ | otherwise+ = FunCo { fco_role = r, fco_afl = afl, fco_afr = afr+ , fco_mult = w, fco_arg = arg_co, fco_res = res_co }+++checkFunCo :: Role -> FunTyFlag -> FunTyFlag+ -> CoercionN -> Coercion -> Coercion+ -> Maybe SDoc+-- Checks well-formed-ness for FunCo+-- Used only in assertions and Lint+{-# NOINLINE checkFunCo #-}+checkFunCo _r afl afr _w arg_co res_co+ | not (ok argl_ty && ok argr_ty && ok resl_ty && ok resr_ty)+ = Just (hang (text "Bad arg or res types") 2 pp_inputs)++ | afl == computed_afl+ , afr == computed_afr+ = Nothing+ | otherwise+ = Just (vcat [ text "afl (provided,computed):" <+> ppr afl <+> ppr computed_afl+ , text "afr (provided,computed):" <+> ppr afr <+> ppr computed_afr+ , pp_inputs ])+ where+ computed_afl = chooseFunTyFlag argl_ty resl_ty+ computed_afr = chooseFunTyFlag argr_ty resr_ty+ Pair argl_ty argr_ty = coercionKind arg_co+ Pair resl_ty resr_ty = coercionKind res_co++ pp_inputs = vcat [ pp_ty "argl" argl_ty, pp_ty "argr" argr_ty+ , pp_ty "resl" resl_ty, pp_ty "resr" resr_ty+ , text "arg_co:" <+> ppr arg_co+ , text "res_co:" <+> ppr res_co ]++ ok ty = isTYPEorCONSTRAINT (typeKind ty)+ pp_ty str ty = text str <> colon <+> hang (ppr ty)+ 2 (dcolon <+> ppr (typeKind ty))+ -- | Apply a 'Coercion' to another 'Coercion'. -- The second coercion must be Nominal, unless the first is Phantom. -- If the first is Phantom, then the second can be either Phantom or Nominal.@@ -818,15 +862,14 @@ -- Expand type synonyms; a TyConAppCo can't have a type synonym (#9102) = mkTyConAppCo r tc (zip_roles (tyConRolesX r tc) tys) where- zip_roles (r1:_) [] = [downgradeRole r1 Nominal arg]- zip_roles (r1:rs) (ty1:tys) = mkReflCo r1 ty1 : zip_roles rs tys- zip_roles _ _ = panic "zip_roles" -- but the roles are infinite...+ zip_roles (Inf r1 _) [] = [downgradeRole r1 Nominal arg]+ zip_roles (Inf r1 rs) (ty1:tys) = mkReflCo r1 ty1 : zip_roles rs tys mkAppCo (TyConAppCo r tc args) arg = case r of Nominal -> mkTyConAppCo Nominal tc (args ++ [arg]) Representational -> mkTyConAppCo Representational tc (args ++ [arg'])- where new_role = (tyConRolesRepresentational tc) !! (length args)+ where new_role = tyConRolesRepresentational tc Inf.!! length args arg' = downgradeRole new_role Nominal arg Phantom -> mkTyConAppCo Phantom tc (args ++ [toPhantomCo arg]) mkAppCo co arg = AppCo co arg@@ -899,11 +942,11 @@ mkForAllCo_NoRefl :: TyCoVar -> CoercionN -> Coercion -> Coercion mkForAllCo_NoRefl v kind_co co | assert (varType v `eqType` (coercionLKind kind_co)) True- , assert (isTyVar v || almostDevoidCoVarOfCo v co) True , assert (not (isReflCo co)) True , isCoVar v+ , assert (almostDevoidCoVarOfCo v co) True , not (v `elemVarSet` tyCoVarsOfCo co)- = FunCo (coercionRole co) (multToCo Many) kind_co co+ = mkFunCoNoFTF (coercionRole co) (multToCo ManyTy) kind_co co -- Functions from coercions are always unrestricted | otherwise = ForAllCo v kind_co co@@ -1064,142 +1107,84 @@ = GRefl r t1 (MCo $ mkTransCo co1 co2) mkTransCo co1 co2 = TransCo co1 co2 -mkNthCo :: HasDebugCallStack- => Role -- The role of the coercion you're creating- -> Int -- Zero-indexed+mkSelCo :: HasDebugCallStack+ => CoSel -> Coercion -> Coercion-mkNthCo r n co- = assertPpr good_call bad_call_msg $- go n co+mkSelCo n co = mkSelCo_maybe n co `orElse` SelCo n co++mkSelCo_maybe :: HasDebugCallStack+ => CoSel+ -> Coercion+ -> Maybe Coercion+-- mkSelCo_maybe tries to optimise call to mkSelCo+mkSelCo_maybe cs co+ = assertPpr (good_call cs) bad_call_msg $+ go cs co where Pair ty1 ty2 = coercionKind co - go 0 co- | Just (ty, _) <- isReflCo_maybe co- , Just (tv, _) <- splitForAllTyCoVar_maybe ty- = -- works for both tyvar and covar- assert (r == Nominal) $- mkNomReflCo (varType tv)-- go n co- | Just (ty, r0) <- isReflCo_maybe co- , let tc = tyConAppTyCon ty- = assertPpr (ok_tc_app ty n) (ppr n $$ ppr ty) $- assert (nthRole r0 tc n == r) $- mkReflCo r (tyConAppArgN n ty)- where ok_tc_app :: Type -> Int -> Bool- ok_tc_app ty n- | Just (_, tys) <- splitTyConApp_maybe ty- = tys `lengthExceeds` n- | isForAllTy ty -- nth:0 pulls out a kind coercion from a hetero forall- = n == 0- | otherwise- = False+ go cs co+ | Just (ty, r) <- isReflCo_maybe co+ = Just (mkReflCo r (getNthFromType cs ty)) - go 0 (ForAllCo _ kind_co _)- = assert (r == Nominal)- kind_co+ go SelForAll (ForAllCo _ kind_co _)+ = Just kind_co -- If co :: (forall a1:k1. t1) ~ (forall a2:k2. t2)- -- then (nth 0 co :: k1 ~N k2)+ -- then (nth SelForAll co :: k1 ~N k2) -- If co :: (forall a1:t1 ~ t2. t1) ~ (forall a2:t3 ~ t4. t2)- -- then (nth 0 co :: (t1 ~ t2) ~N (t3 ~ t4))+ -- then (nth SelForAll co :: (t1 ~ t2) ~N (t3 ~ t4)) - go n (FunCo _ w arg res)- = mkNthCoFunCo n w arg res+ go (SelFun fs) (FunCo _ _ _ w arg res)+ = Just (getNthFun fs w arg res) - go n (TyConAppCo r0 tc arg_cos) = assertPpr (r == nthRole r0 tc n)- (vcat [ ppr tc- , ppr arg_cos- , ppr r0- , ppr n- , ppr r ]) $- arg_cos `getNth` n+ go (SelTyCon i r) (TyConAppCo r0 tc arg_cos)+ = assertPpr (r == tyConRole r0 tc i)+ (vcat [ ppr tc, ppr arg_cos, ppr r0, ppr i, ppr r ]) $+ Just (arg_cos `getNth` i) - go n (SymCo co) -- Recurse, hoping to get to a TyConAppCo or FunCo- = mkSymCo (go n co)+ go cs (SymCo co) -- Recurse, hoping to get to a TyConAppCo or FunCo+ = do { co' <- go cs co; return (mkSymCo co') } - go n co- = NthCo r n co+ go _ _ = Nothing -- Assertion checking bad_call_msg = vcat [ text "Coercion =" <+> ppr co , text "LHS ty =" <+> ppr ty1 , text "RHS ty =" <+> ppr ty2- , text "n =" <+> ppr n, text "r =" <+> ppr r+ , text "cs =" <+> ppr cs , text "coercion role =" <+> ppr (coercionRole co) ]- good_call- -- If the Coercion passed in is between forall-types, then the Int must- -- be 0 and the role must be Nominal.++ -- good_call checks the typing rules given in Note [SelCo]+ good_call SelForAll | Just (_tv1, _) <- splitForAllTyCoVar_maybe ty1 , Just (_tv2, _) <- splitForAllTyCoVar_maybe ty2- = n == 0 && r == Nominal-- -- If the Coercion passed in is between T tys and T tys', then the Int- -- must be less than the length of tys/tys' (which must be the same- -- lengths).- --- -- If the role of the Coercion is nominal, then the role passed in must- -- be nominal. If the role of the Coercion is representational, then the- -- role passed in must be tyConRolesRepresentational T !! n. If the role- -- of the Coercion is Phantom, then the role passed in must be Phantom.- --- -- See also Note [NthCo Cached Roles] if you're wondering why it's- -- blaringly obvious that we should be *computing* this role instead of- -- passing it in.- | Just (tc1, tys1) <- splitTyConApp_maybe ty1- , Just (tc2, tys2) <- splitTyConApp_maybe ty2- , tc1 == tc2- = let len1 = length tys1- len2 = length tys2- good_role = case coercionRole co of- Nominal -> r == Nominal- Representational -> r == (tyConRolesRepresentational tc1 !! n)- Phantom -> r == Phantom- in len1 == len2 && n < len1 && good_role-- | otherwise- = True---- | Extract the nth field of a FunCo-mkNthCoFunCo :: Int -- ^ "n"- -> CoercionN -- ^ multiplicity coercion- -> Coercion -- ^ argument coercion- -> Coercion -- ^ result coercion- -> Coercion -- ^ nth coercion from a FunCo--- See Note [Function coercions]--- If FunCo _ mult arg_co res_co :: (s1:TYPE sk1 :mult-> s2:TYPE sk2)--- ~ (t1:TYPE tk1 :mult-> t2:TYPE tk2)--- Then we want to behave as if co was--- TyConAppCo mult argk_co resk_co arg_co res_co--- where--- argk_co :: sk1 ~ tk1 = mkNthCo 0 (mkKindCo arg_co)--- resk_co :: sk2 ~ tk2 = mkNthCo 0 (mkKindCo res_co)--- i.e. mkRuntimeRepCo-mkNthCoFunCo n w co1 co2 = case n of- 0 -> w- 1 -> mkRuntimeRepCo co1- 2 -> mkRuntimeRepCo co2- 3 -> co1- 4 -> co2- _ -> pprPanic "mkNthCo(FunCo)" (ppr n $$ ppr w $$ ppr co1 $$ ppr co2)+ = True --- | If you're about to call @mkNthCo r n co@, then @r@ should be--- whatever @nthCoRole n co@ returns.-nthCoRole :: Int -> Coercion -> Role-nthCoRole n co- | Just (tc, _) <- splitTyConApp_maybe lty- = nthRole r tc n+ good_call (SelFun {})+ = isFunTy ty1 && isFunTy ty2 - | Just _ <- splitForAllTyCoVar_maybe lty- = Nominal+ good_call (SelTyCon n r)+ | Just (tc1, tys1) <- splitTyConApp_maybe ty1+ , Just (tc2, tys2) <- splitTyConApp_maybe ty2+ , let { len1 = length tys1+ ; len2 = length tys2 }+ = tc1 == tc2+ && len1 == len2+ && n < len1+ && r == tyConRole (coercionRole co) tc1 n - | otherwise- = pprPanic "nthCoRole" (ppr co)+ good_call _ = False - where- lty = coercionLKind co- r = coercionRole co+-- | Extract the nth field of a FunCo+getNthFun :: FunSel+ -> a -- ^ multiplicity+ -> a -- ^ argument+ -> a -- ^ result+ -> a -- ^ One of the above three+getNthFun SelMult mult _ _ = mult+getNthFun SelArg _ arg _ = arg+getNthFun SelRes _ _ res = res mkLRCo :: LeftOrRight -> Coercion -> Coercion mkLRCo lr co@@ -1209,7 +1194,7 @@ = LRCo lr co -- | Instantiates a 'Coercion'.-mkInstCo :: Coercion -> Coercion -> Coercion+mkInstCo :: Coercion -> CoercionN -> Coercion mkInstCo (ForAllCo tcv _kind_co body_co) co | Just (arg, _) <- isReflCo_maybe co -- works for both tyvar and covar@@ -1225,7 +1210,7 @@ -- instead of @isReflCo@ | otherwise = GRefl r ty (MCo co) --- | Given @ty :: k1@, @co :: k1 ~ k2@,+-- | Given @r@, @ty :: k1@, and @co :: k1 ~N k2@, -- produces @co' :: (ty |> co) ~r ty@ mkGReflLeftCo :: Role -> Type -> CoercionN -> Coercion mkGReflLeftCo r ty co@@ -1277,10 +1262,10 @@ mkSubCo (GRefl Nominal ty co) = GRefl Representational ty co mkSubCo (TyConAppCo Nominal tc cos) = TyConAppCo Representational tc (applyRoles tc cos)-mkSubCo (FunCo Nominal w arg res)- = FunCo Representational w- (downgradeRole Representational Nominal arg)- (downgradeRole Representational Nominal res)+mkSubCo co@(FunCo { fco_role = Nominal, fco_arg = arg, fco_res = res })+ = co { fco_role = Representational+ , fco_arg = downgradeRole Representational Nominal arg+ , fco_res = downgradeRole Representational Nominal res } mkSubCo co = assertPpr (coercionRole co == Nominal) (ppr co <+> ppr (coercionRole co)) $ SubCo co @@ -1348,12 +1333,13 @@ setNominalRole_maybe_helper co@(Refl _) = Just co setNominalRole_maybe_helper (GRefl _ ty co) = Just $ GRefl Nominal ty co setNominalRole_maybe_helper (TyConAppCo Representational tc cos)- = do { cos' <- zipWithM setNominalRole_maybe (tyConRolesX Representational tc) cos+ = do { cos' <- zipWithM setNominalRole_maybe (tyConRoleListX Representational tc) cos ; return $ TyConAppCo Nominal tc cos' }- setNominalRole_maybe_helper (FunCo Representational w co1 co2)+ setNominalRole_maybe_helper co@(FunCo { fco_role = Representational+ , fco_arg = co1, fco_res = co2 }) = do { co1' <- setNominalRole_maybe Representational co1 ; co2' <- setNominalRole_maybe Representational co2- ; return $ FunCo Nominal w co1' co2'+ ; return $ co { fco_role = Nominal, fco_arg = co1', fco_res = co2' } } setNominalRole_maybe_helper (SymCo co) = SymCo <$> setNominalRole_maybe_helper co@@ -1363,10 +1349,10 @@ = AppCo <$> setNominalRole_maybe_helper co1 <*> pure co2 setNominalRole_maybe_helper (ForAllCo tv kind_co co) = ForAllCo tv kind_co <$> setNominalRole_maybe_helper co- setNominalRole_maybe_helper (NthCo _r n co)+ setNominalRole_maybe_helper (SelCo n co) -- NB, this case recurses via setNominalRole_maybe, not -- setNominalRole_maybe_helper!- = NthCo Nominal n <$> setNominalRole_maybe (coercionRole co) co+ = SelCo n <$> setNominalRole_maybe (coercionRole co) co setNominalRole_maybe_helper (InstCo co arg) = InstCo <$> setNominalRole_maybe_helper co <*> pure arg setNominalRole_maybe_helper (UnivCo prov _ co1 co2)@@ -1392,28 +1378,44 @@ -- Convert args to a TyConAppCo Nominal to the same TyConAppCo Representational applyRoles :: TyCon -> [Coercion] -> [Coercion]-applyRoles tc cos- = zipWith (\r -> downgradeRole r Nominal) (tyConRolesRepresentational tc) cos+applyRoles = zipWith (`downgradeRole` Nominal) . tyConRoleListRepresentational --- the Role parameter is the Role of the TyConAppCo+-- The Role parameter is the Role of the TyConAppCo -- defined here because this is intimately concerned with the implementation -- of TyConAppCo -- Always returns an infinite list (with a infinite tail of Nominal)-tyConRolesX :: Role -> TyCon -> [Role]+tyConRolesX :: Role -> TyCon -> Infinite Role tyConRolesX Representational tc = tyConRolesRepresentational tc-tyConRolesX role _ = repeat role+tyConRolesX role _ = Inf.repeat role +tyConRoleListX :: Role -> TyCon -> [Role]+tyConRoleListX role = Inf.toList . tyConRolesX role+ -- Returns the roles of the parameters of a tycon, with an infinite tail -- of Nominal-tyConRolesRepresentational :: TyCon -> [Role]-tyConRolesRepresentational tc = tyConRoles tc ++ repeat Nominal+tyConRolesRepresentational :: TyCon -> Infinite Role+tyConRolesRepresentational tc = tyConRoles tc Inf.++ Inf.repeat Nominal -nthRole :: Role -> TyCon -> Int -> Role-nthRole Nominal _ _ = Nominal-nthRole Phantom _ _ = Phantom-nthRole Representational tc n- = (tyConRolesRepresentational tc) `getNth` n+-- Returns the roles of the parameters of a tycon, with an infinite tail+-- of Nominal+tyConRoleListRepresentational :: TyCon -> [Role]+tyConRoleListRepresentational = Inf.toList . tyConRolesRepresentational +tyConRole :: Role -> TyCon -> Int -> Role+tyConRole Nominal _ _ = Nominal+tyConRole Phantom _ _ = Phantom+tyConRole Representational tc n = tyConRolesRepresentational tc Inf.!! n++funRole :: Role -> FunSel -> Role+funRole Nominal _ = Nominal+funRole Phantom _ = Phantom+funRole Representational fs = funRoleRepresentational fs++funRoleRepresentational :: FunSel -> Role+funRoleRepresentational SelMult = Nominal+funRoleRepresentational SelArg = Representational+funRoleRepresentational SelRes = Representational+ ltRole :: Role -> Role -> Bool -- Is one role "less" than another? -- Nominal < Representational < Phantom@@ -1432,20 +1434,18 @@ -- First cases handles anything that should yield refl. promoteCoercion co = case co of - _ | ki1 `eqType` ki2- -> mkNomReflCo (typeKind ty1)- -- no later branch should return refl- -- The assert (False )s throughout- -- are these cases explicitly, but they should never fire.-- Refl _ -> assert False $- mkNomReflCo ki1+ Refl _ -> mkNomReflCo ki1 - GRefl _ _ MRefl -> assert False $- mkNomReflCo ki1+ GRefl _ _ MRefl -> mkNomReflCo ki1 GRefl _ _ (MCo co) -> co + _ | ki1 `eqType` ki2+ -> mkNomReflCo (typeKind ty1)+ -- No later branch should return refl+ -- The assert (False )s throughout+ -- are these cases explicitly, but they should never fire.+ TyConAppCo _ tc args | Just co' <- instCoercions (mkNomReflCo (tyConKind tc)) args -> co'@@ -1463,14 +1463,19 @@ | isTyVar tv -> promoteCoercion g - ForAllCo _ _ _+ ForAllCo {} -> assert False $+ -- (ForAllCo {} :: (forall cv.t1) ~ (forall cv.t2)+ -- The tyvar case is handled above, so the bound var is a+ -- a coercion variable. So both sides have kind Type+ -- (Note [Weird typing rule for ForAllTy] in GHC.Core.TyCo.Rep).+ -- So the result is Refl, and that should have been caught by+ -- the first equation above mkNomReflCo liftedTypeKind- -- See Note [Weird typing rule for ForAllTy] in GHC.Core.TyCo.Rep - FunCo _ _ _ _- -> assert False $- mkNomReflCo liftedTypeKind+ FunCo {} -> mkKindCo co+ -- We can get Type~Constraint or Constraint~Type+ -- from FunCo {} :: (a -> (b::Type)) ~ (a -=> (b'::Constraint)) CoVarCo {} -> mkKindCo co HoleCo {} -> mkKindCo co@@ -1488,14 +1493,9 @@ TransCo co1 co2 -> mkTransCo (promoteCoercion co1) (promoteCoercion co2) - NthCo _ n co1- | Just (_, args) <- splitTyConAppCo_maybe co1- , args `lengthExceeds` n- -> promoteCoercion (args !! n)-- | Just _ <- splitForAllCo_maybe co- , n == 0- -> assert False $ mkNomReflCo liftedTypeKind+ SelCo n co1+ | Just co' <- mkSelCo_maybe n co1+ -> promoteCoercion co' | otherwise -> mkKindCo co@@ -1519,7 +1519,7 @@ -- See Note [Weird typing rule for ForAllTy] in GHC.Core.TyCo.Rep KindCo _- -> assert False $+ -> assert False $ -- See the first equation above mkNomReflCo liftedTypeKind SubCo g@@ -1547,10 +1547,12 @@ -- w :: s1 ~ s2 -- returns mkInstCo g w' :: t2 [t1 |-> s1 ] ~ t3 [t1 |-> s2] = Just $ mkInstCo g w'+ | isFunTy lty && isFunTy rty -- g :: (t1 -> t2) ~ (t3 -> t4) -- returns t2 ~ t4- = Just $ mkNthCo Nominal 4 g -- extract result type, which is the 5th argument to (->)+ = Just $ mkSelCo (SelFun SelRes) g -- extract result type+ | otherwise -- one forall, one funty... = Nothing @@ -1619,17 +1621,18 @@ -- want it to be r. It is only called in 'mkPiCos', which is -- only used in GHC.Core.Opt.Simplify.Utils, where we are sure for -- now (Aug 2018) v won't occur in co.- mkFunResCo r scaled_ty co- | otherwise = mkFunResCo r scaled_ty co- where- scaled_ty = Scaled (varMult v) (varType v)+ mkFunResCo r v co+ | otherwise = mkFunResCo r v co -mkFunResCo :: Role -> Scaled Type -> Coercion -> Coercion--- Given res_co :: res1 -> res2,+mkFunResCo :: Role -> Id -> Coercion -> Coercion+-- Given res_co :: res1 ~ res2, -- mkFunResCo r m arg res_co :: (arg -> res1) ~r (arg -> res2) -- Reflexive in the multiplicity argument-mkFunResCo role (Scaled mult arg_ty) res_co- = mkFunCo role (multToCo mult) (mkReflCo role arg_ty) res_co+mkFunResCo role id res_co+ = mkFunCoNoFTF role mult arg_co res_co+ where+ arg_co = mkReflCo role (varType id)+ mult = multToCo (varMult id) -- mkCoCast (c :: s1 ~?r t1) (g :: (s1 ~?r t1) ~#R (s2 ~?r t2)) :: s2 ~?r t2 -- The first coercion might be lifted or unlifted; thus the ~? above@@ -1835,7 +1838,7 @@ We want to push the coercion inside the constructor application. So we do this - g' :: t1~t2 = Nth 0 g+ g' :: t1~t2 = SelCo (SelTyCon 0) g case K @t2 (x |> g' -> Maybe g') of K (y:t2 -> Maybe t2) -> rhs@@ -1852,7 +1855,7 @@ Note [extendLiftingContextEx] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider we have datatype- K :: \/k. \/a::k. P -> T k -- P be some type+ K :: /\k. /\a::k. P -> T k -- P be some type g :: T k1 ~ T k2 case (K @k1 @t1 x) |> g of@@ -1860,7 +1863,7 @@ We want to push the coercion inside the constructor application. We first get the coercion mapped by the universal type variable k:- lc = k |-> Nth 0 g :: k1~k2+ lc = k |-> SelCo (SelTyCon 0) g :: k1~k2 Here, the important point is that the kind of a is coerced, and P might be dependent on the existential type variable a.@@ -2027,14 +2030,14 @@ = go role ty where go :: Role -> Type -> Coercion- go r ty | Just ty' <- coreView ty- = go r ty'- go Phantom ty = lift_phantom ty- go r (TyVarTy tv) = expectJust "ty_co_subst bad roles" $- liftCoSubstTyVar lc r tv- go r (AppTy ty1 ty2) = mkAppCo (go r ty1) (go Nominal ty2)- go r (TyConApp tc tys) = mkTyConAppCo r tc (zipWith go (tyConRolesX r tc) tys)- go r (FunTy _ w ty1 ty2) = mkFunCo r (go Nominal w) (go r ty1) (go r ty2)+ go r ty | Just ty' <- coreView ty+ = go r ty'+ go Phantom ty = lift_phantom ty+ go r (TyVarTy tv) = expectJust "ty_co_subst bad roles" $+ liftCoSubstTyVar lc r tv+ go r (AppTy ty1 ty2) = mkAppCo (go r ty1) (go Nominal ty2)+ go r (TyConApp tc tys) = mkTyConAppCo r tc (zipWith go (tyConRoleListX r tc) tys)+ go r (FunTy af w t1 t2) = mkFunCo1 r af (go Nominal w) (go r t1) (go r t2) go r t@(ForAllTy (Bndr v _) ty) = let (lc', v', h) = liftCoSubstVarBndr lc v body_co = ty_co_subst lc' r ty in@@ -2192,8 +2195,8 @@ role = coVarRole old_var eta' = downgradeRole role Nominal eta- eta1 = mkNthCo role 2 eta'- eta2 = mkNthCo role 3 eta'+ eta1 = mkSelCo (SelTyCon 2 role) eta'+ eta2 = mkSelCo (SelTyCon 3 role) eta' co1 = mkCoVarCo new_var co2 = mkSymCo eta1 `mkTransCo` co1 `mkTransCo` eta2@@ -2285,7 +2288,8 @@ seqCo (AppCo co1 co2) = seqCo co1 `seq` seqCo co2 seqCo (ForAllCo tv k co) = seqType (varType tv) `seq` seqCo k `seq` seqCo co-seqCo (FunCo r w co1 co2) = r `seq` seqCo w `seq` seqCo co1 `seq` seqCo co2+seqCo (FunCo r af1 af2 w co1 co2) = r `seq` af1 `seq` af2 `seq`+ seqCo w `seq` seqCo co1 `seq` seqCo co2 seqCo (CoVarCo cv) = cv `seq` () seqCo (HoleCo h) = coHoleCoVar h `seq` () seqCo (AxiomInstCo con ind cos) = con `seq` ind `seq` seqCos cos@@ -2293,7 +2297,7 @@ = seqProv p `seq` r `seq` seqType t1 `seq` seqType t2 seqCo (SymCo co) = seqCo co seqCo (TransCo co1 co2) = seqCo co1 `seq` seqCo co2-seqCo (NthCo r n co) = r `seq` n `seq` seqCo co+seqCo (SelCo n co) = n `seq` seqCo co seqCo (LRCo lr co) = lr `seq` seqCo co seqCo (InstCo co arg) = seqCo co `seq` seqCo arg seqCo (KindCo co) = seqCo co@@ -2344,25 +2348,27 @@ coercionLKind co = go co where- go (Refl ty) = ty- go (GRefl _ ty _) = ty- go (TyConAppCo _ tc cos) = mkTyConApp tc (map go cos)- go (AppCo co1 co2) = mkAppTy (go co1) (go co2)- go (ForAllCo tv1 _ co1) = mkTyCoInvForAllTy tv1 (go co1)- go (FunCo _ w co1 co2) = mkFunctionType (go w) (go co1) (go co2)- go (CoVarCo cv) = coVarLType cv- go (HoleCo h) = coVarLType (coHoleCoVar h)- go (UnivCo _ _ ty1 _) = ty1- go (SymCo co) = coercionRKind co- go (TransCo co1 _) = go co1- go (LRCo lr co) = pickLR lr (splitAppTy (go co))- go (InstCo aco arg) = go_app aco [go arg]- go (KindCo co) = typeKind (go co)- go (SubCo co) = go co- go (NthCo _ d co) = go_nth d (go co)- go (AxiomInstCo ax ind cos) = go_ax_inst ax ind (map go cos)- go (AxiomRuleCo ax cos) = pFst $ expectJust "coercionKind" $- coaxrProves ax $ map coercionKind cos+ go (Refl ty) = ty+ go (GRefl _ ty _) = ty+ go (TyConAppCo _ tc cos) = mkTyConApp tc (map go cos)+ go (AppCo co1 co2) = mkAppTy (go co1) (go co2)+ go (ForAllCo tv1 _ co1) = mkTyCoInvForAllTy tv1 (go co1)+ go (FunCo { fco_afl = af, fco_mult = mult, fco_arg = arg, fco_res = res})+ {- See Note [FunCo] -} = FunTy { ft_af = af, ft_mult = go mult+ , ft_arg = go arg, ft_res = go res }+ go (CoVarCo cv) = coVarLType cv+ go (HoleCo h) = coVarLType (coHoleCoVar h)+ go (UnivCo _ _ ty1 _) = ty1+ go (SymCo co) = coercionRKind co+ go (TransCo co1 _) = go co1+ go (LRCo lr co) = pickLR lr (splitAppTy (go co))+ go (InstCo aco arg) = go_app aco [go arg]+ go (KindCo co) = typeKind (go co)+ go (SubCo co) = go co+ go (SelCo d co) = getNthFromType d (go co)+ go (AxiomInstCo ax ind cos) = go_ax_inst ax ind (map go cos)+ go (AxiomRuleCo ax cos) = pFst $ expectJust "coercionKind" $+ coaxrProves ax $ map coercionKind cos go_ax_inst ax ind tys | CoAxBranch { cab_tvs = tvs, cab_cvs = cvs@@ -2382,42 +2388,48 @@ go_app (InstCo co arg) args = go_app co (go arg:args) go_app co args = piResultTys (go co) args -go_nth :: Int -> Type -> Type-go_nth d ty+getNthFromType :: HasDebugCallStack => CoSel -> Type -> Type+getNthFromType (SelFun fs) ty+ | Just (_af, mult, arg, res) <- splitFunTy_maybe ty+ = getNthFun fs mult arg res++getNthFromType (SelTyCon n _) ty | Just args <- tyConAppArgs_maybe ty- = assert (args `lengthExceeds` d) $- args `getNth` d+ = assertPpr (args `lengthExceeds` n) (ppr n $$ ppr ty) $+ args `getNth` n - | d == 0- , Just (tv,_) <- splitForAllTyCoVar_maybe ty+getNthFromType SelForAll ty -- Works for both tyvar and covar+ | Just (tv,_) <- splitForAllTyCoVar_maybe ty = tyVarKind tv - | otherwise- = pprPanic "coercionLKind:nth" (ppr d <+> ppr ty)+getNthFromType cs ty+ = pprPanic "getNthFromType" (ppr cs $$ ppr ty) coercionRKind :: Coercion -> Type coercionRKind co = go co where- go (Refl ty) = ty- go (GRefl _ ty MRefl) = ty- go (GRefl _ ty (MCo co1)) = mkCastTy ty co1- go (TyConAppCo _ tc cos) = mkTyConApp tc (map go cos)- go (AppCo co1 co2) = mkAppTy (go co1) (go co2)- go (CoVarCo cv) = coVarRType cv- go (HoleCo h) = coVarRType (coHoleCoVar h)- go (FunCo _ w co1 co2) = mkFunctionType (go w) (go co1) (go co2)- go (UnivCo _ _ _ ty2) = ty2- go (SymCo co) = coercionLKind co- go (TransCo _ co2) = go co2- go (LRCo lr co) = pickLR lr (splitAppTy (go co))- go (InstCo aco arg) = go_app aco [go arg]- go (KindCo co) = typeKind (go co)- go (SubCo co) = go co- go (NthCo _ d co) = go_nth d (go co)- go (AxiomInstCo ax ind cos) = go_ax_inst ax ind (map go cos)- go (AxiomRuleCo ax cos) = pSnd $ expectJust "coercionKind" $- coaxrProves ax $ map coercionKind cos+ go (Refl ty) = ty+ go (GRefl _ ty MRefl) = ty+ go (GRefl _ ty (MCo co1)) = mkCastTy ty co1+ go (TyConAppCo _ tc cos) = mkTyConApp tc (map go cos)+ go (AppCo co1 co2) = mkAppTy (go co1) (go co2)+ go (CoVarCo cv) = coVarRType cv+ go (HoleCo h) = coVarRType (coHoleCoVar h)+ go (FunCo { fco_afr = af, fco_mult = mult, fco_arg = arg, fco_res = res})+ {- See Note [FunCo] -} = FunTy { ft_af = af, ft_mult = go mult+ , ft_arg = go arg, ft_res = go res }+ go (UnivCo _ _ _ ty2) = ty2+ go (SymCo co) = coercionLKind co+ go (TransCo _ co2) = go co2+ go (LRCo lr co) = pickLR lr (splitAppTy (go co))+ go (InstCo aco arg) = go_app aco [go arg]+ go (KindCo co) = typeKind (go co)+ go (SubCo co) = go co+ go (SelCo d co) = getNthFromType d (go co)+ go (AxiomInstCo ax ind cos) = go_ax_inst ax ind (map go cos)+ go (AxiomRuleCo ax cos) = pSnd $ expectJust "coercionKind" $+ coaxrProves ax $ map coercionKind cos go co@(ForAllCo tv1 k_co co1) -- works for both tyvar and covar | isGReflCo k_co = mkTyCoInvForAllTy tv1 (go co1)@@ -2459,10 +2471,11 @@ | isCoVar cv1 = mkTyCoInvForAllTy cv2 (go_forall subst' co) where- k2 = coercionRKind k_co- r = coVarRole cv1- eta1 = mkNthCo r 2 (downgradeRole r Nominal k_co)- eta2 = mkNthCo r 3 (downgradeRole r Nominal k_co)+ k2 = coercionRKind k_co+ r = coVarRole cv1+ k_co' = downgradeRole r Nominal k_co+ eta1 = mkSelCo (SelTyCon 2 r) k_co'+ eta2 = mkSelCo (SelTyCon 3 r) k_co' -- k_co :: (t1 ~r t2) ~N (s1 ~r s2) -- k1 = t1 ~r t2@@ -2509,14 +2522,16 @@ go (TyConAppCo r _ _) = r go (AppCo co1 _) = go co1 go (ForAllCo _ _ co) = go co- go (FunCo r _ _ _) = r+ go (FunCo { fco_role = r }) = r go (CoVarCo cv) = coVarRole cv go (HoleCo h) = coVarRole (coHoleCoVar h) go (AxiomInstCo ax _ _) = coAxiomRole ax go (UnivCo _ r _ _) = r go (SymCo co) = go co go (TransCo co1 _co2) = go co1- go (NthCo r _d _co) = r+ go (SelCo SelForAll _co) = Nominal+ go (SelCo (SelTyCon _ r) _co) = r+ go (SelCo (SelFun fs) co) = funRole (coercionRole co) fs go (LRCo {}) = Nominal go (InstCo co _) = go co go (KindCo {}) = Nominal@@ -2610,20 +2625,21 @@ ; _ -> False }) $ mkNomReflCo ty1 - go (FunTy { ft_mult = w1, ft_arg = arg1, ft_res = res1 })- (FunTy { ft_mult = w2, ft_arg = arg2, ft_res = res2 })- = mkFunCo Nominal (go w1 w2) (go arg1 arg2) (go res1 res2)+ go (FunTy { ft_af = af1, ft_mult = w1, ft_arg = arg1, ft_res = res1 })+ (FunTy { ft_af = af2, ft_mult = w2, ft_arg = arg2, ft_res = res2 })+ = assert (af1 == af2) $+ mkFunCo1 Nominal af1 (go w1 w2) (go arg1 arg2) (go res1 res2) go (TyConApp tc1 args1) (TyConApp tc2 args2) = assert (tc1 == tc2) $ mkTyConAppCo Nominal tc1 (zipWith go args1 args2) go (AppTy ty1a ty1b) ty2- | Just (ty2a, ty2b) <- repSplitAppTy_maybe ty2+ | Just (ty2a, ty2b) <- splitAppTyNoView_maybe ty2 = mkAppCo (go ty1a ty2a) (go ty1b ty2b) go ty1 (AppTy ty2a ty2b)- | Just (ty1a, ty1b) <- repSplitAppTy_maybe ty1+ | Just (ty1a, ty1b) <- splitAppTyNoView_maybe ty1 = mkAppCo (go ty1a ty2a) (go ty1b ty2b) go (ForAllTy (Bndr tv1 _flag1) ty1) (ForAllTy (Bndr tv2 _flag2) ty2)@@ -2651,8 +2667,8 @@ r = coVarRole cv1 kind_co' = downgradeRole r Nominal kind_co- eta1 = mkNthCo r 2 kind_co'- eta2 = mkNthCo r 3 kind_co'+ eta1 = mkSelCo (SelTyCon 2 r) kind_co'+ eta2 = mkSelCo (SelTyCon 3 r) kind_co' subst = mkEmptySubst $ mkInScopeSet $ tyCoVarsOfType ty2 `unionVarSet` tyCoVarsOfCo kind_co
compiler/GHC/Core/Coercion.hs-boot view
@@ -17,14 +17,16 @@ mkTyConAppCo :: HasDebugCallStack => Role -> TyCon -> [Coercion] -> Coercion mkAppCo :: Coercion -> Coercion -> Coercion mkForAllCo :: TyCoVar -> Coercion -> Coercion -> Coercion-mkFunCo :: Role -> CoercionN -> Coercion -> Coercion -> Coercion+mkFunCo1 :: HasDebugCallStack => Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion+mkNakedFunCo1 :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion+mkFunCo2 :: HasDebugCallStack => Role -> FunTyFlag -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion mkCoVarCo :: CoVar -> Coercion mkAxiomInstCo :: CoAxiom Branched -> BranchIndex -> [Coercion] -> Coercion mkPhantomCo :: Coercion -> Type -> Type -> Coercion mkUnivCo :: UnivCoProvenance -> Role -> Type -> Type -> Coercion mkSymCo :: Coercion -> Coercion mkTransCo :: Coercion -> Coercion -> Coercion-mkNthCo :: HasDebugCallStack => Role -> Int -> Coercion -> Coercion+mkSelCo :: HasDebugCallStack => CoSel -> Coercion -> Coercion mkLRCo :: LeftOrRight -> Coercion -> Coercion mkInstCo :: Coercion -> Coercion -> Coercion mkGReflCo :: Role -> Type -> MCoercionN -> Coercion
compiler/GHC/Core/Coercion/Opt.hs view
@@ -15,6 +15,7 @@ import GHC.Core.TyCo.Rep import GHC.Core.TyCo.Subst+import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.Coercion import GHC.Core.Type as Type hiding( substTyVarBndr, substTy ) import GHC.Core.TyCon@@ -23,6 +24,7 @@ import GHC.Types.Var.Set import GHC.Types.Var.Env+import GHC.Types.Unique.Set import GHC.Data.Pair import GHC.Data.List.SetOps ( getNth )@@ -32,7 +34,6 @@ import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Panic.Plain-import GHC.Utils.Trace import Control.Monad ( zipWithM ) @@ -123,9 +124,20 @@ -- ^ optCoercion applies a substitution to a coercion, -- *and* optimises it to reduce its size optCoercion opts env co- | optCoercionEnabled opts = optCoercion' env co- | otherwise = substCo env co+ | optCoercionEnabled opts+ = optCoercion' env co+{-+ = pprTrace "optCoercion {" (text "Co:" <+> ppr co) $+ let result = optCoercion' env co in+ pprTrace "optCoercion }" (vcat [ text "Co:" <+> ppr co+ , text "Optco:" <+> ppr result ]) $+ result+-} + | otherwise+ = substCo env co++ optCoercion' :: Subst -> Coercion -> NormalCo optCoercion' env co | debugIsOn@@ -136,19 +148,23 @@ assertPpr (substTyUnchecked env in_ty1 `eqType` out_ty1 && substTyUnchecked env in_ty2 `eqType` out_ty2 && in_role == out_role)- ( text "optCoercion changed types!"- $$ hang (text "in_co:") 2 (ppr co)- $$ hang (text "in_ty1:") 2 (ppr in_ty1)- $$ hang (text "in_ty2:") 2 (ppr in_ty2)- $$ hang (text "out_co:") 2 (ppr out_co)- $$ hang (text "out_ty1:") 2 (ppr out_ty1)- $$ hang (text "out_ty2:") 2 (ppr out_ty2)- $$ hang (text "subst:") 2 (ppr env))- out_co+ (hang (text "optCoercion changed types!")+ 2 (vcat [ text "in_co:" <+> ppr co+ , text "in_ty1:" <+> ppr in_ty1+ , text "in_ty2:" <+> ppr in_ty2+ , text "out_co:" <+> ppr out_co+ , text "out_ty1:" <+> ppr out_ty1+ , text "out_ty2:" <+> ppr out_ty2+ , text "in_role:" <+> ppr in_role+ , text "out_role:" <+> ppr out_role+ , vcat $ map ppr_one $ nonDetEltsUniqSet $ coVarsOfCo co+ , text "subst:" <+> ppr env ]))+ out_co | otherwise = opt_co1 lc False co where lc = mkSubstLiftingContext env+ ppr_one cv = ppr cv <+> dcolon <+> ppr (coVarKind cv) type NormalCo = Coercion@@ -191,9 +207,12 @@ -- See Note [Optimising coercion optimisation] -- | Optimize a non-phantom coercion.-opt_co4, opt_co4_wrap :: LiftingContext -> SymFlag -> ReprFlag -> Role -> Coercion -> NormalCo-+opt_co4, opt_co4_wrap :: LiftingContext -> SymFlag -> ReprFlag+ -> Role -> Coercion -> NormalCo+-- Precondition: In every call (opt_co4 lc sym rep role co)+-- we should have role = coercionRole co opt_co4_wrap = opt_co4+ {- opt_co4_wrap env sym rep r co = pprTrace "opt_co4_wrap {"@@ -201,12 +220,13 @@ , text "Rep:" <+> ppr rep , text "Role:" <+> ppr r , text "Co:" <+> ppr co ]) $- assert (r == coercionRole co )+ assert (r == coercionRole co ) $ let result = opt_co4 env sym rep r co in pprTrace "opt_co4_wrap }" (ppr co $$ text "---" $$ ppr result) $ result -} + opt_co4 env _ rep r (Refl ty) = assertPpr (r == Nominal) (text "Expected role:" <+> ppr r $$@@ -246,7 +266,7 @@ (True, Nominal) -> mkTyConAppCo Representational tc (zipWith3 (opt_co3 env sym)- (map Just (tyConRolesRepresentational tc))+ (map Just (tyConRoleListRepresentational tc)) (repeat Nominal) cos) (False, Nominal) ->@@ -255,7 +275,7 @@ -- must use opt_co2 here, because some roles may be P -- See Note [Optimising coercion optimisation] mkTyConAppCo r tc (zipWith (opt_co2 env sym)- (tyConRolesRepresentational tc) -- the current roles+ (tyConRoleListRepresentational tc) -- the current roles cos) (_, Phantom) -> pprPanic "opt_co4 sees a phantom!" (ppr g) @@ -269,15 +289,17 @@ opt_co4_wrap env' sym rep r co -- Use the "mk" functions to check for nested Refls -opt_co4 env sym rep r (FunCo _r cow co1 co2)+opt_co4 env sym rep r (FunCo _r afl afr cow co1 co2) = assert (r == _r) $- if rep- then mkFunCo Representational cow' co1' co2'- else mkFunCo r cow' co1' co2'+ mkFunCo2 r' afl' afr' cow' co1' co2' where co1' = opt_co4_wrap env sym rep r co1 co2' = opt_co4_wrap env sym rep r co2 cow' = opt_co1 env sym cow+ !r' | rep = Representational+ | otherwise = r+ !(afl', afr') | sym = (afr,afl)+ | otherwise = (afl,afr) opt_co4 env sym rep r (CoVarCo cv) | Just co <- lookupCoVar (lcSubst env) cv@@ -333,38 +355,29 @@ co2' = opt_co4_wrap env sym rep r co2 in_scope = lcInScopeSet env -opt_co4 env _sym rep r (NthCo _r n co)- | Just (ty, _) <- isReflCo_maybe co- , Just (_tc, args) <- assert (r == _r )- splitTyConApp_maybe ty- = liftCoSubst (chooseRole rep r) env (args `getNth` n)-- | Just (ty, _) <- isReflCo_maybe co- , n == 0- , Just (tv, _) <- splitForAllTyCoVar_maybe ty- -- works for both tyvar and covar- = liftCoSubst (chooseRole rep r) env (varType tv)+opt_co4 env _sym rep r (SelCo n co)+ | Just (ty, _co_role) <- isReflCo_maybe co+ = liftCoSubst (chooseRole rep r) env (getNthFromType n ty)+ -- NB: it is /not/ true that r = _co_role+ -- Rather, r = coercionRole (SelCo n co) -opt_co4 env sym rep r (NthCo r1 n (TyConAppCo _ _ cos))+opt_co4 env sym rep r (SelCo (SelTyCon n r1) (TyConAppCo _ _ cos)) = assert (r == r1 ) opt_co4_wrap env sym rep r (cos `getNth` n) -- see the definition of GHC.Builtin.Types.Prim.funTyCon-opt_co4 env sym rep r (NthCo r1 n (FunCo _r2 w co1 co2))- = assert (r == r1 )- opt_co4_wrap env sym rep r (mkNthCoFunCo n w co1 co2)+opt_co4 env sym rep r (SelCo (SelFun fs) (FunCo _r2 _afl _afr w co1 co2))+ = opt_co4_wrap env sym rep r (getNthFun fs w co1 co2) -opt_co4 env sym rep r (NthCo _r n (ForAllCo _ eta _))+opt_co4 env sym rep _ (SelCo SelForAll (ForAllCo _ eta _)) -- works for both tyvar and covar- = assert (r == _r )- assert (n == 0 )- opt_co4_wrap env sym rep Nominal eta+ = opt_co4_wrap env sym rep Nominal eta -opt_co4 env sym rep r (NthCo _r n co)- | Just nth_co <- case co' of- TyConAppCo _ _ cos -> Just (cos `getNth` n)- FunCo _ w co1 co2 -> Just (mkNthCoFunCo n w co1 co2)- ForAllCo _ eta _ -> Just eta+opt_co4 env sym rep r (SelCo n co)+ | Just nth_co <- case (co', n) of+ (TyConAppCo _ _ cos, SelTyCon n _) -> Just (cos `getNth` n)+ (FunCo _ _ _ w co1 co2, SelFun fs) -> Just (getNthFun fs w co1 co2)+ (ForAllCo _ eta _, SelForAll) -> Just eta _ -> Nothing = if rep && (r == Nominal) -- keep propagating the SubCo@@ -372,7 +385,7 @@ else nth_co | otherwise- = wrapRole rep r $ NthCo r n co'+ = wrapRole rep r $ SelCo n co' where co' = opt_co1 env sym co @@ -455,8 +468,8 @@ -- new_co = (h1 :: t1 ~ t2) ~ ((n1;h2;sym n2) :: t1 ~ t2) r2 = coVarRole cv kind_co' = downgradeRole r2 Nominal kind_co- n1 = mkNthCo r2 2 kind_co'- n2 = mkNthCo r2 3 kind_co'+ n1 = mkSelCo (SelTyCon 2 r2) kind_co'+ n2 = mkSelCo (SelTyCon 3 r2) kind_co' in mkProofIrrelCo Nominal (Refl (coercionType h1)) h1 (n1 `mkTransCo` h2 `mkTransCo` (mkSymCo n2)) @@ -547,7 +560,7 @@ , equalLength tys1 tys2 -- see Note [Differing kinds] -- NB: prov must not be the two interesting ones (ProofIrrel & Phantom); -- Phantom is already taken care of, and ProofIrrel doesn't relate tyconapps- = let roles = tyConRolesX role tc1+ = let roles = tyConRoleListX role tc1 arg_cos = zipWith3 (mkUnivCo prov') roles tys1 tys2 arg_cos' = zipWith (opt_co4 env sym False) roles arg_cos in@@ -577,9 +590,9 @@ eta = mkUnivCo prov' Nominal k1 k2 eta_d = downgradeRole r' Nominal eta -- eta gets opt'ed soon, but not yet.- n_co = (mkSymCo $ mkNthCo r' 2 eta_d) `mkTransCo`+ n_co = (mkSymCo $ mkSelCo (SelTyCon 2 r') eta_d) `mkTransCo` (mkCoVarCo cv1) `mkTransCo`- (mkNthCo r' 3 eta_d)+ (mkSelCo (SelTyCon 3 r') eta_d) ty2' = substTyWithCoVars [cv2] [n_co] ty2 (env', cv1', eta') = optForAllCoBndr env sym cv1 eta@@ -651,13 +664,12 @@ mkGReflRightCo r1 t1 (opt_trans is co1 co2) -- Push transitivity through matching destructors-opt_trans_rule is in_co1@(NthCo r1 d1 co1) in_co2@(NthCo r2 d2 co2)+opt_trans_rule is in_co1@(SelCo d1 co1) in_co2@(SelCo d2 co2) | d1 == d2 , coercionRole co1 == coercionRole co2 , co1 `compatible_co` co2- = assert (r1 == r2) $- fireTransRule "PushNth" in_co1 in_co2 $- mkNthCo r1 d1 (opt_trans is co1 co2)+ = fireTransRule "PushNth" in_co1 in_co2 $+ mkSelCo d1 (opt_trans is co1 co2) opt_trans_rule is in_co1@(LRCo d1 co1) in_co2@(LRCo d2 co2) | d1 == d2@@ -694,10 +706,14 @@ fireTransRule "PushTyConApp" in_co1 in_co2 $ mkTyConAppCo r1 tc1 (opt_transList is cos1 cos2) -opt_trans_rule is in_co1@(FunCo r1 w1 co1a co1b) in_co2@(FunCo r2 w2 co2a co2b)- = assert (r1 == r2) $ -- Just like the TyConAppCo/TyConAppCo case+opt_trans_rule is in_co1@(FunCo r1 afl1 afr1 w1 co1a co1b)+ in_co2@(FunCo r2 afl2 afr2 w2 co2a co2b)+ = assert (r1 == r2) $ -- Just like the TyConAppCo/TyConAppCo case+ assert (afr1 == afl2) $ fireTransRule "PushFun" in_co1 in_co2 $- mkFunCo r1 (opt_trans is w1 w2) (opt_trans is co1a co2a) (opt_trans is co1b co2b)+ mkFunCo2 r1 afl1 afr2 (opt_trans is w1 w2)+ (opt_trans is co1a co2a)+ (opt_trans is co1b co2b) opt_trans_rule is in_co1@(AppCo co1a co1b) in_co2@(AppCo co2a co2b) -- Must call opt_trans_rule_app; see Note [EtaAppCo]@@ -772,8 +788,8 @@ is' = is `extendInScopeSet` cv1 role = coVarRole cv1 eta1' = downgradeRole role Nominal eta1- n1 = mkNthCo role 2 eta1'- n2 = mkNthCo role 3 eta1'+ n1 = mkSelCo (SelTyCon 2 role) eta1'+ n2 = mkSelCo (SelTyCon 3 role) eta1' r2' = substCo (zipCvSubst [cv2] [(mkSymCo n1) `mkTransCo` (mkCoVarCo cv1) `mkTransCo` n2]) r2@@ -1134,9 +1150,9 @@ Here, - h1 = mkNthCo Nominal 0 g :: (s1~s2)~(s3~s4)- eta1 = mkNthCo r 2 h1 :: (s1 ~ s3)- eta2 = mkNthCo r 3 h1 :: (s2 ~ s4)+ h1 = mkSelCo Nominal 0 g :: (s1~s2)~(s3~s4)+ eta1 = mkSelCo (SelTyCon 2 r) h1 :: (s1 ~ s3)+ eta2 = mkSelCo (SelTyCon 3 r) h1 :: (s2 ~ s4) h2 = mkInstCo g (cv1 ~ (sym eta1;c1;eta2)) -} etaForAllCo_ty_maybe :: Coercion -> Maybe (TyVar, Coercion, Coercion)@@ -1148,7 +1164,7 @@ | Pair ty1 ty2 <- coercionKind co , Just (tv1, _) <- splitForAllTyVar_maybe ty1 , isForAllTy_ty ty2- , let kind_co = mkNthCo Nominal 0 co+ , let kind_co = mkSelCo SelForAll co = Just ( tv1, kind_co , mkInstCo co (mkGReflRightCo Nominal (TyVarTy tv1) kind_co)) @@ -1164,13 +1180,13 @@ | Pair ty1 ty2 <- coercionKind co , Just (cv1, _) <- splitForAllCoVar_maybe ty1 , isForAllTy_co ty2- = let kind_co = mkNthCo Nominal 0 co+ = let kind_co = mkSelCo SelForAll co r = coVarRole cv1 l_co = mkCoVarCo cv1 kind_co' = downgradeRole r Nominal kind_co- r_co = (mkSymCo (mkNthCo r 2 kind_co')) `mkTransCo`- l_co `mkTransCo`- (mkNthCo r 3 kind_co')+ r_co = mkSymCo (mkSelCo (SelTyCon 2 r) kind_co')+ `mkTransCo` l_co+ `mkTransCo` mkSelCo (SelTyCon 3 r) kind_co' in Just ( cv1, kind_co , mkInstCo co (mkProofIrrelCo Nominal kind_co l_co r_co)) @@ -1197,17 +1213,19 @@ etaTyConAppCo_maybe :: TyCon -> Coercion -> Maybe [Coercion] -- If possible, split a coercion -- g :: T s1 .. sn ~ T t1 .. tn--- into [ Nth 0 g :: s1~t1, ..., Nth (n-1) g :: sn~tn ]+-- into [ SelCo (SelTyCon 0) g :: s1~t1+-- , ...+-- , SelCo (SelTyCon (n-1)) g :: sn~tn ] etaTyConAppCo_maybe tc (TyConAppCo _ tc2 cos2) = assert (tc == tc2) $ Just cos2 etaTyConAppCo_maybe tc co- | not (mustBeSaturated tc)+ | not (tyConMustBeSaturated tc) , (Pair ty1 ty2, r) <- coercionKindRole co , Just (tc1, tys1) <- splitTyConApp_maybe ty1 , Just (tc2, tys2) <- splitTyConApp_maybe ty2 , tc1 == tc2- , isInjectiveTyCon tc r -- See Note [NthCo and newtypes] in GHC.Core.TyCo.Rep+ , isInjectiveTyCon tc r -- See Note [SelCo and newtypes] in GHC.Core.TyCo.Rep , let n = length tys1 , tys2 `lengthIs` n -- This can fail in an erroneous program -- E.g. T a ~# T a b
compiler/GHC/Core/ConLike.hs view
@@ -185,10 +185,14 @@ -- -- 7) The original result type conLikeFullSig :: ConLike- -> ([TyVar], [TyCoVar], [EqSpec]+ -> ([TyVar], [TyCoVar] -- Why tyvars for universal but tycovars for existential? -- See Note [Existential coercion variables] in GHC.Core.DataCon- , ThetaType, ThetaType, [Scaled Type], Type)+ , [EqSpec]+ , ThetaType -- Provided theta+ , ThetaType -- Required theta+ , [Scaled Type] -- Arguments+ , Type ) -- Result conLikeFullSig (RealDataCon con) = let (univ_tvs, ex_tvs, eq_spec, theta, arg_tys, res_ty) = dataConFullSig con -- Required theta is empty as normal data cons require no additional
compiler/GHC/Core/DataCon.hs view
@@ -20,7 +20,6 @@ -- ** Equality specs EqSpec, mkEqSpec, eqSpecTyVar, eqSpecType, eqSpecPair, eqSpecPreds,- substEqSpec, filterEqSpec, -- ** Field labels FieldLabel(..), FieldLabelString,@@ -37,11 +36,11 @@ dataConDisplayType, dataConUnivTyVars, dataConExTyCoVars, dataConUnivAndExTyCoVars, dataConUserTyVars, dataConUserTyVarBinders,- dataConEqSpec, dataConTheta,+ dataConTheta, dataConStupidTheta, dataConOtherTheta, dataConInstArgTys, dataConOrigArgTys, dataConOrigResTy,- dataConInstOrigArgTys, dataConRepArgTys,+ dataConInstOrigArgTys, dataConRepArgTys, dataConResRepTyArgs, dataConInstUnivs, dataConFieldLabels, dataConFieldType, dataConFieldType_maybe, dataConSrcBangs,@@ -56,10 +55,10 @@ -- ** Predicates on DataCons isNullarySrcDataCon, isNullaryRepDataCon, isTupleDataCon, isBoxedTupleDataCon, isUnboxedTupleDataCon,- isUnboxedSumDataCon,+ isUnboxedSumDataCon, isCovertGadtDataCon, isVanillaDataCon, isNewDataCon, isTypeDataCon, classDataCon, dataConCannotMatch,- dataConUserTyVarsArePermuted,+ dataConUserTyVarsNeedWrapper, checkDataConTyVars, isBanged, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked, specialPromotedDc, @@ -77,6 +76,7 @@ import GHC.Core.Unify import GHC.Core.TyCon import GHC.Core.TyCo.Subst+import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.Multiplicity import {-# SOURCE #-} GHC.Types.TyThing import GHC.Types.FieldLabel@@ -94,7 +94,7 @@ import GHC.Types.Unique.FM ( UniqFM ) import GHC.Types.Unique.Set import GHC.Builtin.Uniques( mkAlphaTyVarUnique )-+import GHC.Data.Graph.UnVar -- UnVarSet and operations import GHC.Utils.Outputable import GHC.Utils.Misc@@ -422,7 +422,7 @@ -- syntax, provided its type looks like the above. -- The declaration format is held in the TyCon (algTcGadtSyntax) - -- Universally-quantified type vars [a,b,c]+ -- dcUnivTyVars: Universally-quantified type vars [a,b,c] -- INVARIANT: length matches arity of the dcRepTyCon -- INVARIANT: result type of data con worker is exactly (T a b c) -- COROLLARY: The dcUnivTyVars are always in one-to-one correspondence with@@ -431,16 +431,16 @@ -- Existentially-quantified type and coercion vars [x,y] -- For an example involving coercion variables,- -- Why tycovars? See Note [Existential coercion variables]+ -- Why TyCoVars? See Note [Existential coercion variables] dcExTyCoVars :: [TyCoVar], -- INVARIANT: the UnivTyVars and ExTyCoVars all have distinct OccNames -- Reason: less confusing, and easier to generate Iface syntax -- The type/coercion vars in the order the user wrote them [c,y,x,b]- -- INVARIANT: the set of tyvars in dcUserTyVarBinders is exactly the set- -- of tyvars (*not* covars) of dcExTyCoVars unioned with the- -- set of dcUnivTyVars whose tyvars do not appear in dcEqSpec+ -- INVARIANT(dataConTyVars): the set of tyvars in dcUserTyVarBinders is+ -- exactly the set of tyvars (*not* covars) of dcExTyCoVars unioned+ -- with the set of dcUnivTyVars whose tyvars do not appear in dcEqSpec -- See Note [DataCon user type variable binders] dcUserTyVarBinders :: [InvisTVBinder], @@ -553,7 +553,7 @@ * Each argument flag is Inferred or Specified. None are Required. (A DataCon is a term-level function; see- Note [No Required TyCoBinder in terms] in GHC.Core.TyCo.Rep.)+ Note [No Required PiTyBinder in terms] in GHC.Core.TyCo.Rep.) Why do we need the TyVarBinders, rather than just the TyVars? So that we can construct the right type for the DataCon with its foralls@@ -565,23 +565,23 @@ Note [Existential coercion variables] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~- For now (Aug 2018) we can't write coercion quantifications in source Haskell, but we can in Core. Consider having: data T :: forall k. k -> k -> Constraint where- MkT :: forall k (a::k) (b::k). forall k' (c::k') (co::k'~k). (b~(c|>co))- => T k a b+ MkT :: forall k (a::k) (b::k).+ forall k' (c::k') (co::k'~k).+ (b ~# (c|>co)) => T k a b dcUnivTyVars = [k,a,b] dcExTyCoVars = [k',c,co] dcUserTyVarBinders = [k,a,k',c]- dcEqSpec = [b~(c|>co)]+ dcEqSpec = [b ~# (c|>co)] dcOtherTheta = [] dcOrigArgTys = [] dcRepTyCon = T - Function call 'dataConKindEqSpec' returns [k'~k]+Function call 'dataConKindEqSpec' returns [k'~k] Note [DataCon arities] ~~~~~~~~~~~~~~~~~~~~~~@@ -593,6 +593,31 @@ Note [DataCon user type variable binders] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+A DataCon has two different sets of type variables:++* dcUserTyVarBinders, for the type variables binders in the order in which they+ originally arose in the user-written type signature.++ - They are the forall'd binders of the data con /wrapper/, which the user calls.++ - Their order *does* matter for TypeApplications, so they are full TyVarBinders,+ complete with visibilities.++* dcUnivTyVars and dcExTyCoVars, for the "true underlying" (i.e. of the data+ con worker) universal type variable and existential type/coercion variables,+ respectively.++ - They (i.e. univ ++ ex) are the forall'd variables of the data con /worker/++ - Their order is irrelevant for the purposes of TypeApplications,+ and as a consequence, they do not come equipped with visibilities+ (that is, they are TyVars/TyCoVars instead of ForAllTyBinders).++Often (dcUnivTyVars ++ dcExTyCoVars) = dcUserTyVarBinders; but they may differ+for three reasons, coming next:++--- Reason (R1): Order of quantification in GADT syntax ---+ In System FC, data constructor type signatures always quantify over all of their universal type variables, followed by their existential type variables. Normally, this isn't a problem, as most datatypes naturally quantify their type@@ -635,36 +660,119 @@ performs a stable topological sort on the type variables in the user-written type signature, which would place `b` before `a`. -But as noted above, enacting this behavior is not entirely trivial, as System-FC demands the variables go in universal-then-existential order under the hood.-Our solution is thus to equip DataCon with two different sets of type-variables:+--- Reason (R2): GADT constructors quantify over different variables --- -* dcUnivTyVars and dcExTyCoVars, for the universal type variable and existential- type/coercion variables, respectively. Their order is irrelevant for the- purposes of TypeApplications, and as a consequence, they do not come equipped- with visibilities (that is, they are TyVars/TyCoVars instead of- TyCoVarBinders).+GADT constructors may quantify over different variables than the worker+would. Consider+ data T a b where+ MkT :: forall c d. c -> T [c] d -* dcUserTyVarBinders, for the type variables binders in the order in which they- originally arose in the user-written type signature. Their order *does* matter- for TypeApplications, so they are full TyVarBinders, complete with- visibilities.+The dcUserTyVarBinders must be [c, d] -- that's what the user quantified over.+But c is actually existential, as it is not equal to either of the two+universal variables. -This encoding has some redundancy. The set of tyvars in dcUserTyVarBinders-consists precisely of:+Here is what we'll get: + dcUserTyVarBinders = [c, d]+ dcUnivTyVars = [a, d]+ dcExTyCoVars = [c]++Note that dcUnivTyVars contains `a` from the type header (the `data T a b`)+and `d` from the signature for MkT. This is done because d is used in place+of b in the result of MkT, and so we use the name d for the universal, as that+might improve error messages. On the other hand, we need to use a fresh name+for the first universal (recalling that the result of a worker must be the+type constructor applied to a sequence of plain variables), so we use `a`, from+the header. This choice of universals is made in GHC.Tc.TyCl.mkGADTVars.++Because c is not a universal, it is an existential. Here, we see that (even+ignoring order) dcUserTyVarBinders is not dcUnivTyVars ⋃ dcExTyCoVars, because+the latter has `a` while the former does not. To understand this better, let's+look at this type for the "true underlying" worker data con:++ MkT :: forall a d. forall c. (a ~# [c]) => c -> T a d++We see here that the `a` universal is connected with the `c` existential via+an equality constraint. It will always be the case (see the code in mkGADTVars)+that the universals not mentioned in dcUserTyVarBinders will be used in a+GADT equality -- that is, used on the left-hand side of an element of dcEqSpec:++ dcEqSpec = [a ~# [c]]++Putting this all together, all variables used on the left-hand side of an+equation in the dcEqSpec will be in dcUnivTyVars but *not* in+dcUserTyVarBinders.++--- Reason (R3): Kind equalities may have been solved ---++Consider now this case:++ type family F a where+ F Type = False+ F _ = True+ type T :: forall k. (F k ~ True) => k -> k -> Type+ data T a b where+ MkT :: T Maybe List++The constraint F k ~ True tells us that T does not want to be indexed by, say,+Int. Now let's consider the Core types involved:++ axiom for F: axF[0] :: F Type ~ False+ axF[1] :: forall a. F a ~ True (a must be apart from Type)+ tycon: T :: forall k. (F k ~ True) -> k -> k -> Type+ wrapper: MkT :: T @(Type -> Type) @(Eq# (axF[1] (Type -> Type)) Maybe List+ worker: MkT :: forall k (c :: F k ~ True) (a :: k) (b :: k).+ (k ~# (Type -> Type), a ~# Maybe, b ~# List) =>+ T @k @c a b++The key observation here is that the worker quantifies over c, while the wrapper+does not. The worker *must* quantify over c, because c is a universal variable,+and the result of the worker must be the type constructor applied to a sequence+of plain type variables. But the wrapper certainly does not need to quantify over+any evidence that F (Type -> Type) ~ True, as no variables are needed there.++(Aside: the c here is a regular type variable, *not* a coercion variable. This+is because F k ~ True is a *lifted* equality, not the unlifted ~#. This is why+we see Eq# in the type of the wrapper: Eq# boxes the unlifted ~# to become a+lifted ~. See also Note [The equality types story] in GHC.Builtin.Types.Prim about+Eq# and Note [Constraints in kinds] in GHC.Core.TyCo.Rep about having this constraint+in the first place.)++In this case, we'll have these fields of the DataCon:++ dcUserTyVarBinders = [] -- the wrapper quantifies over nothing+ dcUnivTyVars = [k, c, a, b]+ dcExTyCoVars = [] -- no existentials here, but a different constructor might have+ dcEqSpec = [k ~# (Type -> Type), a ~# Maybe, b ~# List]++Note that c is in the dcUserTyVars, but mentioned neither in the dcUserTyVarBinders nor+in the dcEqSpec. We thus have Reason (R3): a variable might be missing from the+dcUserTyVarBinders if its type's kind is Constraint.++(At one point, we thought that the dcEqSpec would have to be non-empty. But that+wouldn't account for silly cases like type T :: (True ~ True) => Type.)++--- End of Reasons ---++INVARIANT(dataConTyVars): the set of tyvars in dcUserTyVarBinders+consists of:+ * The set of tyvars in dcUnivTyVars whose type variables do not appear in dcEqSpec, unioned with:+ * The set of tyvars (*not* covars) in dcExTyCoVars No covars here because because they're not user-written +When comparing for equality, we ignore differences concerning type variables+whose kinds have kind Constraint.+ The word "set" is used above because the order in which the tyvars appear in dcUserTyVarBinders can be completely different from the order in dcUnivTyVars or dcExTyCoVars. That is, the tyvars in dcUserTyVarBinders are a permutation of (tyvars of dcExTyCoVars + a subset of dcUnivTyVars). But aside from the ordering, they in fact share the same type variables (with the same Uniques). We-sometimes refer to this as "the dcUserTyVarBinders invariant".+sometimes refer to this as "the dcUserTyVarBinders invariant". It is checked+in checkDataConTyVars. dcUserTyVarBinders, as the name suggests, is the one that users will see most of the time. It's used when computing the type signature of a@@ -767,8 +875,7 @@ -- | An 'EqSpec' is a tyvar/type pair representing an equality made in -- rejigging a GADT constructor-data EqSpec = EqSpec TyVar- Type+data EqSpec = EqSpec TyVar Type -- | Make a non-dependent 'EqSpec' mkEqSpec :: TyVar -> Type -> EqSpec@@ -787,22 +894,6 @@ eqSpecPreds spec = [ mkPrimEqPred (mkTyVarTy tv) ty | EqSpec tv ty <- spec ] --- | Substitute in an 'EqSpec'. Precondition: if the LHS of the EqSpec--- is mapped in the substitution, it is mapped to a type variable, not--- a full type.-substEqSpec :: Subst -> EqSpec -> EqSpec-substEqSpec subst (EqSpec tv ty)- = EqSpec tv' (substTy subst ty)- where- tv' = getTyVar "substEqSpec" (substTyVar subst tv)---- | Filter out any 'TyVar's mentioned in an 'EqSpec'.-filterEqSpec :: [EqSpec] -> [TyVar] -> [TyVar]-filterEqSpec eq_spec- = filter not_in_eq_spec- where- not_in_eq_spec var = all (not . (== var) . eqSpecTyVar) eq_spec- instance Outputable EqSpec where ppr (EqSpec tv ty) = ppr (tv, ty) @@ -810,20 +901,37 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Notice that we do *not* say the worker Id is strict even if the data constructor is declared strict- e.g. data T = MkT !(Int,Int)-Why? Because the *wrapper* $WMkT is strict (and its unfolding has case-expressions that do the evals) but the *worker* MkT itself is not. If we-pretend it is strict then when we see- case x of y -> MkT y-the simplifier thinks that y is "sure to be evaluated" (because the worker MkT-is strict) and drops the case. No, the workerId MkT is not strict.+ e.g. data T = MkT ![Int] Bool+Even though most often the evals are done by the *wrapper* $WMkT, there are+situations in which tag inference will re-insert evals around the worker.+So for all intents and purposes the *worker* MkT is strict, too! -However, the worker does have StrictnessMarks. When the simplifier sees a-pattern- case e of MkT x -> ...-it uses the dataConRepStrictness of MkT to mark x as evaluated; but that's-fine... dataConRepStrictness comes from the data con not from the worker Id.+Unfortunately, if we exposed accurate strictness of DataCon workers, we'd+see the following transformation: + f xs = case xs of xs' { __DEFAULT -> ... case MkT xs b of x { __DEFAULT -> [x] } } -- DmdAnal: Strict in xs+ ==> { drop-seq, binder swap on xs' }+ f xs = case MkT xs b of x { __DEFAULT -> [x] } -- DmdAnal: Still strict in xs+ ==> { case-to-let }+ f xs = let x = MkT xs' b in [x] -- DmdAnal: No longer strict in xs!++I.e., we are ironically losing strictness in `xs` by dropping the eval on `xs`+and then doing case-to-let. The issue is that `exprIsHNF` currently says that+every DataCon worker app is a value. The implicit assumption is that surrounding+evals will have evaluated strict fields like `xs` before! But now that we had+just dropped the eval on `xs`, that assumption is no longer valid.++Long story short: By keeping the demand signature lazy, the Simplifier will not+drop the eval on `xs` and using `exprIsHNF` to decide case-to-let and others+remains sound.++Similarly, during demand analysis in dmdTransformDataConSig, we bump up the+field demand with `C_01`, *not* `C_11`, because the latter exposes too much+strictness that will drop the eval on `xs` above.++This issue is discussed at length in+"Failed idea: no wrappers for strict data constructors" in #21497 and #22475.+ Note [Bangs on data constructor arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider@@ -884,7 +992,7 @@ Actually, the unboxed part isn't implemented yet! Not that this representation is still *different* from runtime-representation. (Which is what STG uses afer unarise).+representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1047,7 +1155,7 @@ -> KnotTied ThetaType -- ^ Theta-type occurring before the arguments proper -> [KnotTied (Scaled Type)] -- ^ Original argument types -> KnotTied Type -- ^ Original result type- -> RuntimeRepInfo -- ^ See comments on 'GHC.Core.TyCon.RuntimeRepInfo'+ -> PromDataConInfo -- ^ See comments on 'GHC.Core.TyCon.PromDataConInfo' -> KnotTied TyCon -- ^ Representation type constructor -> ConTag -- ^ Constructor tag -> ThetaType -- ^ The "stupid theta", context of the data@@ -1108,8 +1216,11 @@ -- If the DataCon has a wrapper, then the worker's type is never seen -- by the user. The visibilities we pick do not matter here. DCR{} -> mkInfForAllTys univ_tvs $ mkTyCoInvForAllTys ex_tvs $- mkVisFunTys rep_arg_tys $+ mkScaledFunctionTys rep_arg_tys $ mkTyConApp rep_tycon (mkTyVarTys univ_tvs)+ -- res_arg_tys is a mixture of TypeLike and ConstraintLike,+ -- so we don't know which FunTyFlag to use+ -- Hence using mkScaledFunctionTys. -- See Note [Promoted data constructors] in GHC.Core.TyCon prom_tv_bndrs = [ mkNamedTyConBinder (Invisible spec) tv@@ -1119,9 +1230,9 @@ -- fresh_names: make sure that the "anonymous" tyvars don't -- clash in name or unique with the universal/existential ones. -- Tiresome! And unnecessary because these tyvars are never looked at- prom_theta_bndrs = [ mkAnonTyConBinder InvisArg (mkTyVar n t)+ prom_theta_bndrs = [ mkInvisAnonTyConBinder (mkTyVar n t) {- Invisible -} | (n,t) <- fresh_names `zip` theta ]- prom_arg_bndrs = [ mkAnonTyConBinder VisArg (mkTyVar n t)+ prom_arg_bndrs = [ mkAnonTyConBinder (mkTyVar n t) {- Visible -} | (n,t) <- dropList theta fresh_names `zip` map scaledThing orig_arg_tys ] prom_bndrs = prom_tv_bndrs ++ prom_theta_bndrs ++ prom_arg_bndrs prom_res_kind = orig_res_ty@@ -1208,30 +1319,6 @@ dataConUserTyVarBinders :: DataCon -> [InvisTVBinder] dataConUserTyVarBinders = dcUserTyVarBinders --- | Equalities derived from the result type of the data constructor, as written--- by the programmer in any GADT declaration. This includes *all* GADT-like--- equalities, including those written in by hand by the programmer.-dataConEqSpec :: DataCon -> [EqSpec]-dataConEqSpec con@(MkData { dcEqSpec = eq_spec, dcOtherTheta = theta })- = dataConKindEqSpec con- ++ eq_spec ++- [ spec -- heterogeneous equality- | Just (tc, [_k1, _k2, ty1, ty2]) <- map splitTyConApp_maybe theta- , tc `hasKey` heqTyConKey- , spec <- case (getTyVar_maybe ty1, getTyVar_maybe ty2) of- (Just tv1, _) -> [mkEqSpec tv1 ty2]- (_, Just tv2) -> [mkEqSpec tv2 ty1]- _ -> []- ] ++- [ spec -- homogeneous equality- | Just (tc, [_k, ty1, ty2]) <- map splitTyConApp_maybe theta- , tc `hasKey` eqTyConKey- , spec <- case (getTyVar_maybe ty1, getTyVar_maybe ty2) of- (Just tv1, _) -> [mkEqSpec tv1 ty2]- (_, Just tv2) -> [mkEqSpec tv2 ty1]- _ -> []- ]- -- | Dependent (kind-level) equalities in a constructor. -- There are extracted from the existential variables. -- See Note [Existential coercion variables]@@ -1247,7 +1334,7 @@ | cv <- ex_tcvs , isCoVar cv , let (_, _, ty1, ty, _) = coVarKindsTypesRole cv- tv = getTyVar "dataConKindEqSpec" ty1+ tv = getTyVar ty1 ] -- | The *full* constraints on the constructor type, including dependent GADT@@ -1467,19 +1554,23 @@ dcOrigResTy = res_ty, dcStupidTheta = stupid_theta }) = mkInvisForAllTys user_tvbs $- mkInvisFunTysMany (stupid_theta ++ theta) $- mkVisFunTys arg_tys $+ mkInvisFunTys (stupid_theta ++ theta) $+ mkScaledFunTys arg_tys $ res_ty dataConNonlinearType :: DataCon -> Type+-- Just like dataConWrapperType, but with the+-- linearity on the arguments all zapped to Many dataConNonlinearType (MkData { dcUserTyVarBinders = user_tvbs, dcOtherTheta = theta, dcOrigArgTys = arg_tys,- dcOrigResTy = res_ty })- = let arg_tys' = map (\(Scaled w t) -> Scaled (case w of One -> Many; _ -> w) t) arg_tys- in mkInvisForAllTys user_tvbs $- mkInvisFunTysMany theta $- mkVisFunTys arg_tys' $- res_ty+ dcOrigResTy = res_ty,+ dcStupidTheta = stupid_theta })+ = mkInvisForAllTys user_tvbs $+ mkInvisFunTys (stupid_theta ++ theta) $+ mkScaledFunTys arg_tys' $+ res_ty+ where+ arg_tys' = map (\(Scaled w t) -> Scaled (case w of OneTy -> ManyTy; _ -> w) t) arg_tys dataConDisplayType :: Bool -> DataCon -> Type dataConDisplayType show_linear_types dc@@ -1595,7 +1686,7 @@ , dcOtherTheta = theta , dcOrigArgTys = orig_arg_tys }) = case rep of- NoDataConRep -> assert (null eq_spec) $ (map unrestricted theta) ++ orig_arg_tys+ NoDataConRep -> assert (null eq_spec) $ map unrestricted theta ++ orig_arg_tys DCR { dcr_arg_tys = arg_tys } -> arg_tys -- | The string @package:module.name@ identifying a constructor, which is attached@@ -1638,8 +1729,63 @@ -- | Is this data constructor in a "type data" declaration? -- See Note [Type data declarations] in GHC.Rename.Module. isTypeDataCon :: DataCon -> Bool-isTypeDataCon dc = isTcClsNameSpace (nameNameSpace (getName dc))+isTypeDataCon dc = isTypeDataTyCon (dataConTyCon dc) +isCovertGadtDataCon :: DataCon -> Bool+-- See Note [isCovertGadtDataCon]+isCovertGadtDataCon (MkData { dcUnivTyVars = univ_tvs+ , dcEqSpec = eq_spec+ , dcRepTyCon = rep_tc })+ = not (null eq_spec) -- There are some constraints+ && not (any is_visible_spec eq_spec) -- But none of them are visible+ where+ visible_univ_tvs :: [TyVar] -- Visible arguments in result type+ visible_univ_tvs+ = [ univ_tv | (univ_tv, tcb) <- univ_tvs `zip` tyConBinders rep_tc+ , isVisibleTyConBinder tcb ]++ is_visible_spec :: EqSpec -> Bool+ is_visible_spec (EqSpec univ_tv ty)+ = univ_tv `elem` visible_univ_tvs+ && not (isTyVarTy ty) -- See Note [isCovertGadtDataCon] for+ -- an example where 'ty' is a tyvar++{- Note [isCovertGadtDataCon]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+(isCovertGadtDataCon K) returns True if K is a GADT data constructor, but+does not /look/ like it. Consider (#21447)+ type T :: TYPE r -> Type+ data T a where { MkT :: b -> T b }+Here MkT doesn't look GADT-like, but it is. If we make the kind applications+explicit we'd see:+ data T a where { MkT :: b -> T @LiftedRep b }++The test for covert-ness is bit tricky, because we want to see if+ - dcEqSpec is non-empty+ - dcEqSpec does not constrain any of the /required/ (i.e. visible)+ arguments of the TyCon to a non-tyvar++In the example above, the DataCon for MkT will have+ dcUnivTyVars: [(r::RuntimeRep), (a :: TYPE r)]+ dcExTyVars: [(b :: Type)]+ dcEqSpec: [(r, LiftedRep), (a, b)]+Here+ * `r :: RuntimeRep` is constrained by dcEqSpec to LiftedRep+ * `a :: TYPE r` is constrained by dcEqSpec to `b :: Type`+But the constraint on `a` is not visible to the user, so this counts+as a covert GADT data con. The declaration+ MkT :: forall (b :: Type). b -> T b+looks entirely non-GADT-ish.++Wrinkles:+* The visibility or otherwise is a property of the /TyCon/ binders+* The dcUnivTyVars may or may not be the same as the TyCon binders+* So we have to zip them together.+* For a data family the TyCon in question is the /representation/ TyCon+ hence dcRepTyCon+-}++ -- | Should this DataCon be allowed in a type even without -XDataKinds? -- Currently, only Lifted & Unlifted specialPromotedDc :: DataCon -> Bool@@ -1680,17 +1826,71 @@ -- -- This is not a cheap test, so we minimize its use in GHC as much as possible. -- Currently, its only call site in the GHC codebase is in 'mkDataConRep' in--- "MkId", and so 'dataConUserTyVarsArePermuted' is only called at most once+-- "MkId", and so 'dataConUserTyVarsNeedWrapper' is only called at most once -- during a data constructor's lifetime. +dataConResRepTyArgs :: DataCon -> [Type]+-- Returns the arguments of a GADT version of the /representation/ TyCon+-- Thus data instance T [(x,y)] z where+-- MkT :: forall p q. Int -> T [(Int,p)] (Maybe q)+-- The "GADT version of the representation type" is+-- data R:T x y z where+-- MkT :: forall p q. Int -> R:T Int p (Maybe q)+-- so dataConResRepTyArgs for MkT returns [Int, p, Maybe q]+-- This is almost the same as (subst eq_spec univ_tvs); but not quite,+-- because eq_spec omits constraint-kinded equalities+dataConResRepTyArgs dc@(MkData { dcRepTyCon = rep_tc, dcOrigResTy = orig_res_ty })+ | Just (fam_tc, fam_args) <- tyConFamInst_maybe rep_tc+ = -- fvs(fam_args) = tyConTyVars rep_tc+ -- These tyvars are the domain of subst+ -- Fvs(range(subst)) = tvars of the datacon+ case tcMatchTy (mkTyConApp fam_tc fam_args) orig_res_ty of+ Just subst -> map (substTyVar subst) (tyConTyVars rep_tc)+ Nothing -> pprPanic "datacOnResRepTyArgs" $+ vcat [ ppr dc, ppr fam_tc <+> ppr fam_args+ , ppr orig_res_ty ]+ | otherwise+ = tyConAppArgs orig_res_ty++checkDataConTyVars :: DataCon -> Bool+-- Check that the worker and wrapper have the same set of type variables+-- See Note [DataCon user type variable binders]+-- Also ensures that no user tyvar is in the eq_spec (the eq_spec should+-- only relate fresh universals from (R2) of the note)+checkDataConTyVars dc@(MkData { dcUnivTyVars = univ_tvs+ , dcExTyCoVars = ex_tvs+ , dcEqSpec = eq_spec })+ -- use of sets here: (R1) from the Note+ = mkUnVarSet depleted_worker_vars == mkUnVarSet depleted_wrapper_vars &&+ all (not . is_eq_spec_var) wrapper_vars+ where+ is_constraint_var v = typeTypeOrConstraint (tyVarKind v) == ConstraintLike+ -- implements (R3) from the Note++ worker_vars = univ_tvs ++ ex_tvs+ eq_spec_tvs = mkUnVarSet (map eqSpecTyVar eq_spec)+ is_eq_spec_var = (`elemUnVarSet` eq_spec_tvs) -- (R2) from the Note+ depleted_worker_vars = filterOut (is_eq_spec_var <||> is_constraint_var)+ worker_vars++ wrapper_vars = dataConUserTyVars dc+ depleted_wrapper_vars = filterOut is_constraint_var wrapper_vars++dataConUserTyVarsNeedWrapper :: DataCon -> Bool+-- Check whether the worker and wapper have the same type variables+-- in the same order. If not, we need a wrapper to swizzle them. -- See Note [DataCon user type variable binders], as well as -- Note [Data con wrappers and GADT syntax] for an explanation of what -- mkDataConRep is doing with this function.-dataConUserTyVarsArePermuted :: DataCon -> Bool-dataConUserTyVarsArePermuted (MkData { dcUnivTyVars = univ_tvs- , dcExTyCoVars = ex_tvs, dcEqSpec = eq_spec- , dcUserTyVarBinders = user_tvbs }) =- (filterEqSpec eq_spec univ_tvs ++ ex_tvs) /= binderVars user_tvbs+dataConUserTyVarsNeedWrapper dc@(MkData { dcUnivTyVars = univ_tvs+ , dcExTyCoVars = ex_tvs+ , dcEqSpec = eq_spec })+ = assert (null eq_spec || answer) -- all GADTs should say "yes" here+ answer+ where+ answer = (univ_tvs ++ ex_tvs) /= dataConUserTyVars dc+ -- Worker tyvars Wrapper tyvars+ {- %************************************************************************
compiler/GHC/Core/DataCon.hs-boot view
@@ -27,6 +27,7 @@ dataConFullSig :: DataCon -> ([TyVar], [TyCoVar], [EqSpec], ThetaType, [Scaled Type], Type) isUnboxedSumDataCon :: DataCon -> Bool+isTypeDataCon :: DataCon -> Bool instance Eq DataCon instance Uniquable DataCon
compiler/GHC/Core/FVs.hs view
@@ -36,7 +36,7 @@ ruleLhsFreeIds, ruleLhsFreeIdsList, ruleRhsFreeVars, rulesRhsFreeIds, - expr_fvs,+ exprFVs, -- * Orphan names orphNamesOfType, orphNamesOfCo, orphNamesOfAxiom,@@ -72,7 +72,7 @@ import GHC.Core.Coercion.Axiom import GHC.Core.FamInstEnv import GHC.Builtin.Types( unrestrictedFunTyConName )-import GHC.Builtin.Types.Prim( funTyConName )+import GHC.Builtin.Types.Prim( fUNTyCon ) import GHC.Data.Maybe( orElse ) import GHC.Utils.FV as FV@@ -349,19 +349,25 @@ -- Look through type synonyms (#4912) orphNamesOfType (TyVarTy _) = emptyNameSet orphNamesOfType (LitTy {}) = emptyNameSet+orphNamesOfType (ForAllTy bndr res) = orphNamesOfType (binderType bndr)+ `unionNameSet` orphNamesOfType res orphNamesOfType (TyConApp tycon tys) = func `unionNameSet` orphNamesOfTyCon tycon `unionNameSet` orphNamesOfTypes tys where func = case tys of- arg:_ | tycon == funTyCon -> orph_names_of_fun_ty_con arg+ arg:_ | tycon == fUNTyCon -> orph_names_of_fun_ty_con arg _ -> emptyNameSet-orphNamesOfType (ForAllTy bndr res) = orphNamesOfType (binderType bndr)- `unionNameSet` orphNamesOfType res-orphNamesOfType (FunTy _ w arg res) = orph_names_of_fun_ty_con w- `unionNameSet` unitNameSet funTyConName++orphNamesOfType (FunTy af w arg res) = func+ `unionNameSet` unitNameSet fun_tc `unionNameSet` orphNamesOfType w `unionNameSet` orphNamesOfType arg `unionNameSet` orphNamesOfType res+ where func | isVisibleFunArg af = orph_names_of_fun_ty_con w+ | otherwise = emptyNameSet++ fun_tc = tyConName (funTyFlagTyCon af)+ orphNamesOfType (AppTy fun arg) = orphNamesOfType fun `unionNameSet` orphNamesOfType arg orphNamesOfType (CastTy ty co) = orphNamesOfType ty `unionNameSet` orphNamesOfCo co orphNamesOfType (CoercionTy co) = orphNamesOfCo co@@ -381,15 +387,19 @@ orphNamesOfCo (GRefl _ ty mco) = orphNamesOfType ty `unionNameSet` orphNamesOfMCo mco orphNamesOfCo (TyConAppCo _ tc cos) = unitNameSet (getName tc) `unionNameSet` orphNamesOfCos cos orphNamesOfCo (AppCo co1 co2) = orphNamesOfCo co1 `unionNameSet` orphNamesOfCo co2-orphNamesOfCo (ForAllCo _ kind_co co)- = orphNamesOfCo kind_co `unionNameSet` orphNamesOfCo co-orphNamesOfCo (FunCo _ co_mult co1 co2) = orphNamesOfCo co_mult `unionNameSet` orphNamesOfCo co1 `unionNameSet` orphNamesOfCo co2+orphNamesOfCo (ForAllCo _ kind_co co) = orphNamesOfCo kind_co+ `unionNameSet` orphNamesOfCo co+orphNamesOfCo (FunCo { fco_mult = co_mult, fco_arg = co1, fco_res = co2 })+ = orphNamesOfCo co_mult+ `unionNameSet` orphNamesOfCo co1+ `unionNameSet` orphNamesOfCo co2 orphNamesOfCo (CoVarCo _) = emptyNameSet orphNamesOfCo (AxiomInstCo con _ cos) = orphNamesOfCoCon con `unionNameSet` orphNamesOfCos cos-orphNamesOfCo (UnivCo p _ t1 t2) = orphNamesOfProv p `unionNameSet` orphNamesOfType t1 `unionNameSet` orphNamesOfType t2+orphNamesOfCo (UnivCo p _ t1 t2) = orphNamesOfProv p `unionNameSet` orphNamesOfType t1+ `unionNameSet` orphNamesOfType t2 orphNamesOfCo (SymCo co) = orphNamesOfCo co orphNamesOfCo (TransCo co1 co2) = orphNamesOfCo co1 `unionNameSet` orphNamesOfCo co2-orphNamesOfCo (NthCo _ _ co) = orphNamesOfCo co+orphNamesOfCo (SelCo _ co) = orphNamesOfCo co orphNamesOfCo (LRCo _ co) = orphNamesOfCo co orphNamesOfCo (InstCo co arg) = orphNamesOfCo co `unionNameSet` orphNamesOfCo arg orphNamesOfCo (KindCo co) = orphNamesOfCo co@@ -437,8 +447,8 @@ -- Detect FUN 'Many as an application of (->), so that :i (->) works as expected -- (see #8535) Issue #16475 describes a more robust solution orph_names_of_fun_ty_con :: Mult -> NameSet-orph_names_of_fun_ty_con Many = unitNameSet unrestrictedFunTyConName-orph_names_of_fun_ty_con _ = emptyNameSet+orph_names_of_fun_ty_con ManyTy = unitNameSet unrestrictedFunTyConName+orph_names_of_fun_ty_con _ = emptyNameSet {- ************************************************************************@@ -791,3 +801,4 @@ go (Type ty) = (tyCoVarsOfTypeDSet ty, AnnType ty) go (Coercion co) = (tyCoVarsOfCoDSet co, AnnCoercion co)+
compiler/GHC/Core/FamInstEnv.hs view
@@ -3,7 +3,6 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} -{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} -- (c) The University of Glasgow 2006 -- -- FamInstEnv: Type checked family instance declarations@@ -42,6 +41,7 @@ import GHC.Core.Unify import GHC.Core.Type as Type import GHC.Core.TyCo.Rep+import GHC.Core.TyCo.Compare( eqType, eqTypes ) import GHC.Core.TyCon import GHC.Core.Coercion import GHC.Core.Coercion.Axiom@@ -50,6 +50,7 @@ import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Types.Name+import GHC.Data.FastString import GHC.Data.Maybe import GHC.Types.Var import GHC.Types.SrcLoc@@ -62,6 +63,8 @@ import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Data.Bag+import GHC.Data.List.Infinite (Infinite (..))+import qualified GHC.Data.List.Infinite as Inf {- ************************************************************************@@ -686,7 +689,7 @@ -- See Note [Tidy axioms when we build them] -- See also Note [CoAxBranch type variables] in GHC.Core.Coercion.Axiom - init_occ_env = initTidyOccEnv [mkTyVarOcc "_"]+ init_occ_env = initTidyOccEnv [mkTyVarOccFS (fsLit "_")] init_tidy_env = mkEmptyTidyEnv init_occ_env -- See Note [Always number wildcard types in CoAxBranch] @@ -1476,7 +1479,7 @@ Nothing -> do { ArgsReductions redns res_co <- normalise_args (typeKind nfun)- (repeat Nominal)+ (Inf.repeat Nominal) arg_tys ; role <- getRole ; return $@@ -1485,7 +1488,7 @@ (mkSymMCo res_co) } } normalise_args :: Kind -- of the function- -> [Role] -- roles at which to normalise args+ -> Infinite Role -- roles at which to normalise args -> [Type] -- args -> NormM ArgsReductions -- returns ArgsReductions (Reductions cos xis) res_co,@@ -1495,7 +1498,7 @@ -- but the resulting application *will* be well-kinded -- cf. GHC.Tc.Solver.Rewrite.rewrite_args_slow normalise_args fun_ki roles args- = do { normed_args <- zipWithM normalise1 roles args+ = do { normed_args <- zipWithM normalise1 (Inf.toList roles) args ; return $ simplifyArgsWorker ki_binders inner_ki fvs roles normed_args } where (ki_binders, inner_ki) = splitPiTys fun_ki
compiler/GHC/Core/InstEnv.hs view
@@ -38,15 +38,16 @@ -- and depends on TcType in many ways import GHC.Core ( IsOrphan(..), isOrphan, chooseOrphanAnchor ) import GHC.Core.RoughMap+import GHC.Core.Class+import GHC.Core.Unify+ import GHC.Unit.Module.Env import GHC.Unit.Types-import GHC.Core.Class import GHC.Types.Var import GHC.Types.Unique.DSet import GHC.Types.Var.Set import GHC.Types.Name import GHC.Types.Name.Set-import GHC.Core.Unify import GHC.Types.Basic import GHC.Types.Id import Data.Data ( Data )@@ -323,7 +324,9 @@ {- Note [When exactly is an instance decl an orphan?] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~- (see GHC.Iface.Make.instanceToIfaceInst, which implements this)+(See GHC.Iface.Make.instanceToIfaceInst, which implements this.)+See Note [Orphans] in GHC.Core+ Roughly speaking, an instance is an orphan if its head (after the =>) mentions nothing defined in this module.
compiler/GHC/Core/Lint.hs view
@@ -49,9 +49,10 @@ import GHC.Core.Multiplicity import GHC.Core.UsageEnv import GHC.Core.TyCo.Rep -- checks validity of types/coercions+import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.TyCo.Subst import GHC.Core.TyCo.FVs-import GHC.Core.TyCo.Ppr ( pprTyVar, pprTyVars )+import GHC.Core.TyCo.Ppr import GHC.Core.TyCon as TyCon import GHC.Core.Coercion.Axiom import GHC.Core.Unify@@ -86,7 +87,6 @@ import GHC.Utils.Panic import GHC.Utils.Constants (debugIsOn) import GHC.Utils.Misc-import GHC.Utils.Trace import GHC.Utils.Error import qualified GHC.Utils.Error as Err import GHC.Utils.Logger@@ -167,10 +167,11 @@ Note [Linting function types] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-As described in Note [Representation of function types], all saturated-applications of funTyCon are represented with the FunTy constructor. We check-this invariant in lintType.+All saturated applications of funTyCon are represented with the FunTy constructor.+See Note [Function type constructors and FunTy] in GHC.Builtin.Types.Prim + We check this invariant in lintType.+ Note [Linting type lets] ~~~~~~~~~~~~~~~~~~~~~~~~ In the desugarer, it's very very convenient to be able to say (in effect)@@ -320,7 +321,7 @@ , ep_lintPassResult :: !(Maybe LintPassResultConfig) -- ^ Whether we should lint the result of this pass. - , ep_printUnqual :: !PrintUnqualified+ , ep_namePprCtx :: !NamePprCtx , ep_dumpFlag :: !(Maybe DumpFlag) @@ -335,7 +336,7 @@ -> IO () -- Used by the IO-is CorePrep too endPassIO logger cfg binds rules- = do { dumpPassResult logger (ep_dumpCoreSizes cfg) (ep_printUnqual cfg) mb_flag+ = do { dumpPassResult logger (ep_dumpCoreSizes cfg) (ep_namePprCtx cfg) mb_flag (renderWithContext defaultSDocContext (ep_prettyPass cfg)) (ep_passDetails cfg) binds rules ; for_ (ep_lintPassResult cfg) $ \lp_cfg ->@@ -349,16 +350,16 @@ dumpPassResult :: Logger -> Bool -- dump core sizes?- -> PrintUnqualified+ -> NamePprCtx -> Maybe DumpFlag -- Just df => show details in a file whose -- name is specified by df -> String -- Header -> SDoc -- Extra info to appear after header -> CoreProgram -> [CoreRule] -> IO ()-dumpPassResult logger dump_core_sizes unqual mb_flag hdr extra_info binds rules+dumpPassResult logger dump_core_sizes name_ppr_ctx mb_flag hdr extra_info binds rules = do { forM_ mb_flag $ \flag -> do- logDumpFile logger (mkDumpStyle unqual) flag hdr FormatCore dump_doc+ logDumpFile logger (mkDumpStyle name_ppr_ctx) flag hdr FormatCore dump_doc -- Report result size -- This has the side effect of forcing the intermediate to be evaluated@@ -925,7 +926,7 @@ ; ((body_type, body_ue), ues) <- lintRecBindings NotTopLevel pairs $ \ bndrs' -> lintLetBody bndrs' body- ; return (body_type, body_ue `addUE` scaleUE Many (foldr1 addUE ues)) }+ ; return (body_type, body_ue `addUE` scaleUE ManyTy (foldr1 addUE ues)) } where bndrs = map fst pairs @@ -1405,7 +1406,7 @@ -- application. lintValApp :: CoreExpr -> LintedType -> LintedType -> UsageEnv -> UsageEnv -> LintM (LintedType, UsageEnv) lintValApp arg fun_ty arg_ty fun_ue arg_ue- | Just (w, arg_ty', res_ty') <- splitFunTy_maybe fun_ty+ | Just (_, w, arg_ty', res_ty') <- splitFunTy_maybe fun_ty = do { ensureEqTys arg_ty' arg_ty (mkAppMsg arg_ty' arg_ty arg) ; let app_ue = addUE fun_ue (scaleUE w arg_ue) ; return (res_ty', app_ue) }@@ -1567,8 +1568,8 @@ -- We've already check lintL (tycon == dataConTyCon con) (mkBadConMsg tycon con) ; let { con_payload_ty = piResultTys (dataConRepType con) tycon_arg_tys- ; binderMult (Named _) = Many- ; binderMult (Anon _ st) = scaledMult st+ ; binderMult (Named _) = ManyTy+ ; binderMult (Anon st _) = scaledMult st -- See Note [Validating multiplicities in a case] ; multiplicities = map binderMult $ fst $ splitPiTys con_payload_ty } @@ -1637,19 +1638,25 @@ lintTyBndr :: TyVar -> (LintedTyCoVar -> LintM a) -> LintM a lintTyBndr = lintTyCoBndr -- We could specialise it, I guess --- lintCoBndr :: CoVar -> (LintedTyCoVar -> LintM a) -> LintM a--- lintCoBndr = lintTyCoBndr -- We could specialise it, I guess- lintTyCoBndr :: TyCoVar -> (LintedTyCoVar -> LintM a) -> LintM a lintTyCoBndr tcv thing_inside = do { subst <- getSubst- ; kind' <- lintType (varType tcv)+ ; tcv_type' <- lintType (varType tcv) ; let tcv' = uniqAway (getSubstInScope subst) $- setVarType tcv kind'+ setVarType tcv tcv_type' subst' = extendTCvSubstWithClone subst tcv tcv'- ; when (isCoVar tcv) $- lintL (isCoVarType kind')- (text "CoVar with non-coercion type:" <+> pprTyVar tcv)++ -- See (FORALL1) and (FORALL2) in GHC.Core.Type+ ; if (isTyVar tcv)+ then -- Check that in (forall (a:ki). blah) we have ki:Type+ lintL (isLiftedTypeKind (typeKind tcv_type')) $+ hang (text "TyVar whose kind does not have kind Type:")+ 2 (ppr tcv' <+> dcolon <+> ppr tcv_type' <+> dcolon <+> ppr (typeKind tcv_type'))+ else -- Check that in (forall (cv::ty). blah),+ -- then ty looks like (t1 ~# t2)+ lintL (isCoVarType tcv_type') $+ text "CoVar with non-coercion type:" <+> pprTyVar tcv+ ; updateSubst subst' (thing_inside tcv') } lintIdBndrs :: forall a. TopLevelFlag -> [Id] -> ([LintedId] -> LintM a) -> LintM a@@ -1731,7 +1738,7 @@ = addLoc (InType ty) $ do { ty' <- lintType ty ; let sk = typeKind ty'- ; lintL (classifiesTypeWithValues sk) $+ ; lintL (isTYPEorCONSTRAINT sk) $ hang (text "Ill-kinded type:" <+> ppr ty) 2 (text "has kind:" <+> ppr sk) ; return ty' }@@ -1779,13 +1786,11 @@ = do { report_unsat <- lf_report_unsat_syns <$> getLintFlags ; lintTySynFamApp report_unsat ty tc tys } - | isFunTyCon tc- , tys `lengthIs` 5+ | Just {} <- tyConAppFunTy_maybe tc tys -- We should never see a saturated application of funTyCon; such -- applications should be represented with the FunTy constructor.- -- See Note [Linting function types] and- -- Note [Representation of function types].- = failWithL (hang (text "Saturated application of (->)") 2 (ppr ty))+ -- See Note [Linting function types]+ = failWithL (hang (text "Saturated application of" <+> quotes (ppr tc)) 2 (ppr ty)) | otherwise -- Data types, data families, primitive types = do { checkTyCon tc@@ -1800,6 +1805,12 @@ ; t2' <- lintType t2 ; tw' <- lintType tw ; lintArrow (text "type or kind" <+> quotes (ppr ty)) t1' t2' tw'+ ; let real_af = chooseFunTyFlag t1 t2+ ; unless (real_af == af) $ addErrL $+ hang (text "Bad FunTyFlag in FunTy")+ 2 (vcat [ ppr ty+ , text "FunTyFlag =" <+> ppr af+ , text "Computed FunTyFlag =" <+> ppr real_af ]) ; return (FunTy af tw' t1' t2') } lintType ty@(ForAllTy (Bndr tcv vis) body_ty)@@ -1888,7 +1899,7 @@ -- Confirms that a type is really TYPE r or Constraint checkValueType :: LintedType -> SDoc -> LintM () checkValueType ty doc- = lintL (classifiesTypeWithValues kind)+ = lintL (isTYPEorCONSTRAINT kind) (text "Non-Type-like kind when Type-like expected:" <+> ppr kind $$ text "when checking" <+> doc) where@@ -1900,17 +1911,16 @@ -- See Note [GHC Formalism] lintArrow what t1 t2 tw -- Eg lintArrow "type or kind `blah'" k1 k2 kw -- or lintArrow "coercion `blah'" k1 k2 kw- = do { unless (classifiesTypeWithValues k1) (addErrL (msg (text "argument") k1))- ; unless (classifiesTypeWithValues k2) (addErrL (msg (text "result") k2))- ; unless (isMultiplicityTy kw) (addErrL (msg (text "multiplicity") kw)) }+ = do { unless (isTYPEorCONSTRAINT k1) (report (text "argument") k1)+ ; unless (isTYPEorCONSTRAINT k2) (report (text "result") k2)+ ; unless (isMultiplicityTy kw) (report (text "multiplicity") kw) } where k1 = typeKind t1 k2 = typeKind t2 kw = typeKind tw- msg ar k- = vcat [ hang (text "Ill-kinded" <+> ar)- 2 (text "in" <+> what)- , what <+> text "kind:" <+> ppr k ]+ report ar k = addErrL (vcat [ hang (text "Ill-kinded" <+> ar)+ 2 (text "in" <+> what)+ , what <+> text "kind:" <+> ppr k ]) ----------------- lint_ty_app :: Type -> LintedKind -> [LintedType] -> LintM ()@@ -2095,7 +2105,7 @@ inefficient, notably in * TransCo * InstCo-* NthCo (cf #9233)+* SelCo (cf #9233) * LRCo But the code is simple. And this is only Lint. Let's wait to see if@@ -2164,9 +2174,9 @@ ; return (GRefl r ty' (MCo co')) } lintCoercion co@(TyConAppCo r tc cos)- | tc `hasKey` funTyConKey- , [_w, _rep1,_rep2,_co1,_co2] <- cos- = failWithL (text "Saturated TyConAppCo (->):" <+> ppr co)+ | Just {} <- tyConAppFunCo_maybe r tc cos+ = failWithL (hang (text "Saturated application of" <+> quotes (ppr tc))+ 2 (ppr co)) -- All saturated TyConAppCos should be FunCos | Just {} <- synTyConDefn_maybe tc@@ -2178,7 +2188,7 @@ ; let (co_kinds, co_roles) = unzip (map coercionKindRole cos') ; lint_co_app co (tyConKind tc) (map pFst co_kinds) ; lint_co_app co (tyConKind tc) (map pSnd co_kinds)- ; zipWithM_ (lintRole co) (tyConRolesX r tc) co_roles+ ; zipWithM_ (lintRole co) (tyConRoleListX r tc) co_roles ; return (TyConAppCo r tc cos') } lintCoercion co@(AppCo co1 co2)@@ -2232,24 +2242,33 @@ ; return (ForAllCo tcv' kind_co' body_co') } } -lintCoercion co@(FunCo r cow co1 co2)+lintCoercion co@(FunCo { fco_role = r, fco_afl = afl, fco_afr = afr+ , fco_mult = cow, fco_arg = co1, fco_res = co2 }) = do { co1' <- lintCoercion co1 ; co2' <- lintCoercion co2 ; cow' <- lintCoercion cow ; let Pair lt1 rt1 = coercionKind co1 Pair lt2 rt2 = coercionKind co2 Pair ltw rtw = coercionKind cow- ; lintArrow (text "coercion" <+> quotes (ppr co)) lt1 lt2 ltw- ; lintArrow (text "coercion" <+> quotes (ppr co)) rt1 rt2 rtw+ ; lintL (afl == chooseFunTyFlag lt1 lt2) (bad_co_msg "afl")+ ; lintL (afr == chooseFunTyFlag rt1 rt2) (bad_co_msg "afr")+ ; lintArrow (bad_co_msg "arrowl") lt1 lt2 ltw+ ; lintArrow (bad_co_msg "arrowr") rt1 rt2 rtw ; lintRole co1 r (coercionRole co1) ; lintRole co2 r (coercionRole co2)- ; ensureEqTys (typeKind ltw) multiplicityTy (text "coercion" <> quotes (ppr co))- ; ensureEqTys (typeKind rtw) multiplicityTy (text "coercion" <> quotes (ppr co))+ ; ensureEqTys (typeKind ltw) multiplicityTy (bad_co_msg "mult-l")+ ; ensureEqTys (typeKind rtw) multiplicityTy (bad_co_msg "mult-r") ; let expected_mult_role = case r of Phantom -> Phantom _ -> Nominal ; lintRole cow expected_mult_role (coercionRole cow)- ; return (FunCo r cow' co1' co2') }+ ; return (co { fco_mult = cow', fco_arg = co1', fco_res = co2' }) }+ where+ bad_co_msg s = hang (text "Bad coercion" <+> parens (text s))+ 2 (vcat [ text "afl:" <+> ppr afl+ , text "afr:" <+> ppr afr+ , text "arg_co:" <+> ppr co1+ , text "res_co:" <+> ppr co2 ]) -- See Note [Bad unsafe coercion] lintCoercion co@(UnivCo prov r ty1 ty2)@@ -2259,8 +2278,8 @@ k2 = typeKind ty2' ; prov' <- lint_prov k1 k2 prov - ; when (r /= Phantom && classifiesTypeWithValues k1- && classifiesTypeWithValues k2)+ ; when (r /= Phantom && isTYPEorCONSTRAINT k1+ && isTYPEorCONSTRAINT k2) (checkTypes ty1 ty2) ; return (UnivCo prov' r ty1' ty2') }@@ -2353,33 +2372,40 @@ ; lintRole co (coercionRole co1) (coercionRole co2) ; return (TransCo co1' co2') } -lintCoercion the_co@(NthCo r0 n co)+lintCoercion the_co@(SelCo cs co) = do { co' <- lintCoercion co- ; let (Pair s t, r) = coercionKindRole co'- ; case (splitForAllTyCoVar_maybe s, splitForAllTyCoVar_maybe t) of- { (Just _, Just _)- -- works for both tyvar and covar- | n == 0- , (isForAllTy_ty s && isForAllTy_ty t)+ ; let (Pair s t, co_role) = coercionKindRole co'++ ; if -- forall (both TyVar and CoVar)+ | Just _ <- splitForAllTyCoVar_maybe s+ , Just _ <- splitForAllTyCoVar_maybe t+ , SelForAll <- cs+ , (isForAllTy_ty s && isForAllTy_ty t) || (isForAllTy_co s && isForAllTy_co t)- -> do { lintRole the_co Nominal r0- ; return (NthCo r0 n co') }+ -> return (SelCo cs co') - ; _ -> case (splitTyConApp_maybe s, splitTyConApp_maybe t) of- { (Just (tc_s, tys_s), Just (tc_t, tys_t))- | tc_s == tc_t- , isInjectiveTyCon tc_s r- -- see Note [NthCo and newtypes] in GHC.Core.TyCo.Rep- , tys_s `equalLength` tys_t- , tys_s `lengthExceeds` n- -> do { lintRole the_co tr r0- ; return (NthCo r0 n co') }- where- tr = nthRole r tc_s n+ -- function+ | isFunTy s+ , isFunTy t+ , SelFun {} <- cs+ -> return (SelCo cs co') - ; _ -> failWithL (hang (text "Bad getNth:")- 2 (ppr the_co $$ ppr s $$ ppr t)) }}}+ -- TyCon+ | Just (tc_s, tys_s) <- splitTyConApp_maybe s+ , Just (tc_t, tys_t) <- splitTyConApp_maybe t+ , tc_s == tc_t+ , SelTyCon n r0 <- cs+ , isInjectiveTyCon tc_s co_role+ -- see Note [SelCo and newtypes] in GHC.Core.TyCo.Rep+ , tys_s `equalLength` tys_t+ , tys_s `lengthExceeds` n+ -> do { lintRole the_co (tyConRole co_role tc_s n) r0+ ; return (SelCo cs co') } + | otherwise+ -> failWithL (hang (text "Bad SelCo:")+ 2 (ppr the_co $$ ppr s $$ ppr t)) }+ lintCoercion the_co@(LRCo lr co) = do { co' <- lintCoercion co ; let Pair s t = coercionKind co'@@ -2586,10 +2612,14 @@ ; rhs' <- lintType rhs ; let lhs_kind = typeKind lhs' rhs_kind = typeKind rhs'- ; lintL (lhs_kind `eqType` rhs_kind) $+ ; lintL (not (lhs_kind `typesAreApart` rhs_kind)) $ hang (text "Inhomogeneous axiom") 2 (text "lhs:" <+> ppr lhs <+> dcolon <+> ppr lhs_kind $$ text "rhs:" <+> ppr rhs <+> dcolon <+> ppr rhs_kind) }+ -- Type and Constraint are not Apart, so this test allows+ -- the newtype axiom for a single-method class. Indeed the+ -- whole reason Type and Constraint are not Apart is to allow+ -- such axioms! -- these checks do not apply to newtype axioms lint_family_branch :: TyCon -> CoAxBranch -> LintM ()@@ -2833,22 +2863,87 @@ Note [Linting linearity] ~~~~~~~~~~~~~~~~~~~~~~~~-There is one known optimisations that have not yet been updated-to work with Linear Lint:+Core understands linear types: linearity is checked with the flag+`-dlinear-core-lint`. Why not make `-dcore-lint` check linearity? Because+optimisation passes are not (yet) guaranteed to maintain linearity. They should+do so semantically (GHC is careful not to duplicate computation) but it is much+harder to ensure that the statically-checkable constraints of Linear Core are+maintained. The current Linear Core is described in the wiki at:+https://gitlab.haskell.org/ghc/ghc/-/wikis/linear-types/implementation. -* Optimisations can create a letrec which uses a variable linearly, e.g.- letrec f True = f False- f False = x- in f True- uses 'x' linearly, but this is not seen by the linter.- Plan: make let-bound variables remember the usage environment.- See ticket #18694.+Why don't the optimisation passes maintain the static types of Linear Core?+Because doing so would cripple some important optimisations. Here is an+example: -We plan to fix this issue in the very near future.-For now, -dcore-lint enables only linting output of the desugarer,-and full Linear Lint has to be enabled separately with -dlinear-core-lint.-Ticket #19165 concerns enabling Linear Lint with -dcore-lint.+ data T = MkT {-# UNPACK #-} !Int +The wrapper for MkT is++ $wMkT :: Int %1 -> T+ $wMkT n = case %1 n of+ I# n' -> MkT n'++This introduces, in particular, a `case %1` (this is not actual Haskell or Core+syntax), where the `%1` means that the `case` expression consumes its scrutinee+linearly.++Now, `case %1` interacts with the binder swap optimisation in a non-trivial+way. Take a slightly modified version of the code for $wMkT:++ case %1 x of z {+ I# n' -> (x, n')+ }++Binder-swap wants to change this to++ case %1 x of z {+ I# n' -> let x = z in (x, n')+ }++Now, this is not something that a linear type checker usually considers+well-typed. It is not something that `-dlinear-core-lint` considers to be+well-typed either. But it's only because `-dlinear-core-lint` is not good+enough. However, making `-dlinear-core-lint` recognise this expression as valid+is not obvious. There are many such interactions between a linear type system+and GHC optimisations documented in the linear-type implementation wiki page+[https://gitlab.haskell.org/ghc/ghc/-/wikis/linear-types/implementation#core-to-core-passes].++PRINCIPLE: The type system bends to the optimisation, not the other way around.++In the original linear-types implementation, we had tried to make every+optimisation pass produce code that passes `-dlinear-core-lint`. It had proved+very difficult. And we kept finding corner case after corner case. Plus, we+used to restrict transformations when `-dlinear-core-lint` couldn't typecheck+the result. There are still occurrences of such restrictions in the code. But+our current stance is that such restrictions can be removed.++For instance, some optimisations can create a letrec which uses a variable+linearly, e.g.++ letrec f True = f False+ f False = x+ in f True++uses 'x' linearly, but this is not seen by the linter. This issue is discussed+in ticket #18694.++Plus in many cases, in order to make a transformation compatible with linear+linting, we ended up restricting to avoid producing patterns that were not+recognised as linear by the linter. This violates the above principle.++In the future, we may be able to lint the linearity of the output of+Core-to-Core passes (#19165). But right now, we can't. Therefore, in virtue of+the principle above, after the desguarer, the optimiser should take no special+pains to preserve linearity (in the type system sense).++In general the optimiser tries hard not to lose sharing, so it probably doesn't+actually make linear things non-linear. We postulate that any program+transformation which breaks linearity would negatively impact performance, and+therefore wouldn't be suitable for an optimiser. An alternative to linting+linearity after each pass is to prove this statement.++There is a useful discussion at https://gitlab.haskell.org/ghc/ghc/-/issues/22123+ Note [checkCanEtaExpand] ~~~~~~~~~~~~~~~~~~~~~~~~ The checkCanEtaExpand function is responsible for enforcing invariant I3@@ -3125,7 +3220,7 @@ varCallSiteUsage id = do m <- getUEAliases return $ case lookupNameEnv m (getName id) of- Nothing -> unitUE id One+ Nothing -> unitUE id OneTy Just id_ue -> id_ue ensureEqTys :: LintedType -> LintedType -> SDoc -> LintM ()@@ -3136,7 +3231,7 @@ ensureSubUsage :: Usage -> Mult -> SDoc -> LintM () ensureSubUsage Bottom _ _ = return ()-ensureSubUsage Zero described_mult err_msg = ensureSubMult Many described_mult err_msg+ensureSubUsage Zero described_mult err_msg = ensureSubMult ManyTy described_mult err_msg ensureSubUsage (MUsage m) described_mult err_msg = ensureSubMult m described_mult err_msg ensureSubMult :: Mult -> Mult -> SDoc -> LintM ()
compiler/GHC/Core/Make.hs view
@@ -1,5 +1,3 @@-- {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- | Handy functions for creating much Core syntax@@ -25,27 +23,22 @@ FloatBind(..), wrapFloat, wrapFloats, floatBindings, -- * Constructing small tuples- mkCoreVarTupTy, mkCoreTup, mkCoreUbxTup, mkCoreUbxSum,+ mkCoreVarTupTy, mkCoreTup, mkCoreUnboxedTuple, mkCoreUnboxedSum, mkCoreTupBoxity, unitExpr, -- * Constructing big tuples- mkBigCoreVarTup, mkBigCoreVarTup1,+ mkChunkified, chunkify,+ mkBigCoreVarTup, mkBigCoreVarTupSolo, mkBigCoreVarTupTy, mkBigCoreTupTy, mkBigCoreTup, - -- * Deconstructing small tuples- mkSmallTupleSelector, mkSmallTupleCase,-- -- * Deconstructing big tuples- mkTupleSelector, mkTupleSelector1, mkTupleCase,+ -- * Deconstructing big tuples+ mkBigTupleSelector, mkBigTupleSelectorSolo, mkBigTupleCase, -- * Constructing list expressions mkNilExpr, mkConsExpr, mkListExpr, mkFoldrExpr, mkBuildExpr, - -- * Constructing non empty lists- mkNonEmptyListExpr,- -- * Constructing Maybe expressions mkNothingExpr, mkJustExpr, @@ -53,7 +46,7 @@ mkRuntimeErrorApp, mkImpossibleExpr, mkAbsentErrorApp, errorIds, rEC_CON_ERROR_ID, rUNTIME_ERROR_ID, nON_EXHAUSTIVE_GUARDS_ERROR_ID, nO_METHOD_BINDING_ERROR_ID,- pAT_ERROR_ID, rEC_SEL_ERROR_ID, aBSENT_ERROR_ID,+ pAT_ERROR_ID, rEC_SEL_ERROR_ID, tYPE_ERROR_ID, aBSENT_SUM_FIELD_ERROR_ID ) where @@ -61,7 +54,7 @@ import GHC.Platform import GHC.Types.Id-import GHC.Types.Var ( EvVar, setTyVarUnique )+import GHC.Types.Var ( EvVar, setTyVarUnique, visArgConstraintLike ) import GHC.Types.TyThing import GHC.Types.Id.Info import GHC.Types.Cpr@@ -73,12 +66,11 @@ import GHC.Core import GHC.Core.Utils ( exprType, mkSingleAltCase, bindNonRec ) import GHC.Core.Type+import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.Coercion ( isCoVar ) import GHC.Core.DataCon ( DataCon, dataConWorkId ) import GHC.Core.Multiplicity -import GHC.Hs.Utils ( mkChunkified, chunkify )- import GHC.Builtin.Types import GHC.Builtin.Names import GHC.Builtin.Types.Prim@@ -88,6 +80,7 @@ import GHC.Utils.Panic import GHC.Utils.Panic.Plain +import GHC.Settings.Constants( mAX_TUPLE_SIZE ) import GHC.Data.FastString import Data.List ( partition )@@ -171,9 +164,7 @@ = (App fun (Coercion co), funResultTy fun_ty) mkCoreAppTyped d (fun, fun_ty) arg = assertPpr (isFunTy fun_ty) (ppr fun $$ ppr arg $$ d)- (App fun arg, res_ty)- where- (_mult, _arg_ty, res_ty) = splitFunTy fun_ty+ (App fun arg, funResultTy fun_ty) {- ********************************************************************* * *@@ -182,7 +173,7 @@ ********************************************************************* -} mkWildEvBinder :: PredType -> EvVar-mkWildEvBinder pred = mkWildValBinder Many pred+mkWildEvBinder pred = mkWildValBinder ManyTy pred -- | Make a /wildcard binder/. This is typically used when you need a binder -- that you expect to use only at a *binding* site. Do not use it at@@ -221,7 +212,7 @@ -- See Note [Empty case alternatives] in GHC.Core castBottomExpr e res_ty | e_ty `eqType` res_ty = e- | otherwise = Case e (mkWildValBinder One e_ty) res_ty []+ | otherwise = Case e (mkWildValBinder OneTy e_ty) res_ty [] where e_ty = exprType e @@ -238,9 +229,9 @@ | isCoVarType ty = Nothing -- Satisfy INVARIANT 2 | otherwise- = Just (Lit (LitRubbish rep) `mkTyApps` [ty])+ = Just (Lit (LitRubbish torc rep) `mkTyApps` [ty]) where- rep = getRuntimeRep ty+ Just (torc, rep) = sORTKind_maybe (typeKind ty) {- ************************************************************************@@ -335,22 +326,12 @@ {- ************************************************************************ * *-\subsection{Tuple constructors}+ Creating tuples and their types for Core expressions * * ************************************************************************ -} -{--Creating tuples and their types for Core expressions--@mkBigCoreVarTup@ builds a tuple; the inverse to @mkTupleSelector@.--* If it has only one element, it is the identity function.--* If there are more elements than a big tuple can have, it nests- the tuples.--Note [Flattening one-tuples]+{- Note [Flattening one-tuples] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This family of functions creates a tuple of variables/expressions/types. mkCoreTup [e1,e2,e3] = (e1,e2,e3)@@ -361,8 +342,8 @@ mkCoreTup [e1] = e1 * Build a one-tuple (see Note [One-tuples] in GHC.Builtin.Types)- mkCoreTup1 [e1] = Solo e1- We use a suffix "1" to indicate this.+ mkCoreTupSolo [e1] = Solo e1+ We use a suffix "Solo" to indicate this. Usually we want the former, but occasionally the latter. @@ -380,47 +361,52 @@ One-tuples that arise internally depend on the circumstance; often flattening is a good idea. Decisions are made on a case-by-case basis. +'mkCoreBoxedTuple` and `mkBigCoreVarTupSolo` build tuples without flattening. -} --- | Build the type of a small tuple that holds the specified variables--- One-tuples are flattened; see Note [Flattening one-tuples]-mkCoreVarTupTy :: [Id] -> Type-mkCoreVarTupTy ids = mkBoxedTupleTy (map idType ids)- -- | Build a small tuple holding the specified expressions--- One-tuples are flattened; see Note [Flattening one-tuples]-mkCoreTup :: [CoreExpr] -> CoreExpr-mkCoreTup [c] = c-mkCoreTup cs = mkCoreTup1 cs -- non-1-tuples are uniform---- | Build a small tuple holding the specified expressions -- One-tuples are *not* flattened; see Note [Flattening one-tuples] -- See also Note [Don't flatten tuples from HsSyn]-mkCoreTup1 :: [CoreExpr] -> CoreExpr-mkCoreTup1 cs = mkCoreConApps (tupleDataCon Boxed (length cs))- (map (Type . exprType) cs ++ cs)+-- Arguments must have kind Type+mkCoreBoxedTuple :: HasDebugCallStack => [CoreExpr] -> CoreExpr+mkCoreBoxedTuple cs+ = assertPpr (all (tcIsLiftedTypeKind . typeKind . exprType) cs) (ppr cs)+ mkCoreConApps (tupleDataCon Boxed (length cs))+ (map (Type . exprType) cs ++ cs) --- | Build a small unboxed tuple holding the specified expressions,--- with the given types. The types must be the types of the expressions.++-- | Build a small unboxed tuple holding the specified expressions. -- Do not include the RuntimeRep specifiers; this function calculates them -- for you. -- Does /not/ flatten one-tuples; see Note [Flattening one-tuples]-mkCoreUbxTup :: [Type] -> [CoreExpr] -> CoreExpr-mkCoreUbxTup tys exps- = assert (tys `equalLength` exps) $- mkCoreConApps (tupleDataCon Unboxed (length tys))- (map (Type . getRuntimeRep) tys ++ map Type tys ++ exps)+mkCoreUnboxedTuple :: [CoreExpr] -> CoreExpr+mkCoreUnboxedTuple exps+ = mkCoreConApps (tupleDataCon Unboxed (length tys))+ (map (Type . getRuntimeRep) tys ++ map Type tys ++ exps)+ where+ tys = map exprType exps -- | Make a core tuple of the given boxity; don't flatten 1-tuples mkCoreTupBoxity :: Boxity -> [CoreExpr] -> CoreExpr-mkCoreTupBoxity Boxed exps = mkCoreTup1 exps-mkCoreTupBoxity Unboxed exps = mkCoreUbxTup (map exprType exps) exps+mkCoreTupBoxity Boxed exps = mkCoreBoxedTuple exps+mkCoreTupBoxity Unboxed exps = mkCoreUnboxedTuple exps +-- | Build the type of a small tuple that holds the specified variables+-- One-tuples are flattened; see Note [Flattening one-tuples]+mkCoreVarTupTy :: [Id] -> Type+mkCoreVarTupTy ids = mkBoxedTupleTy (map idType ids)++-- | Build a small tuple holding the specified expressions+-- One-tuples are flattened; see Note [Flattening one-tuples]+mkCoreTup :: [CoreExpr] -> CoreExpr+mkCoreTup [c] = c+mkCoreTup cs = mkCoreBoxedTuple cs -- non-1-tuples are uniform+ -- | Build an unboxed sum. -- -- Alternative number ("alt") starts from 1.-mkCoreUbxSum :: Int -> Int -> [Type] -> CoreExpr -> CoreExpr-mkCoreUbxSum arity alt tys exp+mkCoreUnboxedSum :: Int -> Int -> [Type] -> CoreExpr -> CoreExpr+mkCoreUnboxedSum arity alt tys exp = assert (length tys == arity) $ assert (alt <= arity) $ mkCoreConApps (sumDataCon alt arity)@@ -428,37 +414,153 @@ ++ map Type tys ++ [exp]) +{- Note [Big tuples]+~~~~~~~~~~~~~~~~~~~~+"Big" tuples (`mkBigCoreTup` and friends) are more general than "small"+ones (`mkCoreTup` and friends) in two ways.++1. GHCs built-in tuples can only go up to 'mAX_TUPLE_SIZE' in arity, but+ we might conceivably want to build such a massive tuple as part of the+ output of a desugaring stage (notably that for list comprehensions).++ `mkBigCoreTup` encodes such big tuples by creating and pattern+ matching on /nested/ small tuples that are directly expressible by+ GHC.++ Nesting policy: it's better to have a 2-tuple of 10-tuples (3 objects)+ than a 10-tuple of 2-tuples (11 objects), so we want the leaves of any+ construction to be big.++2. When desugaring arrows we gather up a tuple of free variables, which+ may include dictionaries (of kind Constraint) and unboxed values.++ These can't live in a tuple. `mkBigCoreTup` encodes such tuples by+ boxing up the offending arguments: see Note [Boxing constructors]+ in GHC.Builtin.Types.++If you just use the 'mkBigCoreTup', 'mkBigCoreVarTupTy', 'mkBigTupleSelector'+and 'mkBigTupleCase' functions to do all your work with tuples you should be+fine, and not have to worry about the arity limitation, or kind limitation at+all.++The "big" tuple operations flatten 1-tuples just like "small" tuples.+But see Note [Don't flatten tuples from HsSyn]+-}++mkBigCoreVarTupSolo :: [Id] -> CoreExpr+-- Same as mkBigCoreVarTup, but:+-- - one-tuples are not flattened+-- see Note [Flattening one-tuples]+-- - arguments should have kind Type+mkBigCoreVarTupSolo [id] = mkCoreBoxedTuple [Var id]+mkBigCoreVarTupSolo ids = mkChunkified mkCoreTup (map Var ids)+ -- | Build a big tuple holding the specified variables -- One-tuples are flattened; see Note [Flattening one-tuples]+-- Arguments don't have to have kind Type mkBigCoreVarTup :: [Id] -> CoreExpr mkBigCoreVarTup ids = mkBigCoreTup (map Var ids) -mkBigCoreVarTup1 :: [Id] -> CoreExpr--- Same as mkBigCoreVarTup, but one-tuples are NOT flattened--- see Note [Flattening one-tuples]-mkBigCoreVarTup1 [id] = mkCoreConApps (tupleDataCon Boxed 1)- [Type (idType id), Var id]-mkBigCoreVarTup1 ids = mkBigCoreTup (map Var ids)+-- | Build a "big" tuple holding the specified expressions+-- One-tuples are flattened; see Note [Flattening one-tuples]+-- Arguments don't have to have kind Type; ones that do not are boxed+-- This function crashes (in wrapBox) if given a non-Type+-- argument that it doesn't know how to box.+mkBigCoreTup :: [CoreExpr] -> CoreExpr+mkBigCoreTup exprs = mkChunkified mkCoreTup (map wrapBox exprs) -- | Build the type of a big tuple that holds the specified variables -- One-tuples are flattened; see Note [Flattening one-tuples] mkBigCoreVarTupTy :: [Id] -> Type mkBigCoreVarTupTy ids = mkBigCoreTupTy (map idType ids) --- | Build a big tuple holding the specified expressions--- One-tuples are flattened; see Note [Flattening one-tuples]-mkBigCoreTup :: [CoreExpr] -> CoreExpr-mkBigCoreTup = mkChunkified mkCoreTup- -- | Build the type of a big tuple that holds the specified type of thing -- One-tuples are flattened; see Note [Flattening one-tuples] mkBigCoreTupTy :: [Type] -> Type-mkBigCoreTupTy = mkChunkified mkBoxedTupleTy+mkBigCoreTupTy tys = mkChunkified mkBoxedTupleTy $+ map boxTy tys -- | The unit expression unitExpr :: CoreExpr unitExpr = Var unitDataConId +--------------------------------------------------------------+wrapBox :: CoreExpr -> CoreExpr+-- ^ If (e :: ty) and (ty :: Type), wrapBox is a no-op+-- But if (ty :: ki), and ki is not Type, wrapBox returns (K @ty e)+-- which has kind Type+-- where K is the boxing data constructor for ki+-- See Note [Boxing constructors] in GHC.Builtin.Types+-- Panics if there /is/ no boxing data con+wrapBox e+ = case boxingDataCon e_ty of+ BI_NoBoxNeeded -> e+ BI_Box { bi_inst_con = boxing_expr } -> App boxing_expr e+ BI_NoBoxAvailable -> pprPanic "wrapBox" (ppr e $$ ppr (exprType e))+ -- We should do better than panicing: #22336+ where+ e_ty = exprType e++boxTy :: Type -> Type+-- ^ `boxTy ty` is the boxed version of `ty`. That is,+-- if `e :: ty`, then `wrapBox e :: boxTy ty`.+-- Note that if `ty :: Type`, `boxTy ty` just returns `ty`.+-- Panics if it is not possible to box `ty`, like `wrapBox` (#22336)+-- See Note [Boxing constructors] in GHC.Builtin.Types+boxTy ty+ = case boxingDataCon ty of+ BI_NoBoxNeeded -> ty+ BI_Box { bi_boxed_type = box_ty } -> box_ty+ BI_NoBoxAvailable -> pprPanic "boxTy" (ppr ty)+ -- We should do better than panicing: #22336++unwrapBox :: UniqSupply -> Id -> CoreExpr+ -> (UniqSupply, Id, CoreExpr)+-- If v's type required boxing (i.e it is unlifted or a constraint)+-- then (unwrapBox us v body) returns+-- (case box_v of MkDict v -> body)+-- together with box_v+-- where box_v is a fresh variable+-- Otherwise unwrapBox is a no-op+-- Panics if no box is available (#22336)+unwrapBox us var body+ = case boxingDataCon var_ty of+ BI_NoBoxNeeded -> (us, var, body)+ BI_NoBoxAvailable -> pprPanic "unwrapBox" (ppr var $$ ppr var_ty)+ -- We should do better than panicing: #22336+ BI_Box { bi_data_con = box_con, bi_boxed_type = box_ty }+ -> (us', var', body')+ where+ var' = mkSysLocal (fsLit "uc") uniq ManyTy box_ty+ body' = Case (Var var') var' (exprType body)+ [Alt (DataAlt box_con) [var] body]+ where+ var_ty = idType var+ (uniq, us') = takeUniqFromSupply us++-- | Lifts a \"small\" constructor into a \"big\" constructor by recursive decomposition+mkChunkified :: ([a] -> a) -- ^ \"Small\" constructor function, of maximum input arity 'mAX_TUPLE_SIZE'+ -> [a] -- ^ Possible \"big\" list of things to construct from+ -> a -- ^ Constructed thing made possible by recursive decomposition+mkChunkified small_tuple as = mk_big_tuple (chunkify as)+ where+ -- Each sub-list is short enough to fit in a tuple+ mk_big_tuple [as] = small_tuple as+ mk_big_tuple as_s = mk_big_tuple (chunkify (map small_tuple as_s))++chunkify :: [a] -> [[a]]+-- ^ Split a list into lists that are small enough to have a corresponding+-- tuple arity. The sub-lists of the result all have length <= 'mAX_TUPLE_SIZE'+-- But there may be more than 'mAX_TUPLE_SIZE' sub-lists+chunkify xs+ | n_xs <= mAX_TUPLE_SIZE = [xs]+ | otherwise = split xs+ where+ n_xs = length xs+ split [] = []+ split xs = take mAX_TUPLE_SIZE xs : split (drop mAX_TUPLE_SIZE xs)++ {- ************************************************************************ * *@@ -479,16 +581,16 @@ -- If necessary, we pattern match on a \"big\" tuple. -- -- A tuple selector is not linear in its argument. Consequently, the case--- expression built by `mkTupleSelector` must consume its scrutinee 'Many'+-- expression built by `mkBigTupleSelector` must consume its scrutinee 'Many' -- times. And all the argument variables must have multiplicity 'Many'.-mkTupleSelector, mkTupleSelector1+mkBigTupleSelector, mkBigTupleSelectorSolo :: [Id] -- ^ The 'Id's to pattern match the tuple against -> Id -- ^ The 'Id' to select -> Id -- ^ A variable of the same type as the scrutinee -> CoreExpr -- ^ Scrutinee -> CoreExpr -- ^ Selector expression --- mkTupleSelector [a,b,c,d] b v e+-- mkBigTupleSelector [a,b,c,d] b v e -- = case e of v { -- (p,q) -> case p of p { -- (a,b) -> b }}@@ -499,7 +601,7 @@ -- case (case e of v -- (p,q) -> p) of p -- (a,b) -> b-mkTupleSelector vars the_var scrut_var scrut+mkBigTupleSelector vars the_var scrut_var scrut = mk_tup_sel (chunkify vars) the_var where mk_tup_sel [vars] the_var = mkSmallTupleSelector vars the_var scrut_var scrut@@ -508,18 +610,18 @@ where tpl_tys = [mkBoxedTupleTy (map idType gp) | gp <- vars_s] tpl_vs = mkTemplateLocals tpl_tys- [(tpl_v, group)] = [(tpl,gp) | (tpl,gp) <- zipEqual "mkTupleSelector" tpl_vs vars_s,+ [(tpl_v, group)] = [(tpl,gp) | (tpl,gp) <- zipEqual "mkBigTupleSelector" tpl_vs vars_s, the_var `elem` gp ]--- ^ 'mkTupleSelector1' is like 'mkTupleSelector'+-- ^ 'mkBigTupleSelectorSolo' is like 'mkBigTupleSelector' -- but one-tuples are NOT flattened (see Note [Flattening one-tuples])-mkTupleSelector1 vars the_var scrut_var scrut+mkBigTupleSelectorSolo vars the_var scrut_var scrut | [_] <- vars = mkSmallTupleSelector1 vars the_var scrut_var scrut | otherwise- = mkTupleSelector vars the_var scrut_var scrut+ = mkBigTupleSelector vars the_var scrut_var scrut --- | Like 'mkTupleSelector' but for tuples that are guaranteed--- never to be \"big\".+-- | `mkSmallTupleSelector` is like 'mkBigTupleSelector', but for tuples that+-- are guaranteed never to be "big". Also does not unwrap boxed types. -- -- > mkSmallTupleSelector [x] x v e = [| e |] -- > mkSmallTupleSelector [x,y,z] x v e = [| case e of v { (x,y,z) -> x } |]@@ -542,45 +644,71 @@ Case scrut scrut_var (idType the_var) [Alt (DataAlt (tupleDataCon Boxed (length vars))) vars (Var the_var)] --- | A generalization of 'mkTupleSelector', allowing the body+-- | A generalization of 'mkBigTupleSelector', allowing the body -- of the case to be an arbitrary expression. -- -- To avoid shadowing, we use uniques to invent new variables. ----- If necessary we pattern match on a \"big\" tuple.-mkTupleCase :: UniqSupply -- ^ For inventing names of intermediate variables- -> [Id] -- ^ The tuple identifiers to pattern match on- -> CoreExpr -- ^ Body of the case- -> Id -- ^ A variable of the same type as the scrutinee- -> CoreExpr -- ^ Scrutinee- -> CoreExpr+-- If necessary we pattern match on a "big" tuple.+mkBigTupleCase :: UniqSupply -- ^ For inventing names of intermediate variables+ -> [Id] -- ^ The tuple identifiers to pattern match on;+ -- Bring these into scope in the body+ -> CoreExpr -- ^ Body of the case+ -> CoreExpr -- ^ Scrutinee+ -> CoreExpr -- ToDo: eliminate cases where none of the variables are needed. ----- mkTupleCase uniqs [a,b,c,d] body v e+-- mkBigTupleCase uniqs [a,b,c,d] body v e -- = case e of v { (p,q) -> -- case p of p { (a,b) -> -- case q of q { (c,d) -> -- body }}}-mkTupleCase uniqs vars body scrut_var scrut- = mk_tuple_case uniqs (chunkify vars) body+mkBigTupleCase us vars body scrut+ = mk_tuple_case wrapped_us (chunkify wrapped_vars) wrapped_body where+ (wrapped_us, wrapped_vars, wrapped_body) = foldr unwrap (us,[],body) vars++ scrut_ty = exprType scrut++ unwrap var (us,vars,body)+ = (us', var':vars, body')+ where+ (us', var', body') = unwrapBox us var body++ mk_tuple_case :: UniqSupply -> [[Id]] -> CoreExpr -> CoreExpr+ -- mk_tuple_case [[a1..an], [b1..bm], ...] body+ -- case scrut of (p,q, ...) ->+ -- case p of (a1,..an) ->+ -- case q of (b1,..bm) ->+ -- ... -> body -- This is the case where don't need any nesting- mk_tuple_case _ [vars] body+ mk_tuple_case us [vars] body = mkSmallTupleCase vars body scrut_var scrut+ where+ scrut_var = case scrut of+ Var v -> v+ _ -> snd (new_var us scrut_ty) - -- This is the case where we must make nest tuples at least once+ -- This is the case where we must nest tuples at least once mk_tuple_case us vars_s body- = let (us', vars', body') = foldr one_tuple_case (us, [], body) vars_s- in mk_tuple_case us' (chunkify vars') body'+ = mk_tuple_case us' (chunkify vars') body'+ where+ (us', vars', body') = foldr one_tuple_case (us, [], body) vars_s one_tuple_case chunk_vars (us, vs, body)- = let (uniq, us') = takeUniqFromSupply us- scrut_var = mkSysLocal (fsLit "ds") uniq Many- (mkBoxedTupleTy (map idType chunk_vars))- body' = mkSmallTupleCase chunk_vars body scrut_var (Var scrut_var)- in (us', scrut_var:vs, body')+ = (us', scrut_var:vs, body')+ where+ tup_ty = mkBoxedTupleTy (map idType chunk_vars)+ (us', scrut_var) = new_var us tup_ty+ body' = mkSmallTupleCase chunk_vars body scrut_var (Var scrut_var) --- | As 'mkTupleCase', but for a tuple that is small enough to be guaranteed+ new_var :: UniqSupply -> Type -> (UniqSupply, Id)+ new_var us ty = (us', id)+ where+ (uniq, us') = takeUniqFromSupply us+ id = mkSysLocal (fsLit "ds") uniq ManyTy ty++-- | As 'mkBigTupleCase', but for a tuple that is small enough to be guaranteed -- not to need nesting. mkSmallTupleCase :: [Id] -- ^ The tuple args@@ -592,7 +720,6 @@ mkSmallTupleCase [var] body _scrut_var scrut = bindNonRec var scrut body mkSmallTupleCase vars body scrut_var scrut--- One branch no refinement? = Case scrut scrut_var (exprType body) [Alt (DataAlt (tupleDataCon Boxed (length vars))) vars body] @@ -655,9 +782,6 @@ mkListExpr :: Type -> [CoreExpr] -> CoreExpr mkListExpr ty xs = foldr (mkConsExpr ty) (mkNilExpr ty) xs -mkNonEmptyListExpr :: Type -> CoreExpr -> [CoreExpr] -> CoreExpr-mkNonEmptyListExpr ty x xs = mkCoreConApps nonEmptyDataCon [Type ty, x, mkListExpr ty xs]- -- | Make a fully applied 'foldr' expression mkFoldrExpr :: MonadThings m => Type -- ^ Element type of the list@@ -685,7 +809,7 @@ n_tyvar <- newTyVar alphaTyVar let n_ty = mkTyVarTy n_tyvar c_ty = mkVisFunTysMany [elt_ty, n_ty] n_ty- [c, n] <- sequence [mkSysLocalM (fsLit "c") Many c_ty, mkSysLocalM (fsLit "n") Many n_ty]+ [c, n] <- sequence [mkSysLocalM (fsLit "c") ManyTy c_ty, mkSysLocalM (fsLit "n") ManyTy n_ty] build_inside <- mk_build_inside (c, c_ty) (n, n_ty) @@ -766,12 +890,12 @@ pAT_ERROR_ID, rEC_CON_ERROR_ID, rEC_SEL_ERROR_ID,- aBSENT_ERROR_ID,+ aBSENT_ERROR_ID, aBSENT_CONSTRAINT_ERROR_ID, aBSENT_SUM_FIELD_ERROR_ID, tYPE_ERROR_ID -- Used with Opt_DeferTypeErrors, see #10284 ] -recSelErrorName, runtimeErrorName, absentErrorName :: Name+recSelErrorName, runtimeErrorName :: Name recConErrorName, patErrorName :: Name nonExhaustiveGuardsErrorName, noMethodBindingErrorName :: Name typeErrorName :: Name@@ -793,7 +917,7 @@ rEC_SEL_ERROR_ID, rUNTIME_ERROR_ID, rEC_CON_ERROR_ID :: Id pAT_ERROR_ID, nO_METHOD_BINDING_ERROR_ID, nON_EXHAUSTIVE_GUARDS_ERROR_ID :: Id-tYPE_ERROR_ID, aBSENT_ERROR_ID, aBSENT_SUM_FIELD_ERROR_ID :: Id+tYPE_ERROR_ID, aBSENT_SUM_FIELD_ERROR_ID :: Id rEC_SEL_ERROR_ID = mkRuntimeErrorId recSelErrorName rUNTIME_ERROR_ID = mkRuntimeErrorId runtimeErrorName rEC_CON_ERROR_ID = mkRuntimeErrorId recConErrorName@@ -901,13 +1025,6 @@ absentSumFieldErrorIdKey aBSENT_SUM_FIELD_ERROR_ID -absentErrorName- = mkWiredInIdName- gHC_PRIM_PANIC- (fsLit "absentError")- absentErrorIdKey- aBSENT_ERROR_ID- aBSENT_SUM_FIELD_ERROR_ID = mkExceptionId absentSumFieldErrorName -- | Exception with type \"forall a. a\"@@ -1054,19 +1171,51 @@ be relying on anything from it. -} -aBSENT_ERROR_ID -- See Note [aBSENT_ERROR_ID]- = mkVanillaGlobalWithInfo absentErrorName absent_ty id_info- where- absent_ty = mkSpecForAllTys [alphaTyVar] (mkVisFunTyMany addrPrimTy alphaTy)- -- Not runtime-rep polymorphic. aBSENT_ERROR_ID is only used for- -- lifted-type things; see Note [Absent fillers] in GHC.Core.Opt.WorkWrap.Utils- id_info = divergingIdInfo [evalDmd] -- NB: CAFFY!+-- We need two absentError Ids:+-- absentError :: forall (a :: Type). Addr# -> a+-- absentConstraintError :: forall (a :: Constraint). Addr# -> a+-- We don't have polymorphism over TypeOrConstraint!+-- mkAbsentErrorApp chooses which one to use, based on the kind mkAbsentErrorApp :: Type -- The type to instantiate 'a' -> String -- The string to print -> CoreExpr mkAbsentErrorApp res_ty err_msg- = mkApps (Var aBSENT_ERROR_ID) [ Type res_ty, err_string ]+ = mkApps (Var err_id) [ Type res_ty, err_string ] where+ err_id | isConstraintLikeKind (typeKind res_ty) = aBSENT_CONSTRAINT_ERROR_ID+ | otherwise = aBSENT_ERROR_ID err_string = Lit (mkLitString err_msg)++absentErrorName, absentConstraintErrorName :: Name+absentErrorName+ = mkWiredInIdName gHC_PRIM_PANIC (fsLit "absentError")+ absentErrorIdKey aBSENT_ERROR_ID++absentConstraintErrorName+ = mkWiredInIdName gHC_PRIM_PANIC (fsLit "absentConstraintError")+ absentConstraintErrorIdKey aBSENT_CONSTRAINT_ERROR_ID++aBSENT_ERROR_ID, aBSENT_CONSTRAINT_ERROR_ID :: Id++aBSENT_ERROR_ID -- See Note [aBSENT_ERROR_ID]+ = mkVanillaGlobalWithInfo absentErrorName absent_ty id_info+ where+ -- absentError :: forall (a :: Type). Addr# -> a+ absent_ty = mkSpecForAllTys [alphaTyVar] $+ mkVisFunTyMany addrPrimTy (mkTyVarTy alphaTyVar)+ -- Not runtime-rep polymorphic. aBSENT_ERROR_ID is only used for+ -- lifted-type things; see Note [Absent fillers] in GHC.Core.Opt.WorkWrap.Utils+ id_info = divergingIdInfo [evalDmd] -- NB: CAFFY!++aBSENT_CONSTRAINT_ERROR_ID -- See Note [aBSENT_ERROR_ID]+ = mkVanillaGlobalWithInfo absentConstraintErrorName absent_ty id_info+ where+ -- absentConstraintError :: forall (a :: Constraint). Addr# -> a+ absent_ty = mkSpecForAllTys [alphaConstraintTyVar] $+ mkFunTy visArgConstraintLike ManyTy+ addrPrimTy (mkTyVarTy alphaConstraintTyVar)+ id_info = divergingIdInfo [evalDmd] -- NB: CAFFY!++
compiler/GHC/Core/Map/Expr.hs view
@@ -150,9 +150,8 @@ eqDeBruijnExpr :: DeBruijn CoreExpr -> DeBruijn CoreExpr -> Bool eqDeBruijnExpr (D env1 e1) (D env2 e2) = go e1 e2 where- go (Var v1) (Var v2) = eqDeBruijnVar (D env1 v1) (D env2 v2)+ go (Var v1) (Var v2) = eqDeBruijnVar (D env1 v1) (D env2 v2) go (Lit lit1) (Lit lit2) = lit1 == lit2- -- See Note [Using tcView inside eqDeBruijnType] in GHC.Core.Map.Type go (Type t1) (Type t2) = eqDeBruijnType (D env1 t1) (D env2 t2) -- See Note [Alpha-equality for Coercion arguments] go (Coercion {}) (Coercion {}) = True@@ -163,7 +162,6 @@ && go e1 e2 go (Lam b1 e1) (Lam b2 e2)- -- See Note [Using tcView inside eqDeBruijnType] in GHC.Core.Map.Type = eqDeBruijnType (D env1 (varType b1)) (D env2 (varType b2)) && D env1 (varMultMaybe b1) == D env2 (varMultMaybe b2) && eqDeBruijnExpr (D (extendCME env1 b1) e1) (D (extendCME env2 b2) e2)@@ -175,9 +173,7 @@ go (Let (Rec ps1) e1) (Let (Rec ps2) e2) = equalLength ps1 ps2 -- See Note [Alpha-equality for let-bindings]- && all2 (\b1 b2 -> -- See Note [Using tcView inside eqDeBruijnType] in- -- GHC.Core.Map.Type- eqDeBruijnType (D env1 (varType b1))+ && all2 (\b1 b2 -> eqDeBruijnType (D env1 (varType b1)) (D env2 (varType b2))) bs1 bs2 && D env1' rs1 == D env2' rs2
compiler/GHC/Core/Map/Type.hs view
@@ -38,6 +38,7 @@ import GHC.Core.Type import GHC.Core.Coercion import GHC.Core.TyCo.Rep+import GHC.Core.TyCo.Compare( eqForAllVis ) import GHC.Data.TrieMap import GHC.Data.FastString@@ -54,7 +55,6 @@ import qualified Data.IntMap as IntMap import Control.Monad ( (>=>) )-import GHC.Data.Maybe -- NB: Be careful about RULES and type families (#5821). So we should make sure -- to specify @Key TypeMapX@ (and not @DeBruijn Type@, the reduced form)@@ -149,13 +149,6 @@ = TM { tm_var :: VarMap a , tm_app :: TypeMapG (TypeMapG a) -- Note [Equality on AppTys] in GHC.Core.Type , tm_tycon :: DNameEnv a-- -- only InvisArg arrows here- , tm_funty :: TypeMapG (TypeMapG (TypeMapG a))- -- keyed on the argument, result rep, and result- -- constraints are never linear-restricted and are always lifted- -- See also Note [Equality on FunTys] in GHC.Core.TyCo.Rep- , tm_forall :: TypeMapG (BndrMap a) -- See Note [Binders] in GHC.Core.Map.Expr , tm_tylit :: TyLitMap a , tm_coerce :: Maybe a@@ -165,28 +158,27 @@ -- | Squeeze out any synonyms, and change TyConApps to nested AppTys. Why the -- last one? See Note [Equality on AppTys] in GHC.Core.Type ----- Note, however, that we keep Constraint and Type apart here, despite the fact--- that they are both synonyms of TYPE 'LiftedRep (see #11715).--- -- We also keep (Eq a => a) as a FunTy, distinct from ((->) (Eq a) a). trieMapView :: Type -> Maybe Type trieMapView ty -- First check for TyConApps that need to be expanded to- -- AppTy chains.- | Just (tc, tys@(_:_)) <- tcSplitTyConApp_maybe ty+ -- AppTy chains. This includes eliminating FunTy entirely.+ | Just (tc, tys@(_:_)) <- splitTyConApp_maybe ty = Just $ foldl' AppTy (mkTyConTy tc) tys -- Then resolve any remaining nullary synonyms.- | Just ty' <- tcView ty = Just ty'+ | Just ty' <- coreView ty+ = Just ty'+ trieMapView _ = Nothing -- TODO(22292): derive instance Functor TypeMapX where fmap f TM- { tm_var = tvar, tm_app = tapp, tm_tycon = ttycon, tm_funty = tfunty, tm_forall = tforall+ { tm_var = tvar, tm_app = tapp, tm_tycon = ttycon, tm_forall = tforall , tm_tylit = tlit, tm_coerce = tcoerce } = TM { tm_var = fmap f tvar, tm_app = fmap (fmap f) tapp, tm_tycon = fmap f ttycon- , tm_funty = fmap (fmap (fmap f)) tfunty, tm_forall = fmap (fmap f) tforall+ , tm_forall = fmap (fmap f) tforall , tm_tylit = fmap f tlit, tm_coerce = fmap f tcoerce } instance TrieMap TypeMapX where@@ -200,27 +192,6 @@ instance Eq (DeBruijn Type) where (==) = eqDeBruijnType -{- Note [Using tcView inside eqDeBruijnType]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-`eqDeBruijnType` uses `tcView` and thus treats Type and Constraint as-distinct -- see Note [coreView vs tcView] in GHC.Core.Type. We do that because-`eqDeBruijnType` is used in TrieMaps, which are used for instance for instance-selection in the type checker. [Or at least will be soon.]--However, the odds that we have two expressions that are identical save for the-'Type'/'Constraint' distinction are low. (Not impossible to do. But doubtful-anyone has ever done so in the history of Haskell.)--And it's actually all OK: 'eqCoreExpr' is conservative: if `eqCoreExpr e1 e2` returns-'True', thne it must be that `e1` behaves identically to `e2` in all contexts.-But if `eqCoreExpr e1 e2` returns 'False', then we learn nothing. The use of-'tcView' where we expect 'coreView' means 'eqCoreExpr' returns 'False' bit more-often that it should. This might, say, stop a `RULE` from firing or CSE from-optimizing an expression. Stopping `RULE` firing is good actually: `RULES` are-written in Haskell, where `Type /= Constraint`. Stopping CSE is unfortunate,-but tolerable.--}- -- | An equality relation between two 'Type's (known below as @t1 :: k2@ -- and @t2 :: k2@) data TypeEquality = TNEQ -- ^ @t1 /= t2@@@ -262,9 +233,8 @@ | tc1 == tc2 = TEQ go env_t@(D env t) env_t'@(D env' t')- -- See Note [Using tcView inside eqDeBruijnType]- | Just new_t <- tcView t = go (D env new_t) env_t'- | Just new_t' <- tcView t' = go env_t (D env' new_t')+ | Just new_t <- coreView t = go (D env new_t) env_t'+ | Just new_t' <- coreView t' = go env_t (D env' new_t') | otherwise = case (t, t') of -- See Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep@@ -274,9 +244,9 @@ (TyVarTy v, TyVarTy v') -> liftEquality $ eqDeBruijnVar (D env v) (D env' v') -- See Note [Equality on AppTys] in GHC.Core.Type- (AppTy t1 t2, s) | Just (t1', t2') <- repSplitAppTy_maybe s+ (AppTy t1 t2, s) | Just (t1', t2') <- splitAppTyNoView_maybe s -> go (D env t1) (D env' t1') `andEq` go (D env t2) (D env' t2')- (s, AppTy t1' t2') | Just (t1, t2) <- repSplitAppTy_maybe s+ (s, AppTy t1' t2') | Just (t1, t2) <- splitAppTyNoView_maybe s -> go (D env t1) (D env' t1') `andEq` go (D env t2) (D env' t2') (FunTy v1 w1 t1 t2, FunTy v1' w1' t1' t2') @@ -292,9 +262,9 @@ (LitTy l, LitTy l') -> liftEquality (l == l') (ForAllTy (Bndr tv vis) ty, ForAllTy (Bndr tv' vis') ty')- -> -- See Note [ForAllTy and typechecker equality] in- -- GHC.Tc.Solver.Canonical for why we use `sameVis` here- liftEquality (vis `sameVis` vis') `andEq`+ -> -- See Note [ForAllTy and type equality] in+ -- GHC.Core.TyCo.Compare for why we use `eqForAllVis` here+ liftEquality (vis `eqForAllVis` vis') `andEq` go (D env (varType tv)) (D env' (varType tv')) `andEq` go (D (extendCME env tv) ty) (D (extendCME env' tv') ty') (CoercionTy {}, CoercionTy {})@@ -324,7 +294,6 @@ emptyT = TM { tm_var = emptyTM , tm_app = emptyTM , tm_tycon = emptyDNameEnv- , tm_funty = emptyTM , tm_forall = emptyTM , tm_tylit = emptyTyLitMap , tm_coerce = Nothing }@@ -338,19 +307,17 @@ go (AppTy t1 t2) = tm_app >.> lkG (D env t1) >=> lkG (D env t2) go (TyConApp tc []) = tm_tycon >.> lkDNamed tc- go ty@(TyConApp _ (_:_)) = pprPanic "lkT TyConApp" (ppr ty) go (LitTy l) = tm_tylit >.> lkTyLit l go (ForAllTy (Bndr tv _) ty) = tm_forall >.> lkG (D (extendCME env tv) ty) >=> lkBndr env tv- go (FunTy InvisArg _ arg res)- | Just res_rep <- getRuntimeRep_maybe res- = tm_funty >.> lkG (D env arg)- >=> lkG (D env res_rep)- >=> lkG (D env res)- go ty@(FunTy {}) = pprPanic "lkT FunTy" (ppr ty) go (CastTy t _) = go t go (CoercionTy {}) = tm_coerce + -- trieMapView has eliminated non-nullary TyConApp+ -- and FunTy into an AppTy chain+ go ty@(TyConApp _ (_:_)) = pprPanic "lkT TyConApp" (ppr ty)+ go ty@(FunTy {}) = pprPanic "lkT FunTy" (ppr ty)+ ----------------- xtT :: DeBruijn Type -> XT a -> TypeMapX a -> TypeMapX a xtT (D env ty) f m | Just ty' <- trieMapView ty = xtT (D env ty') f m@@ -359,16 +326,15 @@ xtT (D env (AppTy t1 t2)) f m = m { tm_app = tm_app m |> xtG (D env t1) |>> xtG (D env t2) f } xtT (D _ (TyConApp tc [])) f m = m { tm_tycon = tm_tycon m |> xtDNamed tc f }-xtT (D env (FunTy InvisArg _ t1 t2)) f m = m { tm_funty = tm_funty m |> xtG (D env t1)- |>> xtG (D env t2_rep)- |>> xtG (D env t2) f }- where t2_rep = expectJust "xtT FunTy InvisArg" (getRuntimeRep_maybe t2) xtT (D _ (LitTy l)) f m = m { tm_tylit = tm_tylit m |> xtTyLit l f } xtT (D env (CastTy t _)) f m = xtT (D env t) f m xtT (D _ (CoercionTy {})) f m = m { tm_coerce = tm_coerce m |> f } xtT (D env (ForAllTy (Bndr tv _) ty)) f m = m { tm_forall = tm_forall m |> xtG (D (extendCME env tv) ty) |>> xtBndr env tv f }++-- trieMapView has eliminated non-nullary TyConApp+-- and FunTy into an AppTy chain xtT (D _ ty@(TyConApp _ (_:_))) _ _ = pprPanic "xtT TyConApp" (ppr ty) xtT (D _ ty@(FunTy {})) _ _ = pprPanic "xtT FunTy" (ppr ty) @@ -376,19 +342,17 @@ fdT k m = foldTM k (tm_var m) . foldTM (foldTM k) (tm_app m) . foldTM k (tm_tycon m)- . foldTM (foldTM (foldTM k)) (tm_funty m) . foldTM (foldTM k) (tm_forall m) . foldTyLit k (tm_tylit m) . foldMaybe k (tm_coerce m) filterT :: (a -> Bool) -> TypeMapX a -> TypeMapX a filterT f (TM { tm_var = tvar, tm_app = tapp, tm_tycon = ttycon- , tm_funty = tfunty, tm_forall = tforall, tm_tylit = tlit+ , tm_forall = tforall, tm_tylit = tlit , tm_coerce = tcoerce }) = TM { tm_var = filterTM f tvar , tm_app = fmap (filterTM f) tapp , tm_tycon = filterTM f ttycon- , tm_funty = fmap (fmap (filterTM f)) tfunty , tm_forall = fmap (filterTM f) tforall , tm_tylit = filterTM f tlit , tm_coerce = filterMaybe f tcoerce }
compiler/GHC/Core/Multiplicity.hs view
@@ -11,8 +11,8 @@ -} module GHC.Core.Multiplicity ( Mult- , pattern One- , pattern Many+ , pattern OneTy+ , pattern ManyTy , isMultMul , mkMultAdd , mkMultMul@@ -29,14 +29,16 @@ , scaleScaled , IsSubmult(..) , submult- , mapScaledType) where+ , mapScaledType+ , pprArrowWithMultiplicity ) where import GHC.Prelude import GHC.Utils.Outputable+import GHC.Core.Type import GHC.Core.TyCo.Rep+import GHC.Types.Var( isFUNArg ) import {-# SOURCE #-} GHC.Builtin.Types ( multMulTyCon )-import GHC.Core.Type import GHC.Builtin.Names (multMulTyConKey) import GHC.Types.Unique (hasKey) @@ -49,22 +51,30 @@ [https://arxiv.org/abs/1710.09756]. Other important resources in the linear types implementation wiki page [https://gitlab.haskell.org/ghc/ghc/wikis/linear-types/implementation], and the-proposal [https://github.com/ghc-proposals/ghc-proposals/pull/111] which+proposal [https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0111-linear-types.rst] which describes the concrete design at length. For the busy developer, though, here is a high-level view of linear types is the following: - Function arrows are annotated with a multiplicity (as defined by type `Mult` and its smart constructors in this module)- - Because, as a type constructor, the type of function now has an extra- argument, the notation (->) is no longer suitable. We named the function- type constructor `FUN`.- - (->) retains its backward compatible meaning: `(->) a b = a -> b`. To- achieve this, `(->)` is defined as a type synonym to `FUN Many` (see+ - Multiplicities, in Haskell, are types of kind `GHC.Types.Multiplicity`.+ as in++ map :: forall (p :: Multiplicity). (a %p -> b) -> [a] %p -> [b]++ - The type constructor for function types (FUN) has type++ FUN :: forall (m :: Multiplicity) -> forall {r1) {r2}. TYPE r1 -> TYPE r2 -> Type++ The argument order is explained in https://gitlab.haskell.org/ghc/ghc/-/issues/20164+ - (->) retains its backward compatible meaning:++ (->) a b = a -> b = a %'Many -> b++ To achieve this, `(->)` is defined as a type synonym to `FUN Many` (see below).-- Multiplicities can be reified in Haskell as types of kind- `GHC.Types.Multiplicity`-- Ground multiplicity (that is, without a variable) can be `One` or `Many`+- A ground multiplicity (that is, without a variable) can be `One` or `Many` (`Many` is generally rendered as ω in the scientific literature). Functions whose type is annotated with `One` are linear functions, functions whose type is annotated with `Many` are regular functions, often called “unrestricted”@@ -73,19 +83,9 @@ consumed exactly once, *then* its argument is consumed exactly once. You can think of “consuming exactly once” as evaluating a value in normal form exactly once (though not necessarily in one go). The _Linear Haskell_ article (see- infra) has a more precise definition of “consuming exactly once”.-- Data types can have unrestricted fields (the canonical example being the- `Unrestricted` data type), then these don't need to be consumed for a value to- be consumed exactly once. So consuming a value of type `Unrestricted` exactly- once means forcing it at least once.-- Why “at least once”? Because if `case u of { C x y -> f (C x y) }` is linear- (provided `f` is a linear function). So we might as well have done `case u of- { !z -> f z }`. So, we can observe constructors as many times as we want, and- we are actually allowed to force the same thing several times because laziness- means that we are really forcing a the value once, and observing its- constructor several times. The type checker and the linter recognise some (but- not all) of these multiple forces as indeed linear. Mostly just enough to- support variable patterns.+ supra) has a more precise definition of “consuming exactly once”.+- Data constructors are linear by default.+ See Note [Data constructors are linear by default]. - Multiplicities form a semiring. - Multiplicities can also be variables and we can universally quantify over these variables. This is referred to as “multiplicity@@ -100,6 +100,8 @@ multiplicity `Many` can consume its scrutinee as many time as it wishes (no matter how much the case expression is consumed). +For linear types in the linter see Note [Linting linearity] in GHC.Core.Lint.+ Note [Usages] ~~~~~~~~~~~~~ In the _Linear Haskell_ paper, you'll find typing rules such as these:@@ -206,8 +208,8 @@ Note [Data constructors are linear by default] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Data constructors defined without -XLinearTypes (as well as data constructors-defined with the Haskell 98 in all circumstances) have all their fields linear.+All data constructors defined without -XLinearTypes, as well as data constructors+defined with the Haskell 98 in all circumstances, have all their fields linear. That is, in @@ -217,10 +219,52 @@ Just :: a %1 -> Just a +Irrespective of whether -XLinearTypes is turned on or not. Furthermore, when+-XLinearTypes is turned off, the declaration++ data Endo a where { MkIntEndo :: (Int -> Int) -> T Int }++gives++ MkIntEndo :: (Int -> Int) %1 -> T Int++With -XLinearTypes turned on, instead, this would give++ data EndoU a where { MkIntEndoU :: (Int -> Int) -> T Int }+ MkIntEndoU :: (Int -> Int) -> T Int++With -XLinearTypes turned on, to get a linear field with GADT syntax we+would need to write++ data EndoL a where { MkIntEndoL :: (Int -> Int) %1 -> T Int }+ The goal is to maximise reuse of types between linear code and traditional code. This is argued at length in the proposal and the article (links in Note [Linear types]). +Unrestricted field don't need to be consumed for a value to be consumed exactly+once. So consuming a value of type `IntEndoU a` exactly once means forcing it at+least once.++Why “at least once”? Because if `case u of { MkIntEndoL x -> f (MkIntEndoL x) }`+is linear (provided `f` is a linear function). But we might as well have done+`case u of { !z -> f z }`. So, we can observe constructors as many times as we+want, and we are actually allowed to force the same thing several times because+laziness means that we are really forcing the value once, and observing its+constructor several times. The type checker and the linter recognise some (but+not all) of these multiple forces as indeed linear. Mostly just enough to+support variable patterns.++In summary:++- Fields of data constructors defined with Haskell 98 syntax are always linear+ (even if `-XLinearTypes` is off). This choice has been made to favour sharing+ types between linearly typed Haskell and traditional Haskell. To avoid an+ ecosystem split.+- When `-XLinearTypes` is off, GADT-syntax declaration can only use the regular+ arrow `(->)`. However all the fields are linear.++ Note [Polymorphisation of linear fields] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The choice in Note [Data constructors are linear by default] has an impact on@@ -295,13 +339,13 @@ -- With only two multiplicities One and Many, we can always replace -- p + q by Many. See Note [Overapproximating multiplicities]. mkMultAdd :: Mult -> Mult -> Mult-mkMultAdd _ _ = Many+mkMultAdd _ _ = ManyTy mkMultMul :: Mult -> Mult -> Mult-mkMultMul One p = p-mkMultMul p One = p-mkMultMul Many _ = Many-mkMultMul _ Many = Many+mkMultMul OneTy p = p+mkMultMul p OneTy = p+mkMultMul ManyTy _ = ManyTy+mkMultMul _ ManyTy = ManyTy mkMultMul p q = mkTyConApp multMulTyCon [p, q] scaleScaled :: Mult -> Scaled a -> Scaled a@@ -329,8 +373,25 @@ -- value of multiplicity @w2@ is expected. This is a partial order. submult :: Mult -> Mult -> IsSubmult-submult _ Many = Submult-submult One One = Submult+submult _ ManyTy = Submult+submult OneTy OneTy = Submult -- The 1 <= p rule-submult One _ = Submult+submult OneTy _ = Submult submult _ _ = Unknown++pprArrowWithMultiplicity :: FunTyFlag -> Either Bool SDoc -> SDoc+-- Pretty-print a multiplicity arrow. The multiplicity itself+-- is described by the (Either Bool SDoc)+-- Left False -- Many+-- Left True -- One+-- Right doc -- Something else+-- In the Right case, the doc is in parens if not atomic+pprArrowWithMultiplicity af pp_mult+ | isFUNArg af+ = case pp_mult of+ Left False -> arrow+ Left True -> lollipop+ Right doc -> text "%" <> doc <+> arrow+ | otherwise+ = ppr (funTyFlagTyCon af)+
compiler/GHC/Core/Opt/Arity.hs view
@@ -7,7 +7,6 @@ -} {-# LANGUAGE CPP #-}-{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} -- | Arity and eta expansion module GHC.Core.Opt.Arity@@ -64,6 +63,7 @@ import GHC.Core.Subst as Core import GHC.Core.Type as Type import GHC.Core.Coercion as Type+import GHC.Core.TyCo.Compare( eqType ) import GHC.Types.Demand import GHC.Types.Cpr( CprSig, mkCprSig, botCpr )@@ -85,7 +85,6 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Panic.Plain-import GHC.Utils.Trace import GHC.Utils.Misc {-@@ -197,7 +196,7 @@ | Just (_, ty') <- splitForAllTyCoVar_maybe ty = go rec_nts ty' - | Just (_,arg,res) <- splitFunTy_maybe ty+ | Just (_,_,arg,res) <- splitFunTy_maybe ty = typeOneShot arg : go rec_nts res | Just (tc,tys) <- splitTyConApp_maybe ty@@ -2237,7 +2236,7 @@ = (in_scope, EI (tcv' : bs) (mkHomoForAllMCo tcv' mco)) ----------- Function types (t1 -> t2)- | Just (mult, arg_ty, res_ty) <- splitFunTy_maybe ty+ | Just (_af, mult, arg_ty, res_ty) <- splitFunTy_maybe ty , typeHasFixedRuntimeRep arg_ty -- See Note [Representation polymorphism invariants] in GHC.Core -- See also test case typecheck/should_run/EtaExpandLevPoly@@ -2247,7 +2246,7 @@ , let eta_id' = eta_id `setIdOneShotInfo` one_shot , (in_scope, EI bs mco) <- go (n+1) oss1 subst' res_ty- = (in_scope, EI (eta_id' : bs) (mkFunResMCo (idScaledType eta_id') mco))+ = (in_scope, EI (eta_id' : bs) (mkFunResMCo eta_id' mco)) ----------- Newtypes -- Given this:@@ -2678,7 +2677,7 @@ -- ... and that the function can be eta reduced to arity 0 -- without violating invariants of Core and GHC && canEtaReduceToArity fun 0 0 -- criteria (L), (J), (W), (B)- all_calls_with_arity n = isStrict (peelManyCalls n eval_sd)+ all_calls_with_arity n = isStrict (fst $ peelManyCalls n eval_sd) -- See Note [Eta reduction based on evaluation context] ---------------@@ -2710,15 +2709,15 @@ ok_arg bndr (Var v) co fun_ty | bndr == v , let mult = idMult bndr- , Just (fun_mult, _, _) <- splitFunTy_maybe fun_ty+ , Just (_af, fun_mult, _, _) <- splitFunTy_maybe fun_ty , mult `eqType` fun_mult -- There is no change in multiplicity, otherwise we must abort- = Just (mkFunResCo Representational (idScaledType bndr) co, [])+ = Just (mkFunResCo Representational bndr co, []) ok_arg bndr (Cast e co_arg) co fun_ty | (ticks, Var v) <- stripTicksTop tickishFloatable e- , Just (fun_mult, _, _) <- splitFunTy_maybe fun_ty+ , Just (_, fun_mult, _, _) <- splitFunTy_maybe fun_ty , bndr == v , fun_mult `eqType` idMult bndr- = Just (mkFunCo Representational (multToCo fun_mult) (mkSymCo co_arg) co, ticks)+ = Just (mkFunCoNoFTF Representational (multToCo fun_mult) (mkSymCo co_arg) co, ticks) -- The simplifier combines multiple casts into one, -- so we can have a simple-minded pattern match here ok_arg bndr (Tick t arg) co fun_ty@@ -2825,19 +2824,19 @@ = Nothing where Pair tyL tyR = coercionKind co- -- co :: tyL ~ tyR+ -- co :: tyL ~R tyR -- tyL = forall (a1 :: k1). ty1 -- tyR = forall (a2 :: k2). ty2 - co1 = mkSymCo (mkNthCo Nominal 0 co)+ co1 = mkSymCo (mkSelCo SelForAll co) -- co1 :: k2 ~N k1- -- Note that NthCo can extract a Nominal equality between the+ -- Note that SelCo extracts a Nominal equality between the -- kinds of the types related by a coercion between forall-types.- -- See the NthCo case in GHC.Core.Lint.+ -- See the SelCo case in GHC.Core.Lint. co2 = mkInstCo co (mkGReflLeftCo Nominal ty co1)- -- co2 :: ty1[ (ty|>co1)/a1 ] ~ ty2[ ty/a2 ]- -- Arg of mkInstCo is always nominal, hence mkNomReflCo+ -- co2 :: ty1[ (ty|>co1)/a1 ] ~R ty2[ ty/a2 ]+ -- Arg of mkInstCo is always nominal, hence Nominal -- | If @pushCoValArg co = Just (co_arg, co_res)@, then --@@ -2861,7 +2860,7 @@ = Just (MRefl, MRefl) | isFunTy tyL- , (co_mult, co1, co2) <- decomposeFunCo Representational co+ , (co_mult, co1, co2) <- decomposeFunCo co -- If co :: (tyL1 -> tyL2) ~ (tyR1 -> tyR2) -- then co1 :: tyL1 ~ tyR1 -- co2 :: tyL2 ~ tyR2@@ -2903,9 +2902,9 @@ pushCoercionIntoLambda in_scope x e co | assert (not (isTyVar x) && not (isCoVar x)) True , Pair s1s2 t1t2 <- coercionKind co- , Just (_, _s1,_s2) <- splitFunTy_maybe s1s2- , Just (w1, t1,_t2) <- splitFunTy_maybe t1t2- , (co_mult, co1, co2) <- decomposeFunCo Representational co+ , Just {} <- splitFunTy_maybe s1s2+ , Just (_, w1, t1,_t2) <- splitFunTy_maybe t1t2+ , (co_mult, co1, co2) <- decomposeFunCo co , isReflexiveCo co_mult -- We can't push the coercion in the case where co_mult isn't -- reflexivity. See pushCoValArg for more details.@@ -2993,11 +2992,11 @@ collectBindersPushingCo :: CoreExpr -> ([Var], CoreExpr) -- Collect lambda binders, pushing coercions inside if possible -- E.g. (\x.e) |> g g :: <Int> -> blah--- = (\x. e |> Nth 1 g)+-- = (\x. e |> SelCo (SelFun SelRes) g) -- -- That is, ----- collectBindersPushingCo ((\x.e) |> g) === ([x], e |> Nth 1 g)+-- collectBindersPushingCo ((\x.e) |> g) === ([x], e |> SelCo (SelFun SelRes) g) collectBindersPushingCo e = go [] e where@@ -3024,21 +3023,21 @@ , let Pair tyL tyR = coercionKind co , assert (isForAllTy_ty tyL) $ isForAllTy_ty tyR- , isReflCo (mkNthCo Nominal 0 co) -- See Note [collectBindersPushingCo]+ , isReflCo (mkSelCo SelForAll co) -- See Note [collectBindersPushingCo] = go_c (b:bs) e (mkInstCo co (mkNomReflCo (mkTyVarTy b))) | isCoVar b , let Pair tyL tyR = coercionKind co , assert (isForAllTy_co tyL) $ isForAllTy_co tyR- , isReflCo (mkNthCo Nominal 0 co) -- See Note [collectBindersPushingCo]+ , isReflCo (mkSelCo SelForAll co) -- See Note [collectBindersPushingCo] , let cov = mkCoVarCo b = go_c (b:bs) e (mkInstCo co (mkNomReflCo (mkCoercionTy cov))) | isId b , let Pair tyL tyR = coercionKind co , assert (isFunTy tyL) $ isFunTy tyR- , (co_mult, co_arg, co_res) <- decomposeFunCo Representational co+ , (co_mult, co_arg, co_res) <- decomposeFunCo co , isReflCo co_mult -- See Note [collectBindersPushingCo] , isReflCo co_arg -- See Note [collectBindersPushingCo] = go_c (b:bs) e co_res@@ -3104,7 +3103,7 @@ | Just (tv, res_ty) <- splitForAllTyCoVar_maybe ty , let (subst', tv') = substVarBndr subst tv = go (n-1) res_ty subst' (tv' : rev_bs) (e `App` varToCoreExpr tv')- | Just (mult, arg_ty, res_ty) <- splitFunTy_maybe ty+ | Just (_, mult, arg_ty, res_ty) <- splitFunTy_maybe ty , let (subst', b) = freshEtaId n subst (Scaled mult arg_ty) = go (n-1) res_ty subst' (b : rev_bs) (e `App` Var b) | otherwise
compiler/GHC/Core/Opt/ConstantFold.hs view
@@ -46,11 +46,12 @@ import GHC.Core.Make import GHC.Core.SimpleOpt ( exprIsConApp_maybe, exprIsLiteral_maybe ) import GHC.Core.DataCon ( DataCon,dataConTagZ, dataConTyCon, dataConWrapId, dataConWorkId )-import GHC.Core.Utils ( cheapEqExpr, exprIsHNF, exprType+import GHC.Core.Utils ( cheapEqExpr, exprIsHNF , stripTicksTop, stripTicksTopT, mkTicks ) import GHC.Core.Multiplicity import GHC.Core.Rules.Config import GHC.Core.Type+import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.TyCon ( tyConDataCons_maybe, isAlgTyCon, isEnumerationTyCon , isNewTyCon, tyConDataCons@@ -70,7 +71,6 @@ import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Panic.Plain-import GHC.Utils.Trace import Control.Applicative ( Alternative(..) ) import Control.Monad@@ -420,15 +420,14 @@ [Lit (LitNumber _ l1), Lit (LitNumber _ l2)] <- getArgs platform <- getPlatform let r = l1 * l2- pure $ mkCoreUbxTup [intPrimTy,intPrimTy,intPrimTy]+ pure $ mkCoreUnboxedTuple [ Lit (if platformInIntRange platform r then zeroi platform else onei platform) , mkIntLitWrap platform (r `shiftR` platformWordSizeInBits platform) , mkIntLitWrap platform r ] , zeroElem >>= \z ->- pure (mkCoreUbxTup [intPrimTy,intPrimTy,intPrimTy]- [z,z,z])+ pure (mkCoreUnboxedTuple [z,z,z]) -- timesInt2# 1# other -- ~~~>@@ -437,7 +436,7 @@ -- repeated to fill a word. , identityPlatform onei >>= \other -> do platform <- getPlatform- pure $ mkCoreUbxTup [intPrimTy,intPrimTy,intPrimTy]+ pure $ mkCoreUnboxedTuple [ Lit (zeroi platform) , mkCoreApps (Var (primOpId IntSubOp)) [ Lit (zeroi platform)@@ -1000,8 +999,7 @@ retLitNoC :: (Platform -> Literal) -> RuleM CoreExpr retLitNoC l = do platform <- getPlatform let lit = l platform- let ty = literalType lit- return $ mkCoreUbxTup [ty, ty] [Lit lit, Lit (zeroi platform)]+ return $ mkCoreUnboxedTuple [Lit lit, Lit (zeroi platform)] word8Op2 :: (Integral a, Integral b)@@ -1096,9 +1094,8 @@ -------------------------- floatDecodeOp :: RuleOpts -> Literal -> Maybe CoreExpr floatDecodeOp env (LitFloat ((decodeFloat . fromRational @Float) -> (m, e)))- = Just $ mkCoreUbxTup [intPrimTy, intPrimTy]- [ mkIntVal (roPlatform env) (toInteger m)- , mkIntVal (roPlatform env) (toInteger e) ]+ = Just $ mkCoreUnboxedTuple [ mkIntVal (roPlatform env) (toInteger m)+ , mkIntVal (roPlatform env) (toInteger e) ] floatDecodeOp _ _ = Nothing @@ -1113,16 +1110,14 @@ -------------------------- doubleDecodeOp :: RuleOpts -> Literal -> Maybe CoreExpr doubleDecodeOp env (LitDouble ((decodeFloat . fromRational @Double) -> (m, e)))- = Just $ mkCoreUbxTup [iNT64Ty, intPrimTy]- [ Lit (mkLitINT64 (toInteger m))- , mkIntVal platform (toInteger e) ]+ = Just $ mkCoreUnboxedTuple [ Lit (mkLitINT64 (toInteger m))+ , mkIntVal platform (toInteger e) ] where platform = roPlatform env- (iNT64Ty, mkLitINT64)- | platformWordSizeInBits platform < 64- = (int64PrimTy, mkLitInt64Wrap)- | otherwise- = (intPrimTy , mkLitIntWrap platform)+ mkLitINT64 | platformWordSizeInBits platform < 64+ = mkLitInt64Wrap+ | otherwise+ = mkLitIntWrap platform doubleDecodeOp _ _ = Nothing @@ -1227,9 +1222,8 @@ -- Integer is in the target Int range and the corresponding overflow flag -- (@0#@/@1#@) if it wasn't. intCResult :: Platform -> Integer -> Maybe CoreExpr-intCResult platform result = Just (mkPair [Lit lit, Lit c])+intCResult platform result = Just (mkCoreUnboxedTuple [Lit lit, Lit c]) where- mkPair = mkCoreUbxTup [intPrimTy, intPrimTy] (lit, b) = mkLitIntWrapC platform result c = if b then onei platform else zeroi platform @@ -1269,9 +1263,8 @@ -- Integer is in the target Word range and the corresponding carry flag -- (@0#@/@1#@) if it wasn't. wordCResult :: Platform -> Integer -> Maybe CoreExpr-wordCResult platform result = Just (mkPair [Lit lit, Lit c])+wordCResult platform result = Just (mkCoreUnboxedTuple [Lit lit, Lit c]) where- mkPair = mkCoreUbxTup [wordPrimTy, intPrimTy] (lit, b) = mkLitWordWrapC platform result c = if b then onei platform else zeroi platform @@ -1625,7 +1618,7 @@ [Lit l1, e2] <- getArgs guard $ l1 == id_lit platform let no_c = Lit (zeroi platform)- return (mkCoreUbxTup [exprType e2, intPrimTy] [e2, no_c])+ return (mkCoreUnboxedTuple [e2, no_c]) rightIdentityPlatform :: (Platform -> Literal) -> RuleM CoreExpr rightIdentityPlatform id_lit = do@@ -1642,7 +1635,7 @@ [e1, Lit l2] <- getArgs guard $ l2 == id_lit platform let no_c = Lit (zeroi platform)- return (mkCoreUbxTup [exprType e1, intPrimTy] [e1, no_c])+ return (mkCoreUnboxedTuple [e1, no_c]) identityPlatform :: (Platform -> Literal) -> RuleM CoreExpr identityPlatform lit =@@ -1957,9 +1950,9 @@ seqRule :: RuleM CoreExpr seqRule = do- [Type ty_a, Type _ty_s, a, s] <- getArgs+ [Type _ty_a, Type _ty_s, a, s] <- getArgs guard $ exprIsHNF a- return $ mkCoreUbxTup [exprType s, ty_a] [s, a]+ return $ mkCoreUnboxedTuple [s, a] -- spark# :: forall a s . a -> State# s -> (# State# s, a #) sparkRule :: RuleM CoreExpr@@ -2104,7 +2097,7 @@ x <- isNaturalLiteral a0 y <- isNaturalLiteral a1 -- return an unboxed sum: (# (# #) | Natural #)- let ret n v = pure $ mkCoreUbxSum 2 n [unboxedUnitTy,naturalTy] v+ let ret n v = pure $ mkCoreUnboxedSum 2 n [unboxedUnitTy,naturalTy] v platform <- getPlatform if x < y then ret 1 unboxedUnitExpr@@ -2137,12 +2130,12 @@ , divop_one "integerRem" integerRemName rem mkIntegerExpr , divop_one "integerDiv" integerDivName div mkIntegerExpr , divop_one "integerMod" integerModName mod mkIntegerExpr- , divop_both "integerDivMod" integerDivModName divMod mkIntegerExpr integerTy- , divop_both "integerQuotRem" integerQuotRemName quotRem mkIntegerExpr integerTy+ , divop_both "integerDivMod" integerDivModName divMod mkIntegerExpr+ , divop_both "integerQuotRem" integerQuotRemName quotRem mkIntegerExpr , divop_one "naturalQuot" naturalQuotName quot mkNaturalExpr , divop_one "naturalRem" naturalRemName rem mkNaturalExpr- , divop_both "naturalQuotRem" naturalQuotRemName quotRem mkNaturalExpr naturalTy+ , divop_both "naturalQuotRem" naturalQuotRemName quotRem mkNaturalExpr -- conversions from Rational for Float/Double literals , rational_to "rationalToFloat" rationalToFloatName mkFloatExpr@@ -2292,14 +2285,14 @@ platform <- getPlatform pure $ mk_lit platform (n `divop` d) - divop_both str name divop mk_lit ty = mkRule str name 2 $ do+ divop_both str name divop mk_lit = mkRule str name 2 $ do [a0,a1] <- getArgs n <- isBignumLiteral a0 d <- isBignumLiteral a1 guard (d /= 0) let (r,s) = n `divop` d platform <- getPlatform- pure $ mkCoreUbxTup [ty,ty] [mk_lit platform r, mk_lit platform s]+ pure $ mkCoreUnboxedTuple [mk_lit platform r, mk_lit platform s] integer_encode_float :: RealFloat a => String -> Name -> (a -> CoreExpr) -> CoreRule integer_encode_float str name mk_lit = mkRule str name 2 $ do
compiler/GHC/Core/Opt/Monad.hs view
@@ -6,8 +6,6 @@ {-# LANGUAGE DeriveFunctor #-} -{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}- module GHC.Core.Opt.Monad ( -- * Types used in core-to-core passes FloatOutSwitches(..),@@ -19,11 +17,11 @@ -- ** Reading from the monad getHscEnv, getModule,- getRuleBase, getExternalRuleBase,+ initRuleEnv, getExternalRuleBase, getDynFlags, getPackageFamInstEnv, getInteractiveContext,- getVisibleOrphanMods, getUniqMask,- getPrintUnqualified, getSrcSpanM,+ getUniqMask,+ getNamePprCtx, getSrcSpanM, -- ** Writing to the monad addSimplCount,@@ -45,7 +43,7 @@ import GHC.Driver.Session import GHC.Driver.Env -import GHC.Core+import GHC.Core.Rules ( RuleBase, RuleEnv, mkRuleEnv ) import GHC.Core.Opt.Stats ( SimplCount, zeroSimplCount, plusSimplCount ) import GHC.Types.Annotations@@ -114,12 +112,11 @@ data CoreReader = CoreReader { cr_hsc_env :: HscEnv,- cr_rule_base :: RuleBase,+ cr_rule_base :: RuleBase, -- Home package table rules cr_module :: Module,- cr_print_unqual :: PrintUnqualified,+ cr_name_ppr_ctx :: NamePprCtx, cr_loc :: SrcSpan, -- Use this for log/error messages so they -- are at least tagged with the right source file- cr_visible_orphan_mods :: !ModuleSet, cr_uniq_mask :: !Char -- Mask for creating unique values } @@ -181,20 +178,18 @@ -> RuleBase -> Char -- ^ Mask -> Module- -> ModuleSet- -> PrintUnqualified+ -> NamePprCtx -> SrcSpan -> CoreM a -> IO (a, SimplCount)-runCoreM hsc_env rule_base mask mod orph_imps print_unqual loc m+runCoreM hsc_env rule_base mask mod name_ppr_ctx loc m = liftM extract $ runIOEnv reader $ unCoreM m where reader = CoreReader { cr_hsc_env = hsc_env, cr_rule_base = rule_base, cr_module = mod,- cr_visible_orphan_mods = orph_imps,- cr_print_unqual = print_unqual,+ cr_name_ppr_ctx = name_ppr_ctx, cr_loc = loc, cr_uniq_mask = mask }@@ -245,17 +240,20 @@ getHscEnv :: CoreM HscEnv getHscEnv = read cr_hsc_env -getRuleBase :: CoreM RuleBase-getRuleBase = read cr_rule_base+getHomeRuleBase :: CoreM RuleBase+getHomeRuleBase = read cr_rule_base +initRuleEnv :: ModGuts -> CoreM RuleEnv+initRuleEnv guts+ = do { hpt_rules <- getHomeRuleBase+ ; eps_rules <- getExternalRuleBase+ ; return (mkRuleEnv guts eps_rules hpt_rules) }+ getExternalRuleBase :: CoreM RuleBase getExternalRuleBase = eps_rule_base <$> get_eps -getVisibleOrphanMods :: CoreM ModuleSet-getVisibleOrphanMods = read cr_visible_orphan_mods--getPrintUnqualified :: CoreM PrintUnqualified-getPrintUnqualified = read cr_print_unqual+getNamePprCtx :: CoreM NamePprCtx+getNamePprCtx = read cr_name_ppr_ctx getSrcSpanM :: CoreM SrcSpan getSrcSpanM = read cr_loc@@ -362,14 +360,14 @@ msg msg_class doc = do logger <- getLogger loc <- getSrcSpanM- unqual <- getPrintUnqualified+ name_ppr_ctx <- getNamePprCtx let sty = case msg_class of MCDiagnostic _ _ _ -> err_sty MCDump -> dump_sty _ -> user_sty- err_sty = mkErrStyle unqual- user_sty = mkUserStyle unqual AllTheWay- dump_sty = mkDumpStyle unqual+ err_sty = mkErrStyle name_ppr_ctx+ user_sty = mkUserStyle name_ppr_ctx AllTheWay+ dump_sty = mkDumpStyle name_ppr_ctx liftIO $ logMsg logger msg_class loc (withPprStyle sty doc) -- | Output a String message to the screen
compiler/GHC/Core/Opt/OccurAnal.hs view
@@ -54,7 +54,6 @@ import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Misc-import GHC.Utils.Trace import GHC.Builtin.Names( runRWKey ) import GHC.Unit.Module( Module )
compiler/GHC/Core/Opt/Simplify.hs view
@@ -10,7 +10,7 @@ import GHC.Driver.Flags import GHC.Core-import GHC.Core.Rules ( extendRuleBaseList, extendRuleEnv, addRuleInfo )+import GHC.Core.Rules import GHC.Core.Ppr ( pprCoreBindings, pprCoreExpr ) import GHC.Core.Opt.OccurAnal ( occurAnalysePgm, occurAnalyseExpr ) import GHC.Core.Stats ( coreBindsSize, coreBindsStats, exprSize )@@ -27,12 +27,10 @@ import GHC.Utils.Logger as Logger import GHC.Utils.Outputable import GHC.Utils.Constants (debugIsOn)-import GHC.Utils.Trace import GHC.Unit.Env ( UnitEnv, ueEPS ) import GHC.Unit.External import GHC.Unit.Module.ModGuts-import GHC.Unit.Module.Deps import GHC.Types.Id import GHC.Types.Id.Info@@ -41,7 +39,6 @@ import GHC.Types.Var.Env import GHC.Types.Tickish import GHC.Types.Unique.FM-import GHC.Types.Name.Ppr import Control.Monad import Data.Foldable ( for_ )@@ -82,7 +79,7 @@ simpl_env = mkSimplEnv (se_mode opts) fam_envs top_env_cfg = se_top_env_cfg opts read_eps_rules = eps_rule_base <$> eucEPS euc- read_ruleenv = extendRuleEnv emptyRuleEnv <$> read_eps_rules+ read_ruleenv = updExternalPackageRules emptyRuleEnv <$> read_eps_rules ; let sz = exprSize expr @@ -133,27 +130,26 @@ -- The values of this datatype are /only/ driven by the demands of that function. data SimplifyOpts = SimplifyOpts { so_dump_core_sizes :: !Bool- , so_iterations :: !Int- , so_mode :: !SimplMode+ , so_iterations :: !Int+ , so_mode :: !SimplMode , so_pass_result_cfg :: !(Maybe LintPassResultConfig)- , so_rule_base :: !RuleBase- , so_top_env_cfg :: !TopEnvConfig+ , so_hpt_rules :: !RuleBase+ , so_top_env_cfg :: !TopEnvConfig } simplifyPgm :: Logger -> UnitEnv+ -> NamePprCtx -- For dumping -> SimplifyOpts -> ModGuts -> IO (SimplCount, ModGuts) -- New bindings -simplifyPgm logger unit_env opts+simplifyPgm logger unit_env name_ppr_ctx opts guts@(ModGuts { mg_module = this_mod- , mg_rdr_env = rdr_env- , mg_deps = deps- , mg_binds = binds, mg_rules = rules+ , mg_binds = binds, mg_rules = local_rules , mg_fam_inst_env = fam_inst_env }) = do { (termination_msg, it_count, counts_out, guts')- <- do_iteration 1 [] binds rules+ <- do_iteration 1 [] binds local_rules ; when (logHasDumpFlag logger Opt_D_verbose_core2core && logHasDumpFlag logger Opt_D_dump_simpl_stats) $@@ -170,22 +166,25 @@ dump_core_sizes = so_dump_core_sizes opts mode = so_mode opts max_iterations = so_iterations opts- hpt_rule_base = so_rule_base opts top_env_cfg = so_top_env_cfg opts- print_unqual = mkPrintUnqualified unit_env rdr_env active_rule = activeRule mode active_unf = activeUnfolding mode -- Note the bang in !guts_no_binds. If you don't force `guts_no_binds` -- the old bindings are retained until the end of all simplifier iterations !guts_no_binds = guts { mg_binds = [], mg_rules = [] } + hpt_rule_env :: RuleEnv+ hpt_rule_env = mkRuleEnv guts emptyRuleBase (so_hpt_rules opts)+ -- emptyRuleBase: no EPS rules yet; we will update+ -- them on each iteration to pick up the most up to date set+ do_iteration :: Int -- Counts iterations -> [SimplCount] -- Counts from earlier iterations, reversed- -> CoreProgram -- Bindings in- -> [CoreRule] -- and orphan rules+ -> CoreProgram -- Bindings+ -> [CoreRule] -- Local rules for imported Ids -> IO (String, Int, SimplCount, ModGuts) - do_iteration iteration_no counts_so_far binds rules+ do_iteration iteration_no counts_so_far binds local_rules -- iteration_no is the number of the iteration we are -- about to begin, with '1' for the first | iteration_no > max_iterations -- Stop if we've run out of iterations@@ -201,7 +200,7 @@ -- number of iterations we actually completed return ( "Simplifier baled out", iteration_no - 1 , totalise counts_so_far- , guts_no_binds { mg_binds = binds, mg_rules = rules } )+ , guts_no_binds { mg_binds = binds, mg_rules = local_rules } ) -- Try and force thunks off the binds; significantly reduces -- space usage, especially with -O. JRS, 000620.@@ -210,8 +209,8 @@ = do { -- Occurrence analysis let { tagged_binds = {-# SCC "OccAnal" #-}- occurAnalysePgm this_mod active_unf active_rule rules- binds+ occurAnalysePgm this_mod active_unf active_rule+ local_rules binds } ; Logger.putDumpFileMaybe logger Opt_D_dump_occur_anal "Occurrence analysis" FormatCore@@ -222,24 +221,29 @@ -- poke on IdInfo thunks, which in turn brings in new rules -- behind the scenes. Otherwise there's a danger we'll simply -- miss the rules for Ids hidden inside imported inlinings- -- Hence just before attempting to match rules we read on the EPS- -- value and then combine it when the existing rule base.+ -- Hence just before attempting to match a rule we read the EPS+ -- value (via read_rule_env) and then combine it with the existing rule base. -- See `GHC.Core.Opt.Simplify.Monad.getSimplRules`.- eps <- ueEPS unit_env ;- let { -- Forcing this value to avoid unnessecary allocations.+ eps <- ueEPS unit_env ;+ let { -- base_rule_env contains+ -- (a) home package rules, fixed across all iterations+ -- (b) local rules (substituted) from `local_rules` arg to do_iteration+ -- Forcing base_rule_env to avoid unnecessary allocations. -- Not doing so results in +25.6% allocations of LargeRecord.- ; !rule_base = extendRuleBaseList hpt_rule_base rules- ; vis_orphs = this_mod : dep_orphs deps- ; base_ruleenv = mkRuleEnv rule_base vis_orphs+ ; !base_rule_env = updLocalRules hpt_rule_env local_rules++ ; read_eps_rules :: IO PackageRuleBase ; read_eps_rules = eps_rule_base <$> ueEPS unit_env- ; read_ruleenv = extendRuleEnv base_ruleenv <$> read_eps_rules + ; read_rule_env :: IO RuleEnv+ ; read_rule_env = updExternalPackageRules base_rule_env <$> read_eps_rules+ ; fam_envs = (eps_fam_inst_env eps, fam_inst_env) ; simpl_env = mkSimplEnv mode fam_envs } ; -- Simplify the program ((binds1, rules1), counts1) <-- initSmpl logger read_ruleenv top_env_cfg sz $+ initSmpl logger read_rule_env top_env_cfg sz $ do { (floats, env1) <- {-# SCC "SimplTopBinds" #-} simplTopBinds simpl_env tagged_binds @@ -247,7 +251,7 @@ -- for imported Ids. Eg RULE map my_f = blah -- If we have a substitution my_f :-> other_f, we'd better -- apply it to the rule to, or it'll never match- ; rules1 <- simplImpRules env1 rules+ ; rules1 <- simplImpRules env1 local_rules ; return (getTopFloatBinds floats, rules1) } ; @@ -269,7 +273,7 @@ let { binds2 = {-# SCC "ZapInd" #-} shortOutIndirections binds1 } ; -- Dump the result of this iteration- dump_end_iteration logger dump_core_sizes print_unqual iteration_no counts1 binds2 rules1 ;+ dump_end_iteration logger dump_core_sizes name_ppr_ctx iteration_no counts1 binds2 rules1 ; for_ (so_pass_result_cfg opts) $ \pass_result_cfg -> lintPassResult logger pass_result_cfg binds2 ;@@ -286,10 +290,10 @@ totalise = foldr (\c acc -> acc `plusSimplCount` c) (zeroSimplCount $ logHasDumpFlag logger Opt_D_dump_simpl_stats) -dump_end_iteration :: Logger -> Bool -> PrintUnqualified -> Int+dump_end_iteration :: Logger -> Bool -> NamePprCtx -> Int -> SimplCount -> CoreProgram -> [CoreRule] -> IO ()-dump_end_iteration logger dump_core_sizes print_unqual iteration_no counts binds rules- = dumpPassResult logger dump_core_sizes print_unqual mb_flag hdr pp_counts binds rules+dump_end_iteration logger dump_core_sizes name_ppr_ctx iteration_no counts binds rules+ = dumpPassResult logger dump_core_sizes name_ppr_ctx mb_flag hdr pp_counts binds rules where mb_flag | logHasDumpFlag logger Opt_D_dump_simpl_iterations = Just Opt_D_dump_simpl_iterations | otherwise = Nothing
compiler/GHC/Core/Opt/Simplify/Env.hs view
@@ -69,7 +69,6 @@ import GHC.Types.Id as Id import GHC.Core.Make ( mkWildValBinder, mkCoreLet ) import GHC.Builtin.Types-import GHC.Core.TyCo.Rep ( TyCoBinder(..) ) import qualified GHC.Core.Type as Type import GHC.Core.Type hiding ( substTy, substTyVar, substTyVarBndr, substCo , extendTvSubst, extendCvSubst )@@ -503,7 +502,7 @@ -- The top level "enclosing CC" is "SUBSUMED". init_in_scope :: InScopeSet-init_in_scope = mkInScopeSet (unitVarSet (mkWildValBinder Many unitTy))+init_in_scope = mkInScopeSet (unitVarSet (mkWildValBinder ManyTy unitTy)) -- See Note [WildCard binders] {-@@ -1188,7 +1187,7 @@ = pprPanic "adjustJoinPointType" (ppr orig_ar <+> ppr orig_ty) -- See Note [Bangs in the Simplifier]- scale_bndr (Anon af t) = Anon af $! (scaleScaled mult t)+ scale_bndr (Anon t af) = (Anon $! (scaleScaled mult t)) af scale_bndr b@(Named _) = b {- Note [Scaling join point arguments]
compiler/GHC/Core/Opt/Simplify/Iteration.hs view
@@ -8,7 +8,7 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MultiWayIf #-} -{-# OPTIONS_GHC -Wno-incomplete-record-updates -Wno-incomplete-uni-patterns #-}+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module GHC.Core.Opt.Simplify.Iteration ( simplTopBinds, simplExpr, simplImpRules ) where import GHC.Prelude@@ -20,6 +20,7 @@ import GHC.Core import GHC.Core.Opt.Simplify.Monad import GHC.Core.Type hiding ( substTy, substTyVar, extendTvSubst, extendCvSubst )+import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.Opt.Simplify.Env import GHC.Core.Opt.Simplify.Utils import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs, scrutBinderSwap_maybe )@@ -68,7 +69,6 @@ import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Constants (debugIsOn)-import GHC.Utils.Trace import GHC.Utils.Monad ( mapAccumLM, liftIO ) import GHC.Utils.Logger import GHC.Utils.Misc@@ -605,7 +605,7 @@ -- See Note [OPAQUE pragma] = do { uniq <- getUniqueM ; let work_name = mkSystemVarName uniq occ_fs- work_id = mkLocalIdWithInfo work_name Many work_ty work_info+ work_id = mkLocalIdWithInfo work_name ManyTy work_ty work_info is_strict = isStrictId bndr ; (rhs_floats, work_rhs) <- prepareBinding env top_lvl is_rec is_strict@@ -832,7 +832,7 @@ = do { (floats, expr1) <- prepareRhs env top_lvl occ_fs expr ; uniq <- getUniqueM ; let name = mkSystemVarName uniq occ_fs- var = mkLocalIdWithInfo name Many expr_ty id_info+ var = mkLocalIdWithInfo name ManyTy expr_ty id_info -- Now something very like completeBind, -- but without the postInlineUnconditionally part@@ -1498,9 +1498,10 @@ ApplyToTy { sc_arg_ty = ty, sc_cont = cont} -> rebuild env (App expr (Type ty)) cont - ApplyToVal { sc_arg = arg, sc_env = se, sc_dup = dup_flag, sc_cont = cont}+ ApplyToVal { sc_arg = arg, sc_env = se, sc_dup = dup_flag+ , sc_cont = cont, sc_hole_ty = fun_ty } -- See Note [Avoid redundant simplification]- -> do { (_, _, arg') <- simplArg env dup_flag se arg+ -> do { (_, _, arg') <- simplArg env dup_flag fun_ty se arg ; rebuild env (App expr arg') cont } completeBindX :: SimplEnv@@ -1546,7 +1547,7 @@ * (f |> co) @t1 @t2 ... @tn x1 .. xm Here we will use pushCoTyArg and pushCoValArg successively, which- build up NthCo stacks. Silly to do that if co is reflexive.+ build up SelCo stacks. Silly to do that if co is reflexive. However, we don't want to call isReflexiveCo too much, because it uses type equality which is expensive on big types (#14737 comment:7).@@ -1599,7 +1600,8 @@ -- co1 :: t1 ~ s1 -- co2 :: s2 ~ t2 addCoerce co cont@(ApplyToVal { sc_arg = arg, sc_env = arg_se- , sc_dup = dup, sc_cont = tail })+ , sc_dup = dup, sc_cont = tail+ , sc_hole_ty = fun_ty }) | Just (m_co1, m_co2) <- pushCoValArg co , fixed_rep m_co1 = {-#SCC "addCoerce-pushCoValArg" #-}@@ -1611,7 +1613,7 @@ -- See Note [Avoiding exponential behaviour] MCo co1 ->- do { (dup', arg_se', arg') <- simplArg env dup arg_se arg+ do { (dup', arg_se', arg') <- simplArg env dup fun_ty arg_se arg -- When we build the ApplyTo we can't mix the OutCoercion -- 'co' with the InExpr 'arg', so we simplify -- to make it all consistent. It's a bit messy.@@ -1637,14 +1639,16 @@ -- See Note [Representation polymorphism invariants] in GHC.Core -- test: typecheck/should_run/EtaExpandLevPoly -simplArg :: SimplEnv -> DupFlag -> StaticEnv -> CoreExpr+simplArg :: SimplEnv -> DupFlag+ -> OutType -- Type of the function applied to this arg+ -> StaticEnv -> CoreExpr -- Expression with its static envt -> SimplM (DupFlag, StaticEnv, OutExpr)-simplArg env dup_flag arg_env arg+simplArg env dup_flag fun_ty arg_env arg | isSimplified dup_flag = return (dup_flag, arg_env, arg) | otherwise = do { let arg_env' = arg_env `setInScopeFromE` env- ; arg' <- simplExpr arg_env' arg+ ; arg' <- simplExprC arg_env' arg (mkBoringStop (funArgTy fun_ty)) ; return (Simplified, zapSubstEnv arg_env', arg') } -- Return a StaticEnv that includes the in-scope set from 'env', -- because arg' may well mention those variables (#20639)@@ -2030,6 +2034,21 @@ We'll clone the inner \x, adding x->x' in the id_subst Then when we inline y, we must *not* replace x by x' in the inlined copy!!++Note [Fast path for data constructors]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+For applications of a data constructor worker, the full glory of+rebuildCall is a waste of effort;+* They never inline, obviously+* They have no rewrite rules+* They are not strict (see Note [Data-con worker strictness]+ in GHC.Core.DataCon)+So it's fine to zoom straight to `rebuild` which just rebuilds the+call in a very straightforward way.++Some programs have a /lot/ of data constructors in the source program+(compiler/perf/T9961 is an example), so this fast path can be very+valuable. -} simplVar :: SimplEnv -> InVar -> SimplM OutExpr@@ -2047,6 +2066,9 @@ simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont+ | isDataConWorkId var -- See Note [Fast path for data constructors]+ = rebuild env (Var var) cont+ | otherwise = case substId env var of ContEx tvs cvs ids e -> simplExprF env' e cont -- Don't trimJoinCont; haven't already simplified e,@@ -2164,7 +2186,7 @@ ; 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") Many realWorldStatePrimTy+ _ -> 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'@@ -2316,6 +2338,8 @@ If we inline `f` before simplifying `BIG` well use preInlineUnconditionally, and we'll simplify BIG once, at x's occurrence, rather than twice. +* GHC.Core.Opt.Simplify.Utils. mkRewriteCall: if there are no rules, and no+ unfolding, we can skip both TryRules and TryInlining, which saves work. Note [Avoid redundant simplification] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -3169,7 +3193,7 @@ -- Note [Improving seq] improveSeq fam_envs env scrut case_bndr case_bndr1 [Alt DEFAULT _ _] | Just (Reduction co ty2) <- topNormaliseType_maybe fam_envs (idType case_bndr1)- = do { case_bndr2 <- newId (fsLit "nt") Many ty2+ = do { case_bndr2 <- newId (fsLit "nt") ManyTy ty2 ; let rhs = DoneEx (Var case_bndr2 `Cast` mkSymCo co) Nothing env2 = extendIdSubst env case_bndr rhs ; return (env2, scrut `Cast` co, case_bndr2) }@@ -3276,6 +3300,7 @@ where ppr_with_length list = ppr list <+> parens (text "length =" <+> ppr (length list))+ strdisp :: StrictnessMark -> SDoc strdisp MarkedStrict = text "MarkedStrict" strdisp NotMarkedStrict = text "NotMarkedStrict" @@ -3646,7 +3671,7 @@ do { let (dmd:cont_dmds) = dmds -- Never fails ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1- ; (_, se', arg') <- simplArg env' dup se arg+ ; (_, se', arg') <- simplArg env' dup hole_ty se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ; let all_floats = floats1 `addLetFloats` let_floats2 ; return ( all_floats
compiler/GHC/Core/Opt/Simplify/Monad.hs view
@@ -27,8 +27,8 @@ import GHC.Types.Id ( Id, mkSysLocalOrCoVarM ) import GHC.Types.Id.Info ( IdDetails(..), vanillaIdInfo, setArityInfo ) import GHC.Core.Type ( Type, Mult )-import GHC.Core ( RuleEnv(..) ) import GHC.Core.Opt.Stats+import GHC.Core.Rules import GHC.Core.Utils ( mkLamTypes ) import GHC.Types.Unique.Supply import GHC.Driver.Flags@@ -40,7 +40,7 @@ import GHC.Utils.Panic (throwGhcExceptionIO, GhcException (..)) import GHC.Types.Basic ( IntWithInf, treatZeroAsInf, mkIntWithInf ) import Control.Monad ( ap )-import GHC.Core.Multiplicity ( pattern Many )+import GHC.Core.Multiplicity ( pattern ManyTy ) import GHC.Exts( oneShot ) {-@@ -221,7 +221,7 @@ id_info = vanillaIdInfo `setArityInfo` arity -- `setOccInfo` strongLoopBreaker - ; return (mkLocalVar details name Many join_id_ty id_info) }+ ; return (mkLocalVar details name ManyTy join_id_ty id_info) } {- ************************************************************************
compiler/GHC/Core/Opt/Simplify/Utils.hs view
@@ -53,7 +53,7 @@ import GHC.Core.TyCo.Ppr ( pprParendType ) import GHC.Core.FVs import GHC.Core.Utils-import GHC.Core.Rules( getRules )+import GHC.Core.Rules( RuleEnv, getRules ) import GHC.Core.Opt.Arity import GHC.Core.Unfold import GHC.Core.Unfold.Make@@ -80,7 +80,6 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Panic.Plain-import GHC.Utils.Trace import Control.Monad ( when ) import Data.List ( sortBy )@@ -426,12 +425,22 @@ decArgCount (TryRules n rules) = TryRules (n-1) rules decArgCount rew = rew -mkTryRules :: [CoreRule] -> RewriteCall+mkRewriteCall :: Id -> RuleEnv -> RewriteCall -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration-mkTryRules [] = TryInlining-mkTryRules rs = TryRules n_required rs+-- We try to skip any unnecessary stages:+-- No rules => skip TryRules+-- No unfolding => skip TryInlining+-- This skipping is "just" for efficiency. But rebuildCall is+-- quite a heavy hammer, so skipping stages is a good plan.+-- And it's extremely simple to do.+mkRewriteCall fun rule_env+ | not (null rules) = TryRules n_required rules+ | canUnfold unf = TryInlining+ | otherwise = TryNothing where- n_required = maximum (map ruleArity rs)+ n_required = maximum (map ruleArity rules)+ rules = getRules rule_env fun+ unf = idUnfolding fun {- ************************************************************************@@ -515,7 +524,7 @@ -- should be scaled if it commutes with E. This appears, in particular, in the -- case-of-case transformation. contHoleScaling :: SimplCont -> Mult-contHoleScaling (Stop _ _ _) = One+contHoleScaling (Stop _ _ _) = OneTy contHoleScaling (CastIt _ k) = contHoleScaling k contHoleScaling (StrictBind { sc_bndr = id, sc_cont = k }) = idMult id `mkMultMul` contHoleScaling k@@ -605,21 +614,23 @@ mkArgInfo env rule_base fun cont | n_val_args < idArity fun -- Note [Unsaturated functions] = ArgInfo { ai_fun = fun, ai_args = []- , ai_rewrite = fun_rules+ , ai_rewrite = fun_rewrite , ai_encl = False , ai_dmds = vanilla_dmds , ai_discs = vanilla_discounts } | otherwise = ArgInfo { ai_fun = fun , ai_args = []- , ai_rewrite = fun_rules- , ai_encl = notNull rules || contHasRules cont+ , ai_rewrite = fun_rewrite+ , ai_encl = fun_has_rules || contHasRules cont , ai_dmds = add_type_strictness (idType fun) arg_dmds , ai_discs = arg_discounts } where- rules = getRules rule_base fun- fun_rules = mkTryRules rules- n_val_args = countValArgs cont+ n_val_args = countValArgs cont+ fun_rewrite = mkRewriteCall fun rule_base+ fun_has_rules = case fun_rewrite of+ TryRules {} -> True+ _ -> False vanilla_discounts, arg_discounts :: [Int] vanilla_discounts = repeat 0@@ -670,7 +681,7 @@ | Just (_, fun_ty') <- splitForAllTyCoVar_maybe fun_ty = add_type_strictness fun_ty' dmds -- Look through foralls - | Just (_, arg_ty, fun_ty') <- splitFunTy_maybe fun_ty -- Add strict-type info+ | Just (_, _, arg_ty, fun_ty') <- splitFunTy_maybe fun_ty -- Add strict-type info , dmd : rest_dmds <- dmds , let dmd' | Just Unlifted <- typeLevity_maybe arg_ty@@ -729,8 +740,8 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We want to avoid inlining an expression where there can't possibly be any gain, such as in an argument position. Hence, if the continuation-is interesting (eg. a case scrutinee, application etc.) then we-inline, otherwise we don't.+is interesting (eg. a case scrutinee that isn't just a seq, application etc.)+then we inline, otherwise we don't. Previously some_benefit used to return True only if the variable was applied to some value arguments. This didn't work:@@ -770,6 +781,53 @@ reduce unnecessary code expansion, we just make the context look boring. This made a small compile-time perf improvement in perf/compiler/T6048, and it looks plausible to me.++Note [Seq is boring]+~~~~~~~~~~~~~~~~~~~~+Suppose+ f x = case v of+ True -> Just x+ False -> Just (x-1)++Now consider these cases:++1. case f x of b{-dead-} { DEFAULT -> blah[no b] }+ Inlining (f x) will allow us to avoid ever allocating (Just x),+ since the case binder `b` is dead. We will end up with a+ join point for blah, thus+ join j = blah in+ case v of { True -> j; False -> j }+ which will turn into (case v of DEFAULT -> blah+ All good++2. case f x of b { DEFAULT -> blah[b] }+ Inlining (f x) will still mean we allocate (Just x). We'd get:+ join j b = blah[b]+ case v of { True -> j (Just x); False -> j (Just (x-1)) }+ No new optimisations are revealed. Nothing is gained.+ (This is the situation in T22317.)++2a. case g x of b { (x{-dead-}, x{-dead-}) -> blah[b, no x, no y] }+ Instead of DEFAULT we have a single constructor alternative+ with all dead binders. This is just a variant of (2); no+ gain from inlining (f x)++3. case f x of b { Just y -> blah[y,b] }+ Inlining (f x) will mean we still allocate (Just x),+ but we also get to bind `y` without fetching it out of the Just, thus+ join j y b = blah[y,b]+ case v of { True -> j x (Just x)+ ; False -> let y = x-1 in j y (Just y) }+ Inlining (f x) has a small benefit, perhaps.+ (To T14955 it makes a surprisingly large difference of ~30% to inline here.)+++Conclusion: if the case expression+ * Has a non-dead case-binder+ * Has one alternative+ * All the binders in the alternative are dead+then the `case` is just a strict let-binding, and the scrutinee is+BoringCtxt (don't inline). Otherwise CaseCtxt. -} lazyArgContext :: ArgInfo -> CallCtxt@@ -800,11 +858,14 @@ interestingCallContext env cont = interesting cont where- interesting (Select {})- | seCaseCase env = CaseCtxt- | otherwise = BoringCtxt- -- See Note [No case of case is boring]+ interesting (Select {sc_alts=alts, sc_bndr=case_bndr})+ | not (seCaseCase env) = BoringCtxt -- See Note [No case of case is boring]+ | [Alt _ bs _] <- alts+ , all isDeadBinder bs+ , not (isDeadBinder case_bndr) = BoringCtxt -- See Note [Seq is boring]+ | otherwise = CaseCtxt + interesting (ApplyToVal {}) = ValAppCtxt -- Can happen if we have (f Int |> co) y -- If f has an INLINE prag we need to give it some@@ -2304,16 +2365,25 @@ 3## -> ... DEFAULT -> ... -There are some wrinkles+There are some wrinkles. -* Do not apply caseRules if there is just a single DEFAULT alternative+Wrinkle 1:+ Do not apply caseRules if there is just a single DEFAULT alternative,+ unless the case-binder is dead. Example: case e +# 3# of b { DEFAULT -> rhs } If we applied the transformation here we would (stupidly) get- case a of b' { DEFAULT -> let b = e +# 3# in rhs }+ case e of b' { DEFAULT -> let b = b' +# 3# in rhs } and now the process may repeat, because that let will really- be a case.+ be a case. But if the original case binder b is dead, we instead get+ case e of b' { DEFAULT -> rhs }+ and there is no such problem. -* The type of the scrutinee might change. E.g.+ See Note [Example of case-merging and caseRules] for a compelling+ example of why this dead-binder business can be really important.+++Wrinkle 2:+ The type of the scrutinee might change. E.g. case tagToEnum (x :: Int#) of (b::Bool) False -> e1 True -> e2@@ -2322,7 +2392,8 @@ DEFAULT -> e1 1# -> e2 -* The case binder may be used in the right hand sides, so we need+Wrinkle 3:+ The case binder may be used in the right hand sides, so we need to make a local binding for it, if it is alive. e.g. case e +# 10# of b DEFAULT -> blah...b...@@ -2336,8 +2407,87 @@ whereas in the DEFAULT case we must reconstruct the original value. But NB: we use b'; we do not duplicate 'e'. -* In dataToTag we might need to make up some fake binders;+Wrinkle 4:+ In dataToTag we might need to make up some fake binders; see Note [caseRules for dataToTag] in GHC.Core.Opt.ConstantFold++++Note [Example of case-merging and caseRules]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The case-transformation rules are quite powerful. Here's a+subtle example from #22375. We start with++ data T = A | B | ...+ deriving Eq++ f :: T -> String+ f x = if | x==A -> "one"+ | x==B -> "two"+ | ...++In Core after a bit of simplification we get:++ f x = case dataToTag# x of a# { _DEFAULT ->+ case a# of+ _DEFAULT -> case dataToTag# x of b# { _DEFAULT ->+ case b# of+ _DEFAULT -> ...+ 1# -> "two"+ }+ 0# -> "one"+ }++Now consider what mkCase does to these case expressions.+The case-merge transformation Note [Merge Nested Cases]+does this (affecting both pairs of cases):++ f x = case dataToTag# x of a# {+ _DEFAULT -> case dataToTag# x of b# {+ _DEFAULT -> ...+ 1# -> "two"+ }+ 0# -> "one"+ }++Now Note [caseRules for dataToTag] does its work, again+on both dataToTag# cases:++ f x = case x of x1 {+ _DEFAULT -> case dataToTag# x1 of a# { _DEFAULT ->+ case x of x2 {+ _DEFAULT -> case dataToTag# x2 of b# { _DEFAULT -> ... }+ B -> "two"+ }}+ A -> "one"+ }+++The new dataToTag# calls come from the "reconstruct scrutinee" part of+caseRules (note that a# and b# were not dead in the original program+before all this merging). However, since a# and b# /are/ in fact dead+in the resulting program, we are left with redundant dataToTag# calls.+But they are easily eliminated by doing caseRules again, in+the next Simplifier iteration, this time noticing that a# and b# are+dead. Hence the "dead-binder" sub-case of Wrinkle 1 of Note+[Scrutinee Constant Folding] above. Once we do this we get++ f x = case x of x1 {+ _DEFAULT -> case x1 of x2 { _DEFAULT ->+ case x1 of x2 {+ _DEFAULT -> case x2 of x3 { _DEFAULT -> ... }+ B -> "two"+ }}+ A -> "one"+ }++and now we can do case-merge again, getting the desired++ f x = case x of+ A -> "one"+ B -> "two"+ ...+ -} mkCase, mkCase1, mkCase2, mkCase3@@ -2439,12 +2589,12 @@ mkCase2 mode scrut bndr alts_ty alts | -- See Note [Scrutinee Constant Folding]- case alts of -- Not if there is just a DEFAULT alternative- [Alt DEFAULT _ _] -> False+ case alts of+ [Alt DEFAULT _ _] -> isDeadBinder bndr -- see wrinkle 1 _ -> True , sm_case_folding mode , Just (scrut', tx_con, mk_orig) <- caseRules (smPlatform mode) scrut- = do { bndr' <- newId (fsLit "lwild") Many (exprType scrut')+ = do { bndr' <- newId (fsLit "lwild") ManyTy (exprType scrut') ; alts' <- mapMaybeM (tx_alt tx_con mk_orig bndr') alts -- mapMaybeM: discard unreachable alternatives@@ -2462,13 +2612,9 @@ -- binder if the latter isn't dead. Hence we wrap rhs of alternatives with -- "let bndr = ... in": --- -- case v + 10 of y =====> case v of y- -- 20 -> e1 10 -> let y = 20 in e1- -- DEFAULT -> e2 DEFAULT -> let y = v + 10 in e2- --- -- Other transformations give: =====> case v of y'- -- 10 -> let y = 20 in e1- -- DEFAULT -> let y = y' + 10 in e2+ -- case v + 10 of y =====> case v of y'+ -- 20 -> e1 10 -> let y = 20 in e1+ -- DEFAULT -> e2 DEFAULT -> let y = y' + 10 in e2 -- -- This wrapping is done in tx_alt; we use mk_orig, returned by caseRules, -- to construct an expression equivalent to the original one, for use
compiler/GHC/Core/PatSyn.hs view
@@ -389,7 +389,7 @@ -> [FieldLabel] -- ^ Names of fields for -- a record pattern synonym -> PatSyn- -- NB: The univ and ex vars are both in TyBinder form and TyVar form for+ -- NB: The univ and ex vars are both in PiTyVarBinder form and TyVar form for -- convenience. All the TyBinders should be Named! mkPatSyn name declared_infix (univ_tvs, req_theta)@@ -508,6 +508,6 @@ , pprType sigma_ty ] where sigma_ty = mkInvisForAllTys ex_tvs $- mkInvisFunTysMany prov_theta $+ mkInvisFunTys prov_theta $ mkVisFunTysMany orig_args orig_res_ty insert_empty_ctxt = null req_theta && not (null prov_theta && null ex_tvs)
compiler/GHC/Core/Reduction.hs view
@@ -35,14 +35,16 @@ import GHC.Core.Type import GHC.Data.Pair ( Pair(Pair) )+import GHC.Data.List.Infinite ( Infinite (..) )+import qualified GHC.Data.List.Infinite as Inf -import GHC.Types.Var ( setTyVarKind )+import GHC.Types.Var ( VarBndr(..), setTyVarKind ) import GHC.Types.Var.Env ( mkInScopeSet ) import GHC.Types.Var.Set ( TyCoVarSet ) import GHC.Utils.Misc ( HasDebugCallStack, equalLength ) import GHC.Utils.Outputable-import GHC.Utils.Panic ( assertPpr, panic )+import GHC.Utils.Panic ( assertPpr ) {- %************************************************************************@@ -349,25 +351,25 @@ -- -- Combines 'mkFunCo' and 'mkFunTy'. mkFunRedn :: Role- -> AnonArgFlag+ -> FunTyFlag -> ReductionN -- ^ multiplicity reduction -> Reduction -- ^ argument reduction -> Reduction -- ^ result reduction -> Reduction-mkFunRedn r vis+mkFunRedn r af (Reduction w_co w_ty) (Reduction arg_co arg_ty) (Reduction res_co res_ty) = mkReduction- (mkFunCo r w_co arg_co res_co)- (mkFunTy vis w_ty arg_ty res_ty)+ (mkFunCo1 r af w_co arg_co res_co)+ (mkFunTy af w_ty arg_ty res_ty) {-# INLINE mkFunRedn #-} -- | Create a 'Reduction' associated to a Π type, -- from a kind 'Reduction' and a body 'Reduction'. -- -- Combines 'mkForAllCo' and 'mkForAllTy'.-mkForAllRedn :: ArgFlag+mkForAllRedn :: ForAllTyFlag -> TyVar -> ReductionN -- ^ kind reduction -> Reduction -- ^ body reduction@@ -375,7 +377,7 @@ mkForAllRedn vis tv1 (Reduction h ki') (Reduction co ty) = mkReduction (mkForAllCo tv1 h co)- (mkForAllTy tv2 vis ty)+ (mkForAllTy (Bndr tv2 vis) ty) where tv2 = setTyVarKind tv1 ki' {-# INLINE mkForAllRedn #-}@@ -784,11 +786,11 @@ -- This function is only called in two locations, so the amount of code duplication -- should be rather reasonable despite the size of the function. simplifyArgsWorker :: HasDebugCallStack- => [TyCoBinder] -> Kind+ => [PiTyBinder] -> Kind -- the binders & result kind (not a Π-type) of the function applied to the args -- list of binders can be shorter or longer than the list of args -> TyCoVarSet -- free vars of the args- -> [Role] -- list of roles, r+ -> Infinite Role-- list of roles, r -> [Reduction] -- rewritten type arguments, arg_i -- each comes with the coercion used to rewrite it, -- arg_co_i :: ty_i ~ arg_i@@ -810,10 +812,10 @@ orig_lc = emptyLiftingContext $ mkInScopeSet orig_fvs go :: LiftingContext -- mapping from tyvars to rewriting coercions- -> [TyCoBinder] -- Unsubsted binders of function's kind- -> Kind -- Unsubsted result kind of function (not a Pi-type)- -> [Role] -- Roles at which to rewrite these ...- -> [Reduction] -- rewritten arguments, with their rewriting coercions+ -> [PiTyBinder] -- Unsubsted binders of function's kind+ -> Kind -- Unsubsted result kind of function (not a Pi-type)+ -> Infinite Role -- Roles at which to rewrite these ...+ -> [Reduction] -- rewritten arguments, with their rewriting coercions -> ArgsReductions go !lc binders inner_ki _ [] -- The !lc makes the function strict in the lifting context@@ -826,10 +828,10 @@ kind_co | noFreeVarsOfType final_kind = MRefl | otherwise = MCo $ liftCoSubst Nominal lc final_kind - go lc (binder:binders) inner_ki (role:roles) (arg_redn:arg_redns)+ go lc (binder:binders) inner_ki (Inf role roles) (arg_redn:arg_redns) = -- We rewrite an argument ty with arg_redn = Reduction arg_co arg -- By Note [Rewriting] in GHC.Tc.Solver.Rewrite invariant (F2),- -- tcTypeKind(ty) = tcTypeKind(arg).+ -- typeKind(ty) = typeKind(arg). -- However, it is possible that arg will be used as an argument to a function -- whose kind is different, if earlier arguments have been rewritten. -- We thus need to compose the reduction with a kind coercion to ensure@@ -837,11 +839,11 @@ -- -- The bangs here have been observed to improve performance -- significantly in optimized builds; see #18502- let !kind_co = liftCoSubst Nominal lc (tyCoBinderType binder)+ let !kind_co = liftCoSubst Nominal lc (piTyBinderType binder) !(Reduction casted_co casted_xi) = mkCoherenceRightRedn role arg_redn kind_co -- now, extend the lifting context with the new binding- !new_lc | Just tv <- tyCoBinderVar_maybe binder+ !new_lc | Just tv <- namedPiTyBinder_maybe binder = extendLiftingContextAndInScope lc tv casted_co | otherwise = lc@@ -859,7 +861,7 @@ (arg_cos, res_co) = decomposePiCos co1 co1_kind unrewritten_tys casted_args = assertPpr (equalLength arg_redns arg_cos) (ppr arg_redns $$ ppr arg_cos)- $ zipWith3 mkCoherenceRightRedn roles arg_redns arg_cos+ $ zipWith3 mkCoherenceRightRedn (Inf.toList roles) arg_redns arg_cos -- In general decomposePiCos can return fewer cos than tys, -- but not here; because we're well typed, there will be enough -- binders. Note that decomposePiCos does substitutions, so even@@ -874,19 +876,3 @@ = go zapped_lc bndrs new_inner roles casted_args in ArgsReductions redns_out (res_co `mkTransMCoR` res_co_out)-- go _ _ _ _ _ = panic- "simplifyArgsWorker wandered into deeper water than usual"- -- This debug information is commented out because leaving it in- -- causes a ~2% increase in allocations in T9872d.- -- That's independent of the analogous case in rewrite_args_fast- -- in GHC.Tc.Solver.Rewrite:- -- each of these causes a 2% increase on its own, so commenting them- -- both out gives a 4% decrease in T9872d.- {--- (vcat [ppr orig_binders,- ppr orig_inner_ki,- ppr (take 10 orig_roles), -- often infinite!- ppr orig_tys])- -}
compiler/GHC/Core/RoughMap.hs view
@@ -13,6 +13,9 @@ , RoughMatchLookupTc(..) , typeToRoughMatchLookupTc , roughMatchTcToLookup+ , roughMatchTcs+ , roughMatchTcsLookup+ , instanceCantMatch -- * RoughMap , RoughMap@@ -37,11 +40,10 @@ import GHC.Utils.Outputable import GHC.Types.Name import GHC.Types.Name.Env+import GHC.Builtin.Types.Prim( cONSTRAINTTyConName, tYPETyConName ) import Control.Monad (join) import Data.Data (Data)-import GHC.Utils.Misc-import Data.Bifunctor import GHC.Utils.Panic {-@@ -108,6 +110,10 @@ This explains the third clause of the mightMatch specification in Note [Simple Matching Semantics]. As soon as the lookup key runs out, the remaining instances might match. +This only matters for the data-family case of a FamInstEnv (see Note [Over-saturated matches]+in GHC.Core.FamInstEnv; it's irrelevantfor ClsInstEnv and for type-family instances.+But we use RoughMaps for all cases, so we are conservative.+ Note [Matching a RoughMap] ~~~~~~~~~~~~~~~~~~~~~~~~~~ The /lookup key/ into a rough map (RoughMatchLookupTc) is slightly@@ -135,6 +141,7 @@ doesn't match with any of the KnownTC instances so we can discard them all. For example: Show a[sk] or Show (a[sk] b[sk]). One place constraints like this arise is when typechecking derived instances.+ 2. The head of the application is a known type family. For example: F a[sk]. The application of F is stuck, and because F is a type family it won't match any KnownTC instance so it's safe to discard@@ -222,20 +229,59 @@ -} +{- *********************************************************************+* *+ Rough matching+* *+********************************************************************* -}++{- Note [Rough matching in class and family instances]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider+ instance C (Maybe [Tree a]) Bool+and suppose we are looking up+ C Bool Bool++We can very quickly rule the instance out, because the first+argument is headed by Maybe, whereas in the constraint we are looking+up has first argument headed by Bool. These "headed by" TyCons are+called the "rough match TyCons" of the constraint or instance.+They are used for a quick filter, to check when an instance cannot+possibly match.++The main motivation is to avoid sucking in whole instance+declarations that are utterly useless. See GHC.Core.InstEnv+Note [ClsInst laziness and the rough-match fields].++INVARIANT: a rough-match TyCons `tc` is always a real, generative tycon,+like Maybe or Either, including a newtype or a data family, both of+which are generative. It replies True to `isGenerativeTyCon tc Nominal`.++But it is never+ - A type synonym+ E.g. Int and (S Bool) might match+ if (S Bool) is a synonym for Int++ - A type family (#19336)+ E.g. (Just a) and (F a) might match if (F a) reduces to (Just a)+ albeit perhaps only after 'a' is instantiated.+-}++ -- Key for insertion into a RoughMap data RoughMatchTc- = RM_KnownTc Name -- INVARIANT: Name refers to a TyCon tc that responds- -- true to `isGenerativeTyCon tc Nominal`. See- -- Note [Rough matching in class and family instances]- | RM_WildCard -- e.g. type variable at the head+ = RM_KnownTc Name -- INVARIANT: Name refers to a TyCon tc that responds+ -- true to `isGenerativeTyCon tc Nominal`. See+ -- Note [Rough matching in class and family instances]+ | RM_WildCard -- e.g. type variable at the head deriving( Data ) -- Key for lookup into a RoughMap -- See Note [Matching a RoughMap] data RoughMatchLookupTc = RML_KnownTc Name -- ^ The position only matches the specified KnownTc- | RML_NoKnownTc -- ^ The position definitely doesn't match any KnownTc- | RML_WildCard -- ^ The position can match anything+ | RML_NoKnownTc -- ^ The position definitely doesn't match any KnownTc+ | RML_WildCard -- ^ The position can match anything deriving ( Data ) instance Outputable RoughMatchLookupTc where@@ -243,31 +289,51 @@ ppr RML_NoKnownTc = text "RML_NoKnownTC" ppr RML_WildCard = text "_" -roughMatchTcToLookup :: RoughMatchTc -> RoughMatchLookupTc-roughMatchTcToLookup (RM_KnownTc n) = RML_KnownTc n-roughMatchTcToLookup RM_WildCard = RML_WildCard- instance Outputable RoughMatchTc where ppr (RM_KnownTc nm) = text "KnownTc" <+> ppr nm ppr RM_WildCard = text "OtherTc" +instanceCantMatch :: [RoughMatchTc] -> [RoughMatchTc] -> Bool+-- (instanceCantMatch tcs1 tcs2) returns True if tcs1 cannot+-- possibly be instantiated to actual, nor vice versa;+-- False is non-committal+instanceCantMatch (mt : ts) (ma : as) = itemCantMatch mt ma || instanceCantMatch ts as+instanceCantMatch _ _ = False -- Safe++itemCantMatch :: RoughMatchTc -> RoughMatchTc -> Bool+itemCantMatch (RM_KnownTc t) (RM_KnownTc a) = t /= a+itemCantMatch _ _ = False++roughMatchTcToLookup :: RoughMatchTc -> RoughMatchLookupTc+roughMatchTcToLookup (RM_KnownTc n) = RML_KnownTc n+roughMatchTcToLookup RM_WildCard = RML_WildCard+ isRoughWildcard :: RoughMatchTc -> Bool isRoughWildcard RM_WildCard = True isRoughWildcard (RM_KnownTc {}) = False +roughMatchTcs :: [Type] -> [RoughMatchTc]+roughMatchTcs tys = map typeToRoughMatchTc tys++roughMatchTcsLookup :: [Type] -> [RoughMatchLookupTc]+roughMatchTcsLookup tys = map typeToRoughMatchLookupTc tys+ typeToRoughMatchLookupTc :: Type -> RoughMatchLookupTc typeToRoughMatchLookupTc ty- | Just (ty', _) <- splitCastTy_maybe ty = typeToRoughMatchLookupTc ty'- | otherwise =- case splitAppTys ty of+ | Just (ty', _) <- splitCastTy_maybe ty+ = typeToRoughMatchLookupTc ty'+ | otherwise+ = case splitAppTys ty of -- Case 1: Head of application is a type variable, does not match any KnownTc. (TyVarTy {}, _) -> RML_NoKnownTc+ (TyConApp tc _, _) -- Case 2: Head of application is a known type constructor, hence KnownTc.- | not (isTypeFamilyTyCon tc) -> RML_KnownTc $! tyConName tc+ | not (isTypeFamilyTyCon tc) -> RML_KnownTc $! roughMatchTyConName tc -- Case 3: Head is a type family so it's stuck and therefore doesn't match -- any KnownTc | isTypeFamilyTyCon tc -> RML_NoKnownTc+ -- Fallthrough: Otherwise, anything might match this position _ -> RML_WildCard @@ -275,11 +341,23 @@ typeToRoughMatchTc ty | Just (ty', _) <- splitCastTy_maybe ty = typeToRoughMatchTc ty' | Just (tc,_) <- splitTyConApp_maybe ty- , not (isTypeFamilyTyCon tc) = assertPpr (isGenerativeTyCon tc Nominal) (ppr tc)- RM_KnownTc $! tyConName tc+ , not (isTypeFamilyTyCon tc) = RM_KnownTc $! roughMatchTyConName tc -- See Note [Rough matching in class and family instances] | otherwise = RM_WildCard +roughMatchTyConName :: TyCon -> Name+roughMatchTyConName tc+ | tc_name == cONSTRAINTTyConName+ = tYPETyConName -- TYPE and CONSTRAINT are not apart, so they must use+ -- the same rough-map key. We arbitrarily use TYPE.+ -- See Note [Type and Constraint are not apart]+ -- wrinkle (W1) in GHC.Builtin.Types.Prim+ | otherwise+ = assertPpr (isGenerativeTyCon tc Nominal) (ppr tc) tc_name+ where+ tc_name = tyConName tc++ -- | Trie of @[RoughMatchTc]@ -- -- *Examples*@@ -288,15 +366,21 @@ -- insert [OtherTc] 2 -- lookup [OtherTc] == [1,2] -- @-data RoughMap a = RM { rm_empty :: Bag a- , rm_known :: DNameEnv (RoughMap a)- -- See Note [InstEnv determinism] in GHC.Core.InstEnv- , rm_unknown :: RoughMap a }- | RMEmpty -- an optimised (finite) form of emptyRM- -- invariant: Empty RoughMaps are always represented with RMEmpty+data RoughMap a+ = RMEmpty -- An optimised (finite) form of emptyRM+ -- Invariant: Empty RoughMaps are always represented with RMEmpty - deriving (Functor)+ | RM { rm_empty :: Bag a+ -- Keyed by an empty [RoughMapTc] + , rm_known :: DNameEnv (RoughMap a)+ -- Keyed by (RM_KnownTc tc : rm_tcs)+ -- DNameEnv: see Note [InstEnv determinism] in GHC.Core.InstEnv++ , rm_wild :: RoughMap a }+ -- Keyed by (RM_WildCard : rm_tcs)+ deriving (Functor)+ instance Outputable a => Outputable (RoughMap a) where ppr (RM empty known unknown) = vcat [text "RM"@@ -323,28 +407,37 @@ -- See Note [Matches vs Unifiers] lookupRM' :: [RoughMatchLookupTc] -> RoughMap a -> (Bag a -- Potential matches , [a]) -- Potential unifiers-lookupRM' _ RMEmpty = (emptyBag, [])--- See Note [Simple Matching Semantics] about why we return everything when the lookup--- key runs out.-lookupRM' [] rm = let m = elemsRM rm- in (listToBag m, m)+lookupRM' _ RMEmpty -- The RoughMap is empty+ = (emptyBag, [])++lookupRM' [] rm -- See Note [Simple Matching Semantics] about why+ = (listToBag m, m) -- we return everything when the lookup key runs out+ where+ m = elemsRM rm+ lookupRM' (RML_KnownTc tc : tcs) rm =- let (common_m, common_u) = lookupRM' tcs (rm_unknown rm)+ let (common_m, common_u) = lookupRM' tcs (rm_wild rm) (m, u) = maybe (emptyBag, []) (lookupRM' tcs) (lookupDNameEnv (rm_known rm) tc)- in (rm_empty rm `unionBags` common_m `unionBags` m+ in ( rm_empty rm `unionBags` common_m `unionBags` m , bagToList (rm_empty rm) ++ common_u ++ u)--- A RML_NoKnownTC does **not** match any KnownTC but can unify-lookupRM' (RML_NoKnownTc : tcs) rm = - let (u_m, _u_u) = lookupRM' tcs (rm_unknown rm)- in (rm_empty rm `unionBags` u_m -- Definitely don't match+-- A RML_NoKnownTC does **not** match any KnownTC but can unify+lookupRM' (RML_NoKnownTc : tcs) rm =+ let (u_m, _u_u) = lookupRM' tcs (rm_wild rm)+ in ( rm_empty rm `unionBags` u_m -- Definitely don't match , snd $ lookupRM' (RML_WildCard : tcs) rm) -- But could unify.. lookupRM' (RML_WildCard : tcs) rm =- let (m, u) = bimap unionManyBags concat (mapAndUnzip (lookupRM' tcs) (eltsDNameEnv $ rm_known rm))- (u_m, u_u) = lookupRM' tcs (rm_unknown rm)- in (rm_empty rm `unionBags` u_m `unionBags` m- , bagToList (rm_empty rm) ++ u_u ++ u)+-- pprTrace "RM wild" (ppr tcs $$ ppr (eltsDNameEnv (rm_known rm))) $+ let (m, u) = foldDNameEnv add_one (emptyBag, []) (rm_known rm)+ (u_m, u_u) = lookupRM' tcs (rm_wild rm)+ in ( rm_empty rm `unionBags` u_m `unionBags` m+ , bagToList (rm_empty rm) ++ u_u ++ u )+ where+ add_one :: RoughMap a -> (Bag a, [a]) -> (Bag a, [a])+ add_one rm ~(m2, u2) = (m1 `unionBags` m2, u1 ++ u2)+ where+ (m1,u1) = lookupRM' tcs rm unionRM :: RoughMap a -> RoughMap a -> RoughMap a unionRM RMEmpty a = a@@ -352,7 +445,7 @@ unionRM a b = RM { rm_empty = rm_empty a `unionBags` rm_empty b , rm_known = plusDNameEnv_C unionRM (rm_known a) (rm_known b)- , rm_unknown = rm_unknown a `unionRM` rm_unknown b+ , rm_wild = rm_wild a `unionRM` rm_wild b } @@ -360,17 +453,19 @@ insertRM k v RMEmpty = insertRM k v $ RM { rm_empty = emptyBag , rm_known = emptyDNameEnv- , rm_unknown = emptyRM }+ , rm_wild = emptyRM } insertRM [] v rm@(RM {}) = -- See Note [Simple Matching Semantics] rm { rm_empty = v `consBag` rm_empty rm }+ insertRM (RM_KnownTc k : ks) v rm@(RM {}) = rm { rm_known = alterDNameEnv f (rm_known rm) k } where f Nothing = Just $ (insertRM ks v emptyRM) f (Just m) = Just $ (insertRM ks v m)+ insertRM (RM_WildCard : ks) v rm@(RM {}) =- rm { rm_unknown = insertRM ks v (rm_unknown rm) }+ rm { rm_wild = insertRM ks v (rm_wild rm) } filterRM :: (a -> Bool) -> RoughMap a -> RoughMap a filterRM _ RMEmpty = RMEmpty@@ -378,7 +473,7 @@ normalise $ RM { rm_empty = filterBag pred (rm_empty rm), rm_known = mapDNameEnv (filterRM pred) (rm_known rm),- rm_unknown = filterRM pred (rm_unknown rm)+ rm_wild = filterRM pred (rm_wild rm) } -- | Place a 'RoughMap' in normal form, turning all empty 'RM's into@@ -399,13 +494,13 @@ normalise $ RM { rm_empty = filterBag pred (rm_empty rm), rm_known = alterDNameEnv (join . fmap (dropEmpty . filterMatchingRM pred tcs)) (rm_known rm) tc,- rm_unknown = filterMatchingRM pred tcs (rm_unknown rm)+ rm_wild = filterMatchingRM pred tcs (rm_wild rm) } filterMatchingRM pred (RM_WildCard : tcs) rm = normalise $ RM { rm_empty = filterBag pred (rm_empty rm), rm_known = mapDNameEnv (filterMatchingRM pred tcs) (rm_known rm),- rm_unknown = filterMatchingRM pred tcs (rm_unknown rm)+ rm_wild = filterMatchingRM pred tcs (rm_wild rm) } dropEmpty :: RoughMap a -> Maybe (RoughMap a)@@ -421,7 +516,7 @@ -- N.B. local worker ensures that the loop can be specialised to the fold -- function. go z RMEmpty = z- go z (RM{ rm_unknown = unk, rm_known = known, rm_empty = empty}) =+ go z (RM{ rm_wild = unk, rm_known = known, rm_empty = empty}) = foldr f (foldDNameEnv@@ -442,7 +537,7 @@ f (nonDetStrictFoldDNameEnv (flip go)- (go z (rm_unknown rm))+ (go z (rm_wild rm)) (rm_known rm) ) (rm_empty rm)
compiler/GHC/Core/Rules.hs view
@@ -12,8 +12,10 @@ lookupRule, -- ** RuleBase, RuleEnv+ RuleBase, RuleEnv(..), mkRuleEnv, emptyRuleEnv,+ updExternalPackageRules, addLocalRules, updLocalRules, emptyRuleBase, mkRuleBase, extendRuleBaseList,- pprRuleBase, extendRuleEnv,+ pprRuleBase, -- ** Checking rule applications ruleCheckProgram,@@ -22,6 +24,8 @@ extendRuleInfo, addRuleInfo, addIdSpecialisations, + -- ** RuleBase and RuleEnv+ -- * Misc. CoreRule helpers rulesOfBinds, getRules, pprRulesForUser, @@ -34,6 +38,8 @@ import GHC.Unit.Module ( Module ) import GHC.Unit.Module.Env+import GHC.Unit.Module.ModGuts( ModGuts(..) )+import GHC.Unit.Module.Deps( Dependencies(..) ) import GHC.Driver.Session( DynFlags ) import GHC.Driver.Ppr( showSDoc )@@ -78,7 +84,6 @@ import GHC.Data.Bag import GHC.Utils.Misc as Utils-import GHC.Utils.Trace import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Constants (debugIsOn)@@ -136,7 +141,7 @@ * At the moment (c) is carried in a reader-monad way by the GHC.Core.Opt.Monad. The HomePackageTable doesn't have a single RuleBase because technically we should only be able to "see" rules "below" this module; so we- generate a RuleBase for (c) by combing rules from all the modules+ generate a RuleBase for (c) by combining rules from all the modules "below" us. That's why we can't just select the home-package RuleBase from HscEnv. @@ -340,12 +345,106 @@ rulesOfBinds :: [CoreBind] -> [CoreRule] rulesOfBinds binds = concatMap (concatMap idCoreRules . bindersOf) binds ++{-+************************************************************************+* *+ RuleBase+* *+************************************************************************+-}++-- | Gathers a collection of 'CoreRule's. Maps (the name of) an 'Id' to its rules+type RuleBase = NameEnv [CoreRule]+ -- The rules are unordered;+ -- we sort out any overlaps on lookup++emptyRuleBase :: RuleBase+emptyRuleBase = emptyNameEnv++mkRuleBase :: [CoreRule] -> RuleBase+mkRuleBase rules = extendRuleBaseList emptyRuleBase rules++extendRuleBaseList :: RuleBase -> [CoreRule] -> RuleBase+extendRuleBaseList rule_base new_guys+ = foldl' extendRuleBase rule_base new_guys++extendRuleBase :: RuleBase -> CoreRule -> RuleBase+extendRuleBase rule_base rule+ = extendNameEnv_Acc (:) Utils.singleton rule_base (ruleIdName rule) rule++pprRuleBase :: RuleBase -> SDoc+pprRuleBase rules = pprUFM rules $ \rss ->+ vcat [ pprRules (tidyRules emptyTidyEnv rs)+ | rs <- rss ]++-- | A full rule environment which we can apply rules from. Like a 'RuleBase',+-- but it also includes the set of visible orphans we use to filter out orphan+-- rules which are not visible (even though we can see them...)+-- See Note [Orphans] in GHC.Core+data RuleEnv+ = RuleEnv { re_local_rules :: !RuleBase -- Rules from this module+ , re_home_rules :: !RuleBase -- Rule from the home package+ -- (excl this module)+ , re_eps_rules :: !RuleBase -- Rules from other packages+ -- see Note [External package rules]+ , re_visible_orphs :: !ModuleSet+ }++mkRuleEnv :: ModGuts -> RuleBase -> RuleBase -> RuleEnv+mkRuleEnv (ModGuts { mg_module = this_mod+ , mg_deps = deps+ , mg_rules = local_rules })+ eps_rules hpt_rules+ = RuleEnv { re_local_rules = mkRuleBase local_rules+ , re_home_rules = hpt_rules+ , re_eps_rules = eps_rules+ , re_visible_orphs = mkModuleSet vis_orphs }+ where+ vis_orphs = this_mod : dep_orphs deps++updExternalPackageRules :: RuleEnv -> RuleBase -> RuleEnv+-- Completely over-ride the external rules in RuleEnv+updExternalPackageRules rule_env eps_rules+ = rule_env { re_eps_rules = eps_rules }++updLocalRules :: RuleEnv -> [CoreRule] -> RuleEnv+-- Completely over-ride the local rules in RuleEnv+updLocalRules rule_env local_rules+ = rule_env { re_local_rules = mkRuleBase local_rules }++addLocalRules :: RuleEnv -> [CoreRule] -> RuleEnv+-- Add new local rules+addLocalRules rule_env rules+ = rule_env { re_local_rules = extendRuleBaseList (re_local_rules rule_env) rules }++emptyRuleEnv :: RuleEnv+emptyRuleEnv = RuleEnv { re_local_rules = emptyNameEnv+ , re_home_rules = emptyNameEnv+ , re_eps_rules = emptyNameEnv+ , re_visible_orphs = emptyModuleSet }+ getRules :: RuleEnv -> Id -> [CoreRule]+-- Given a RuleEnv and an Id, find the visible rules for that Id -- See Note [Where rules are found]-getRules (RuleEnv { re_base = rule_base, re_visible_orphs = orphs }) fn- = idCoreRules fn ++ concatMap imp_rules rule_base+getRules (RuleEnv { re_local_rules = local_rules+ , re_home_rules = home_rules+ , re_eps_rules = eps_rules+ , re_visible_orphs = orphs }) fn++ | Just {} <- isDataConId_maybe fn -- Short cut for data constructor workers+ = [] -- and wrappers, which never have any rules++ | otherwise+ = idCoreRules fn +++ get local_rules +++ find_visible home_rules +++ find_visible eps_rules+ where- imp_rules rb = filter (ruleIsVisible orphs) (lookupNameEnv rb (idName fn) `orElse` [])+ fn_name = idName fn+ find_visible rb = filter (ruleIsVisible orphs) (get rb)+ get rb = lookupNameEnv rb fn_name `orElse` [] ruleIsVisible :: ModuleSet -> CoreRule -> Bool ruleIsVisible _ BuiltinRule{} = True@@ -371,37 +470,28 @@ in the module defining the Id (when it's a LocalId), but the rules are kept in the global RuleBase --************************************************************************-* *- RuleBase-* *-************************************************************************--}---- RuleBase itself is defined in GHC.Core, along with CoreRule--emptyRuleBase :: RuleBase-emptyRuleBase = emptyNameEnv+ Note [External package rules]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In Note [Overall plumbing for rules], it is explained that the final+RuleBase which we must consider is combined from 4 different sources. -mkRuleBase :: [CoreRule] -> RuleBase-mkRuleBase rules = extendRuleBaseList emptyRuleBase rules+During simplifier runs, the fourth source of rules is constantly being updated+as new interfaces are loaded into the EPS. Therefore just before we check to see+if any rules match we get the EPS RuleBase and combine it with the existing RuleBase+and then perform exactly 1 lookup into the new map. -extendRuleBaseList :: RuleBase -> [CoreRule] -> RuleBase-extendRuleBaseList rule_base new_guys- = foldl' extendRuleBase rule_base new_guys+It is more efficient to avoid combining the environments and store the uncombined+environments as we can instead perform 1 lookup into each environment and then combine+the results. -extendRuleBase :: RuleBase -> CoreRule -> RuleBase-extendRuleBase rule_base rule- = extendNameEnv_Acc (:) Utils.singleton rule_base (ruleIdName rule) rule+Essentially we use the identity: -extendRuleEnv :: RuleEnv -> RuleBase -> RuleEnv-extendRuleEnv (RuleEnv rules orphs) rb = (RuleEnv (rb:rules) orphs)+> lookupNameEnv n (plusNameEnv_C (++) rb1 rb2)+> = lookupNameEnv n rb1 ++ lookupNameEnv n rb2 -pprRuleBase :: RuleBase -> SDoc-pprRuleBase rules = pprUFM rules $ \rss ->- vcat [ pprRules (tidyRules emptyTidyEnv rs)- | rs <- rss ]+The latter being more efficient as we don't construct an intermediate+map.+-} {- ************************************************************************@@ -1576,7 +1666,7 @@ | otherwise = unitBag (ruleAppCheck_help env fn args name_match_rules) where name_match_rules = filter match (rc_rules env fn)- match rule = (rc_pattern env) `isPrefixOf` unpackFS (ruleName rule)+ match rule = rc_pattern env `isPrefixOf` unpackFS (ruleName rule) ruleAppCheck_help :: RuleCheckEnv -> Id -> [CoreExpr] -> [CoreRule] -> SDoc ruleAppCheck_help env fn args rules
compiler/GHC/Core/SimpleOpt.hs view
@@ -1225,7 +1225,7 @@ -- Good: returning (Mk#, [x]) with a float of case exp of x { DEFAULT -> [] } -- simplifier produces case exp of a { DEFAULT -> exp[x/a] } = let arg' = subst_expr subst arg- bndr = uniqAway (subst_in_scope subst) (mkWildValBinder Many arg_type)+ bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type) float = FloatCase arg' bndr DEFAULT [] subst' = subst_extend_in_scope subst bndr in go subst' (float:floats) fun (CC (Var bndr : args) co)
compiler/GHC/Core/Subst.hs view
@@ -6,8 +6,6 @@ Utility functions on @Core@ syntax -} --{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module GHC.Core.Subst ( -- * Main data types Subst(..), -- Implementation exported for supercompiler's Renaming.hs only@@ -65,6 +63,7 @@ import GHC.Utils.Panic import GHC.Utils.Panic.Plain +import Data.Functor.Identity (Identity (..)) import Data.List (mapAccumL) {-@@ -343,15 +342,18 @@ | otherwise = substIdBndr (text "var-bndr") subst subst bndr -- | Applies 'substBndr' to a number of 'Var's, accumulating a new 'Subst' left-to-right-substBndrs :: Subst -> [Var] -> (Subst, [Var])-substBndrs subst bndrs = mapAccumL substBndr subst bndrs+substBndrs :: Traversable f => Subst -> f Var -> (Subst, f Var)+substBndrs = mapAccumL substBndr+{-# INLINE substBndrs #-} -- | Substitute in a mutually recursive group of 'Id's-substRecBndrs :: Subst -> [Id] -> (Subst, [Id])+substRecBndrs :: Traversable f => Subst -> f Id -> (Subst, f Id) substRecBndrs subst bndrs = (new_subst, new_bndrs) where -- Here's the reason we need to pass rec_subst to subst_id (new_subst, new_bndrs) = mapAccumL (substIdBndr (text "rec-bndr") new_subst) subst bndrs+{-# SPECIALIZE substRecBndrs :: Subst -> [Id] -> (Subst, [Id]) #-}+{-# SPECIALIZE substRecBndrs :: Subst -> Identity Id -> (Subst, Identity Id) #-} substIdBndr :: SDoc -> Subst -- ^ Substitution to use for the IdInfo@@ -577,7 +579,7 @@ = tyCoFVsOfCo fv_co (const True) emptyVarSet $! acc | otherwise , let fv_expr = lookupIdSubst subst fv- = expr_fvs fv_expr isLocalVar emptyVarSet $! acc+ = exprFVs fv_expr (const True) emptyVarSet $! acc ------------------ substTickish :: Subst -> CoreTickish -> CoreTickish
compiler/GHC/Core/Tidy.hs view
@@ -8,7 +8,6 @@ -} -{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module GHC.Core.Tidy ( tidyExpr, tidyRules, tidyCbvInfoTop, tidyBndrs ) where@@ -34,7 +33,6 @@ import GHC.Data.Maybe import GHC.Utils.Misc import Data.List (mapAccumL)--- import GHC.Utils.Trace import GHC.Utils.Outputable import GHC.Types.RepType (typePrimRep) import GHC.Utils.Panic
+ compiler/GHC/Core/TyCo/Compare.hs view
@@ -0,0 +1,584 @@+-- (c) The University of Glasgow 2006+-- (c) The GRASP/AQUA Project, Glasgow University, 1998++{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MagicHash #-}++-- | Type equality and comparison+module GHC.Core.TyCo.Compare (++ -- * Type comparison+ eqType, eqTypeX, eqTypes, nonDetCmpType, nonDetCmpTypes, nonDetCmpTypeX,+ nonDetCmpTypesX, nonDetCmpTc,+ eqVarBndrs,++ pickyEqType, tcEqType, tcEqKind, tcEqTypeNoKindCheck, tcEqTypeVis,+ tcEqTyConApps,++ -- * Visiblity comparision+ eqForAllVis, cmpForAllVis++ ) where++import GHC.Prelude++import GHC.Core.Type( typeKind, coreView, tcSplitAppTyNoView_maybe, splitAppTyNoView_maybe )++import GHC.Core.TyCo.Rep+import GHC.Core.TyCo.FVs+import GHC.Core.TyCon++import GHC.Types.Var+import GHC.Types.Unique+import GHC.Types.Var.Env++import GHC.Utils.Outputable+import GHC.Utils.Misc+import GHC.Utils.Panic++import GHC.Base (reallyUnsafePtrEquality#)++import qualified Data.Semigroup as S++{- GHC.Core.TyCo.Compare overview+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+This module implements type equality and comparison++It uses a few functions from GHC.Core.Type, notably `typeKind`,+so it currently sits "on top of" GHC.Core.Type.+-}++{- *********************************************************************+* *+ Type equality+* *+********************************************************************* -}++{- Note [Computing equality on types]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+This module implements type equality, notably `eqType`. This is+"definitional equality" or just "equality" for short.++There are several places within GHC that depend on the precise choice of+definitional equality used. If we change that definition, all these places+must be updated. This Note merely serves as a place for all these places+to refer to, so searching for references to this Note will find every place+that needs to be updated.++* See Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep.++* See Historical Note [Typechecker equality vs definitional equality]+ below++Note [Type comparisons using object pointer comparisons]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Quite often we substitute the type from a definition site into+occurances without a change. This means for code like:+ \x -> (x,x,x)+The type of every `x` will often be represented by a single object+in the heap. We can take advantage of this by shortcutting the equality+check if two types are represented by the same pointer under the hood.+In some cases this reduces compiler allocations by ~2%.+-}+++tcEqKind :: HasDebugCallStack => Kind -> Kind -> Bool+tcEqKind = tcEqType++tcEqType :: HasDebugCallStack => Type -> Type -> Bool+-- ^ tcEqType implements typechecker equality+-- It behaves just like eqType, but is implemented+-- differently (for now)+tcEqType ty1 ty2+ = tcEqTypeNoSyns ki1 ki2+ && tcEqTypeNoSyns ty1 ty2+ where+ ki1 = typeKind ty1+ ki2 = typeKind ty2++-- | Just like 'tcEqType', but will return True for types of different kinds+-- as long as their non-coercion structure is identical.+tcEqTypeNoKindCheck :: Type -> Type -> Bool+tcEqTypeNoKindCheck ty1 ty2+ = tcEqTypeNoSyns ty1 ty2++-- | Check whether two TyConApps are the same; if the number of arguments+-- are different, just checks the common prefix of arguments.+tcEqTyConApps :: TyCon -> [Type] -> TyCon -> [Type] -> Bool+tcEqTyConApps tc1 args1 tc2 args2+ = tc1 == tc2 &&+ and (zipWith tcEqTypeNoKindCheck args1 args2)+ -- No kind check necessary: if both arguments are well typed, then+ -- any difference in the kinds of later arguments would show up+ -- as differences in earlier (dependent) arguments++{-+Note [Specialising tc_eq_type]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The type equality predicates in Type are hit pretty hard during typechecking.+Consequently we take pains to ensure that these paths are compiled to+efficient, minimally-allocating code.++To this end we place an INLINE on tc_eq_type, ensuring that it is inlined into+its publicly-visible interfaces (e.g. tcEqType). In addition to eliminating+some dynamic branches, this allows the simplifier to eliminate the closure+allocations that would otherwise be necessary to capture the two boolean "mode"+flags. This reduces allocations by a good fraction of a percent when compiling+Cabal.++See #19226.+-}++-- | 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++-- | 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++-- | 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+ = go orig_env orig_ty1 orig_ty2+ where+ go :: RnEnv2 -> Type -> Type -> Bool+ -- See Note [Comparing nullary type synonyms] in GHC.Core.Type.+ 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 (ForAllTy (Bndr tv1 vis1) ty1)+ (ForAllTy (Bndr tv2 vis2) ty2)+ = vis1 `eqForAllVis` vis2+ && (vis_only || 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+ -- AppTy case means that tcSplitAppTyNoView_maybe may see an unzonked+ -- kind variable, which causes things to blow up.+ -- 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)++ -- 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 (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++ go _ _ _ = False++ gos _ _ [] [] = True+ gos env (ig:igs) (t1:ts1) (t2:ts2) = (ig || go env t1 t2)+ && gos env igs 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].+++-- | Do these denote the same level of visibility? 'Required'+-- arguments are visible, others are not. So this function+-- equates 'Specified' and 'Inferred'. Used for printing.+eqForAllVis :: ForAllTyFlag -> ForAllTyFlag -> Bool+-- See Note [ForAllTy and type equality]+-- If you change this, see IMPORTANT NOTE in the above Note+eqForAllVis Required Required = True+eqForAllVis (Invisible _) (Invisible _) = True+eqForAllVis _ _ = False++-- | Do these denote the same level of visibility? 'Required'+-- arguments are visible, others are not. So this function+-- equates 'Specified' and 'Inferred'. Used for printing.+cmpForAllVis :: ForAllTyFlag -> ForAllTyFlag -> Ordering+-- See Note [ForAllTy and type equality]+-- If you change this, see IMPORTANT NOTE in the above Note+cmpForAllVis Required Required = EQ+cmpForAllVis Required (Invisible {}) = LT+cmpForAllVis (Invisible _) Required = GT+cmpForAllVis (Invisible _) (Invisible _) = EQ+++{- Note [ForAllTy and type equality]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When we compare (ForAllTy (Bndr tv1 vis1) ty1)+ and (ForAllTy (Bndr tv2 vis2) ty2)+what should we do about `vis1` vs `vis2`.++First, we always compare with `eqForAllVis` and `cmpForAllVis`.+But what decision do we make?++Should GHC type-check the following program (adapted from #15740)?++ {-# LANGUAGE PolyKinds, ... #-}+ data D a+ type family F :: forall k. k -> Type+ type instance F = D++Due to the way F is declared, any instance of F must have a right-hand side+whose kind is equal to `forall k. k -> Type`. The kind of D is+`forall {k}. k -> Type`, which is very close, but technically uses distinct+Core:++ -----------------------------------------------------------+ | Source Haskell | Core |+ -----------------------------------------------------------+ | forall k. <...> | ForAllTy (Bndr k Specified) (<...>) |+ | forall {k}. <...> | ForAllTy (Bndr k Inferred) (<...>) |+ -----------------------------------------------------------++We could deem these kinds to be unequal, but that would imply rejecting+programs like the one above. Whether a kind variable binder ends up being+specified or inferred can be somewhat subtle, however, especially for kinds+that aren't explicitly written out in the source code (like in D above).++For now, we decide++ the specified/inferred status of an invisible type variable binder+ does not affect GHC's notion of equality.++That is, we have the following:++ --------------------------------------------------+ | Type 1 | Type 2 | Equal? |+ --------------------|-----------------------------+ | forall k. <...> | forall k. <...> | Yes |+ | | forall {k}. <...> | Yes |+ | | forall k -> <...> | No |+ --------------------------------------------------+ | forall {k}. <...> | forall k. <...> | Yes |+ | | forall {k}. <...> | Yes |+ | | forall k -> <...> | No |+ --------------------------------------------------+ | forall k -> <...> | forall k. <...> | No |+ | | forall {k}. <...> | No |+ | | forall k -> <...> | Yes |+ --------------------------------------------------++IMPORTANT NOTE: if we want to change this decision, ForAllCo will need to carry+visiblity (by taking a ForAllTyBinder rathre than a TyCoVar), so that+coercionLKind/RKind build forall types that match (are equal to) the desired+ones. Otherwise we get an infinite loop in the solver via canEqCanLHSHetero.+Examples: T16946, T15079.++Historical Note [Typechecker equality vs definitional equality]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+This Note describes some history, in case there are vesitges of this+history lying around in the code.++Summary: prior to summer 2022, GHC had have two notions of equality+over Core types. But now there is only one: definitional equality,+or just equality for short.++The old setup was:++* Definitional equality, as implemented by GHC.Core.Type.eqType.+ See Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep.++* Typechecker equality, as implemented by tcEqType.+ GHC.Tc.Solver.Canonical.canEqNC also respects typechecker equality.++Typechecker equality implied definitional equality: if two types are equal+according to typechecker equality, then they are also equal according to+definitional equality. The converse is not always true, as typechecker equality+is more finer-grained than definitional equality in two places:++* Constraint vs Type. Definitional equality equated Type and+ Constraint, but typechecker treats them as distinct types.++* Unlike definitional equality, which does not care about the ForAllTyFlag of a+ ForAllTy, typechecker equality treats Required type variable binders as+ distinct from Invisible type variable binders.+ See Note [ForAllTy and type equality]+++************************************************************************+* *+ Comparison for types+ (We don't use instances so that we know where it happens)+* *+************************************************************************++Note [Equality on AppTys]+~~~~~~~~~~~~~~~~~~~~~~~~~+In our cast-ignoring equality, we want to say that the following two+are equal:++ (Maybe |> co) (Int |> co') ~? Maybe Int++But the left is an AppTy while the right is a TyConApp. The solution is+to use splitAppTyNoView_maybe to break up the TyConApp into its pieces and+then continue. Easy to do, but also easy to forget to do.++Note [Comparing nullary type synonyms]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider the task of testing equality between two 'Type's of the form++ TyConApp tc []++where @tc@ is a type synonym. A naive way to perform this comparison these+would first expand the synonym and then compare the resulting expansions.++However, this is obviously wasteful and the RHS of @tc@ may be large; it is+much better to rather compare the TyCons directly. Consequently, before+expanding type synonyms in type comparisons we first look for a nullary+TyConApp and simply compare the TyCons if we find one. Of course, if we find+that the TyCons are *not* equal then we still need to perform the expansion as+their RHSs may still be equal.++We perform this optimisation in a number of places:++ * GHC.Core.Types.eqType+ * GHC.Core.Types.nonDetCmpType+ * GHC.Core.Unify.unify_ty+ * TcCanonical.can_eq_nc'+ * TcUnify.uType++This optimisation is especially helpful for the ubiquitous GHC.Types.Type,+since GHC prefers to use the type synonym over @TYPE 'LiftedRep@ applications+whenever possible. See Note [Using synonyms to compress types] in+GHC.Core.Type for details.++-}++eqType :: Type -> Type -> Bool+-- ^ Type equality on source types. Does not look through @newtypes@,+-- 'PredType's or type families, but it does look through type synonyms.+-- This first checks that the kinds of the types are equal and then+-- checks whether the types are equal, ignoring casts and coercions.+-- (The kind check is a recursive call, but since all kinds have type+-- @Type@, there is no need to check the types of kinds.)+-- See also Note [Non-trivial definitional equality] in "GHC.Core.TyCo.Rep".+eqType t1 t2 = isEqual $ nonDetCmpType t1 t2+ -- It's OK to use nonDetCmpType here and eqType is deterministic,+ -- nonDetCmpType does equality deterministically++-- | Compare types with respect to a (presumably) non-empty 'RnEnv2'.+eqTypeX :: RnEnv2 -> Type -> Type -> Bool+eqTypeX env t1 t2 = isEqual $ nonDetCmpTypeX env t1 t2+ -- It's OK to use nonDetCmpType here and eqTypeX is deterministic,+ -- nonDetCmpTypeX does equality deterministically++-- | Type equality on lists of types, looking through type synonyms+-- but not newtypes.+eqTypes :: [Type] -> [Type] -> Bool+eqTypes tys1 tys2 = isEqual $ nonDetCmpTypes tys1 tys2+ -- It's OK to use nonDetCmpType here and eqTypes is deterministic,+ -- nonDetCmpTypes does equality deterministically++eqVarBndrs :: RnEnv2 -> [Var] -> [Var] -> Maybe RnEnv2+-- Check that the var lists are the same length+-- and have matching kinds; if so, extend the RnEnv2+-- Returns Nothing if they don't match+eqVarBndrs env [] []+ = Just env+eqVarBndrs env (tv1:tvs1) (tv2:tvs2)+ | eqTypeX env (varType tv1) (varType tv2)+ = eqVarBndrs (rnBndr2 env tv1 tv2) tvs1 tvs2+eqVarBndrs _ _ _= Nothing++-- Now here comes the real worker++{-+Note [nonDetCmpType nondeterminism]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+nonDetCmpType is implemented in terms of nonDetCmpTypeX. nonDetCmpTypeX+uses nonDetCmpTc which compares TyCons by their Unique value. Using Uniques for+ordering leads to nondeterminism. We hit the same problem in the TyVarTy case,+comparing type variables is nondeterministic, note the call to nonDetCmpVar in+nonDetCmpTypeX.+See Note [Unique Determinism] for more details.+-}++nonDetCmpType :: Type -> Type -> Ordering+nonDetCmpType !t1 !t2+ -- See Note [Type comparisons using object pointer comparisons]+ | 1# <- reallyUnsafePtrEquality# t1 t2+ = EQ+nonDetCmpType (TyConApp tc1 []) (TyConApp tc2 []) | tc1 == tc2+ = EQ+nonDetCmpType t1 t2+ -- we know k1 and k2 have the same kind, because they both have kind *.+ = nonDetCmpTypeX rn_env t1 t2+ where+ rn_env = mkRnEnv2 (mkInScopeSet (tyCoVarsOfTypes [t1, t2]))+{-# INLINE nonDetCmpType #-}++nonDetCmpTypes :: [Type] -> [Type] -> Ordering+nonDetCmpTypes ts1 ts2 = nonDetCmpTypesX rn_env ts1 ts2+ where+ rn_env = mkRnEnv2 (mkInScopeSet (tyCoVarsOfTypes (ts1 ++ ts2)))++-- | An ordering relation between two 'Type's (known below as @t1 :: k1@+-- and @t2 :: k2@)+data TypeOrdering = TLT -- ^ @t1 < t2@+ | TEQ -- ^ @t1 ~ t2@ and there are no casts in either,+ -- therefore we can conclude @k1 ~ k2@+ | TEQX -- ^ @t1 ~ t2@ yet one of the types contains a cast so+ -- they may differ in kind.+ | TGT -- ^ @t1 > t2@+ deriving (Eq, Ord, Enum, Bounded)++nonDetCmpTypeX :: RnEnv2 -> Type -> Type -> Ordering -- Main workhorse+ -- See Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep+ -- See Note [Computing equality on types]+nonDetCmpTypeX env orig_t1 orig_t2 =+ case go env orig_t1 orig_t2 of+ -- If there are casts then we also need to do a comparison of+ -- the kinds of the types being compared+ TEQX -> toOrdering $ go env k1 k2+ ty_ordering -> toOrdering ty_ordering+ where+ k1 = typeKind orig_t1+ k2 = typeKind orig_t2++ toOrdering :: TypeOrdering -> Ordering+ toOrdering TLT = LT+ toOrdering TEQ = EQ+ toOrdering TEQX = EQ+ toOrdering TGT = GT++ liftOrdering :: Ordering -> TypeOrdering+ liftOrdering LT = TLT+ liftOrdering EQ = TEQ+ liftOrdering GT = TGT++ thenCmpTy :: TypeOrdering -> TypeOrdering -> TypeOrdering+ thenCmpTy TEQ rel = rel+ thenCmpTy TEQX rel = hasCast rel+ thenCmpTy rel _ = rel++ hasCast :: TypeOrdering -> TypeOrdering+ hasCast TEQ = TEQX+ hasCast rel = rel++ -- 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].+ go _ (TyConApp tc1 []) (TyConApp tc2 [])+ | tc1 == tc2+ = TEQ+ go env t1 t2+ | Just t1' <- coreView t1 = go env t1' t2+ | Just t2' <- coreView t2 = go env t1 t2'++ go env (TyVarTy tv1) (TyVarTy tv2)+ = liftOrdering $ rnOccL env tv1 `nonDetCmpVar` rnOccR env tv2+ go env (ForAllTy (Bndr tv1 vis1) t1) (ForAllTy (Bndr tv2 vis2) t2)+ = liftOrdering (vis1 `cmpForAllVis` vis2)+ `thenCmpTy` go env (varType tv1) (varType tv2)+ `thenCmpTy` go (rnBndr2 env tv1 tv2) t1 t2++ -- See Note [Equality on AppTys]+ go env (AppTy s1 t1) ty2+ | Just (s2, t2) <- splitAppTyNoView_maybe ty2+ = go env s1 s2 `thenCmpTy` go env t1 t2+ go env ty1 (AppTy s2 t2)+ | Just (s1, t1) <- splitAppTyNoView_maybe ty1+ = go env s1 s2 `thenCmpTy` go env t1 t2++ go env (FunTy _ w1 s1 t1) (FunTy _ w2 s2 t2)+ -- NB: nonDepCmpTypeX does the kind check requested by+ -- Note [Equality on FunTys] in GHC.Core.TyCo.Rep+ = liftOrdering (nonDetCmpTypeX env s1 s2 S.<> nonDetCmpTypeX env t1 t2)+ `thenCmpTy` go env w1 w2+ -- Comparing multiplicities last because the test is usually true++ go env (TyConApp tc1 tys1) (TyConApp tc2 tys2)+ = liftOrdering (tc1 `nonDetCmpTc` tc2) `thenCmpTy` gos env tys1 tys2++ go _ (LitTy l1) (LitTy l2) = liftOrdering (nonDetCmpTyLit l1 l2)+ go env (CastTy t1 _) t2 = hasCast $ go env t1 t2+ go env t1 (CastTy t2 _) = hasCast $ go env t1 t2++ go _ (CoercionTy {}) (CoercionTy {}) = TEQ++ -- Deal with the rest: TyVarTy < CoercionTy < AppTy < LitTy < TyConApp < ForAllTy+ go _ ty1 ty2+ = liftOrdering $ (get_rank ty1) `compare` (get_rank ty2)+ where get_rank :: Type -> Int+ get_rank (CastTy {})+ = pprPanic "nonDetCmpTypeX.get_rank" (ppr [ty1,ty2])+ get_rank (TyVarTy {}) = 0+ get_rank (CoercionTy {}) = 1+ get_rank (AppTy {}) = 3+ get_rank (LitTy {}) = 4+ get_rank (TyConApp {}) = 5+ get_rank (FunTy {}) = 6+ get_rank (ForAllTy {}) = 7++ gos :: RnEnv2 -> [Type] -> [Type] -> TypeOrdering+ gos _ [] [] = TEQ+ gos _ [] _ = TLT+ gos _ _ [] = TGT+ gos env (ty1:tys1) (ty2:tys2) = go env ty1 ty2 `thenCmpTy` gos env tys1 tys2++-------------+nonDetCmpTypesX :: RnEnv2 -> [Type] -> [Type] -> Ordering+nonDetCmpTypesX _ [] [] = EQ+nonDetCmpTypesX env (t1:tys1) (t2:tys2) = nonDetCmpTypeX env t1 t2 S.<>+ nonDetCmpTypesX env tys1 tys2+nonDetCmpTypesX _ [] _ = LT+nonDetCmpTypesX _ _ [] = GT++-------------+-- | Compare two 'TyCon's.+-- See Note [nonDetCmpType nondeterminism]+nonDetCmpTc :: TyCon -> TyCon -> Ordering+nonDetCmpTc tc1 tc2+ = u1 `nonDetCmpUnique` u2+ where+ u1 = tyConUnique tc1+ u2 = tyConUnique tc2+++
compiler/GHC/Core/TyCo/FVs.hs view
@@ -30,6 +30,15 @@ anyFreeVarsOfType, anyFreeVarsOfTypes, anyFreeVarsOfCo, noFreeVarsOfType, noFreeVarsOfTypes, noFreeVarsOfCo, + -- * Free type constructors+ tyConsOfType,++ -- * Free vars with visible/invisible separate+ visVarsOfTypes, visVarsOfType,++ -- * Occurrence-check expansion+ occCheckExpand,+ -- * Well-scoped free variables scopedSort, tyCoVarsOfTypeWellScoped, tyCoVarsOfTypesWellScoped,@@ -44,19 +53,26 @@ import GHC.Prelude -import {-# SOURCE #-} GHC.Core.Type (coreView, partitionInvisibleTypes)+import {-# SOURCE #-} GHC.Core.Type( partitionInvisibleTypes, coreView )+import {-# SOURCE #-} GHC.Core.Coercion( coercionLKind ) +import GHC.Builtin.Types.Prim( funTyFlagTyCon )+ import Data.Monoid as DM ( Endo(..), Any(..) ) import GHC.Core.TyCo.Rep import GHC.Core.TyCon-import GHC.Types.Var+import GHC.Core.Coercion.Axiom( coAxiomTyCon ) import GHC.Utils.FV +import GHC.Types.Var import GHC.Types.Unique.FM+import GHC.Types.Unique.Set+ import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Utils.Misc import GHC.Utils.Panic+import GHC.Data.Pair {- %************************************************************************@@ -575,7 +591,7 @@ tyCoFVsOfType (CastTy ty co) f bound_vars acc = (tyCoFVsOfType ty `unionFV` tyCoFVsOfCo co) f bound_vars acc tyCoFVsOfType (CoercionTy co) f bound_vars acc = tyCoFVsOfCo co f bound_vars acc -tyCoFVsBndr :: TyCoVarBinder -> FV -> FV+tyCoFVsBndr :: ForAllTyBinder -> FV -> FV -- Free vars of (forall b. <thing with fvs>) tyCoFVsBndr (Bndr tv _) fvs = tyCoFVsVarBndr tv fvs @@ -617,7 +633,7 @@ = (tyCoFVsOfCo co `unionFV` tyCoFVsOfCo arg) fv_cand in_scope acc tyCoFVsOfCo (ForAllCo tv kind_co co) fv_cand in_scope acc = (tyCoFVsVarBndr tv (tyCoFVsOfCo co) `unionFV` tyCoFVsOfCo kind_co) fv_cand in_scope acc-tyCoFVsOfCo (FunCo _ w co1 co2) fv_cand in_scope acc+tyCoFVsOfCo (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 }) fv_cand in_scope acc = (tyCoFVsOfCo co1 `unionFV` tyCoFVsOfCo co2 `unionFV` tyCoFVsOfCo w) fv_cand in_scope acc tyCoFVsOfCo (CoVarCo v) fv_cand in_scope acc = tyCoFVsOfCoVar v fv_cand in_scope acc@@ -630,7 +646,7 @@ `unionFV` tyCoFVsOfType t2) fv_cand in_scope acc tyCoFVsOfCo (SymCo co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfCo (TransCo co1 co2) fv_cand in_scope acc = (tyCoFVsOfCo co1 `unionFV` tyCoFVsOfCo co2) fv_cand in_scope acc-tyCoFVsOfCo (NthCo _ _ co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc+tyCoFVsOfCo (SelCo _ co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfCo (LRCo _ co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfCo (InstCo co arg) fv_cand in_scope acc = (tyCoFVsOfCo co `unionFV` tyCoFVsOfCo arg) fv_cand in_scope acc tyCoFVsOfCo (KindCo co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc@@ -673,8 +689,8 @@ almost_devoid_co_var_of_co (ForAllCo v kind_co co) cv = almost_devoid_co_var_of_co kind_co cv && (v == cv || almost_devoid_co_var_of_co co cv)-almost_devoid_co_var_of_co (FunCo _ w co1 co2) cv- = almost_devoid_co_var_of_co w cv+almost_devoid_co_var_of_co (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 }) cv+ = almost_devoid_co_var_of_co w cv && almost_devoid_co_var_of_co co1 cv && almost_devoid_co_var_of_co co2 cv almost_devoid_co_var_of_co (CoVarCo v) cv = v /= cv@@ -690,7 +706,7 @@ almost_devoid_co_var_of_co (TransCo co1 co2) cv = almost_devoid_co_var_of_co co1 cv && almost_devoid_co_var_of_co co2 cv-almost_devoid_co_var_of_co (NthCo _ _ co) cv+almost_devoid_co_var_of_co (SelCo _ co) cv = almost_devoid_co_var_of_co co cv almost_devoid_co_var_of_co (LRCo _ co) cv = almost_devoid_co_var_of_co co cv@@ -747,6 +763,43 @@ +{-+%************************************************************************+%* *+ Free tyvars, but with visible/invisible info+%* *+%************************************************************************++-}+-- | Retrieve the free variables in this type, splitting them based+-- on whether they are used visibly or invisibly. Invisible ones come+-- first.+visVarsOfType :: Type -> Pair TyCoVarSet+visVarsOfType orig_ty = Pair invis_vars vis_vars+ where+ Pair invis_vars1 vis_vars = go orig_ty+ invis_vars = invis_vars1 `minusVarSet` vis_vars++ go (TyVarTy tv) = Pair (tyCoVarsOfType $ tyVarKind tv) (unitVarSet tv)+ go (AppTy t1 t2) = go t1 `mappend` go t2+ go (TyConApp tc tys) = go_tc tc tys+ go (FunTy _ w t1 t2) = go w `mappend` go t1 `mappend` go t2+ go (ForAllTy (Bndr tv _) ty)+ = ((`delVarSet` tv) <$> go ty) `mappend`+ (invisible (tyCoVarsOfType $ varType tv))+ go (LitTy {}) = mempty+ go (CastTy ty co) = go ty `mappend` invisible (tyCoVarsOfCo co)+ go (CoercionTy co) = invisible $ tyCoVarsOfCo co++ invisible vs = Pair vs emptyVarSet++ go_tc tc tys = let (invis, vis) = partitionInvisibleTypes tc tys in+ invisible (tyCoVarsOfTypes invis) `mappend` foldMap go vis++visVarsOfTypes :: [Type] -> Pair TyCoVarSet+visVarsOfTypes = foldMap visVarsOfType++ {- ********************************************************************* * * Injective free vars@@ -833,7 +886,7 @@ -- * In the kind of a bound variable in a forall -- * In a coercion -- * In a Specified or Inferred argument to a function--- See Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in "GHC.Core.TyCo.Rep"+-- See Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in "GHC.Core.TyCo.Rep" invisibleVarsOfType :: Type -> FV invisibleVarsOfType = go where@@ -996,3 +1049,273 @@ -- | Get the free vars of types in scoped order tyCoVarsOfTypesWellScoped :: [Type] -> [TyVar] tyCoVarsOfTypesWellScoped = scopedSort . tyCoVarsOfTypesList++{-+************************************************************************+* *+ Free type constructors+* *+************************************************************************+-}++-- | All type constructors occurring in the type; looking through type+-- synonyms, but not newtypes.+-- When it finds a Class, it returns the class TyCon.+tyConsOfType :: Type -> UniqSet TyCon+tyConsOfType ty+ = go ty+ where+ go :: Type -> UniqSet TyCon -- The UniqSet does duplicate elim+ go ty | Just ty' <- coreView ty = go ty'+ go (TyVarTy {}) = emptyUniqSet+ go (LitTy {}) = emptyUniqSet+ go (TyConApp tc tys) = go_tc tc `unionUniqSets` go_s tys+ go (AppTy a b) = go a `unionUniqSets` go b+ go (FunTy af w a b) = go w `unionUniqSets`+ go a `unionUniqSets` go b+ `unionUniqSets` go_tc (funTyFlagTyCon af)+ go (ForAllTy (Bndr tv _) ty) = go ty `unionUniqSets` go (varType tv)+ go (CastTy ty co) = go ty `unionUniqSets` go_co co+ go (CoercionTy co) = go_co co++ go_co (Refl ty) = go ty+ go_co (GRefl _ ty mco) = go ty `unionUniqSets` go_mco mco+ go_co (TyConAppCo _ tc args) = go_tc tc `unionUniqSets` go_cos args+ go_co (AppCo co arg) = go_co co `unionUniqSets` go_co arg+ go_co (ForAllCo _ kind_co co) = go_co kind_co `unionUniqSets` go_co co+ go_co (FunCo { fco_mult = m, fco_arg = a, fco_res = r })+ = go_co m `unionUniqSets` go_co a `unionUniqSets` go_co r+ go_co (AxiomInstCo ax _ args) = go_ax ax `unionUniqSets` go_cos args+ go_co (UnivCo p _ t1 t2) = go_prov p `unionUniqSets` go t1 `unionUniqSets` go t2+ go_co (CoVarCo {}) = emptyUniqSet+ go_co (HoleCo {}) = emptyUniqSet+ go_co (SymCo co) = go_co co+ go_co (TransCo co1 co2) = go_co co1 `unionUniqSets` go_co co2+ go_co (SelCo _ co) = go_co co+ go_co (LRCo _ co) = go_co co+ go_co (InstCo co arg) = go_co co `unionUniqSets` go_co arg+ go_co (KindCo co) = go_co co+ go_co (SubCo co) = go_co co+ go_co (AxiomRuleCo _ cs) = go_cos cs++ go_mco MRefl = emptyUniqSet+ go_mco (MCo co) = go_co co++ go_prov (PhantomProv co) = go_co co+ go_prov (ProofIrrelProv co) = go_co co+ go_prov (PluginProv _) = emptyUniqSet+ go_prov (CorePrepProv _) = emptyUniqSet+ -- this last case can happen from the tyConsOfType used from+ -- checkTauTvUpdate++ go_s tys = foldr (unionUniqSets . go) emptyUniqSet tys+ go_cos cos = foldr (unionUniqSets . go_co) emptyUniqSet cos++ go_tc tc = unitUniqSet tc+ go_ax ax = go_tc $ coAxiomTyCon ax+++{- **********************************************************************+* *+ Occurs check expansion+%* *+%********************************************************************* -}++{- Note [Occurs check expansion]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+(occurCheckExpand tv xi) expands synonyms in xi just enough to get rid+of occurrences of tv outside type function arguments, if that is+possible; otherwise, it returns Nothing.++For example, suppose we have+ type F a b = [a]+Then+ occCheckExpand b (F Int b) = Just [Int]+but+ occCheckExpand a (F a Int) = Nothing++We don't promise to do the absolute minimum amount of expanding+necessary, but we try not to do expansions we don't need to. We+prefer doing inner expansions first. For example,+ type F a b = (a, Int, a, [a])+ type G b = Char+We have+ occCheckExpand b (F (G b)) = Just (F Char)+even though we could also expand F to get rid of b.++Note [Occurrence checking: look inside kinds]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose we are considering unifying+ (alpha :: *) ~ Int -> (beta :: alpha -> alpha)+This may be an error (what is that alpha doing inside beta's kind?),+but we must not make the mistake of actually unifying or we'll+build an infinite data structure. So when looking for occurrences+of alpha in the rhs, we must look in the kinds of type variables+that occur there.++occCheckExpand tries to expand type synonyms to remove+unnecessary occurrences of a variable, and thereby get past an+occurs-check failure. This is good; but+ we can't do it in the /kind/ of a variable /occurrence/++For example #18451 built an infinite type:+ type Const a b = a+ data SameKind :: k -> k -> Type+ type T (k :: Const Type a) = forall (b :: k). SameKind a b++We have+ b :: k+ k :: Const Type a+ a :: k (must be same as b)++So if we aren't careful, a's kind mentions a, which is bad.+And expanding an /occurrence/ of 'a' doesn't help, because the+/binding site/ is the master copy and all the occurrences should+match it.++Here's a related example:+ f :: forall a b (c :: Const Type b). Proxy '[a, c]++The list means that 'a' gets the same kind as 'c'; but that+kind mentions 'b', so the binders are out of order.++Bottom line: in occCheckExpand, do not expand inside the kinds+of occurrences. See bad_var_occ in occCheckExpand. And+see #18451 for more debate.+-}++occCheckExpand :: [Var] -> Type -> Maybe Type+-- See Note [Occurs check expansion]+-- We may have needed to do some type synonym unfolding in order to+-- get rid of the variable (or forall), so we also return the unfolded+-- version of the type, which is guaranteed to be syntactically free+-- of the given type variable. If the type is already syntactically+-- free of the variable, then the same type is returned.+occCheckExpand vs_to_avoid ty+ | null vs_to_avoid -- Efficient shortcut+ = Just ty -- Can happen, eg. GHC.Core.Utils.mkSingleAltCase++ | otherwise+ = go (mkVarSet vs_to_avoid, emptyVarEnv) ty+ where+ go :: (VarSet, VarEnv TyCoVar) -> Type -> Maybe Type+ -- The VarSet is the set of variables we are trying to avoid+ -- The VarEnv carries mappings necessary+ -- because of kind expansion+ go (as, env) ty@(TyVarTy tv)+ | Just tv' <- lookupVarEnv env tv = return (mkTyVarTy tv')+ | bad_var_occ as tv = Nothing+ | otherwise = return ty++ go _ ty@(LitTy {}) = return ty+ go cxt (AppTy ty1 ty2) = do { ty1' <- go cxt ty1+ ; ty2' <- go cxt ty2+ ; return (AppTy ty1' ty2') }+ go cxt ty@(FunTy _ w ty1 ty2)+ = do { w' <- go cxt w+ ; ty1' <- go cxt ty1+ ; ty2' <- go cxt ty2+ ; return (ty { ft_mult = w', ft_arg = ty1', ft_res = ty2' }) }+ go cxt@(as, env) (ForAllTy (Bndr tv vis) body_ty)+ = do { ki' <- go cxt (varType tv)+ ; let tv' = setVarType tv ki'+ env' = extendVarEnv env tv tv'+ as' = as `delVarSet` tv+ ; body' <- go (as', env') body_ty+ ; return (ForAllTy (Bndr tv' vis) body') }++ -- For a type constructor application, first try expanding away the+ -- offending variable from the arguments. If that doesn't work, next+ -- see if the type constructor is a type synonym, and if so, expand+ -- it and try again.+ go cxt ty@(TyConApp tc tys)+ = case mapM (go cxt) tys of+ Just tys' -> return (TyConApp tc tys')+ Nothing | Just ty' <- coreView ty -> go cxt ty'+ | otherwise -> Nothing+ -- Failing that, try to expand a synonym++ go cxt (CastTy ty co) = do { ty' <- go cxt ty+ ; co' <- go_co cxt co+ ; return (CastTy ty' co') }+ go cxt (CoercionTy co) = do { co' <- go_co cxt co+ ; return (CoercionTy co') }++ ------------------+ bad_var_occ :: VarSet -> Var -> Bool+ -- Works for TyVar and CoVar+ -- See Note [Occurrence checking: look inside kinds]+ bad_var_occ vs_to_avoid v+ = v `elemVarSet` vs_to_avoid+ || tyCoVarsOfType (varType v) `intersectsVarSet` vs_to_avoid++ ------------------+ go_mco _ MRefl = return MRefl+ go_mco ctx (MCo co) = MCo <$> go_co ctx co++ ------------------+ go_co cxt (Refl ty) = do { ty' <- go cxt ty+ ; return (Refl ty') }+ go_co cxt (GRefl r ty mco) = do { mco' <- go_mco cxt mco+ ; ty' <- go cxt ty+ ; return (GRefl r ty' mco') }+ -- Note: Coercions do not contain type synonyms+ go_co cxt (TyConAppCo r tc args) = do { args' <- mapM (go_co cxt) args+ ; return (TyConAppCo r tc args') }+ go_co cxt (AppCo co arg) = do { co' <- go_co cxt co+ ; arg' <- go_co cxt arg+ ; return (AppCo co' arg') }+ go_co cxt@(as, env) (ForAllCo tv kind_co body_co)+ = do { kind_co' <- go_co cxt kind_co+ ; let tv' = setVarType tv $+ coercionLKind kind_co'+ env' = extendVarEnv env tv tv'+ as' = as `delVarSet` tv+ ; body' <- go_co (as', env') body_co+ ; return (ForAllCo tv' kind_co' body') }+ go_co cxt co@(FunCo { fco_mult = w, fco_arg = co1 ,fco_res = co2 })+ = do { co1' <- go_co cxt co1+ ; co2' <- go_co cxt co2+ ; w' <- go_co cxt w+ ; return (co { fco_mult = w', fco_arg = co1', fco_res = co2' })}++ go_co (as,env) co@(CoVarCo c)+ | Just c' <- lookupVarEnv env c = return (CoVarCo c')+ | bad_var_occ as c = Nothing+ | otherwise = return co++ go_co (as,_) co@(HoleCo h)+ | bad_var_occ as (ch_co_var h) = Nothing+ | otherwise = return co++ go_co cxt (AxiomInstCo ax ind args) = do { args' <- mapM (go_co cxt) args+ ; return (AxiomInstCo ax ind args') }+ go_co cxt (UnivCo p r ty1 ty2) = do { p' <- go_prov cxt p+ ; ty1' <- go cxt ty1+ ; ty2' <- go cxt ty2+ ; return (UnivCo p' r ty1' ty2') }+ go_co cxt (SymCo co) = do { co' <- go_co cxt co+ ; return (SymCo co') }+ go_co cxt (TransCo co1 co2) = do { co1' <- go_co cxt co1+ ; co2' <- go_co cxt co2+ ; return (TransCo co1' co2') }+ go_co cxt (SelCo n co) = do { co' <- go_co cxt co+ ; return (SelCo n co') }+ go_co cxt (LRCo lr co) = do { co' <- go_co cxt co+ ; return (LRCo lr co') }+ go_co cxt (InstCo co arg) = do { co' <- go_co cxt co+ ; arg' <- go_co cxt arg+ ; return (InstCo co' arg') }+ go_co cxt (KindCo co) = do { co' <- go_co cxt co+ ; return (KindCo co') }+ go_co cxt (SubCo co) = do { co' <- go_co cxt co+ ; return (SubCo co') }+ go_co cxt (AxiomRuleCo ax cs) = do { cs' <- mapM (go_co cxt) cs+ ; return (AxiomRuleCo ax cs') }++ ------------------+ go_prov cxt (PhantomProv co) = PhantomProv <$> go_co cxt co+ go_prov cxt (ProofIrrelProv co) = ProofIrrelProv <$> go_co cxt co+ go_prov _ p@(PluginProv _) = return p+ go_prov _ p@(CorePrepProv _) = return p+
compiler/GHC/Core/TyCo/Ppr.hs view
@@ -27,14 +27,14 @@ import GHC.Prelude import {-# SOURCE #-} GHC.CoreToIface- ( toIfaceTypeX, toIfaceTyLit, toIfaceForAllBndr+ ( toIfaceTypeX, toIfaceTyLit, toIfaceForAllBndrs , toIfaceTyCon, toIfaceTcArgs, toIfaceCoercionX ) import {-# SOURCE #-} GHC.Core.DataCon ( dataConFullSig , dataConUserTyVarBinders, DataCon ) -import GHC.Core.Type ( pickyIsLiftedTypeKind, pattern One, pattern Many,- splitForAllReqTVBinders, splitForAllInvisTVBinders )+import GHC.Core.Type ( pickyIsLiftedTypeKind, pattern OneTy, pattern ManyTy,+ splitForAllReqTyBinders, splitForAllInvisTyBinders ) import GHC.Core.TyCon import GHC.Core.TyCo.Rep@@ -42,7 +42,7 @@ import GHC.Core.TyCo.FVs import GHC.Core.Class import GHC.Types.Var-+import GHC.Core.Multiplicity( pprArrowWithMultiplicity ) import GHC.Iface.Type import GHC.Types.Var.Set@@ -161,18 +161,18 @@ pprSigmaType :: Type -> SDoc pprSigmaType = pprIfaceSigmaType ShowForAllWhen . tidyToIfaceType -pprForAll :: [TyCoVarBinder] -> SDoc-pprForAll tvs = pprIfaceForAll (map toIfaceForAllBndr tvs)+pprForAll :: [ForAllTyBinder] -> SDoc+pprForAll tvs = pprIfaceForAll (toIfaceForAllBndrs tvs) -- | Print a user-level forall; see @Note [When to print foralls]@ in -- "GHC.Iface.Type".-pprUserForAll :: [TyCoVarBinder] -> SDoc-pprUserForAll = pprUserIfaceForAll . map toIfaceForAllBndr+pprUserForAll :: [ForAllTyBinder] -> SDoc+pprUserForAll = pprUserIfaceForAll . toIfaceForAllBndrs -pprTCvBndrs :: [TyCoVarBinder] -> SDoc+pprTCvBndrs :: [ForAllTyBinder] -> SDoc pprTCvBndrs tvs = sep (map pprTCvBndr tvs) -pprTCvBndr :: TyCoVarBinder -> SDoc+pprTCvBndr :: ForAllTyBinder -> SDoc pprTCvBndr = pprTyVar . binderVar pprTyVars :: [TyVar] -> SDoc@@ -230,18 +230,15 @@ debug_ppr_ty _ (TyVarTy tv) = ppr tv -- With -dppr-debug we get (tv :: kind) -debug_ppr_ty prec ty@(FunTy { ft_af = af, ft_mult = mult, ft_arg = arg, ft_res = res })+debug_ppr_ty prec (FunTy { ft_af = af, ft_mult = mult, ft_arg = arg, ft_res = res }) = maybeParen prec funPrec $ sep [debug_ppr_ty funPrec arg, arr <+> debug_ppr_ty prec res] where- arr = case af of- VisArg -> case mult of- One -> lollipop- Many -> arrow- w -> mulArrow (const ppr) w- InvisArg -> case mult of- Many -> darrow- _ -> pprPanic "unexpected multiplicity" (ppr ty)+ arr = pprArrowWithMultiplicity af $+ case mult of+ OneTy -> Left True+ ManyTy -> Left False+ _ -> Right (debug_ppr_ty appPrec mult) debug_ppr_ty prec (TyConApp tc tys) | null tys = ppr tc@@ -263,7 +260,7 @@ -- Invisible forall: forall {k} (a :: k). t debug_ppr_ty prec t- | (bndrs, body) <- splitForAllInvisTVBinders t+ | (bndrs, body) <- splitForAllInvisTyBinders t , not (null bndrs) = maybeParen prec funPrec $ sep [ text "forall" <+> fsep (map ppr_bndr bndrs) <> dot,@@ -276,7 +273,7 @@ -- Visible forall: forall x y -> t debug_ppr_ty prec t- | (bndrs, body) <- splitForAllReqTVBinders t+ | (bndrs, body) <- splitForAllReqTyBinders t , not (null bndrs) = maybeParen prec funPrec $ sep [ text "forall" <+> fsep (map ppr_bndr bndrs) <+> arrow,@@ -288,7 +285,7 @@ -- Impossible case: neither visible nor invisible forall. debug_ppr_ty _ ForAllTy{}- = panic "debug_ppr_ty: neither splitForAllInvisTVBinders nor splitForAllReqTVBinders returned any binders"+ = panic "debug_ppr_ty: neither splitForAllInvisTyBinders nor splitForAllReqTyBinders returned any binders" {- Note [Infix type variables]
compiler/GHC/Core/TyCo/Ppr.hs-boot view
@@ -5,6 +5,7 @@ import GHC.Utils.Outputable ( SDoc ) pprType :: Type -> SDoc+debugPprType :: Type -> SDoc pprKind :: Kind -> SDoc pprCo :: Coercion -> SDoc pprTyLit :: TyLit -> SDoc
compiler/GHC/Core/TyCo/Rep.hs view
@@ -30,13 +30,13 @@ TyLit(..), KindOrType, Kind,- RuntimeRepType,+ RuntimeRepType, LevityType, KnotTied, PredType, ThetaType, FRRType, -- Synonyms- ArgFlag(..), AnonArgFlag(..),+ ForAllTyFlag(..), FunTyFlag(..), -- * Coercions- Coercion(..),+ Coercion(..), CoSel(..), FunSel(..), UnivCoProvenance(..), CoercionHole(..), coHoleCoVar, setCoHoleCoVar, CoercionN, CoercionR, CoercionP, KindCoercion,@@ -45,23 +45,15 @@ -- * Functions over types mkNakedTyConTy, mkTyVarTy, mkTyVarTys, mkTyCoVarTy, mkTyCoVarTys,- mkFunTy, mkVisFunTy, mkInvisFunTy, mkVisFunTys,+ mkFunTy, mkNakedFunTy,+ mkVisFunTy, mkScaledFunTys,+ mkInvisFunTy, mkInvisFunTys,+ tcMkVisFunTy, tcMkInvisFunTy, tcMkScaledFunTys, mkForAllTy, mkForAllTys, mkInvisForAllTys, mkPiTy, mkPiTys,- mkFunTyMany,- mkScaledFunTy, mkVisFunTyMany, mkVisFunTysMany,- mkInvisFunTyMany, mkInvisFunTysMany, nonDetCmpTyLit, cmpTyLit, - -- * Functions over binders- TyCoBinder(..), TyCoVarBinder, TyBinder,- binderVar, binderVars, binderType, binderArgFlag,- delBinderVar,- isInvisibleArgFlag, isVisibleArgFlag,- isInvisibleBinder, isVisibleBinder,- isTyBinder, isNamedBinder,- -- * Functions over coercions pickLR, @@ -78,27 +70,30 @@ import GHC.Prelude import {-# SOURCE #-} GHC.Core.TyCo.Ppr ( pprType, pprCo, pprTyLit )+import {-# SOURCE #-} GHC.Builtin.Types+import {-# SOURCE #-} GHC.Core.Type( chooseFunTyFlag, typeKind, typeTypeOrConstraint ) -- Transitively pulls in a LOT of stuff, better to break the loop -- friends: import GHC.Types.Var-import GHC.Types.Var.Set import GHC.Core.TyCon import GHC.Core.Coercion.Axiom -- others-import {-# SOURCE #-} GHC.Builtin.Types ( manyDataConTy )+import GHC.Builtin.Names+ import GHC.Types.Basic ( LeftOrRight(..), pickLR )-import GHC.Types.Unique ( Uniquable(..) ) import GHC.Utils.Outputable import GHC.Data.FastString import GHC.Utils.Misc import GHC.Utils.Panic+import GHC.Utils.Binary -- libraries import qualified Data.Data as Data hiding ( TyCon ) import Data.IORef ( IORef ) -- for CoercionHole+import Control.DeepSeq {- ********************************************************************** * *@@ -116,6 +111,9 @@ -- | Type synonym used for types of kind RuntimeRep. type RuntimeRepType = Type +-- | Type synonym used for types of kind Levity.+type LevityType = Type+ -- A type with a syntactically fixed RuntimeRep, in the sense -- of Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete. type FRRType = Type@@ -155,7 +153,7 @@ -- can appear as the right hand side of a type synonym. | ForAllTy- {-# UNPACK #-} !TyCoVarBinder+ {-# UNPACK #-} !ForAllTyBinder Type -- ^ A Π type. -- Note [When we quantify over a coercion variable] -- INVARIANT: If the binder is a coercion variable, it must@@ -164,11 +162,15 @@ | FunTy -- ^ FUN m t1 t2 Very common, so an important special case -- See Note [Function types]- { ft_af :: AnonArgFlag -- Is this (->) or (=>)?- , ft_mult :: Mult -- Multiplicity- , ft_arg :: Type -- Argument type- , ft_res :: Type } -- Result type+ { ft_af :: FunTyFlag -- Is this (->/FUN) or (=>) or (==>)?+ -- This info is fully specified by the kinds in+ -- ft_arg and ft_res+ -- Note [FunTyFlag] in GHC.Types.Var + , ft_mult :: Mult -- Multiplicity; always Many for (=>) and (==>)+ , ft_arg :: Type -- Argument type+ , ft_res :: Type } -- Result type+ | LitTy TyLit -- ^ Type literals are similar to type constructors. | CastTy@@ -232,9 +234,9 @@ TYPE r2 -> Type mkTyConApp ensures that we convert a saturated application- TyConApp FUN [m,r1,r2,t1,t2] into FunTy VisArg m t1 t2+ TyConApp FUN [m,r1,r2,t1,t2] into FunTy FTF_T_T m t1 t2 dropping the 'r1' and 'r2' arguments; they are easily recovered- from 't1' and 't2'. The visibility is always VisArg, because+ from 't1' and 't2'. The FunTyFlag is always FTF_T_T, because we build constraint arrows (=>) with e.g. mkPhiTy and friends, never `mkTyConApp funTyCon args`. @@ -255,12 +257,8 @@ There is a plan to change the argument order and make the multiplicity argument nondependent in #20164. -* The ft_af field says whether or not this is an invisible argument- VisArg: t1 -> t2 Ordinary function type- InvisArg: t1 => t2 t1 is guaranteed to be a predicate type,- i.e. t1 :: Constraint+* Re the ft_af field: see Note [FunTyFlag] in GHC.Types.Var See Note [Types for coercions, predicates, and evidence]- This visibility info makes no difference in Core; it matters only when we regard the type as a Haskell source type. @@ -299,8 +297,8 @@ of kind Constrain), are just regular old types, are visible, and are not implicitly instantiated. -In a FunTy { ft_af = InvisArg }, the argument type is always-a Predicate type.+In a FunTy { ft_af = af } and af = FTF_C_T or FTF_C_C, the argument+type is always a Predicate type. Note [Weird typing rule for ForAllTy] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -363,7 +361,7 @@ the box on the spot. * How can we get such a MkT? By promoting a GADT-style data- constructor+ constructor, written with an explicit equality constraint. data T a b where MkT :: (a~b) => a -> b -> T a b See DataCon.mkPromotedDataCon@@ -386,15 +384,15 @@ * The existence of promoted MkT with an equality-constraint argument is the (only) reason that the AnonTCB constructor- of TyConBndrVis carries an AnonArgFlag (VisArg/InvisArg).+ of TyConBndrVis carries an FunTyFlag. For example, when we promote the data constructor MkT :: forall a b. (a~b) => a -> b -> T a b we get a PromotedDataCon with tyConBinders Bndr (a :: Type) (NamedTCB Inferred) Bndr (b :: Type) (NamedTCB Inferred)- Bndr (_ :: a ~ b) (AnonTCB InvisArg)- Bndr (_ :: a) (AnonTCB VisArg))- Bndr (_ :: b) (AnonTCB VisArg))+ Bndr (_ :: a ~ b) (AnonTCB FTF_C_T)+ Bndr (_ :: a) (AnonTCB FTF_T_T))+ Bndr (_ :: b) (AnonTCB FTF_T_T)) * One might reasonably wonder who *unpacks* these boxes once they are made. After all, there is no type-level `case` construct. The@@ -539,12 +537,6 @@ extract relevant free variables, but it would not be hard to write if the need arises. -Besides eqType, another equality relation that upholds the (EQ) property above-is /typechecker equality/, which is implemented as-GHC.Tc.Utils.TcType.tcEqType. See-Note [Typechecker equality vs definitional equality] in GHC.Tc.Utils.TcType for-what the difference between eqType and tcEqType is.- Note [Respecting definitional equality] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Note [Non-trivial definitional equality] introduces the property (EQ).@@ -634,7 +626,7 @@ Note [When we quantify over a coercion variable] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The TyCoVarBinder in a ForAllTy can be (most often) a TyVar or (rarely)+The ForAllTyBinder in a ForAllTy can be (most often) a TyVar or (rarely) a CoVar. We support quantifying over a CoVar here in order to support a homogeneous (~#) relation (someday -- not yet implemented). Here is the example:@@ -664,11 +656,11 @@ Note [Unused coercion variable in ForAllTy] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose we have- \(co:t1 ~ t2). e+ \(co:t1 ~# t2). e -What type should we give to this expression?- (1) forall (co:t1 ~ t2) -> t- (2) (t1 ~ t2) -> t+What type should we give to the above expression?+ (1) forall (co:t1 ~# t2) -> t+ (2) (t1 ~# t2) -> t If co is used in t, (1) should be the right choice. if co is not used in t, we would like to have (1) and (2) equivalent.@@ -734,242 +726,6 @@ {- ********************************************************************** * *- TyCoBinder and ArgFlag-* *-********************************************************************** -}---- | A 'TyCoBinder' represents an argument to a function. TyCoBinders can be--- dependent ('Named') or nondependent ('Anon'). They may also be visible or--- not. See Note [TyCoBinders]-data TyCoBinder- = Named TyCoVarBinder -- A type-lambda binder- | Anon AnonArgFlag (Scaled Type) -- A term-lambda binder. Type here can be CoercionTy.- -- Visibility is determined by the AnonArgFlag- deriving Data.Data--instance Outputable TyCoBinder where- ppr (Anon af ty) = ppr af <+> ppr ty- ppr (Named (Bndr v Required)) = ppr v- ppr (Named (Bndr v Specified)) = char '@' <> ppr v- ppr (Named (Bndr v Inferred)) = braces (ppr v)----- | 'TyBinder' is like 'TyCoBinder', but there can only be 'TyVarBinder'--- in the 'Named' field.-type TyBinder = TyCoBinder---- | Remove the binder's variable from the set, if the binder has--- a variable.-delBinderVar :: VarSet -> TyCoVarBinder -> VarSet-delBinderVar vars (Bndr tv _) = vars `delVarSet` tv---- | Does this binder bind an invisible argument?-isInvisibleBinder :: TyCoBinder -> Bool-isInvisibleBinder (Named (Bndr _ vis)) = isInvisibleArgFlag vis-isInvisibleBinder (Anon InvisArg _) = True-isInvisibleBinder (Anon VisArg _) = False---- | Does this binder bind a visible argument?-isVisibleBinder :: TyCoBinder -> Bool-isVisibleBinder = not . isInvisibleBinder--isNamedBinder :: TyCoBinder -> Bool-isNamedBinder (Named {}) = True-isNamedBinder (Anon {}) = False---- | If its a named binder, is the binder a tyvar?--- Returns True for nondependent binder.--- This check that we're really returning a *Ty*Binder (as opposed to a--- coercion binder). That way, if/when we allow coercion quantification--- in more places, we'll know we missed updating some function.-isTyBinder :: TyCoBinder -> Bool-isTyBinder (Named bnd) = isTyVarBinder bnd-isTyBinder _ = True--{- Note [TyCoBinders]-~~~~~~~~~~~~~~~~~~~-A ForAllTy contains a TyCoVarBinder. But a type can be decomposed-to a telescope consisting of a [TyCoBinder]--A TyCoBinder represents the type of binders -- that is, the type of an-argument to a Pi-type. GHC Core currently supports two different-Pi-types:-- * A non-dependent function type,- written with ->, e.g. ty1 -> ty2- represented as FunTy ty1 ty2. These are- lifted to Coercions with the corresponding FunCo.-- * A dependent compile-time-only polytype,- written with forall, e.g. forall (a:*). ty- represented as ForAllTy (Bndr a v) ty--Both Pi-types classify terms/types that take an argument. In other-words, if `x` is either a function or a polytype, `x arg` makes sense-(for an appropriate `arg`).---Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-* A ForAllTy (used for both types and kinds) contains a TyCoVarBinder.- Each TyCoVarBinder- Bndr a tvis- is equipped with tvis::ArgFlag, which says whether or not arguments- for this binder should be visible (explicit) in source Haskell.--* A TyCon contains a list of TyConBinders. Each TyConBinder- Bndr a cvis- is equipped with cvis::TyConBndrVis, which says whether or not type- and kind arguments for this TyCon should be visible (explicit) in- source Haskell.--This table summarises the visibility rules:-----------------------------------------------------------------------------------------| Occurrences look like this-| GHC displays type as in Haskell source code-|---------------------------------------------------------------------------------------| Bndr a tvis :: TyCoVarBinder, in the binder of ForAllTy for a term-| tvis :: ArgFlag-| tvis = Inferred: f :: forall {a}. type Arg not allowed: f- f :: forall {co}. type Arg not allowed: f-| tvis = Specified: f :: forall a. type Arg optional: f or f @Int-| tvis = Required: T :: forall k -> type Arg required: T *-| This last form is illegal in terms: See Note [No Required TyCoBinder in terms]-|-| Bndr k cvis :: TyConBinder, in the TyConBinders of a TyCon-| cvis :: TyConBndrVis-| cvis = AnonTCB: T :: kind -> kind Required: T *-| cvis = NamedTCB Inferred: T :: forall {k}. kind Arg not allowed: T-| T :: forall {co}. kind Arg not allowed: T-| cvis = NamedTCB Specified: T :: forall k. kind Arg not allowed[1]: T-| cvis = NamedTCB Required: T :: forall k -> kind Required: T *------------------------------------------------------------------------------------------[1] In types, in the Specified case, it would make sense to allow- optional kind applications, thus (T @*), but we have not- yet implemented that------ In term declarations ------* Inferred. Function defn, with no signature: f1 x = x- We infer f1 :: forall {a}. a -> a, with 'a' Inferred- It's Inferred because it doesn't appear in any- user-written signature for f1--* Specified. Function defn, with signature (implicit forall):- f2 :: a -> a; f2 x = x- So f2 gets the type f2 :: forall a. a -> a, with 'a' Specified- even though 'a' is not bound in the source code by an explicit forall--* Specified. Function defn, with signature (explicit forall):- f3 :: forall a. a -> a; f3 x = x- So f3 gets the type f3 :: forall a. a -> a, with 'a' Specified--* Inferred. Function defn, with signature (explicit forall), marked as inferred:- f4 :: forall {a}. a -> a; f4 x = x- So f4 gets the type f4 :: forall {a}. a -> a, with 'a' Inferred- It's Inferred because the user marked it as such, even though it does appear- in the user-written signature for f4--* Inferred/Specified. Function signature with inferred kind polymorphism.- f5 :: a b -> Int- So 'f5' gets the type f5 :: forall {k} (a:k->*) (b:k). a b -> Int- Here 'k' is Inferred (it's not mentioned in the type),- but 'a' and 'b' are Specified.--* Specified. Function signature with explicit kind polymorphism- f6 :: a (b :: k) -> Int- This time 'k' is Specified, because it is mentioned explicitly,- so we get f6 :: forall (k:*) (a:k->*) (b:k). a b -> Int--* Similarly pattern synonyms:- Inferred - from inferred types (e.g. no pattern type signature)- - or from inferred kind polymorphism------ In type declarations ------* Inferred (k)- data T1 a b = MkT1 (a b)- Here T1's kind is T1 :: forall {k:*}. (k->*) -> k -> *- The kind variable 'k' is Inferred, since it is not mentioned-- Note that 'a' and 'b' correspond to /Anon/ TyCoBinders in T1's kind,- and Anon binders don't have a visibility flag. (Or you could think- of Anon having an implicit Required flag.)--* Specified (k)- data T2 (a::k->*) b = MkT (a b)- Here T's kind is T :: forall (k:*). (k->*) -> k -> *- The kind variable 'k' is Specified, since it is mentioned in- the signature.--* Required (k)- data T k (a::k->*) b = MkT (a b)- Here T's kind is T :: forall k:* -> (k->*) -> k -> *- The kind is Required, since it bound in a positional way in T's declaration- Every use of T must be explicitly applied to a kind--* Inferred (k1), Specified (k)- data T a b (c :: k) = MkT (a b) (Proxy c)- Here T's kind is T :: forall {k1:*} (k:*). (k1->*) -> k1 -> k -> *- So 'k' is Specified, because it appears explicitly,- but 'k1' is Inferred, because it does not--Generally, in the list of TyConBinders for a TyCon,--* Inferred arguments always come first-* Specified, Anon and Required can be mixed--e.g.- data Foo (a :: Type) :: forall b. (a -> b -> Type) -> Type where ...--Here Foo's TyConBinders are- [Required 'a', Specified 'b', Anon]-and its kind prints as- Foo :: forall a -> forall b. (a -> b -> Type) -> Type--See also Note [Required, Specified, and Inferred for types] in GHC.Tc.TyCl------ Printing ------- We print forall types with enough syntax to tell you their visibility- flag. But this is not source Haskell, and these types may not all- be parsable.-- Specified: a list of Specified binders is written between `forall` and `.`:- const :: forall a b. a -> b -> a-- Inferred: like Specified, but every binder is written in braces:- f :: forall {k} (a:k). S k a -> Int-- Required: binders are put between `forall` and `->`:- T :: forall k -> *------ Other points -------* In classic Haskell, all named binders (that is, the type variables in- a polymorphic function type f :: forall a. a -> a) have been Inferred.--* Inferred variables correspond to "generalized" variables from the- Visible Type Applications paper (ESOP'16).--Note [No Required TyCoBinder in terms]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We don't allow Required foralls for term variables, including pattern-synonyms and data constructors. Why? Because then an application-would need a /compulsory/ type argument (possibly without an "@"?),-thus (f Int); and we don't have concrete syntax for that.--We could change this decision, but Required, Named TyCoBinders are rare-anyway. (Most are Anons.)--However the type of a term can (just about) have a required quantifier;-see Note [Required quantifiers in the type of a term] in GHC.Tc.Gen.Expr.--}---{- **********************************************************************-* * PredType * * ********************************************************************** -}@@ -1041,60 +797,106 @@ mkTyCoVarTys :: [TyCoVar] -> [Type] mkTyCoVarTys = map mkTyCoVarTy -infixr 3 `mkFunTy`, `mkVisFunTy`, `mkInvisFunTy`, `mkVisFunTyMany`,- `mkInvisFunTyMany` -- Associates to the right+infixr 3 `mkFunTy`, `mkInvisFunTy`, `mkVisFunTyMany` -mkFunTy :: AnonArgFlag -> Mult -> Type -> Type -> Type-mkFunTy af mult arg res = FunTy { ft_af = af- , ft_mult = mult- , ft_arg = arg- , ft_res = res }+mkNakedFunTy :: FunTyFlag -> Kind -> Kind -> Kind+-- See Note [Naked FunTy] in GHC.Builtin.Types+-- Always Many multiplicity; kinds have no linearity+mkNakedFunTy af arg res+ = FunTy { ft_af = af, ft_mult = manyDataConTy+ , ft_arg = arg, ft_res = res } -mkScaledFunTy :: AnonArgFlag -> Scaled Type -> Type -> Type-mkScaledFunTy af (Scaled mult arg) res = mkFunTy af mult arg res+mkFunTy :: HasDebugCallStack => FunTyFlag -> Mult -> Type -> Type -> Type+mkFunTy af mult arg res+ = assertPpr (af == chooseFunTyFlag arg res) (vcat+ [ text "af" <+> ppr af+ , text "chooseAAF" <+> ppr (chooseFunTyFlag arg res)+ , text "arg" <+> ppr arg <+> dcolon <+> ppr (typeKind arg)+ , text "res" <+> ppr res <+> dcolon <+> ppr (typeKind res) ]) $+ FunTy { ft_af = af+ , ft_mult = mult+ , ft_arg = arg+ , ft_res = res } -mkVisFunTy, mkInvisFunTy :: Mult -> Type -> Type -> Type-mkVisFunTy = mkFunTy VisArg-mkInvisFunTy = mkFunTy InvisArg+mkInvisFunTy :: HasDebugCallStack => Type -> Type -> Type+mkInvisFunTy arg res+ = mkFunTy (invisArg (typeTypeOrConstraint res)) manyDataConTy arg res -mkFunTyMany :: AnonArgFlag -> Type -> Type -> Type-mkFunTyMany af = mkFunTy af manyDataConTy+mkInvisFunTys :: HasDebugCallStack => [Type] -> Type -> Type+mkInvisFunTys args res+ = foldr (mkFunTy af manyDataConTy) res args+ where+ af = invisArg (typeTypeOrConstraint res) --- | Special, common, case: Arrow type with mult Many-mkVisFunTyMany :: Type -> Type -> Type-mkVisFunTyMany = mkVisFunTy manyDataConTy+tcMkVisFunTy :: Mult -> Type -> Type -> Type+-- Always TypeLike, user-specified multiplicity.+-- Does not have the assert-checking in mkFunTy: used by the typechecker+-- to avoid looking at the result kind, which may not be zonked+tcMkVisFunTy mult arg res+ = FunTy { ft_af = visArgTypeLike, ft_mult = mult+ , ft_arg = arg, ft_res = res } -mkInvisFunTyMany :: Type -> Type -> Type-mkInvisFunTyMany = mkInvisFunTy manyDataConTy+tcMkInvisFunTy :: TypeOrConstraint -> Type -> Type -> Type+-- Always TypeLike, invisible argument+-- Does not have the assert-checking in mkFunTy: used by the typechecker+-- to avoid looking at the result kind, which may not be zonked+tcMkInvisFunTy res_torc arg res+ = FunTy { ft_af = invisArg res_torc, ft_mult = manyDataConTy+ , ft_arg = arg, ft_res = res } +mkVisFunTy :: HasDebugCallStack => Mult -> Type -> Type -> Type+-- Always TypeLike, user-specified multiplicity.+mkVisFunTy = mkFunTy visArgTypeLike+ -- | Make nested arrow types-mkVisFunTys :: [Scaled Type] -> Type -> Type-mkVisFunTys tys ty = foldr (mkScaledFunTy VisArg) ty tys+-- | Special, common, case: Arrow type with mult Many+mkVisFunTyMany :: HasDebugCallStack => Type -> Type -> Type+-- Always TypeLike, multiplicity Many+mkVisFunTyMany = mkVisFunTy manyDataConTy mkVisFunTysMany :: [Type] -> Type -> Type+-- Always TypeLike, multiplicity Many mkVisFunTysMany tys ty = foldr mkVisFunTyMany ty tys -mkInvisFunTysMany :: [Type] -> Type -> Type-mkInvisFunTysMany tys ty = foldr mkInvisFunTyMany ty tys+---------------+mkScaledFunTy :: HasDebugCallStack => FunTyFlag -> Scaled Type -> Type -> Type+mkScaledFunTy af (Scaled mult arg) res = mkFunTy af mult arg res +mkScaledFunTys :: HasDebugCallStack => [Scaled Type] -> Type -> Type+-- All visible args+-- Result type can be TypeLike or ConstraintLike+-- Example of the latter: dataConWrapperType for the data con of a class+mkScaledFunTys tys ty = foldr (mkScaledFunTy af) ty tys+ where+ af = visArg (typeTypeOrConstraint ty)++tcMkScaledFunTys :: [Scaled Type] -> Type -> Type+-- All visible args+-- Result type must be TypeLike+-- No mkFunTy assert checking; result kind may not be zonked+tcMkScaledFunTys tys ty = foldr mk ty tys+ where+ mk (Scaled mult arg) res = tcMkVisFunTy mult arg res++--------------- -- | Like 'mkTyCoForAllTy', but does not check the occurrence of the binder -- See Note [Unused coercion variable in ForAllTy]-mkForAllTy :: TyCoVar -> ArgFlag -> Type -> Type-mkForAllTy tv vis ty = ForAllTy (Bndr tv vis) ty+mkForAllTy :: ForAllTyBinder -> Type -> Type+mkForAllTy = ForAllTy -- | Wraps foralls over the type using the provided 'TyCoVar's from left to right-mkForAllTys :: [TyCoVarBinder] -> Type -> Type+mkForAllTys :: [ForAllTyBinder] -> Type -> Type mkForAllTys tyvars ty = foldr ForAllTy ty tyvars -- | Wraps foralls over the type using the provided 'InvisTVBinder's from left to right mkInvisForAllTys :: [InvisTVBinder] -> Type -> Type mkInvisForAllTys tyvars = mkForAllTys (tyVarSpecToBinders tyvars) -mkPiTy :: TyCoBinder -> Type -> Type-mkPiTy (Anon af ty1) ty2 = mkScaledFunTy af ty1 ty2-mkPiTy (Named (Bndr tv vis)) ty = mkForAllTy tv vis ty+mkPiTy :: PiTyBinder -> Type -> Type+mkPiTy (Anon ty1 af) ty2 = mkScaledFunTy af ty1 ty2+mkPiTy (Named bndr) ty = mkForAllTy bndr ty -mkPiTys :: [TyCoBinder] -> Type -> Type+mkPiTys :: [PiTyBinder] -> Type -> Type mkPiTys tbs ty = foldr mkPiTy ty tbs -- | 'mkNakedTyConTy' creates a nullary 'TyConApp'. In general you@@ -1158,13 +960,15 @@ | ForAllCo TyCoVar KindCoercion Coercion -- ForAllCo :: _ -> N -> e -> e - | FunCo Role CoercionN Coercion Coercion -- lift FunTy- -- FunCo :: "e" -> N -> e -> e -> e- -- Note: why doesn't FunCo have a AnonArgFlag, like FunTy?- -- Because the AnonArgFlag has no impact on Core; it is only- -- there to guide implicit instantiation of Haskell source- -- types, and that is irrelevant for coercions, which are- -- Core-only.+ | FunCo -- FunCo :: "e" -> N/P -> e -> e -> e+ -- See Note [FunCo] for fco_afl, fco_afr+ { fco_role :: Role+ , fco_afl :: FunTyFlag -- Arrow for coercionLKind+ , fco_afr :: FunTyFlag -- Arrow for coercionRKind+ , fco_mult :: CoercionN+ , fco_arg, fco_res :: Coercion }+ -- (if the role "e" is Phantom, the first coercion is, too)+ -- the first coercion is for the multiplicity -- These are special | CoVarCo CoVar -- :: _ -> (N or R)@@ -1191,14 +995,7 @@ | SymCo Coercion -- :: e -> e | TransCo Coercion Coercion -- :: e -> e -> e - | NthCo Role Int Coercion -- Zero-indexed; decomposes (T t0 ... tn)- -- :: "e" -> _ -> e0 -> e (inverse of TyConAppCo, see Note [TyConAppCo roles])- -- Using NthCo on a ForAllCo gives an N coercion always- -- See Note [NthCo and newtypes]- --- -- Invariant: (NthCo r i co), it is always the case that r = role of (Nth i co)- -- That is: the role of the entire coercion is redundantly cached here.- -- See Note [NthCo Cached Roles]+ | SelCo CoSel Coercion -- See Note [SelCo] | LRCo LeftOrRight CoercionN -- Decomposes (t_left t_right) -- :: _ -> N -> N@@ -1218,6 +1015,27 @@ -- Only present during typechecking deriving Data.Data +data CoSel -- See Note [SelCo]+ = SelTyCon Int Role -- Decomposes (T co1 ... con); zero-indexed+ -- Invariant: Given: SelCo (SelTyCon i r) co+ -- we have r == tyConRole (coercionRole co) tc+ -- and tc1 == tc2+ -- where T tc1 _ = coercionLKind co+ -- T tc2 _ = coercionRKind co+ -- See Note [SelCo]++ | SelFun FunSel -- Decomposes (co1 -> co2)++ | SelForAll -- Decomposes (forall a. co)++ deriving( Eq, Data.Data )++data FunSel -- See Note [SelCo]+ = SelMult -- Multiplicity+ | SelArg -- Argument of function+ | SelRes -- Result of function+ deriving( Eq, Data.Data )+ type CoercionN = Coercion -- always nominal type CoercionR = Coercion -- always representational type CoercionP = Coercion -- always phantom@@ -1226,6 +1044,36 @@ instance Outputable Coercion where ppr = pprCo +instance Outputable CoSel where+ ppr (SelTyCon n _r) = text "Tc" <> parens (int n)+ ppr SelForAll = text "All"+ ppr (SelFun fs) = text "Fun" <> parens (ppr fs)++instance Outputable FunSel where+ ppr SelMult = text "mult"+ ppr SelArg = text "arg"+ ppr SelRes = text "res"++instance Binary CoSel where+ put_ bh (SelTyCon n r) = do { putByte bh 0; put_ bh n; put_ bh r }+ put_ bh SelForAll = putByte bh 1+ put_ bh (SelFun SelMult) = putByte bh 2+ put_ bh (SelFun SelArg) = putByte bh 3+ put_ bh (SelFun SelRes) = putByte bh 4++ get bh = do { h <- getByte bh+ ; case h of+ 0 -> do { n <- get bh; r <- get bh; return (SelTyCon n r) }+ 1 -> return SelForAll+ 2 -> return (SelFun SelMult)+ 3 -> return (SelFun SelArg)+ _ -> return (SelFun SelRes) }++instance NFData CoSel where+ rnf (SelTyCon n r) = n `seq` r `seq` ()+ rnf SelForAll = ()+ rnf (SelFun fs) = fs `seq` ()+ -- | A semantically more meaningful type to represent what may or may not be a -- useful 'Coercion'. data MCoercion@@ -1246,7 +1094,7 @@ Invariant 1: Refl lifting Refl (similar for GRefl r ty MRefl) is always lifted as far as possible. For example- (Refl T) (Refl a) (Refl b) is normalised (by mkAPpCo) to (Refl (T a b)).+ (Refl T) (Refl a) (Refl b) is normalised (by mkAppCo) to (Refl (T a b)). You might think that a consequences is: Every identity coercion has Refl at the root@@ -1298,6 +1146,72 @@ A nominal reflexive coercion is quite common, so we keep the special form Refl to save allocation. +Note [SelCo]+~~~~~~~~~~~~+The Coercion form SelCo allows us to decompose a structural coercion, one+between ForallTys, or TyConApps, or FunTys.++There are three forms, split by the CoSel field inside the SelCo:+SelTyCon, SelForAll, and SelFun.++* SelTyCon:++ co : (T s1..sn) ~r0 (T t1..tn)+ T is a data type, not a newtype, nor an arrow type+ r = tyConRole tc r0 i+ i < n (i is zero-indexed)+ ----------------------------------+ SelCo (SelTyCon i r) : si ~r ti++ "Not a newtype": see Note [SelCo and newtypes]+ "Not an arrow type": see SelFun below++ See Note [SelCo Cached Roles]++* SelForAll:+ co : forall (a:k1).t1 ~r0 forall (a:k2).t2+ ----------------------------------+ SelCo SelForAll : k1 ~N k2++ NB: SelForAll always gives a Nominal coercion.++* The SelFun form, for functions, has three sub-forms for the three+ components of the function type (multiplicity, argument, result).++ co : (s1 %{m1}-> t1) ~r0 (s2 %{m2}-> t2)+ r = funRole r0 SelMult+ ----------------------------------+ SelCo (SelFun SelMult) : m1 ~r m2++ co : (s1 %{m1}-> t1) ~r0 (s2 %{m2}-> t2)+ r = funRole r0 SelArg+ ----------------------------------+ SelCo (SelFun SelArg) : s1 ~r s2++ co : (s1 %{m1}-> t1) ~r0 (s2 %{m2}-> t2)+ r = funRole r0 SelRes+ ----------------------------------+ SelCo (SelFun SelRes) : t1 ~r t2++Note [FunCo]+~~~~~~~~~~~~+Just as FunTy has a ft_af :: FunTyFlag field, FunCo (which connects+two function types) has two FunTyFlag fields:+ funco_afl, funco_afr :: FunTyFlag+In all cases, the FunTyFlag is recoverable from the kinds of the argument+and result types/coercions; but experiments show that it's better to+cache it.++Why does FunCo need /two/ flags? If we have a single method class,+implemented as a newtype+ class C a where { op :: [a] -> a }+then we can have a coercion+ co :: C Int ~R ([Int]->Int)+So now we can define+ FunCo co <Bool> : (C Int => Bool) ~R (([Int]->Int) -> Bool)+Notice that the left and right arrows are different! Hence two flags,+one for coercionLKind and one for coercionRKind.+ Note [Coercion axioms applied to coercions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The reason coercion axioms can be applied to coercions and not just@@ -1416,7 +1330,7 @@ This collapse is done by mkPredCo; there is no PredCo constructor in Coercion. This is important because we need Nth to work on predicates too:- Nth 1 ((~) [c] g) = g+ SelCo (SelTyCon 1) ((~) [c] g) = g See Simplify.simplCoercionF, which generates such selections. Note [Roles]@@ -1530,7 +1444,7 @@ The rules here dictate the roles of the parameters to mkTyConAppCo (should be checked by Lint). -Note [NthCo and newtypes]+Note [SelCo and newtypes] ~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose we have @@ -1547,20 +1461,21 @@ co = NTCo:N a ; sym (NTCo:N b) for any `a` and `b`. Because of the role annotation on N, if we use-NthCo, we'll get out a representational coercion. That is:+SelCo, we'll get out a representational coercion. That is: - NthCo r 0 co :: forall a b. a ~R b+ SelCo (SelTyCon 0 r) co :: forall a b. a ~r b Yikes! Clearly, this is terrible. The solution is simple: forbid-NthCo to be used on newtypes if the internal coercion is representational.+SelCo to be used on newtypes if the internal coercion is representational.+See the SelCo equation for GHC.Core.Lint.lintCoercion. This is not just some corner case discovered by a segfault somewhere; it was discovered in the proof of soundness of roles and described in the "Safe Coercions" paper (ICFP '14). -Note [NthCo Cached Roles]+Note [SelCo Cached Roles] ~~~~~~~~~~~~~~~~~~~~~~~~~-Why do we cache the role of NthCo in the NthCo constructor?+Why do we cache the role of SelCo in the SelCo constructor? Because computing role(Nth i co) involves figuring out that co :: T tys1 ~ T tys2@@ -1570,7 +1485,7 @@ we have to compute the kind and role of a coercion simultaneously, which makes the code complicated and inefficient. -This only happens for NthCo. Caching the role solves the problem, and+This only happens for SelCo. Caching the role solves the problem, and allows coercionKind and coercionRole to be simple. See #11735@@ -1886,7 +1801,7 @@ -- ^ What to do with coercion holes. -- See Note [Coercion holes] in "GHC.Core.TyCo.Rep". - , tcf_tycobinder :: env -> TyCoVar -> ArgFlag -> env+ , tcf_tycobinder :: env -> TyCoVar -> ForAllTyFlag -> env -- ^ The returned env is used in the extended scope } @@ -1921,27 +1836,28 @@ go_cos _ [] = mempty go_cos env (c:cs) = go_co env c `mappend` go_cos env cs - go_co env (Refl ty) = go_ty env ty- go_co env (GRefl _ ty MRefl) = go_ty env ty- go_co env (GRefl _ ty (MCo co)) = go_ty env ty `mappend` go_co env co- go_co env (TyConAppCo _ _ args) = go_cos env args- go_co env (AppCo c1 c2) = go_co env c1 `mappend` go_co env c2- go_co env (FunCo _ cw c1 c2) = go_co env cw `mappend`- go_co env c1 `mappend`- go_co env c2- go_co env (CoVarCo cv) = covar env cv- go_co env (AxiomInstCo _ _ args) = go_cos env args- go_co env (HoleCo hole) = cohole env hole- go_co env (UnivCo p _ t1 t2) = go_prov env p `mappend` go_ty env t1- `mappend` go_ty env t2- go_co env (SymCo co) = go_co env co- go_co env (TransCo c1 c2) = go_co env c1 `mappend` go_co env c2- go_co env (AxiomRuleCo _ cos) = go_cos env cos- go_co env (NthCo _ _ co) = go_co env co- go_co env (LRCo _ co) = go_co env co- go_co env (InstCo co arg) = go_co env co `mappend` go_co env arg- go_co env (KindCo co) = go_co env co- go_co env (SubCo co) = go_co env co+ go_co env (Refl ty) = go_ty env ty+ go_co env (GRefl _ ty MRefl) = go_ty env ty+ go_co env (GRefl _ ty (MCo co)) = go_ty env ty `mappend` go_co env co+ go_co env (TyConAppCo _ _ args) = go_cos env args+ go_co env (AppCo c1 c2) = go_co env c1 `mappend` go_co env c2+ go_co env (CoVarCo cv) = covar env cv+ go_co env (AxiomInstCo _ _ args) = go_cos env args+ go_co env (HoleCo hole) = cohole env hole+ go_co env (UnivCo p _ t1 t2) = go_prov env p `mappend` go_ty env t1+ `mappend` go_ty env t2+ go_co env (SymCo co) = go_co env co+ go_co env (TransCo c1 c2) = go_co env c1 `mappend` go_co env c2+ go_co env (AxiomRuleCo _ cos) = go_cos env cos+ go_co env (SelCo _ co) = go_co env co+ go_co env (LRCo _ co) = go_co env co+ go_co env (InstCo co arg) = go_co env co `mappend` go_co env arg+ go_co env (KindCo co) = go_co env co+ go_co env (SubCo co) = go_co env co++ go_co env (FunCo { fco_mult = cw, fco_arg = c1, fco_res = c2 })+ = go_co env cw `mappend` go_co env c1 `mappend` go_co env c2+ go_co env (ForAllCo tv kind_co co) = go_co env kind_co `mappend` go_ty env (varType tv) `mappend` go_co env' co@@ -1991,17 +1907,17 @@ coercionSize (GRefl _ ty MRefl) = typeSize ty coercionSize (GRefl _ ty (MCo co)) = 1 + typeSize ty + coercionSize co coercionSize (TyConAppCo _ _ args) = 1 + sum (map coercionSize args)-coercionSize (AppCo co arg) = coercionSize co + coercionSize arg-coercionSize (ForAllCo _ h co) = 1 + coercionSize co + coercionSize h-coercionSize (FunCo _ w co1 co2) = 1 + coercionSize co1 + coercionSize co2- + coercionSize w+coercionSize (AppCo co arg) = coercionSize co + coercionSize arg+coercionSize (ForAllCo _ h co) = 1 + coercionSize co + coercionSize h+coercionSize (FunCo _ _ _ w c1 c2) = 1 + coercionSize c1 + coercionSize c2+ + coercionSize w coercionSize (CoVarCo _) = 1 coercionSize (HoleCo _) = 1 coercionSize (AxiomInstCo _ _ args) = 1 + sum (map coercionSize args) coercionSize (UnivCo p _ t1 t2) = 1 + provSize p + typeSize t1 + typeSize t2 coercionSize (SymCo co) = 1 + coercionSize co coercionSize (TransCo co1 co2) = 1 + coercionSize co1 + coercionSize co2-coercionSize (NthCo _ _ co) = 1 + coercionSize co+coercionSize (SelCo _ co) = 1 + coercionSize co coercionSize (LRCo _ co) = 1 + coercionSize co coercionSize (InstCo co arg) = 1 + coercionSize co + coercionSize arg coercionSize (KindCo co) = 1 + coercionSize co
compiler/GHC/Core/TyCo/Rep.hs-boot view
@@ -3,17 +3,19 @@ import GHC.Utils.Outputable ( Outputable ) import Data.Data ( Data )-import {-# SOURCE #-} GHC.Types.Var( Var, ArgFlag, AnonArgFlag )+import {-# SOURCE #-} GHC.Types.Var( Var, VarBndr, ForAllTyFlag, FunTyFlag ) import {-# SOURCE #-} GHC.Core.TyCon ( TyCon ) data Type data Coercion+data CoSel data UnivCoProvenance data TyLit-data TyCoBinder data MCoercion data Scaled a+scaledThing :: Scaled a -> a+ type Mult = Type type PredType = Type@@ -23,9 +25,17 @@ type CoercionN = Coercion type MCoercionN = MCoercion -mkFunTyMany :: AnonArgFlag -> Type -> Type -> Type-mkForAllTy :: Var -> ArgFlag -> Type -> Type-mkNakedTyConTy :: TyCon -> Type+mkForAllTy :: VarBndr Var ForAllTyFlag -> Type -> Type+mkNakedTyConTy :: TyCon -> Type+mkNakedFunTy :: FunTyFlag -> Type -> Type -> Type -instance Data Type -- To support Data instances in GHC.Core.Coercion.Axiom++-- To support Data instances in GHC.Core.Coercion.Axiom+instance Data Type++-- To support instances PiTyBinder in Var+instance Data a => Data (Scaled a)++-- To support debug pretty-printing instance Outputable Type+instance Outputable a => Outputable (Scaled a)
compiler/GHC/Core/TyCo/Subst.hs view
@@ -6,7 +6,6 @@ {-# LANGUAGE BangPatterns #-}-{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} -- | Substitution into types and coercions. module GHC.Core.TyCo.Subst@@ -44,9 +43,9 @@ substVarBndr, substVarBndrs, substTyVarBndr, substTyVarBndrs, substCoVarBndr,- substTyVar, substTyVars, substTyCoVars,- substTyCoBndr,- substForAllCoBndr,+ substTyVar, substTyVars, substTyVarToTyVar,+ substTyCoVars,+ substTyCoBndr, substForAllCoBndr, substVarBndrUsing, substForAllCoBndrUsing, checkValidSubst, isValidTCvSubst, ) where@@ -54,11 +53,11 @@ import GHC.Prelude import {-# SOURCE #-} GHC.Core.Type- ( mkCastTy, mkAppTy, isCoercionTy, mkTyConApp )+ ( mkCastTy, mkAppTy, isCoercionTy, mkTyConApp, getTyVar_maybe ) import {-# SOURCE #-} GHC.Core.Coercion- ( mkCoVarCo, mkKindCo, mkNthCo, mkTransCo+ ( mkCoVarCo, mkKindCo, mkSelCo, mkTransCo , mkNomReflCo, mkSubCo, mkSymCo- , mkFunCo, mkForAllCo, mkUnivCo+ , mkFunCo2, mkForAllCo, mkUnivCo , mkAxiomInstCo, mkAppCo, mkGReflCo , mkInstCo, mkLRCo, mkTyConAppCo , mkCoercionType@@ -375,7 +374,7 @@ = assert (isTyVar tv) $ Subst in_scope ids (extendVarEnv tvs tv ty) cvs -extendTvSubstBinderAndInScope :: Subst -> TyCoBinder -> Type -> Subst+extendTvSubstBinderAndInScope :: Subst -> PiTyBinder -> Type -> Subst extendTvSubstBinderAndInScope subst (Named (Bndr v _)) ty = assert (isTyVar v ) extendTvSubstAndInScope subst v ty@@ -820,6 +819,16 @@ Just ty -> ty Nothing -> TyVarTy tv +substTyVarToTyVar :: HasDebugCallStack => Subst -> TyVar -> TyVar+-- Apply the substitution, expecing the result to be a TyVarTy+substTyVarToTyVar (Subst _ _ tenv _) tv+ = assert (isTyVar tv) $+ case lookupVarEnv tenv tv of+ Just ty -> case getTyVar_maybe ty of+ Just tv -> tv+ Nothing -> pprPanic "substTyVarToTyVar" (ppr tv $$ ppr ty)+ Nothing -> tv+ substTyVars :: Subst -> [TyVar] -> [Type] substTyVars subst = map $ substTyVar subst @@ -884,14 +893,14 @@ = case substForAllCoBndrUnchecked subst tv kind_co of (subst', tv', kind_co') -> ((mkForAllCo $! tv') $! kind_co') $! subst_co subst' co- go (FunCo r w co1 co2) = ((mkFunCo r $! go w) $! go co1) $! go co2+ go (FunCo r afl afr w co1 co2) = ((mkFunCo2 r afl afr $! go w) $! go co1) $! go co2 go (CoVarCo cv) = substCoVar subst cv go (AxiomInstCo con ind cos) = mkAxiomInstCo con ind $! map go cos go (UnivCo p r t1 t2) = (((mkUnivCo $! go_prov p) $! r) $! (go_ty t1)) $! (go_ty t2) go (SymCo co) = mkSymCo $! (go co) go (TransCo co1 co2) = (mkTransCo $! (go co1)) $! (go co2)- go (NthCo r d co) = mkNthCo r d $! (go co)+ go (SelCo d co) = mkSelCo d $! (go co) go (LRCo lr co) = mkLRCo lr $! (go co) go (InstCo co arg) = (mkInstCo $! (go co)) $! go arg go (KindCo co) = mkKindCo $! (go co)@@ -1114,8 +1123,8 @@ (subst' , tv ) = cloneTyVarBndr subst t uniq (subst'', tvs) = cloneTyVarBndrs subst' ts usupply' -substTyCoBndr :: Subst -> TyCoBinder -> (Subst, TyCoBinder)-substTyCoBndr subst (Anon af ty) = (subst, Anon af (substScaledTy subst ty))+substTyCoBndr :: Subst -> PiTyBinder -> (Subst, PiTyBinder)+substTyCoBndr subst (Anon ty af) = (subst, Anon (substScaledTy subst ty) af) substTyCoBndr subst (Named (Bndr tv vis)) = (subst', Named (Bndr tv' vis)) where (subst', tv') = substVarBndr subst tv
compiler/GHC/Core/TyCo/Tidy.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE BangPatterns #-}-{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- | Tidying types and coercions for printing in error messages.@@ -13,10 +12,11 @@ tidyTyCoVarOcc, tidyTopType, tidyCo, tidyCos,- tidyTyCoVarBinder, tidyTyCoVarBinders+ tidyForAllTyBinder, tidyForAllTyBinders ) where import GHC.Prelude+import GHC.Data.FastString import GHC.Core.TyCo.Rep import GHC.Core.TyCo.FVs (tyCoVarsOfTypesWellScoped, tyCoVarsOfTypeList)@@ -70,24 +70,24 @@ -- this way is a helpful clue for users getHelpfulOccName tv | isSystemName name, isTcTyVar tv- = mkTyVarOcc (occNameString occ ++ "0")+ = mkTyVarOccFS (occNameFS occ `appendFS` fsLit "0") | otherwise = occ where name = varName tv occ = getOccName name -tidyTyCoVarBinder :: TidyEnv -> VarBndr TyCoVar vis+tidyForAllTyBinder :: TidyEnv -> VarBndr TyCoVar vis -> (TidyEnv, VarBndr TyCoVar vis)-tidyTyCoVarBinder tidy_env (Bndr tv vis)+tidyForAllTyBinder tidy_env (Bndr tv vis) = (tidy_env', Bndr tv' vis) where (tidy_env', tv') = tidyVarBndr tidy_env tv -tidyTyCoVarBinders :: TidyEnv -> [VarBndr TyCoVar vis]+tidyForAllTyBinders :: TidyEnv -> [VarBndr TyCoVar vis] -> (TidyEnv, [VarBndr TyCoVar vis])-tidyTyCoVarBinders tidy_env tvbs- = mapAccumL tidyTyCoVarBinder+tidyForAllTyBinders tidy_env tvbs+ = mapAccumL tidyForAllTyBinder (avoidNameClashes (binderVars tvbs) tidy_env) tvbs ---------------@@ -174,14 +174,14 @@ -- The following two functions differ from mkForAllTys and splitForAllTyCoVars in that--- they expect/preserve the ArgFlag argument. These belong to "GHC.Core.Type", but+-- they expect/preserve the ForAllTyFlag argument. These belong to "GHC.Core.Type", but -- how should they be named?-mkForAllTys' :: [(TyCoVar, ArgFlag)] -> Type -> Type+mkForAllTys' :: [(TyCoVar, ForAllTyFlag)] -> Type -> Type mkForAllTys' tvvs ty = foldr strictMkForAllTy ty tvvs where strictMkForAllTy (tv,vis) ty = (ForAllTy $! ((Bndr $! tv) $! vis)) $! ty -splitForAllTyCoVars' :: Type -> ([TyCoVar], [ArgFlag], Type)+splitForAllTyCoVars' :: Type -> ([TyCoVar], [ForAllTyFlag], Type) splitForAllTyCoVars' ty = go ty [] [] where go (ForAllTy (Bndr tv vis) ty) tvs viss = go ty (tv:tvs) (vis:viss)@@ -232,7 +232,7 @@ where (envp, tvp) = tidyVarBndr env tv -- the case above duplicates a bit of work in tidying h and the kind -- of tv. But the alternative is to use coercionKind, which seems worse.- go (FunCo r w co1 co2) = ((FunCo r $! go w) $! go co1) $! go co2+ go (FunCo r afl afr w co1 co2) = ((FunCo r afl afr $! go w) $! go co1) $! go co2 go (CoVarCo cv) = case lookupVarEnv subst cv of Nothing -> CoVarCo cv Just cv' -> CoVarCo cv'@@ -242,7 +242,7 @@ tidyType env t1) $! tidyType env t2 go (SymCo co) = SymCo $! go co go (TransCo co1 co2) = (TransCo $! go co1) $! go co2- go (NthCo r d co) = NthCo r d $! go co+ go (SelCo d co) = SelCo d $! go co go (LRCo lr co) = LRCo lr $! go co go (InstCo co ty) = (InstCo $! go co) $! go ty go (KindCo co) = KindCo $! go co
compiler/GHC/Core/TyCon.hs view
@@ -17,14 +17,14 @@ AlgTyConRhs(..), visibleDataCons, AlgTyConFlav(..), isNoParent, FamTyConFlav(..), Role(..), Injectivity(..),- RuntimeRepInfo(..), TyConFlavour(..),+ PromDataConInfo(..), TyConFlavour(..), -- * TyConBinder- TyConBinder, TyConBndrVis(..), TyConTyCoBinder,+ TyConBinder, TyConBndrVis(..), TyConPiTyBinder, mkNamedTyConBinder, mkNamedTyConBinders, mkRequiredTyConBinder,- mkAnonTyConBinder, mkAnonTyConBinders,- tyConBinderArgFlag, tyConBndrVisArgFlag, isNamedTyConBinder,+ mkAnonTyConBinder, mkAnonTyConBinders, mkInvisAnonTyConBinder,+ tyConBinderForAllTyFlag, tyConBndrVisForAllTyFlag, isNamedTyConBinder, isVisibleTyConBinder, isInvisibleTyConBinder, isVisibleTcbVis, -- ** Field labels@@ -33,7 +33,6 @@ -- ** Constructing TyCons mkAlgTyCon, mkClassTyCon,- mkFunTyCon, mkPrimTyCon, mkTupleTyCon, mkSumTyCon,@@ -46,20 +45,21 @@ noTcTyConScopedTyVars, -- ** Predicates on TyCons- isAlgTyCon, isVanillaAlgTyCon, isConstraintKindCon,+ isAlgTyCon, isVanillaAlgTyCon, isClassTyCon, isFamInstTyCon,- isFunTyCon, isPrimTyCon, isTupleTyCon, isUnboxedTupleTyCon, isBoxedTupleTyCon, isUnboxedSumTyCon, isPromotedTupleTyCon, isLiftedAlgTyCon, isTypeSynonymTyCon,- mustBeSaturated,+ tyConMustBeSaturated, isPromotedDataCon, isPromotedDataCon_maybe,+ isDataKindsPromotedDataCon, isKindTyCon, isLiftedTypeKindTyConName, isTauTyCon, isFamFreeTyCon, isForgetfulSynTyCon, isDataTyCon,+ isTypeDataTyCon, isEnumerationTyCon, isNewTyCon, isAbstractTyCon, isFamilyTyCon, isOpenFamilyTyCon,@@ -89,7 +89,7 @@ tyConFamilySize, tyConStupidTheta, tyConArity,- tyConNullaryTy,+ tyConNullaryTy, mkTyConTy, tyConRoles, tyConFlavour, tyConTuple_maybe, tyConClass_maybe, tyConATs,@@ -102,7 +102,7 @@ unwrapNewTyCon_maybe, unwrapNewTyConEtad_maybe, newTyConDataCon_maybe, algTcFields,- tyConRuntimeRepInfo,+ tyConPromDataConInfo, tyConBinders, tyConResKind, tyConInvisTVBinders, tcTyConScopedTyVars, tcTyConIsPoly, mkTyConTagMap,@@ -130,6 +130,8 @@ primRepIsFloat, primRepsCompatible, primRepCompatible,+ primRepIsWord,+ primRepIsInt, ) where @@ -137,17 +139,17 @@ import GHC.Platform import {-# SOURCE #-} GHC.Core.TyCo.Rep- ( Kind, Type, PredType, mkForAllTy, mkFunTyMany, mkNakedTyConTy )+ ( Kind, Type, PredType, mkForAllTy, mkNakedFunTy, mkNakedTyConTy ) import {-# SOURCE #-} GHC.Core.TyCo.Ppr ( pprType ) import {-# SOURCE #-} GHC.Builtin.Types ( runtimeRepTyCon, constraintKind, levityTyCon , multiplicityTyCon- , vecCountTyCon, vecElemTyCon, liftedTypeKind )+ , vecCountTyCon, vecElemTyCon ) import {-# SOURCE #-} GHC.Core.DataCon ( DataCon, dataConFieldLabels , dataConTyCon, dataConFullSig- , isUnboxedSumDataCon )+ , isUnboxedSumDataCon, isTypeDataCon ) import {-# SOURCE #-} GHC.Core.Type ( isLiftedTypeKind ) import GHC.Builtin.Uniques@@ -440,37 +442,44 @@ ************************************************************************ * *- TyConBinder, TyConTyCoBinder+ TyConBinder, TyConPiTyBinder * * ************************************************************************ -} type TyConBinder = VarBndr TyVar TyConBndrVis-type TyConTyCoBinder = VarBndr TyCoVar TyConBndrVis- -- Only PromotedDataCon has TyConTyCoBinders+type TyConPiTyBinder = VarBndr TyCoVar TyConBndrVis+ -- Only PromotedDataCon has TyConPiTyBinders -- See Note [Promoted GADT data constructors] data TyConBndrVis- = NamedTCB ArgFlag- | AnonTCB AnonArgFlag+ = NamedTCB ForAllTyFlag+ | AnonTCB FunTyFlag instance Outputable TyConBndrVis where- ppr (NamedTCB flag) = text "NamedTCB" <> ppr flag- ppr (AnonTCB af) = text "AnonTCB" <> ppr af+ ppr (NamedTCB flag) = ppr flag+ ppr (AnonTCB af) = ppr af -mkAnonTyConBinder :: AnonArgFlag -> TyVar -> TyConBinder-mkAnonTyConBinder af tv = assert (isTyVar tv) $- Bndr tv (AnonTCB af)+mkAnonTyConBinder :: TyVar -> TyConBinder+-- Make a visible anonymous TyCon binder+mkAnonTyConBinder tv = assert (isTyVar tv) $+ Bndr tv (AnonTCB visArgTypeLike) -mkAnonTyConBinders :: AnonArgFlag -> [TyVar] -> [TyConBinder]-mkAnonTyConBinders af tvs = map (mkAnonTyConBinder af) tvs+mkAnonTyConBinders :: [TyVar] -> [TyConBinder]+mkAnonTyConBinders tvs = map mkAnonTyConBinder tvs -mkNamedTyConBinder :: ArgFlag -> TyVar -> TyConBinder+mkInvisAnonTyConBinder :: TyVar -> TyConBinder+-- Make an /invisible/ anonymous TyCon binder+-- Not used much+mkInvisAnonTyConBinder tv = assert (isTyVar tv) $+ Bndr tv (AnonTCB invisArgTypeLike)++mkNamedTyConBinder :: ForAllTyFlag -> TyVar -> TyConBinder -- The odd argument order supports currying mkNamedTyConBinder vis tv = assert (isTyVar tv) $ Bndr tv (NamedTCB vis) -mkNamedTyConBinders :: ArgFlag -> [TyVar] -> [TyConBinder]+mkNamedTyConBinders :: ForAllTyFlag -> [TyVar] -> [TyConBinder] -- The odd argument order supports currying mkNamedTyConBinders vis tvs = map (mkNamedTyConBinder vis) tvs @@ -481,15 +490,16 @@ -> TyConBinder mkRequiredTyConBinder dep_set tv | tv `elemVarSet` dep_set = mkNamedTyConBinder Required tv- | otherwise = mkAnonTyConBinder VisArg tv+ | otherwise = mkAnonTyConBinder tv -tyConBinderArgFlag :: TyConBinder -> ArgFlag-tyConBinderArgFlag (Bndr _ vis) = tyConBndrVisArgFlag vis+tyConBinderForAllTyFlag :: TyConBinder -> ForAllTyFlag+tyConBinderForAllTyFlag (Bndr _ vis) = tyConBndrVisForAllTyFlag vis -tyConBndrVisArgFlag :: TyConBndrVis -> ArgFlag-tyConBndrVisArgFlag (NamedTCB vis) = vis-tyConBndrVisArgFlag (AnonTCB VisArg) = Required-tyConBndrVisArgFlag (AnonTCB InvisArg) = Inferred -- See Note [AnonTCB InvisArg]+tyConBndrVisForAllTyFlag :: TyConBndrVis -> ForAllTyFlag+tyConBndrVisForAllTyFlag (NamedTCB vis) = vis+tyConBndrVisForAllTyFlag (AnonTCB af) -- See Note [AnonTCB with constraint arg]+ | isVisibleFunArg af = Required+ | otherwise = Inferred isNamedTyConBinder :: TyConBinder -> Bool -- Identifies kind variables@@ -503,9 +513,8 @@ isVisibleTyConBinder (Bndr _ tcb_vis) = isVisibleTcbVis tcb_vis isVisibleTcbVis :: TyConBndrVis -> Bool-isVisibleTcbVis (NamedTCB vis) = isVisibleArgFlag vis-isVisibleTcbVis (AnonTCB VisArg) = True-isVisibleTcbVis (AnonTCB InvisArg) = False+isVisibleTcbVis (NamedTCB vis) = isVisibleForAllTyFlag vis+isVisibleTcbVis (AnonTCB af) = isVisibleFunArg af isInvisibleTyConBinder :: VarBndr tv TyConBndrVis -> Bool -- Works for IfaceTyConBinder too@@ -517,9 +526,17 @@ mkTyConKind bndrs res_kind = foldr mk res_kind bndrs where mk :: TyConBinder -> Kind -> Kind- mk (Bndr tv (AnonTCB af)) k = mkFunTyMany af (varType tv) k- mk (Bndr tv (NamedTCB vis)) k = mkForAllTy tv vis k+ mk (Bndr tv (NamedTCB vis)) k = mkForAllTy (Bndr tv vis) k+ mk (Bndr tv (AnonTCB af)) k = mkNakedFunTy af (varType tv) k+ -- mkNakedFunTy: see Note [Naked FunTy] in GHC.Builtin.Types +-- | (mkTyConTy tc) returns (TyConApp tc [])+-- but arranges to share that TyConApp among all calls+-- See Note [Sharing nullary TyConApps]+-- So it's just an alias for tyConNullaryTy!+mkTyConTy :: TyCon -> Type+mkTyConTy tycon = tyConNullaryTy tycon+ tyConInvisTVBinders :: [TyConBinder] -- From the TyCon -> [InvisTVBinder] -- Suitable for the foralls of a term function -- See Note [Building TyVarBinders from TyConBinders]@@ -529,8 +546,9 @@ mk_binder (Bndr tv tc_vis) = mkTyVarBinder vis tv where vis = case tc_vis of- AnonTCB VisArg -> SpecifiedSpec- AnonTCB InvisArg -> InferredSpec -- See Note [AnonTCB InvisArg]+ AnonTCB af -- Note [AnonTCB with constraint arg]+ | isInvisibleFunArg af -> InferredSpec+ | otherwise -> SpecifiedSpec NamedTCB Required -> SpecifiedSpec NamedTCB (Invisible vis) -> vis @@ -540,10 +558,10 @@ = [ tv | Bndr tv vis <- tyConBinders tc , isVisibleTcbVis vis ] -{- Note [AnonTCB InvisArg]-~~~~~~~~~~~~~~~~~~~~~~~~~~-It's pretty rare to have an (AnonTCB InvisArg) binder. The-only way it can occur is through equality constraints in kinds. These+{- Note [AnonTCB with constraint arg]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+It's pretty rare to have an (AnonTCB af) binder with af=FTF_C_T or FTF_C_C.+The only way it can occur is through equality constraints in kinds. These can arise in one of two ways: * In a PromotedDataCon whose kind has an equality constraint:@@ -552,19 +570,20 @@ See Note [Constraints in kinds] in GHC.Core.TyCo.Rep, and Note [Promoted data constructors] in this module.+ * In a data type whose kind has an equality constraint, as in the following example from #12102: data T :: forall a. (IsTypeLit a ~ 'True) => a -> Type -When mapping an (AnonTCB InvisArg) to an ArgFlag, in-tyConBndrVisArgFlag, we use "Inferred" to mean "the user cannot+When mapping an (AnonTCB FTF_C_x) to an ForAllTyFlag, in+tyConBndrVisForAllTyFlag, we use "Inferred" to mean "the user cannot specify this arguments, even with visible type/kind application; instead the type checker must fill it in. -We map (AnonTCB VisArg) to Required, of course: the user must+We map (AnonTCB FTF_T_x) to Required, of course: the user must provide it. It would be utterly wrong to do this for constraint-arguments, which is why AnonTCB must have the AnonArgFlag in+arguments, which is why AnonTCB must have the FunTyFlag in the first place. Note [Building TyVarBinders from TyConBinders]@@ -576,12 +595,12 @@ * From data T a = MkT (Maybe a) we are going to make a data constructor with type MkT :: forall a. Maybe a -> T a- See the TyCoVarBinders passed to buildDataCon+ See the ForAllTyBinders passed to buildDataCon * From class C a where { op :: a -> Maybe a } we are going to make a default method $dmop :: forall a. C a => a -> Maybe a- See the TyCoVarBinders passed to mkSigmaTy in mkDefaultMethodType+ See the ForAllTyBinders passed to mkSigmaTy in mkDefaultMethodType Both of these are user-callable. (NB: default methods are not callable directly by the user but rather via the code generated by 'deriving',@@ -602,7 +621,7 @@ But the DataCon MkApp has the type MkApp :: forall {k} (a:k->*) (b:k). a b -> App k a b -That is, its TyCoVarBinders should be+That is, its ForAllTyBinders should be dataConUnivTyVarBinders = [ Bndr (k:*) Inferred , Bndr (a:k->*) Specified@@ -615,15 +634,15 @@ The last part about Required->Specified comes from this: data T k (a:k) b = MkT (a b) Here k is Required in T's kind, but we don't have Required binders in-the TyCoBinders for a term (see Note [No Required TyCoBinder in terms]-in GHC.Core.TyCo.Rep), so we change it to Specified when making MkT's TyCoBinders+the PiTyBinders for a term (see Note [No Required PiTyBinder in terms]+in GHC.Core.TyCo.Rep), so we change it to Specified when making MkT's PiTyBinders -} {- Note [The binders/kind/arity fields of a TyCon] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ All TyCons have this group of fields- tyConBinders :: [TyConBinder/TyConTyCoBinder]+ tyConBinders :: [TyConBinder/TyConPiTyBinder] tyConResKind :: Kind tyConTyVars :: [TyVar] -- Cached = binderVars tyConBinders -- NB: Currently (Aug 2018), TyCons that own this@@ -648,7 +667,7 @@ See Note [tyConBinders and lexical scoping] -* See Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep+* See Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep for what the visibility flag means. * Each TyConBinder tyConBinders has a TyVar (sometimes it is TyCoVar), and@@ -720,13 +739,7 @@ -} instance OutputableBndr tv => Outputable (VarBndr tv TyConBndrVis) where- ppr (Bndr v bi) = ppr_bi bi <+> parens (pprBndr LetBind v)- where- ppr_bi (AnonTCB VisArg) = text "anon-vis"- ppr_bi (AnonTCB InvisArg) = text "anon-invis"- ppr_bi (NamedTCB Required) = text "req"- ppr_bi (NamedTCB Specified) = text "spec"- ppr_bi (NamedTCB Inferred) = text "inf"+ ppr (Bndr v bi) = ppr bi <+> parens (pprBndr LetBind v) instance Binary TyConBndrVis where put_ bh (AnonTCB af) = do { putByte bh 0; put_ bh af }@@ -765,25 +778,7 @@ -- If you edit this type, you may need to update the GHC formalism -- See Note [GHC Formalism] in GHC.Core.Lint-data TyCon- = -- | The function type constructor, @(->)@- FunTyCon {- tyConUnique :: Unique, -- ^ A Unique of this TyCon. Invariant:- -- identical to Unique of Name stored in- -- tyConName field.-- tyConName :: Name, -- ^ Name of the constructor-- -- See Note [The binders/kind/arity fields of a TyCon]- tyConBinders :: [TyConBinder], -- ^ Full binders- tyConResKind :: Kind, -- ^ Result kind- tyConKind :: Kind, -- ^ Kind of this TyCon- tyConArity :: Arity, -- ^ Arity- tyConNullaryTy :: Type,-- tcRepName :: TyConRepName- }-+data TyCon = -- | Algebraic data types, from -- - @data@ declarations -- - @newtype@ declarations@@ -796,10 +791,10 @@ -- - unboxed sums -- Data/newtype/type /families/ are handled by 'FamilyTyCon'. -- See 'AlgTyConRhs' for more information.- | AlgTyCon {- tyConUnique :: Unique, -- ^ A Unique of this TyCon. Invariant:- -- identical to Unique of Name stored in- -- tyConName field.+ AlgTyCon {+ tyConUnique :: !Unique, -- ^ A Unique of this TyCon. Invariant:+ -- identical to Unique of Name stored in+ -- tyConName field. tyConName :: Name, -- ^ Name of the constructor @@ -858,9 +853,9 @@ -- | Represents type synonyms | SynonymTyCon {- tyConUnique :: Unique, -- ^ A Unique of this TyCon. Invariant:- -- identical to Unique of Name stored in- -- tyConName field.+ tyConUnique :: !Unique, -- ^ A Unique of this TyCon. Invariant:+ -- identical to Unique of Name stored in+ -- tyConName field. tyConName :: Name, -- ^ Name of the constructor @@ -897,7 +892,7 @@ -- | Represents families (both type and data) -- Argument roles are all Nominal | FamilyTyCon {- tyConUnique :: Unique, -- ^ A Unique of this TyCon. Invariant:+ tyConUnique :: !Unique, -- ^ A Unique of this TyCon. Invariant: -- identical to Unique of Name stored in -- tyConName field. @@ -935,9 +930,9 @@ -- the usual suspects (such as @Int#@) as well as foreign-imported -- types and kinds (@*@, @#@, and @?@) | PrimTyCon {- tyConUnique :: Unique, -- ^ A Unique of this TyCon. Invariant:- -- identical to Unique of Name stored in- -- tyConName field.+ tyConUnique :: !Unique, -- ^ A Unique of this TyCon. Invariant:+ -- identical to Unique of Name stored in+ -- tyConName field. tyConName :: Name, -- ^ Name of the constructor @@ -959,12 +954,12 @@ -- | Represents promoted data constructor. | PromotedDataCon { -- See Note [Promoted data constructors]- tyConUnique :: Unique, -- ^ Same Unique as the data constructor+ tyConUnique :: !Unique, -- ^ Same Unique as the data constructor tyConName :: Name, -- ^ Same Name as the data constructor -- See Note [The binders/kind/arity fields of a TyCon]- tyConBinders :: [TyConTyCoBinder], -- ^ Full binders- -- TyConTyCoBinder: see Note [Promoted GADT data constructors]+ tyConBinders :: [TyConPiTyBinder], -- ^ Full binders+ -- TyConPiTyBinder: see Note [Promoted GADT data constructors] tyConResKind :: Kind, -- ^ Result kind tyConKind :: Kind, -- ^ Kind of this TyCon tyConArity :: Arity, -- ^ Arity@@ -973,13 +968,13 @@ tcRoles :: [Role], -- ^ Roles: N for kind vars, R for type vars dataCon :: DataCon, -- ^ Corresponding data constructor tcRepName :: TyConRepName,- promDcRepInfo :: RuntimeRepInfo -- ^ See comments with 'RuntimeRepInfo'+ promDcInfo :: PromDataConInfo -- ^ See comments with 'PromDataConInfo' } -- | These exist only during type-checking. See Note [How TcTyCons work] -- in "GHC.Tc.TyCl" | TcTyCon {- tyConUnique :: Unique,+ tyConUnique :: !Unique, tyConName :: Name, -- See Note [The binders/kind/arity fields of a TyCon]@@ -1031,8 +1026,8 @@ K :: forall a b. (a ~# [b]) => a -> b -> T a So, when promoted to become a type constructor, the tyConBinders-will include CoVars. That is why we use [TyConTyCoBinder] for the-tyconBinders field. TyConTyCoBinder is a synonym for TyConBinder,+will include CoVars. That is why we use [TyConPiTyBinder] for the+tyconBinders field. TyConPiTyBinder is a synonym for TyConBinder, but with the clue that the binder can be a CoVar not just a TyVar. Note [Representation-polymorphic TyCons]@@ -1138,6 +1133,9 @@ -- ^ Cached value: length data_cons is_enum :: Bool, -- ^ Cached value: is this an enumeration type? -- See Note [Enumeration types]+ is_type_data :: Bool,+ -- from a "type data" declaration+ -- See Note [Type data declarations] in GHC.Rename.Module data_fixed_lev :: Bool -- ^ 'True' if the data type constructor has -- a known, fixed levity when fully applied@@ -1218,14 +1216,18 @@ -- | Create an 'AlgTyConRhs' from the data constructors, -- for a potentially levity-polymorphic datatype (with `UnliftedDatatypes`). mkLevPolyDataTyConRhs :: Bool -- ^ whether the 'DataCon' has a fixed levity+ -> Bool -- ^ True if this is a "type data" declaration+ -- See Note [Type data declarations]+ -- in GHC.Rename.Module -> [DataCon] -> AlgTyConRhs-mkLevPolyDataTyConRhs fixed_lev cons+mkLevPolyDataTyConRhs fixed_lev type_data cons = DataTyCon { data_cons = cons, data_cons_size = length cons, is_enum = not (null cons) && all is_enum_con cons, -- See Note [Enumeration types] in GHC.Core.TyCon+ is_type_data = type_data, data_fixed_lev = fixed_lev } where@@ -1236,26 +1238,29 @@ -- | Create an 'AlgTyConRhs' from the data constructors. ----- Use 'mkLevPolyDataConRhs' if the datatype can be levity-polymorphic.+-- Use 'mkLevPolyDataConRhs' if the datatype can be levity-polymorphic+-- or if it comes from a "data type" declaration mkDataTyConRhs :: [DataCon] -> AlgTyConRhs-mkDataTyConRhs = mkLevPolyDataTyConRhs True+mkDataTyConRhs = mkLevPolyDataTyConRhs True False -- | Some promoted datacons signify extra info relevant to GHC. For example,--- the @IntRep@ constructor of @RuntimeRep@ corresponds to the 'IntRep'+-- the `IntRep` constructor of `RuntimeRep` corresponds to the 'IntRep' -- constructor of 'PrimRep'. This data structure allows us to store this -- information right in the 'TyCon'. The other approach would be to look--- up things like @RuntimeRep@'s @PrimRep@ by known-key every time.+-- up things like `RuntimeRep`'s `PrimRep` by known-key every time. -- See also Note [Getting from RuntimeRep to PrimRep] in "GHC.Types.RepType"-data RuntimeRepInfo- = NoRRI -- ^ an ordinary promoted data con+data PromDataConInfo+ = NoPromInfo -- ^ an ordinary promoted data con | RuntimeRep ([Type] -> [PrimRep])- -- ^ A constructor of @RuntimeRep@. The argument to the function should+ -- ^ A constructor of `RuntimeRep`. The argument to the function should -- be the list of arguments to the promoted datacon.- | VecCount Int -- ^ A constructor of @VecCount@- | VecElem PrimElemRep -- ^ A constructor of @VecElem@- | LiftedInfo -- ^ A constructor of @Levity@- | UnliftedInfo -- ^ A constructor of @Levity@ + | VecCount Int -- ^ A constructor of `VecCount`++ | VecElem PrimElemRep -- ^ A constructor of `VecElem`++ | Levity Levity -- ^ A constructor of `Levity`+ -- | Extract those 'DataCon's that we are able to learn about. Note -- that visibility in this sense does not correspond to visibility in -- the context of any particular user program!@@ -1409,8 +1414,8 @@ via the PromotedDataCon alternative in GHC.Core.TyCon. * The TyCon promoted from a DataCon has the *same* Name and Unique as- the DataCon. Eg. If the data constructor Data.Maybe.Just(unique 78,- say) is promoted to a TyCon whose name is Data.Maybe.Just(unique 78)+ the DataCon. Eg. If the data constructor Data.Maybe.Just(unique 78)+ is promoted to a TyCon whose name is Data.Maybe.Just(unique 78) * We promote the *user* type of the DataCon. Eg data T = MkT {-# UNPACK #-} !(Bool, Bool)@@ -1512,8 +1517,6 @@ -- $tcMaybe = TyCon { tyConName = "Maybe", ... } tyConRepName_maybe :: TyCon -> Maybe TyConRepName-tyConRepName_maybe (FunTyCon { tcRepName = rep_nm })- = Just rep_nm tyConRepName_maybe (PrimTyCon { primRepName = rep_nm }) = Just rep_nm tyConRepName_maybe (AlgTyCon { algTcFlavour = parent }) = case parent of@@ -1786,6 +1789,24 @@ primRepIsFloat (VecRep _ _) = Nothing primRepIsFloat _ = Just False +-- Rep is one of the word reps.+primRepIsWord :: PrimRep -> Bool+primRepIsWord WordRep = True+primRepIsWord (Word8Rep) = True+primRepIsWord (Word16Rep) = True+primRepIsWord (Word32Rep) = True+primRepIsWord (Word64Rep) = True+primRepIsWord _ = False++-- Rep is one of the int reps.+primRepIsInt :: PrimRep -> Bool+primRepIsInt (IntRep) = True+primRepIsInt (Int8Rep) = True+primRepIsInt (Int16Rep) = True+primRepIsInt (Int32Rep) = True+primRepIsInt (Int64Rep) = True+primRepIsInt _ = False+ {- ************************************************************************ * *@@ -1832,24 +1853,6 @@ So we compromise, and move their Kind calculation to the call site. -} --- | Given the name of the function type constructor and it's kind, create the--- corresponding 'TyCon'. It is recommended to use 'GHC.Builtin.Types.funTyCon' if you want--- this functionality-mkFunTyCon :: Name -> [TyConBinder] -> Name -> TyCon-mkFunTyCon name binders rep_nm- = let tc =- FunTyCon {- tyConUnique = nameUnique name,- tyConName = name,- tyConBinders = binders,- tyConResKind = liftedTypeKind,- tyConKind = mkTyConKind binders liftedTypeKind,- tyConArity = length binders,- tyConNullaryTy = mkNakedTyConTy tc,- tcRepName = rep_nm- }- in tc- -- | This is the making of an algebraic 'TyCon'. mkAlgTyCon :: Name -> [TyConBinder] -- ^ Binders of the 'TyCon'@@ -2061,8 +2064,8 @@ -- as the data constructor itself; when we pretty-print -- the TyCon we add a quote; see the Outputable TyCon instance mkPromotedDataCon :: DataCon -> Name -> TyConRepName- -> [TyConTyCoBinder] -> Kind -> [Role]- -> RuntimeRepInfo -> TyCon+ -> [TyConPiTyBinder] -> Kind -> [Role]+ -> PromDataConInfo -> TyCon mkPromotedDataCon con name rep_name binders res_kind roles rep_info = let tc = PromotedDataCon {@@ -2076,14 +2079,10 @@ tyConKind = mkTyConKind binders res_kind, dataCon = con, tcRepName = rep_name,- promDcRepInfo = rep_info+ promDcInfo = rep_info } in tc -isFunTyCon :: TyCon -> Bool-isFunTyCon (FunTyCon {}) = True-isFunTyCon _ = False- -- | Test if the 'TyCon' is algebraic but abstract (invisible data constructors) isAbstractTyCon :: TyCon -> Bool isAbstractTyCon (AlgTyCon { algTcRhs = AbstractTyCon {} }) = True@@ -2106,16 +2105,6 @@ isVanillaAlgTyCon (AlgTyCon { algTcFlavour = VanillaAlgTyCon _ }) = True isVanillaAlgTyCon _ = False --- | Returns @True@ for the 'TyCon' of the 'Constraint' kind.-{-# INLINE isConstraintKindCon #-} -- See Note [Inlining coreView] in GHC.Core.Type-isConstraintKindCon :: TyCon -> Bool--- NB: We intentionally match on AlgTyCon, because 'constraintKindTyCon' is--- always an AlgTyCon (see 'pcTyCon' in TysWiredIn) and the record selector--- for 'tyConUnique' would generate unreachable code for every other data--- constructor of TyCon (see #18026).-isConstraintKindCon AlgTyCon { tyConUnique = u } = u == constraintKindTyConKey-isConstraintKindCon _ = False- isDataTyCon :: TyCon -> Bool -- ^ Returns @True@ for data types that are /definitely/ represented by -- heap-allocated constructors. These are scrutinised by Core-level@@ -2133,19 +2122,29 @@ TupleTyCon { tup_sort = sort } -> isBoxed (tupleSortBoxity sort) SumTyCon {} -> False- DataTyCon {} -> True+ -- Constructors from "type data" declarations exist only at+ -- the type level.+ -- See Note [Type data declarations] in GHC.Rename.Module.+ DataTyCon { is_type_data = type_data } -> not type_data NewTyCon {} -> False AbstractTyCon {} -> False -- We don't know, so return False isDataTyCon _ = False +-- | Was this 'TyCon' declared as "type data"?+-- See Note [Type data declarations] in GHC.Rename.Module.+isTypeDataTyCon :: TyCon -> Bool+isTypeDataTyCon (AlgTyCon {algTcRhs = DataTyCon {is_type_data = type_data }})+ = type_data+isTypeDataTyCon _ = False+ -- | 'isInjectiveTyCon' is true of 'TyCon's for which this property holds--- (where X is the role passed in):--- If (T a1 b1 c1) ~X (T a2 b2 c2), then (a1 ~X1 a2), (b1 ~X2 b2), and (c1 ~X3 c2)--- (where X1, X2, and X3, are the roles given by tyConRolesX tc X)--- See also Note [Decomposing equality] in "GHC.Tc.Solver.Canonical"+-- (where r is the role passed in):+-- If (T a1 b1 c1) ~r (T a2 b2 c2), then (a1 ~r1 a2), (b1 ~r2 b2), and (c1 ~r3 c2)+-- (where r1, r2, and r3, are the roles given by tyConRolesX tc r)+-- See also Note [Decomposing TyConApp equalities] in "GHC.Tc.Solver.Canonical" isInjectiveTyCon :: TyCon -> Role -> Bool-isInjectiveTyCon _ Phantom = False-isInjectiveTyCon (FunTyCon {}) _ = True+isInjectiveTyCon _ Phantom = True -- Vacuously; (t1 ~P t2) holes for all t1, t2!+ isInjectiveTyCon (AlgTyCon {}) Nominal = True isInjectiveTyCon (AlgTyCon {algTcRhs = rhs}) Representational = isGenInjAlgRhs rhs@@ -2161,9 +2160,9 @@ -- See Note [How TcTyCons work] item (1) in GHC.Tc.TyCl -- | 'isGenerativeTyCon' is true of 'TyCon's for which this property holds--- (where X is the role passed in):--- If (T tys ~X t), then (t's head ~X T).--- See also Note [Decomposing equality] in "GHC.Tc.Solver.Canonical"+-- (where r is the role passed in):+-- If (T tys ~r t), then (t's head ~r T).+-- See also Note [Decomposing TyConApp equalities] in "GHC.Tc.Solver.Canonical" isGenerativeTyCon :: TyCon -> Role -> Bool isGenerativeTyCon (FamilyTyCon { famTcFlav = DataFamilyTyCon _ }) Nominal = True isGenerativeTyCon (FamilyTyCon {}) _ = False@@ -2238,11 +2237,11 @@ -- (T ~N d), (a ~N e) and (b ~N f)? -- Specifically NOT true of synonyms (open and otherwise) ----- It'd be unusual to call mustBeSaturated on a regular H98+-- It'd be unusual to call tyConMustBeSaturated on a regular H98 -- type synonym, because you should probably have expanded it first -- But regardless, it's not decomposable-mustBeSaturated :: TyCon -> Bool-mustBeSaturated = tcFlavourMustBeSaturated . tyConFlavour+tyConMustBeSaturated :: TyCon -> Bool+tyConMustBeSaturated = tcFlavourMustBeSaturated . tyConFlavour -- | Is this an algebraic 'TyCon' declared with the GADT syntax? isGadtSyntaxTyCon :: TyCon -> Bool@@ -2385,6 +2384,19 @@ isPromotedDataCon (PromotedDataCon {}) = True isPromotedDataCon _ = False +-- | This function identifies PromotedDataCon's from data constructors in+-- `data T = K1 | K2`, promoted by -XDataKinds. These type constructors+-- are printed with a tick mark 'K1 and 'K2, and similarly have a tick+-- mark added to their OccName's.+--+-- In contrast, constructors in `type data T = K1 | K2` are printed and+-- represented with their original undecorated names.+-- See Note [Type data declarations] in GHC.Rename.Module+isDataKindsPromotedDataCon :: TyCon -> Bool+isDataKindsPromotedDataCon (PromotedDataCon { dataCon = dc })+ = not (isTypeDataCon dc)+isDataKindsPromotedDataCon _ = False+ -- | Retrieves the promoted DataCon if this is a PromotedDataCon; isPromotedDataCon_maybe :: TyCon -> Maybe DataCon isPromotedDataCon_maybe (PromotedDataCon { dataCon = dc }) = Just dc@@ -2425,7 +2437,6 @@ -- (namely: boxed and unboxed tuples are wired-in and implicit, -- but constraint tuples are not) isImplicitTyCon :: TyCon -> Bool-isImplicitTyCon (FunTyCon {}) = True isImplicitTyCon (PrimTyCon {}) = True isImplicitTyCon (PromotedDataCon {}) = True isImplicitTyCon (AlgTyCon { algTcRhs = rhs, tyConName = name })@@ -2465,7 +2476,6 @@ -- -- See Note [Representation-polymorphic TyCons] tcHasFixedRuntimeRep :: TyCon -> Bool-tcHasFixedRuntimeRep FunTyCon{} = True tcHasFixedRuntimeRep (AlgTyCon { algTcRhs = rhs }) = case rhs of AbstractTyCon {} -> False -- An abstract TyCon might not have a fixed runtime representation.@@ -2655,8 +2665,7 @@ -- See also Note [TyCon Role signatures] tyConRoles tc = case tc of- { FunTyCon {} -> [Nominal, Nominal, Nominal, Representational, Representational]- ; AlgTyCon { tcRoles = roles } -> roles+ { AlgTyCon { tcRoles = roles } -> roles ; SynonymTyCon { tcRoles = roles } -> roles ; FamilyTyCon {} -> const_role Nominal ; PrimTyCon { tcRoles = roles } -> roles@@ -2708,7 +2717,7 @@ -- @data Eq a => T a ...@. See @Note [The stupid context]@ in "GHC.Core.DataCon". tyConStupidTheta :: TyCon -> [PredType] tyConStupidTheta (AlgTyCon {algTcStupidTheta = stupid}) = stupid-tyConStupidTheta (FunTyCon {}) = []+tyConStupidTheta (PrimTyCon {}) = [] tyConStupidTheta tycon = pprPanic "tyConStupidTheta" (ppr tycon) -- | Extract the 'TyVar's bound by a vanilla type synonym@@ -2774,9 +2783,9 @@ tyConFamilyCoercion_maybe _ = Nothing -- | Extract any 'RuntimeRepInfo' from this TyCon-tyConRuntimeRepInfo :: TyCon -> RuntimeRepInfo-tyConRuntimeRepInfo (PromotedDataCon { promDcRepInfo = rri }) = rri-tyConRuntimeRepInfo _ = NoRRI+tyConPromDataConInfo :: TyCon -> PromDataConInfo+tyConPromDataConInfo (PromotedDataCon { promDcInfo = rri }) = rri+tyConPromDataConInfo _ = NoPromInfo -- could panic in that second case. But Douglas Adams told me not to. {-@@ -2883,7 +2892,6 @@ AbstractClosedSynFamilyTyCon -> ClosedTypeFamilyFlavour BuiltInSynFamTyCon{} -> ClosedTypeFamilyFlavour tyConFlavour (SynonymTyCon {}) = TypeSynonymFlavour-tyConFlavour (FunTyCon {}) = BuiltInTypeFlavour tyConFlavour (PrimTyCon {}) = BuiltInTypeFlavour tyConFlavour (PromotedDataCon {}) = PromotedDataConFlavour tyConFlavour (TcTyCon { tcTyConFlavour = flav }) = flav@@ -2920,10 +2928,15 @@ pprPromotionQuote :: TyCon -> SDoc -- Promoted data constructors already have a tick in their OccName-pprPromotionQuote tc- = case tc of- PromotedDataCon {} -> char '\'' -- Always quote promoted DataCons in types- _ -> empty+pprPromotionQuote tc =+ getPprStyle $ \sty ->+ let+ name = getOccName tc+ ticked = isDataKindsPromotedDataCon tc && promTick sty (PromotedItemDataCon name)+ in+ if ticked+ then char '\''+ else empty instance NamedThing TyCon where getName = tyConName
compiler/GHC/Core/TyCon.hs-boot view
@@ -14,7 +14,6 @@ isTupleTyCon :: TyCon -> Bool isUnboxedTupleTyCon :: TyCon -> Bool-isFunTyCon :: TyCon -> Bool tyConRepName_maybe :: TyCon -> Maybe TyConRepName mkPrelTyConRepName :: Name -> TyConRepName
compiler/GHC/Core/Type.hs view
@@ -3,3940 +3,3308 @@ -- -- Type - public interface -{-# LANGUAGE FlexibleContexts, PatternSynonyms, ViewPatterns #-}-{-# LANGUAGE MagicHash #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}-{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}---- | Main functions for manipulating types and type-related things-module GHC.Core.Type (- -- Note some of this is just re-exports from TyCon..-- -- * Main data types representing Types- -- $type_classification-- -- $representation_types- Type, ArgFlag(..), AnonArgFlag(..),- Specificity(..),- KindOrType, PredType, ThetaType, FRRType,- Var, TyVar, isTyVar, TyCoVar, TyCoBinder, TyCoVarBinder, TyVarBinder,- Mult, Scaled,- KnotTied,-- -- ** Constructing and deconstructing types- mkTyVarTy, mkTyVarTys, getTyVar, getTyVar_maybe, repGetTyVar_maybe,- getCastedTyVar_maybe, tyVarKind, varType,-- mkAppTy, mkAppTys, splitAppTy, splitAppTys, repSplitAppTys,- splitAppTy_maybe, repSplitAppTy_maybe, tcRepSplitAppTy_maybe,-- mkFunTy, mkVisFunTy, mkInvisFunTy,- mkVisFunTys,- mkVisFunTyMany, mkInvisFunTyMany,- mkVisFunTysMany, mkInvisFunTysMany,- splitFunTy, splitFunTy_maybe,- splitFunTys, funResultTy, funArgTy,-- mkTyConApp, mkTyConTy, mkTYPEapp,- tyConAppTyCon_maybe, tyConAppTyConPicky_maybe,- tyConAppArgs_maybe, tyConAppTyCon, tyConAppArgs,- splitTyConApp_maybe, splitTyConApp, tyConAppArgN,- tcSplitTyConApp_maybe,- splitListTyConApp_maybe,- repSplitTyConApp_maybe,- tcRepSplitTyConApp_maybe,-- mkForAllTy, mkForAllTys, mkInvisForAllTys, mkTyCoInvForAllTys,- mkSpecForAllTy, mkSpecForAllTys,- mkVisForAllTys, mkTyCoInvForAllTy,- mkInfForAllTy, mkInfForAllTys,- splitForAllTyCoVars,- splitForAllReqTVBinders, splitForAllInvisTVBinders,- splitForAllTyCoVarBinders,- splitForAllTyCoVar_maybe, splitForAllTyCoVar,- splitForAllTyVar_maybe, splitForAllCoVar_maybe,- splitPiTy_maybe, splitPiTy, splitPiTys,- getRuntimeArgTys,- mkTyConBindersPreferAnon,- mkPiTy, mkPiTys,- piResultTy, piResultTys,- applyTysX, dropForAlls,- mkFamilyTyConApp,- buildSynTyCon,-- mkNumLitTy, isNumLitTy,- mkStrLitTy, isStrLitTy,- mkCharLitTy, isCharLitTy,- isLitTy,-- isPredTy,-- getRuntimeRep_maybe, kindRep_maybe, kindRep,-- mkCastTy, mkCoercionTy, splitCastTy_maybe,-- userTypeError_maybe, pprUserTypeErrorTy,-- coAxNthLHS,- stripCoercionTy,-- splitInvisPiTys, splitInvisPiTysN,- invisibleTyBndrCount,- filterOutInvisibleTypes, filterOutInferredTypes,- partitionInvisibleTypes, partitionInvisibles,- tyConArgFlags, appTyArgFlags,-- -- ** Analyzing types- TyCoMapper(..), mapTyCo, mapTyCoX,- TyCoFolder(..), foldTyCo, noView,-- -- (Newtypes)- newTyConInstRhs,-- -- ** Binders- sameVis,- mkTyCoVarBinder, mkTyCoVarBinders,- mkTyVarBinder, mkTyVarBinders,- tyVarSpecToBinders,- mkAnonBinder,- isAnonTyCoBinder,- binderVar, binderVars, binderType, binderArgFlag,- tyCoBinderType, tyCoBinderVar_maybe,- tyBinderType,- binderRelevantType_maybe,- isVisibleArgFlag, isInvisibleArgFlag, isVisibleBinder,- isInvisibleBinder, isNamedBinder,- tyConBindersTyCoBinders,-- -- ** Common type constructors- funTyCon, unrestrictedFunTyCon,-- -- ** Predicates on types- isTyVarTy, isFunTy, isCoercionTy,- isCoercionTy_maybe, isForAllTy,- isForAllTy_ty, isForAllTy_co,- isPiTy, isTauTy, isFamFreeTy,- isCoVarType, isAtomicTy,-- isValidJoinPointType,- tyConAppNeedsKindSig,-- -- *** Levity and boxity- typeLevity_maybe,- isLiftedTypeKind, isUnliftedTypeKind, pickyIsLiftedTypeKind,- isLiftedRuntimeRep, isUnliftedRuntimeRep, runtimeRepLevity_maybe,- isBoxedRuntimeRep,- isLiftedLevity, isUnliftedLevity,- isUnliftedType, isBoxedType, isUnboxedTupleType, isUnboxedSumType,- kindBoxedRepLevity_maybe,- mightBeLiftedType, mightBeUnliftedType,- isAlgType, isDataFamilyAppType,- isPrimitiveType, isStrictType,- isLevityTy, isLevityVar,- isRuntimeRepTy, isRuntimeRepVar, isRuntimeRepKindedTy,- dropRuntimeRepArgs,- getRuntimeRep, getLevity, getLevity_maybe,-- -- * Multiplicity-- isMultiplicityTy, isMultiplicityVar,- unrestricted, linear, tymult,- mkScaled, irrelevantMult, scaledSet,- pattern One, pattern Many,- isOneDataConTy, isManyDataConTy,- isLinearType,-- -- * Main data types representing Kinds- Kind,-- -- ** Finding the kind of a type- typeKind, tcTypeKind, typeHasFixedRuntimeRep, argsHaveFixedRuntimeRep,- tcIsLiftedTypeKind, tcIsConstraintKind, tcReturnsConstraintKind,- tcIsBoxedTypeKind, tcIsRuntimeTypeKind,-- -- ** Common Kind- liftedTypeKind, unliftedTypeKind,-- -- * Type free variables- tyCoFVsOfType, tyCoFVsBndr, tyCoFVsVarBndr, tyCoFVsVarBndrs,- tyCoVarsOfType, tyCoVarsOfTypes,- tyCoVarsOfTypeDSet,- coVarsOfType,- coVarsOfTypes,-- anyFreeVarsOfType, anyFreeVarsOfTypes,- noFreeVarsOfType,- splitVisVarsOfType, splitVisVarsOfTypes,- expandTypeSynonyms,- typeSize, occCheckExpand,-- -- ** Closing over kinds- closeOverKindsDSet, closeOverKindsList,- closeOverKinds,-- -- * Well-scoped lists of variables- scopedSort, tyCoVarsOfTypeWellScoped,- tyCoVarsOfTypesWellScoped,-- -- * Type comparison- eqType, eqTypeX, eqTypes, nonDetCmpType, nonDetCmpTypes, nonDetCmpTypeX,- nonDetCmpTypesX, nonDetCmpTc,- eqVarBndrs,-- -- * Forcing evaluation of types- seqType, seqTypes,-- -- * Other views onto Types- coreView, tcView,-- tyConsOfType,-- -- * Main type substitution data types- TvSubstEnv, -- Representation widely visible- IdSubstEnv,- Subst(..), -- Representation visible to a few friends-- -- ** Manipulating type substitutions- emptyTvSubstEnv, emptySubst, mkEmptySubst,-- mkSubst, zipTvSubst, mkTvSubstPrs,- zipTCvSubst,- notElemSubst,- getTvSubstEnv,- zapSubst, getSubstInScope, setInScope, getSubstRangeTyCoFVs,- extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet,- extendTCvSubst, extendCvSubst,- extendTvSubst, extendTvSubstBinderAndInScope,- extendTvSubstList, extendTvSubstAndInScope,- extendTCvSubstList,- extendTvSubstWithClone,- extendTCvSubstWithClone,- isInScope, composeTCvSubst, zipTyEnv, zipCoEnv,- isEmptySubst, unionSubst, isEmptyTCvSubst,-- -- ** Performing substitution on types and kinds- substTy, substTys, substScaledTy, substScaledTys, substTyWith, substTysWith, substTheta,- substTyAddInScope,- substTyUnchecked, substTysUnchecked, substScaledTyUnchecked, substScaledTysUnchecked,- substThetaUnchecked, substTyWithUnchecked,- substCo, substCoUnchecked, substCoWithUnchecked,- substTyVarBndr, substTyVarBndrs, substTyVar, substTyVars,- substVarBndr, substVarBndrs,- substTyCoBndr,- cloneTyVarBndr, cloneTyVarBndrs, lookupTyVar,-- -- * Tidying type related things up for printing- tidyType, tidyTypes,- tidyOpenType, tidyOpenTypes,- tidyVarBndr, tidyVarBndrs, tidyFreeTyCoVars,- tidyOpenTyCoVar, tidyOpenTyCoVars,- tidyTyCoVarOcc,- tidyTopType,- tidyTyCoVarBinder, tidyTyCoVarBinders,-- -- * Kinds- isConstraintKindCon,- classifiesTypeWithValues,- isConcrete, isFixedRuntimeRepKind,- ) where--import GHC.Prelude--import GHC.Types.Basic---- We import the representation and primitive functions from GHC.Core.TyCo.Rep.--- Many things are reexported, but not the representation!--import GHC.Core.TyCo.Rep-import GHC.Core.TyCo.Subst-import GHC.Core.TyCo.Tidy-import GHC.Core.TyCo.FVs---- friends:-import GHC.Types.Var-import GHC.Types.Var.Env-import GHC.Types.Var.Set-import GHC.Types.Unique.Set--import GHC.Core.TyCon-import GHC.Builtin.Types.Prim-import {-# SOURCE #-} GHC.Builtin.Types- ( charTy, naturalTy, listTyCon- , typeSymbolKind, liftedTypeKind, unliftedTypeKind- , liftedRepTy, unliftedRepTy, zeroBitRepTy- , boxedRepDataConTyCon- , constraintKind, zeroBitTypeKind- , unrestrictedFunTyCon- , manyDataConTy, oneDataConTy )-import GHC.Types.Name( Name )-import GHC.Builtin.Names-import GHC.Core.Coercion.Axiom-import {-# SOURCE #-} GHC.Core.Coercion- ( mkNomReflCo, mkGReflCo, mkReflCo- , mkTyConAppCo, mkAppCo, mkCoVarCo, mkAxiomRuleCo- , mkForAllCo, mkFunCo, mkAxiomInstCo, mkUnivCo- , mkSymCo, mkTransCo, mkNthCo, mkLRCo, mkInstCo- , mkKindCo, mkSubCo- , decomposePiCos, coercionKind, coercionLKind- , coercionRKind, coercionType- , isReflexiveCo, seqCo- , topNormaliseNewType_maybe- )-import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isConcreteTyVar )---- others-import GHC.Utils.Misc-import GHC.Utils.FV-import GHC.Utils.Outputable-import GHC.Utils.Panic-import GHC.Utils.Panic.Plain-import GHC.Data.FastString-import GHC.Data.Pair-import GHC.Data.List.SetOps-import GHC.Types.Unique ( nonDetCmpUnique )--import GHC.Base (reallyUnsafePtrEquality#)-import GHC.Data.Maybe ( orElse, expectJust, isJust )-import Control.Monad ( guard )-import qualified Data.Semigroup as S---- $type_classification--- #type_classification#------ Types are any, but at least one, of:------ [Boxed] Iff its representation is a pointer to an object on the--- GC'd heap. Operationally, heap objects can be entered as--- a means of evaluation.------ [Lifted] Iff it has bottom as an element: An instance of a--- lifted type might diverge when evaluated.--- GHC Haskell's unboxed types are unlifted.--- An unboxed, but lifted type is not very useful.--- (Example: A byte-represented type, where evaluating 0xff--- computes the 12345678th collatz number modulo 0xff.)--- Only lifted types may be unified with a type variable.------ [Algebraic] Iff it is a type with one or more constructors, whether--- declared with @data@ or @newtype@.--- An algebraic type is one that can be deconstructed--- with a case expression. There are algebraic types that--- are not lifted types, like unlifted data types or--- unboxed tuples.------ [Data] Iff it is a type declared with @data@, or a boxed tuple.--- There are also /unlifted/ data types.------ [Primitive] Iff it is a built-in type that can't be expressed in Haskell.------ [Unlifted] Anything that isn't lifted is considered unlifted.------ Currently, all primitive types are unlifted, but that's not necessarily--- the case: for example, @Int@ could be primitive.------ Some primitive types are unboxed, such as @Int#@, whereas some are boxed--- but unlifted (such as @ByteArray#@). The only primitive types that we--- classify as algebraic are the unboxed tuples.------ Some examples of type classifications that may make this a bit clearer are:------ @--- Type primitive boxed lifted algebraic--- -------------------------------------------------------------------------------- Int# Yes No No No--- ByteArray# Yes Yes No No--- (\# a, b \#) Yes No No Yes--- (\# a | b \#) Yes No No Yes--- ( a, b ) No Yes Yes Yes--- [a] No Yes Yes Yes--- @---- $representation_types--- A /source type/ is a type that is a separate type as far as the type checker is--- concerned, but which has a more low-level representation as far as Core-to-Core--- passes and the rest of the back end is concerned.------ You don't normally have to worry about this, as the utility functions in--- this module will automatically convert a source into a representation type--- if they are spotted, to the best of its abilities. If you don't want this--- to happen, use the equivalent functions from the "TcType" module.--{--************************************************************************-* *- Type representation-* *-************************************************************************--Note [coreView vs tcView]-~~~~~~~~~~~~~~~~~~~~~~~~~-So far as the typechecker is concerned, 'Constraint' and 'TYPE-LiftedRep' are distinct kinds.--But in Core these two are treated as identical.--We implement this by making 'coreView' convert 'Constraint' to 'TYPE-LiftedRep' on the fly. The function tcView (used in the type checker)-does not do this. Accordingly, tcView is used in type-checker-oriented-functions (including the pure unifier, used in instance resolution),-while coreView is used during e.g. optimisation passes.--See also #11715, which tracks removing this inconsistency.--In order to prevent users from discerning between Type and Constraint-(which could create inconsistent axioms -- see #21092), we say that-Type and Constraint are not SurelyApart in the pure unifier. See-GHC.Core.Unify.unify_ty, where this case produces MaybeApart.--One annoying consequence of this inconsistency is that we can get ill-kinded-updates to metavariables. #20356 is a case in point. Simplifying somewhat,-we end up with- [W] (alpha :: Constraint) ~ (Int :: Type)-This is heterogeneous, so we produce- [W] co :: (Constraint ~ Type)-and transform our original wanted to become- [W] alpha ~ Int |> sym co-in accordance with Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Canonical.-Our transformed wanted is now homogeneous (both sides have kind Constraint)-and so we unify alpha := Int |> sym co.--However, it's not so easy: when we build the cast (Int |> sym co), we actually-just get Int back. This is because we forbid reflexive casts (invariant (EQ2) of-Note [Respecting definitional equality] in GHC.Core.TyCo.Rep), and co looks-reflexive: it relates Type and Constraint, even though these are considered-identical in Core. Above, when we tried to say alpha := Int |> sym co, we-really ended up doing alpha := Int -- even though alpha :: Constraint and-Int :: Type have different kinds. Nothing has really gone wrong, though:-we still emitted [W] co :: (Constraint ~ Type), which will be insoluble-and lead to a decent error message. We simply need not to fall over at the-moment of unification, because all will be OK in the end. We thus use the-Core eqType, not the Haskell tcEqType, in the kind check for a meta-tyvar-unification in GHC.Tc.Utils.TcMType.writeMetaTyVarRef.---}---- | Gives the typechecker view of a type. This unwraps synonyms but--- leaves 'Constraint' alone. c.f. 'coreView', which turns 'Constraint' into--- 'Type'. Returns 'Nothing' if no unwrapping happens.--- See also Note [coreView vs tcView]-tcView :: Type -> Maybe Type-tcView (TyConApp tc tys)- | res@(Just _) <- expandSynTyConApp_maybe tc tys- = res-tcView _ = Nothing--- See Note [Inlining coreView].-{-# INLINE tcView #-}--coreView :: Type -> Maybe Type--- ^ This function strips off the /top layer only/ of a type synonym--- application (if any) its underlying representation type.--- Returns 'Nothing' if there is nothing to look through.--- This function considers 'Constraint' to be a synonym of @Type@.------ This function does not look through type family applications.------ By being non-recursive and inlined, this case analysis gets efficiently--- joined onto the case analysis that the caller is already doing-coreView ty@(TyConApp tc tys)- | res@(Just _) <- expandSynTyConApp_maybe tc tys- = res-- -- At the Core level, Constraint = Type- -- See Note [coreView vs tcView]- | isConstraintKindCon tc- = assertPpr (null tys) (ppr ty) $- Just liftedTypeKind--coreView _ = Nothing--- See Note [Inlining coreView].-{-# INLINE coreView #-}----------------------------------------------------- | @expandSynTyConApp_maybe tc tys@ expands the RHS of type synonym @tc@--- instantiated at arguments @tys@, or returns 'Nothing' if @tc@ is not a--- synonym.-expandSynTyConApp_maybe :: TyCon -> [Type] -> Maybe Type-{-# INLINE expandSynTyConApp_maybe #-}--- This INLINE will inline the call to expandSynTyConApp_maybe in coreView,--- which will eliminate the allocat ion Just/Nothing in the result--- Don't be tempted to make `expand_syn` (which is NOINLIN) return the--- Just/Nothing, else you'll increase allocation-expandSynTyConApp_maybe tc arg_tys- | Just (tvs, rhs) <- synTyConDefn_maybe tc- , arg_tys `lengthAtLeast` (tyConArity tc)- = Just (expand_syn tvs rhs arg_tys)- | otherwise- = Nothing---- | A helper for 'expandSynTyConApp_maybe' to avoid inlining this cold path--- into call-sites.------ Precondition: the call is saturated or over-saturated;--- i.e. length tvs <= length arg_tys-expand_syn :: [TyVar] -- ^ the variables bound by the synonym- -> Type -- ^ the RHS of the synonym- -> [Type] -- ^ the type arguments the synonym is instantiated at.- -> Type-{-# NOINLINE expand_syn #-} -- We never want to inline this cold-path.--expand_syn tvs rhs arg_tys- -- No substitution necessary if either tvs or tys is empty- -- This is both more efficient, and steers clear of an infinite- -- loop; see Note [Care using synonyms to compress types]- | null arg_tys = assert (null tvs) rhs- | null tvs = mkAppTys rhs arg_tys- | otherwise = go empty_subst tvs arg_tys- where- empty_subst = mkEmptySubst in_scope- in_scope = mkInScopeSet $ shallowTyCoVarsOfTypes $ arg_tys- -- The free vars of 'rhs' should all be bound by 'tenv',- -- so we only need the free vars of tys- -- See also Note [The substitution invariant] in GHC.Core.TyCo.Subst.-- go subst [] tys- | null tys = rhs' -- Exactly Saturated- | otherwise = mkAppTys rhs' tys- -- Its important to use mkAppTys, rather than (foldl AppTy),- -- because the function part might well return a- -- partially-applied type constructor; indeed, usually will!- where- rhs' = substTy subst rhs-- go subst (tv:tvs) (ty:tys) = go (extendTvSubst subst tv ty) tvs tys-- go _ (_:_) [] = pprPanic "expand_syn" (ppr tvs $$ ppr rhs $$ ppr arg_tys)- -- Under-saturated, precondition failed----coreFullView :: Type -> Type--- ^ Iterates 'coreView' until there is no more to synonym to expand.--- See Note [Inlining coreView].-coreFullView ty@(TyConApp tc _)- | isTypeSynonymTyCon tc || isConstraintKindCon tc = go ty- where- go ty- | Just ty' <- coreView ty = go ty'- | otherwise = ty--coreFullView ty = ty-{-# INLINE coreFullView #-}--{- Note [Inlining coreView]-~~~~~~~~~~~~~~~~~~~~~~~~~~~-It is very common to have a function-- f :: Type -> ...- f ty | Just ty' <- coreView ty = f ty'- f (TyVarTy ...) = ...- f ... = ...--If f is not otherwise recursive, the initial call to coreView-causes f to become recursive, which kills the possibility of-inlining. Instead, for non-recursive functions, we prefer to-use coreFullView, which guarantees to unwrap top-level type-synonyms. It can be inlined and is efficient and non-allocating-in its fast path. For this to really be fast, all calls made-on its fast path must also be inlined, linked back to this Note.--}--------------------------------------------------expandTypeSynonyms :: Type -> Type--- ^ Expand out all type synonyms. Actually, it'd suffice to expand out--- just the ones that discard type variables (e.g. type Funny a = Int)--- But we don't know which those are currently, so we just expand all.------ 'expandTypeSynonyms' only expands out type synonyms mentioned in the type,--- not in the kinds of any TyCon or TyVar mentioned in the type.------ Keep this synchronized with 'synonymTyConsOfType'-expandTypeSynonyms ty- = go (mkEmptySubst in_scope) ty- where- in_scope = mkInScopeSet (tyCoVarsOfType ty)-- go subst (TyConApp tc tys)- | ExpandsSyn tenv rhs tys' <- expandSynTyCon_maybe tc expanded_tys- = let subst' = mkTvSubst in_scope (mkVarEnv tenv)- -- Make a fresh substitution; rhs has nothing to- -- do with anything that has happened so far- -- NB: if you make changes here, be sure to build an- -- /idempotent/ substitution, even in the nested case- -- type T a b = a -> b- -- type S x y = T y x- -- (#11665)- in mkAppTys (go subst' rhs) tys'- | otherwise- = TyConApp tc expanded_tys- where- expanded_tys = (map (go subst) tys)-- go _ (LitTy l) = LitTy l- go subst (TyVarTy tv) = substTyVar subst tv- go subst (AppTy t1 t2) = mkAppTy (go subst t1) (go subst t2)- go subst ty@(FunTy _ mult arg res)- = ty { ft_mult = go subst mult, ft_arg = go subst arg, ft_res = go subst res }- go subst (ForAllTy (Bndr tv vis) t)- = let (subst', tv') = substVarBndrUsing go subst tv in- ForAllTy (Bndr tv' vis) (go subst' t)- go subst (CastTy ty co) = mkCastTy (go subst ty) (go_co subst co)- go subst (CoercionTy co) = mkCoercionTy (go_co subst co)-- go_mco _ MRefl = MRefl- go_mco subst (MCo co) = MCo (go_co subst co)-- go_co subst (Refl ty)- = mkNomReflCo (go subst ty)- go_co subst (GRefl r ty mco)- = mkGReflCo r (go subst ty) (go_mco subst mco)- -- NB: coercions are always expanded upon creation- go_co subst (TyConAppCo r tc args)- = mkTyConAppCo r tc (map (go_co subst) args)- go_co subst (AppCo co arg)- = mkAppCo (go_co subst co) (go_co subst arg)- go_co subst (ForAllCo tv kind_co co)- = let (subst', tv', kind_co') = go_cobndr subst tv kind_co in- mkForAllCo tv' kind_co' (go_co subst' co)- go_co subst (FunCo r w co1 co2)- = mkFunCo r (go_co subst w) (go_co subst co1) (go_co subst co2)- go_co subst (CoVarCo cv)- = substCoVar subst cv- go_co subst (AxiomInstCo ax ind args)- = mkAxiomInstCo ax ind (map (go_co subst) args)- go_co subst (UnivCo p r t1 t2)- = mkUnivCo (go_prov subst p) r (go subst t1) (go subst t2)- go_co subst (SymCo co)- = mkSymCo (go_co subst co)- go_co subst (TransCo co1 co2)- = mkTransCo (go_co subst co1) (go_co subst co2)- go_co subst (NthCo r n co)- = mkNthCo r n (go_co subst co)- go_co subst (LRCo lr co)- = mkLRCo lr (go_co subst co)- go_co subst (InstCo co arg)- = mkInstCo (go_co subst co) (go_co subst arg)- go_co subst (KindCo co)- = mkKindCo (go_co subst co)- go_co subst (SubCo co)- = mkSubCo (go_co subst co)- go_co subst (AxiomRuleCo ax cs)- = AxiomRuleCo ax (map (go_co subst) cs)- go_co _ (HoleCo h)- = pprPanic "expandTypeSynonyms hit a hole" (ppr h)-- go_prov subst (PhantomProv co) = PhantomProv (go_co subst co)- go_prov subst (ProofIrrelProv co) = ProofIrrelProv (go_co subst co)- go_prov _ p@(PluginProv _) = p- go_prov _ p@(CorePrepProv _) = p-- -- the "False" and "const" are to accommodate the type of- -- substForAllCoBndrUsing, which is general enough to- -- handle coercion optimization (which sometimes swaps the- -- order of a coercion)- go_cobndr subst = substForAllCoBndrUsing False (go_co subst) subst---- | An INLINE helper for function such as 'kindRep_maybe' below.------ @isTyConKeyApp_maybe key ty@ returns @Just tys@ iff--- the type @ty = T tys@, where T's unique = key-isTyConKeyApp_maybe :: Unique -> Type -> Maybe [Type]-isTyConKeyApp_maybe key ty- | TyConApp tc args <- coreFullView ty- , tc `hasKey` key- = Just args- | otherwise- = Nothing-{-# INLINE isTyConKeyApp_maybe #-}---- | Extract the RuntimeRep classifier of a type from its kind. For example,--- @kindRep * = LiftedRep@; Panics if this is not possible.--- Treats * and Constraint as the same-kindRep :: HasDebugCallStack => Kind -> RuntimeRepType-kindRep k = case kindRep_maybe k of- Just r -> r- Nothing -> pprPanic "kindRep" (ppr k)---- | Given a kind (TYPE rr), extract its RuntimeRep classifier rr.--- For example, @kindRep_maybe * = Just LiftedRep@--- Returns 'Nothing' if the kind is not of form (TYPE rr)--- Treats * and Constraint as the same-kindRep_maybe :: HasDebugCallStack => Kind -> Maybe RuntimeRepType-kindRep_maybe kind- | Just [arg] <- isTyConKeyApp_maybe tYPETyConKey kind = Just arg- | otherwise = Nothing---- | This version considers Constraint to be the same as *. Returns True--- if the argument is equivalent to Type/Constraint and False otherwise.--- See Note [Kind Constraint and kind Type]-isLiftedTypeKind :: Kind -> Bool-isLiftedTypeKind kind- = case kindRep_maybe kind of- Just rep -> isLiftedRuntimeRep rep- Nothing -> False--pickyIsLiftedTypeKind :: Kind -> Bool--- Checks whether the kind is literally--- TYPE LiftedRep--- or TYPE ('BoxedRep 'Lifted)--- or Type--- without expanding type synonyms or anything--- Used only when deciding whether to suppress the ":: *" in--- (a :: *) when printing kinded type variables--- See Note [Suppressing * kinds] in GHC.Core.TyCo.Ppr-pickyIsLiftedTypeKind kind- | TyConApp tc [arg] <- kind- , tc `hasKey` tYPETyConKey- , TyConApp rr_tc rr_args <- arg = case rr_args of- [] -> rr_tc `hasKey` liftedRepTyConKey- [rr_arg]- | rr_tc `hasKey` boxedRepDataConKey- , TyConApp lev [] <- rr_arg- , lev `hasKey` liftedDataConKey -> True- _ -> False- | TyConApp tc [] <- kind- , tc `hasKey` liftedTypeKindTyConKey = True- | otherwise = False---- | Returns True if the kind classifies unlifted types (like 'Int#') and False--- otherwise. Note that this returns False for representation-polymorphic--- kinds, which may be specialized to a kind that classifies unlifted types.-isUnliftedTypeKind :: Kind -> Bool-isUnliftedTypeKind kind- = case kindRep_maybe kind of- Just rep -> isUnliftedRuntimeRep rep- Nothing -> False---- | See 'isBoxedRuntimeRep_maybe'.-isBoxedRuntimeRep :: Type -> Bool-isBoxedRuntimeRep rep = isJust (isBoxedRuntimeRep_maybe rep)---- | `isBoxedRuntimeRep_maybe (rep :: RuntimeRep)` returns `Just lev` if `rep`--- expands to `Boxed lev` and returns `Nothing` otherwise.------ Types with this runtime rep are represented by pointers on the GC'd heap.-isBoxedRuntimeRep_maybe :: Type -> Maybe Type-isBoxedRuntimeRep_maybe rep- | Just [lev] <- isTyConKeyApp_maybe boxedRepDataConKey rep- = Just lev- | otherwise- = Nothing---- | Check whether a type of kind 'RuntimeRep' is lifted, unlifted, or unknown.------ @isLiftedRuntimeRep rr@ returns:------ * @Just Lifted@ if @rr@ is @LiftedRep :: RuntimeRep@--- * @Just Unlifted@ if @rr@ is definitely unlifted, e.g. @IntRep@--- * @Nothing@ if not known (e.g. it's a type variable or a type family application).-runtimeRepLevity_maybe :: Type -> Maybe Levity-runtimeRepLevity_maybe rep- | TyConApp rr_tc args <- coreFullView rep- , isPromotedDataCon rr_tc =- -- NB: args might be non-empty e.g. TupleRep [r1, .., rn]- if (rr_tc `hasKey` boxedRepDataConKey)- then case args of- [lev] | isLiftedLevity lev -> Just Lifted- | isUnliftedLevity lev -> Just Unlifted- _ -> Nothing- else Just Unlifted- -- Avoid searching all the unlifted RuntimeRep type cons- -- In the RuntimeRep data type, only LiftedRep is lifted- -- But be careful of type families (F tys) :: RuntimeRep,- -- hence the isPromotedDataCon rr_tc-runtimeRepLevity_maybe _ = Nothing---- | Check whether a kind is of the form @TYPE (BoxedRep Lifted)@--- or @TYPE (BoxedRep Unlifted)@.------ Returns:------ - @Just Lifted@ for @TYPE (BoxedRep Lifted)@ and @Type@,--- - @Just Unlifted@ for @TYPE (BoxedRep Unlifted)@ and @UnliftedType@,--- - @Nothing@ for anything else, e.g. @TYPE IntRep@, @TYPE (BoxedRep l)@, etc.-kindBoxedRepLevity_maybe :: Type -> Maybe Levity-kindBoxedRepLevity_maybe ty- | Just rep <- kindRep_maybe ty- , isBoxedRuntimeRep rep- = runtimeRepLevity_maybe rep- | otherwise- = Nothing---- | Check whether a type of kind 'RuntimeRep' is lifted.------ 'isLiftedRuntimeRep' is:------ * True of @LiftedRep :: RuntimeRep@--- * False of type variables, type family applications,--- and of other reps such as @IntRep :: RuntimeRep@.-isLiftedRuntimeRep :: Type -> Bool-isLiftedRuntimeRep rep =- runtimeRepLevity_maybe rep == Just Lifted---- | Check whether a type of kind 'RuntimeRep' is unlifted.------ * True of definitely unlifted 'RuntimeRep's such as--- 'UnliftedRep', 'IntRep', 'FloatRep', ...--- * False of 'LiftedRep',--- * False for type variables and type family applications.-isUnliftedRuntimeRep :: Type -> Bool-isUnliftedRuntimeRep rep =- runtimeRepLevity_maybe rep == Just Unlifted---- | An INLINE helper for functions such as 'isLiftedLevity' and 'isUnliftedLevity'.------ Checks whether the type is a nullary 'TyCon' application,--- for a 'TyCon' with the given 'Unique'.-isNullaryTyConKeyApp :: Unique -> Type -> Bool-isNullaryTyConKeyApp key ty- | Just args <- isTyConKeyApp_maybe key ty- = assert (null args) True- | otherwise- = False-{-# INLINE isNullaryTyConKeyApp #-}--isLiftedLevity :: Type -> Bool-isLiftedLevity = isNullaryTyConKeyApp liftedDataConKey--isUnliftedLevity :: Type -> Bool-isUnliftedLevity = isNullaryTyConKeyApp unliftedDataConKey---- | Is this the type 'Levity'?-isLevityTy :: Type -> Bool-isLevityTy = isNullaryTyConKeyApp levityTyConKey---- | Is this the type 'RuntimeRep'?-isRuntimeRepTy :: Type -> Bool-isRuntimeRepTy = isNullaryTyConKeyApp runtimeRepTyConKey---- | Is a tyvar of type 'RuntimeRep'?-isRuntimeRepVar :: TyVar -> Bool-isRuntimeRepVar = isRuntimeRepTy . tyVarKind---- | Is a tyvar of type 'Levity'?-isLevityVar :: TyVar -> Bool-isLevityVar = isLevityTy . tyVarKind---- | Is this the type 'Multiplicity'?-isMultiplicityTy :: Type -> Bool-isMultiplicityTy = isNullaryTyConKeyApp multiplicityTyConKey---- | Is a tyvar of type 'Multiplicity'?-isMultiplicityVar :: TyVar -> Bool-isMultiplicityVar = isMultiplicityTy . tyVarKind--{- *********************************************************************-* *- mapType-* *-************************************************************************--These functions do a map-like operation over types, performing some operation-on all variables and binding sites. Primarily used for zonking.--Note [Efficiency for ForAllCo case of mapTyCoX]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-As noted in Note [Forall coercions] in GHC.Core.TyCo.Rep, a ForAllCo is a bit redundant.-It stores a TyCoVar and a Coercion, where the kind of the TyCoVar always matches-the left-hand kind of the coercion. This is convenient lots of the time, but-not when mapping a function over a coercion.--The problem is that tcm_tybinder will affect the TyCoVar's kind and-mapCoercion will affect the Coercion, and we hope that the results will be-the same. Even if they are the same (which should generally happen with-correct algorithms), then there is an efficiency issue. In particular,-this problem seems to make what should be a linear algorithm into a potentially-exponential one. But it's only going to be bad in the case where there's-lots of foralls in the kinds of other foralls. Like this:-- forall a : (forall b : (forall c : ...). ...). ...--This construction seems unlikely. So we'll do the inefficient, easy way-for now.--Note [Specialising mappers]-~~~~~~~~~~~~~~~~~~~~~~~~~~~-These INLINE pragmas are indispensable. mapTyCo and mapTyCoX are used-to implement zonking, and it's vital that they get specialised to the TcM-monad and the particular mapper in use.--Even specialising to the monad alone made a 20% allocation difference-in perf/compiler/T5030.--See Note [Specialising foldType] in "GHC.Core.TyCo.Rep" for more details of this-idiom.--}---- | This describes how a "map" operation over a type/coercion should behave-data TyCoMapper env m- = TyCoMapper- { tcm_tyvar :: env -> TyVar -> m Type- , tcm_covar :: env -> CoVar -> m Coercion- , tcm_hole :: env -> CoercionHole -> m Coercion- -- ^ What to do with coercion holes.- -- See Note [Coercion holes] in "GHC.Core.TyCo.Rep".-- , tcm_tycobinder :: env -> TyCoVar -> ArgFlag -> m (env, TyCoVar)- -- ^ The returned env is used in the extended scope-- , tcm_tycon :: TyCon -> m TyCon- -- ^ This is used only for TcTyCons- -- a) To zonk TcTyCons- -- b) To turn TcTyCons into TyCons.- -- See Note [Type checking recursive type and class declarations]- -- in "GHC.Tc.TyCl"- }--{-# INLINE mapTyCo #-} -- See Note [Specialising mappers]-mapTyCo :: Monad m => TyCoMapper () m- -> ( Type -> m Type- , [Type] -> m [Type]- , Coercion -> m Coercion- , [Coercion] -> m[Coercion])-mapTyCo mapper- = case mapTyCoX mapper of- (go_ty, go_tys, go_co, go_cos)- -> (go_ty (), go_tys (), go_co (), go_cos ())--{-# INLINE mapTyCoX #-} -- See Note [Specialising mappers]-mapTyCoX :: Monad m => TyCoMapper env m- -> ( env -> Type -> m Type- , env -> [Type] -> m [Type]- , env -> Coercion -> m Coercion- , env -> [Coercion] -> m[Coercion])-mapTyCoX (TyCoMapper { tcm_tyvar = tyvar- , tcm_tycobinder = tycobinder- , tcm_tycon = tycon- , tcm_covar = covar- , tcm_hole = cohole })- = (go_ty, go_tys, go_co, go_cos)- where- go_tys _ [] = return []- go_tys env (ty:tys) = (:) <$> go_ty env ty <*> go_tys env tys-- go_ty env (TyVarTy tv) = tyvar env tv- go_ty env (AppTy t1 t2) = mkAppTy <$> go_ty env t1 <*> go_ty env t2- go_ty _ ty@(LitTy {}) = return ty- go_ty env (CastTy ty co) = mkCastTy <$> go_ty env ty <*> go_co env co- go_ty env (CoercionTy co) = CoercionTy <$> go_co env co-- go_ty env ty@(FunTy _ w arg res)- = do { w' <- go_ty env w; arg' <- go_ty env arg; res' <- go_ty env res- ; return (ty { ft_mult = w', ft_arg = arg', ft_res = res' }) }-- go_ty env ty@(TyConApp tc tys)- | isTcTyCon tc- = do { tc' <- tycon tc- ; mkTyConApp tc' <$> go_tys env tys }-- -- Not a TcTyCon- | null tys -- Avoid allocation in this very- = return ty -- common case (E.g. Int, LiftedRep etc)-- | otherwise- = mkTyConApp tc <$> go_tys env tys-- go_ty env (ForAllTy (Bndr tv vis) inner)- = do { (env', tv') <- tycobinder env tv vis- ; inner' <- go_ty env' inner- ; return $ ForAllTy (Bndr tv' vis) inner' }-- go_cos _ [] = return []- go_cos env (co:cos) = (:) <$> go_co env co <*> go_cos env cos-- go_mco _ MRefl = return MRefl- go_mco env (MCo co) = MCo <$> (go_co env co)-- go_co env (Refl ty) = Refl <$> go_ty env ty- go_co env (GRefl r ty mco) = mkGReflCo r <$> go_ty env ty <*> go_mco env mco- go_co env (AppCo c1 c2) = mkAppCo <$> go_co env c1 <*> go_co env c2- go_co env (FunCo r cw c1 c2) = mkFunCo r <$> go_co env cw <*> go_co env c1 <*> go_co env c2- go_co env (CoVarCo cv) = covar env cv- go_co env (HoleCo hole) = cohole env hole- go_co env (UnivCo p r t1 t2) = mkUnivCo <$> go_prov env p <*> pure r- <*> go_ty env t1 <*> go_ty env t2- go_co env (SymCo co) = mkSymCo <$> go_co env co- go_co env (TransCo c1 c2) = mkTransCo <$> go_co env c1 <*> go_co env c2- go_co env (AxiomRuleCo r cos) = AxiomRuleCo r <$> go_cos env cos- go_co env (NthCo r i co) = mkNthCo r i <$> go_co env co- go_co env (LRCo lr co) = mkLRCo lr <$> go_co env co- go_co env (InstCo co arg) = mkInstCo <$> go_co env co <*> go_co env arg- go_co env (KindCo co) = mkKindCo <$> go_co env co- go_co env (SubCo co) = mkSubCo <$> go_co env co- go_co env (AxiomInstCo ax i cos) = mkAxiomInstCo ax i <$> go_cos env cos- go_co env co@(TyConAppCo r tc cos)- | isTcTyCon tc- = do { tc' <- tycon tc- ; mkTyConAppCo r tc' <$> go_cos env cos }-- -- Not a TcTyCon- | null cos -- Avoid allocation in this very- = return co -- common case (E.g. Int, LiftedRep etc)-- | otherwise- = mkTyConAppCo r tc <$> go_cos env cos- go_co env (ForAllCo tv kind_co co)- = do { kind_co' <- go_co env kind_co- ; (env', tv') <- tycobinder env tv Inferred- ; co' <- go_co env' co- ; return $ mkForAllCo tv' kind_co' co' }- -- See Note [Efficiency for ForAllCo case of mapTyCoX]-- go_prov env (PhantomProv co) = PhantomProv <$> go_co env co- go_prov env (ProofIrrelProv co) = ProofIrrelProv <$> go_co env co- go_prov _ p@(PluginProv _) = return p- go_prov _ p@(CorePrepProv _) = return p---{--************************************************************************-* *-\subsection{Constructor-specific functions}-* *-************************************************************************------------------------------------------------------------------------- TyVarTy- ~~~~~~~--}---- | Attempts to obtain the type variable underlying a 'Type', and panics with the--- given message if this is not a type variable type. See also 'getTyVar_maybe'-getTyVar :: String -> Type -> TyVar-getTyVar msg ty = case getTyVar_maybe ty of- Just tv -> tv- Nothing -> panic ("getTyVar: " ++ msg)--isTyVarTy :: Type -> Bool-isTyVarTy ty = isJust (getTyVar_maybe ty)---- | Attempts to obtain the type variable underlying a 'Type'-getTyVar_maybe :: Type -> Maybe TyVar-getTyVar_maybe = repGetTyVar_maybe . coreFullView---- | If the type is a tyvar, possibly under a cast, returns it, along--- with the coercion. Thus, the co is :: kind tv ~N kind ty-getCastedTyVar_maybe :: Type -> Maybe (TyVar, CoercionN)-getCastedTyVar_maybe ty = case coreFullView ty of- CastTy (TyVarTy tv) co -> Just (tv, co)- TyVarTy tv -> Just (tv, mkReflCo Nominal (tyVarKind tv))- _ -> Nothing---- | Attempts to obtain the type variable underlying a 'Type', without--- any expansion-repGetTyVar_maybe :: Type -> Maybe TyVar-repGetTyVar_maybe (TyVarTy tv) = Just tv-repGetTyVar_maybe _ = Nothing--{------------------------------------------------------------------------ AppTy- ~~~~~-We need to be pretty careful with AppTy to make sure we obey the-invariant that a TyConApp is always visibly so. mkAppTy maintains the-invariant: use it.--Note [Decomposing fat arrow c=>t]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Can we unify (a b) with (Eq a => ty)? If we do so, we end up with-a partial application like ((=>) Eq a) which doesn't make sense in-source Haskell. In contrast, we *can* unify (a b) with (t1 -> t2).-Here's an example (#9858) of how you might do it:- i :: (Typeable a, Typeable b) => Proxy (a b) -> TypeRep- i p = typeRep p-- j = i (Proxy :: Proxy (Eq Int => Int))-The type (Proxy (Eq Int => Int)) is only accepted with -XImpredicativeTypes,-but suppose we want that. But then in the call to 'i', we end-up decomposing (Eq Int => Int), and we definitely don't want that.--This really only applies to the type checker; in Core, '=>' and '->'-are the same, as are 'Constraint' and '*'. But for now I've put-the test in repSplitAppTy_maybe, which applies throughout, because-the other calls to splitAppTy are in GHC.Core.Unify, which is also used by-the type checker (e.g. when matching type-function equations).---}---- | Applies a type to another, as in e.g. @k a@-mkAppTy :: Type -> Type -> Type- -- See Note [Respecting definitional equality], invariant (EQ1).-mkAppTy (CastTy fun_ty co) arg_ty- | ([arg_co], res_co) <- decomposePiCos co (coercionKind co) [arg_ty]- = (fun_ty `mkAppTy` (arg_ty `mkCastTy` arg_co)) `mkCastTy` res_co--mkAppTy (TyConApp tc tys) ty2 = mkTyConApp tc (tys ++ [ty2])-mkAppTy ty1 ty2 = AppTy ty1 ty2- -- Note that the TyConApp could be an- -- under-saturated type synonym. GHC allows that; e.g.- -- type Foo k = k a -> k a- -- type Id x = x- -- foo :: Foo Id -> Foo Id- --- -- Here Id is partially applied in the type sig for Foo,- -- but once the type synonyms are expanded all is well- --- -- Moreover in GHC.Tc.Types.tcInferTyApps we build up a type- -- (T t1 t2 t3) one argument at a type, thus forming- -- (T t1), (T t1 t2), etc--mkAppTys :: Type -> [Type] -> Type-mkAppTys ty1 [] = ty1-mkAppTys (CastTy fun_ty co) arg_tys -- much more efficient then nested mkAppTy- -- Why do this? See (EQ1) of- -- Note [Respecting definitional equality]- -- in GHC.Core.TyCo.Rep- = foldl' AppTy ((mkAppTys fun_ty casted_arg_tys) `mkCastTy` res_co) leftovers- where- (arg_cos, res_co) = decomposePiCos co (coercionKind co) arg_tys- (args_to_cast, leftovers) = splitAtList arg_cos arg_tys- casted_arg_tys = zipWith mkCastTy args_to_cast arg_cos-mkAppTys (TyConApp tc tys1) tys2 = mkTyConApp tc (tys1 ++ tys2)-mkAppTys ty1 tys2 = foldl' AppTy ty1 tys2----------------splitAppTy_maybe :: Type -> Maybe (Type, Type)--- ^ Attempt to take a type application apart, whether it is a--- function, type constructor, or plain type application. Note--- that type family applications are NEVER unsaturated by this!-splitAppTy_maybe = repSplitAppTy_maybe . coreFullView----------------repSplitAppTy_maybe :: HasDebugCallStack => Type -> Maybe (Type,Type)--- ^ Does the AppTy split as in 'splitAppTy_maybe', but assumes that--- any Core view stuff is already done-repSplitAppTy_maybe (FunTy _ w ty1 ty2)- = Just (TyConApp funTyCon [w, rep1, rep2, ty1], ty2)- where- rep1 = getRuntimeRep ty1- rep2 = getRuntimeRep ty2--repSplitAppTy_maybe (AppTy ty1 ty2)- = Just (ty1, ty2)--repSplitAppTy_maybe (TyConApp tc tys)- | not (mustBeSaturated tc) || tys `lengthExceeds` tyConArity tc- , Just (tys', ty') <- snocView tys- = Just (TyConApp tc tys', ty') -- Never create unsaturated type family apps!--repSplitAppTy_maybe _other = Nothing---- This one doesn't break apart (c => t).--- See Note [Decomposing fat arrow c=>t]--- Defined here to avoid module loops between Unify and TcType.-tcRepSplitAppTy_maybe :: Type -> Maybe (Type,Type)--- ^ Does the AppTy split as in 'tcSplitAppTy_maybe', but assumes that--- any coreView stuff is already done. Refuses to look through (c => t)-tcRepSplitAppTy_maybe (FunTy { ft_af = af, ft_mult = w, ft_arg = ty1, ft_res = ty2 })- | VisArg <- af -- See Note [Decomposing fat arrow c=>t]-- -- See Note [The Purely Kinded Type Invariant (PKTI)] in GHC.Tc.Gen.HsType,- -- Wrinkle around FunTy- , Just rep1 <- getRuntimeRep_maybe ty1- , Just rep2 <- getRuntimeRep_maybe ty2- = Just (TyConApp funTyCon [w, rep1, rep2, ty1], ty2)-- | otherwise- = Nothing--tcRepSplitAppTy_maybe (AppTy ty1 ty2) = Just (ty1, ty2)-tcRepSplitAppTy_maybe (TyConApp tc tys)- | not (mustBeSaturated tc) || tys `lengthExceeds` tyConArity tc- , Just (tys', ty') <- snocView tys- = Just (TyConApp tc tys', ty') -- Never create unsaturated type family apps!-tcRepSplitAppTy_maybe _other = Nothing----------------splitAppTy :: Type -> (Type, Type)--- ^ Attempts to take a type application apart, as in 'splitAppTy_maybe',--- and panics if this is not possible-splitAppTy ty = case splitAppTy_maybe ty of- Just pr -> pr- Nothing -> panic "splitAppTy"----------------splitAppTys :: Type -> (Type, [Type])--- ^ Recursively splits a type as far as is possible, leaving a residual--- type being applied to and the type arguments applied to it. Never fails,--- even if that means returning an empty list of type applications.-splitAppTys ty = split ty ty []- where- split orig_ty ty args | Just ty' <- coreView ty = split orig_ty ty' args- split _ (AppTy ty arg) args = split ty ty (arg:args)- split _ (TyConApp tc tc_args) args- = let -- keep type families saturated- n | mustBeSaturated tc = tyConArity tc- | otherwise = 0- (tc_args1, tc_args2) = splitAt n tc_args- in- (TyConApp tc tc_args1, tc_args2 ++ args)- split _ (FunTy _ w ty1 ty2) args- = assert (null args )- (TyConApp funTyCon [], [w, rep1, rep2, ty1, ty2])- where- rep1 = getRuntimeRep ty1- rep2 = getRuntimeRep ty2-- split orig_ty _ args = (orig_ty, args)---- | Like 'splitAppTys', but doesn't look through type synonyms-repSplitAppTys :: HasDebugCallStack => Type -> (Type, [Type])-repSplitAppTys ty = split ty []- where- split (AppTy ty arg) args = split ty (arg:args)- split (TyConApp tc tc_args) args- = let n | mustBeSaturated tc = tyConArity tc- | otherwise = 0- (tc_args1, tc_args2) = splitAt n tc_args- in- (TyConApp tc tc_args1, tc_args2 ++ args)- split (FunTy _ w ty1 ty2) args- = assert (null args )- (TyConApp funTyCon [], [w, rep1, rep2, ty1, ty2])- where- rep1 = getRuntimeRep ty1- rep2 = getRuntimeRep ty2-- split ty args = (ty, args)--{-- LitTy- ~~~~~--}--mkNumLitTy :: Integer -> Type-mkNumLitTy n = LitTy (NumTyLit n)---- | Is this a numeric literal. We also look through type synonyms.-isNumLitTy :: Type -> Maybe Integer-isNumLitTy ty- | LitTy (NumTyLit n) <- coreFullView ty = Just n- | otherwise = Nothing--mkStrLitTy :: FastString -> Type-mkStrLitTy s = LitTy (StrTyLit s)---- | Is this a symbol literal. We also look through type synonyms.-isStrLitTy :: Type -> Maybe FastString-isStrLitTy ty- | LitTy (StrTyLit s) <- coreFullView ty = Just s- | otherwise = Nothing--mkCharLitTy :: Char -> Type-mkCharLitTy c = LitTy (CharTyLit c)---- | Is this a char literal? We also look through type synonyms.-isCharLitTy :: Type -> Maybe Char-isCharLitTy ty- | LitTy (CharTyLit s) <- coreFullView ty = Just s- | otherwise = Nothing----- | Is this a type literal (symbol, numeric, or char)?-isLitTy :: Type -> Maybe TyLit-isLitTy ty- | LitTy l <- coreFullView ty = Just l- | otherwise = Nothing---- | Is this type a custom user error?--- If so, give us the kind and the error message.-userTypeError_maybe :: Type -> Maybe Type-userTypeError_maybe t- = do { (tc, _kind : msg : _) <- splitTyConApp_maybe t- -- There may be more than 2 arguments, if the type error is- -- used as a type constructor (e.g. at kind `Type -> Type`).-- ; guard (tyConName tc == errorMessageTypeErrorFamName)- ; return msg }---- | Render a type corresponding to a user type error into a SDoc.-pprUserTypeErrorTy :: Type -> SDoc-pprUserTypeErrorTy ty =- case splitTyConApp_maybe ty of-- -- Text "Something"- Just (tc,[txt])- | tyConName tc == typeErrorTextDataConName- , Just str <- isStrLitTy txt -> ftext str-- -- ShowType t- Just (tc,[_k,t])- | tyConName tc == typeErrorShowTypeDataConName -> ppr t-- -- t1 :<>: t2- Just (tc,[t1,t2])- | tyConName tc == typeErrorAppendDataConName ->- pprUserTypeErrorTy t1 <> pprUserTypeErrorTy t2-- -- t1 :$$: t2- Just (tc,[t1,t2])- | tyConName tc == typeErrorVAppendDataConName ->- pprUserTypeErrorTy t1 $$ pprUserTypeErrorTy t2-- -- An unevaluated type function- _ -> ppr ty-----{------------------------------------------------------------------------ FunTy- ~~~~~--Note [Representation of function types]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--Functions (e.g. Int -> Char) can be thought of as being applications-of funTyCon (known in Haskell surface syntax as (->)), (note that-`RuntimeRep' quantifiers are left inferred)-- (->) :: forall {r1 :: RuntimeRep} {r2 :: RuntimeRep}- (a :: TYPE r1) (b :: TYPE r2).- a -> b -> Type--However, for efficiency's sake we represent saturated applications of (->)-with FunTy. For instance, the type,-- (->) r1 r2 a b--is equivalent to,-- FunTy (Anon a) b--Note how the RuntimeReps are implied in the FunTy representation. For this-reason we must be careful when reconstructing the TyConApp representation (see,-for instance, splitTyConApp_maybe).--In the compiler we maintain the invariant that all saturated applications of-(->) are represented with FunTy.--See #11714.--}--splitFunTy :: Type -> (Mult, Type, Type)--- ^ Attempts to extract the multiplicity, argument and result types from a type,--- and panics if that is not possible. See also 'splitFunTy_maybe'-splitFunTy = expectJust "splitFunTy" . splitFunTy_maybe--{-# INLINE splitFunTy_maybe #-}-splitFunTy_maybe :: Type -> Maybe (Mult, Type, Type)--- ^ Attempts to extract the multiplicity, argument and result types from a type-splitFunTy_maybe ty- | FunTy _ w arg res <- coreFullView ty = Just (w, arg, res)- | otherwise = Nothing--splitFunTys :: Type -> ([Scaled Type], Type)-splitFunTys ty = split [] ty ty- where- -- common case first- split args _ (FunTy _ w arg res) = split ((Scaled w arg):args) res res- split args orig_ty ty | Just ty' <- coreView ty = split args orig_ty ty'- split args orig_ty _ = (reverse args, orig_ty)--funResultTy :: Type -> Type--- ^ Extract the function result type and panic if that is not possible-funResultTy ty- | FunTy { ft_res = res } <- coreFullView ty = res- | otherwise = pprPanic "funResultTy" (ppr ty)--funArgTy :: Type -> Type--- ^ Extract the function argument type and panic if that is not possible-funArgTy ty- | FunTy { ft_arg = arg } <- coreFullView ty = arg- | otherwise = pprPanic "funArgTy" (ppr ty)---- ^ Just like 'piResultTys' but for a single argument--- Try not to iterate 'piResultTy', because it's inefficient to substitute--- one variable at a time; instead use 'piResultTys"-piResultTy :: HasDebugCallStack => Type -> Type -> Type-piResultTy ty arg = case piResultTy_maybe ty arg of- Just res -> res- Nothing -> pprPanic "piResultTy" (ppr ty $$ ppr arg)--piResultTy_maybe :: Type -> Type -> Maybe Type--- We don't need a 'tc' version, because--- this function behaves the same for Type and Constraint-piResultTy_maybe ty arg = case coreFullView ty of- FunTy { ft_res = res } -> Just res-- ForAllTy (Bndr tv _) res- -> let empty_subst = mkEmptySubst $ mkInScopeSet $- tyCoVarsOfTypes [arg,res]- in Just (substTy (extendTCvSubst empty_subst tv arg) res)-- _ -> Nothing---- | (piResultTys f_ty [ty1, .., tyn]) gives the type of (f ty1 .. tyn)--- where f :: f_ty--- 'piResultTys' is interesting because:--- 1. 'f_ty' may have more for-alls than there are args--- 2. Less obviously, it may have fewer for-alls--- For case 2. think of:--- piResultTys (forall a.a) [forall b.b, Int]--- This really can happen, but only (I think) in situations involving--- undefined. For example:--- undefined :: forall a. a--- Term: undefined @(forall b. b->b) @Int--- This term should have type (Int -> Int), but notice that--- there are more type args than foralls in 'undefined's type.---- If you edit this function, you may need to update the GHC formalism--- See Note [GHC Formalism] in GHC.Core.Lint---- This is a heavily used function (e.g. from typeKind),--- so we pay attention to efficiency, especially in the special case--- where there are no for-alls so we are just dropping arrows from--- a function type/kind.-piResultTys :: HasDebugCallStack => Type -> [Type] -> Type-piResultTys ty [] = ty-piResultTys ty orig_args@(arg:args)- | FunTy { ft_res = res } <- ty- = piResultTys res args-- | ForAllTy (Bndr tv _) res <- ty- = go (extendTCvSubst init_subst tv arg) res args-- | Just ty' <- coreView ty- = piResultTys ty' orig_args-- | otherwise- = pprPanic "piResultTys1" (ppr ty $$ ppr orig_args)- where- init_subst = mkEmptySubst $ mkInScopeSet (tyCoVarsOfTypes (ty:orig_args))-- go :: Subst -> Type -> [Type] -> Type- go subst ty [] = substTyUnchecked subst ty-- go subst ty all_args@(arg:args)- | FunTy { ft_res = res } <- ty- = go subst res args-- | ForAllTy (Bndr tv _) res <- ty- = go (extendTCvSubst subst tv arg) res args-- | Just ty' <- coreView ty- = go subst ty' all_args-- | not (isEmptyTCvSubst subst) -- See Note [Care with kind instantiation]- = go init_subst- (substTy subst ty)- all_args-- | otherwise- = -- We have not run out of arguments, but the function doesn't- -- have the right kind to apply to them; so panic.- -- Without the explicit isEmptyVarEnv test, an ill-kinded type- -- would give an infinite loop, which is very unhelpful- -- c.f. #15473- pprPanic "piResultTys2" (ppr ty $$ ppr orig_args $$ ppr all_args)--applyTysX :: [TyVar] -> Type -> [Type] -> Type--- applyTysX beta-reduces (/\tvs. body_ty) arg_tys--- Assumes that (/\tvs. body_ty) is closed-applyTysX tvs body_ty arg_tys- = assertPpr (tvs `leLength` arg_tys) pp_stuff $- assertPpr (tyCoVarsOfType body_ty `subVarSet` mkVarSet tvs) pp_stuff $- mkAppTys (substTyWith tvs arg_tys_prefix body_ty)- arg_tys_rest- where- pp_stuff = vcat [ppr tvs, ppr body_ty, ppr arg_tys]- (arg_tys_prefix, arg_tys_rest) = splitAtList tvs arg_tys----{- Note [Care with kind instantiation]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Suppose we have- T :: forall k. k-and we are finding the kind of- T (forall b. b -> b) * Int-Then- T (forall b. b->b) :: k[ k :-> forall b. b->b]- :: forall b. b -> b-So- T (forall b. b->b) * :: (b -> b)[ b :-> *]- :: * -> *--In other words we must instantiate the forall!--Similarly (#15428)- S :: forall k f. k -> f k-and we are finding the kind of- S * (* ->) Int Bool-We have- S * (* ->) :: (k -> f k)[ k :-> *, f :-> (* ->)]- :: * -> * -> *-So again we must instantiate.--The same thing happens in GHC.CoreToIface.toIfaceAppArgsX.------------------------------------------------------------------------ TyConApp- ~~~~~~~~--}---- splitTyConApp "looks through" synonyms, because they don't--- mean a distinct type, but all other type-constructor applications--- including functions are returned as Just ..---- | Retrieve the tycon heading this type, if there is one. Does /not/--- look through synonyms.-tyConAppTyConPicky_maybe :: Type -> Maybe TyCon-tyConAppTyConPicky_maybe (TyConApp tc _) = Just tc-tyConAppTyConPicky_maybe (FunTy {}) = Just funTyCon-tyConAppTyConPicky_maybe _ = Nothing----- | The same as @fst . splitTyConApp@-{-# INLINE tyConAppTyCon_maybe #-}-tyConAppTyCon_maybe :: Type -> Maybe TyCon-tyConAppTyCon_maybe ty = case coreFullView ty of- TyConApp tc _ -> Just tc- FunTy {} -> Just funTyCon- _ -> Nothing--tyConAppTyCon :: HasDebugCallStack => Type -> TyCon-tyConAppTyCon ty = tyConAppTyCon_maybe ty `orElse` pprPanic "tyConAppTyCon" (ppr ty)---- | The same as @snd . splitTyConApp@-tyConAppArgs_maybe :: Type -> Maybe [Type]-tyConAppArgs_maybe ty = case coreFullView ty of- TyConApp _ tys -> Just tys- FunTy _ w arg res- | Just rep1 <- getRuntimeRep_maybe arg- , Just rep2 <- getRuntimeRep_maybe res- -> Just [w, rep1, rep2, arg, res]- _ -> Nothing--tyConAppArgs :: HasCallStack => Type -> [Type]-tyConAppArgs ty = tyConAppArgs_maybe ty `orElse` pprPanic "tyConAppArgs" (ppr ty)--tyConAppArgN :: Int -> Type -> Type--- Executing Nth-tyConAppArgN n ty- = case tyConAppArgs_maybe ty of- Just tys -> tys `getNth` n- Nothing -> pprPanic "tyConAppArgN" (ppr n <+> ppr ty)---- | Attempts to tease a type apart into a type constructor and the application--- of a number of arguments to that constructor. Panics if that is not possible.--- See also 'splitTyConApp_maybe'-splitTyConApp :: Type -> (TyCon, [Type])-splitTyConApp ty = case splitTyConApp_maybe ty of- Just stuff -> stuff- Nothing -> pprPanic "splitTyConApp" (ppr ty)---- | Attempts to tease a type apart into a type constructor and the application--- of a number of arguments to that constructor-splitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type])-splitTyConApp_maybe = repSplitTyConApp_maybe . coreFullView---- | Split a type constructor application into its type constructor and--- applied types. Note that this may fail in the case of a 'FunTy' with an--- argument of unknown kind 'FunTy' (e.g. @FunTy (a :: k) Int@. since the kind--- of @a@ isn't of the form @TYPE rep@). Consequently, you may need to zonk your--- type before using this function.------ This does *not* split types headed with (=>), as that's not a TyCon in the--- type-checker.------ If you only need the 'TyCon', consider using 'tcTyConAppTyCon_maybe'.-tcSplitTyConApp_maybe :: HasCallStack => Type -> Maybe (TyCon, [Type])--- Defined here to avoid module loops between Unify and TcType.-tcSplitTyConApp_maybe ty | Just ty' <- tcView ty = tcSplitTyConApp_maybe ty'- | otherwise = tcRepSplitTyConApp_maybe ty----------------------repSplitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type])--- ^ Like 'splitTyConApp_maybe', but doesn't look through synonyms. This--- assumes the synonyms have already been dealt with.-repSplitTyConApp_maybe (TyConApp tc tys) = Just (tc, tys)-repSplitTyConApp_maybe (FunTy _ w arg res)- -- NB: we're in Core, so no check for VisArg- = Just (funTyCon, [w, arg_rep, res_rep, arg, res])- where- arg_rep = getRuntimeRep arg- res_rep = getRuntimeRep res-repSplitTyConApp_maybe _ = Nothing--tcRepSplitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type])--- ^ Like 'tcSplitTyConApp_maybe', but doesn't look through synonyms. This--- assumes the synonyms have already been dealt with.------ Moreover, for a FunTy, it only succeeds if the argument types--- have enough info to extract the runtime-rep arguments that--- the funTyCon requires. This will usually be true;--- but may be temporarily false during canonicalization:--- see Note [Decomposing FunTy] in GHC.Tc.Solver.Canonical--- and Note [The Purely Kinded Type Invariant (PKTI)] in GHC.Tc.Gen.HsType,--- Wrinkle around FunTy-tcRepSplitTyConApp_maybe (TyConApp tc tys) = Just (tc, tys)-tcRepSplitTyConApp_maybe (FunTy VisArg w arg res)- -- NB: VisArg. See Note [Decomposing fat arrow c=>t]- | Just arg_rep <- getRuntimeRep_maybe arg- , Just res_rep <- getRuntimeRep_maybe res- = Just (funTyCon, [w, arg_rep, res_rep, arg, res])-tcRepSplitTyConApp_maybe _ = Nothing------------------------ | Attempts to tease a list type apart and gives the type of the elements if--- successful (looks through type synonyms)-splitListTyConApp_maybe :: Type -> Maybe Type-splitListTyConApp_maybe ty = case splitTyConApp_maybe ty of- Just (tc,[e]) | tc == listTyCon -> Just e- _other -> Nothing--newTyConInstRhs :: TyCon -> [Type] -> Type--- ^ Unwrap one 'layer' of newtype on a type constructor and its--- arguments, using an eta-reduced version of the @newtype@ if possible.--- This requires tys to have at least @newTyConInstArity tycon@ elements.-newTyConInstRhs tycon tys- = assertPpr (tvs `leLength` tys) (ppr tycon $$ ppr tys $$ ppr tvs) $- applyTysX tvs rhs tys- where- (tvs, rhs) = newTyConEtadRhs tycon--{------------------------------------------------------------------------ CastTy- ~~~~~~-A casted type has its *kind* casted into something new.--}--splitCastTy_maybe :: Type -> Maybe (Type, Coercion)-splitCastTy_maybe ty- | CastTy ty' co <- coreFullView ty = Just (ty', co)- | otherwise = Nothing---- | Make a 'CastTy'. The Coercion must be nominal. Checks the--- Coercion for reflexivity, dropping it if it's reflexive.--- See @Note [Respecting definitional equality]@ in "GHC.Core.TyCo.Rep"-mkCastTy :: Type -> Coercion -> Type-mkCastTy orig_ty co | isReflexiveCo co = orig_ty -- (EQ2) from the Note--- NB: Do the slow check here. This is important to keep the splitXXX--- functions working properly. Otherwise, we may end up with something--- like (((->) |> something_reflexive_but_not_obviously_so) biz baz)--- fails under splitFunTy_maybe. This happened with the cheaper check--- in test dependent/should_compile/dynamic-paper.-mkCastTy orig_ty co = mk_cast_ty orig_ty co---- | Like 'mkCastTy', but avoids checking the coercion for reflexivity,--- as that can be expensive.-mk_cast_ty :: Type -> Coercion -> Type-mk_cast_ty orig_ty co = go orig_ty- where- go :: Type -> Type- -- See Note [Using coreView in mk_cast_ty]- go ty | Just ty' <- coreView ty = go ty'-- go (CastTy ty co1)- -- (EQ3) from the Note- = mkCastTy ty (co1 `mkTransCo` co)- -- call mkCastTy again for the reflexivity check-- go (ForAllTy (Bndr tv vis) inner_ty)- -- (EQ4) from the Note- -- See Note [Weird typing rule for ForAllTy] in GHC.Core.TyCo.Rep.- | isTyVar tv- , let fvs = tyCoVarsOfCo co- = -- have to make sure that pushing the co in doesn't capture the bound var!- if tv `elemVarSet` fvs- then let empty_subst = mkEmptySubst (mkInScopeSet fvs)- (subst, tv') = substVarBndr empty_subst tv- in ForAllTy (Bndr tv' vis) (substTy subst inner_ty `mk_cast_ty` co)- else ForAllTy (Bndr tv vis) (inner_ty `mk_cast_ty` co)-- go _ = CastTy orig_ty co -- NB: orig_ty: preserve synonyms if possible--{--Note [Using coreView in mk_cast_ty]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Invariants (EQ3) and (EQ4) of Note [Respecting definitional equality] in-GHC.Core.TyCo.Rep must apply regardless of type synonyms. For instance,-consider this example (#19742):-- type EqSameNat = () |> co- useNatEq :: EqSameNat |> sym co--(Those casts aren't visible in the user-source code, of course; see #19742 for-what the user might write.)--The type `EqSameNat |> sym co` looks as if it satisfies (EQ3), as it has no-nested casts, but if we expand EqSameNat, we see that it doesn't.-And then Bad Things happen.--The solution is easy: just use `coreView` when establishing (EQ3) and (EQ4) in-`mk_cast_ty`.--}--tyConBindersTyCoBinders :: [TyConBinder] -> [TyCoBinder]--- Return the tyConBinders in TyCoBinder form-tyConBindersTyCoBinders = map to_tyb- where- to_tyb (Bndr tv (NamedTCB vis)) = Named (Bndr tv vis)- to_tyb (Bndr tv (AnonTCB af)) = Anon af (tymult (varType tv))---- | (mkTyConTy tc) returns (TyConApp tc [])--- but arranges to share that TyConApp among all calls--- See Note [Sharing nullary TyConApps] in GHC.Core.TyCon-mkTyConTy :: TyCon -> Type-mkTyConTy tycon = tyConNullaryTy tycon---- | A key function: builds a 'TyConApp' or 'FunTy' as appropriate to--- its arguments. Applies its arguments to the constructor from left to right.-mkTyConApp :: TyCon -> [Type] -> Type-mkTyConApp tycon []- = -- See Note [Sharing nullary TyConApps] in GHC.Core.TyCon- mkTyConTy tycon--mkTyConApp tycon tys@(ty1:rest)- | key == funTyConKey- = case tys of- [w, _rep1,_rep2,arg,res] -> FunTy { ft_af = VisArg, ft_mult = w- , ft_arg = arg, ft_res = res }- _ -> bale_out-- -- See Note [Using synonyms to compress types]- | key == tYPETyConKey- = assert (null rest) $--- mkTYPEapp_maybe ty1 `orElse` bale_out- case mkTYPEapp_maybe ty1 of- Just ty -> ty -- pprTrace "mkTYPEapp:yes" (ppr ty) ty- Nothing -> bale_out -- pprTrace "mkTYPEapp:no" (ppr bale_out) bale_out-- -- See Note [Using synonyms to compress types]- | key == boxedRepDataConTyConKey- = assert (null rest) $--- mkBoxedRepApp_maybe ty1 `orElse` bale_out- case mkBoxedRepApp_maybe ty1 of- Just ty -> ty -- pprTrace "mkBoxedRepApp:yes" (ppr ty) ty- Nothing -> bale_out -- pprTrace "mkBoxedRepApp:no" (ppr bale_out) bale_out-- | key == tupleRepDataConTyConKey- = case mkTupleRepApp_maybe ty1 of- Just ty -> ty -- pprTrace "mkTupleRepApp:yes" (ppr ty) ty- Nothing -> bale_out -- pprTrace "mkTupleRepApp:no" (ppr bale_out) bale_out-- -- The catch-all case- | otherwise- = bale_out- where- key = tyConUnique tycon- bale_out = TyConApp tycon tys--mkTYPEapp :: RuntimeRepType -> Type-mkTYPEapp rr- = case mkTYPEapp_maybe rr of- Just ty -> ty- Nothing -> TyConApp tYPETyCon [rr]--mkTYPEapp_maybe :: RuntimeRepType -> Maybe Type--- ^ Given a @RuntimeRep@, applies @TYPE@ to it.--- On the fly it rewrites--- TYPE LiftedRep --> liftedTypeKind (a synonym)--- TYPE UnliftedRep --> unliftedTypeKind (ditto)--- TYPE ZeroBitRep --> zeroBitTypeKind (ditto)--- NB: no need to check for TYPE (BoxedRep Lifted), TYPE (BoxedRep Unlifted)--- because those inner types should already have been rewritten--- to LiftedRep and UnliftedRep respectively, by mkTyConApp------ see Note [TYPE and RuntimeRep] in GHC.Builtin.Types.Prim.--- See Note [Using synonyms to compress types] in GHC.Core.Type-{-# NOINLINE mkTYPEapp_maybe #-}-mkTYPEapp_maybe (TyConApp tc args)- | key == liftedRepTyConKey = assert (null args) $ Just liftedTypeKind -- TYPE LiftedRep- | key == unliftedRepTyConKey = assert (null args) $ Just unliftedTypeKind -- TYPE UnliftedRep- | key == zeroBitRepTyConKey = assert (null args) $ Just zeroBitTypeKind -- TYPE ZeroBitRep- where- key = tyConUnique tc-mkTYPEapp_maybe _ = Nothing--mkBoxedRepApp_maybe :: Type -> Maybe Type--- ^ Given a `Levity`, apply `BoxedRep` to it--- On the fly, rewrite--- BoxedRep Lifted --> liftedRepTy (a synonym)--- BoxedRep Unlifted --> unliftedRepTy (ditto)--- See Note [TYPE and RuntimeRep] in GHC.Builtin.Types.Prim.--- See Note [Using synonyms to compress types] in GHC.Core.Type-{-# NOINLINE mkBoxedRepApp_maybe #-}-mkBoxedRepApp_maybe (TyConApp tc args)- | key == liftedDataConKey = assert (null args) $ Just liftedRepTy -- BoxedRep Lifted- | key == unliftedDataConKey = assert (null args) $ Just unliftedRepTy -- BoxedRep Unlifted- where- key = tyConUnique tc-mkBoxedRepApp_maybe _ = Nothing--mkTupleRepApp_maybe :: Type -> Maybe Type--- ^ Given a `[RuntimeRep]`, apply `TupleRep` to it--- On the fly, rewrite--- TupleRep [] -> zeroBitRepTy (a synonym)--- See Note [TYPE and RuntimeRep] in GHC.Builtin.Types.Prim.--- See Note [Using synonyms to compress types] in GHC.Core.Type-{-# NOINLINE mkTupleRepApp_maybe #-}-mkTupleRepApp_maybe (TyConApp tc args)- | key == nilDataConKey = assert (isSingleton args) $ Just zeroBitRepTy -- ZeroBitRep- where- key = tyConUnique tc-mkTupleRepApp_maybe _ = Nothing--{- Note [Using synonyms to compress types]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Was: Prefer Type over TYPE (BoxedRep Lifted)]--The Core of nearly any program will have numerous occurrences of the Types-- TyConApp BoxedRep [TyConApp Lifted []] -- Synonym LiftedRep- TyConApp BoxedRep [TyConApp Unlifted []] -- Synonym UnliftedREp- TyConApp TYPE [TyConApp LiftedRep []] -- Synonym Type- TyConApp TYPE [TyConApp UnliftedRep []] -- Synonym UnliftedType--While investigating #17292 we found that these constituted a majority-of all TyConApp constructors on the heap:-- (From a sample of 100000 TyConApp closures)- 0x45f3523 - 28732 - `Type`- 0x420b840702 - 9629 - generic type constructors- 0x42055b7e46 - 9596- 0x420559b582 - 9511- 0x420bb15a1e - 9509- 0x420b86c6ba - 9501- 0x42055bac1e - 9496- 0x45e68fd - 538 - `TYPE ...`--Consequently, we try hard to ensure that operations on such types are-efficient. Specifically, we strive to-- a. Avoid heap allocation of such types; use a single static TyConApp- b. Use a small (shallow in the tree-depth sense) representation- for such types--Goal (b) is particularly useful as it makes traversals (e.g. free variable-traversal, substitution, and comparison) more efficient.-Comparison in particular takes special advantage of nullary type synonym-applications (e.g. things like @TyConApp typeTyCon []@), Note [Comparing-nullary type synonyms] in "GHC.Core.Type".--To accomplish these we use a number of tricks, implemented by mkTyConApp.-- 1. Instead of (TyConApp BoxedRep [TyConApp Lifted []]),- we prefer a statically-allocated (TyConApp LiftedRep [])- where `LiftedRep` is a type synonym:- type LiftedRep = BoxedRep Lifted- Similarly for UnliftedRep-- 2. Instead of (TyConApp TYPE [TyConApp LiftedRep []])- we prefer the statically-allocated (TyConApp Type [])- where `Type` is a type synonym- type Type = TYPE LiftedRep- Similarly for UnliftedType--These serve goal (b) since there are no applied type arguments to traverse,-e.g., during comparison.-- 3. We have a single, statically allocated top-level binding to- represent `TyConApp GHC.Types.Type []` (namely- 'GHC.Builtin.Types.Prim.liftedTypeKind'), ensuring that we don't- need to allocate such types (goal (a)). See functions- mkTYPEapp and mkBoxedRepApp-- 4. We use the sharing mechanism described in Note [Sharing nullary TyConApps]- in GHC.Core.TyCon to ensure that we never need to allocate such- nullary applications (goal (a)).--See #17958, #20541--Note [Care using synonyms to compress types]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Using a synonym to compress a types has a tricky wrinkle. Consider-coreView applied to (TyConApp LiftedRep [])--* coreView expands the LiftedRep synonym:- type LiftedRep = BoxedRep Lifted--* Danger: we might apply the empty substitution to the RHS of the- synonym. And substTy calls mkTyConApp BoxedRep [Lifted]. And- mkTyConApp compresses that back to LiftedRep. Loop!--* Solution: in expandSynTyConApp_maybe, don't call substTy for nullary- type synonyms. That's more efficient anyway.--}----{----------------------------------------------------------------------- CoercionTy- ~~~~~~~~~~-CoercionTy allows us to inject coercions into types. A CoercionTy-should appear only in the right-hand side of an application.--}--mkCoercionTy :: Coercion -> Type-mkCoercionTy = CoercionTy--isCoercionTy :: Type -> Bool-isCoercionTy (CoercionTy _) = True-isCoercionTy _ = False--isCoercionTy_maybe :: Type -> Maybe Coercion-isCoercionTy_maybe (CoercionTy co) = Just co-isCoercionTy_maybe _ = Nothing--stripCoercionTy :: Type -> Coercion-stripCoercionTy (CoercionTy co) = co-stripCoercionTy ty = pprPanic "stripCoercionTy" (ppr ty)--{------------------------------------------------------------------------ SynTy- ~~~~~--Notes on type synonyms-~~~~~~~~~~~~~~~~~~~~~~-The various "split" functions (splitFunTy, splitRhoTy, splitForAllTy) try-to return type synonyms wherever possible. Thus-- type Foo a = a -> a--we want- splitFunTys (a -> Foo a) = ([a], Foo a)-not ([a], a -> a)--The reason is that we then get better (shorter) type signatures in-interfaces. Notably this plays a role in tcTySigs in GHC.Tc.Gen.Bind.------------------------------------------------------------------------- ForAllTy- ~~~~~~~~--}---- | Make a dependent forall over an 'Inferred' variable-mkTyCoInvForAllTy :: TyCoVar -> Type -> Type-mkTyCoInvForAllTy tv ty- | isCoVar tv- , not (tv `elemVarSet` tyCoVarsOfType ty)- = mkVisFunTyMany (varType tv) ty- | otherwise- = ForAllTy (Bndr tv Inferred) ty---- | Like 'mkTyCoInvForAllTy', but tv should be a tyvar-mkInfForAllTy :: TyVar -> Type -> Type-mkInfForAllTy tv ty = assert (isTyVar tv )- ForAllTy (Bndr tv Inferred) ty---- | Like 'mkForAllTys', but assumes all variables are dependent and--- 'Inferred', a common case-mkTyCoInvForAllTys :: [TyCoVar] -> Type -> Type-mkTyCoInvForAllTys tvs ty = foldr mkTyCoInvForAllTy ty tvs---- | Like 'mkTyCoInvForAllTys', but tvs should be a list of tyvar-mkInfForAllTys :: [TyVar] -> Type -> Type-mkInfForAllTys tvs ty = foldr mkInfForAllTy ty tvs---- | Like 'mkForAllTy', but assumes the variable is dependent and 'Specified',--- a common case-mkSpecForAllTy :: TyVar -> Type -> Type-mkSpecForAllTy tv ty = assert (isTyVar tv )- -- covar is always Inferred, so input should be tyvar- ForAllTy (Bndr tv Specified) ty---- | Like 'mkForAllTys', but assumes all variables are dependent and--- 'Specified', a common case-mkSpecForAllTys :: [TyVar] -> Type -> Type-mkSpecForAllTys tvs ty = foldr mkSpecForAllTy ty tvs---- | Like mkForAllTys, but assumes all variables are dependent and visible-mkVisForAllTys :: [TyVar] -> Type -> Type-mkVisForAllTys tvs = assert (all isTyVar tvs )- -- covar is always Inferred, so all inputs should be tyvar- mkForAllTys [ Bndr tv Required | tv <- tvs ]---- | Given a list of type-level vars and the free vars of a result kind,--- makes TyCoBinders, preferring anonymous binders--- if the variable is, in fact, not dependent.--- e.g. mkTyConBindersPreferAnon [(k:*),(b:k),(c:k)] (k->k)--- We want (k:*) Named, (b:k) Anon, (c:k) Anon------ All non-coercion binders are /visible/.-mkTyConBindersPreferAnon :: [TyVar] -- ^ binders- -> TyCoVarSet -- ^ free variables of result- -> [TyConBinder]-mkTyConBindersPreferAnon vars inner_tkvs = assert (all isTyVar vars)- fst (go vars)- where- go :: [TyVar] -> ([TyConBinder], VarSet) -- also returns the free vars- go [] = ([], inner_tkvs)- go (v:vs) | v `elemVarSet` fvs- = ( Bndr v (NamedTCB Required) : binders- , fvs `delVarSet` v `unionVarSet` kind_vars )- | otherwise- = ( Bndr v (AnonTCB VisArg) : binders- , fvs `unionVarSet` kind_vars )- where- (binders, fvs) = go vs- kind_vars = tyCoVarsOfType $ tyVarKind v---- | Take a ForAllTy apart, returning the list of tycovars and the result type.--- This always succeeds, even if it returns only an empty list. Note that the--- result type returned may have free variables that were bound by a forall.-splitForAllTyCoVars :: Type -> ([TyCoVar], Type)-splitForAllTyCoVars ty = split ty ty []- where- split _ (ForAllTy (Bndr tv _) ty) tvs = 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)---- | Splits the longest initial sequence of 'ForAllTy's that satisfy--- @argf_pred@, returning the binders transformed by @argf_pred@-splitSomeForAllTyCoVarBndrs :: (ArgFlag -> Maybe af) -> Type -> ([VarBndr TyCoVar af], Type)-splitSomeForAllTyCoVarBndrs argf_pred ty = split ty ty []- where- split _ (ForAllTy (Bndr tcv argf) ty) tvs- | Just argf' <- argf_pred argf = split ty ty (Bndr tcv argf' : tvs)- split orig_ty ty tvs | Just ty' <- coreView ty = split orig_ty ty' tvs- split orig_ty _ tvs = (reverse tvs, orig_ty)---- | Like 'splitForAllTyCoVars', but only splits 'ForAllTy's with 'Required' type--- variable binders. Furthermore, each returned tyvar is annotated with '()'.-splitForAllReqTVBinders :: Type -> ([ReqTVBinder], Type)-splitForAllReqTVBinders ty = splitSomeForAllTyCoVarBndrs argf_pred ty- where- argf_pred :: ArgFlag -> Maybe ()- argf_pred Required = Just ()- argf_pred (Invisible {}) = Nothing---- | Like 'splitForAllTyCoVars', but only splits 'ForAllTy's with 'Invisible' type--- variable binders. Furthermore, each returned tyvar is annotated with its--- 'Specificity'.-splitForAllInvisTVBinders :: Type -> ([InvisTVBinder], Type)-splitForAllInvisTVBinders ty = splitSomeForAllTyCoVarBndrs argf_pred ty- where- argf_pred :: ArgFlag -> Maybe Specificity- argf_pred Required = Nothing- argf_pred (Invisible spec) = Just spec---- | Like 'splitForAllTyCoVars', but split only for tyvars.--- This always succeeds, even if it returns only an empty list. Note that the--- result type returned may have free variables that were bound by a forall.-splitForAllTyVars :: Type -> ([TyVar], Type)-splitForAllTyVars ty = split ty ty []- where- split _ (ForAllTy (Bndr tv _) ty) tvs | isTyVar tv = 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)---- | Checks whether this is a proper forall (with a named binder)-isForAllTy :: Type -> Bool-isForAllTy ty- | ForAllTy {} <- coreFullView ty = True- | otherwise = False---- | Like `isForAllTy`, but returns True only if it is a tyvar binder-isForAllTy_ty :: Type -> Bool-isForAllTy_ty ty- | ForAllTy (Bndr tv _) _ <- coreFullView ty- , isTyVar tv- = True-- | otherwise = False---- | Like `isForAllTy`, but returns True only if it is a covar binder-isForAllTy_co :: Type -> Bool-isForAllTy_co ty- | ForAllTy (Bndr tv _) _ <- coreFullView ty- , isCoVar tv- = True-- | otherwise = False---- | Is this a function or forall?-isPiTy :: Type -> Bool-isPiTy ty = case coreFullView ty of- ForAllTy {} -> True- FunTy {} -> True- _ -> False---- | Is this a function?-isFunTy :: Type -> Bool-isFunTy ty- | FunTy {} <- coreFullView ty = True- | otherwise = False---- | Take a forall type apart, or panics if that is not possible.-splitForAllTyCoVar :: Type -> (TyCoVar, Type)-splitForAllTyCoVar ty- | Just answer <- splitForAllTyCoVar_maybe ty = answer- | otherwise = pprPanic "splitForAllTyCoVar" (ppr ty)---- | Drops all ForAllTys-dropForAlls :: Type -> Type-dropForAlls ty = go ty- where- go (ForAllTy _ res) = go res- go ty | Just ty' <- coreView ty = go ty'- go res = res---- | Attempts to take a forall type apart, but only if it's a proper forall,--- with a named binder-splitForAllTyCoVar_maybe :: Type -> Maybe (TyCoVar, Type)-splitForAllTyCoVar_maybe ty- | ForAllTy (Bndr tv _) inner_ty <- coreFullView ty = Just (tv, inner_ty)- | otherwise = Nothing---- | Like 'splitForAllTyCoVar_maybe', but only returns Just if it is a tyvar binder.-splitForAllTyVar_maybe :: Type -> Maybe (TyCoVar, Type)-splitForAllTyVar_maybe ty- | ForAllTy (Bndr tv _) inner_ty <- coreFullView ty- , isTyVar tv- = Just (tv, inner_ty)-- | otherwise = Nothing---- | Like 'splitForAllTyCoVar_maybe', but only returns Just if it is a covar binder.-splitForAllCoVar_maybe :: Type -> Maybe (TyCoVar, Type)-splitForAllCoVar_maybe ty- | ForAllTy (Bndr tv _) inner_ty <- coreFullView ty- , isCoVar tv- = Just (tv, inner_ty)-- | otherwise = Nothing---- | Attempts to take a forall type apart; works with proper foralls and--- functions-{-# INLINE splitPiTy_maybe #-} -- callers will immediately deconstruct-splitPiTy_maybe :: Type -> Maybe (TyCoBinder, Type)-splitPiTy_maybe ty = case coreFullView ty of- ForAllTy bndr ty -> Just (Named bndr, ty)- FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res}- -> Just (Anon af (mkScaled w arg), res)- _ -> Nothing---- | Takes a forall type apart, or panics-splitPiTy :: Type -> (TyCoBinder, Type)-splitPiTy ty- | Just answer <- splitPiTy_maybe ty = answer- | otherwise = pprPanic "splitPiTy" (ppr ty)---- | Split off all TyCoBinders to a type, splitting both proper foralls--- and functions-splitPiTys :: Type -> ([TyCoBinder], Type)-splitPiTys ty = split ty ty []- where- split _ (ForAllTy b res) bs = split res res (Named b : bs)- split _ (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res }) bs- = split res res (Anon af (Scaled w arg) : bs)- split orig_ty ty bs | Just ty' <- coreView ty = split orig_ty ty' bs- split orig_ty _ bs = (reverse bs, orig_ty)---- | Extracts a list of run-time arguments from a function type,--- looking through newtypes to the right of arrows.------ Examples:------ @--- newtype Identity a = I a------ getRuntimeArgTys (Int -> Bool -> Double) == [(Int, VisArg), (Bool, VisArg)]--- getRuntimeArgTys (Identity Int -> Bool -> Double) == [(Identity Int, VisArg), (Bool, VisArg)]--- getRuntimeArgTys (Int -> Identity (Bool -> Identity Double)) == [(Int, VisArg), (Bool, VisArg)]--- getRuntimeArgTys (forall a. Show a => Identity a -> a -> Int -> Bool) == [(Show a, InvisArg), (Identity a, VisArg),(a, VisArg),(Int, VisArg)]--- @------ Note that, in the last case, the returned types might mention an out-of-scope--- type variable. This function is used only when we really care about the /kinds/--- of the returned types, so this is OK.------ **Warning**: this function can return an infinite list. For example:------ @--- newtype N a = MkN (a -> N a)--- getRuntimeArgTys (N a) == repeat (a, VisArg)--- @-getRuntimeArgTys :: Type -> [(Scaled Type, AnonArgFlag)]-getRuntimeArgTys = go- where- go :: Type -> [(Scaled Type, AnonArgFlag)]- go (ForAllTy _ res)- = go res- go (FunTy { ft_mult = w, ft_arg = arg, ft_res = res, ft_af = af })- = (Scaled w arg, af) : go res- go ty- | Just ty' <- coreView ty- = go ty'- | Just (_,ty') <- topNormaliseNewType_maybe ty- = go ty'- | otherwise- = []---- | Like 'splitPiTys' but split off only /named/ binders--- and returns 'TyCoVarBinder's rather than 'TyCoBinder's-splitForAllTyCoVarBinders :: Type -> ([TyCoVarBinder], Type)-splitForAllTyCoVarBinders ty = split ty ty []- where- split orig_ty ty bs | Just ty' <- coreView ty = split orig_ty ty' bs- split _ (ForAllTy b res) bs = split res res (b:bs)- split orig_ty _ bs = (reverse bs, orig_ty)-{-# INLINE splitForAllTyCoVarBinders #-}--invisibleTyBndrCount :: Type -> Int--- Returns the number of leading invisible forall'd binders in the type--- Includes invisible predicate arguments; e.g. for--- e.g. forall {k}. (k ~ *) => k -> k--- returns 2 not 1-invisibleTyBndrCount ty = length (fst (splitInvisPiTys ty))---- | Like 'splitPiTys', but returns only *invisible* binders, including constraints.--- Stops at the first visible binder.-splitInvisPiTys :: Type -> ([TyCoBinder], Type)-splitInvisPiTys ty = split ty ty []- where- split _ (ForAllTy b res) bs- | Bndr _ vis <- b- , isInvisibleArgFlag vis = split res res (Named b : bs)- split _ (FunTy { ft_af = InvisArg, ft_mult = mult, ft_arg = arg, ft_res = res }) bs- = split res res (Anon InvisArg (mkScaled mult arg) : bs)- split orig_ty ty bs- | Just ty' <- coreView ty = split orig_ty ty' bs- split orig_ty _ bs = (reverse bs, orig_ty)--splitInvisPiTysN :: Int -> Type -> ([TyCoBinder], Type)--- ^ Same as 'splitInvisPiTys', but stop when--- - you have found @n@ 'TyCoBinder's,--- - or you run out of invisible binders-splitInvisPiTysN n ty = split n ty ty []- where- split n orig_ty ty bs- | n == 0 = (reverse bs, orig_ty)- | Just ty' <- coreView ty = split n orig_ty ty' bs- | ForAllTy b res <- ty- , Bndr _ vis <- b- , isInvisibleArgFlag vis = split (n-1) res res (Named b : bs)- | FunTy { ft_af = InvisArg, ft_mult = mult, ft_arg = arg, ft_res = res } <- ty- = split (n-1) res res (Anon InvisArg (Scaled mult arg) : bs)- | otherwise = (reverse bs, orig_ty)---- | Given a 'TyCon' and a list of argument types, filter out any invisible--- (i.e., 'Inferred' or 'Specified') arguments.-filterOutInvisibleTypes :: TyCon -> [Type] -> [Type]-filterOutInvisibleTypes tc tys = snd $ partitionInvisibleTypes tc tys---- | Given a 'TyCon' and a list of argument types, filter out any 'Inferred'--- arguments.-filterOutInferredTypes :: TyCon -> [Type] -> [Type]-filterOutInferredTypes tc tys =- filterByList (map (/= Inferred) $ tyConArgFlags tc tys) tys---- | Given a 'TyCon' and a list of argument types, partition the arguments--- into:------ 1. 'Inferred' or 'Specified' (i.e., invisible) arguments and------ 2. 'Required' (i.e., visible) arguments-partitionInvisibleTypes :: TyCon -> [Type] -> ([Type], [Type])-partitionInvisibleTypes tc tys =- partitionByList (map isInvisibleArgFlag $ tyConArgFlags tc tys) tys---- | Given a list of things paired with their visibilities, partition the--- things into (invisible things, visible things).-partitionInvisibles :: [(a, ArgFlag)] -> ([a], [a])-partitionInvisibles = partitionWith pick_invis- where- pick_invis :: (a, ArgFlag) -> Either a a- pick_invis (thing, vis) | isInvisibleArgFlag vis = Left thing- | otherwise = Right thing---- | Given a 'TyCon' and a list of argument types to which the 'TyCon' is--- applied, determine each argument's visibility--- ('Inferred', 'Specified', or 'Required').------ Wrinkle: consider the following scenario:------ > T :: forall k. k -> k--- > tyConArgFlags T [forall m. m -> m -> m, S, R, Q]------ After substituting, we get------ > T (forall m. m -> m -> m) :: (forall m. m -> m -> m) -> forall n. n -> n -> n------ Thus, the first argument is invisible, @S@ is visible, @R@ is invisible again,--- and @Q@ is visible.-tyConArgFlags :: TyCon -> [Type] -> [ArgFlag]-tyConArgFlags tc = fun_kind_arg_flags (tyConKind tc)---- | Given a 'Type' and a list of argument types to which the 'Type' is--- applied, determine each argument's visibility--- ('Inferred', 'Specified', or 'Required').------ Most of the time, the arguments will be 'Required', but not always. Consider--- @f :: forall a. a -> Type@. In @f Type Bool@, the first argument (@Type@) is--- 'Specified' and the second argument (@Bool@) is 'Required'. It is precisely--- this sort of higher-rank situation in which 'appTyArgFlags' comes in handy,--- since @f Type Bool@ would be represented in Core using 'AppTy's.--- (See also #15792).-appTyArgFlags :: Type -> [Type] -> [ArgFlag]-appTyArgFlags ty = fun_kind_arg_flags (typeKind ty)---- | Given a function kind and a list of argument types (where each argument's--- kind aligns with the corresponding position in the argument kind), determine--- each argument's visibility ('Inferred', 'Specified', or 'Required').-fun_kind_arg_flags :: Kind -> [Type] -> [ArgFlag]-fun_kind_arg_flags = go emptySubst- where- go subst ki arg_tys- | Just ki' <- coreView ki = go subst ki' arg_tys- go _ _ [] = []- go subst (ForAllTy (Bndr tv argf) res_ki) (arg_ty:arg_tys)- = argf : go subst' res_ki arg_tys- where- subst' = extendTvSubst subst tv arg_ty- go subst (TyVarTy tv) arg_tys- | Just ki <- lookupTyVar subst tv = go subst ki arg_tys- -- This FunTy case is important to handle kinds with nested foralls, such- -- as this kind (inspired by #16518):- --- -- forall {k1} k2. k1 -> k2 -> forall k3. k3 -> Type- --- -- Here, we want to get the following ArgFlags:- --- -- [Inferred, Specified, Required, Required, Specified, Required]- -- forall {k1}. forall k2. k1 -> k2 -> forall k3. k3 -> Type- go subst (FunTy{ft_af = af, ft_res = res_ki}) (_:arg_tys)- = argf : go subst res_ki arg_tys- where- argf = case af of- VisArg -> Required- InvisArg -> Inferred- go _ _ arg_tys = map (const Required) arg_tys- -- something is ill-kinded. But this can happen- -- when printing errors. Assume everything is Required.---- @isTauTy@ tests if a type has no foralls or (=>)-isTauTy :: Type -> Bool-isTauTy ty | Just ty' <- coreView ty = isTauTy ty'-isTauTy (TyVarTy _) = True-isTauTy (LitTy {}) = True-isTauTy (TyConApp tc tys) = all isTauTy tys && isTauTyCon tc-isTauTy (AppTy a b) = isTauTy a && isTauTy b-isTauTy (FunTy af w a b) = case af of- InvisArg -> False -- e.g., Eq a => b- VisArg -> isTauTy w && isTauTy a && isTauTy b -- e.g., a -> b-isTauTy (ForAllTy {}) = False-isTauTy (CastTy ty _) = isTauTy ty-isTauTy (CoercionTy _) = False -- Not sure about this--isAtomicTy :: Type -> Bool--- True if the type is just a single token, and can be printed compactly--- Used when deciding how to lay out type error messages; see the--- call in GHC.Tc.Errors-isAtomicTy (TyVarTy {}) = True-isAtomicTy (LitTy {}) = True-isAtomicTy (TyConApp _ []) = True--isAtomicTy ty | isLiftedTypeKind ty = True- -- 'Type' prints compactly as *- -- See GHC.Iface.Type.ppr_kind_type--isAtomicTy _ = False--{--%************************************************************************-%* *- TyCoBinders-%* *-%************************************************************************--}---- | Make an anonymous binder-mkAnonBinder :: AnonArgFlag -> Scaled Type -> TyCoBinder-mkAnonBinder = Anon---- | Does this binder bind a variable that is /not/ erased? Returns--- 'True' for anonymous binders.-isAnonTyCoBinder :: TyCoBinder -> Bool-isAnonTyCoBinder (Named {}) = False-isAnonTyCoBinder (Anon {}) = True--tyCoBinderVar_maybe :: TyCoBinder -> Maybe TyCoVar-tyCoBinderVar_maybe (Named tv) = Just $ binderVar tv-tyCoBinderVar_maybe _ = Nothing--tyCoBinderType :: TyCoBinder -> Type-tyCoBinderType (Named tvb) = binderType tvb-tyCoBinderType (Anon _ ty) = scaledThing ty--tyBinderType :: TyBinder -> Type-tyBinderType (Named (Bndr tv _))- = assert (isTyVar tv )- tyVarKind tv-tyBinderType (Anon _ ty) = scaledThing ty---- | Extract a relevant type, if there is one.-binderRelevantType_maybe :: TyCoBinder -> Maybe Type-binderRelevantType_maybe (Named {}) = Nothing-binderRelevantType_maybe (Anon _ ty) = Just (scaledThing ty)--{--************************************************************************-* *-\subsection{Type families}-* *-************************************************************************--}--mkFamilyTyConApp :: TyCon -> [Type] -> Type--- ^ Given a family instance TyCon and its arg types, return the--- corresponding family type. E.g:------ > data family T a--- > data instance T (Maybe b) = MkT b------ Where the instance tycon is :RTL, so:------ > mkFamilyTyConApp :RTL Int = T (Maybe Int)-mkFamilyTyConApp tc tys- | Just (fam_tc, fam_tys) <- tyConFamInst_maybe tc- , let tvs = tyConTyVars tc- fam_subst = assertPpr (tvs `equalLength` tys) (ppr tc <+> ppr tys) $- zipTvSubst tvs tys- = mkTyConApp fam_tc (substTys fam_subst fam_tys)- | otherwise- = mkTyConApp tc tys---- | Get the type on the LHS of a coercion induced by a type/data--- family instance.-coAxNthLHS :: CoAxiom br -> Int -> Type-coAxNthLHS ax ind =- mkTyConApp (coAxiomTyCon ax) (coAxBranchLHS (coAxiomNthBranch ax ind))--isFamFreeTy :: Type -> Bool-isFamFreeTy ty | Just ty' <- coreView ty = isFamFreeTy ty'-isFamFreeTy (TyVarTy _) = True-isFamFreeTy (LitTy {}) = True-isFamFreeTy (TyConApp tc tys) = all isFamFreeTy tys && isFamFreeTyCon tc-isFamFreeTy (AppTy a b) = isFamFreeTy a && isFamFreeTy b-isFamFreeTy (FunTy _ w a b) = isFamFreeTy w && isFamFreeTy a && isFamFreeTy b-isFamFreeTy (ForAllTy _ ty) = isFamFreeTy ty-isFamFreeTy (CastTy ty _) = isFamFreeTy ty-isFamFreeTy (CoercionTy _) = False -- Not sure about this---- | Does this type classify a core (unlifted) Coercion?--- At either role nominal or representational--- (t1 ~# t2) or (t1 ~R# t2)--- See Note [Types for coercions, predicates, and evidence] in "GHC.Core.TyCo.Rep"-isCoVarType :: Type -> Bool- -- ToDo: should we check saturation?-isCoVarType ty- | Just tc <- tyConAppTyCon_maybe ty- = tc `hasKey` eqPrimTyConKey || tc `hasKey` eqReprPrimTyConKey- | otherwise- = False--buildSynTyCon :: Name -> [KnotTied TyConBinder] -> Kind -- ^ /result/ kind- -> [Role] -> KnotTied Type -> TyCon--- This function is here because here is where we have--- isFamFree and isTauTy-buildSynTyCon name binders res_kind roles rhs- = mkSynonymTyCon name binders res_kind roles rhs is_tau is_fam_free is_forgetful- where- is_tau = isTauTy rhs- is_fam_free = isFamFreeTy rhs- is_forgetful = any (not . (`elemVarSet` tyCoVarsOfType rhs) . binderVar) binders ||- uniqSetAny isForgetfulSynTyCon (tyConsOfType rhs)- -- NB: This is allowed to be conservative, returning True more often- -- than it should. See comments on GHC.Core.TyCon.isForgetfulSynTyCon--{--************************************************************************-* *-\subsection{Liftedness}-* *-************************************************************************--}---- | Tries to compute the 'Levity' of the given type. Returns either--- a definite 'Levity', or 'Nothing' if we aren't sure (e.g. the--- type is representation-polymorphic).------ Panics if the kind does not have the shape @TYPE r@.-typeLevity_maybe :: HasDebugCallStack => Type -> Maybe Levity-typeLevity_maybe ty = runtimeRepLevity_maybe (getRuntimeRep ty)---- | Is the given type definitely unlifted?--- See "Type#type_classification" for what an unlifted type is.------ Panics on representation-polymorphic types; See 'mightBeUnliftedType' for--- a more approximate predicate that behaves better in the presence of--- representation polymorphism.-isUnliftedType :: HasDebugCallStack => Type -> Bool- -- isUnliftedType returns True for forall'd unlifted types:- -- x :: forall a. Int#- -- I found bindings like these were getting floated to the top level.- -- They are pretty bogus types, mind you. It would be better never to- -- construct them-isUnliftedType ty =- case typeLevity_maybe ty of- Just Lifted -> False- Just Unlifted -> True- Nothing ->- pprPanic "isUnliftedType" (ppr ty <+> dcolon <+> ppr (typeKind ty))---- | Returns:------ * 'False' if the type is /guaranteed/ unlifted or--- * 'True' if it lifted, OR we aren't sure--- (e.g. in a representation-polymorphic case)-mightBeLiftedType :: Type -> Bool-mightBeLiftedType = mightBeLifted . typeLevity_maybe---- | Returns:------ * 'False' if the type is /guaranteed/ lifted or--- * 'True' if it is unlifted, OR we aren't sure--- (e.g. in a representation-polymorphic case)-mightBeUnliftedType :: Type -> Bool-mightBeUnliftedType = mightBeUnlifted . typeLevity_maybe---- | See "Type#type_classification" for what a boxed type is.--- Panics on representation-polymorphic types; See 'mightBeUnliftedType' for--- a more approximate predicate that behaves better in the presence of--- representation polymorphism.-isBoxedType :: Type -> Bool-isBoxedType ty = isBoxedRuntimeRep (getRuntimeRep ty)---- | Is this a type of kind RuntimeRep? (e.g. LiftedRep)-isRuntimeRepKindedTy :: Type -> Bool-isRuntimeRepKindedTy = isRuntimeRepTy . typeKind---- | Drops prefix of RuntimeRep constructors in 'TyConApp's. Useful for e.g.--- dropping 'LiftedRep arguments of unboxed tuple TyCon applications:------ dropRuntimeRepArgs [ 'LiftedRep, 'IntRep--- , String, Int# ] == [String, Int#]----dropRuntimeRepArgs :: [Type] -> [Type]-dropRuntimeRepArgs = dropWhile isRuntimeRepKindedTy---- | Extract the RuntimeRep classifier of a type. For instance,--- @getRuntimeRep_maybe Int = Just LiftedRep@. Returns 'Nothing' if this is not--- possible.-getRuntimeRep_maybe :: HasDebugCallStack- => Type -> Maybe RuntimeRepType-getRuntimeRep_maybe = kindRep_maybe . typeKind---- | Extract the RuntimeRep classifier of a type. For instance,--- @getRuntimeRep_maybe Int = LiftedRep@. Panics if this is not possible.-getRuntimeRep :: HasDebugCallStack => Type -> RuntimeRepType-getRuntimeRep ty- = case getRuntimeRep_maybe ty of- Just r -> r- Nothing -> pprPanic "getRuntimeRep" (ppr ty <+> dcolon <+> ppr (typeKind ty))---- | Extract the 'Levity' of a type. For example, @getLevity_maybe Int = Just Lifted@,--- @getLevity (Array# Int) = Just Unlifted@, @getLevity Float# = Nothing@.------ Returns 'Nothing' if this is not possible. Does not look through type family applications.-getLevity_maybe :: HasDebugCallStack => Type -> Maybe Type-getLevity_maybe ty- | Just rep <- getRuntimeRep_maybe ty- , Just (tc, [lev]) <- splitTyConApp_maybe rep- , tc == boxedRepDataConTyCon- = Just lev- | otherwise- = Nothing---- | Extract the 'Levity' of a type. For example, @getLevity Int = Lifted@,--- or @getLevity (Array# Int) = Unlifted@.------ Panics if this is not possible. Does not look through type family applications.-getLevity :: HasDebugCallStack => Type -> Type-getLevity ty- | Just lev <- getLevity_maybe ty- = lev- | otherwise- = pprPanic "getLevity" (ppr ty <+> dcolon <+> ppr (typeKind ty))--isUnboxedTupleType :: Type -> Bool-isUnboxedTupleType ty- = tyConAppTyCon (getRuntimeRep ty) `hasKey` tupleRepDataConKey- -- NB: Do not use typePrimRep, as that can't tell the difference between- -- unboxed tuples and unboxed sums---isUnboxedSumType :: Type -> Bool-isUnboxedSumType ty- = tyConAppTyCon (getRuntimeRep ty) `hasKey` sumRepDataConKey---- | See "Type#type_classification" for what an algebraic type is.--- Should only be applied to /types/, as opposed to e.g. partially--- saturated type constructors-isAlgType :: Type -> Bool-isAlgType ty- = case splitTyConApp_maybe ty of- Just (tc, ty_args) -> assert (ty_args `lengthIs` tyConArity tc )- isAlgTyCon tc- _other -> False---- | Check whether a type is a data family type-isDataFamilyAppType :: Type -> Bool-isDataFamilyAppType ty = case tyConAppTyCon_maybe ty of- Just tc -> isDataFamilyTyCon tc- _ -> False---- | Computes whether an argument (or let right hand side) should--- be computed strictly or lazily, based only on its type.--- Currently, it's just 'isUnliftedType'.--- Panics on representation-polymorphic types.-isStrictType :: HasDebugCallStack => Type -> Bool-isStrictType = isUnliftedType--isPrimitiveType :: Type -> Bool--- ^ Returns true of types that are opaque to Haskell.-isPrimitiveType ty = case splitTyConApp_maybe ty of- Just (tc, ty_args) -> assert (ty_args `lengthIs` tyConArity tc )- isPrimTyCon tc- _ -> False--{--************************************************************************-* *-\subsection{Join points}-* *-************************************************************************--}---- | Determine whether a type could be the type of a join point of given total--- arity, according to the polymorphism rule. A join point cannot be polymorphic--- in its return type, since given--- join j @a @b x y z = e1 in e2,--- the types of e1 and e2 must be the same, and a and b are not in scope for e2.--- (See Note [The polymorphism rule of join points] in "GHC.Core".) Returns False--- also if the type simply doesn't have enough arguments.------ Note that we need to know how many arguments (type *and* value) the putative--- join point takes; for instance, if--- j :: forall a. a -> Int--- then j could be a binary join point returning an Int, but it could *not* be a--- unary join point returning a -> Int.------ TODO: See Note [Excess polymorphism and join points]-isValidJoinPointType :: JoinArity -> Type -> Bool-isValidJoinPointType arity ty- = valid_under emptyVarSet arity ty- where- valid_under tvs arity ty- | arity == 0- = tvs `disjointVarSet` tyCoVarsOfType ty- | Just (t, ty') <- splitForAllTyCoVar_maybe ty- = valid_under (tvs `extendVarSet` t) (arity-1) ty'- | Just (_, _, res_ty) <- splitFunTy_maybe ty- = valid_under tvs (arity-1) res_ty- | otherwise- = False--{- Note [Excess polymorphism and join points]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-In principle, if a function would be a join point except that it fails-the polymorphism rule (see Note [The polymorphism rule of join points] in-GHC.Core), it can still be made a join point with some effort. This is because-all tail calls must return the same type (they return to the same context!), and-thus if the return type depends on an argument, that argument must always be the-same.--For instance, consider:-- let f :: forall a. a -> Char -> [a]- f @a x c = ... f @a y 'a' ...- in ... f @Int 1 'b' ... f @Int 2 'c' ...--(where the calls are tail calls). `f` fails the polymorphism rule because its-return type is [a], where [a] is bound. But since the type argument is always-'Int', we can rewrite it as:-- let f' :: Int -> Char -> [Int]- f' x c = ... f' y 'a' ...- in ... f' 1 'b' ... f 2 'c' ...--and now we can make f' a join point:-- join f' :: Int -> Char -> [Int]- f' x c = ... jump f' y 'a' ...- in ... jump f' 1 'b' ... jump f' 2 'c' ...--It's not clear that this comes up often, however. TODO: Measure how often and-add this analysis if necessary. See #14620.---************************************************************************-* *-\subsection{Sequencing on types}-* *-************************************************************************--}--seqType :: Type -> ()-seqType (LitTy n) = n `seq` ()-seqType (TyVarTy tv) = tv `seq` ()-seqType (AppTy t1 t2) = seqType t1 `seq` seqType t2-seqType (FunTy _ w t1 t2) = seqType w `seq` seqType t1 `seq` seqType t2-seqType (TyConApp tc tys) = tc `seq` seqTypes tys-seqType (ForAllTy (Bndr tv _) ty) = seqType (varType tv) `seq` seqType ty-seqType (CastTy ty co) = seqType ty `seq` seqCo co-seqType (CoercionTy co) = seqCo co--seqTypes :: [Type] -> ()-seqTypes [] = ()-seqTypes (ty:tys) = seqType ty `seq` seqTypes tys--{--************************************************************************-* *- Comparison for types- (We don't use instances so that we know where it happens)-* *-************************************************************************--Note [Equality on AppTys]-~~~~~~~~~~~~~~~~~~~~~~~~~-In our cast-ignoring equality, we want to say that the following two-are equal:-- (Maybe |> co) (Int |> co') ~? Maybe Int--But the left is an AppTy while the right is a TyConApp. The solution is-to use repSplitAppTy_maybe to break up the TyConApp into its pieces and-then continue. Easy to do, but also easy to forget to do.--Note [Comparing nullary type synonyms]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider the task of testing equality between two 'Type's of the form-- TyConApp tc []--where @tc@ is a type synonym. A naive way to perform this comparison these-would first expand the synonym and then compare the resulting expansions.--However, this is obviously wasteful and the RHS of @tc@ may be large; it is-much better to rather compare the TyCons directly. Consequently, before-expanding type synonyms in type comparisons we first look for a nullary-TyConApp and simply compare the TyCons if we find one. Of course, if we find-that the TyCons are *not* equal then we still need to perform the expansion as-their RHSs may still be equal.--We perform this optimisation in a number of places:-- * GHC.Core.Types.eqType- * GHC.Core.Types.nonDetCmpType- * GHC.Core.Unify.unify_ty- * TcCanonical.can_eq_nc'- * TcUnify.uType--This optimisation is especially helpful for the ubiquitous GHC.Types.Type,-since GHC prefers to use the type synonym over @TYPE 'LiftedRep@ applications-whenever possible. See Note [Using synonyms to compress types] in-GHC.Core.Type for details.---}--eqType :: Type -> Type -> Bool--- ^ Type equality on source types. Does not look through @newtypes@,--- 'PredType's or type families, but it does look through type synonyms.--- This first checks that the kinds of the types are equal and then--- checks whether the types are equal, ignoring casts and coercions.--- (The kind check is a recursive call, but since all kinds have type--- @Type@, there is no need to check the types of kinds.)--- See also Note [Non-trivial definitional equality] in "GHC.Core.TyCo.Rep".-eqType t1 t2 = isEqual $ nonDetCmpType t1 t2- -- It's OK to use nonDetCmpType here and eqType is deterministic,- -- nonDetCmpType does equality deterministically---- | Compare types with respect to a (presumably) non-empty 'RnEnv2'.-eqTypeX :: RnEnv2 -> Type -> Type -> Bool-eqTypeX env t1 t2 = isEqual $ nonDetCmpTypeX env t1 t2- -- It's OK to use nonDetCmpType here and eqTypeX is deterministic,- -- nonDetCmpTypeX does equality deterministically---- | Type equality on lists of types, looking through type synonyms--- but not newtypes.-eqTypes :: [Type] -> [Type] -> Bool-eqTypes tys1 tys2 = isEqual $ nonDetCmpTypes tys1 tys2- -- It's OK to use nonDetCmpType here and eqTypes is deterministic,- -- nonDetCmpTypes does equality deterministically--eqVarBndrs :: RnEnv2 -> [Var] -> [Var] -> Maybe RnEnv2--- Check that the var lists are the same length--- and have matching kinds; if so, extend the RnEnv2--- Returns Nothing if they don't match-eqVarBndrs env [] []- = Just env-eqVarBndrs env (tv1:tvs1) (tv2:tvs2)- | eqTypeX env (varType tv1) (varType tv2)- = eqVarBndrs (rnBndr2 env tv1 tv2) tvs1 tvs2-eqVarBndrs _ _ _= Nothing---- Now here comes the real worker--{--Note [nonDetCmpType nondeterminism]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-nonDetCmpType is implemented in terms of nonDetCmpTypeX. nonDetCmpTypeX-uses nonDetCmpTc which compares TyCons by their Unique value. Using Uniques for-ordering leads to nondeterminism. We hit the same problem in the TyVarTy case,-comparing type variables is nondeterministic, note the call to nonDetCmpVar in-nonDetCmpTypeX.-See Note [Unique Determinism] for more details.--Note [Type comparisons using object pointer comparisons]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Quite often we substitute the type from a definition site into-occurances without a change. This means for code like:- \x -> (x,x,x)-The type of every `x` will often be represented by a single object-in the heap. We can take advantage of this by shortcutting the equality-check if two types are represented by the same pointer under the hood.-In some cases this reduces compiler allocations by ~2%.--Note [Computing equality on types]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-There are several places within GHC that depend on the precise choice of-definitional equality used. If we change that definition, all these places-must be updated. This Note merely serves as a place for all these places-to refer to, so searching for references to this Note will find every place-that needs to be updated.--See also Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep.---}--nonDetCmpType :: Type -> Type -> Ordering-nonDetCmpType !t1 !t2- -- See Note [Type comparisons using object pointer comparisons]- | 1# <- reallyUnsafePtrEquality# t1 t2- = EQ-nonDetCmpType (TyConApp tc1 []) (TyConApp tc2 []) | tc1 == tc2- = EQ-nonDetCmpType t1 t2 =- -- we know k1 and k2 have the same kind, because they both have kind *.- nonDetCmpTypeX rn_env t1 t2- where- rn_env = mkRnEnv2 (mkInScopeSet (tyCoVarsOfTypes [t1, t2]))-{-# INLINE nonDetCmpType #-}--nonDetCmpTypes :: [Type] -> [Type] -> Ordering-nonDetCmpTypes ts1 ts2 = nonDetCmpTypesX rn_env ts1 ts2- where- rn_env = mkRnEnv2 (mkInScopeSet (tyCoVarsOfTypes (ts1 ++ ts2)))---- | An ordering relation between two 'Type's (known below as @t1 :: k1@--- and @t2 :: k2@)-data TypeOrdering = TLT -- ^ @t1 < t2@- | TEQ -- ^ @t1 ~ t2@ and there are no casts in either,- -- therefore we can conclude @k1 ~ k2@- | TEQX -- ^ @t1 ~ t2@ yet one of the types contains a cast so- -- they may differ in kind.- | TGT -- ^ @t1 > t2@- deriving (Eq, Ord, Enum, Bounded)--nonDetCmpTypeX :: RnEnv2 -> Type -> Type -> Ordering -- Main workhorse- -- See Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep- -- See Note [Computing equality on types]-nonDetCmpTypeX env orig_t1 orig_t2 =- case go env orig_t1 orig_t2 of- -- If there are casts then we also need to do a comparison of the kinds of- -- the types being compared- TEQX -> toOrdering $ go env k1 k2- ty_ordering -> toOrdering ty_ordering- where- k1 = typeKind orig_t1- k2 = typeKind orig_t2-- toOrdering :: TypeOrdering -> Ordering- toOrdering TLT = LT- toOrdering TEQ = EQ- toOrdering TEQX = EQ- toOrdering TGT = GT-- liftOrdering :: Ordering -> TypeOrdering- liftOrdering LT = TLT- liftOrdering EQ = TEQ- liftOrdering GT = TGT-- thenCmpTy :: TypeOrdering -> TypeOrdering -> TypeOrdering- thenCmpTy TEQ rel = rel- thenCmpTy TEQX rel = hasCast rel- thenCmpTy rel _ = rel-- hasCast :: TypeOrdering -> TypeOrdering- hasCast TEQ = TEQX- hasCast rel = rel-- -- 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].- go _ (TyConApp tc1 []) (TyConApp tc2 [])- | tc1 == tc2- = TEQ- go env t1 t2- | Just t1' <- coreView t1 = go env t1' t2- | Just t2' <- coreView t2 = go env t1 t2'-- go env (TyVarTy tv1) (TyVarTy tv2)- = liftOrdering $ rnOccL env tv1 `nonDetCmpVar` rnOccR env tv2- go env (ForAllTy (Bndr tv1 _) t1) (ForAllTy (Bndr tv2 _) t2)- = go env (varType tv1) (varType tv2)- `thenCmpTy` go (rnBndr2 env tv1 tv2) t1 t2- -- See Note [Equality on AppTys]- go env (AppTy s1 t1) ty2- | Just (s2, t2) <- repSplitAppTy_maybe ty2- = go env s1 s2 `thenCmpTy` go env t1 t2- go env ty1 (AppTy s2 t2)- | Just (s1, t1) <- repSplitAppTy_maybe ty1- = go env s1 s2 `thenCmpTy` go env t1 t2- go env (FunTy _ w1 s1 t1) (FunTy _ w2 s2 t2)- -- NB: nonDepCmpTypeX does the kind check requested by- -- Note [Equality on FunTys] in GHC.Core.TyCo.Rep- = liftOrdering (nonDetCmpTypeX env s1 s2 S.<> nonDetCmpTypeX env t1 t2)- `thenCmpTy` go env w1 w2- -- Comparing multiplicities last because the test is usually true- go env (TyConApp tc1 tys1) (TyConApp tc2 tys2)- = liftOrdering (tc1 `nonDetCmpTc` tc2) `thenCmpTy` gos env tys1 tys2- go _ (LitTy l1) (LitTy l2) = liftOrdering (nonDetCmpTyLit l1 l2)- go env (CastTy t1 _) t2 = hasCast $ go env t1 t2- go env t1 (CastTy t2 _) = hasCast $ go env t1 t2-- go _ (CoercionTy {}) (CoercionTy {}) = TEQ-- -- Deal with the rest: TyVarTy < CoercionTy < AppTy < LitTy < TyConApp < ForAllTy- go _ ty1 ty2- = liftOrdering $ (get_rank ty1) `compare` (get_rank ty2)- where get_rank :: Type -> Int- get_rank (CastTy {})- = pprPanic "nonDetCmpTypeX.get_rank" (ppr [ty1,ty2])- get_rank (TyVarTy {}) = 0- get_rank (CoercionTy {}) = 1- get_rank (AppTy {}) = 3- get_rank (LitTy {}) = 4- get_rank (TyConApp {}) = 5- get_rank (FunTy {}) = 6- get_rank (ForAllTy {}) = 7-- gos :: RnEnv2 -> [Type] -> [Type] -> TypeOrdering- gos _ [] [] = TEQ- gos _ [] _ = TLT- gos _ _ [] = TGT- gos env (ty1:tys1) (ty2:tys2) = go env ty1 ty2 `thenCmpTy` gos env tys1 tys2----------------nonDetCmpTypesX :: RnEnv2 -> [Type] -> [Type] -> Ordering-nonDetCmpTypesX _ [] [] = EQ-nonDetCmpTypesX env (t1:tys1) (t2:tys2) = nonDetCmpTypeX env t1 t2 S.<>- nonDetCmpTypesX env tys1 tys2-nonDetCmpTypesX _ [] _ = LT-nonDetCmpTypesX _ _ [] = GT------------------ | Compare two 'TyCon's. NB: This should /never/ see 'Constraint' (as--- recognized by Kind.isConstraintKindCon) which is considered a synonym for--- 'Type' in Core.--- See Note [Kind Constraint and kind Type] in "GHC.Core.Type".--- See Note [nonDetCmpType nondeterminism]-nonDetCmpTc :: TyCon -> TyCon -> Ordering-nonDetCmpTc tc1 tc2- = assert (not (isConstraintKindCon tc1) && not (isConstraintKindCon tc2)) $- u1 `nonDetCmpUnique` u2- where- u1 = tyConUnique tc1- u2 = tyConUnique tc2--{--************************************************************************-* *- The kind of a type-* *-************************************************************************--Note [typeKind vs tcTypeKind]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-We have two functions to get the kind of a type-- * typeKind ignores the distinction between Constraint and *- * tcTypeKind respects the distinction between Constraint and *--tcTypeKind is used by the type inference engine, for which Constraint-and * are different; after that we use typeKind.--See also Note [coreView vs tcView]--Note [Kinding rules for types]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-In typeKind we consider Constraint and (TYPE LiftedRep) to be identical.-We then have-- t1 : TYPE rep1- t2 : TYPE rep2- (FUN) ----------------- t1 -> t2 : Type-- ty : TYPE rep- `a` is not free in rep-(FORALL) ------------------------ forall a. ty : TYPE rep--In tcTypeKind we consider Constraint and (TYPE LiftedRep) to be distinct:-- t1 : TYPE rep1- t2 : TYPE rep2- (FUN) ----------------- t1 -> t2 : Type-- t1 : Constraint- t2 : TYPE rep- (PRED1) ----------------- t1 => t2 : Type-- t1 : Constraint- t2 : Constraint- (PRED2) ---------------------- t1 => t2 : Constraint-- ty : TYPE rep- `a` is not free in rep-(FORALL1) ------------------------ forall a. ty : TYPE rep-- ty : Constraint-(FORALL2) -------------------------- forall a. ty : Constraint--Note that:-* The only way we distinguish '->' from '=>' is by the fact- that the argument is a PredTy. Both are FunTys--Note [Phantom type variables in kinds]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider-- type K (r :: RuntimeRep) = Type -- Note 'r' is unused- data T r :: K r -- T :: forall r -> K r- foo :: forall r. T r--The body of the forall in foo's type has kind (K r), and-normally it would make no sense to have- forall r. (ty :: K r)-because the kind of the forall would escape the binding-of 'r'. But in this case it's fine because (K r) expands-to Type, so we explicitly /permit/ the type- forall r. T r--To accommodate such a type, in typeKind (forall a.ty) we use-occCheckExpand to expand any type synonyms in the kind of 'ty'-to eliminate 'a'. See kinding rule (FORALL) in-Note [Kinding rules for types]--See also- * GHC.Core.Type.occCheckExpand- * GHC.Core.Utils.coreAltsType- * GHC.Tc.Validity.checkEscapingKind-all of which grapple with the same problem.--See #14939.--}--------------------------------typeKind :: HasDebugCallStack => Type -> Kind--- No need to expand synonyms-typeKind (TyConApp tc tys) = piResultTys (tyConKind tc) tys-typeKind (LitTy l) = typeLiteralKind l-typeKind (FunTy {}) = liftedTypeKind-typeKind (TyVarTy tyvar) = tyVarKind tyvar-typeKind (CastTy _ty co) = coercionRKind co-typeKind (CoercionTy co) = coercionType co--typeKind (AppTy fun arg)- = go fun [arg]- where- -- Accumulate the type arguments, so we can call piResultTys,- -- rather than a succession of calls to piResultTy (which is- -- asymptotically costly as the number of arguments increases)- go (AppTy fun arg) args = go fun (arg:args)- go fun args = piResultTys (typeKind fun) args--typeKind ty@(ForAllTy {})- = case occCheckExpand tvs body_kind of- -- We must make sure tv does not occur in kind- -- As it is already out of scope!- -- See Note [Phantom type variables in kinds]- Just k' -> k'- Nothing -> pprPanic "typeKind"- (ppr ty $$ ppr tvs $$ ppr body <+> dcolon <+> ppr body_kind)- where- (tvs, body) = splitForAllTyVars ty- body_kind = typeKind body-------------------------------------------------- Utilities to be used in GHC.Core.Unify,--- which uses "tc" functions------------------------------------------------tcTypeKind :: HasDebugCallStack => Type -> Kind--- No need to expand synonyms-tcTypeKind (TyConApp tc tys) = piResultTys (tyConKind tc) tys-tcTypeKind (LitTy l) = typeLiteralKind l-tcTypeKind (TyVarTy tyvar) = tyVarKind tyvar-tcTypeKind (CastTy _ty co) = coercionRKind co-tcTypeKind (CoercionTy co) = coercionType co--tcTypeKind (FunTy { ft_af = af, ft_res = res })- | InvisArg <- af- , tcIsConstraintKind (tcTypeKind res)- = constraintKind -- Eq a => Ord a :: Constraint- | otherwise -- Eq a => a -> a :: TYPE LiftedRep- = liftedTypeKind -- Eq a => Array# Int :: TYPE LiftedRep (not TYPE PtrRep)--tcTypeKind (AppTy fun arg)- = go fun [arg]- where- -- Accumulate the type arguments, so we can call piResultTys,- -- rather than a succession of calls to piResultTy (which is- -- asymptotically costly as the number of arguments increases)- go (AppTy fun arg) args = go fun (arg:args)- go fun args = piResultTys (tcTypeKind fun) args--tcTypeKind ty@(ForAllTy {})- | tcIsConstraintKind body_kind- = constraintKind-- | otherwise- = case occCheckExpand tvs body_kind of- -- We must make sure tv does not occur in kind- -- As it is already out of scope!- -- See Note [Phantom type variables in kinds]- Just k' -> k'- Nothing -> pprPanic "tcTypeKind"- (ppr ty $$ ppr tvs $$ ppr body <+> dcolon <+> ppr body_kind)- where- (tvs, body) = splitForAllTyVars ty- body_kind = tcTypeKind body---isPredTy :: HasDebugCallStack => Type -> Bool--- See Note [Types for coercions, predicates, and evidence] in GHC.Core.TyCo.Rep-isPredTy ty = tcIsConstraintKind (tcTypeKind ty)---- tcIsConstraintKind stuff only makes sense in the typechecker--- After that Constraint = Type--- See Note [coreView vs tcView]--- Defined here because it is used in isPredTy and tcRepSplitAppTy_maybe (sigh)-tcIsConstraintKind :: Kind -> Bool-tcIsConstraintKind ty- | Just (tc, args) <- tcSplitTyConApp_maybe ty -- Note: tcSplit here- , isConstraintKindCon tc- = assertPpr (null args) (ppr ty) True-- | otherwise- = False---- | Like 'kindRep_maybe', but considers 'Constraint' to be distinct--- from 'Type'. For a version that treats them as the same type, see--- 'kindRep_maybe'.-tcKindRep_maybe :: HasDebugCallStack => Kind -> Maybe RuntimeRepType-tcKindRep_maybe kind- | Just (tc, [arg]) <- tcSplitTyConApp_maybe kind -- Note: tcSplit here- , tc `hasKey` tYPETyConKey = Just arg- | otherwise = Nothing---- | Is this kind equivalent to 'Type'?------ This considers 'Constraint' to be distinct from 'Type'. For a version that--- treats them as the same type, see 'isLiftedTypeKind'.-tcIsLiftedTypeKind :: Kind -> Bool-tcIsLiftedTypeKind kind- = case tcKindRep_maybe kind of- Just rep -> isLiftedRuntimeRep rep- Nothing -> False---- | Is this kind equivalent to @TYPE (BoxedRep l)@ for some @l :: Levity@?------ This considers 'Constraint' to be distinct from 'Type'. For a version that--- treats them as the same type, see 'isLiftedTypeKind'.-tcIsBoxedTypeKind :: Kind -> Bool-tcIsBoxedTypeKind kind- = case tcKindRep_maybe kind of- Just rep -> isBoxedRuntimeRep rep- Nothing -> False---- | Is this kind equivalent to @TYPE r@ (for some unknown r)?------ This considers 'Constraint' to be distinct from @*@.-tcIsRuntimeTypeKind :: Kind -> Bool-tcIsRuntimeTypeKind kind = isJust (tcKindRep_maybe kind)--tcReturnsConstraintKind :: Kind -> Bool--- True <=> the Kind ultimately returns a Constraint--- E.g. * -> Constraint--- forall k. k -> Constraint-tcReturnsConstraintKind kind- | Just kind' <- tcView kind = tcReturnsConstraintKind kind'-tcReturnsConstraintKind (ForAllTy _ ty) = tcReturnsConstraintKind ty-tcReturnsConstraintKind (FunTy { ft_res = ty }) = tcReturnsConstraintKind ty-tcReturnsConstraintKind (TyConApp tc _) = isConstraintKindCon tc-tcReturnsConstraintKind _ = False-----------------------------typeLiteralKind :: TyLit -> Kind-typeLiteralKind (NumTyLit {}) = naturalTy-typeLiteralKind (StrTyLit {}) = typeSymbolKind-typeLiteralKind (CharTyLit {}) = charTy---- | Returns True if a type has a syntactically fixed runtime rep,--- as per Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete.------ This function is equivalent to @('isFixedRuntimeRepKind' . 'typeKind')@,--- but much faster.------ __Precondition:__ The type has kind @('TYPE' blah)@-typeHasFixedRuntimeRep :: Type -> Bool-typeHasFixedRuntimeRep = go- where- go (TyConApp tc _)- | tcHasFixedRuntimeRep tc = True- go (FunTy {}) = True- go (LitTy {}) = True- go (ForAllTy _ ty) = go ty- go ty = isFixedRuntimeRepKind (typeKind ty)--argsHaveFixedRuntimeRep :: Type -> Bool--- ^ True if the argument types of this function type--- all have a fixed-runtime-rep-argsHaveFixedRuntimeRep ty- = all ok bndrs- where- ok :: TyCoBinder -> Bool- ok (Anon _ ty) = typeHasFixedRuntimeRep (scaledThing ty)- ok _ = True-- bndrs :: [TyCoBinder]- (bndrs, _) = splitPiTys ty--{- **********************************************************************-* *- Occurs check expansion-%* *-%********************************************************************* -}--{- Note [Occurs check expansion]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-(occurCheckExpand tv xi) expands synonyms in xi just enough to get rid-of occurrences of tv outside type function arguments, if that is-possible; otherwise, it returns Nothing.--For example, suppose we have- type F a b = [a]-Then- occCheckExpand b (F Int b) = Just [Int]-but- occCheckExpand a (F a Int) = Nothing--We don't promise to do the absolute minimum amount of expanding-necessary, but we try not to do expansions we don't need to. We-prefer doing inner expansions first. For example,- type F a b = (a, Int, a, [a])- type G b = Char-We have- occCheckExpand b (F (G b)) = Just (F Char)-even though we could also expand F to get rid of b.--Note [Occurrence checking: look inside kinds]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Suppose we are considering unifying- (alpha :: *) ~ Int -> (beta :: alpha -> alpha)-This may be an error (what is that alpha doing inside beta's kind?),-but we must not make the mistake of actually unifying or we'll-build an infinite data structure. So when looking for occurrences-of alpha in the rhs, we must look in the kinds of type variables-that occur there.--occCheckExpand tries to expand type synonyms to remove-unnecessary occurrences of a variable, and thereby get past an-occurs-check failure. This is good; but- we can't do it in the /kind/ of a variable /occurrence/--For example #18451 built an infinite type:- type Const a b = a- data SameKind :: k -> k -> Type- type T (k :: Const Type a) = forall (b :: k). SameKind a b--We have- b :: k- k :: Const Type a- a :: k (must be same as b)--So if we aren't careful, a's kind mentions a, which is bad.-And expanding an /occurrence/ of 'a' doesn't help, because the-/binding site/ is the master copy and all the occurrences should-match it.--Here's a related example:- f :: forall a b (c :: Const Type b). Proxy '[a, c]--The list means that 'a' gets the same kind as 'c'; but that-kind mentions 'b', so the binders are out of order.--Bottom line: in occCheckExpand, do not expand inside the kinds-of occurrences. See bad_var_occ in occCheckExpand. And-see #18451 for more debate.--}--occCheckExpand :: [Var] -> Type -> Maybe Type--- See Note [Occurs check expansion]--- We may have needed to do some type synonym unfolding in order to--- get rid of the variable (or forall), so we also return the unfolded--- version of the type, which is guaranteed to be syntactically free--- of the given type variable. If the type is already syntactically--- free of the variable, then the same type is returned.-occCheckExpand vs_to_avoid ty- | null vs_to_avoid -- Efficient shortcut- = Just ty -- Can happen, eg. GHC.Core.Utils.mkSingleAltCase-- | otherwise- = go (mkVarSet vs_to_avoid, emptyVarEnv) ty- where- go :: (VarSet, VarEnv TyCoVar) -> Type -> Maybe Type- -- The VarSet is the set of variables we are trying to avoid- -- The VarEnv carries mappings necessary- -- because of kind expansion- go (as, env) ty@(TyVarTy tv)- | Just tv' <- lookupVarEnv env tv = return (mkTyVarTy tv')- | bad_var_occ as tv = Nothing- | otherwise = return ty-- go _ ty@(LitTy {}) = return ty- go cxt (AppTy ty1 ty2) = do { ty1' <- go cxt ty1- ; ty2' <- go cxt ty2- ; return (mkAppTy ty1' ty2') }- go cxt ty@(FunTy _ w ty1 ty2)- = do { w' <- go cxt w- ; ty1' <- go cxt ty1- ; ty2' <- go cxt ty2- ; return (ty { ft_mult = w', ft_arg = ty1', ft_res = ty2' }) }- go cxt@(as, env) (ForAllTy (Bndr tv vis) body_ty)- = do { ki' <- go cxt (varType tv)- ; let tv' = setVarType tv ki'- env' = extendVarEnv env tv tv'- as' = as `delVarSet` tv- ; body' <- go (as', env') body_ty- ; return (ForAllTy (Bndr tv' vis) body') }-- -- For a type constructor application, first try expanding away the- -- offending variable from the arguments. If that doesn't work, next- -- see if the type constructor is a type synonym, and if so, expand- -- it and try again.- go cxt ty@(TyConApp tc tys)- = case mapM (go cxt) tys of- Just tys' -> return (mkTyConApp tc tys')- Nothing | Just ty' <- tcView ty -> go cxt ty'- | otherwise -> Nothing- -- Failing that, try to expand a synonym-- go cxt (CastTy ty co) = do { ty' <- go cxt ty- ; co' <- go_co cxt co- ; return (mkCastTy ty' co') }- go cxt (CoercionTy co) = do { co' <- go_co cxt co- ; return (mkCoercionTy co') }-- ------------------- bad_var_occ :: VarSet -> Var -> Bool- -- Works for TyVar and CoVar- -- See Note [Occurrence checking: look inside kinds]- bad_var_occ vs_to_avoid v- = v `elemVarSet` vs_to_avoid- || tyCoVarsOfType (varType v) `intersectsVarSet` vs_to_avoid-- ------------------- go_mco _ MRefl = return MRefl- go_mco ctx (MCo co) = MCo <$> go_co ctx co-- ------------------- go_co cxt (Refl ty) = do { ty' <- go cxt ty- ; return (mkNomReflCo ty') }- go_co cxt (GRefl r ty mco) = do { mco' <- go_mco cxt mco- ; ty' <- go cxt ty- ; return (mkGReflCo r ty' mco') }- -- Note: Coercions do not contain type synonyms- go_co cxt (TyConAppCo r tc args) = do { args' <- mapM (go_co cxt) args- ; return (mkTyConAppCo r tc args') }- go_co cxt (AppCo co arg) = do { co' <- go_co cxt co- ; arg' <- go_co cxt arg- ; return (mkAppCo co' arg') }- go_co cxt@(as, env) (ForAllCo tv kind_co body_co)- = do { kind_co' <- go_co cxt kind_co- ; let tv' = setVarType tv $- coercionLKind kind_co'- env' = extendVarEnv env tv tv'- as' = as `delVarSet` tv- ; body' <- go_co (as', env') body_co- ; return (ForAllCo tv' kind_co' body') }- go_co cxt (FunCo r w co1 co2) = do { co1' <- go_co cxt co1- ; co2' <- go_co cxt co2- ; w' <- go_co cxt w- ; return (mkFunCo r w' co1' co2') }- go_co (as,env) co@(CoVarCo c)- | Just c' <- lookupVarEnv env c = return (mkCoVarCo c')- | bad_var_occ as c = Nothing- | otherwise = return co-- go_co (as,_) co@(HoleCo h)- | bad_var_occ as (ch_co_var h) = Nothing- | otherwise = return co-- go_co cxt (AxiomInstCo ax ind args) = do { args' <- mapM (go_co cxt) args- ; return (mkAxiomInstCo ax ind args') }- go_co cxt (UnivCo p r ty1 ty2) = do { p' <- go_prov cxt p- ; ty1' <- go cxt ty1- ; ty2' <- go cxt ty2- ; return (mkUnivCo p' r ty1' ty2') }- go_co cxt (SymCo co) = do { co' <- go_co cxt co- ; return (mkSymCo co') }- go_co cxt (TransCo co1 co2) = do { co1' <- go_co cxt co1- ; co2' <- go_co cxt co2- ; return (mkTransCo co1' co2') }- go_co cxt (NthCo r n co) = do { co' <- go_co cxt co- ; return (mkNthCo r n co') }- go_co cxt (LRCo lr co) = do { co' <- go_co cxt co- ; return (mkLRCo lr co') }- go_co cxt (InstCo co arg) = do { co' <- go_co cxt co- ; arg' <- go_co cxt arg- ; return (mkInstCo co' arg') }- go_co cxt (KindCo co) = do { co' <- go_co cxt co- ; return (mkKindCo co') }- go_co cxt (SubCo co) = do { co' <- go_co cxt co- ; return (mkSubCo co') }- go_co cxt (AxiomRuleCo ax cs) = do { cs' <- mapM (go_co cxt) cs- ; return (mkAxiomRuleCo ax cs') }-- ------------------- go_prov cxt (PhantomProv co) = PhantomProv <$> go_co cxt co- go_prov cxt (ProofIrrelProv co) = ProofIrrelProv <$> go_co cxt co- go_prov _ p@(PluginProv _) = return p- go_prov _ p@(CorePrepProv _) = return p---{--%************************************************************************-%* *- Miscellaneous functions-%* *-%************************************************************************---}--- | All type constructors occurring in the type; looking through type--- synonyms, but not newtypes.--- When it finds a Class, it returns the class TyCon.-tyConsOfType :: Type -> UniqSet TyCon-tyConsOfType ty- = go ty- where- go :: Type -> UniqSet TyCon -- The UniqSet does duplicate elim- go ty | Just ty' <- coreView ty = go ty'- go (TyVarTy {}) = emptyUniqSet- go (LitTy {}) = emptyUniqSet- go (TyConApp tc tys) = go_tc tc `unionUniqSets` go_s tys- go (AppTy a b) = go a `unionUniqSets` go b- go (FunTy _ w a b) = go w `unionUniqSets`- go a `unionUniqSets` go b `unionUniqSets` go_tc funTyCon- go (ForAllTy (Bndr tv _) ty) = go ty `unionUniqSets` go (varType tv)- go (CastTy ty co) = go ty `unionUniqSets` go_co co- go (CoercionTy co) = go_co co-- go_co (Refl ty) = go ty- go_co (GRefl _ ty mco) = go ty `unionUniqSets` go_mco mco- go_co (TyConAppCo _ tc args) = go_tc tc `unionUniqSets` go_cos args- go_co (AppCo co arg) = go_co co `unionUniqSets` go_co arg- go_co (ForAllCo _ kind_co co) = go_co kind_co `unionUniqSets` go_co co- go_co (FunCo _ co_mult co1 co2) = go_co co_mult `unionUniqSets` go_co co1 `unionUniqSets` go_co co2- go_co (AxiomInstCo ax _ args) = go_ax ax `unionUniqSets` go_cos args- go_co (UnivCo p _ t1 t2) = go_prov p `unionUniqSets` go t1 `unionUniqSets` go t2- go_co (CoVarCo {}) = emptyUniqSet- go_co (HoleCo {}) = emptyUniqSet- go_co (SymCo co) = go_co co- go_co (TransCo co1 co2) = go_co co1 `unionUniqSets` go_co co2- go_co (NthCo _ _ co) = go_co co- go_co (LRCo _ co) = go_co co- go_co (InstCo co arg) = go_co co `unionUniqSets` go_co arg- go_co (KindCo co) = go_co co- go_co (SubCo co) = go_co co- go_co (AxiomRuleCo _ cs) = go_cos cs-- go_mco MRefl = emptyUniqSet- go_mco (MCo co) = go_co co-- go_prov (PhantomProv co) = go_co co- go_prov (ProofIrrelProv co) = go_co co- go_prov (PluginProv _) = emptyUniqSet- go_prov (CorePrepProv _) = emptyUniqSet- -- this last case can happen from the tyConsOfType used from- -- checkTauTvUpdate-- go_s tys = foldr (unionUniqSets . go) emptyUniqSet tys- go_cos cos = foldr (unionUniqSets . go_co) emptyUniqSet cos-- go_tc tc = unitUniqSet tc- go_ax ax = go_tc $ coAxiomTyCon ax---- | Retrieve the free variables in this type, splitting them based--- on whether they are used visibly or invisibly. Invisible ones come--- first.-splitVisVarsOfType :: Type -> Pair TyCoVarSet-splitVisVarsOfType orig_ty = Pair invis_vars vis_vars- where- Pair invis_vars1 vis_vars = go orig_ty- invis_vars = invis_vars1 `minusVarSet` vis_vars-- go (TyVarTy tv) = Pair (tyCoVarsOfType $ tyVarKind tv) (unitVarSet tv)- go (AppTy t1 t2) = go t1 `mappend` go t2- go (TyConApp tc tys) = go_tc tc tys- go (FunTy _ w t1 t2) = go w `mappend` go t1 `mappend` go t2- go (ForAllTy (Bndr tv _) ty)- = ((`delVarSet` tv) <$> go ty) `mappend`- (invisible (tyCoVarsOfType $ varType tv))- go (LitTy {}) = mempty- go (CastTy ty co) = go ty `mappend` invisible (tyCoVarsOfCo co)- go (CoercionTy co) = invisible $ tyCoVarsOfCo co-- invisible vs = Pair vs emptyVarSet-- go_tc tc tys = let (invis, vis) = partitionInvisibleTypes tc tys in- invisible (tyCoVarsOfTypes invis) `mappend` foldMap go vis--splitVisVarsOfTypes :: [Type] -> Pair TyCoVarSet-splitVisVarsOfTypes = foldMap splitVisVarsOfType--{--************************************************************************-* *- Functions over Kinds-* *-************************************************************************--Note [Kind Constraint and kind Type]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The kind Constraint is the kind of classes and other type constraints.-The special thing about types of kind Constraint is that- * They are displayed with double arrow:- f :: Ord a => a -> a- * They are implicitly instantiated at call sites; so the type inference- engine inserts an extra argument of type (Ord a) at every call site- to f.--However, once type inference is over, there is *no* distinction between-Constraint and Type. Indeed we can have coercions between the two. Consider- class C a where- op :: a -> a-For this single-method class we may generate a newtype, which in turn-generates an axiom witnessing- C a ~ (a -> a)-so on the left we have Constraint, and on the right we have Type.-See #7451.--Because we treat Constraint/Type differently during and after type inference,-GHC has two notions of equality that differ in whether they equate-Constraint/Type or not:--* GHC.Tc.Utils.TcType.tcEqType implements typechecker equality (see- Note [Typechecker equality vs definitional equality] in GHC.Tc.Utils.TcType),- which treats Constraint and Type as distinct. This is used during type- inference. See #11715 for issues that arise from this.-* GHC.Core.TyCo.Rep.eqType implements definitional equality (see- Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep), which treats- Constraint and Type as equal. This is used after type inference.--Bottom line: although 'Type' and 'Constraint' are distinct TyCons, with-distinct uniques, they are treated as equal at all times except-during type inference.--}---- | Checks that a kind of the form 'Type', 'Constraint'--- or @'TYPE r@ is concrete. See 'isConcrete'.------ __Precondition:__ The type has kind @('TYPE' blah)@.-isFixedRuntimeRepKind :: HasDebugCallStack => Kind -> Bool-isFixedRuntimeRepKind k- = assertPpr (isLiftedTypeKind k || _is_type) (ppr k) $- -- the isLiftedTypeKind check is necessary b/c of Constraint- isConcrete k- where- _is_type = classifiesTypeWithValues k---- | Tests whether the given type is concrete, i.e. it--- whether it consists only of concrete type constructors,--- concrete type variables, and applications.------ See Note [Concrete types] in GHC.Tc.Utils.Concrete.-isConcrete :: Type -> Bool-isConcrete = go- where- go ty | Just ty' <- coreView ty = go ty'- go (TyVarTy tv) = isConcreteTyVar tv- go (AppTy ty1 ty2) = go ty1 && go ty2- go (TyConApp tc tys)- | isConcreteTyCon tc = all go tys- | otherwise = False- go ForAllTy{} = False- go (FunTy _ w t1 t2) = go w- && go (typeKind t1) && go t1- && go (typeKind t2) && go t2- go LitTy{} = True- go CastTy{} = False- go CoercionTy{} = False---------------------------------------------- | Does this classify a type allowed to have values? Responds True to things--- like *, TYPE Lifted, TYPE IntRep, TYPE v, Constraint.-classifiesTypeWithValues :: Kind -> Bool--- ^ True of any sub-kind of OpenTypeKind-classifiesTypeWithValues k = isJust (kindRep_maybe k)--{--%************************************************************************-%* *- Pretty-printing-%* *-%************************************************************************--Most pretty-printing is either in GHC.Core.TyCo.Rep or GHC.Iface.Type.---}---- | Does a 'TyCon' (that is applied to some number of arguments) need to be--- ascribed with an explicit kind signature to resolve ambiguity if rendered as--- a source-syntax type?--- (See @Note [When does a tycon application need an explicit kind signature?]@--- for a full explanation of what this function checks for.)-tyConAppNeedsKindSig- :: Bool -- ^ Should specified binders count towards injective positions in- -- the kind of the TyCon? (If you're using visible kind- -- applications, then you want True here.- -> TyCon- -> Int -- ^ The number of args the 'TyCon' is applied to.- -> Bool -- ^ Does @T t_1 ... t_n@ need a kind signature? (Where @n@ is the- -- number of arguments)-tyConAppNeedsKindSig spec_inj_pos tc n_args- | LT <- listLengthCmp tc_binders n_args- = False- | otherwise- = let (dropped_binders, remaining_binders)- = splitAt n_args tc_binders- result_kind = mkTyConKind remaining_binders tc_res_kind- result_vars = tyCoVarsOfType result_kind- dropped_vars = fvVarSet $- mapUnionFV injective_vars_of_binder dropped_binders-- in not (subVarSet result_vars dropped_vars)- where- tc_binders = tyConBinders tc- tc_res_kind = tyConResKind tc-- -- Returns the variables that would be fixed by knowing a TyConBinder. See- -- Note [When does a tycon application need an explicit kind signature?]- -- for a more detailed explanation of what this function does.- injective_vars_of_binder :: TyConBinder -> FV- injective_vars_of_binder (Bndr tv vis) =- case vis of- AnonTCB VisArg -> injectiveVarsOfType False -- conservative choice- (varType tv)- NamedTCB argf | source_of_injectivity argf- -> unitFV tv `unionFV`- injectiveVarsOfType False (varType tv)- _ -> emptyFV-- source_of_injectivity Required = True- source_of_injectivity Specified = spec_inj_pos- source_of_injectivity Inferred = False--{--Note [When does a tycon application need an explicit kind signature?]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-There are a couple of places in GHC where we convert Core Types into forms that-more closely resemble user-written syntax. These include:--1. Template Haskell Type reification (see, for instance, GHC.Tc.Gen.Splice.reify_tc_app)-2. Converting Types to LHsTypes (such as in Haddock.Convert in haddock)--This conversion presents a challenge: how do we ensure that the resulting type-has enough kind information so as not to be ambiguous? To better motivate this-question, consider the following Core type:-- -- Foo :: Type -> Type- type Foo = Proxy Type--There is nothing ambiguous about the RHS of Foo in Core. But if we were to,-say, reify it into a TH Type, then it's tempting to just drop the invisible-Type argument and simply return `Proxy`. But now we've lost crucial kind-information: we don't know if we're dealing with `Proxy Type` or `Proxy Bool`-or `Proxy Int` or something else! We've inadvertently introduced ambiguity.--Unlike in other situations in GHC, we can't just turn on--fprint-explicit-kinds, as we need to produce something which has the same-structure as a source-syntax type. Moreover, we can't rely on visible kind-application, since the first kind argument to Proxy is inferred, not specified.-Our solution is to annotate certain tycons with their kinds whenever they-appear in applied form in order to resolve the ambiguity. For instance, we-would reify the RHS of Foo like so:-- type Foo = (Proxy :: Type -> Type)--We need to devise an algorithm that determines precisely which tycons need-these explicit kind signatures. We certainly don't want to annotate _every_-tycon with a kind signature, or else we might end up with horribly bloated-types like the following:-- (Either :: Type -> Type -> Type) (Int :: Type) (Char :: Type)--We only want to annotate tycons that absolutely require kind signatures in-order to resolve some sort of ambiguity, and nothing more.--Suppose we have a tycon application (T ty_1 ... ty_n). Why might this type-require a kind signature? It might require it when we need to fill in any of-T's omitted arguments. By "omitted argument", we mean one that is dropped when-reifying ty_1 ... ty_n. Sometimes, the omitted arguments are inferred and-specified arguments (e.g., TH reification in GHC.Tc.Gen.Splice), and sometimes the-omitted arguments are only the inferred ones (e.g., in situations where-specified arguments are reified through visible kind application).-Regardless, the key idea is that _some_ arguments are going to be omitted after-reification, and the only mechanism we have at our disposal for filling them in-is through explicit kind signatures.--What do we mean by "fill in"? Let's consider this small example:-- T :: forall {k}. Type -> (k -> Type) -> k--Moreover, we have this application of T:-- T @{j} Int aty--When we reify this type, we omit the inferred argument @{j}. Is it fixed by the-other (non-inferred) arguments? Yes! If we know the kind of (aty :: blah), then-we'll generate an equality constraint (kappa -> Type) and, assuming we can-solve it, that will fix `kappa`. (Here, `kappa` is the unification variable-that we instantiate `k` with.)--Therefore, for any application of a tycon T to some arguments, the Question We-Must Answer is:--* Given the first n arguments of T, do the kinds of the non-omitted arguments- fill in the omitted arguments?--(This is still a bit hand-wavy, but we'll refine this question incrementally-as we explain more of the machinery underlying this process.)--Answering this question is precisely the role that the `injectiveVarsOfType`-and `injective_vars_of_binder` functions exist to serve. If an omitted argument-`a` appears in the set returned by `injectiveVarsOfType ty`, then knowing-`ty` determines (i.e., fills in) `a`. (More on `injective_vars_of_binder` in a-bit.)--More formally, if-`a` is in `injectiveVarsOfType ty`-and S1(ty) ~ S2(ty),-then S1(a) ~ S2(a),-where S1 and S2 are arbitrary substitutions.--For example, is `F` is a non-injective type family, then-- injectiveVarsOfType(Either c (Maybe (a, F b c))) = {a, c}--Now that we know what this function does, here is a second attempt at the-Question We Must Answer:--* Given the first n arguments of T (ty_1 ... ty_n), consider the binders- of T that are instantiated by non-omitted arguments. Do the injective- variables of these binders fill in the remainder of T's kind?--Alright, we're getting closer. Next, we need to clarify what the injective-variables of a tycon binder are. This the role that the-`injective_vars_of_binder` function serves. Here is what this function does for-each form of tycon binder:--* Anonymous binders are injective positions. For example, in the promoted data- constructor '(:):-- '(:) :: forall a. a -> [a] -> [a]-- The second and third tyvar binders (of kinds `a` and `[a]`) are both- anonymous, so if we had '(:) 'True '[], then the kinds of 'True and- '[] would contribute to the kind of '(:) 'True '[]. Therefore,- injective_vars_of_binder(_ :: a) = injectiveVarsOfType(a) = {a}.- (Similarly, injective_vars_of_binder(_ :: [a]) = {a}.)-* Named binders:- - Inferred binders are never injective positions. For example, in this data- type:-- data Proxy a- Proxy :: forall {k}. k -> Type-- If we had Proxy 'True, then the kind of 'True would not contribute to the- kind of Proxy 'True. Therefore,- injective_vars_of_binder(forall {k}. ...) = {}.- - Required binders are injective positions. For example, in this data type:-- data Wurble k (a :: k) :: k- Wurble :: forall k -> k -> k-- The first tyvar binder (of kind `forall k`) has required visibility, so if- we had Wurble (Maybe a) Nothing, then the kind of Maybe a would- contribute to the kind of Wurble (Maybe a) Nothing. Hence,- injective_vars_of_binder(forall a -> ...) = {a}.- - Specified binders /might/ be injective positions, depending on how you- approach things. Continuing the '(:) example:-- '(:) :: forall a. a -> [a] -> [a]-- Normally, the (forall a. ...) tyvar binder wouldn't contribute to the kind- of '(:) 'True '[], since it's not explicitly instantiated by the user. But- if visible kind application is enabled, then this is possible, since the- user can write '(:) @Bool 'True '[]. (In that case,- injective_vars_of_binder(forall a. ...) = {a}.)-- There are some situations where using visible kind application is appropriate- and others where it is not (e.g., TH- reification), so the `injective_vars_of_binder` function is parameterized by- a Bool which decides if specified binders should be counted towards- injective positions or not.--Now that we've defined injective_vars_of_binder, we can refine the Question We-Must Answer once more:--* Given the first n arguments of T (ty_1 ... ty_n), consider the binders- of T that are instantiated by non-omitted arguments. For each such binder- b_i, take the union of all injective_vars_of_binder(b_i). Is this set a- superset of the free variables of the remainder of T's kind?--If the answer to this question is "no", then (T ty_1 ... ty_n) needs an-explicit kind signature, since T's kind has kind variables leftover that-aren't fixed by the non-omitted arguments.--One last sticking point: what does "the remainder of T's kind" mean? You might-be tempted to think that it corresponds to all of the arguments in the kind of-T that would normally be instantiated by omitted arguments. But this isn't-quite right, strictly speaking. Consider the following (silly) example:-- S :: forall {k}. Type -> Type--And suppose we have this application of S:-- S Int Bool--The Int argument would be omitted, and-injective_vars_of_binder(_ :: Type) = {}. This is not a superset of {k}, which-might suggest that (S Bool) needs an explicit kind signature. But-(S Bool :: Type) doesn't actually fix `k`! This is because the kind signature-only affects the /result/ of the application, not all of the individual-arguments. So adding a kind signature here won't make a difference. Therefore,-the fourth (and final) iteration of the Question We Must Answer is:--* Given the first n arguments of T (ty_1 ... ty_n), consider the binders- of T that are instantiated by non-omitted arguments. For each such binder- b_i, take the union of all injective_vars_of_binder(b_i). Is this set a- superset of the free variables of the kind of (T ty_1 ... ty_n)?--Phew, that was a lot of work!--How can be sure that this is correct? That is, how can we be sure that in the-event that we leave off a kind annotation, that one could infer the kind of the-tycon application from its arguments? It's essentially a proof by induction: if-we can infer the kinds of every subtree of a type, then the whole tycon-application will have an inferrable kind--unless, of course, the remainder of-the tycon application's kind has uninstantiated kind variables.--What happens if T is oversaturated? That is, if T's kind has fewer than n-arguments, in the case that the concrete application instantiates a result-kind variable with an arrow kind? If we run out of arguments, we do not attach-a kind annotation. This should be a rare case, indeed. Here is an example:-- data T1 :: k1 -> k2 -> *- data T2 :: k1 -> k2 -> *-- type family G (a :: k) :: k- type instance G T1 = T2-- type instance F Char = (G T1 Bool :: (* -> *) -> *) -- F from above--Here G's kind is (forall k. k -> k), and the desugared RHS of that last-instance of F is (G (* -> (* -> *) -> *) (T1 * (* -> *)) Bool). According to-the algorithm above, there are 3 arguments to G so we should peel off 3-arguments in G's kind. But G's kind has only two arguments. This is the-rare special case, and we choose not to annotate the application of G with-a kind signature. After all, we needn't do this, since that instance would-be reified as:-- type instance F Char = G (T1 :: * -> (* -> *) -> *) Bool--So the kind of G isn't ambiguous anymore due to the explicit kind annotation-on its argument. See #8953 and test th/T8953.--}--{--************************************************************************-* *- Multiplicities-* *-************************************************************************--These functions would prefer to be in GHC.Core.Multiplicity, but-they some are used elsewhere in this module, and wanted to bring-their friends here with them.--}--unrestricted, linear, tymult :: a -> Scaled a---- | Scale a payload by Many-unrestricted = Scaled Many---- | Scale a payload by One-linear = Scaled One---- | Scale a payload by Many; used for type arguments in core-tymult = Scaled Many--irrelevantMult :: Scaled a -> a-irrelevantMult = scaledThing--mkScaled :: Mult -> a -> Scaled a-mkScaled = Scaled--scaledSet :: Scaled a -> b -> Scaled b-scaledSet (Scaled m _) b = Scaled m b--pattern One :: Mult-pattern One <- (isOneDataConTy -> True)- where One = oneDataConTy--pattern Many :: Mult-pattern Many <- (isManyDataConTy -> True)- where Many = manyDataConTy--isManyDataConTy :: Mult -> Bool-isManyDataConTy ty- | Just tc <- tyConAppTyCon_maybe ty- = tc `hasKey` manyDataConKey-isManyDataConTy _ = False--isOneDataConTy :: Mult -> Bool-isOneDataConTy ty- | Just tc <- tyConAppTyCon_maybe ty- = tc `hasKey` oneDataConKey-isOneDataConTy _ = False--isLinearType :: Type -> Bool--- ^ @isLinear t@ returns @True@ of a if @t@ is a type of (curried) function--- where at least one argument is linear (or otherwise non-unrestricted). We use--- this function to check whether it is safe to eta reduce an Id in CorePrep. It--- is always safe to return 'True', because 'True' deactivates the optimisation.-isLinearType ty = case ty of- FunTy _ Many _ res -> isLinearType res- FunTy _ _ _ _ -> True- ForAllTy _ res -> isLinearType res- _ -> False+{-# LANGUAGE FlexibleContexts, PatternSynonyms, ViewPatterns, MultiWayIf #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++-- | Main functions for manipulating types and type-related things+module GHC.Core.Type (+ -- Note some of this is just re-exports from TyCon..++ -- * Main data types representing Types+ -- $type_classification++ -- $representation_types+ Type, ForAllTyFlag(..), FunTyFlag(..),+ Specificity(..),+ KindOrType, PredType, ThetaType, FRRType,+ Var, TyVar, isTyVar, TyCoVar, PiTyBinder, ForAllTyBinder, TyVarBinder,+ Mult, Scaled,+ KnotTied, RuntimeRepType,++ -- ** Constructing and deconstructing types+ mkTyVarTy, mkTyVarTys, getTyVar, getTyVar_maybe, repGetTyVar_maybe,+ getCastedTyVar_maybe, tyVarKind, varType,++ mkAppTy, mkAppTys, splitAppTy, splitAppTys, splitAppTysNoView,+ splitAppTy_maybe, splitAppTyNoView_maybe, tcSplitAppTyNoView_maybe,++ mkFunTy, mkVisFunTy,+ mkVisFunTyMany, mkVisFunTysMany,+ mkScaledFunTys,+ mkInvisFunTy, mkInvisFunTys,+ tcMkVisFunTy, tcMkScaledFunTys, tcMkInvisFunTy,+ splitFunTy, splitFunTy_maybe,+ splitFunTys, funResultTy, funArgTy,+ funTyConAppTy_maybe, funTyFlagTyCon,+ tyConAppFunTy_maybe, tyConAppFunCo_maybe,+ mkFunctionType, mkScaledFunctionTys, chooseFunTyFlag,++ mkTyConApp, mkTyConTy,+ tyConAppTyCon_maybe, tyConAppTyConPicky_maybe,+ tyConAppArgs_maybe, tyConAppTyCon, tyConAppArgs,++ splitTyConApp_maybe, splitTyConAppNoView_maybe, splitTyConApp,+ tcSplitTyConApp, tcSplitTyConApp_maybe,++ mkForAllTy, mkForAllTys, mkInvisForAllTys, mkTyCoInvForAllTys,+ mkSpecForAllTy, mkSpecForAllTys,+ mkVisForAllTys, mkTyCoInvForAllTy,+ mkInfForAllTy, mkInfForAllTys,+ splitForAllTyCoVars,+ splitForAllReqTyBinders, splitForAllInvisTyBinders,+ splitForAllForAllTyBinders,+ splitForAllTyCoVar_maybe, splitForAllTyCoVar,+ splitForAllTyVar_maybe, splitForAllCoVar_maybe,+ splitPiTy_maybe, splitPiTy, splitPiTys,+ getRuntimeArgTys,+ mkTyConBindersPreferAnon,+ mkPiTy, mkPiTys,+ piResultTy, piResultTys,+ applyTysX, dropForAlls,+ mkFamilyTyConApp,+ buildSynTyCon,++ mkNumLitTy, isNumLitTy,+ mkStrLitTy, isStrLitTy,+ mkCharLitTy, isCharLitTy,+ isLitTy,++ isPredTy,++ getRuntimeRep, splitRuntimeRep_maybe, kindRep_maybe, kindRep,+ getLevity, levityType_maybe,++ mkCastTy, mkCoercionTy, splitCastTy_maybe,++ userTypeError_maybe, pprUserTypeErrorTy,++ coAxNthLHS,+ stripCoercionTy,++ splitInvisPiTys, splitInvisPiTysN,+ invisibleTyBndrCount,+ filterOutInvisibleTypes, filterOutInferredTypes,+ partitionInvisibleTypes, partitionInvisibles,+ tyConForAllTyFlags, appTyForAllTyFlags,++ -- ** Analyzing types+ TyCoMapper(..), mapTyCo, mapTyCoX,+ TyCoFolder(..), foldTyCo, noView,++ -- (Newtypes)+ newTyConInstRhs,++ -- ** Binders+ mkForAllTyBinder, mkForAllTyBinders,+ mkTyVarBinder, mkTyVarBinders,+ tyVarSpecToBinders,+ isAnonPiTyBinder,+ binderVar, binderVars, binderType, binderFlag, binderFlags,+ piTyBinderType, namedPiTyBinder_maybe,+ anonPiTyBinderType_maybe,+ isVisibleForAllTyFlag, isInvisibleForAllTyFlag, isVisiblePiTyBinder,+ isInvisiblePiTyBinder, isNamedPiTyBinder,+ tyConBindersPiTyBinders,++ -- ** Predicates on types+ isTyVarTy, isFunTy, isCoercionTy,+ isCoercionTy_maybe, isForAllTy,+ isForAllTy_ty, isForAllTy_co,+ isPiTy, isTauTy, isFamFreeTy,+ isCoVarType, isAtomicTy,++ isValidJoinPointType,+ tyConAppNeedsKindSig,++ -- * Space-saving construction+ mkTYPEapp, mkTYPEapp_maybe,+ mkCONSTRAINTapp, mkCONSTRAINTapp_maybe,+ mkBoxedRepApp_maybe, mkTupleRepApp_maybe,+ typeOrConstraintKind,++ -- *** Levity and boxity+ sORTKind_maybe, typeTypeOrConstraint,+ typeLevity_maybe,+ isLiftedTypeKind, isUnliftedTypeKind, pickyIsLiftedTypeKind,+ isLiftedRuntimeRep, isUnliftedRuntimeRep, runtimeRepLevity_maybe,+ isBoxedRuntimeRep,+ isLiftedLevity, isUnliftedLevity,+ isUnliftedType, isBoxedType, isUnboxedTupleType, isUnboxedSumType,+ kindBoxedRepLevity_maybe,+ mightBeLiftedType, mightBeUnliftedType,+ isAlgType, isDataFamilyAppType,+ isPrimitiveType, isStrictType,+ isLevityTy, isLevityVar,+ isRuntimeRepTy, isRuntimeRepVar, isRuntimeRepKindedTy,+ dropRuntimeRepArgs,++ -- * Multiplicity++ isMultiplicityTy, isMultiplicityVar,+ unrestricted, linear, tymult,+ mkScaled, irrelevantMult, scaledSet,+ pattern OneTy, pattern ManyTy,+ isOneTy, isManyTy,+ isLinearType,++ -- * Main data types representing Kinds+ Kind,++ -- ** Finding the kind of a type+ typeKind, typeHasFixedRuntimeRep, argsHaveFixedRuntimeRep,+ tcIsLiftedTypeKind,+ isConstraintKind, isConstraintLikeKind, returnsConstraintKind,+ tcIsBoxedTypeKind, isTypeLikeKind,++ -- ** Common Kind+ liftedTypeKind, unliftedTypeKind,++ -- * Type free variables+ tyCoFVsOfType, tyCoFVsBndr, tyCoFVsVarBndr, tyCoFVsVarBndrs,+ tyCoVarsOfType, tyCoVarsOfTypes,+ tyCoVarsOfTypeDSet,+ coVarsOfType,+ coVarsOfTypes,++ anyFreeVarsOfType, anyFreeVarsOfTypes,+ noFreeVarsOfType,+ expandTypeSynonyms,+ typeSize, occCheckExpand,++ -- ** Closing over kinds+ closeOverKindsDSet, closeOverKindsList,+ closeOverKinds,++ -- * Well-scoped lists of variables+ scopedSort, tyCoVarsOfTypeWellScoped,+ tyCoVarsOfTypesWellScoped,++ -- * Forcing evaluation of types+ seqType, seqTypes,++ -- * Other views onto Types+ coreView,++ tyConsOfType,++ -- * Main type substitution data types+ TvSubstEnv, -- Representation widely visible+ IdSubstEnv,+ Subst(..), -- Representation visible to a few friends++ -- ** Manipulating type substitutions+ emptyTvSubstEnv, emptySubst, mkEmptySubst,++ mkSubst, zipTvSubst, mkTvSubstPrs,+ zipTCvSubst,+ notElemSubst,+ getTvSubstEnv,+ zapSubst, getSubstInScope, setInScope, getSubstRangeTyCoFVs,+ extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet,+ extendTCvSubst, extendCvSubst,+ extendTvSubst, extendTvSubstBinderAndInScope,+ extendTvSubstList, extendTvSubstAndInScope,+ extendTCvSubstList,+ extendTvSubstWithClone,+ extendTCvSubstWithClone,+ isInScope, composeTCvSubst, zipTyEnv, zipCoEnv,+ isEmptySubst, unionSubst, isEmptyTCvSubst,++ -- ** Performing substitution on types and kinds+ substTy, substTys, substScaledTy, substScaledTys, substTyWith, substTysWith, substTheta,+ substTyAddInScope,+ substTyUnchecked, substTysUnchecked, substScaledTyUnchecked, substScaledTysUnchecked,+ substThetaUnchecked, substTyWithUnchecked,+ substCo, substCoUnchecked, substCoWithUnchecked,+ substTyVarBndr, substTyVarBndrs, substTyVar, substTyVars,+ substVarBndr, substVarBndrs,+ substTyCoBndr, substTyVarToTyVar,+ cloneTyVarBndr, cloneTyVarBndrs, lookupTyVar,++ -- * Tidying type related things up for printing+ tidyType, tidyTypes,+ tidyOpenType, tidyOpenTypes,+ tidyVarBndr, tidyVarBndrs, tidyFreeTyCoVars,+ tidyOpenTyCoVar, tidyOpenTyCoVars,+ tidyTyCoVarOcc,+ tidyTopType,+ tidyForAllTyBinder, tidyForAllTyBinders,++ -- * Kinds+ isTYPEorCONSTRAINT,+ isConcrete, isFixedRuntimeRepKind,+ ) where++import GHC.Prelude++import GHC.Types.Basic++-- We import the representation and primitive functions from GHC.Core.TyCo.Rep.+-- Many things are reexported, but not the representation!++import GHC.Core.TyCo.Rep+import GHC.Core.TyCo.Subst+import GHC.Core.TyCo.Tidy+import GHC.Core.TyCo.FVs++-- friends:+import GHC.Types.Var+import GHC.Types.Var.Env+import GHC.Types.Var.Set+import GHC.Types.Unique.Set++import GHC.Core.TyCon+import GHC.Builtin.Types.Prim++import {-# SOURCE #-} GHC.Builtin.Types+ ( charTy, naturalTy+ , typeSymbolKind, liftedTypeKind, unliftedTypeKind+ , constraintKind, zeroBitTypeKind+ , manyDataConTy, oneDataConTy+ , liftedRepTy, unliftedRepTy, zeroBitRepTy )++import GHC.Types.Name( Name )+import GHC.Builtin.Names+import GHC.Core.Coercion.Axiom++import {-# SOURCE #-} GHC.Core.Coercion+ ( mkNomReflCo, mkGReflCo, mkReflCo+ , mkTyConAppCo, mkAppCo+ , mkForAllCo, mkFunCo2, mkAxiomInstCo, mkUnivCo+ , mkSymCo, mkTransCo, mkSelCo, mkLRCo, mkInstCo+ , mkKindCo, mkSubCo, mkFunCo1+ , decomposePiCos, coercionKind+ , coercionRKind, coercionType+ , isReflexiveCo, seqCo+ , topNormaliseNewType_maybe+ )+import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isConcreteTyVar )++-- others+import GHC.Utils.Misc+import GHC.Utils.FV+import GHC.Utils.Outputable+import GHC.Utils.Panic+import GHC.Utils.Panic.Plain+import GHC.Data.FastString++import Control.Monad ( guard )+import GHC.Data.Maybe ( orElse, isJust )++-- $type_classification+-- #type_classification#+--+-- Types are any, but at least one, of:+--+-- [Boxed] Iff its representation is a pointer to an object on the+-- GC'd heap. Operationally, heap objects can be entered as+-- a means of evaluation.+--+-- [Lifted] Iff it has bottom as an element: An instance of a+-- lifted type might diverge when evaluated.+-- GHC Haskell's unboxed types are unlifted.+-- An unboxed, but lifted type is not very useful.+-- (Example: A byte-represented type, where evaluating 0xff+-- computes the 12345678th collatz number modulo 0xff.)+-- Only lifted types may be unified with a type variable.+--+-- [Algebraic] Iff it is a type with one or more constructors, whether+-- declared with @data@ or @newtype@.+-- An algebraic type is one that can be deconstructed+-- with a case expression. There are algebraic types that+-- are not lifted types, like unlifted data types or+-- unboxed tuples.+--+-- [Data] Iff it is a type declared with @data@, or a boxed tuple.+-- There are also /unlifted/ data types.+--+-- [Primitive] Iff it is a built-in type that can't be expressed in Haskell.+--+-- [Unlifted] Anything that isn't lifted is considered unlifted.+--+-- Currently, all primitive types are unlifted, but that's not necessarily+-- the case: for example, @Int@ could be primitive.+--+-- Some primitive types are unboxed, such as @Int#@, whereas some are boxed+-- but unlifted (such as @ByteArray#@). The only primitive types that we+-- classify as algebraic are the unboxed tuples.+--+-- Some examples of type classifications that may make this a bit clearer are:+--+-- @+-- Type primitive boxed lifted algebraic+-- -----------------------------------------------------------------------------+-- Int# Yes No No No+-- ByteArray# Yes Yes No No+-- (\# a, b \#) Yes No No Yes+-- (\# a | b \#) Yes No No Yes+-- ( a, b ) No Yes Yes Yes+-- [a] No Yes Yes Yes+-- @++-- $representation_types+-- A /source type/ is a type that is a separate type as far as the type checker is+-- concerned, but which has a more low-level representation as far as Core-to-Core+-- passes and the rest of the back end is concerned.+--+-- You don't normally have to worry about this, as the utility functions in+-- this module will automatically convert a source into a representation type+-- if they are spotted, to the best of its abilities. If you don't want this+-- to happen, use the equivalent functions from the "TcType" module.++{-+************************************************************************+* *+ Type representation+* *+************************************************************************+-}++coreView :: Type -> Maybe Type+-- ^ This function strips off the /top layer only/ of a type synonym+-- application (if any) its underlying representation type.+-- Returns 'Nothing' if there is nothing to look through.+--+-- This function does not look through type family applications.+--+-- By being non-recursive and inlined, this case analysis gets efficiently+-- joined onto the case analysis that the caller is already doing+coreView (TyConApp tc tys) = expandSynTyConApp_maybe tc tys+coreView _ = Nothing+-- See Note [Inlining coreView].+{-# INLINE coreView #-}++coreFullView, core_full_view :: Type -> Type+-- ^ Iterates 'coreView' until there is no more to synonym to expand.+-- NB: coreFullView is non-recursive and can be inlined;+-- core_full_view is the recursive one+-- See Note [Inlining coreView].+coreFullView ty@(TyConApp tc _)+ | isTypeSynonymTyCon tc = core_full_view ty+coreFullView ty = ty+{-# INLINE coreFullView #-}++core_full_view ty+ | Just ty' <- coreView ty = core_full_view ty'+ | otherwise = ty++-----------------------------------------------+-- | @expandSynTyConApp_maybe tc tys@ expands the RHS of type synonym @tc@+-- instantiated at arguments @tys@, or returns 'Nothing' if @tc@ is not a+-- synonym.+expandSynTyConApp_maybe :: TyCon -> [Type] -> Maybe Type+{-# INLINE expandSynTyConApp_maybe #-}+-- This INLINE will inline the call to expandSynTyConApp_maybe in coreView,+-- which will eliminate the allocation Just/Nothing in the result+-- Don't be tempted to make `expand_syn` (which is NOINLINE) return the+-- Just/Nothing, else you'll increase allocation+expandSynTyConApp_maybe tc arg_tys+ | Just (tvs, rhs) <- synTyConDefn_maybe tc+ , arg_tys `saturates` tyConArity tc+ = Just (expand_syn tvs rhs arg_tys)+ | otherwise+ = Nothing++saturates :: [Type] -> Arity -> Bool+saturates _ 0 = True+saturates [] _ = False+saturates (_:tys) n = assert( n >= 0 ) $ saturates tys (n-1)+ -- Arities are always positive; the assertion just checks+ -- that, to avoid an ininite loop in the bad case++-- | A helper for 'expandSynTyConApp_maybe' to avoid inlining this cold path+-- into call-sites.+--+-- Precondition: the call is saturated or over-saturated;+-- i.e. length tvs <= length arg_tys+expand_syn :: [TyVar] -- ^ the variables bound by the synonym+ -> Type -- ^ the RHS of the synonym+ -> [Type] -- ^ the type arguments the synonym is instantiated at.+ -> Type+{-# NOINLINE expand_syn #-} -- We never want to inline this cold-path.++expand_syn tvs rhs arg_tys+ -- No substitution necessary if either tvs or tys is empty+ -- This is both more efficient, and steers clear of an infinite+ -- loop; see Note [Care using synonyms to compress types]+ | null arg_tys = assert (null tvs) rhs+ | null tvs = mkAppTys rhs arg_tys+ | otherwise = go empty_subst tvs arg_tys+ where+ empty_subst = mkEmptySubst in_scope+ in_scope = mkInScopeSet $ shallowTyCoVarsOfTypes $ arg_tys+ -- The free vars of 'rhs' should all be bound by 'tenv',+ -- so we only need the free vars of tys+ -- See also Note [The substitution invariant] in GHC.Core.TyCo.Subst.++ go subst [] tys+ | null tys = rhs' -- Exactly Saturated+ | otherwise = mkAppTys rhs' tys+ -- Its important to use mkAppTys, rather than (foldl AppTy),+ -- because the function part might well return a+ -- partially-applied type constructor; indeed, usually will!+ where+ rhs' = substTy subst rhs++ go subst (tv:tvs) (ty:tys) = go (extendTvSubst subst tv ty) tvs tys++ go _ (_:_) [] = pprPanic "expand_syn" (ppr tvs $$ ppr rhs $$ ppr arg_tys)+ -- Under-saturated, precondition failed++{- Note [Inlining coreView]+~~~~~~~~~~~~~~~~~~~~~~~~~~~+It is very common to have a function++ f :: Type -> ...+ f ty | Just ty' <- coreView ty = f ty'+ f (TyVarTy ...) = ...+ f ... = ...++If f is not otherwise recursive, the initial call to coreView+causes f to become recursive, which kills the possibility of+inlining. Instead, for non-recursive functions, we prefer to+use coreFullView, which guarantees to unwrap top-level type+synonyms. It can be inlined and is efficient and non-allocating+in its fast path. For this to really be fast, all calls made+on its fast path must also be inlined, linked back to this Note.+-}+++{- *********************************************************************+* *+ expandTypeSynonyms+* *+********************************************************************* -}++expandTypeSynonyms :: Type -> Type+-- ^ Expand out all type synonyms. Actually, it'd suffice to expand out+-- just the ones that discard type variables (e.g. type Funny a = Int)+-- But we don't know which those are currently, so we just expand all.+--+-- 'expandTypeSynonyms' only expands out type synonyms mentioned in the type,+-- not in the kinds of any TyCon or TyVar mentioned in the type.+--+-- Keep this synchronized with 'synonymTyConsOfType'+expandTypeSynonyms ty+ = go (mkEmptySubst in_scope) ty+ where+ in_scope = mkInScopeSet (tyCoVarsOfType ty)++ go subst (TyConApp tc tys)+ | ExpandsSyn tenv rhs tys' <- expandSynTyCon_maybe tc expanded_tys+ = let subst' = mkTvSubst in_scope (mkVarEnv tenv)+ -- Make a fresh substitution; rhs has nothing to+ -- do with anything that has happened so far+ -- NB: if you make changes here, be sure to build an+ -- /idempotent/ substitution, even in the nested case+ -- type T a b = a -> b+ -- type S x y = T y x+ -- (#11665)+ in mkAppTys (go subst' rhs) tys'+ | otherwise+ = TyConApp tc expanded_tys+ where+ expanded_tys = (map (go subst) tys)++ go _ (LitTy l) = LitTy l+ go subst (TyVarTy tv) = substTyVar subst tv+ go subst (AppTy t1 t2) = mkAppTy (go subst t1) (go subst t2)+ go subst ty@(FunTy _ mult arg res)+ = ty { ft_mult = go subst mult, ft_arg = go subst arg, ft_res = go subst res }+ go subst (ForAllTy (Bndr tv vis) t)+ = let (subst', tv') = substVarBndrUsing go subst tv in+ ForAllTy (Bndr tv' vis) (go subst' t)+ go subst (CastTy ty co) = mkCastTy (go subst ty) (go_co subst co)+ go subst (CoercionTy co) = mkCoercionTy (go_co subst co)++ go_mco _ MRefl = MRefl+ go_mco subst (MCo co) = MCo (go_co subst co)++ go_co subst (Refl ty)+ = mkNomReflCo (go subst ty)+ go_co subst (GRefl r ty mco)+ = mkGReflCo r (go subst ty) (go_mco subst mco)+ -- NB: coercions are always expanded upon creation+ go_co subst (TyConAppCo r tc args)+ = mkTyConAppCo r tc (map (go_co subst) args)+ go_co subst (AppCo co arg)+ = mkAppCo (go_co subst co) (go_co subst arg)+ go_co subst (ForAllCo tv kind_co co)+ = let (subst', tv', kind_co') = go_cobndr subst tv kind_co in+ mkForAllCo tv' kind_co' (go_co subst' co)+ go_co subst (FunCo r afl afr w co1 co2)+ = mkFunCo2 r afl afr (go_co subst w) (go_co subst co1) (go_co subst co2)+ go_co subst (CoVarCo cv)+ = substCoVar subst cv+ go_co subst (AxiomInstCo ax ind args)+ = mkAxiomInstCo ax ind (map (go_co subst) args)+ go_co subst (UnivCo p r t1 t2)+ = mkUnivCo (go_prov subst p) r (go subst t1) (go subst t2)+ go_co subst (SymCo co)+ = mkSymCo (go_co subst co)+ go_co subst (TransCo co1 co2)+ = mkTransCo (go_co subst co1) (go_co subst co2)+ go_co subst (SelCo n co)+ = mkSelCo n (go_co subst co)+ go_co subst (LRCo lr co)+ = mkLRCo lr (go_co subst co)+ go_co subst (InstCo co arg)+ = mkInstCo (go_co subst co) (go_co subst arg)+ go_co subst (KindCo co)+ = mkKindCo (go_co subst co)+ go_co subst (SubCo co)+ = mkSubCo (go_co subst co)+ go_co subst (AxiomRuleCo ax cs)+ = AxiomRuleCo ax (map (go_co subst) cs)+ go_co _ (HoleCo h)+ = pprPanic "expandTypeSynonyms hit a hole" (ppr h)++ go_prov subst (PhantomProv co) = PhantomProv (go_co subst co)+ go_prov subst (ProofIrrelProv co) = ProofIrrelProv (go_co subst co)+ go_prov _ p@(PluginProv _) = p+ go_prov _ p@(CorePrepProv _) = p++ -- the "False" and "const" are to accommodate the type of+ -- substForAllCoBndrUsing, which is general enough to+ -- handle coercion optimization (which sometimes swaps the+ -- order of a coercion)+ go_cobndr subst = substForAllCoBndrUsing False (go_co subst) subst++{- Notes on type synonyms+~~~~~~~~~~~~~~~~~~~~~~~~~+The various "split" functions (splitFunTy, splitRhoTy, splitForAllTy) try+to return type synonyms wherever possible. Thus++ type Foo a = a -> a++we want+ splitFunTys (a -> Foo a) = ([a], Foo a)+not ([a], a -> a)++The reason is that we then get better (shorter) type signatures in+interfaces. Notably this plays a role in tcTySigs in GHC.Tc.Gen.Bind.+-}++{- *********************************************************************+* *+ Random functions (todo: organise)+* *+********************************************************************* -}++-- | An INLINE helper for function such as 'kindRep_maybe' below.+--+-- @isTyConKeyApp_maybe key ty@ returns @Just tys@ iff+-- the type @ty = T tys@, where T's unique = key+-- key must not be `fUNTyConKey`; to test for functions, use `splitFunTy_maybe`.+-- Thanks to this fact, we don't have to pattern match on `FunTy` here.+isTyConKeyApp_maybe :: Unique -> Type -> Maybe [Type]+isTyConKeyApp_maybe key ty+ | TyConApp tc args <- coreFullView ty+ , tc `hasKey` key+ = Just args+ | otherwise+ = Nothing+{-# INLINE isTyConKeyApp_maybe #-}++-- | Extract the RuntimeRep classifier of a type from its kind. For example,+-- @kindRep * = LiftedRep@; Panics if this is not possible.+-- Treats * and Constraint as the same+kindRep :: HasDebugCallStack => Kind -> RuntimeRepType+kindRep k = case kindRep_maybe k of+ Just r -> r+ Nothing -> pprPanic "kindRep" (ppr k)++-- | Given a kind (TYPE rr) or (CONSTRAINT rr), extract its RuntimeRep classifier rr.+-- For example, @kindRep_maybe * = Just LiftedRep@+-- Returns 'Nothing' if the kind is not of form (TYPE rr)+kindRep_maybe :: HasDebugCallStack => Kind -> Maybe RuntimeRepType+kindRep_maybe kind+ | Just (_, rep) <- sORTKind_maybe kind = Just rep+ | otherwise = Nothing++-- | Returns True if the argument is (lifted) Type or Constraint+-- See Note [TYPE and CONSTRAINT] in GHC.Builtin.Types.Prim+isLiftedTypeKind :: Kind -> Bool+isLiftedTypeKind kind+ = case kindRep_maybe kind of+ Just rep -> isLiftedRuntimeRep rep+ Nothing -> False++-- | Returns True if the kind classifies unlifted types (like 'Int#') and False+-- otherwise. Note that this returns False for representation-polymorphic+-- kinds, which may be specialized to a kind that classifies unlifted types.+isUnliftedTypeKind :: Kind -> Bool+isUnliftedTypeKind kind+ = case kindRep_maybe kind of+ Just rep -> isUnliftedRuntimeRep rep+ Nothing -> False++pickyIsLiftedTypeKind :: Kind -> Bool+-- Checks whether the kind is literally+-- TYPE LiftedRep+-- or TYPE ('BoxedRep 'Lifted)+-- or Type+-- without expanding type synonyms or anything+-- Used only when deciding whether to suppress the ":: *" in+-- (a :: *) when printing kinded type variables+-- See Note [Suppressing * kinds] in GHC.Core.TyCo.Ppr+pickyIsLiftedTypeKind kind+ | TyConApp tc [arg] <- kind+ , tc `hasKey` tYPETyConKey+ , TyConApp rr_tc rr_args <- arg = case rr_args of+ [] -> rr_tc `hasKey` liftedRepTyConKey+ [rr_arg]+ | rr_tc `hasKey` boxedRepDataConKey+ , TyConApp lev [] <- rr_arg+ , lev `hasKey` liftedDataConKey -> True+ _ -> False+ | TyConApp tc [] <- kind+ , tc `hasKey` liftedTypeKindTyConKey = True+ | otherwise = False++-- | Check whether a kind is of the form `TYPE (BoxedRep Lifted)`+-- or `TYPE (BoxedRep Unlifted)`.+--+-- Returns:+--+-- - `Just Lifted` for `TYPE (BoxedRep Lifted)` and `Type`,+-- - `Just Unlifted` for `TYPE (BoxedRep Unlifted)` and `UnliftedType`,+-- - `Nothing` for anything else, e.g. `TYPE IntRep`, `TYPE (BoxedRep l)`, etc.+kindBoxedRepLevity_maybe :: Type -> Maybe Levity+kindBoxedRepLevity_maybe ty+ | Just rep <- kindRep_maybe ty+ , isBoxedRuntimeRep rep+ = runtimeRepLevity_maybe rep+ | otherwise+ = Nothing++-- | Check whether a type of kind 'RuntimeRep' is lifted.+--+-- 'isLiftedRuntimeRep' is:+--+-- * True of @LiftedRep :: RuntimeRep@+-- * False of type variables, type family applications,+-- and of other reps such as @IntRep :: RuntimeRep@.+isLiftedRuntimeRep :: RuntimeRepType -> Bool+isLiftedRuntimeRep rep =+ runtimeRepLevity_maybe rep == Just Lifted++-- | Check whether a type of kind 'RuntimeRep' is unlifted.+--+-- * True of definitely unlifted 'RuntimeRep's such as+-- 'UnliftedRep', 'IntRep', 'FloatRep', ...+-- * False of 'LiftedRep',+-- * False for type variables and type family applications.+isUnliftedRuntimeRep :: RuntimeRepType -> Bool+isUnliftedRuntimeRep rep =+ runtimeRepLevity_maybe rep == Just Unlifted++-- | An INLINE helper for functions such as 'isLiftedLevity' and 'isUnliftedLevity'.+--+-- Checks whether the type is a nullary 'TyCon' application,+-- for a 'TyCon' with the given 'Unique'.+isNullaryTyConKeyApp :: Unique -> Type -> Bool+isNullaryTyConKeyApp key ty+ | Just args <- isTyConKeyApp_maybe key ty+ = assert (null args) True+ | otherwise+ = False+{-# INLINE isNullaryTyConKeyApp #-}++isLiftedLevity :: Type -> Bool+isLiftedLevity = isNullaryTyConKeyApp liftedDataConKey++isUnliftedLevity :: Type -> Bool+isUnliftedLevity = isNullaryTyConKeyApp unliftedDataConKey++-- | Is this the type 'Levity'?+isLevityTy :: Type -> Bool+isLevityTy = isNullaryTyConKeyApp levityTyConKey++-- | Is this the type 'RuntimeRep'?+isRuntimeRepTy :: Type -> Bool+isRuntimeRepTy = isNullaryTyConKeyApp runtimeRepTyConKey++-- | Is a tyvar of type 'RuntimeRep'?+isRuntimeRepVar :: TyVar -> Bool+isRuntimeRepVar = isRuntimeRepTy . tyVarKind++-- | Is a tyvar of type 'Levity'?+isLevityVar :: TyVar -> Bool+isLevityVar = isLevityTy . tyVarKind++-- | Is this the type 'Multiplicity'?+isMultiplicityTy :: Type -> Bool+isMultiplicityTy = isNullaryTyConKeyApp multiplicityTyConKey++-- | Is a tyvar of type 'Multiplicity'?+isMultiplicityVar :: TyVar -> Bool+isMultiplicityVar = isMultiplicityTy . tyVarKind++--------------------------------------------+-- Splitting RuntimeRep+--------------------------------------------++-- | (splitRuntimeRep_maybe rr) takes a Type rr :: RuntimeRep, and+-- returns the (TyCon,[Type]) for the RuntimeRep, if possible, where+-- the TyCon is one of the promoted DataCons of RuntimeRep.+-- Remember: the unique on TyCon that is a a promoted DataCon is the+-- same as the unique on the DataCon+-- See Note [Promoted data constructors] in GHC.Core.TyCon+-- May not be possible if `rr` is a type variable or type+-- family application+splitRuntimeRep_maybe :: RuntimeRepType -> Maybe (TyCon, [Type])+splitRuntimeRep_maybe rep+ | TyConApp rr_tc args <- coreFullView rep+ , isPromotedDataCon rr_tc+ -- isPromotedDataCon: be careful of type families (F tys) :: RuntimeRep,+ = Just (rr_tc, args)+ | otherwise+ = Nothing++-- | See 'isBoxedRuntimeRep_maybe'.+isBoxedRuntimeRep :: RuntimeRepType -> Bool+isBoxedRuntimeRep rep = isJust (isBoxedRuntimeRep_maybe rep)++-- | `isBoxedRuntimeRep_maybe (rep :: RuntimeRep)` returns `Just lev` if `rep`+-- expands to `Boxed lev` and returns `Nothing` otherwise.+--+-- Types with this runtime rep are represented by pointers on the GC'd heap.+isBoxedRuntimeRep_maybe :: RuntimeRepType -> Maybe Type+isBoxedRuntimeRep_maybe rep+ | Just (rr_tc, args) <- splitRuntimeRep_maybe rep+ , rr_tc `hasKey` boxedRepDataConKey+ , [lev] <- args+ = Just lev+ | otherwise+ = Nothing++-- | Check whether a type of kind 'RuntimeRep' is lifted, unlifted, or unknown.+--+-- `isLiftedRuntimeRep rr` returns:+--+-- * `Just Lifted` if `rr` is `LiftedRep :: RuntimeRep`+-- * `Just Unlifted` if `rr` is definitely unlifted, e.g. `IntRep`+-- * `Nothing` if not known (e.g. it's a type variable or a type family application).+runtimeRepLevity_maybe :: RuntimeRepType -> Maybe Levity+runtimeRepLevity_maybe rep+ | Just (rr_tc, args) <- splitRuntimeRep_maybe rep+ = -- NB: args might be non-empty e.g. TupleRep [r1, .., rn]+ if (rr_tc `hasKey` boxedRepDataConKey)+ then case args of+ [lev] -> levityType_maybe lev+ _ -> pprPanic "runtimeRepLevity_maybe" (ppr rep)+ else Just Unlifted+ -- Avoid searching all the unlifted RuntimeRep type cons+ -- In the RuntimeRep data type, only LiftedRep is lifted+ | otherwise+ = Nothing++--------------------------------------------+-- Splitting Levity+--------------------------------------------++-- | `levity_maybe` takes a Type of kind Levity, and returns its levity+-- May not be possible for a type variable or type family application+levityType_maybe :: LevityType -> Maybe Levity+levityType_maybe lev+ | TyConApp lev_tc args <- coreFullView lev+ = if | lev_tc `hasKey` liftedDataConKey -> assert( null args) $ Just Lifted+ | lev_tc `hasKey` unliftedDataConKey -> assert( null args) $ Just Unlifted+ | otherwise -> Nothing+ | otherwise+ = Nothing+++{- *********************************************************************+* *+ mapType+* *+************************************************************************++These functions do a map-like operation over types, performing some operation+on all variables and binding sites. Primarily used for zonking.++Note [Efficiency for ForAllCo case of mapTyCoX]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+As noted in Note [Forall coercions] in GHC.Core.TyCo.Rep, a ForAllCo is a bit redundant.+It stores a TyCoVar and a Coercion, where the kind of the TyCoVar always matches+the left-hand kind of the coercion. This is convenient lots of the time, but+not when mapping a function over a coercion.++The problem is that tcm_tybinder will affect the TyCoVar's kind and+mapCoercion will affect the Coercion, and we hope that the results will be+the same. Even if they are the same (which should generally happen with+correct algorithms), then there is an efficiency issue. In particular,+this problem seems to make what should be a linear algorithm into a potentially+exponential one. But it's only going to be bad in the case where there's+lots of foralls in the kinds of other foralls. Like this:++ forall a : (forall b : (forall c : ...). ...). ...++This construction seems unlikely. So we'll do the inefficient, easy way+for now.++Note [Specialising mappers]+~~~~~~~~~~~~~~~~~~~~~~~~~~~+These INLINE pragmas are indispensable. mapTyCo and mapTyCoX are used+to implement zonking, and it's vital that they get specialised to the TcM+monad and the particular mapper in use.++Even specialising to the monad alone made a 20% allocation difference+in perf/compiler/T5030.++See Note [Specialising foldType] in "GHC.Core.TyCo.Rep" for more details of this+idiom.+-}++-- | This describes how a "map" operation over a type/coercion should behave+data TyCoMapper env m+ = TyCoMapper+ { tcm_tyvar :: env -> TyVar -> m Type+ , tcm_covar :: env -> CoVar -> m Coercion+ , tcm_hole :: env -> CoercionHole -> m Coercion+ -- ^ What to do with coercion holes.+ -- See Note [Coercion holes] in "GHC.Core.TyCo.Rep".++ , tcm_tycobinder :: env -> TyCoVar -> ForAllTyFlag -> m (env, TyCoVar)+ -- ^ The returned env is used in the extended scope++ , tcm_tycon :: TyCon -> m TyCon+ -- ^ This is used only for TcTyCons+ -- a) To zonk TcTyCons+ -- b) To turn TcTyCons into TyCons.+ -- See Note [Type checking recursive type and class declarations]+ -- in "GHC.Tc.TyCl"+ }++{-# INLINE mapTyCo #-} -- See Note [Specialising mappers]+mapTyCo :: Monad m => TyCoMapper () m+ -> ( Type -> m Type+ , [Type] -> m [Type]+ , Coercion -> m Coercion+ , [Coercion] -> m[Coercion])+mapTyCo mapper+ = case mapTyCoX mapper of+ (go_ty, go_tys, go_co, go_cos)+ -> (go_ty (), go_tys (), go_co (), go_cos ())++{-# INLINE mapTyCoX #-} -- See Note [Specialising mappers]+mapTyCoX :: Monad m => TyCoMapper env m+ -> ( env -> Type -> m Type+ , env -> [Type] -> m [Type]+ , env -> Coercion -> m Coercion+ , env -> [Coercion] -> m[Coercion])+mapTyCoX (TyCoMapper { tcm_tyvar = tyvar+ , tcm_tycobinder = tycobinder+ , tcm_tycon = tycon+ , tcm_covar = covar+ , tcm_hole = cohole })+ = (go_ty, go_tys, go_co, go_cos)+ where+ go_tys _ [] = return []+ go_tys env (ty:tys) = (:) <$> go_ty env ty <*> go_tys env tys++ go_ty env (TyVarTy tv) = tyvar env tv+ go_ty env (AppTy t1 t2) = mkAppTy <$> go_ty env t1 <*> go_ty env t2+ go_ty _ ty@(LitTy {}) = return ty+ go_ty env (CastTy ty co) = mkCastTy <$> go_ty env ty <*> go_co env co+ go_ty env (CoercionTy co) = CoercionTy <$> go_co env co++ go_ty env ty@(FunTy _ w arg res)+ = do { w' <- go_ty env w; arg' <- go_ty env arg; res' <- go_ty env res+ ; return (ty { ft_mult = w', ft_arg = arg', ft_res = res' }) }++ go_ty env ty@(TyConApp tc tys)+ | isTcTyCon tc+ = do { tc' <- tycon tc+ ; mkTyConApp tc' <$> go_tys env tys }++ -- Not a TcTyCon+ | null tys -- Avoid allocation in this very+ = return ty -- common case (E.g. Int, LiftedRep etc)++ | otherwise+ = mkTyConApp tc <$> go_tys env tys++ go_ty env (ForAllTy (Bndr tv vis) inner)+ = do { (env', tv') <- tycobinder env tv vis+ ; inner' <- go_ty env' inner+ ; return $ ForAllTy (Bndr tv' vis) inner' }++ go_cos _ [] = return []+ go_cos env (co:cos) = (:) <$> go_co env co <*> go_cos env cos++ go_mco _ MRefl = return MRefl+ go_mco env (MCo co) = MCo <$> (go_co env co)++ go_co env (Refl ty) = Refl <$> go_ty env ty+ go_co env (GRefl r ty mco) = mkGReflCo r <$> go_ty env ty <*> go_mco env mco+ go_co env (AppCo c1 c2) = mkAppCo <$> go_co env c1 <*> go_co env c2+ go_co env (FunCo r afl afr cw c1 c2) = mkFunCo2 r afl afr <$> go_co env cw+ <*> go_co env c1 <*> go_co env c2+ go_co env (CoVarCo cv) = covar env cv+ go_co env (HoleCo hole) = cohole env hole+ go_co env (UnivCo p r t1 t2) = mkUnivCo <$> go_prov env p <*> pure r+ <*> go_ty env t1 <*> go_ty env t2+ go_co env (SymCo co) = mkSymCo <$> go_co env co+ go_co env (TransCo c1 c2) = mkTransCo <$> go_co env c1 <*> go_co env c2+ go_co env (AxiomRuleCo r cos) = AxiomRuleCo r <$> go_cos env cos+ go_co env (SelCo i co) = mkSelCo i <$> go_co env co+ go_co env (LRCo lr co) = mkLRCo lr <$> go_co env co+ go_co env (InstCo co arg) = mkInstCo <$> go_co env co <*> go_co env arg+ go_co env (KindCo co) = mkKindCo <$> go_co env co+ go_co env (SubCo co) = mkSubCo <$> go_co env co+ go_co env (AxiomInstCo ax i cos) = mkAxiomInstCo ax i <$> go_cos env cos+ go_co env co@(TyConAppCo r tc cos)+ | isTcTyCon tc+ = do { tc' <- tycon tc+ ; mkTyConAppCo r tc' <$> go_cos env cos }++ -- Not a TcTyCon+ | null cos -- Avoid allocation in this very+ = return co -- common case (E.g. Int, LiftedRep etc)++ | otherwise+ = mkTyConAppCo r tc <$> go_cos env cos+ go_co env (ForAllCo tv kind_co co)+ = do { kind_co' <- go_co env kind_co+ ; (env', tv') <- tycobinder env tv Inferred+ ; co' <- go_co env' co+ ; return $ mkForAllCo tv' kind_co' co' }+ -- See Note [Efficiency for ForAllCo case of mapTyCoX]++ go_prov env (PhantomProv co) = PhantomProv <$> go_co env co+ go_prov env (ProofIrrelProv co) = ProofIrrelProv <$> go_co env co+ go_prov _ p@(PluginProv _) = return p+ go_prov _ p@(CorePrepProv _) = return p+++{- *********************************************************************+* *+ TyVarTy+* *+********************************************************************* -}++-- | Attempts to obtain the type variable underlying a 'Type', and panics with the+-- given message if this is not a type variable type. See also 'getTyVar_maybe'+getTyVar :: HasDebugCallStack => Type -> TyVar+getTyVar ty = case getTyVar_maybe ty of+ Just tv -> tv+ Nothing -> pprPanic "getTyVar" (ppr ty)++-- | Attempts to obtain the type variable underlying a 'Type'+getTyVar_maybe :: Type -> Maybe TyVar+getTyVar_maybe = repGetTyVar_maybe . coreFullView++-- | Attempts to obtain the type variable underlying a 'Type', without+-- any expansion+repGetTyVar_maybe :: Type -> Maybe TyVar+repGetTyVar_maybe (TyVarTy tv) = Just tv+repGetTyVar_maybe _ = Nothing++isTyVarTy :: Type -> Bool+isTyVarTy ty = isJust (getTyVar_maybe ty)++-- | If the type is a tyvar, possibly under a cast, returns it, along+-- with the coercion. Thus, the co is :: kind tv ~N kind ty+getCastedTyVar_maybe :: Type -> Maybe (TyVar, CoercionN)+getCastedTyVar_maybe ty = case coreFullView ty of+ CastTy (TyVarTy tv) co -> Just (tv, co)+ TyVarTy tv -> Just (tv, mkReflCo Nominal (tyVarKind tv))+ _ -> Nothing+++{- *********************************************************************+* *+ AppTy+* *+********************************************************************* -}++{- We need to be pretty careful with AppTy to make sure we obey the+invariant that a TyConApp is always visibly so. mkAppTy maintains the+invariant: use it.++Note [Decomposing fat arrow c=>t]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Can we unify (a b) with (Eq a => ty)? If we do so, we end up with+a partial application like ((=>) Eq a) which doesn't make sense in+source Haskell. In contrast, we *can* unify (a b) with (t1 -> t2).+Here's an example (#9858) of how you might do it:+ i :: (Typeable a, Typeable b) => Proxy (a b) -> TypeRep+ i p = typeRep p++ j = i (Proxy :: Proxy (Eq Int => Int))+The type (Proxy (Eq Int => Int)) is only accepted with -XImpredicativeTypes,+but suppose we want that. But then in the call to 'i', we end+up decomposing (Eq Int => Int), and we definitely don't want that.++This really only applies to the type checker; in Core, '=>' and '->'+are the same, as are 'Constraint' and '*'. But for now I've put+the test in splitAppTyNoView_maybe, which applies throughout, because+the other calls to splitAppTy are in GHC.Core.Unify, which is also used by+the type checker (e.g. when matching type-function equations).++We are willing to split (t1 -=> t2) because the argument is still of+kind Type, not Constraint. So the criterion is isVisibleFunArg.+-}++-- | Applies a type to another, as in e.g. @k a@+mkAppTy :: Type -> Type -> Type+ -- See Note [Respecting definitional equality], invariant (EQ1).+mkAppTy (CastTy fun_ty co) arg_ty+ | ([arg_co], res_co) <- decomposePiCos co (coercionKind co) [arg_ty]+ = (fun_ty `mkAppTy` (arg_ty `mkCastTy` arg_co)) `mkCastTy` res_co++mkAppTy (TyConApp tc tys) ty2 = mkTyConApp tc (tys ++ [ty2])+mkAppTy ty1 ty2 = AppTy ty1 ty2+ -- Note that the TyConApp could be an+ -- under-saturated type synonym. GHC allows that; e.g.+ -- type Foo k = k a -> k a+ -- type Id x = x+ -- foo :: Foo Id -> Foo Id+ --+ -- Here Id is partially applied in the type sig for Foo,+ -- but once the type synonyms are expanded all is well+ --+ -- Moreover in GHC.Tc.Types.tcInferTyApps we build up a type+ -- (T t1 t2 t3) one argument at a type, thus forming+ -- (T t1), (T t1 t2), etc++mkAppTys :: Type -> [Type] -> Type+mkAppTys ty1 [] = ty1+mkAppTys (CastTy fun_ty co) arg_tys -- much more efficient then nested mkAppTy+ -- Why do this? See (EQ1) of+ -- Note [Respecting definitional equality]+ -- in GHC.Core.TyCo.Rep+ = foldl' AppTy ((mkAppTys fun_ty casted_arg_tys) `mkCastTy` res_co) leftovers+ where+ (arg_cos, res_co) = decomposePiCos co (coercionKind co) arg_tys+ (args_to_cast, leftovers) = splitAtList arg_cos arg_tys+ casted_arg_tys = zipWith mkCastTy args_to_cast arg_cos+mkAppTys (TyConApp tc tys1) tys2 = mkTyConApp tc (tys1 ++ tys2)+mkAppTys ty1 tys2 = foldl' AppTy ty1 tys2++-------------+splitAppTy_maybe :: Type -> Maybe (Type, Type)+-- ^ Attempt to take a type application apart, whether it is a+-- function, type constructor, or plain type application. Note+-- that type family applications are NEVER unsaturated by this!+splitAppTy_maybe = splitAppTyNoView_maybe . coreFullView++splitAppTy :: Type -> (Type, Type)+-- ^ Attempts to take a type application apart, as in 'splitAppTy_maybe',+-- and panics if this is not possible+splitAppTy ty = splitAppTy_maybe ty `orElse` pprPanic "splitAppTy" (ppr ty)++-------------+splitAppTyNoView_maybe :: HasDebugCallStack => Type -> Maybe (Type,Type)+-- ^ Does the AppTy split as in 'splitAppTy_maybe', but assumes that+-- any coreView stuff is already done+splitAppTyNoView_maybe (AppTy ty1 ty2)+ = Just (ty1, ty2)++splitAppTyNoView_maybe (FunTy af w ty1 ty2)+ | Just (tc, tys) <- funTyConAppTy_maybe af w ty1 ty2+ , Just (tys', ty') <- snocView tys+ = Just (TyConApp tc tys', ty')++splitAppTyNoView_maybe (TyConApp tc tys)+ | not (tyConMustBeSaturated tc) || tys `lengthExceeds` tyConArity tc+ , Just (tys', ty') <- snocView tys+ = Just (TyConApp tc tys', ty') -- Never create unsaturated type family apps!++splitAppTyNoView_maybe _other = Nothing++tcSplitAppTyNoView_maybe :: Type -> Maybe (Type,Type)+-- ^ Just like splitAppTyNoView_maybe, but does not split (c => t)+-- See Note [Decomposing fat arrow c=>t]+tcSplitAppTyNoView_maybe ty+ | FunTy { ft_af = af } <- ty+ , not (isVisibleFunArg af) -- See Note [Decomposing fat arrow c=>t]+ = Nothing+ | otherwise+ = splitAppTyNoView_maybe ty++-------------+splitAppTys :: Type -> (Type, [Type])+-- ^ Recursively splits a type as far as is possible, leaving a residual+-- type being applied to and the type arguments applied to it. Never fails,+-- even if that means returning an empty list of type applications.+splitAppTys ty = split ty ty []+ where+ split orig_ty ty args | Just ty' <- coreView ty = split orig_ty ty' args+ split _ (AppTy ty arg) args = split ty ty (arg:args)+ split _ (TyConApp tc tc_args) args+ = let -- keep type families saturated+ n | tyConMustBeSaturated tc = tyConArity tc+ | otherwise = 0+ (tc_args1, tc_args2) = splitAt n tc_args+ in+ (TyConApp tc tc_args1, tc_args2 ++ args)+ split _ (FunTy af w ty1 ty2) args+ | Just (tc,tys) <- funTyConAppTy_maybe af w ty1 ty2+ = assert (null args )+ (TyConApp tc [], tys)++ split orig_ty _ args = (orig_ty, args)++-- | Like 'splitAppTys', but doesn't look through type synonyms+splitAppTysNoView :: HasDebugCallStack => Type -> (Type, [Type])+splitAppTysNoView ty = split ty []+ where+ split (AppTy ty arg) args = split ty (arg:args)+ split (TyConApp tc tc_args) args+ = let n | tyConMustBeSaturated tc = tyConArity tc+ | otherwise = 0+ (tc_args1, tc_args2) = splitAt n tc_args+ in+ (TyConApp tc tc_args1, tc_args2 ++ args)+ split (FunTy af w ty1 ty2) args+ | Just (tc, tys) <- funTyConAppTy_maybe af w ty1 ty2+ = assert (null args )+ (TyConApp tc [], tys)++ split ty args = (ty, args)+++{- *********************************************************************+* *+ LitTy+* *+********************************************************************* -}++mkNumLitTy :: Integer -> Type+mkNumLitTy n = LitTy (NumTyLit n)++-- | Is this a numeric literal. We also look through type synonyms.+isNumLitTy :: Type -> Maybe Integer+isNumLitTy ty+ | LitTy (NumTyLit n) <- coreFullView ty = Just n+ | otherwise = Nothing++mkStrLitTy :: FastString -> Type+mkStrLitTy s = LitTy (StrTyLit s)++-- | Is this a symbol literal. We also look through type synonyms.+isStrLitTy :: Type -> Maybe FastString+isStrLitTy ty+ | LitTy (StrTyLit s) <- coreFullView ty = Just s+ | otherwise = Nothing++mkCharLitTy :: Char -> Type+mkCharLitTy c = LitTy (CharTyLit c)++-- | Is this a char literal? We also look through type synonyms.+isCharLitTy :: Type -> Maybe Char+isCharLitTy ty+ | LitTy (CharTyLit s) <- coreFullView ty = Just s+ | otherwise = Nothing+++-- | Is this a type literal (symbol, numeric, or char)?+isLitTy :: Type -> Maybe TyLit+isLitTy ty+ | LitTy l <- coreFullView ty = Just l+ | otherwise = Nothing++-- | Is this type a custom user error?+-- If so, give us the kind and the error message.+userTypeError_maybe :: Type -> Maybe Type+userTypeError_maybe t+ = do { (tc, _kind : msg : _) <- splitTyConApp_maybe t+ -- There may be more than 2 arguments, if the type error is+ -- used as a type constructor (e.g. at kind `Type -> Type`).++ ; guard (tyConName tc == errorMessageTypeErrorFamName)+ ; return msg }++-- | Render a type corresponding to a user type error into a SDoc.+pprUserTypeErrorTy :: Type -> SDoc+pprUserTypeErrorTy ty =+ case splitTyConApp_maybe ty of++ -- Text "Something"+ Just (tc,[txt])+ | tyConName tc == typeErrorTextDataConName+ , Just str <- isStrLitTy txt -> ftext str++ -- ShowType t+ Just (tc,[_k,t])+ | tyConName tc == typeErrorShowTypeDataConName -> ppr t++ -- t1 :<>: t2+ Just (tc,[t1,t2])+ | tyConName tc == typeErrorAppendDataConName ->+ pprUserTypeErrorTy t1 <> pprUserTypeErrorTy t2++ -- t1 :$$: t2+ Just (tc,[t1,t2])+ | tyConName tc == typeErrorVAppendDataConName ->+ pprUserTypeErrorTy t1 $$ pprUserTypeErrorTy t2++ -- An unevaluated type function+ _ -> ppr ty+++{- *********************************************************************+* *+ FunTy+* *+********************************************************************* -}++{- Note [Representation of function types]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Functions (e.g. Int -> Char) can be thought of as being applications+of funTyCon (known in Haskell surface syntax as (->)), (note that+`RuntimeRep' quantifiers are left inferred)++ (->) :: forall {r1 :: RuntimeRep} {r2 :: RuntimeRep}+ (a :: TYPE r1) (b :: TYPE r2).+ a -> b -> Type++However, for efficiency's sake we represent saturated applications of (->)+with FunTy. For instance, the type,++ (->) r1 r2 a b++is equivalent to,++ FunTy (Anon a) b++Note how the RuntimeReps are implied in the FunTy representation. For this+reason we must be careful when reconstructing the TyConApp representation (see,+for instance, splitTyConApp_maybe).++In the compiler we maintain the invariant that all saturated applications of+(->) are represented with FunTy.++See #11714.+-}++-----------------------------------------------+funTyConAppTy_maybe :: FunTyFlag -> Type -> Type -> Type+ -> Maybe (TyCon, [Type])+-- ^ Given the components of a FunTy+-- figure out the corresponding TyConApp.+funTyConAppTy_maybe af mult arg res+ | Just arg_rep <- getRuntimeRep_maybe arg+ , Just res_rep <- getRuntimeRep_maybe res+ , let args | isFUNArg af = [mult, arg_rep, res_rep, arg, res]+ | otherwise = [ arg_rep, res_rep, arg, res]+ = Just $ (funTyFlagTyCon af, args)+ | otherwise+ = Nothing++tyConAppFunTy_maybe :: HasDebugCallStack => TyCon -> [Type] -> Maybe Type+-- ^ Return Just if this TyConApp should be represented as a FunTy+tyConAppFunTy_maybe tc tys+ | Just (af, mult, arg, res) <- ty_con_app_fun_maybe manyDataConTy tc tys+ = Just (FunTy { ft_af = af, ft_mult = mult, ft_arg = arg, ft_res = res })+ | otherwise = Nothing++tyConAppFunCo_maybe :: HasDebugCallStack => Role -> TyCon -> [Coercion]+ -> Maybe Coercion+-- ^ Return Just if this TyConAppCo should be represented as a FunCo+tyConAppFunCo_maybe r tc cos+ | Just (af, mult, arg, res) <- ty_con_app_fun_maybe (mkReflCo r manyDataConTy) tc cos+ = Just (mkFunCo1 r af mult arg res)+ | otherwise = Nothing++ty_con_app_fun_maybe :: (HasDebugCallStack, Outputable a) => a -> TyCon -> [a]+ -> Maybe (FunTyFlag, a, a, a)+{-# INLINE ty_con_app_fun_maybe #-}+-- Specialise this function for its two call sites+ty_con_app_fun_maybe many_ty_co tc args+ | tc_uniq == fUNTyConKey = fUN_case+ | tc_uniq == tcArrowTyConKey = non_FUN_case FTF_T_C+ | tc_uniq == ctArrowTyConKey = non_FUN_case FTF_C_T+ | tc_uniq == ccArrowTyConKey = non_FUN_case FTF_C_C+ | otherwise = Nothing+ where+ tc_uniq = tyConUnique tc++ fUN_case+ | (w:_r1:_r2:a1:a2:rest) <- args+ = assertPpr (null rest) (ppr tc <+> ppr args) $+ Just (FTF_T_T, w, a1, a2)+ | otherwise = Nothing++ non_FUN_case ftf+ | (_r1:_r2:a1:a2:rest) <- args+ = assertPpr (null rest) (ppr tc <+> ppr args) $+ Just (ftf, many_ty_co, a1, a2)+ | otherwise+ = Nothing++mkFunctionType :: Mult -> Type -> Type -> Type+-- ^ This one works out the FunTyFlag from the argument type+-- See GHC.Types.Var Note [FunTyFlag]+mkFunctionType mult arg_ty res_ty+ = FunTy { ft_af = af, ft_arg = arg_ty, ft_res = res_ty+ , ft_mult = assertPpr mult_ok (ppr [mult, arg_ty, res_ty]) $+ mult }+ where+ af = chooseFunTyFlag arg_ty res_ty+ mult_ok = isVisibleFunArg af || isManyTy mult++mkScaledFunctionTys :: [Scaled Type] -> Type -> Type+-- ^ Like mkFunctionType, compute the FunTyFlag from the arguments+mkScaledFunctionTys arg_tys res_ty+ = foldr mk res_ty arg_tys+ where+ mk (Scaled mult arg_ty) res_ty+ = mkFunTy (chooseFunTyFlag arg_ty res_ty)+ mult arg_ty res_ty++chooseFunTyFlag :: HasDebugCallStack => Type -> Type -> FunTyFlag+-- ^ See GHC.Types.Var Note [FunTyFlag]+chooseFunTyFlag arg_ty res_ty+ = mkFunTyFlag (typeTypeOrConstraint arg_ty) (typeTypeOrConstraint res_ty)++splitFunTy :: Type -> (Mult, Type, Type)+-- ^ Attempts to extract the multiplicity, argument and result types from a type,+-- and panics if that is not possible. See also 'splitFunTy_maybe'+splitFunTy ty = case splitFunTy_maybe ty of+ Just (_af, mult, arg, res) -> (mult,arg,res)+ Nothing -> pprPanic "splitFunTy" (ppr ty)++{-# INLINE splitFunTy_maybe #-}+splitFunTy_maybe :: Type -> Maybe (FunTyFlag, Mult, Type, Type)+-- ^ Attempts to extract the multiplicity, argument and result types from a type+splitFunTy_maybe ty+ | FunTy af w arg res <- coreFullView ty = Just (af, w, arg, res)+ | otherwise = Nothing++splitFunTys :: Type -> ([Scaled Type], Type)+splitFunTys ty = split [] ty ty+ where+ -- common case first+ split args _ (FunTy _ w arg res) = split (Scaled w arg : args) res res+ split args orig_ty ty | Just ty' <- coreView ty = split args orig_ty ty'+ split args orig_ty _ = (reverse args, orig_ty)++funResultTy :: HasDebugCallStack => Type -> Type+-- ^ Extract the function result type and panic if that is not possible+funResultTy ty+ | FunTy { ft_res = res } <- coreFullView ty = res+ | otherwise = pprPanic "funResultTy" (ppr ty)++funArgTy :: Type -> Type+-- ^ Extract the function argument type and panic if that is not possible+funArgTy ty+ | FunTy { ft_arg = arg } <- coreFullView ty = arg+ | otherwise = pprPanic "funArgTy" (ppr ty)++-- ^ Just like 'piResultTys' but for a single argument+-- Try not to iterate 'piResultTy', because it's inefficient to substitute+-- one variable at a time; instead use 'piResultTys"+piResultTy :: HasDebugCallStack => Type -> Type -> Type+piResultTy ty arg = case piResultTy_maybe ty arg of+ Just res -> res+ Nothing -> pprPanic "piResultTy" (ppr ty $$ ppr arg)++piResultTy_maybe :: Type -> Type -> Maybe Type+-- We don't need a 'tc' version, because+-- this function behaves the same for Type and Constraint+piResultTy_maybe ty arg = case coreFullView ty of+ FunTy { ft_res = res } -> Just res++ ForAllTy (Bndr tv _) res+ -> let empty_subst = mkEmptySubst $ mkInScopeSet $+ tyCoVarsOfTypes [arg,res]+ in Just (substTy (extendTCvSubst empty_subst tv arg) res)++ _ -> Nothing++-- | (piResultTys f_ty [ty1, .., tyn]) gives the type of (f ty1 .. tyn)+-- where f :: f_ty+-- 'piResultTys' is interesting because:+-- 1. 'f_ty' may have more for-alls than there are args+-- 2. Less obviously, it may have fewer for-alls+-- For case 2. think of:+-- piResultTys (forall a.a) [forall b.b, Int]+-- This really can happen, but only (I think) in situations involving+-- undefined. For example:+-- undefined :: forall a. a+-- Term: undefined @(forall b. b->b) @Int+-- This term should have type (Int -> Int), but notice that+-- there are more type args than foralls in 'undefined's type.++-- If you edit this function, you may need to update the GHC formalism+-- See Note [GHC Formalism] in GHC.Core.Lint++-- This is a heavily used function (e.g. from typeKind),+-- so we pay attention to efficiency, especially in the special case+-- where there are no for-alls so we are just dropping arrows from+-- a function type/kind.+piResultTys :: HasDebugCallStack => Type -> [Type] -> Type+piResultTys ty [] = ty+piResultTys ty orig_args@(arg:args)+ | FunTy { ft_res = res } <- ty+ = piResultTys res args++ | ForAllTy (Bndr tv _) res <- ty+ = go (extendTCvSubst init_subst tv arg) res args++ | Just ty' <- coreView ty+ = piResultTys ty' orig_args++ | otherwise+ = pprPanic "piResultTys1" (ppr ty $$ ppr orig_args)+ where+ init_subst = mkEmptySubst $ mkInScopeSet (tyCoVarsOfTypes (ty:orig_args))++ go :: Subst -> Type -> [Type] -> Type+ go subst ty [] = substTyUnchecked subst ty++ go subst ty all_args@(arg:args)+ | FunTy { ft_res = res } <- ty+ = go subst res args++ | ForAllTy (Bndr tv _) res <- ty+ = go (extendTCvSubst subst tv arg) res args++ | Just ty' <- coreView ty+ = go subst ty' all_args++ | not (isEmptyTCvSubst subst) -- See Note [Care with kind instantiation]+ = go init_subst+ (substTy subst ty)+ all_args++ | otherwise+ = -- We have not run out of arguments, but the function doesn't+ -- have the right kind to apply to them; so panic.+ -- Without the explicit isEmptyVarEnv test, an ill-kinded type+ -- would give an infinite loop, which is very unhelpful+ -- c.f. #15473+ pprPanic "piResultTys2" (ppr ty $$ ppr orig_args $$ ppr all_args)++applyTysX :: [TyVar] -> Type -> [Type] -> Type+-- applyTysX beta-reduces (/\tvs. body_ty) arg_tys+-- Assumes that (/\tvs. body_ty) is closed+applyTysX tvs body_ty arg_tys+ = assertPpr (tvs `leLength` arg_tys) pp_stuff $+ assertPpr (tyCoVarsOfType body_ty `subVarSet` mkVarSet tvs) pp_stuff $+ mkAppTys (substTyWith tvs arg_tys_prefix body_ty)+ arg_tys_rest+ where+ pp_stuff = vcat [ppr tvs, ppr body_ty, ppr arg_tys]+ (arg_tys_prefix, arg_tys_rest) = splitAtList tvs arg_tys+++{- Note [Care with kind instantiation]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose we have+ T :: forall k. k+and we are finding the kind of+ T (forall b. b -> b) * Int+Then+ T (forall b. b->b) :: k[ k :-> forall b. b->b]+ :: forall b. b -> b+So+ T (forall b. b->b) * :: (b -> b)[ b :-> *]+ :: * -> *++In other words we must instantiate the forall!++Similarly (#15428)+ S :: forall k f. k -> f k+and we are finding the kind of+ S * (* ->) Int Bool+We have+ S * (* ->) :: (k -> f k)[ k :-> *, f :-> (* ->)]+ :: * -> * -> *+So again we must instantiate.++The same thing happens in GHC.CoreToIface.toIfaceAppArgsX.+-}+++{- *********************************************************************+* *+ TyConApp+* *+********************************************************************* -}++-- splitTyConApp "looks through" synonyms, because they don't+-- mean a distinct type, but all other type-constructor applications+-- including functions are returned as Just ..++-- | Retrieve the tycon heading this type, if there is one. Does /not/+-- look through synonyms.+tyConAppTyConPicky_maybe :: Type -> Maybe TyCon+tyConAppTyConPicky_maybe (TyConApp tc _) = Just tc+tyConAppTyConPicky_maybe (FunTy { ft_af = af }) = Just (funTyFlagTyCon af)+tyConAppTyConPicky_maybe _ = Nothing+++-- | The same as @fst . splitTyConApp@+-- We can short-cut the FunTy case+{-# INLINE tyConAppTyCon_maybe #-}+tyConAppTyCon_maybe :: Type -> Maybe TyCon+tyConAppTyCon_maybe ty = case coreFullView ty of+ TyConApp tc _ -> Just tc+ FunTy { ft_af = af } -> Just (funTyFlagTyCon af)+ _ -> Nothing++tyConAppTyCon :: HasDebugCallStack => Type -> TyCon+tyConAppTyCon ty = tyConAppTyCon_maybe ty `orElse` pprPanic "tyConAppTyCon" (ppr ty)++-- | The same as @snd . splitTyConApp@+tyConAppArgs_maybe :: Type -> Maybe [Type]+tyConAppArgs_maybe ty = case splitTyConApp_maybe ty of+ Just (_, tys) -> Just tys+ Nothing -> Nothing++tyConAppArgs :: HasCallStack => Type -> [Type]+tyConAppArgs ty = tyConAppArgs_maybe ty `orElse` pprPanic "tyConAppArgs" (ppr ty)++-- | Attempts to tease a type apart into a type constructor and the application+-- of a number of arguments to that constructor. Panics if that is not possible.+-- See also 'splitTyConApp_maybe'+splitTyConApp :: Type -> (TyCon, [Type])+splitTyConApp ty = splitTyConApp_maybe ty `orElse` pprPanic "splitTyConApp" (ppr ty)++-- | Attempts to tease a type apart into a type constructor and the application+-- of a number of arguments to that constructor+splitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type])+splitTyConApp_maybe ty = splitTyConAppNoView_maybe (coreFullView ty)++splitTyConAppNoView_maybe :: Type -> Maybe (TyCon, [Type])+-- Same as splitTyConApp_maybe but without looking through synonyms+splitTyConAppNoView_maybe ty+ = case ty of+ FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res}+ -> funTyConAppTy_maybe af w arg res+ TyConApp tc tys -> Just (tc, tys)+ _ -> Nothing++-- | tcSplitTyConApp_maybe splits a type constructor application into+-- its type constructor and applied types.+--+-- Differs from splitTyConApp_maybe in that it does *not* split types+-- headed with (=>), as that's not a TyCon in the type-checker.+--+-- Note that this may fail (in funTyConAppTy_maybe) in the case+-- of a 'FunTy' with an argument of unknown kind 'FunTy'+-- (e.g. `FunTy (a :: k) Int`, since the kind of @a@ isn't of+-- the form `TYPE rep`. This isn't usually a problem but may+-- be temporarily the cas during canonicalization:+-- see Note [Decomposing FunTy] in GHC.Tc.Solver.Canonical+-- and Note [The Purely Kinded Type Invariant (PKTI)] in GHC.Tc.Gen.HsType,+-- Wrinkle around FunTy+--+-- Consequently, you may need to zonk your type before+-- using this function.+tcSplitTyConApp_maybe :: HasCallStack => Type -> Maybe (TyCon, [Type])+-- Defined here to avoid module loops between Unify and TcType.+tcSplitTyConApp_maybe ty+ = case coreFullView ty of+ FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res}+ | isVisibleFunArg af -- Visible args only+ -- See Note [Decomposing fat arrow c=>t]+ -> funTyConAppTy_maybe af w arg res+ TyConApp tc tys -> Just (tc, tys)+ _ -> Nothing++tcSplitTyConApp :: Type -> (TyCon, [Type])+tcSplitTyConApp ty+ = tcSplitTyConApp_maybe ty `orElse` pprPanic "tcSplitTyConApp" (ppr ty)++---------------------------+newTyConInstRhs :: TyCon -> [Type] -> Type+-- ^ Unwrap one 'layer' of newtype on a type constructor and its+-- arguments, using an eta-reduced version of the @newtype@ if possible.+-- This requires tys to have at least @newTyConInstArity tycon@ elements.+newTyConInstRhs tycon tys+ = assertPpr (tvs `leLength` tys) (ppr tycon $$ ppr tys $$ ppr tvs) $+ applyTysX tvs rhs tys+ where+ (tvs, rhs) = newTyConEtadRhs tycon+++{- *********************************************************************+* *+ CastTy+* *+********************************************************************* -}++splitCastTy_maybe :: Type -> Maybe (Type, Coercion)+splitCastTy_maybe ty+ | CastTy ty' co <- coreFullView ty = Just (ty', co)+ | otherwise = Nothing++-- | Make a 'CastTy'. The Coercion must be nominal. Checks the+-- Coercion for reflexivity, dropping it if it's reflexive.+-- See @Note [Respecting definitional equality]@ in "GHC.Core.TyCo.Rep"+mkCastTy :: Type -> Coercion -> Type+mkCastTy orig_ty co | isReflexiveCo co = orig_ty -- (EQ2) from the Note+-- NB: Do the slow check here. This is important to keep the splitXXX+-- functions working properly. Otherwise, we may end up with something+-- like (((->) |> something_reflexive_but_not_obviously_so) biz baz)+-- fails under splitFunTy_maybe. This happened with the cheaper check+-- in test dependent/should_compile/dynamic-paper.+mkCastTy orig_ty co = mk_cast_ty orig_ty co++-- | Like 'mkCastTy', but avoids checking the coercion for reflexivity,+-- as that can be expensive.+mk_cast_ty :: Type -> Coercion -> Type+mk_cast_ty orig_ty co = go orig_ty+ where+ go :: Type -> Type+ -- See Note [Using coreView in mk_cast_ty]+ go ty | Just ty' <- coreView ty = go ty'++ go (CastTy ty co1)+ -- (EQ3) from the Note+ = mkCastTy ty (co1 `mkTransCo` co)+ -- call mkCastTy again for the reflexivity check++ go (ForAllTy (Bndr tv vis) inner_ty)+ -- (EQ4) from the Note+ -- See Note [Weird typing rule for ForAllTy] in GHC.Core.TyCo.Rep.+ | isTyVar tv+ , let fvs = tyCoVarsOfCo co+ = -- have to make sure that pushing the co in doesn't capture the bound var!+ if tv `elemVarSet` fvs+ then let empty_subst = mkEmptySubst (mkInScopeSet fvs)+ (subst, tv') = substVarBndr empty_subst tv+ in ForAllTy (Bndr tv' vis) (substTy subst inner_ty `mk_cast_ty` co)+ else ForAllTy (Bndr tv vis) (inner_ty `mk_cast_ty` co)++ go _ = CastTy orig_ty co -- NB: orig_ty: preserve synonyms if possible++{-+Note [Using coreView in mk_cast_ty]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Invariants (EQ3) and (EQ4) of Note [Respecting definitional equality] in+GHC.Core.TyCo.Rep must apply regardless of type synonyms. For instance,+consider this example (#19742):++ type EqSameNat = () |> co+ useNatEq :: EqSameNat |> sym co++(Those casts aren't visible in the user-source code, of course; see #19742 for+what the user might write.)++The type `EqSameNat |> sym co` looks as if it satisfies (EQ3), as it has no+nested casts, but if we expand EqSameNat, we see that it doesn't.+And then Bad Things happen.++The solution is easy: just use `coreView` when establishing (EQ3) and (EQ4) in+`mk_cast_ty`.+-}++{- *********************************************************************+* *+ CoercionTy+ CoercionTy allows us to inject coercions into types. A CoercionTy+ should appear only in the right-hand side of an application.+* *+********************************************************************* -}++mkCoercionTy :: Coercion -> Type+mkCoercionTy = CoercionTy++isCoercionTy :: Type -> Bool+isCoercionTy (CoercionTy _) = True+isCoercionTy _ = False++isCoercionTy_maybe :: Type -> Maybe Coercion+isCoercionTy_maybe (CoercionTy co) = Just co+isCoercionTy_maybe _ = Nothing++stripCoercionTy :: Type -> Coercion+stripCoercionTy (CoercionTy co) = co+stripCoercionTy ty = pprPanic "stripCoercionTy" (ppr ty)+++{- *********************************************************************+* *+ ForAllTy+* *+********************************************************************* -}++tyConBindersPiTyBinders :: [TyConBinder] -> [PiTyBinder]+-- Return the tyConBinders in PiTyBinder form+tyConBindersPiTyBinders = map to_tyb+ where+ to_tyb (Bndr tv (NamedTCB vis)) = Named (Bndr tv vis)+ to_tyb (Bndr tv (AnonTCB af)) = Anon (tymult (varType tv)) af++-- | Make a dependent forall over an 'Inferred' variable+mkTyCoInvForAllTy :: TyCoVar -> Type -> Type+mkTyCoInvForAllTy tv ty+ | isCoVar tv+ , not (tv `elemVarSet` tyCoVarsOfType ty)+ = mkVisFunTyMany (varType tv) ty+ | otherwise+ = ForAllTy (Bndr tv Inferred) ty++-- | Like 'mkTyCoInvForAllTy', but tv should be a tyvar+mkInfForAllTy :: TyVar -> Type -> Type+mkInfForAllTy tv ty = assert (isTyVar tv )+ ForAllTy (Bndr tv Inferred) ty++-- | Like 'mkForAllTys', but assumes all variables are dependent and+-- 'Inferred', a common case+mkTyCoInvForAllTys :: [TyCoVar] -> Type -> Type+mkTyCoInvForAllTys tvs ty = foldr mkTyCoInvForAllTy ty tvs++-- | Like 'mkTyCoInvForAllTys', but tvs should be a list of tyvar+mkInfForAllTys :: [TyVar] -> Type -> Type+mkInfForAllTys tvs ty = foldr mkInfForAllTy ty tvs++-- | Like 'mkForAllTy', but assumes the variable is dependent and 'Specified',+-- a common case+mkSpecForAllTy :: TyVar -> Type -> Type+mkSpecForAllTy tv ty = assert (isTyVar tv )+ -- covar is always Inferred, so input should be tyvar+ ForAllTy (Bndr tv Specified) ty++-- | Like 'mkForAllTys', but assumes all variables are dependent and+-- 'Specified', a common case+mkSpecForAllTys :: [TyVar] -> Type -> Type+mkSpecForAllTys tvs ty = foldr mkSpecForAllTy ty tvs++-- | Like mkForAllTys, but assumes all variables are dependent and visible+mkVisForAllTys :: [TyVar] -> Type -> Type+mkVisForAllTys tvs = assert (all isTyVar tvs )+ -- covar is always Inferred, so all inputs should be tyvar+ mkForAllTys [ Bndr tv Required | tv <- tvs ]++-- | Given a list of type-level vars and the free vars of a result kind,+-- makes PiTyBinders, preferring anonymous binders+-- if the variable is, in fact, not dependent.+-- e.g. mkTyConBindersPreferAnon [(k:*),(b:k),(c:k)] (k->k)+-- We want (k:*) Named, (b:k) Anon, (c:k) Anon+--+-- All non-coercion binders are /visible/.+mkTyConBindersPreferAnon :: [TyVar] -- ^ binders+ -> TyCoVarSet -- ^ free variables of result+ -> [TyConBinder]+mkTyConBindersPreferAnon vars inner_tkvs = assert (all isTyVar vars)+ fst (go vars)+ where+ go :: [TyVar] -> ([TyConBinder], VarSet) -- also returns the free vars+ go [] = ([], inner_tkvs)+ go (v:vs) | v `elemVarSet` fvs+ = ( Bndr v (NamedTCB Required) : binders+ , fvs `delVarSet` v `unionVarSet` kind_vars )+ | otherwise+ = ( Bndr v (AnonTCB visArgTypeLike) : binders+ , fvs `unionVarSet` kind_vars )+ where+ (binders, fvs) = go vs+ kind_vars = tyCoVarsOfType $ tyVarKind v++-- | Take a ForAllTy apart, returning the binders and result type+splitForAllForAllTyBinders :: Type -> ([ForAllTyBinder], Type)+splitForAllForAllTyBinders ty = split ty ty []+ where+ split _ (ForAllTy b res) bs = split res res (b:bs)+ split orig_ty ty bs | Just ty' <- coreView ty = split orig_ty ty' bs+ split orig_ty _ bs = (reverse bs, orig_ty)+{-# INLINE splitForAllForAllTyBinders #-}++-- | Take a ForAllTy apart, returning the list of tycovars and the result type.+-- This always succeeds, even if it returns only an empty list. Note that the+-- result type returned may have free variables that were bound by a forall.+splitForAllTyCoVars :: Type -> ([TyCoVar], Type)+splitForAllTyCoVars ty = split ty ty []+ where+ split _ (ForAllTy (Bndr tv _) ty) tvs = 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)++-- | Like 'splitForAllTyCoVars', but split only for tyvars.+-- This always succeeds, even if it returns only an empty list. Note that the+-- result type returned may have free variables that were bound by a forall.+splitForAllTyVars :: Type -> ([TyVar], Type)+splitForAllTyVars ty = split ty ty []+ where+ split _ (ForAllTy (Bndr tv _) ty) tvs | isTyVar tv = 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)++-- | Like 'splitForAllTyCoVars', but only splits 'ForAllTy's with 'Required' type+-- variable binders. Furthermore, each returned tyvar is annotated with '()'.+splitForAllReqTyBinders :: Type -> ([ReqTyBinder], Type)+splitForAllReqTyBinders ty = split ty ty []+ where+ split _ (ForAllTy (Bndr tv Required) ty) tvs = split ty ty (Bndr tv ():tvs)+ split orig_ty ty tvs | Just ty' <- coreView ty = split orig_ty ty' tvs+ split orig_ty _ tvs = (reverse tvs, orig_ty)++-- | Like 'splitForAllTyCoVars', but only splits 'ForAllTy's with 'Invisible' type+-- variable binders. Furthermore, each returned tyvar is annotated with its+-- 'Specificity'.+splitForAllInvisTyBinders :: Type -> ([InvisTyBinder], Type)+splitForAllInvisTyBinders ty = split ty ty []+ where+ split _ (ForAllTy (Bndr tv (Invisible spec)) ty) tvs = split ty ty (Bndr tv spec:tvs)+ split orig_ty ty tvs | Just ty' <- coreView ty = split orig_ty ty' tvs+ split orig_ty _ tvs = (reverse tvs, orig_ty)++-- | Checks whether this is a proper forall (with a named binder)+isForAllTy :: Type -> Bool+isForAllTy ty+ | ForAllTy {} <- coreFullView ty = True+ | otherwise = False++-- | Like `isForAllTy`, but returns True only if it is a tyvar binder+isForAllTy_ty :: Type -> Bool+isForAllTy_ty ty+ | ForAllTy (Bndr tv _) _ <- coreFullView ty+ , isTyVar tv+ = True++ | otherwise = False++-- | Like `isForAllTy`, but returns True only if it is a covar binder+isForAllTy_co :: Type -> Bool+isForAllTy_co ty+ | ForAllTy (Bndr tv _) _ <- coreFullView ty+ , isCoVar tv+ = True++ | otherwise = False++-- | Is this a function or forall?+isPiTy :: Type -> Bool+isPiTy ty = case coreFullView ty of+ ForAllTy {} -> True+ FunTy {} -> True+ _ -> False++-- | Is this a function?+isFunTy :: Type -> Bool+isFunTy ty+ | FunTy {} <- coreFullView ty = True+ | otherwise = False++-- | Take a forall type apart, or panics if that is not possible.+splitForAllTyCoVar :: Type -> (TyCoVar, Type)+splitForAllTyCoVar ty+ | Just answer <- splitForAllTyCoVar_maybe ty = answer+ | otherwise = pprPanic "splitForAllTyCoVar" (ppr ty)++-- | Drops all ForAllTys+dropForAlls :: Type -> Type+dropForAlls ty = go ty+ where+ go (ForAllTy _ res) = go res+ go ty | Just ty' <- coreView ty = go ty'+ go res = res++-- | Attempts to take a forall type apart, but only if it's a proper forall,+-- with a named binder+splitForAllTyCoVar_maybe :: Type -> Maybe (TyCoVar, Type)+splitForAllTyCoVar_maybe ty+ | ForAllTy (Bndr tv _) inner_ty <- coreFullView ty = Just (tv, inner_ty)+ | otherwise = Nothing++-- | Like 'splitForAllTyCoVar_maybe', but only returns Just if it is a tyvar binder.+splitForAllTyVar_maybe :: Type -> Maybe (TyVar, Type)+splitForAllTyVar_maybe ty+ | ForAllTy (Bndr tv _) inner_ty <- coreFullView ty+ , isTyVar tv+ = Just (tv, inner_ty)++ | otherwise = Nothing++-- | Like 'splitForAllTyCoVar_maybe', but only returns Just if it is a covar binder.+splitForAllCoVar_maybe :: Type -> Maybe (CoVar, Type)+splitForAllCoVar_maybe ty+ | ForAllTy (Bndr tv _) inner_ty <- coreFullView ty+ , isCoVar tv+ = Just (tv, inner_ty)++ | otherwise = Nothing++-- | Attempts to take a forall type apart; works with proper foralls and+-- functions+{-# INLINE splitPiTy_maybe #-} -- callers will immediately deconstruct+splitPiTy_maybe :: Type -> Maybe (PiTyBinder, Type)+splitPiTy_maybe ty = case coreFullView ty of+ ForAllTy bndr ty -> Just (Named bndr, ty)+ FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res}+ -> Just (Anon (mkScaled w arg) af, res)+ _ -> Nothing++-- | Takes a forall type apart, or panics+splitPiTy :: Type -> (PiTyBinder, Type)+splitPiTy ty+ | Just answer <- splitPiTy_maybe ty = answer+ | otherwise = pprPanic "splitPiTy" (ppr ty)++-- | Split off all PiTyBinders to a type, splitting both proper foralls+-- and functions+splitPiTys :: Type -> ([PiTyBinder], Type)+splitPiTys ty = split ty ty []+ where+ split _ (ForAllTy b res) bs = split res res (Named b : bs)+ split _ (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res }) bs+ = split res res (Anon (Scaled w arg) af : bs)+ split orig_ty ty bs | Just ty' <- coreView ty = split orig_ty ty' bs+ split orig_ty _ bs = (reverse bs, orig_ty)++-- | Extracts a list of run-time arguments from a function type,+-- looking through newtypes to the right of arrows.+--+-- Examples:+--+-- @+-- newtype Identity a = I a+--+-- getRuntimeArgTys (Int -> Bool -> Double) == [(Int, FTF_T_T), (Bool, FTF_T_T)]+-- getRuntimeArgTys (Identity Int -> Bool -> Double) == [(Identity Int, FTF_T_T), (Bool, FTF_T_T)]+-- getRuntimeArgTys (Int -> Identity (Bool -> Identity Double)) == [(Int, FTF_T_T), (Bool, FTF_T_T)]+-- getRuntimeArgTys (forall a. Show a => Identity a -> a -> Int -> Bool)+-- == [(Show a, FTF_C_T), (Identity a, FTF_T_T),(a, FTF_T_T),(Int, FTF_T_T)]+-- @+--+-- Note that, in the last case, the returned types might mention an out-of-scope+-- type variable. This function is used only when we really care about the /kinds/+-- of the returned types, so this is OK.+--+-- **Warning**: this function can return an infinite list. For example:+--+-- @+-- newtype N a = MkN (a -> N a)+-- getRuntimeArgTys (N a) == repeat (a, FTF_T_T)+-- @+getRuntimeArgTys :: Type -> [(Scaled Type, FunTyFlag)]+getRuntimeArgTys = go+ where+ go :: Type -> [(Scaled Type, FunTyFlag)]+ go (ForAllTy _ res)+ = go res+ go (FunTy { ft_mult = w, ft_arg = arg, ft_res = res, ft_af = af })+ = (Scaled w arg, af) : go res+ go ty+ | Just ty' <- coreView ty+ = go ty'+ | Just (_,ty') <- topNormaliseNewType_maybe ty+ = go ty'+ | otherwise+ = []++invisibleTyBndrCount :: Type -> Int+-- Returns the number of leading invisible forall'd binders in the type+-- Includes invisible predicate arguments; e.g. for+-- e.g. forall {k}. (k ~ *) => k -> k+-- returns 2 not 1+invisibleTyBndrCount ty = length (fst (splitInvisPiTys ty))++-- | Like 'splitPiTys', but returns only *invisible* binders, including constraints.+-- Stops at the first visible binder.+splitInvisPiTys :: Type -> ([PiTyBinder], Type)+splitInvisPiTys ty = split ty ty []+ where+ split _ (ForAllTy b res) bs+ | Bndr _ vis <- b+ , isInvisibleForAllTyFlag vis = split res res (Named b : bs)+ split _ (FunTy { ft_af = af, ft_mult = mult, ft_arg = arg, ft_res = res }) bs+ | isInvisibleFunArg af = split res res (Anon (mkScaled mult arg) af : bs)+ split orig_ty ty bs+ | Just ty' <- coreView ty = split orig_ty ty' bs+ split orig_ty _ bs = (reverse bs, orig_ty)++splitInvisPiTysN :: Int -> Type -> ([PiTyBinder], Type)+-- ^ Same as 'splitInvisPiTys', but stop when+-- - you have found @n@ 'PiTyBinder's,+-- - or you run out of invisible binders+splitInvisPiTysN n ty = split n ty ty []+ where+ split n orig_ty ty bs+ | n == 0 = (reverse bs, orig_ty)+ | Just ty' <- coreView ty = split n orig_ty ty' bs+ | ForAllTy b res <- ty+ , Bndr _ vis <- b+ , isInvisibleForAllTyFlag vis = split (n-1) res res (Named b : bs)+ | FunTy { ft_af = af, ft_mult = mult, ft_arg = arg, ft_res = res } <- ty+ , isInvisibleFunArg af = split (n-1) res res (Anon (Scaled mult arg) af : bs)+ | otherwise = (reverse bs, orig_ty)++-- | Given a 'TyCon' and a list of argument types, filter out any invisible+-- (i.e., 'Inferred' or 'Specified') arguments.+filterOutInvisibleTypes :: TyCon -> [Type] -> [Type]+filterOutInvisibleTypes tc tys = snd $ partitionInvisibleTypes tc tys++-- | Given a 'TyCon' and a list of argument types, filter out any 'Inferred'+-- arguments.+filterOutInferredTypes :: TyCon -> [Type] -> [Type]+filterOutInferredTypes tc tys =+ filterByList (map (/= Inferred) $ tyConForAllTyFlags tc tys) tys++-- | Given a 'TyCon' and a list of argument types, partition the arguments+-- into:+--+-- 1. 'Inferred' or 'Specified' (i.e., invisible) arguments and+--+-- 2. 'Required' (i.e., visible) arguments+partitionInvisibleTypes :: TyCon -> [Type] -> ([Type], [Type])+partitionInvisibleTypes tc tys =+ partitionByList (map isInvisibleForAllTyFlag $ tyConForAllTyFlags tc tys) tys++-- | Given a list of things paired with their visibilities, partition the+-- things into (invisible things, visible things).+partitionInvisibles :: [(a, ForAllTyFlag)] -> ([a], [a])+partitionInvisibles = partitionWith pick_invis+ where+ pick_invis :: (a, ForAllTyFlag) -> Either a a+ pick_invis (thing, vis) | isInvisibleForAllTyFlag vis = Left thing+ | otherwise = Right thing++-- | Given a 'TyCon' and a list of argument types to which the 'TyCon' is+-- applied, determine each argument's visibility+-- ('Inferred', 'Specified', or 'Required').+--+-- Wrinkle: consider the following scenario:+--+-- > T :: forall k. k -> k+-- > tyConForAllTyFlags T [forall m. m -> m -> m, S, R, Q]+--+-- After substituting, we get+--+-- > T (forall m. m -> m -> m) :: (forall m. m -> m -> m) -> forall n. n -> n -> n+--+-- Thus, the first argument is invisible, @S@ is visible, @R@ is invisible again,+-- and @Q@ is visible.+tyConForAllTyFlags :: TyCon -> [Type] -> [ForAllTyFlag]+tyConForAllTyFlags tc = fun_kind_arg_flags (tyConKind tc)++-- | Given a 'Type' and a list of argument types to which the 'Type' is+-- applied, determine each argument's visibility+-- ('Inferred', 'Specified', or 'Required').+--+-- Most of the time, the arguments will be 'Required', but not always. Consider+-- @f :: forall a. a -> Type@. In @f Type Bool@, the first argument (@Type@) is+-- 'Specified' and the second argument (@Bool@) is 'Required'. It is precisely+-- this sort of higher-rank situation in which 'appTyForAllTyFlags' comes in handy,+-- since @f Type Bool@ would be represented in Core using 'AppTy's.+-- (See also #15792).+appTyForAllTyFlags :: Type -> [Type] -> [ForAllTyFlag]+appTyForAllTyFlags ty = fun_kind_arg_flags (typeKind ty)++-- | Given a function kind and a list of argument types (where each argument's+-- kind aligns with the corresponding position in the argument kind), determine+-- each argument's visibility ('Inferred', 'Specified', or 'Required').+fun_kind_arg_flags :: Kind -> [Type] -> [ForAllTyFlag]+fun_kind_arg_flags = go emptySubst+ where+ go subst ki arg_tys+ | Just ki' <- coreView ki = go subst ki' arg_tys+ go _ _ [] = []+ go subst (ForAllTy (Bndr tv argf) res_ki) (arg_ty:arg_tys)+ = argf : go subst' res_ki arg_tys+ where+ subst' = extendTvSubst subst tv arg_ty+ go subst (TyVarTy tv) arg_tys+ | Just ki <- lookupTyVar subst tv = go subst ki arg_tys+ -- This FunTy case is important to handle kinds with nested foralls, such+ -- as this kind (inspired by #16518):+ --+ -- forall {k1} k2. k1 -> k2 -> forall k3. k3 -> Type+ --+ -- Here, we want to get the following ForAllTyFlags:+ --+ -- [Inferred, Specified, Required, Required, Specified, Required]+ -- forall {k1}. forall k2. k1 -> k2 -> forall k3. k3 -> Type+ go subst (FunTy{ft_af = af, ft_res = res_ki}) (_:arg_tys)+ = argf : go subst res_ki arg_tys+ where+ argf | isVisibleFunArg af = Required+ | otherwise = Inferred+ go _ _ arg_tys = map (const Required) arg_tys+ -- something is ill-kinded. But this can happen+ -- when printing errors. Assume everything is Required.++-- @isTauTy@ tests if a type has no foralls or (=>)+isTauTy :: Type -> Bool+isTauTy ty | Just ty' <- coreView ty = isTauTy ty'+isTauTy (TyVarTy _) = True+isTauTy (LitTy {}) = True+isTauTy (TyConApp tc tys) = all isTauTy tys && isTauTyCon tc+isTauTy (AppTy a b) = isTauTy a && isTauTy b+isTauTy (FunTy { ft_af = af, ft_mult = w, ft_arg = a, ft_res = b })+ | isInvisibleFunArg af = False -- e.g., Eq a => b+ | otherwise = isTauTy w && isTauTy a && isTauTy b -- e.g., a -> b+isTauTy (ForAllTy {}) = False+isTauTy (CastTy ty _) = isTauTy ty+isTauTy (CoercionTy _) = False -- Not sure about this++isAtomicTy :: Type -> Bool+-- True if the type is just a single token, and can be printed compactly+-- Used when deciding how to lay out type error messages; see the+-- call in GHC.Tc.Errors+isAtomicTy (TyVarTy {}) = True+isAtomicTy (LitTy {}) = True+isAtomicTy (TyConApp _ []) = True++isAtomicTy ty | isLiftedTypeKind ty = True+ -- 'Type' prints compactly as *+ -- See GHC.Iface.Type.ppr_kind_type++isAtomicTy _ = False++{-+************************************************************************+* *+\subsection{Type families}+* *+************************************************************************+-}++mkFamilyTyConApp :: TyCon -> [Type] -> Type+-- ^ Given a family instance TyCon and its arg types, return the+-- corresponding family type. E.g:+--+-- > data family T a+-- > data instance T (Maybe b) = MkT b+--+-- Where the instance tycon is :RTL, so:+--+-- > mkFamilyTyConApp :RTL Int = T (Maybe Int)+mkFamilyTyConApp tc tys+ | Just (fam_tc, fam_tys) <- tyConFamInst_maybe tc+ , let tvs = tyConTyVars tc+ fam_subst = assertPpr (tvs `equalLength` tys) (ppr tc <+> ppr tys) $+ zipTvSubst tvs tys+ = mkTyConApp fam_tc (substTys fam_subst fam_tys)+ | otherwise+ = mkTyConApp tc tys++-- | Get the type on the LHS of a coercion induced by a type/data+-- family instance.+coAxNthLHS :: CoAxiom br -> Int -> Type+coAxNthLHS ax ind =+ mkTyConApp (coAxiomTyCon ax) (coAxBranchLHS (coAxiomNthBranch ax ind))++isFamFreeTy :: Type -> Bool+isFamFreeTy ty | Just ty' <- coreView ty = isFamFreeTy ty'+isFamFreeTy (TyVarTy _) = True+isFamFreeTy (LitTy {}) = True+isFamFreeTy (TyConApp tc tys) = all isFamFreeTy tys && isFamFreeTyCon tc+isFamFreeTy (AppTy a b) = isFamFreeTy a && isFamFreeTy b+isFamFreeTy (FunTy _ w a b) = isFamFreeTy w && isFamFreeTy a && isFamFreeTy b+isFamFreeTy (ForAllTy _ ty) = isFamFreeTy ty+isFamFreeTy (CastTy ty _) = isFamFreeTy ty+isFamFreeTy (CoercionTy _) = False -- Not sure about this++-- | Does this type classify a core (unlifted) Coercion?+-- At either role nominal or representational+-- (t1 ~# t2) or (t1 ~R# t2)+-- See Note [Types for coercions, predicates, and evidence] in "GHC.Core.TyCo.Rep"+isCoVarType :: Type -> Bool+ -- ToDo: should we check saturation?+isCoVarType ty+ | Just tc <- tyConAppTyCon_maybe ty+ = tc `hasKey` eqPrimTyConKey || tc `hasKey` eqReprPrimTyConKey+ | otherwise+ = False++buildSynTyCon :: Name -> [KnotTied TyConBinder] -> Kind -- ^ /result/ kind+ -> [Role] -> KnotTied Type -> TyCon+-- This function is here because here is where we have+-- isFamFree and isTauTy+buildSynTyCon name binders res_kind roles rhs+ = mkSynonymTyCon name binders res_kind roles rhs is_tau is_fam_free is_forgetful+ where+ is_tau = isTauTy rhs+ is_fam_free = isFamFreeTy rhs+ is_forgetful = any (not . (`elemVarSet` tyCoVarsOfType rhs) . binderVar) binders ||+ uniqSetAny isForgetfulSynTyCon (tyConsOfType rhs)+ -- NB: This is allowed to be conservative, returning True more often+ -- than it should. See comments on GHC.Core.TyCon.isForgetfulSynTyCon++{-+************************************************************************+* *+\subsection{Liftedness}+* *+************************************************************************+-}++-- | Tries to compute the 'Levity' of the given type. Returns either+-- a definite 'Levity', or 'Nothing' if we aren't sure (e.g. the+-- type is representation-polymorphic).+--+-- Panics if the kind does not have the shape @TYPE r@.+typeLevity_maybe :: HasDebugCallStack => Type -> Maybe Levity+typeLevity_maybe ty = runtimeRepLevity_maybe (getRuntimeRep ty)++-- | Is the given type definitely unlifted?+-- See "Type#type_classification" for what an unlifted type is.+--+-- Panics on representation-polymorphic types; See 'mightBeUnliftedType' for+-- a more approximate predicate that behaves better in the presence of+-- representation polymorphism.+isUnliftedType :: HasDebugCallStack => Type -> Bool+ -- isUnliftedType returns True for forall'd unlifted types:+ -- x :: forall a. Int#+ -- I found bindings like these were getting floated to the top level.+ -- They are pretty bogus types, mind you. It would be better never to+ -- construct them+isUnliftedType ty =+ case typeLevity_maybe ty of+ Just Lifted -> False+ Just Unlifted -> True+ Nothing ->+ pprPanic "isUnliftedType" (ppr ty <+> dcolon <+> ppr (typeKind ty))++-- | Returns:+--+-- * 'False' if the type is /guaranteed/ unlifted or+-- * 'True' if it lifted, OR we aren't sure+-- (e.g. in a representation-polymorphic case)+mightBeLiftedType :: Type -> Bool+mightBeLiftedType = mightBeLifted . typeLevity_maybe++-- | Returns:+--+-- * 'False' if the type is /guaranteed/ lifted or+-- * 'True' if it is unlifted, OR we aren't sure+-- (e.g. in a representation-polymorphic case)+mightBeUnliftedType :: Type -> Bool+mightBeUnliftedType = mightBeUnlifted . typeLevity_maybe++-- | See "Type#type_classification" for what a boxed type is.+-- Panics on representation-polymorphic types; See 'mightBeUnliftedType' for+-- a more approximate predicate that behaves better in the presence of+-- representation polymorphism.+isBoxedType :: Type -> Bool+isBoxedType ty = isBoxedRuntimeRep (getRuntimeRep ty)++-- | Is this a type of kind RuntimeRep? (e.g. LiftedRep)+isRuntimeRepKindedTy :: Type -> Bool+isRuntimeRepKindedTy = isRuntimeRepTy . typeKind++-- | Drops prefix of RuntimeRep constructors in 'TyConApp's. Useful for e.g.+-- dropping 'LiftedRep arguments of unboxed tuple TyCon applications:+--+-- dropRuntimeRepArgs [ 'LiftedRep, 'IntRep+-- , String, Int# ] == [String, Int#]+--+dropRuntimeRepArgs :: [Type] -> [Type]+dropRuntimeRepArgs = dropWhile isRuntimeRepKindedTy++-- | Extract the RuntimeRep classifier of a type. For instance,+-- @getRuntimeRep_maybe Int = Just LiftedRep@. Returns 'Nothing' if this is not+-- possible.+getRuntimeRep_maybe :: HasDebugCallStack+ => Type -> Maybe RuntimeRepType+getRuntimeRep_maybe = kindRep_maybe . typeKind++-- | Extract the RuntimeRep classifier of a type. For instance,+-- @getRuntimeRep_maybe Int = LiftedRep@. Panics if this is not possible.+getRuntimeRep :: HasDebugCallStack => Type -> RuntimeRepType+getRuntimeRep ty+ = case getRuntimeRep_maybe ty of+ Just r -> r+ Nothing -> pprPanic "getRuntimeRep" (ppr ty <+> dcolon <+> ppr (typeKind ty))++-- | Extract the 'Levity' of a type. For example, @getLevity_maybe Int = Just Lifted@,+-- @getLevity (Array# Int) = Just Unlifted@, @getLevity Float# = Nothing@.+--+-- Returns 'Nothing' if this is not possible. Does not look through type family applications.+getLevity_maybe :: HasDebugCallStack => Type -> Maybe Type+getLevity_maybe ty+ | Just rep <- getRuntimeRep_maybe ty+ -- Directly matching on TyConApp after expanding type synonyms+ -- saves allocations compared to `splitTyConApp_maybe`. See #22254.+ -- Given that this is a pretty hot function we make use of the fact+ -- and use isTyConKeyApp_maybe instead.+ , Just [lev] <- isTyConKeyApp_maybe boxedRepDataConKey rep+ = Just lev+ | otherwise+ = Nothing++-- | Extract the 'Levity' of a type. For example, @getLevity Int = Lifted@,+-- or @getLevity (Array# Int) = Unlifted@.+--+-- Panics if this is not possible. Does not look through type family applications.+getLevity :: HasDebugCallStack => Type -> Type+getLevity ty+ | Just lev <- getLevity_maybe ty+ = lev+ | otherwise+ = pprPanic "getLevity" (ppr ty <+> dcolon <+> ppr (typeKind ty))++isUnboxedTupleType :: Type -> Bool+isUnboxedTupleType ty+ = tyConAppTyCon (getRuntimeRep ty) `hasKey` tupleRepDataConKey+ -- NB: Do not use typePrimRep, as that can't tell the difference between+ -- unboxed tuples and unboxed sums+++isUnboxedSumType :: Type -> Bool+isUnboxedSumType ty+ = tyConAppTyCon (getRuntimeRep ty) `hasKey` sumRepDataConKey++-- | See "Type#type_classification" for what an algebraic type is.+-- Should only be applied to /types/, as opposed to e.g. partially+-- saturated type constructors+isAlgType :: Type -> Bool+isAlgType ty+ = case splitTyConApp_maybe ty of+ Just (tc, ty_args) -> assert (ty_args `lengthIs` tyConArity tc )+ isAlgTyCon tc+ _other -> False++-- | Check whether a type is a data family type+isDataFamilyAppType :: Type -> Bool+isDataFamilyAppType ty = case tyConAppTyCon_maybe ty of+ Just tc -> isDataFamilyTyCon tc+ _ -> False++-- | Computes whether an argument (or let right hand side) should+-- be computed strictly or lazily, based only on its type.+-- Currently, it's just 'isUnliftedType'.+-- Panics on representation-polymorphic types.+isStrictType :: HasDebugCallStack => Type -> Bool+isStrictType = isUnliftedType++isPrimitiveType :: Type -> Bool+-- ^ Returns true of types that are opaque to Haskell.+isPrimitiveType ty = case splitTyConApp_maybe ty of+ Just (tc, ty_args) -> assert (ty_args `lengthIs` tyConArity tc )+ isPrimTyCon tc+ _ -> False++{-+************************************************************************+* *+\subsection{Join points}+* *+************************************************************************+-}++-- | Determine whether a type could be the type of a join point of given total+-- arity, according to the polymorphism rule. A join point cannot be polymorphic+-- in its return type, since given+-- join j @a @b x y z = e1 in e2,+-- the types of e1 and e2 must be the same, and a and b are not in scope for e2.+-- (See Note [The polymorphism rule of join points] in "GHC.Core".) Returns False+-- also if the type simply doesn't have enough arguments.+--+-- Note that we need to know how many arguments (type *and* value) the putative+-- join point takes; for instance, if+-- j :: forall a. a -> Int+-- then j could be a binary join point returning an Int, but it could *not* be a+-- unary join point returning a -> Int.+--+-- TODO: See Note [Excess polymorphism and join points]+isValidJoinPointType :: JoinArity -> Type -> Bool+isValidJoinPointType arity ty+ = valid_under emptyVarSet arity ty+ where+ valid_under tvs arity ty+ | arity == 0+ = tvs `disjointVarSet` tyCoVarsOfType ty+ | Just (t, ty') <- splitForAllTyCoVar_maybe ty+ = valid_under (tvs `extendVarSet` t) (arity-1) ty'+ | Just (_, _, _, res_ty) <- splitFunTy_maybe ty+ = valid_under tvs (arity-1) res_ty+ | otherwise+ = False++{- Note [Excess polymorphism and join points]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+In principle, if a function would be a join point except that it fails+the polymorphism rule (see Note [The polymorphism rule of join points] in+GHC.Core), it can still be made a join point with some effort. This is because+all tail calls must return the same type (they return to the same context!), and+thus if the return type depends on an argument, that argument must always be the+same.++For instance, consider:++ let f :: forall a. a -> Char -> [a]+ f @a x c = ... f @a y 'a' ...+ in ... f @Int 1 'b' ... f @Int 2 'c' ...++(where the calls are tail calls). `f` fails the polymorphism rule because its+return type is [a], where [a] is bound. But since the type argument is always+'Int', we can rewrite it as:++ let f' :: Int -> Char -> [Int]+ f' x c = ... f' y 'a' ...+ in ... f' 1 'b' ... f 2 'c' ...++and now we can make f' a join point:++ join f' :: Int -> Char -> [Int]+ f' x c = ... jump f' y 'a' ...+ in ... jump f' 1 'b' ... jump f' 2 'c' ...++It's not clear that this comes up often, however. TODO: Measure how often and+add this analysis if necessary. See #14620.+++************************************************************************+* *+\subsection{Sequencing on types}+* *+************************************************************************+-}++seqType :: Type -> ()+seqType (LitTy n) = n `seq` ()+seqType (TyVarTy tv) = tv `seq` ()+seqType (AppTy t1 t2) = seqType t1 `seq` seqType t2+seqType (FunTy _ w t1 t2) = seqType w `seq` seqType t1 `seq` seqType t2+seqType (TyConApp tc tys) = tc `seq` seqTypes tys+seqType (ForAllTy (Bndr tv _) ty) = seqType (varType tv) `seq` seqType ty+seqType (CastTy ty co) = seqType ty `seq` seqCo co+seqType (CoercionTy co) = seqCo co++seqTypes :: [Type] -> ()+seqTypes [] = ()+seqTypes (ty:tys) = seqType ty `seq` seqTypes tys++{-+************************************************************************+* *+ The kind of a type+* *+************************************************************************++Note [Kinding rules for types]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Here are the key kinding rules for types++ torc1 is TYPE or CONSTRAINT+ torc2 is TYPE or CONSTRAINT+ t1 : torc1 rep1+ t2 : torc2 rep2+ (FUN) ----------------+ t1 -> t2 : torc2 LiftedRep+ -- In fact the arrow varies with torc1/torc2+ -- See Note [Function type constructors and FunTy]+ -- in GHC.Builtin.Types.Prim++ torc is TYPE or CONSTRAINT+ ty : body_torc rep+ bndr_torc is Type or Constraint+ ki : bndr_torc+ `a` is a type variable+ `a` is not free in rep+(FORALL1) -----------------------+ forall (a::ki). ty : torc rep++ torc is TYPE or CONSTRAINT+ ty : body_torc rep+ `c` is a coercion variable+ `c` is not free in rep+ `c` is free in ty -- Surprise 1!+(FORALL2) -------------------------+ forall (cv::k1 ~#{N,R} k2). ty : body_torc LiftedRep+ -- Surprise 2!++Note that:+* (FORALL1) rejects (forall (a::Maybe). blah)++* (FORALL1) accepts (forall (a :: t1~t2) blah), where the type variable+ (not coercion variable!) 'a' has a kind (t1~t2) that in turn has kind+ Constraint. See Note [Constraints in kinds] in GHC.Core.TyCo.Rep.++* (FORALL2) Surprise 1:+ See GHC.Core.TyCo.Rep Note [Unused coercion variable in ForAllTy]++* (FORALL2) Surprise 2: coercion abstractions are not erased, so+ this must be LiftedRep, just like (FUN). (FORALL2) is just a+ dependent form of (FUN).+++Note [Phantom type variables in kinds]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider++ type K (r :: RuntimeRep) = Type -- Note 'r' is unused+ data T r :: K r -- T :: forall r -> K r+ foo :: forall r. T r++The body of the forall in foo's type has kind (K r), and+normally it would make no sense to have+ forall r. (ty :: K r)+because the kind of the forall would escape the binding+of 'r'. But in this case it's fine because (K r) expands+to Type, so we explicitly /permit/ the type+ forall r. T r++To accommodate such a type, in typeKind (forall a.ty) we use+occCheckExpand to expand any type synonyms in the kind of 'ty'+to eliminate 'a'. See kinding rule (FORALL) in+Note [Kinding rules for types]+++See also+ * GHC.Core.Type.occCheckExpand+ * GHC.Core.Utils.coreAltsType+ * GHC.Tc.Validity.checkEscapingKind+all of which grapple with the same problem.++See #14939.+-}++-----------------------------+typeKind :: HasDebugCallStack => Type -> Kind+-- No need to expand synonyms+typeKind (TyConApp tc tys) = piResultTys (tyConKind tc) tys+typeKind (LitTy l) = typeLiteralKind l+typeKind (FunTy { ft_af = af }) = case funTyFlagResultTypeOrConstraint af of+ TypeLike -> liftedTypeKind+ ConstraintLike -> constraintKind+typeKind (TyVarTy tyvar) = tyVarKind tyvar+typeKind (CastTy _ty co) = coercionRKind co+typeKind (CoercionTy co) = coercionType co++typeKind (AppTy fun arg)+ = go fun [arg]+ where+ -- Accumulate the type arguments, so we can call piResultTys,+ -- rather than a succession of calls to piResultTy (which is+ -- asymptotically costly as the number of arguments increases)+ go (AppTy fun arg) args = go fun (arg:args)+ go fun args = piResultTys (typeKind fun) args++typeKind ty@(ForAllTy {})+ = case occCheckExpand tvs body_kind of+ -- We must make sure tv does not occur in kind+ -- As it is already out of scope!+ -- See Note [Phantom type variables in kinds]+ Nothing -> pprPanic "typeKind"+ (ppr ty $$ ppr tvs $$ ppr body <+> dcolon <+> ppr body_kind)++ Just k' | all isTyVar tvs -> k' -- Rule (FORALL1)+ | otherwise -> lifted_kind_from_body -- Rule (FORALL2)+ where+ (tvs, body) = splitForAllTyVars ty+ body_kind = typeKind body++ lifted_kind_from_body -- Implements (FORALL2)+ = case sORTKind_maybe body_kind of+ Just (ConstraintLike, _) -> constraintKind+ Just (TypeLike, _) -> liftedTypeKind+ Nothing -> pprPanic "typeKind" (ppr body_kind)++---------------------------------------------++sORTKind_maybe :: Kind -> Maybe (TypeOrConstraint, Type)+-- Sees if the argument is of form (TYPE rep) or (CONSTRAINT rep)+-- and if so returns which, and the runtime rep+--+-- This is a "hot" function. Do not call splitTyConApp_maybe here,+-- to avoid the faff with FunTy+sORTKind_maybe (TyConApp tc tys)+ -- First, short-cuts for Type and Constraint that do no allocation+ | tc_uniq == liftedTypeKindTyConKey = assert( null tys ) $ Just (TypeLike, liftedRepTy)+ | tc_uniq == constraintKindTyConKey = assert( null tys ) $ Just (ConstraintLike, liftedRepTy)+ | tc_uniq == tYPETyConKey = get_rep TypeLike+ | tc_uniq == cONSTRAINTTyConKey = get_rep ConstraintLike+ | Just ty' <- expandSynTyConApp_maybe tc tys = sORTKind_maybe ty'+ where+ !tc_uniq = tyConUnique tc+ -- This bang on tc_uniq is important. It means that sORTKind_maybe starts+ -- by evaluating tc_uniq, and then ends up with a single case with a 4-way branch++ get_rep torc = case tys of+ (rep:_reps) -> assert (null _reps) $ Just (torc, rep)+ [] -> Nothing++sORTKind_maybe _ = Nothing++typeTypeOrConstraint :: HasDebugCallStack => Type -> TypeOrConstraint+-- Precondition: expects a type that classifies values.+-- Returns whether it is TypeLike or ConstraintLike.+-- Equivalent to calling sORTKind_maybe, but faster in the FunTy case+typeTypeOrConstraint ty+ = case coreFullView ty of+ FunTy { ft_af = af } -> funTyFlagResultTypeOrConstraint af+ ty' | Just (torc, _) <- sORTKind_maybe (typeKind ty')+ -> torc+ | otherwise+ -> pprPanic "typeOrConstraint" (ppr ty <+> dcolon <+> ppr (typeKind ty))++isPredTy :: HasDebugCallStack => Type -> Bool+-- Precondition: expects a type that classifies values+-- See Note [Types for coercions, predicates, and evidence] in GHC.Core.TyCo.Rep+-- Returns True for types of kind (CONSTRAINT _), False for ones of kind (TYPE _)+isPredTy ty = case typeTypeOrConstraint ty of+ TypeLike -> False+ ConstraintLike -> True++-----------------------------------------+-- | Does this classify a type allowed to have values? Responds True to things+-- like *, TYPE Lifted, TYPE IntRep, TYPE v, Constraint.+isTYPEorCONSTRAINT :: Kind -> Bool+-- ^ True of a kind `TYPE _` or `CONSTRAINT _`+isTYPEorCONSTRAINT k = isJust (sORTKind_maybe k)++isConstraintLikeKind :: Kind -> Bool+-- True of (CONSTRAINT _)+isConstraintLikeKind kind+ = case sORTKind_maybe kind of+ Just (ConstraintLike, _) -> True+ _ -> False++isConstraintKind :: Kind -> Bool+-- True of (CONSTRAINT LiftedRep)+isConstraintKind kind+ = case sORTKind_maybe kind of+ Just (ConstraintLike, rep) -> isLiftedRuntimeRep rep+ _ -> False++tcIsLiftedTypeKind :: Kind -> Bool+-- ^ Is this kind equivalent to 'Type' i.e. TYPE LiftedRep?+tcIsLiftedTypeKind kind+ | Just (TypeLike, rep) <- sORTKind_maybe kind+ = isLiftedRuntimeRep rep+ | otherwise+ = False++tcIsBoxedTypeKind :: Kind -> Bool+-- ^ Is this kind equivalent to @TYPE (BoxedRep l)@ for some @l :: Levity@?+tcIsBoxedTypeKind kind+ | Just (TypeLike, rep) <- sORTKind_maybe kind+ = isBoxedRuntimeRep rep+ | otherwise+ = False++-- | Is this kind equivalent to @TYPE r@ (for some unknown r)?+--+-- This considers 'Constraint' to be distinct from @*@.+isTypeLikeKind :: Kind -> Bool+isTypeLikeKind kind+ = case sORTKind_maybe kind of+ Just (TypeLike, _) -> True+ _ -> False++returnsConstraintKind :: Kind -> Bool+-- True <=> the Kind ultimately returns a Constraint+-- E.g. * -> Constraint+-- forall k. k -> Constraint+returnsConstraintKind kind+ | Just kind' <- coreView kind = returnsConstraintKind kind'+returnsConstraintKind (ForAllTy _ ty) = returnsConstraintKind ty+returnsConstraintKind (FunTy { ft_res = ty }) = returnsConstraintKind ty+returnsConstraintKind kind = isConstraintLikeKind kind++--------------------------+typeLiteralKind :: TyLit -> Kind+typeLiteralKind (NumTyLit {}) = naturalTy+typeLiteralKind (StrTyLit {}) = typeSymbolKind+typeLiteralKind (CharTyLit {}) = charTy++-- | Returns True if a type has a syntactically fixed runtime rep,+-- as per Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete.+--+-- This function is equivalent to `isFixedRuntimeRepKind . typeKind`+-- but much faster.+--+-- __Precondition:__ The type has kind @('TYPE' blah)@+typeHasFixedRuntimeRep :: HasDebugCallStack => Type -> Bool+typeHasFixedRuntimeRep = go+ where+ go (TyConApp tc _)+ | tcHasFixedRuntimeRep tc = True+ go (FunTy {}) = True+ go (LitTy {}) = True+ go (ForAllTy _ ty) = go ty+ go ty = isFixedRuntimeRepKind (typeKind ty)++argsHaveFixedRuntimeRep :: Type -> Bool+-- ^ True if the argument types of this function type+-- all have a fixed-runtime-rep+argsHaveFixedRuntimeRep ty+ = all ok bndrs+ where+ ok :: PiTyBinder -> Bool+ ok (Anon ty _) = typeHasFixedRuntimeRep (scaledThing ty)+ ok _ = True++ bndrs :: [PiTyBinder]+ (bndrs, _) = splitPiTys ty++-- | Checks that a kind of the form 'Type', 'Constraint'+-- or @'TYPE r@ is concrete. See 'isConcrete'.+--+-- __Precondition:__ The type has kind `TYPE blah` or `CONSTRAINT blah`+isFixedRuntimeRepKind :: HasDebugCallStack => Kind -> Bool+isFixedRuntimeRepKind k+ = assertPpr (isTYPEorCONSTRAINT k) (ppr k) $+ -- the isLiftedTypeKind check is necessary b/c of Constraint+ isConcrete k++-- | Tests whether the given type is concrete, i.e. it+-- whether it consists only of concrete type constructors,+-- concrete type variables, and applications.+--+-- See Note [Concrete types] in GHC.Tc.Utils.Concrete.+isConcrete :: Type -> Bool+isConcrete = go+ where+ go ty | Just ty' <- coreView ty = go ty'+ go (TyVarTy tv) = isConcreteTyVar tv+ go (AppTy ty1 ty2) = go ty1 && go ty2+ go (TyConApp tc tys)+ | isConcreteTyCon tc = all go tys+ | otherwise = False+ go ForAllTy{} = False+ go (FunTy _ w t1 t2) = go w+ && go (typeKind t1) && go t1+ && go (typeKind t2) && go t2+ go LitTy{} = True+ go CastTy{} = False+ go CoercionTy{} = False+++{-+%************************************************************************+%* *+ Pretty-printing+%* *+%************************************************************************++Most pretty-printing is either in GHC.Core.TyCo.Rep or GHC.Iface.Type.++-}++-- | Does a 'TyCon' (that is applied to some number of arguments) need to be+-- ascribed with an explicit kind signature to resolve ambiguity if rendered as+-- a source-syntax type?+-- (See @Note [When does a tycon application need an explicit kind signature?]@+-- for a full explanation of what this function checks for.)+tyConAppNeedsKindSig+ :: Bool -- ^ Should specified binders count towards injective positions in+ -- the kind of the TyCon? (If you're using visible kind+ -- applications, then you want True here.+ -> TyCon+ -> Int -- ^ The number of args the 'TyCon' is applied to.+ -> Bool -- ^ Does @T t_1 ... t_n@ need a kind signature? (Where @n@ is the+ -- number of arguments)+tyConAppNeedsKindSig spec_inj_pos tc n_args+ | LT <- listLengthCmp tc_binders n_args+ = False+ | otherwise+ = let (dropped_binders, remaining_binders)+ = splitAt n_args tc_binders+ result_kind = mkTyConKind remaining_binders tc_res_kind+ result_vars = tyCoVarsOfType result_kind+ dropped_vars = fvVarSet $+ mapUnionFV injective_vars_of_binder dropped_binders++ in not (subVarSet result_vars dropped_vars)+ where+ tc_binders = tyConBinders tc+ tc_res_kind = tyConResKind tc++ -- Returns the variables that would be fixed by knowing a TyConBinder. See+ -- Note [When does a tycon application need an explicit kind signature?]+ -- for a more detailed explanation of what this function does.+ injective_vars_of_binder :: TyConBinder -> FV+ injective_vars_of_binder (Bndr tv vis) =+ case vis of+ AnonTCB af | isVisibleFunArg af+ -> injectiveVarsOfType False -- conservative choice+ (varType tv)+ NamedTCB argf | source_of_injectivity argf+ -> unitFV tv `unionFV`+ injectiveVarsOfType False (varType tv)+ _ -> emptyFV++ source_of_injectivity Required = True+ source_of_injectivity Specified = spec_inj_pos+ source_of_injectivity Inferred = False++{-+Note [When does a tycon application need an explicit kind signature?]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+There are a couple of places in GHC where we convert Core Types into forms that+more closely resemble user-written syntax. These include:++1. Template Haskell Type reification (see, for instance, GHC.Tc.Gen.Splice.reify_tc_app)+2. Converting Types to LHsTypes (such as in Haddock.Convert in haddock)++This conversion presents a challenge: how do we ensure that the resulting type+has enough kind information so as not to be ambiguous? To better motivate this+question, consider the following Core type:++ -- Foo :: Type -> Type+ type Foo = Proxy Type++There is nothing ambiguous about the RHS of Foo in Core. But if we were to,+say, reify it into a TH Type, then it's tempting to just drop the invisible+Type argument and simply return `Proxy`. But now we've lost crucial kind+information: we don't know if we're dealing with `Proxy Type` or `Proxy Bool`+or `Proxy Int` or something else! We've inadvertently introduced ambiguity.++Unlike in other situations in GHC, we can't just turn on+-fprint-explicit-kinds, as we need to produce something which has the same+structure as a source-syntax type. Moreover, we can't rely on visible kind+application, since the first kind argument to Proxy is inferred, not specified.+Our solution is to annotate certain tycons with their kinds whenever they+appear in applied form in order to resolve the ambiguity. For instance, we+would reify the RHS of Foo like so:++ type Foo = (Proxy :: Type -> Type)++We need to devise an algorithm that determines precisely which tycons need+these explicit kind signatures. We certainly don't want to annotate _every_+tycon with a kind signature, or else we might end up with horribly bloated+types like the following:++ (Either :: Type -> Type -> Type) (Int :: Type) (Char :: Type)++We only want to annotate tycons that absolutely require kind signatures in+order to resolve some sort of ambiguity, and nothing more.++Suppose we have a tycon application (T ty_1 ... ty_n). Why might this type+require a kind signature? It might require it when we need to fill in any of+T's omitted arguments. By "omitted argument", we mean one that is dropped when+reifying ty_1 ... ty_n. Sometimes, the omitted arguments are inferred and+specified arguments (e.g., TH reification in GHC.Tc.Gen.Splice), and sometimes the+omitted arguments are only the inferred ones (e.g., in situations where+specified arguments are reified through visible kind application).+Regardless, the key idea is that _some_ arguments are going to be omitted after+reification, and the only mechanism we have at our disposal for filling them in+is through explicit kind signatures.++What do we mean by "fill in"? Let's consider this small example:++ T :: forall {k}. Type -> (k -> Type) -> k++Moreover, we have this application of T:++ T @{j} Int aty++When we reify this type, we omit the inferred argument @{j}. Is it fixed by the+other (non-inferred) arguments? Yes! If we know the kind of (aty :: blah), then+we'll generate an equality constraint (kappa -> Type) and, assuming we can+solve it, that will fix `kappa`. (Here, `kappa` is the unification variable+that we instantiate `k` with.)++Therefore, for any application of a tycon T to some arguments, the Question We+Must Answer is:++* Given the first n arguments of T, do the kinds of the non-omitted arguments+ fill in the omitted arguments?++(This is still a bit hand-wavy, but we'll refine this question incrementally+as we explain more of the machinery underlying this process.)++Answering this question is precisely the role that the `injectiveVarsOfType`+and `injective_vars_of_binder` functions exist to serve. If an omitted argument+`a` appears in the set returned by `injectiveVarsOfType ty`, then knowing+`ty` determines (i.e., fills in) `a`. (More on `injective_vars_of_binder` in a+bit.)++More formally, if+`a` is in `injectiveVarsOfType ty`+and S1(ty) ~ S2(ty),+then S1(a) ~ S2(a),+where S1 and S2 are arbitrary substitutions.++For example, is `F` is a non-injective type family, then++ injectiveVarsOfType(Either c (Maybe (a, F b c))) = {a, c}++Now that we know what this function does, here is a second attempt at the+Question We Must Answer:++* Given the first n arguments of T (ty_1 ... ty_n), consider the binders+ of T that are instantiated by non-omitted arguments. Do the injective+ variables of these binders fill in the remainder of T's kind?++Alright, we're getting closer. Next, we need to clarify what the injective+variables of a tycon binder are. This the role that the+`injective_vars_of_binder` function serves. Here is what this function does for+each form of tycon binder:++* Anonymous binders are injective positions. For example, in the promoted data+ constructor '(:):++ '(:) :: forall a. a -> [a] -> [a]++ The second and third tyvar binders (of kinds `a` and `[a]`) are both+ anonymous, so if we had '(:) 'True '[], then the kinds of 'True and+ '[] would contribute to the kind of '(:) 'True '[]. Therefore,+ injective_vars_of_binder(_ :: a) = injectiveVarsOfType(a) = {a}.+ (Similarly, injective_vars_of_binder(_ :: [a]) = {a}.)+* Named binders:+ - Inferred binders are never injective positions. For example, in this data+ type:++ data Proxy a+ Proxy :: forall {k}. k -> Type++ If we had Proxy 'True, then the kind of 'True would not contribute to the+ kind of Proxy 'True. Therefore,+ injective_vars_of_binder(forall {k}. ...) = {}.+ - Required binders are injective positions. For example, in this data type:++ data Wurble k (a :: k) :: k+ Wurble :: forall k -> k -> k++ The first tyvar binder (of kind `forall k`) has required visibility, so if+ we had Wurble (Maybe a) Nothing, then the kind of Maybe a would+ contribute to the kind of Wurble (Maybe a) Nothing. Hence,+ injective_vars_of_binder(forall a -> ...) = {a}.+ - Specified binders /might/ be injective positions, depending on how you+ approach things. Continuing the '(:) example:++ '(:) :: forall a. a -> [a] -> [a]++ Normally, the (forall a. ...) tyvar binder wouldn't contribute to the kind+ of '(:) 'True '[], since it's not explicitly instantiated by the user. But+ if visible kind application is enabled, then this is possible, since the+ user can write '(:) @Bool 'True '[]. (In that case,+ injective_vars_of_binder(forall a. ...) = {a}.)++ There are some situations where using visible kind application is appropriate+ and others where it is not (e.g., TH+ reification), so the `injective_vars_of_binder` function is parameterized by+ a Bool which decides if specified binders should be counted towards+ injective positions or not.++Now that we've defined injective_vars_of_binder, we can refine the Question We+Must Answer once more:++* Given the first n arguments of T (ty_1 ... ty_n), consider the binders+ of T that are instantiated by non-omitted arguments. For each such binder+ b_i, take the union of all injective_vars_of_binder(b_i). Is this set a+ superset of the free variables of the remainder of T's kind?++If the answer to this question is "no", then (T ty_1 ... ty_n) needs an+explicit kind signature, since T's kind has kind variables leftover that+aren't fixed by the non-omitted arguments.++One last sticking point: what does "the remainder of T's kind" mean? You might+be tempted to think that it corresponds to all of the arguments in the kind of+T that would normally be instantiated by omitted arguments. But this isn't+quite right, strictly speaking. Consider the following (silly) example:++ S :: forall {k}. Type -> Type++And suppose we have this application of S:++ S Int Bool++The Int argument would be omitted, and+injective_vars_of_binder(_ :: Type) = {}. This is not a superset of {k}, which+might suggest that (S Bool) needs an explicit kind signature. But+(S Bool :: Type) doesn't actually fix `k`! This is because the kind signature+only affects the /result/ of the application, not all of the individual+arguments. So adding a kind signature here won't make a difference. Therefore,+the fourth (and final) iteration of the Question We Must Answer is:++* Given the first n arguments of T (ty_1 ... ty_n), consider the binders+ of T that are instantiated by non-omitted arguments. For each such binder+ b_i, take the union of all injective_vars_of_binder(b_i). Is this set a+ superset of the free variables of the kind of (T ty_1 ... ty_n)?++Phew, that was a lot of work!++How can be sure that this is correct? That is, how can we be sure that in the+event that we leave off a kind annotation, that one could infer the kind of the+tycon application from its arguments? It's essentially a proof by induction: if+we can infer the kinds of every subtree of a type, then the whole tycon+application will have an inferrable kind--unless, of course, the remainder of+the tycon application's kind has uninstantiated kind variables.++What happens if T is oversaturated? That is, if T's kind has fewer than n+arguments, in the case that the concrete application instantiates a result+kind variable with an arrow kind? If we run out of arguments, we do not attach+a kind annotation. This should be a rare case, indeed. Here is an example:++ data T1 :: k1 -> k2 -> *+ data T2 :: k1 -> k2 -> *++ type family G (a :: k) :: k+ type instance G T1 = T2++ type instance F Char = (G T1 Bool :: (* -> *) -> *) -- F from above++Here G's kind is (forall k. k -> k), and the desugared RHS of that last+instance of F is (G (* -> (* -> *) -> *) (T1 * (* -> *)) Bool). According to+the algorithm above, there are 3 arguments to G so we should peel off 3+arguments in G's kind. But G's kind has only two arguments. This is the+rare special case, and we choose not to annotate the application of G with+a kind signature. After all, we needn't do this, since that instance would+be reified as:++ type instance F Char = G (T1 :: * -> (* -> *) -> *) Bool++So the kind of G isn't ambiguous anymore due to the explicit kind annotation+on its argument. See #8953 and test th/T8953.+-}++{-+************************************************************************+* *+ Multiplicities+* *+************************************************************************++These functions would prefer to be in GHC.Core.Multiplicity, but+they some are used elsewhere in this module, and wanted to bring+their friends here with them.+-}++unrestricted, linear, tymult :: a -> Scaled a++-- | Scale a payload by Many+unrestricted = Scaled ManyTy++-- | Scale a payload by One+linear = Scaled OneTy++-- | Scale a payload by Many; used for type arguments in core+tymult = Scaled ManyTy++irrelevantMult :: Scaled a -> a+irrelevantMult = scaledThing++mkScaled :: Mult -> a -> Scaled a+mkScaled = Scaled++scaledSet :: Scaled a -> b -> Scaled b+scaledSet (Scaled m _) b = Scaled m b++pattern OneTy :: Mult+pattern OneTy <- (isOneTy -> True)+ where OneTy = oneDataConTy++pattern ManyTy :: Mult+pattern ManyTy <- (isManyTy -> True)+ where ManyTy = manyDataConTy++isManyTy :: Mult -> Bool+isManyTy ty+ | Just tc <- tyConAppTyCon_maybe ty+ = tc `hasKey` manyDataConKey+isManyTy _ = False++isOneTy :: Mult -> Bool+isOneTy ty+ | Just tc <- tyConAppTyCon_maybe ty+ = tc `hasKey` oneDataConKey+isOneTy _ = False++isLinearType :: Type -> Bool+-- ^ @isLinear t@ returns @True@ of a if @t@ is a type of (curried) function+-- where at least one argument is linear (or otherwise non-unrestricted). We use+-- this function to check whether it is safe to eta reduce an Id in CorePrep. It+-- is always safe to return 'True', because 'True' deactivates the optimisation.+isLinearType ty = case ty of+ FunTy _ ManyTy _ res -> isLinearType res+ FunTy _ _ _ _ -> True+ ForAllTy _ res -> isLinearType res+ _ -> False++{- *********************************************************************+* *+ Space-saving construction+* *+********************************************************************* -}++{- Note [Using synonyms to compress types]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Was: [Prefer Type over TYPE (BoxedRep Lifted)]++The Core of nearly any program will have numerous occurrences of the Types++ TyConApp BoxedRep [TyConApp Lifted []] -- Synonym LiftedRep+ TyConApp BoxedRep [TyConApp Unlifted []] -- Synonym UnliftedREp+ TyConApp TYPE [TyConApp LiftedRep []] -- Synonym Type+ TyConApp TYPE [TyConApp UnliftedRep []] -- Synonym UnliftedType++While investigating #17292 we found that these constituted a majority+of all TyConApp constructors on the heap:++ (From a sample of 100000 TyConApp closures)+ 0x45f3523 - 28732 - `Type`+ 0x420b840702 - 9629 - generic type constructors+ 0x42055b7e46 - 9596+ 0x420559b582 - 9511+ 0x420bb15a1e - 9509+ 0x420b86c6ba - 9501+ 0x42055bac1e - 9496+ 0x45e68fd - 538 - `TYPE ...`++Consequently, we try hard to ensure that operations on such types are+efficient. Specifically, we strive to++ a. Avoid heap allocation of such types; use a single static TyConApp+ b. Use a small (shallow in the tree-depth sense) representation+ for such types++Goal (b) is particularly useful as it makes traversals (e.g. free variable+traversal, substitution, and comparison) more efficient.+Comparison in particular takes special advantage of nullary type synonym+applications (e.g. things like @TyConApp typeTyCon []@), Note [Comparing+nullary type synonyms] in "GHC.Core.Type".++To accomplish these we use a number of tricks, implemented by mkTyConApp.++ 1. Instead of (TyConApp BoxedRep [TyConApp Lifted []]),+ we prefer a statically-allocated (TyConApp LiftedRep [])+ where `LiftedRep` is a type synonym:+ type LiftedRep = BoxedRep Lifted+ Similarly for UnliftedRep++ 2. Instead of (TyConApp TYPE [TyConApp LiftedRep []])+ we prefer the statically-allocated (TyConApp Type [])+ where `Type` is a type synonym+ type Type = TYPE LiftedRep+ Similarly for UnliftedType++These serve goal (b) since there are no applied type arguments to traverse,+e.g., during comparison.++ 3. We have a single, statically allocated top-level binding to+ represent `TyConApp GHC.Types.Type []` (namely+ 'GHC.Builtin.Types.Prim.liftedTypeKind'), ensuring that we don't+ need to allocate such types (goal (a)). See functions+ mkTYPEapp and mkBoxedRepApp++ 4. We use the sharing mechanism described in Note [Sharing nullary TyConApps]+ in GHC.Core.TyCon to ensure that we never need to allocate such+ nullary applications (goal (a)).++See #17958, #20541+-}++-- | A key function: builds a 'TyConApp' or 'FunTy' as appropriate to+-- its arguments. Applies its arguments to the constructor from left to right.+mkTyConApp :: TyCon -> [Type] -> Type+mkTyConApp tycon []+ = -- See Note [Sharing nullary TyConApps] in GHC.Core.TyCon+ mkTyConTy tycon++mkTyConApp tycon tys@(ty1:rest)+ | Just fun_ty <- tyConAppFunTy_maybe tycon tys+ = fun_ty++ -- See Note [Using synonyms to compress types]+ | key == tYPETyConKey+ , Just ty <- mkTYPEapp_maybe ty1+ = assert (null rest) ty++ | key == cONSTRAINTTyConKey+ , Just ty <- mkCONSTRAINTapp_maybe ty1+ = assert (null rest) ty++ -- See Note [Using synonyms to compress types]+ | key == boxedRepDataConTyConKey+ , Just ty <- mkBoxedRepApp_maybe ty1+ = assert (null rest) ty++ | key == tupleRepDataConTyConKey+ , Just ty <- mkTupleRepApp_maybe ty1+ = assert (null rest) ty++ -- The catch-all case+ | otherwise+ = TyConApp tycon tys+ where+ key = tyConUnique tycon+++{- Note [Care using synonyms to compress types]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Using a synonym to compress a types has a tricky wrinkle. Consider+coreView applied to (TyConApp LiftedRep [])++* coreView expands the LiftedRep synonym:+ type LiftedRep = BoxedRep Lifted++* Danger: we might apply the empty substitution to the RHS of the+ synonym. And substTy calls mkTyConApp BoxedRep [Lifted]. And+ mkTyConApp compresses that back to LiftedRep. Loop!++* Solution: in expandSynTyConApp_maybe, don't call substTy for nullary+ type synonyms. That's more efficient anyway.+-}+++mkTYPEapp :: RuntimeRepType -> Type+mkTYPEapp rr+ = case mkTYPEapp_maybe rr of+ Just ty -> ty+ Nothing -> TyConApp tYPETyCon [rr]++mkTYPEapp_maybe :: RuntimeRepType -> Maybe Type+-- ^ Given a @RuntimeRep@, applies @TYPE@ to it.+-- On the fly it rewrites+-- TYPE LiftedRep --> liftedTypeKind (a synonym)+-- TYPE UnliftedRep --> unliftedTypeKind (ditto)+-- TYPE ZeroBitRep --> zeroBitTypeKind (ditto)+-- NB: no need to check for TYPE (BoxedRep Lifted), TYPE (BoxedRep Unlifted)+-- because those inner types should already have been rewritten+-- to LiftedRep and UnliftedRep respectively, by mkTyConApp+--+-- see Note [TYPE and CONSTRAINT] in GHC.Builtin.Types.Prim.+-- See Note [Using synonyms to compress types] in GHC.Core.Type+{-# NOINLINE mkTYPEapp_maybe #-}+mkTYPEapp_maybe (TyConApp tc args)+ | key == liftedRepTyConKey = assert (null args) $ Just liftedTypeKind -- TYPE LiftedRep+ | key == unliftedRepTyConKey = assert (null args) $ Just unliftedTypeKind -- TYPE UnliftedRep+ | key == zeroBitRepTyConKey = assert (null args) $ Just zeroBitTypeKind -- TYPE ZeroBitRep+ where+ key = tyConUnique tc+mkTYPEapp_maybe _ = Nothing++------------------+mkCONSTRAINTapp :: RuntimeRepType -> Type+-- ^ Just like mkTYPEapp+mkCONSTRAINTapp rr+ = case mkCONSTRAINTapp_maybe rr of+ Just ty -> ty+ Nothing -> TyConApp cONSTRAINTTyCon [rr]++mkCONSTRAINTapp_maybe :: RuntimeRepType -> Maybe Type+-- ^ Just like mkTYPEapp_maybe+{-# NOINLINE mkCONSTRAINTapp_maybe #-}+mkCONSTRAINTapp_maybe (TyConApp tc args)+ | key == liftedRepTyConKey = assert (null args) $ Just constraintKind -- CONSTRAINT LiftedRep+ where+ key = tyConUnique tc+mkCONSTRAINTapp_maybe _ = Nothing++------------------+mkBoxedRepApp_maybe :: LevityType -> Maybe Type+-- ^ Given a `Levity`, apply `BoxedRep` to it+-- On the fly, rewrite+-- BoxedRep Lifted --> liftedRepTy (a synonym)+-- BoxedRep Unlifted --> unliftedRepTy (ditto)+-- See Note [TYPE and CONSTRAINT] in GHC.Builtin.Types.Prim.+-- See Note [Using synonyms to compress types] in GHC.Core.Type+{-# NOINLINE mkBoxedRepApp_maybe #-}+mkBoxedRepApp_maybe (TyConApp tc args)+ | key == liftedDataConKey = assert (null args) $ Just liftedRepTy -- BoxedRep Lifted+ | key == unliftedDataConKey = assert (null args) $ Just unliftedRepTy -- BoxedRep Unlifted+ where+ key = tyConUnique tc+mkBoxedRepApp_maybe _ = Nothing++mkTupleRepApp_maybe :: Type -> Maybe Type+-- ^ Given a `[RuntimeRep]`, apply `TupleRep` to it+-- On the fly, rewrite+-- TupleRep [] -> zeroBitRepTy (a synonym)+-- See Note [TYPE and CONSTRAINT] in GHC.Builtin.Types.Prim.+-- See Note [Using synonyms to compress types] in GHC.Core.Type+{-# NOINLINE mkTupleRepApp_maybe #-}+mkTupleRepApp_maybe (TyConApp tc args)+ | key == nilDataConKey = assert (isSingleton args) $ Just zeroBitRepTy -- ZeroBitRep+ where+ key = tyConUnique tc+mkTupleRepApp_maybe _ = Nothing++typeOrConstraintKind :: TypeOrConstraint -> RuntimeRepType -> Kind+typeOrConstraintKind TypeLike rep = mkTYPEapp rep+typeOrConstraintKind ConstraintLike rep = mkCONSTRAINTapp rep
compiler/GHC/Core/Type.hs-boot view
@@ -4,29 +4,35 @@ import GHC.Prelude import {-# SOURCE #-} GHC.Core.TyCon-import {-# SOURCE #-} GHC.Core.TyCo.Rep( Type, RuntimeRepType, Coercion )+import {-# SOURCE #-} GHC.Core.TyCo.Rep( Type, Coercion ) import GHC.Utils.Misc+import GHC.Types.Var( FunTyFlag, TyVar )+import GHC.Types.Basic( TypeOrConstraint ) isPredTy :: HasDebugCallStack => Type -> Bool isCoercionTy :: Type -> Bool mkAppTy :: Type -> Type -> Type mkCastTy :: Type -> Coercion -> Type-mkTyConTy :: TyCon -> Type mkTyConApp :: TyCon -> [Type] -> Type+mkCoercionTy :: Coercion -> Type piResultTy :: HasDebugCallStack => Type -> Type -> Type +typeKind :: HasDebugCallStack => Type -> Type+typeTypeOrConstraint :: HasDebugCallStack => Type -> TypeOrConstraint+ coreView :: Type -> Maybe Type-tcView :: Type -> Maybe Type isRuntimeRepTy :: Type -> Bool isLevityTy :: Type -> Bool isMultiplicityTy :: Type -> Bool isLiftedTypeKind :: Type -> Bool-mkTYPEapp :: RuntimeRepType -> Type splitTyConApp_maybe :: HasDebugCallStack => Type -> Maybe (TyCon, [Type]) tyConAppTyCon_maybe :: Type -> Maybe TyCon+getTyVar_maybe :: Type -> Maybe TyVar getLevity :: HasDebugCallStack => Type -> Type partitionInvisibleTypes :: TyCon -> [Type] -> ([Type], [Type])++chooseFunTyFlag :: HasDebugCallStack => Type -> Type -> FunTyFlag
compiler/GHC/Core/Unfold.hs view
@@ -1347,8 +1347,11 @@ for the RHS of a 'let', we only profit from the inlining if we get a CONLIKE thing (modulo lets). -Note [Lone variables] See also Note [Interaction of exprIsWorkFree and lone variables]-~~~~~~~~~~~~~~~~~~~~~ which appears below+Note [Lone variables]+~~~~~~~~~~~~~~~~~~~~~+See also Note [Interaction of exprIsWorkFree and lone variables]+which appears below+ The "lone-variable" case is important. I spent ages messing about with unsatisfactory variants, but this is nice. The idea is that if a variable appears all alone
compiler/GHC/Core/Unify.hs view
@@ -10,21 +10,19 @@ tcMatchTyX, tcMatchTysX, tcMatchTyKisX, tcMatchTyX_BM, ruleMatchTyKiX, - -- * Rough matching- RoughMatchTc(..), roughMatchTcs, roughMatchTcsLookup, instanceCantMatch,- typesCantMatch, isRoughWildcard,- -- Side-effect free unification tcUnifyTy, tcUnifyTyKi, tcUnifyTys, tcUnifyTyKis, tcUnifyTysFG, tcUnifyTyWithTFs, BindFun, BindFlag(..), matchBindFun, alwaysBindFun, UnifyResult, UnifyResultM(..), MaybeApartReason(..),+ typesCantMatch, typesAreApart, -- Matching a type against a lifted type (coercion) liftCoMatch, -- The core flattening algorithm- flattenTys, flattenTysX+ flattenTys, flattenTysX,+ ) where import GHC.Prelude@@ -37,9 +35,9 @@ import GHC.Core.Coercion hiding ( getCvSubstEnv ) import GHC.Core.TyCon import GHC.Core.TyCo.Rep-import GHC.Core.TyCo.FVs ( tyCoVarsOfCoList, tyCoFVsOfTypes )-import GHC.Core.TyCo.Subst ( mkTvSubst, emptyIdSubstEnv )-import GHC.Core.RoughMap+import GHC.Core.TyCo.Compare ( eqType, tcEqType )+import GHC.Core.TyCo.FVs ( tyCoVarsOfCoList, tyCoFVsOfTypes )+import GHC.Core.TyCo.Subst ( mkTvSubst, emptyIdSubstEnv ) import GHC.Core.Map.Type import GHC.Utils.FV( FV, fvVarList ) import GHC.Utils.Misc@@ -48,7 +46,6 @@ import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Set-import {-# SOURCE #-} GHC.Tc.Utils.TcType ( tcEqType ) import GHC.Exts( oneShot ) import GHC.Utils.Panic.Plain import GHC.Data.FastString@@ -57,8 +54,6 @@ import Control.Monad import qualified Data.Semigroup as S -import GHC.Builtin.Names (constraintKindTyConKey, liftedTypeKindTyConKey)- {- Unification is much tricker than you might think.@@ -161,7 +156,7 @@ -- See also Note [tcMatchTy vs tcMatchTyKi] tcMatchTys :: [Type] -- ^ Template -> [Type] -- ^ Target- -> Maybe Subst -- ^ One-shot; in principle the template+ -> Maybe Subst -- ^ One-shot; in principle the template -- variables could be free in the target tcMatchTys tys1 tys2 = tc_match_tys alwaysBindFun False tys1 tys2@@ -254,62 +249,6 @@ alwaysBindFun :: BindFun alwaysBindFun _tv _ty = BindMe -{- *********************************************************************-* *- Rough matching-* *-********************************************************************* -}--{- Note [Rough matching in class and family instances]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Consider- instance C (Maybe [Tree a]) Bool-and suppose we are looking up- C Bool Bool--We can very quickly rule the instance out, because the first-argument is headed by Maybe, whereas in the constraint we are looking-up has first argument headed by Bool. These "headed by" TyCons are-called the "rough match TyCons" of the constraint or instance.-They are used for a quick filter, to check when an instance cannot-possibly match.--The main motivation is to avoid sucking in whole instance-declarations that are utterly useless. See GHC.Core.InstEnv-Note [ClsInst laziness and the rough-match fields].--INVARIANT: a rough-match TyCons `tc` is always a real, generative tycon,-like Maybe or Either, including a newtype or a data family, both of-which are generative. It replies True to `isGenerativeTyCon tc Nominal`.--But it is never- - A type synonym- E.g. Int and (S Bool) might match- if (S Bool) is a synonym for Int-- - A type family (#19336)- E.g. (Just a) and (F a) might match if (F a) reduces to (Just a)- albeit perhaps only after 'a' is instantiated.--}--roughMatchTcs :: [Type] -> [RoughMatchTc]-roughMatchTcs tys = map typeToRoughMatchTc tys--roughMatchTcsLookup :: [Type] -> [RoughMatchLookupTc]-roughMatchTcsLookup tys = map typeToRoughMatchLookupTc tys--instanceCantMatch :: [RoughMatchTc] -> [RoughMatchTc] -> Bool--- (instanceCantMatch tcs1 tcs2) returns True if tcs1 cannot--- possibly be instantiated to actual, nor vice versa;--- False is non-committal-instanceCantMatch (mt : ts) (ma : as) = itemCantMatch mt ma || instanceCantMatch ts as-instanceCantMatch _ _ = False -- Safe--itemCantMatch :: RoughMatchTc -> RoughMatchTc -> Bool-itemCantMatch (RM_KnownTc t) (RM_KnownTc a) = t /= a-itemCantMatch _ _ = False-- {- ************************************************************************ * *@@ -351,13 +290,12 @@ -- apart, even after arbitrary type function evaluation and substitution? typesCantMatch :: [(Type,Type)] -> Bool -- See Note [Pruning dead case alternatives]-typesCantMatch prs = any (uncurry cant_match) prs- where- cant_match :: Type -> Type -> Bool- cant_match t1 t2 = case tcUnifyTysFG alwaysBindFun [t1] [t2] of- SurelyApart -> True- _ -> False+typesCantMatch prs = any (uncurry typesAreApart) prs +typesAreApart :: Type -> Type -> Bool+typesAreApart t1 t2 = case tcUnifyTysFG alwaysBindFun [t1] [t2] of+ SurelyApart -> True+ _ -> False {- ************************************************************************ * *@@ -538,11 +476,14 @@ -- This is used (only) in Note [Infinitary substitution in lookup] in GHC.Core.InstEnv -- As of Feb 2022, we never differentiate between MARTypeFamily and MARTypeVsConstraint; -- it's really only MARInfinite that's interesting here.-data MaybeApartReason = MARTypeFamily -- ^ matching e.g. F Int ~? Bool- | MARInfinite -- ^ matching e.g. a ~? Maybe a- | MARTypeVsConstraint -- ^ matching Type ~? Constraint- -- See Note [coreView vs tcView] in GHC.Core.Type+data MaybeApartReason+ = MARTypeFamily -- ^ matching e.g. F Int ~? Bool + | MARInfinite -- ^ matching e.g. a ~? Maybe a++ | MARTypeVsConstraint -- ^ matching Type ~? Constraint or the arrow types+ -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim+ instance Outputable MaybeApartReason where ppr MARTypeFamily = text "MARTypeFamily" ppr MARInfinite = text "MARInfinite"@@ -943,10 +884,18 @@ kind of the right-hand type. Note that we do not unify kinds at the leaves (as we did previously). We thus have -INVARIANT: In the call- unify_ty ty1 ty2 kco-it must be that subst(kco) :: subst(kind(ty1)) ~N subst(kind(ty2)), where-`subst` is the ambient substitution in the UM monad.+Hence: (Unification Kind Invariant)+-----------------------------------+In the call+ unify_ty ty1 ty2 kco+it must be that+ subst(kco) :: subst(kind(ty1)) ~N subst(kind(ty2))+where `subst` is the ambient substitution in the UM monad. And in the call+ unify_tys tys1 tys2+(which has no kco), after we unify any prefix of tys1,tys2, the kinds of the+head of the remaining tys1,tys2 are identical after substitution. This+implies, for example, that the kinds of the head of tys1,tys2 are identical+after substitution. To get this coercion, we first have to match/unify the kinds before looking at the types. Happily, we need look only one level@@ -1057,6 +1006,8 @@ -> CoercionN -- A coercion between their kinds -- See Note [Kind coercions in Unify] -> UM ()+-- Precondition: see (Unification Kind Invariant)+-- -- See Note [Specification of unification] -- Respects newtypes, PredTypes -- See Note [Computing equality on types] in GHC.Core.Type@@ -1065,19 +1016,10 @@ | tc1 == tc2 = return () - -- See Note [coreView vs tcView] in GHC.Core.Type.- | tc1 `hasKey` constraintKindTyConKey- , tc2 `hasKey` liftedTypeKindTyConKey- = maybeApart MARTypeVsConstraint-- | tc2 `hasKey` constraintKindTyConKey- , tc1 `hasKey` liftedTypeKindTyConKey- = maybeApart MARTypeVsConstraint- unify_ty env ty1 ty2 kco -- Now handle the cases we can "look through": synonyms and casts.- | Just ty1' <- tcView ty1 = unify_ty env ty1' ty2 kco- | Just ty2' <- tcView ty2 = unify_ty env ty1 ty2' kco+ | Just ty1' <- coreView ty1 = unify_ty env ty1' ty2 kco+ | Just ty2' <- coreView ty2 = unify_ty env ty1 ty2' kco | CastTy ty1' co <- ty1 = if um_unif env then unify_ty env ty1' ty2 (co `mkTransCo` kco) else -- See Note [Matching in the presence of casts (1)]@@ -1093,8 +1035,6 @@ = uVar (umSwapRn env) tv2 ty1 (mkSymCo kco) unify_ty env ty1 ty2 _kco- -- NB: This keeps Constraint and Type distinct, as it should for use in the- -- type-checker. | Just (tc1, tys1) <- mb_tc_app1 , Just (tc2, tys2) <- mb_tc_app2 , tc1 == tc2@@ -1130,32 +1070,44 @@ -- NB: we have already dealt with the 'ty1 = variable' case = maybeApart MARTypeFamily + -- TYPE and CONSTRAINT are not Apart+ -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim+ -- NB: at this point we know that the two TyCons do not match+ | Just {} <- sORTKind_maybe ty1+ , Just {} <- sORTKind_maybe ty2+ = maybeApart MARTypeVsConstraint+ -- We don't bother to look inside; wrinkle (W3) in GHC.Builtin.Types.Prim+ -- Note [Type and Constraint are not apart]++ -- The arrow types are not Apart+ -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim+ -- wrinkle (W2)+ -- NB1: at this point we know that the two TyCons do not match+ -- NB2: In the common FunTy/FunTy case you might wonder if we want to go via+ -- splitTyConApp_maybe. But yes we do: we need to look at those implied+ -- kind argument in order to satisfy (Unification Kind Invariant)+ | FunTy {} <- ty1+ , FunTy {} <- ty2+ = maybeApart MARTypeVsConstraint+ -- We don't bother to look inside; wrinkle (W3) in GHC.Builtin.Types.Prim+ -- Note [Type and Constraint are not apart]+ where- mb_tc_app1 = tcSplitTyConApp_maybe ty1- mb_tc_app2 = tcSplitTyConApp_maybe ty2+ mb_tc_app1 = splitTyConApp_maybe ty1+ mb_tc_app2 = splitTyConApp_maybe ty2 -- Applications need a bit of care! -- They can match FunTy and TyConApp, so use splitAppTy_maybe -- NB: we've already dealt with type variables, -- so if one type is an App the other one jolly well better be too unify_ty env (AppTy ty1a ty1b) ty2 _kco- | Just (ty2a, ty2b) <- tcRepSplitAppTy_maybe ty2+ | Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2 = unify_ty_app env ty1a [ty1b] ty2a [ty2b] unify_ty env ty1 (AppTy ty2a ty2b) _kco- | Just (ty1a, ty1b) <- tcRepSplitAppTy_maybe ty1+ | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1 = unify_ty_app env ty1a [ty1b] ty2a [ty2b] - -- tcSplitTyConApp won't split a (=>), so we handle this separately.-unify_ty env (FunTy InvisArg _w1 arg1 res1) (FunTy InvisArg _w2 arg2 res2) _kco- -- Look at result representations, but arg representations would be redundant- -- as anything that can appear to the left of => is lifted.- -- And anything that can appear to the left of => is unrestricted, so skip the- -- multiplicities.- | Just res_rep1 <- getRuntimeRep_maybe res1- , Just res_rep2 <- getRuntimeRep_maybe res2- = unify_tys env [res_rep1, arg1, res1] [res_rep2, arg2, res2]- unify_ty _ (LitTy x) (LitTy y) _kco | x == y = return () unify_ty env (ForAllTy (Bndr tv1 _) ty1) (ForAllTy (Bndr tv2 _) ty2) kco@@ -1170,7 +1122,7 @@ CoVarCo cv | not (um_unif env) , not (cv `elemVarEnv` c_subst)- , let (_, co_l, co_r) = decomposeFunCo Nominal kco+ , let (_, co_l, co_r) = decomposeFunCo kco -- Because the coercion is used in a type, it should be safe to -- ignore the multiplicity coercion. -- cv :: t1 ~ t2@@ -1187,8 +1139,8 @@ unify_ty_app :: UMEnv -> Type -> [Type] -> Type -> [Type] -> UM () unify_ty_app env ty1 ty1args ty2 ty2args- | Just (ty1', ty1a) <- repSplitAppTy_maybe ty1- , Just (ty2', ty2a) <- repSplitAppTy_maybe ty2+ | Just (ty1', ty1a) <- splitAppTyNoView_maybe ty1+ , Just (ty2', ty2a) <- splitAppTyNoView_maybe ty2 = unify_ty_app env ty1' (ty1a : ty1args) ty2' (ty2a : ty2args) | otherwise@@ -1202,6 +1154,7 @@ ; unify_tys env ty1args ty2args } unify_tys :: UMEnv -> [Type] -> [Type] -> UM ()+-- Precondition: see (Unification Kind Invariant) unify_tys env orig_xs orig_ys = go orig_xs orig_ys where@@ -1260,8 +1213,7 @@ -- We know that tv1 isn't refined uUnrefined env tv1' ty2 ty2' kco- -- Use tcView, not coreView. See Note [coreView vs tcView] in GHC.Core.Type.- | Just ty2'' <- tcView ty2'+ | Just ty2'' <- coreView ty2' = uUnrefined env tv1' ty2 ty2'' kco -- Unwrap synonyms -- This is essential, in case we have -- type Foo a = a@@ -1555,8 +1507,6 @@ -- where lsubst = lcSubstLeft(env) and rsubst = lcSubstRight(env) ty_co_match menv subst ty co lkco rkco | Just ty' <- coreView ty = ty_co_match menv subst ty' co lkco rkco- -- why coreView here, not tcView? Because we're firmly after type-checking.- -- This function is used only during coercion optimisation. -- handle Refl case: | tyCoVarsOfType ty `isNotInDomainOf` subst@@ -1615,25 +1565,25 @@ | Just (co2, arg2) <- splitAppCo_maybe co -- c.f. Unify.match on AppTy = ty_co_match_app menv subst ty1a [ty1b] co2 [arg2] ty_co_match menv subst ty1 (AppCo co2 arg2) _lkco _rkco- | Just (ty1a, ty1b) <- repSplitAppTy_maybe ty1+ | Just (ty1a, ty1b) <- splitAppTyNoView_maybe ty1 -- yes, the one from Type, not TcType; this is for coercion optimization = ty_co_match_app menv subst ty1a [ty1b] co2 [arg2] ty_co_match menv subst (TyConApp tc1 tys) (TyConAppCo _ tc2 cos) _lkco _rkco = ty_co_match_tc menv subst tc1 tys tc2 cos-ty_co_match menv subst (FunTy _ w ty1 ty2) co _lkco _rkco- | Just (tc, [co_mult,rrco1,rrco2,co1,co2]) <- splitTyConAppCo_maybe co- , tc == funTyCon- = let rr1 = getRuntimeRep ty1- rr2 = getRuntimeRep ty2- Pair lkcos rkcos = traverse (fmap (mkNomReflCo . typeKind) . coercionKind)- [co_mult,rrco1, rrco2,co1,co2]- in -- NB: we include the RuntimeRep arguments in the matching; not doing so caused #21205.- ty_co_match_args menv subst- [w, rr1, rr2, ty1, ty2]- [co_mult, rrco1, rrco2, co1, co2]- lkcos rkcos +ty_co_match menv subst (FunTy { ft_mult = w, ft_arg = ty1, ft_res = ty2 })+ (FunCo { fco_mult = co_w, fco_arg = co1, fco_res = co2 }) _lkco _rkco+ = ty_co_match_args menv subst [w, rep1, rep2, ty1, ty2]+ [co_w, co1_rep, co2_rep, co1, co2]+ where+ rep1 = getRuntimeRep ty1+ rep2 = getRuntimeRep ty2+ co1_rep = mkRuntimeRepCo co1+ co2_rep = mkRuntimeRepCo co2+ -- NB: we include the RuntimeRep arguments in the matching;+ -- not doing so caused #21205.+ ty_co_match menv subst (ForAllTy (Bndr tv1 _) ty1) (ForAllCo tv2 kind_co2 co2) lkco rkco@@ -1655,9 +1605,9 @@ -- 1. Given: -- cv1 :: (s1 :: k1) ~r (s2 :: k2) -- kind_co2 :: (s1' ~ s2') ~N (t1 ~ t2)--- eta1 = mkNthCo role 2 (downgradeRole r Nominal kind_co2)+-- eta1 = mkSelCo (SelTyCon 2 role) (downgradeRole r Nominal kind_co2) -- :: s1' ~ t1--- eta2 = mkNthCo role 3 (downgradeRole r Nominal kind_co2)+-- eta2 = mkSelCo (SelTyCon 3 role) (downgradeRole r Nominal kind_co2) -- :: s2' ~ t2 -- Wanted: -- subst1 <- ty_co_match menv subst s1 eta1 kco1 kco2@@ -1687,7 +1637,6 @@ in ty_co_match menv subst ty (mkReflCo r t) (lkco `mkTransCo` kco') (rkco `mkTransCo` kco') - ty_co_match menv subst ty co lkco rkco | Just co' <- pushRefl co = ty_co_match menv subst ty co' lkco rkco | otherwise = Nothing@@ -1698,16 +1647,13 @@ -> Maybe LiftCoEnv ty_co_match_tc menv subst tc1 tys1 tc2 cos2 = do { guard (tc1 == tc2)- ; ty_co_match_args menv subst tys1 cos2 lkcos rkcos }- where- Pair lkcos rkcos- = traverse (fmap (mkNomReflCo . typeKind) . coercionKind) cos2+ ; ty_co_match_args menv subst tys1 cos2 } ty_co_match_app :: MatchEnv -> LiftCoEnv -> Type -> [Type] -> Coercion -> [Coercion] -> Maybe LiftCoEnv ty_co_match_app menv subst ty1 ty1args co2 co2args- | Just (ty1', ty1a) <- repSplitAppTy_maybe ty1+ | Just (ty1', ty1a) <- splitAppTyNoView_maybe ty1 , Just (co2', co2a) <- splitAppCo_maybe co2 = ty_co_match_app menv subst ty1' (ty1a : ty1args) co2' (co2a : co2args) @@ -1715,34 +1661,32 @@ = do { subst1 <- ty_co_match menv subst ki1 ki2 ki_ki_co ki_ki_co ; let Pair lkco rkco = mkNomReflCo <$> coercionKind ki2 ; subst2 <- ty_co_match menv subst1 ty1 co2 lkco rkco- ; let Pair lkcos rkcos = traverse (fmap (mkNomReflCo . typeKind) . coercionKind) co2args- ; ty_co_match_args menv subst2 ty1args co2args lkcos rkcos }+ ; ty_co_match_args menv subst2 ty1args co2args } where ki1 = typeKind ty1 ki2 = promoteCoercion co2 ki_ki_co = mkNomReflCo liftedTypeKind -ty_co_match_args :: MatchEnv -> LiftCoEnv -> [Type]- -> [Coercion] -> [Coercion] -> [Coercion]+ty_co_match_args :: MatchEnv -> LiftCoEnv -> [Type] -> [Coercion] -> Maybe LiftCoEnv-ty_co_match_args _ subst [] [] _ _ = Just subst-ty_co_match_args menv subst (ty:tys) (arg:args) (lkco:lkcos) (rkco:rkcos)- = do { subst' <- ty_co_match menv subst ty arg lkco rkco- ; ty_co_match_args menv subst' tys args lkcos rkcos }-ty_co_match_args _ _ _ _ _ _ = Nothing+ty_co_match_args menv subst (ty:tys) (arg:args)+ = do { let Pair lty rty = coercionKind arg+ lkco = mkNomReflCo (typeKind lty)+ rkco = mkNomReflCo (typeKind rty)+ ; subst' <- ty_co_match menv subst ty arg lkco rkco+ ; ty_co_match_args menv subst' tys args }+ty_co_match_args _ subst [] [] = Just subst+ty_co_match_args _ _ _ _ = Nothing pushRefl :: Coercion -> Maybe Coercion pushRefl co = case (isReflCo_maybe co) of Just (AppTy ty1 ty2, Nominal) -> Just (AppCo (mkReflCo Nominal ty1) (mkNomReflCo ty2))- Just (FunTy _ w ty1 ty2, r)- | Just rep1 <- getRuntimeRep_maybe ty1- , Just rep2 <- getRuntimeRep_maybe ty2- -> Just (TyConAppCo r funTyCon [ multToCo w, mkReflCo r rep1, mkReflCo r rep2- , mkReflCo r ty1, mkReflCo r ty2 ])+ Just (FunTy af w ty1 ty2, r)+ -> Just (FunCo r af af (mkReflCo r w) (mkReflCo r ty1) (mkReflCo r ty2)) Just (TyConApp tc tys, r)- -> Just (TyConAppCo r tc (zipWith mkReflCo (tyConRolesX r tc) tys))+ -> Just (TyConAppCo r tc (zipWith mkReflCo (tyConRoleListX r tc) tys)) Just (ForAllTy (Bndr tv _) ty, r) -> Just (ForAllCo tv (mkNomReflCo (varType tv)) (mkReflCo r ty)) -- NB: NoRefl variant. Otherwise, we get a loop!@@ -2065,3 +2009,4 @@ = let uniq = unsafeGetFreshLocalUnique in_scope name = mkSystemVarName uniq (fsLit "flc") in mkCoVar name kind+
compiler/GHC/Core/UsageEnv.hs view
@@ -46,10 +46,10 @@ addUsage (MUsage x) (MUsage y) = MUsage $ mkMultAdd x y scaleUsage :: Mult -> Usage -> Usage-scaleUsage One Bottom = Bottom-scaleUsage _ Zero = Zero-scaleUsage x Bottom = MUsage x-scaleUsage x (MUsage y) = MUsage $ mkMultMul x y+scaleUsage OneTy Bottom = Bottom+scaleUsage _ Zero = Zero+scaleUsage x Bottom = MUsage x+scaleUsage x (MUsage y) = MUsage $ mkMultMul x y -- For now, we use extra multiplicity Bottom for empty case. data UsageEnv = UsageEnv !(NameEnv Mult) Bool@@ -67,19 +67,19 @@ UsageEnv (plusNameEnv_C mkMultAdd e1 e2) (b1 || b2) scaleUE :: Mult -> UsageEnv -> UsageEnv-scaleUE One ue = ue+scaleUE OneTy ue = ue scaleUE w (UsageEnv e _) = UsageEnv (mapNameEnv (mkMultMul w) e) False supUE :: UsageEnv -> UsageEnv -> UsageEnv supUE (UsageEnv e1 False) (UsageEnv e2 False) =- UsageEnv (plusNameEnv_CD mkMultSup e1 Many e2 Many) False+ UsageEnv (plusNameEnv_CD mkMultSup e1 ManyTy e2 ManyTy) False supUE (UsageEnv e1 b1) (UsageEnv e2 b2) = UsageEnv (plusNameEnv_CD2 combineUsage e1 e2) (b1 && b2) where combineUsage (Just x) (Just y) = mkMultSup x y combineUsage Nothing (Just x) | b1 = x- | otherwise = Many+ | otherwise = ManyTy combineUsage (Just x) Nothing | b2 = x- | otherwise = Many+ | otherwise = ManyTy combineUsage Nothing Nothing = pprPanic "supUE" (ppr e1 <+> ppr e2) -- Note: If you are changing this logic, check 'mkMultSup' in Multiplicity as well.
compiler/GHC/Core/Utils.hs view
@@ -73,7 +73,7 @@ import GHC.Core.DataCon import GHC.Core.Type as Type import GHC.Core.FamInstEnv-import GHC.Core.TyCo.Rep( TyCoBinder(..), TyBinder )+import GHC.Core.TyCo.Compare( eqType, eqTypeX ) import GHC.Core.Coercion import GHC.Core.Reduction import GHC.Core.TyCon@@ -107,7 +107,6 @@ import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Misc-import GHC.Utils.Trace import Data.ByteString ( ByteString ) import Data.Function ( on )@@ -170,26 +169,15 @@ mkLamType v body_ty | isTyVar v- = mkForAllTy v Inferred body_ty+ = mkForAllTy (Bndr v Inferred) body_ty | isCoVar v , v `elemVarSet` tyCoVarsOfType body_ty- = mkForAllTy v Required body_ty+ = mkForAllTy (Bndr v Required) body_ty | otherwise = mkFunctionType (varMult v) (varType v) body_ty -mkFunctionType :: Mult -> Type -> Type -> Type--- This one works out the AnonArgFlag from the argument type--- See GHC.Types.Var Note [AnonArgFlag]-mkFunctionType mult arg_ty res_ty- | isPredTy arg_ty -- See GHC.Types.Var Note [AnonArgFlag]- = assert (eqType mult Many) $- mkInvisFunTy mult arg_ty res_ty-- | otherwise- = mkVisFunTy mult arg_ty res_ty- mkLamTypes vs ty = foldr mkLamType ty vs {-@@ -239,7 +227,7 @@ go op_ty [] = op_ty go op_ty (Type ty : args) = go_ty_args op_ty [ty] args go op_ty (Coercion co : args) = go_ty_args op_ty [mkCoercionTy co] args- go op_ty (_ : args) | Just (_, _, res_ty) <- splitFunTy_maybe op_ty+ go op_ty (_ : args) | Just (_, _, _, res_ty) <- splitFunTy_maybe op_ty = go res_ty args go _ args = pprPanic "applyTypeToArgs" (panic_msg args) @@ -1401,9 +1389,8 @@ | Just (bndr, ty) <- splitPiTy_maybe ty = case bndr of- Named {} -> all_pred_args n_val_args ty- Anon InvisArg _ -> all_pred_args (n_val_args-1) ty- Anon VisArg _ -> False+ Named {} -> all_pred_args n_val_args ty+ Anon _ af -> isInvisibleFunArg af && all_pred_args (n_val_args-1) ty | otherwise = False@@ -1636,9 +1623,9 @@ (arg_tys, _) = splitPiTys (idType fun) -- Used for arguments to primops and to partial applications- arg_ok :: TyBinder -> CoreExpr -> Bool+ arg_ok :: PiTyVarBinder -> CoreExpr -> Bool arg_ok (Named _) _ = True -- A type argument- arg_ok (Anon _ ty) arg -- A term argument+ arg_ok (Anon ty _) arg -- A term argument | Just Lifted <- typeLevity_maybe (scaledThing ty) = True -- See Note [Primops with lifted arguments] | otherwise
− compiler/GHC/Core/Utils.hs-boot
@@ -1,6 +0,0 @@-module GHC.Core.Utils where--import GHC.Core.Multiplicity-import GHC.Core.Type--mkFunctionType :: Mult -> Type -> Type -> Type
compiler/GHC/CoreToIface.hs view
@@ -9,7 +9,7 @@ , toIfaceBndr , toIfaceTopBndr , toIfaceForAllBndr- , toIfaceTyCoVarBinders+ , toIfaceForAllBndrs , toIfaceTyVar -- * Types , toIfaceType, toIfaceTypeX@@ -57,18 +57,18 @@ import GHC.Core.Multiplicity import GHC.Core.PatSyn import GHC.Core.TyCo.Rep+import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.TyCo.Tidy ( tidyCo ) import GHC.Builtin.Types.Prim ( eqPrimTyCon, eqReprPrimTyCon ) import GHC.Builtin.Types ( heqTyCon )-import GHC.Builtin.Names import GHC.Iface.Syntax import GHC.Data.FastString import GHC.Types.Id import GHC.Types.Id.Info-import GHC.Types.Id.Make ( noinlineIdName )+import GHC.Types.Id.Make ( noinlineIdName, noinlineConstraintIdName ) import GHC.Types.Literal import GHC.Types.Name import GHC.Types.Basic@@ -82,9 +82,8 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Misc-import GHC.Utils.Trace -import Data.Maybe ( catMaybes )+import Data.Maybe ( isNothing, catMaybes ) {- Note [Avoiding space leaks in toIface*] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -144,12 +143,15 @@ | isId var = IfaceIdBndr (toIfaceIdBndrX fr var) | otherwise = IfaceTvBndr (toIfaceTvBndrX fr var) -toIfaceTyCoVarBinder :: VarBndr Var vis -> VarBndr IfaceBndr vis-toIfaceTyCoVarBinder (Bndr tv vis) = Bndr (toIfaceBndr tv) vis+toIfaceForAllBndrs :: [VarBndr TyCoVar vis] -> [VarBndr IfaceBndr vis]+toIfaceForAllBndrs = map toIfaceForAllBndr -toIfaceTyCoVarBinders :: [VarBndr Var vis] -> [VarBndr IfaceBndr vis]-toIfaceTyCoVarBinders = map toIfaceTyCoVarBinder+toIfaceForAllBndr :: VarBndr TyCoVar flag -> VarBndr IfaceBndr flag+toIfaceForAllBndr = toIfaceForAllBndrX emptyVarSet +toIfaceForAllBndrX :: VarSet -> (VarBndr TyCoVar flag) -> (VarBndr IfaceBndr flag)+toIfaceForAllBndrX fr (Bndr v vis) = Bndr (toIfaceBndrX fr v) vis+ {- ************************************************************************ * *@@ -218,12 +220,6 @@ toIfaceCoVar :: CoVar -> FastString toIfaceCoVar = occNameFS . getOccName -toIfaceForAllBndr :: (VarBndr TyCoVar flag) -> (VarBndr IfaceBndr flag)-toIfaceForAllBndr = toIfaceForAllBndrX emptyVarSet--toIfaceForAllBndrX :: VarSet -> (VarBndr TyCoVar flag) -> (VarBndr IfaceBndr flag)-toIfaceForAllBndrX fr (Bndr v vis) = Bndr (toIfaceBndrX fr v) vis- ---------------- toIfaceTyCon :: TyCon -> IfaceTyCon toIfaceTyCon tc@@ -231,7 +227,7 @@ where tc_name = tyConName tc info = mkIfaceTyConInfo promoted sort- promoted | isPromotedDataCon tc = IsPromoted+ promoted | isDataKindsPromotedDataCon tc = IsPromoted | otherwise = NotPromoted tupleSort :: TyCon -> Maybe IfaceTyConSort@@ -291,7 +287,7 @@ go (AppCo co1 co2) = IfaceAppCo (go co1) (go co2) go (SymCo co) = IfaceSymCo (go co) go (TransCo co1 co2) = IfaceTransCo (go co1) (go co2)- go (NthCo _r d co) = IfaceNthCo d (go co)+ go (SelCo d co) = IfaceSelCo d (go co) go (LRCo lr co) = IfaceLRCo lr (go co) go (InstCo co arg) = IfaceInstCo (go co) (go arg) go (KindCo c) = IfaceKindCo (go c)@@ -301,13 +297,13 @@ go (UnivCo p r t1 t2) = IfaceUnivCo (go_prov p) r (toIfaceTypeX fr t1) (toIfaceTypeX fr t2)- go (TyConAppCo r tc cos)- | tc `hasKey` funTyConKey- , [_,_,_,_, _] <- cos = panic "toIfaceCoercion"- | otherwise =- IfaceTyConAppCo r (toIfaceTyCon tc) (map go cos)- go (FunCo r w co1 co2) = IfaceFunCo r (go w) (go co1) (go co2)+ go co@(TyConAppCo r tc cos)+ = assertPpr (isNothing (tyConAppFunCo_maybe r tc cos)) (ppr co) $+ IfaceTyConAppCo r (toIfaceTyCon tc) (map go cos) + go (FunCo { fco_role = r, fco_mult = w, fco_arg = co1, fco_res = co2 })+ = IfaceFunCo r (go w) (go co1) (go co2)+ go (ForAllCo tv k co) = IfaceForAllCo (toIfaceBndr tv) (toIfaceCoercionX fr' k) (toIfaceCoercionX fr' co)@@ -339,6 +335,9 @@ -- Is 'blib' visible? It depends on the visibility flag on j, -- so we have to substitute for k. Annoying! toIfaceAppArgsX fr kind ty_args+ | null ty_args+ = IA_Nil+ | otherwise = go (mkEmptySubst in_scope) kind ty_args where in_scope = mkInScopeSet (tyCoVarsOfTypes ty_args)@@ -356,11 +355,10 @@ go env (FunTy { ft_af = af, ft_res = res }) (t:ts) = IA_Arg (toIfaceTypeX fr t) argf (go env res ts) where- argf = case af of- VisArg -> Required- InvisArg -> Inferred- -- It's rare for a kind to have a constraint argument, but- -- it can happen. See Note [AnonTCB InvisArg] in GHC.Core.TyCon.+ argf | isVisibleFunArg af = Required+ | otherwise = Inferred+ -- It's rare for a kind to have a constraint argument, but it+ -- can happen. See Note [AnonTCB with constraint arg] in GHC.Core.TyCon. go env ty ts@(t1:ts1) | not (isEmptyTCvSubst env)@@ -411,8 +409,8 @@ (_univ_tvs, req_theta, _ex_tvs, prov_theta, args, rhs_ty) = patSynSig ps univ_bndrs = patSynUnivTyVarBinders ps ex_bndrs = patSynExTyVarBinders ps- (env1, univ_bndrs') = tidyTyCoVarBinders emptyTidyEnv univ_bndrs- (env2, ex_bndrs') = tidyTyCoVarBinders env1 ex_bndrs+ (env1, univ_bndrs') = tidyForAllTyBinders emptyTidyEnv univ_bndrs+ (env2, ex_bndrs') = tidyForAllTyBinders env1 ex_bndrs to_if_pr (name, _type, needs_dummy) = (name, needs_dummy) {-@@ -549,7 +547,7 @@ toIfaceExpr :: CoreExpr -> IfaceExpr toIfaceExpr (Var v) = toIfaceVar v-toIfaceExpr (Lit (LitRubbish r)) = IfaceLitRubbish (toIfaceType r)+toIfaceExpr (Lit (LitRubbish tc r)) = IfaceLitRubbish tc (toIfaceType r) toIfaceExpr (Lit l) = IfaceLit l toIfaceExpr (Type ty) = IfaceType (toIfaceType ty) toIfaceExpr (Coercion co) = IfaceCo (toIfaceCoercion co)@@ -647,8 +645,8 @@ toIfaceVar v | isBootUnfolding (idUnfolding v) = -- See Note [Inlining and hs-boot files]- IfaceApp (IfaceApp (IfaceExt noinlineIdName)- (IfaceType (toIfaceType (idType v))))+ IfaceApp (IfaceApp (IfaceExt noinline_id)+ (IfaceType (toIfaceType ty))) (IfaceExt name) -- don't use mkIfaceApps, or infinite loop | Just fcall <- isFCallId_maybe v = IfaceFCall fcall (toIfaceType (idType v))@@ -656,9 +654,14 @@ | isExternalName name = IfaceExt name | otherwise = IfaceLcl (getOccFS name)- where name = idName v+ where+ name = idName v+ ty = idType v+ noinline_id | isConstraintKind (typeKind ty) = noinlineConstraintIdName+ | otherwise = noinlineIdName + --------------------- toIfaceLFInfo :: Name -> LambdaFormInfo -> IfaceLFInfo toIfaceLFInfo nm lfi = case lfi of@@ -735,7 +738,8 @@ 1. When we serialize out unfoldings to IfaceExprs (toIfaceVar), for every variable reference we see if we are referring to an 'Id' that came from an hs-boot file. If so, we add a `noinline`- to the reference.+ to the reference. See Note [noinlineId magic]+ in GHC.Types.Id.Make 2. But how do we know if a reference came from an hs-boot file or not? We could record this directly in the 'IdInfo', but
compiler/GHC/CoreToIface.hs-boot view
@@ -11,7 +11,7 @@ -- For GHC.Core.TyCo.Rep toIfaceTypeX :: VarSet -> Type -> IfaceType toIfaceTyLit :: TyLit -> IfaceTyLit-toIfaceForAllBndr :: (VarBndr TyCoVar flag) -> (VarBndr IfaceBndr flag)+toIfaceForAllBndrs :: [VarBndr TyCoVar flag] -> [VarBndr IfaceBndr flag] toIfaceTyCon :: TyCon -> IfaceTyCon toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs toIfaceCoercionX :: VarSet -> Coercion -> IfaceCoercion
compiler/GHC/Data/Bool.hs view
@@ -4,7 +4,7 @@ ) where -import GHC.Prelude+import GHC.Prelude.Basic data OverridingBool = Auto
compiler/GHC/Data/FastMutInt.hs view
@@ -13,7 +13,7 @@ atomicFetchAddFastMut ) where -import GHC.Prelude+import GHC.Prelude.Basic import GHC.Base
compiler/GHC/Data/FastString.hs view
@@ -56,6 +56,7 @@ FastZString, hPutFZS, zString,+ zStringTakeN, lengthFZS, -- * FastStrings@@ -103,12 +104,13 @@ -- ** Deconstruction unpackPtrString,+ unpackPtrStringTakeN, -- ** Operations lengthPS ) where -import GHC.Prelude as Prelude+import GHC.Prelude.Basic as Prelude import GHC.Utils.Encoding import GHC.Utils.IO.Unsafe@@ -179,6 +181,14 @@ zString (FastZString bs) = inlinePerformIO $ BS.unsafeUseAsCStringLen bs peekCAStringLen +-- | @zStringTakeN n = 'take' n . 'zString'@+-- but is performed in \(O(\min(n,l))\) rather than \(O(l)\),+-- where \(l\) is the length of the 'FastZString'.+zStringTakeN :: Int -> FastZString -> String+zStringTakeN n (FastZString bs) =+ inlinePerformIO $ BS.unsafeUseAsCStringLen bs $ \(cp, len) ->+ peekCAStringLen (cp, min n len)+ lengthFZS :: FastZString -> Int lengthFZS (FastZString bs) = BS.length bs @@ -586,7 +596,7 @@ nullFS :: FastString -> Bool nullFS fs = SBS.null $ fs_sbs fs --- | Unpacks and decodes the FastString+-- | Lazily unpacks and decodes the FastString unpackFS :: FastString -> String unpackFS fs = utf8DecodeShortByteString $ fs_sbs fs @@ -665,6 +675,14 @@ -- This does not free the memory associated with 'PtrString'. unpackPtrString :: PtrString -> String unpackPtrString (PtrString (Ptr p#) (I# n#)) = unpackNBytes# p# n#++-- | @unpackPtrStringTakeN n = 'take' n . 'unpackPtrString'@+-- but is performed in \(O(\min(n,l))\) rather than \(O(l)\),+-- where \(l\) is the length of the 'PtrString'.+unpackPtrStringTakeN :: Int -> PtrString -> String+unpackPtrStringTakeN n (PtrString (Ptr p#) len) =+ case min n len of+ I# n# -> unpackNBytes# p# n# -- | Return the length of a 'PtrString' lengthPS :: PtrString -> Int
compiler/GHC/Data/Graph/Directed.hs view
@@ -7,6 +7,7 @@ module GHC.Data.Graph.Directed ( Graph, graphFromEdgedVerticesOrd, graphFromEdgedVerticesUniq,+ graphFromVerticesAndAdjacency, SCC(..), Node(..), flattenSCC, flattenSCCs, stronglyConnCompG,@@ -547,3 +548,21 @@ ends'' = addToUFM ends' n time'' in (time'' + 1, starts'', ends'')++graphFromVerticesAndAdjacency+ :: Ord key+ => [Node key payload]+ -> [(key, key)] -- First component is source vertex key,+ -- second is target vertex key (thing depended on)+ -- Unlike the other interface I insist they correspond to+ -- actual vertices because the alternative hides bugs. I can't+ -- do the same thing for the other one for backcompat reasons.+ -> Graph (Node key payload)+graphFromVerticesAndAdjacency [] _ = emptyGraph+graphFromVerticesAndAdjacency vertices edges = Graph graph vertex_node (key_vertex . key_extractor)+ where key_extractor = node_key+ (bounds, vertex_node, key_vertex, _) = reduceNodesIntoVerticesOrd vertices key_extractor+ key_vertex_pair (a, b) = (expectJust "graphFromVerticesAndAdjacency" $ key_vertex a,+ expectJust "graphFromVerticesAndAdjacency" $ key_vertex b)+ reduced_edges = map key_vertex_pair edges+ graph = buildG bounds reduced_edges
compiler/GHC/Data/Graph/UnVar.hs view
@@ -16,7 +16,7 @@ -} module GHC.Data.Graph.UnVar ( UnVarSet- , emptyUnVarSet, mkUnVarSet, varEnvDom, unionUnVarSet, unionUnVarSets+ , emptyUnVarSet, mkUnVarSet, unionUnVarSet, unionUnVarSets , extendUnVarSet, extendUnVarSetList, delUnVarSet, delUnVarSetList , elemUnVarSet, isEmptyUnVarSet , UnVarGraph@@ -26,13 +26,13 @@ , neighbors , hasLoopAt , delNode+ , domUFMUnVarSet ) where import GHC.Prelude -import GHC.Types.Id-import GHC.Types.Var.Env-import GHC.Types.Unique.FM+import GHC.Types.Unique.FM( UniqFM, ufmToSet_Directly )+import GHC.Types.Var import GHC.Utils.Outputable import GHC.Types.Unique @@ -50,6 +50,9 @@ k :: Var -> Int k v = getKey (getUnique v) +domUFMUnVarSet :: UniqFM key elt -> UnVarSet+domUFMUnVarSet ae = UnVarSet $ ufmToSet_Directly ae+ emptyUnVarSet :: UnVarSet emptyUnVarSet = UnVarSet S.empty @@ -74,9 +77,6 @@ mkUnVarSet :: [Var] -> UnVarSet mkUnVarSet vs = UnVarSet $ S.fromList $ map k vs--varEnvDom :: VarEnv a -> UnVarSet-varEnvDom ae = UnVarSet $ ufmToSet_Directly ae extendUnVarSet :: Var -> UnVarSet -> UnVarSet extendUnVarSet v (UnVarSet s) = UnVarSet $ S.insert (k v) s
+ compiler/GHC/Data/List/Infinite.hs view
@@ -0,0 +1,194 @@+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE RankNTypes #-}++module GHC.Data.List.Infinite+ ( Infinite (..)+ , head, tail+ , filter+ , (++)+ , unfoldr+ , (!!)+ , groupBy+ , dropList+ , iterate+ , concatMap+ , allListsOf+ , toList+ , repeat+ ) where++import Prelude ((-), Applicative (..), Bool (..), Foldable, Functor (..), Int, Maybe (..), Traversable (..), flip, otherwise)+import Control.Category (Category (..))+import Control.Monad (guard)+import qualified Data.Foldable as F+import Data.List.NonEmpty (NonEmpty (..))+import qualified GHC.Base as List (build)++data Infinite a = Inf a (Infinite a)+ deriving (Foldable, Functor, Traversable)++head :: Infinite a -> a+head (Inf a _) = a+{-# NOINLINE [1] head #-}++tail :: Infinite a -> Infinite a+tail (Inf _ as) = as+{-# NOINLINE [1] tail #-}++{-# RULES+"head/build" forall (g :: forall b . (a -> b -> b) -> b) . head (build g) = g \ x _ -> x+ #-}++instance Applicative Infinite where+ pure = repeat+ Inf f fs <*> Inf a as = Inf (f a) (fs <*> as)++mapMaybe :: (a -> Maybe b) -> Infinite a -> Infinite b+mapMaybe f = go+ where+ go (Inf a as) = let bs = go as in case f a of+ Nothing -> bs+ Just b -> Inf b bs+{-# NOINLINE [1] mapMaybe #-}++{-# RULES+"mapMaybe" [~1] forall f as . mapMaybe f as = build \ c -> foldr (mapMaybeFB c f) as+"mapMaybeList" [1] forall f . foldr (mapMaybeFB Inf f) = mapMaybe f+ #-}++{-# INLINE [0] mapMaybeFB #-}+mapMaybeFB :: (b -> r -> r) -> (a -> Maybe b) -> a -> r -> r+mapMaybeFB cons f a bs = case f a of+ Nothing -> bs+ Just r -> cons r bs++filter :: (a -> Bool) -> Infinite a -> Infinite a+filter f = mapMaybe (\ a -> a <$ guard (f a))+{-# INLINE filter #-}++infixr 5 +++(++) :: Foldable f => f a -> Infinite a -> Infinite a+(++) = flip (F.foldr Inf)++unfoldr :: (b -> (a, b)) -> b -> Infinite a+unfoldr f b = build \ c -> let go b = case f b of (a, b') -> a `c` go b' in go b+{-# INLINE unfoldr #-}++(!!) :: Infinite a -> Int -> a+Inf a _ !! 0 = a+Inf _ as !! n = as !! (n-1)++groupBy :: (a -> a -> Bool) -> Infinite a -> Infinite (NonEmpty a)+groupBy eq = go+ where+ go (Inf a as) = Inf (a:|bs) (go cs)+ where (bs, cs) = span (eq a) as++span :: (a -> Bool) -> Infinite a -> ([a], Infinite a)+span p = spanJust (\ a -> a <$ guard (p a))+{-# INLINE span #-}++spanJust :: (a -> Maybe b) -> Infinite a -> ([b], Infinite a)+spanJust p = go+ where+ go as@(Inf a as')+ | Just b <- p a = let (bs, cs) = go as' in (b:bs, cs)+ | otherwise = ([], as)++iterate :: (a -> a) -> a -> Infinite a+iterate f = go where go a = Inf a (go (f a))+{-# NOINLINE [1] iterate #-}++{-# RULES+"iterate" [~1] forall f a . iterate f a = build (\ c -> iterateFB c f a)+"iterateFB" [1] iterateFB Inf = iterate+ #-}++iterateFB :: (a -> b -> b) -> (a -> a) -> a -> b+iterateFB c f a = go a+ where go a = a `c` go (f a)+{-# INLINE [0] iterateFB #-}++concatMap :: Foldable f => (a -> f b) -> Infinite a -> Infinite b+concatMap f = go where go (Inf a as) = f a ++ go as+{-# NOINLINE [1] concatMap #-}++{-# RULES "concatMap" forall f as . concatMap f as = build \ c -> foldr (\ x b -> F.foldr c b (f x)) as #-}++{-# SPECIALIZE concatMap :: (a -> [b]) -> Infinite a -> Infinite b #-}++foldr :: (a -> b -> b) -> Infinite a -> b+foldr f = go where go (Inf a as) = f a (go as)+{-# INLINE [0] foldr #-}++build :: (forall b . (a -> b -> b) -> b) -> Infinite a+build g = g Inf+{-# INLINE [1] build #-}++-- Analogous to 'foldr'/'build' fusion for '[]'+{-# RULES+"foldr/build" forall f (g :: forall b . (a -> b -> b) -> b) . foldr f (build g) = g f+"foldr/id" foldr Inf = id++"foldr/cons/build" forall f a (g :: forall b . (a -> b -> b) -> b) . foldr f (Inf a (build g)) = f a (g f)+ #-}++{-# RULES+"map" [~1] forall f (as :: Infinite a) . fmap f as = build \ c -> foldr (mapFB c f) as+"mapFB" forall c f g . mapFB (mapFB c f) g = mapFB c (f . g)+"mapFB/id" forall c . mapFB c (\ x -> x) = c+ #-}++mapFB :: (b -> c -> c) -> (a -> b) -> a -> c -> c+mapFB c f = \ x ys -> c (f x) ys+{-# INLINE [0] mapFB #-}++dropList :: [a] -> Infinite b -> Infinite b+dropList [] bs = bs+dropList (_:as) (Inf _ bs) = dropList as bs++-- | Compute all lists of the given alphabet.+-- For example: @'allListsOf' "ab" = ["a", "b", "aa", "ba", "ab", "bb", "aaa", "baa", "aba", ...]@+allListsOf :: [a] -> Infinite [a]+allListsOf as = concatMap (\ bs -> [a:bs | a <- as]) ([] `Inf` allListsOf as)++-- See Note [Fusion for `Infinite` lists].+toList :: Infinite a -> [a]+toList = \ as -> List.build (\ c _ -> foldr c as)+{-# INLINE toList #-}++repeat :: a -> Infinite a+repeat a = as where as = Inf a as+{-# INLINE [0] repeat #-}++repeatFB :: (a -> b -> b) -> a -> b+repeatFB c x = xs where xs = c x xs+{-# INLINE [0] repeatFB #-}++{-# RULES+"repeat" [~1] forall a . repeat a = build \ c -> repeatFB c a+"repeatFB" [1] repeatFB Inf = repeat+ #-}++{-+Note [Fusion for `Infinite` lists]+~~~~~~~~~~~~~~~~~~~~+We use RULES to support foldr/build fusion for Infinite lists, analogously to the RULES in+GHC.Base to support fusion for regular lists. In particular, we define the following:+• `build :: (forall b . (a -> b -> b) -> b) -> Infinite a`+• `foldr :: (a -> b -> b) -> Infinite a -> b`+• A RULE `foldr f (build g) = g f`+• `Infinite`-producing functions in terms of `build`, and `Infinite`-consuming functions in+ terms of `foldr`++This can work across data types. For example, consider `toList :: Infinite a -> [a]`.+We want 'toList' to be both a good consumer (of 'Infinite' lists) and a good producer (of '[]').+Ergo, we define it in terms of 'Infinite.foldr' and `List.build`.++For a bigger example, consider `List.map f (toList (Infinite.map g as))`++We want to fuse away the intermediate `Infinite` structure between `Infnite.map` and `toList`,+and the list structure between `toList` and `List.map`. And indeed we do: see test+"InfiniteListFusion".+-}
compiler/GHC/Data/List/SetOps.hs view
@@ -33,7 +33,6 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Misc-import GHC.Utils.Trace import qualified Data.List as L import qualified Data.List.NonEmpty as NE
compiler/GHC/Driver/Backend.hs view
@@ -45,6 +45,7 @@ -- * Available back ends , ncgBackend , llvmBackend+ , jsBackend , viaCBackend , interpreterBackend , noBackend@@ -96,6 +97,7 @@ , backendAssemblerInfoGetter , backendCDefs , backendCodeOutput+ , backendUseJSLinker , backendPostHscPipeline , backendNormalSuccessorPhase , backendName@@ -193,12 +195,11 @@ --------------------------------------------------------------------------------- -- platformDefaultBackend :: Platform -> Backend platformDefaultBackend platform = if | platformUnregisterised platform -> viaCBackend | platformNcgSupported platform -> ncgBackend+ | platformJSSupported platform -> jsBackend | otherwise -> llvmBackend -- | Is the platform supported by the Native Code Generator?@@ -214,8 +215,14 @@ ArchPPC -> True ArchPPC_64 {} -> True ArchAArch64 -> True+ ArchWasm32 -> True _ -> False +-- | Is the platform supported by the JS backend?+platformJSSupported :: Platform -> Bool+platformJSSupported platform+ | platformArch platform == ArchJavaScript = True+ | otherwise = False -- | A value of type @Backend@ represents one of GHC's back ends.@@ -246,7 +253,7 @@ show = backendDescription -ncgBackend, llvmBackend, viaCBackend, interpreterBackend, noBackend+ncgBackend, llvmBackend, viaCBackend, interpreterBackend, jsBackend, noBackend :: Backend -- | The native code generator.@@ -273,6 +280,11 @@ -- See "GHC.CmmToLlvm" llvmBackend = Named LLVM +-- | The JavaScript Backend+--+-- See documentation in GHC.StgToJS+jsBackend = Named JavaScript+ -- | Via-C ("unregisterised") backend. -- -- Compiles Cmm code into C code, then relies on a C compiler@@ -328,8 +340,9 @@ -- it without mutual recursion across module boundaries.) data PrimitiveImplementation- = LlvmPrimitives -- ^ Primitives supported by LLVM- | NcgPrimitives -- ^ Primitives supported by the native code generator+ = LlvmPrimitives -- ^ Primitives supported by LLVM+ | NcgPrimitives -- ^ Primitives supported by the native code generator+ | JSPrimitives -- ^ Primitives supported by JS backend | GenericPrimitives -- ^ Primitives supported by all back ends deriving Show @@ -343,6 +356,8 @@ data DefunctionalizedAssemblerProg = StandardAssemblerProg -- ^ Use the standard system assembler+ | JSAssemblerProg+ -- ^ JS Backend compile to JS via Stg, and so does not use any assembler | DarwinClangAssemblerProg -- ^ If running on Darwin, use the assembler from the @clang@ -- toolchain. Otherwise use the standard system assembler.@@ -359,6 +374,8 @@ data DefunctionalizedAssemblerInfoGetter = StandardAssemblerInfoGetter -- ^ Interrogate the standard system assembler+ | JSAssemblerInfoGetter+ -- ^ If using the JS backend; return 'Emscripten' | DarwinClangAssemblerInfoGetter -- ^ If running on Darwin, return `Clang`; otherwise -- interrogate the standard system assembler.@@ -386,6 +403,7 @@ = NcgCodeOutput | ViaCCodeOutput | LlvmCodeOutput+ | JSCodeOutput -- | Names a function that tells the driver what should happen after@@ -406,6 +424,7 @@ = NcgPostHscPipeline | ViaCPostHscPipeline | LlvmPostHscPipeline+ | JSPostHscPipeline | NoPostHscPipeline -- ^ After code generation, nothing else need happen. -- | Names a function that tells the driver what command-line options@@ -431,42 +450,46 @@ -- issuing warning messages /only/. If code depends on -- what's in the string, you deserve what happens to you. backendDescription :: Backend -> String-backendDescription (Named NCG) = "native code generator"-backendDescription (Named LLVM) = "LLVM"-backendDescription (Named ViaC) = "compiling via C"+backendDescription (Named NCG) = "native code generator"+backendDescription (Named LLVM) = "LLVM"+backendDescription (Named ViaC) = "compiling via C"+backendDescription (Named JavaScript) = "compiling to JavaScript" backendDescription (Named Interpreter) = "byte-code interpreter"-backendDescription (Named NoBackend) = "no code generated"+backendDescription (Named NoBackend) = "no code generated" -- | This flag tells the compiler driver whether the back -- end will write files: interface files and object files. -- It is typically true for "real" back ends that generate -- code into the filesystem. (That means, not the interpreter.) backendWritesFiles :: Backend -> Bool-backendWritesFiles (Named NCG) = True-backendWritesFiles (Named LLVM) = True-backendWritesFiles (Named ViaC) = True+backendWritesFiles (Named NCG) = True+backendWritesFiles (Named LLVM) = True+backendWritesFiles (Named ViaC) = True+backendWritesFiles (Named JavaScript) = True backendWritesFiles (Named Interpreter) = False-backendWritesFiles (Named NoBackend) = False+backendWritesFiles (Named NoBackend) = False -- | When the back end does write files, this value tells -- the compiler in what manner of file the output should go: -- temporary, persistent, or specific. backendPipelineOutput :: Backend -> PipelineOutput-backendPipelineOutput (Named NCG) = Persistent+backendPipelineOutput (Named NCG) = Persistent backendPipelineOutput (Named LLVM) = Persistent backendPipelineOutput (Named ViaC) = Persistent+backendPipelineOutput (Named JavaScript) = Persistent backendPipelineOutput (Named Interpreter) = NoOutputFile-backendPipelineOutput (Named NoBackend) = NoOutputFile+backendPipelineOutput (Named NoBackend) = NoOutputFile -- | This flag tells the driver whether the back end can -- reuse code (bytecode or object code) that has been -- loaded dynamically. Likely true only of the interpreter. backendCanReuseLoadedCode :: Backend -> Bool-backendCanReuseLoadedCode (Named NCG) = False-backendCanReuseLoadedCode (Named LLVM) = False-backendCanReuseLoadedCode (Named ViaC) = False+backendCanReuseLoadedCode (Named NCG) = False+backendCanReuseLoadedCode (Named LLVM) = False+backendCanReuseLoadedCode (Named ViaC) = False+backendCanReuseLoadedCode (Named JavaScript) = False backendCanReuseLoadedCode (Named Interpreter) = True-backendCanReuseLoadedCode (Named NoBackend) = False+backendCanReuseLoadedCode (Named NoBackend) = False -- | It is is true of every back end except @-fno-code@ -- that it "generates code." Surprisingly, this property@@ -486,33 +509,36 @@ -- to date). -- backendGeneratesCode :: Backend -> Bool-backendGeneratesCode (Named NCG) = True-backendGeneratesCode (Named LLVM) = True-backendGeneratesCode (Named ViaC) = True+backendGeneratesCode (Named NCG) = True+backendGeneratesCode (Named LLVM) = True+backendGeneratesCode (Named ViaC) = True+backendGeneratesCode (Named JavaScript) = True backendGeneratesCode (Named Interpreter) = True-backendGeneratesCode (Named NoBackend) = False+backendGeneratesCode (Named NoBackend) = False -- | When set, this flag turns on interface writing for -- Backpack. It should probably be the same as -- `backendGeneratesCode`, but it is kept distinct for -- reasons described in Note [-fno-code mode]. backendSupportsInterfaceWriting :: Backend -> Bool-backendSupportsInterfaceWriting (Named NCG) = True-backendSupportsInterfaceWriting (Named LLVM) = True-backendSupportsInterfaceWriting (Named ViaC) = True+backendSupportsInterfaceWriting (Named NCG) = True+backendSupportsInterfaceWriting (Named LLVM) = True+backendSupportsInterfaceWriting (Named ViaC) = True+backendSupportsInterfaceWriting (Named JavaScript) = True backendSupportsInterfaceWriting (Named Interpreter) = True-backendSupportsInterfaceWriting (Named NoBackend) = False+backendSupportsInterfaceWriting (Named NoBackend) = False -- | When preparing code for this back end, the type -- checker should pay attention to SPECIALISE pragmas. If -- this flag is `False`, then the type checker ignores -- SPECIALISE pragmas (for imported things?). backendRespectsSpecialise :: Backend -> Bool-backendRespectsSpecialise (Named NCG) = True-backendRespectsSpecialise (Named LLVM) = True-backendRespectsSpecialise (Named ViaC) = True+backendRespectsSpecialise (Named NCG) = True+backendRespectsSpecialise (Named LLVM) = True+backendRespectsSpecialise (Named ViaC) = True+backendRespectsSpecialise (Named JavaScript) = True backendRespectsSpecialise (Named Interpreter) = False-backendRespectsSpecialise (Named NoBackend) = False+backendRespectsSpecialise (Named NoBackend) = False -- | This back end wants the `mi_globals` field of a -- `ModIface` to be populated (with the top-level bindings@@ -521,11 +547,12 @@ -- (After typechecking a module, Haddock wants access to -- the module's `GlobalRdrEnv`.) backendWantsGlobalBindings :: Backend -> Bool-backendWantsGlobalBindings (Named NCG) = False-backendWantsGlobalBindings (Named LLVM) = False-backendWantsGlobalBindings (Named ViaC) = False+backendWantsGlobalBindings (Named NCG) = False+backendWantsGlobalBindings (Named LLVM) = False+backendWantsGlobalBindings (Named ViaC) = False+backendWantsGlobalBindings (Named JavaScript) = False backendWantsGlobalBindings (Named Interpreter) = True-backendWantsGlobalBindings (Named NoBackend) = True+backendWantsGlobalBindings (Named NoBackend) = True -- | The back end targets a technology that implements -- `switch` natively. (For example, LLVM or C.) Therefore@@ -533,11 +560,12 @@ -- form into a decision tree with jump tables at the -- leaves. backendHasNativeSwitch :: Backend -> Bool-backendHasNativeSwitch (Named NCG) = False-backendHasNativeSwitch (Named LLVM) = True-backendHasNativeSwitch (Named ViaC) = True+backendHasNativeSwitch (Named NCG) = False+backendHasNativeSwitch (Named LLVM) = True+backendHasNativeSwitch (Named ViaC) = True+backendHasNativeSwitch (Named JavaScript) = True backendHasNativeSwitch (Named Interpreter) = False-backendHasNativeSwitch (Named NoBackend) = False+backendHasNativeSwitch (Named NoBackend) = False -- | As noted in the documentation for -- `PrimitiveImplementation`, certain primitives have@@ -546,32 +574,35 @@ -- "GHC.StgToCmm.Prim" what implementations to use with -- this back end. backendPrimitiveImplementation :: Backend -> PrimitiveImplementation-backendPrimitiveImplementation (Named NCG) = NcgPrimitives-backendPrimitiveImplementation (Named LLVM) = LlvmPrimitives-backendPrimitiveImplementation (Named ViaC) = GenericPrimitives+backendPrimitiveImplementation (Named NCG) = NcgPrimitives+backendPrimitiveImplementation (Named LLVM) = LlvmPrimitives+backendPrimitiveImplementation (Named JavaScript) = JSPrimitives+backendPrimitiveImplementation (Named ViaC) = GenericPrimitives backendPrimitiveImplementation (Named Interpreter) = GenericPrimitives-backendPrimitiveImplementation (Named NoBackend) = GenericPrimitives+backendPrimitiveImplementation (Named NoBackend) = GenericPrimitives -- | When this value is `IsValid`, the back end is -- compatible with vector instructions. When it is -- `NotValid`, it carries a message that is shown to -- users. backendSimdValidity :: Backend -> Validity' String-backendSimdValidity (Named NCG) = NotValid $ unlines ["SIMD vector instructions require the LLVM back-end.","Please use -fllvm."]-backendSimdValidity (Named LLVM) = IsValid-backendSimdValidity (Named ViaC) = NotValid $ unlines ["SIMD vector instructions require the LLVM back-end.","Please use -fllvm."]+backendSimdValidity (Named NCG) = NotValid $ unlines ["SIMD vector instructions require the LLVM back-end.","Please use -fllvm."]+backendSimdValidity (Named LLVM) = IsValid+backendSimdValidity (Named ViaC) = NotValid $ unlines ["SIMD vector instructions require the LLVM back-end.","Please use -fllvm."]+backendSimdValidity (Named JavaScript) = NotValid $ unlines ["SIMD vector instructions require the LLVM back-end.","Please use -fllvm."] backendSimdValidity (Named Interpreter) = NotValid $ unlines ["SIMD vector instructions require the LLVM back-end.","Please use -fllvm."]-backendSimdValidity (Named NoBackend) = NotValid $ unlines ["SIMD vector instructions require the LLVM back-end.","Please use -fllvm."]+backendSimdValidity (Named NoBackend) = NotValid $ unlines ["SIMD vector instructions require the LLVM back-end.","Please use -fllvm."] -- | This flag says whether the back end supports large -- binary blobs. See Note [Embedding large binary blobs] -- in "GHC.CmmToAsm.Ppr". backendSupportsEmbeddedBlobs :: Backend -> Bool-backendSupportsEmbeddedBlobs (Named NCG) = True-backendSupportsEmbeddedBlobs (Named LLVM) = False-backendSupportsEmbeddedBlobs (Named ViaC) = False+backendSupportsEmbeddedBlobs (Named NCG) = True+backendSupportsEmbeddedBlobs (Named LLVM) = False+backendSupportsEmbeddedBlobs (Named ViaC) = False+backendSupportsEmbeddedBlobs (Named JavaScript) = False backendSupportsEmbeddedBlobs (Named Interpreter) = False-backendSupportsEmbeddedBlobs (Named NoBackend) = False+backendSupportsEmbeddedBlobs (Named NoBackend) = False -- | This flag tells the compiler driver that the back end -- does not support every target platform; it supports@@ -581,22 +612,24 @@ -- platform support, the driver fails over to the LLVM -- back end. backendNeedsPlatformNcgSupport :: Backend -> Bool-backendNeedsPlatformNcgSupport (Named NCG) = True-backendNeedsPlatformNcgSupport (Named LLVM) = False-backendNeedsPlatformNcgSupport (Named ViaC) = False+backendNeedsPlatformNcgSupport (Named NCG) = True+backendNeedsPlatformNcgSupport (Named LLVM) = False+backendNeedsPlatformNcgSupport (Named ViaC) = False+backendNeedsPlatformNcgSupport (Named JavaScript) = False backendNeedsPlatformNcgSupport (Named Interpreter) = False-backendNeedsPlatformNcgSupport (Named NoBackend) = False+backendNeedsPlatformNcgSupport (Named NoBackend) = False -- | This flag is set if the back end can generate code -- for proc points. If the flag is not set, then a Cmm -- pass needs to split proc points (that is, turn each -- proc point into a standalone procedure). backendSupportsUnsplitProcPoints :: Backend -> Bool-backendSupportsUnsplitProcPoints (Named NCG) = True-backendSupportsUnsplitProcPoints (Named LLVM) = False-backendSupportsUnsplitProcPoints (Named ViaC) = False+backendSupportsUnsplitProcPoints (Named NCG) = True+backendSupportsUnsplitProcPoints (Named LLVM) = False+backendSupportsUnsplitProcPoints (Named ViaC) = False+backendSupportsUnsplitProcPoints (Named JavaScript) = False backendSupportsUnsplitProcPoints (Named Interpreter) = False-backendSupportsUnsplitProcPoints (Named NoBackend) = False+backendSupportsUnsplitProcPoints (Named NoBackend) = False -- | This flag guides the driver in resolving issues about -- API support on the target platform. If the flag is set,@@ -609,113 +642,124 @@ -- this back end can replace compilation via C. -- backendSwappableWithViaC :: Backend -> Bool-backendSwappableWithViaC (Named NCG) = True-backendSwappableWithViaC (Named LLVM) = True-backendSwappableWithViaC (Named ViaC) = False+backendSwappableWithViaC (Named NCG) = True+backendSwappableWithViaC (Named LLVM) = True+backendSwappableWithViaC (Named ViaC) = False+backendSwappableWithViaC (Named JavaScript) = False backendSwappableWithViaC (Named Interpreter) = False-backendSwappableWithViaC (Named NoBackend) = False+backendSwappableWithViaC (Named NoBackend) = False -- | This flag is true if the back end works *only* with -- the unregisterised ABI. backendUnregisterisedAbiOnly :: Backend -> Bool-backendUnregisterisedAbiOnly (Named NCG) = False-backendUnregisterisedAbiOnly (Named LLVM) = False-backendUnregisterisedAbiOnly (Named ViaC) = True+backendUnregisterisedAbiOnly (Named NCG) = False+backendUnregisterisedAbiOnly (Named LLVM) = False+backendUnregisterisedAbiOnly (Named ViaC) = True+backendUnregisterisedAbiOnly (Named JavaScript) = False backendUnregisterisedAbiOnly (Named Interpreter) = False-backendUnregisterisedAbiOnly (Named NoBackend) = False+backendUnregisterisedAbiOnly (Named NoBackend) = False -- | This flag is set if the back end generates C code in -- a @.hc@ file. The flag lets the compiler driver know -- if the command-line flag @-C@ is meaningful. backendGeneratesHc :: Backend -> Bool-backendGeneratesHc (Named NCG) = False-backendGeneratesHc (Named LLVM) = False-backendGeneratesHc (Named ViaC) = True+backendGeneratesHc (Named NCG) = False+backendGeneratesHc (Named LLVM) = False+backendGeneratesHc (Named ViaC) = True+backendGeneratesHc (Named JavaScript) = False backendGeneratesHc (Named Interpreter) = False-backendGeneratesHc (Named NoBackend) = False+backendGeneratesHc (Named NoBackend) = False -- | This flag says whether SPT (static pointer table) -- entries will be inserted dynamically if needed. If -- this flag is `False`, then "GHC.Iface.Tidy" should emit C -- stubs that initialize the SPT entries. backendSptIsDynamic :: Backend -> Bool-backendSptIsDynamic (Named NCG) = False-backendSptIsDynamic (Named LLVM) = False-backendSptIsDynamic (Named ViaC) = False+backendSptIsDynamic (Named NCG) = False+backendSptIsDynamic (Named LLVM) = False+backendSptIsDynamic (Named ViaC) = False+backendSptIsDynamic (Named JavaScript) = False backendSptIsDynamic (Named Interpreter) = True-backendSptIsDynamic (Named NoBackend) = False+backendSptIsDynamic (Named NoBackend) = False -- | If this flag is set, then "GHC.HsToCore.Ticks" -- inserts `Breakpoint` ticks. Used only for the -- interpreter. backendWantsBreakpointTicks :: Backend -> Bool-backendWantsBreakpointTicks (Named NCG) = False-backendWantsBreakpointTicks (Named LLVM) = False-backendWantsBreakpointTicks (Named ViaC) = False+backendWantsBreakpointTicks (Named NCG) = False+backendWantsBreakpointTicks (Named LLVM) = False+backendWantsBreakpointTicks (Named ViaC) = False+backendWantsBreakpointTicks (Named JavaScript) = False backendWantsBreakpointTicks (Named Interpreter) = True-backendWantsBreakpointTicks (Named NoBackend) = False+backendWantsBreakpointTicks (Named NoBackend) = False -- | If this flag is set, then the driver forces the -- optimization level to 0, issuing a warning message if -- the command line requested a higher optimization level. backendForcesOptimization0 :: Backend -> Bool-backendForcesOptimization0 (Named NCG) = False-backendForcesOptimization0 (Named LLVM) = False-backendForcesOptimization0 (Named ViaC) = False+backendForcesOptimization0 (Named NCG) = False+backendForcesOptimization0 (Named LLVM) = False+backendForcesOptimization0 (Named ViaC) = False+backendForcesOptimization0 (Named JavaScript) = False backendForcesOptimization0 (Named Interpreter) = True-backendForcesOptimization0 (Named NoBackend) = False+backendForcesOptimization0 (Named NoBackend) = False -- | I don't understand exactly how this works. But if -- this flag is set *and* another condition is met, then -- @ghc/Main.hs@ will alter the `DynFlags` so that all the -- `hostFullWays` are asked for. It is set only for the interpreter. backendNeedsFullWays :: Backend -> Bool-backendNeedsFullWays (Named NCG) = False-backendNeedsFullWays (Named LLVM) = False-backendNeedsFullWays (Named ViaC) = False+backendNeedsFullWays (Named NCG) = False+backendNeedsFullWays (Named LLVM) = False+backendNeedsFullWays (Named ViaC) = False+backendNeedsFullWays (Named JavaScript) = False backendNeedsFullWays (Named Interpreter) = True-backendNeedsFullWays (Named NoBackend) = False+backendNeedsFullWays (Named NoBackend) = False -- | This flag is also special for the interpreter: if a -- message about a module needs to be shown, do we know -- anything special about where the module came from? The -- Boolean argument is a `recomp` flag. backendSpecialModuleSource :: Backend -> Bool -> Maybe String-backendSpecialModuleSource (Named NCG) = const Nothing-backendSpecialModuleSource (Named LLVM) = const Nothing-backendSpecialModuleSource (Named ViaC) = const Nothing+backendSpecialModuleSource (Named NCG) = const Nothing+backendSpecialModuleSource (Named LLVM) = const Nothing+backendSpecialModuleSource (Named ViaC) = const Nothing+backendSpecialModuleSource (Named JavaScript) = const Nothing backendSpecialModuleSource (Named Interpreter) = \b -> if b then Just "interpreted" else Nothing-backendSpecialModuleSource (Named NoBackend) = const (Just "nothing")+backendSpecialModuleSource (Named NoBackend) = const (Just "nothing") -- | This flag says whether the back end supports Haskell -- Program Coverage (HPC). If not, the compiler driver -- will ignore the `-fhpc` option (and will issue a -- warning message if it is used). backendSupportsHpc :: Backend -> Bool-backendSupportsHpc (Named NCG) = True-backendSupportsHpc (Named LLVM) = True-backendSupportsHpc (Named ViaC) = True+backendSupportsHpc (Named NCG) = True+backendSupportsHpc (Named LLVM) = True+backendSupportsHpc (Named ViaC) = True+backendSupportsHpc (Named JavaScript) = False backendSupportsHpc (Named Interpreter) = False-backendSupportsHpc (Named NoBackend) = True+backendSupportsHpc (Named NoBackend) = True -- | This flag says whether the back end supports foreign -- import of C functions. ("Supports" means "does not -- barf on," so @-fno-code@ supports foreign C imports.) backendSupportsCImport :: Backend -> Bool-backendSupportsCImport (Named NCG) = True-backendSupportsCImport (Named LLVM) = True-backendSupportsCImport (Named ViaC) = True+backendSupportsCImport (Named NCG) = True+backendSupportsCImport (Named LLVM) = True+backendSupportsCImport (Named ViaC) = True+backendSupportsCImport (Named JavaScript) = True backendSupportsCImport (Named Interpreter) = True-backendSupportsCImport (Named NoBackend) = True+backendSupportsCImport (Named NoBackend) = True -- | This flag says whether the back end supports foreign -- export of Haskell functions to C. backendSupportsCExport :: Backend -> Bool-backendSupportsCExport (Named NCG) = True-backendSupportsCExport (Named LLVM) = True-backendSupportsCExport (Named ViaC) = True+backendSupportsCExport (Named NCG) = True+backendSupportsCExport (Named LLVM) = True+backendSupportsCExport (Named ViaC) = True+backendSupportsCExport (Named JavaScript) = True backendSupportsCExport (Named Interpreter) = False-backendSupportsCExport (Named NoBackend) = True+backendSupportsCExport (Named NoBackend) = True -- | This (defunctionalized) function runs the assembler -- used on the code that is written by this back end. A@@ -730,11 +774,12 @@ -- -- This field is usually defaulted. backendAssemblerProg :: Backend -> DefunctionalizedAssemblerProg-backendAssemblerProg (Named NCG) = StandardAssemblerProg+backendAssemblerProg (Named NCG) = StandardAssemblerProg backendAssemblerProg (Named LLVM) = DarwinClangAssemblerProg backendAssemblerProg (Named ViaC) = StandardAssemblerProg+backendAssemblerProg (Named JavaScript) = JSAssemblerProg backendAssemblerProg (Named Interpreter) = StandardAssemblerProg-backendAssemblerProg (Named NoBackend) = StandardAssemblerProg+backendAssemblerProg (Named NoBackend) = StandardAssemblerProg -- | This (defunctionalized) function is used to retrieve -- an enumeration value that characterizes the C/assembler@@ -748,11 +793,12 @@ -- -- This field is usually defaulted. backendAssemblerInfoGetter :: Backend -> DefunctionalizedAssemblerInfoGetter-backendAssemblerInfoGetter (Named NCG) = StandardAssemblerInfoGetter-backendAssemblerInfoGetter (Named LLVM) = DarwinClangAssemblerInfoGetter-backendAssemblerInfoGetter (Named ViaC) = StandardAssemblerInfoGetter+backendAssemblerInfoGetter (Named NCG) = StandardAssemblerInfoGetter+backendAssemblerInfoGetter (Named LLVM) = DarwinClangAssemblerInfoGetter+backendAssemblerInfoGetter (Named ViaC) = StandardAssemblerInfoGetter+backendAssemblerInfoGetter (Named JavaScript) = JSAssemblerInfoGetter backendAssemblerInfoGetter (Named Interpreter) = StandardAssemblerInfoGetter-backendAssemblerInfoGetter (Named NoBackend) = StandardAssemblerInfoGetter+backendAssemblerInfoGetter (Named NoBackend) = StandardAssemblerInfoGetter -- | When using this back end, it may be necessary or -- advisable to pass some `-D` options to a C compiler.@@ -768,11 +814,12 @@ -- -- This field is usually defaulted. backendCDefs :: Backend -> DefunctionalizedCDefs-backendCDefs (Named NCG) = NoCDefs-backendCDefs (Named LLVM) = LlvmCDefs-backendCDefs (Named ViaC) = NoCDefs+backendCDefs (Named NCG) = NoCDefs+backendCDefs (Named LLVM) = LlvmCDefs+backendCDefs (Named ViaC) = NoCDefs+backendCDefs (Named JavaScript) = NoCDefs backendCDefs (Named Interpreter) = NoCDefs-backendCDefs (Named NoBackend) = NoCDefs+backendCDefs (Named NoBackend) = NoCDefs -- | This (defunctionalized) function generates code and -- writes it to a file. The type of the function is@@ -786,12 +833,21 @@ -- > -> Stream IO RawCmmGroup a -- results from `StgToCmm` -- > -> IO a backendCodeOutput :: Backend -> DefunctionalizedCodeOutput-backendCodeOutput (Named NCG) = NcgCodeOutput-backendCodeOutput (Named LLVM) = LlvmCodeOutput-backendCodeOutput (Named ViaC) = ViaCCodeOutput+backendCodeOutput (Named NCG) = NcgCodeOutput+backendCodeOutput (Named LLVM) = LlvmCodeOutput+backendCodeOutput (Named ViaC) = ViaCCodeOutput+backendCodeOutput (Named JavaScript) = JSCodeOutput backendCodeOutput (Named Interpreter) = panic "backendCodeOutput: interpreterBackend"-backendCodeOutput (Named NoBackend) = panic "backendCodeOutput: noBackend"+backendCodeOutput (Named NoBackend) = panic "backendCodeOutput: noBackend" +backendUseJSLinker :: Backend -> Bool+backendUseJSLinker (Named NCG) = False+backendUseJSLinker (Named LLVM) = False+backendUseJSLinker (Named ViaC) = False+backendUseJSLinker (Named JavaScript) = True+backendUseJSLinker (Named Interpreter) = False+backendUseJSLinker (Named NoBackend) = False+ -- | This (defunctionalized) function tells the compiler -- driver what else has to be run after code output. -- The type of the function is@@ -804,9 +860,10 @@ -- > -> FilePath -- > -> m (Maybe FilePath) backendPostHscPipeline :: Backend -> DefunctionalizedPostHscPipeline-backendPostHscPipeline (Named NCG) = NcgPostHscPipeline+backendPostHscPipeline (Named NCG) = NcgPostHscPipeline backendPostHscPipeline (Named LLVM) = LlvmPostHscPipeline backendPostHscPipeline (Named ViaC) = ViaCPostHscPipeline+backendPostHscPipeline (Named JavaScript) = JSPostHscPipeline backendPostHscPipeline (Named Interpreter) = NoPostHscPipeline backendPostHscPipeline (Named NoBackend) = NoPostHscPipeline @@ -817,21 +874,23 @@ -- value gives instructions like "run the C compiler", -- "run the assembler," or "run the LLVM Optimizer." backendNormalSuccessorPhase :: Backend -> Phase-backendNormalSuccessorPhase (Named NCG) = As False+backendNormalSuccessorPhase (Named NCG) = As False backendNormalSuccessorPhase (Named LLVM) = LlvmOpt backendNormalSuccessorPhase (Named ViaC) = HCc+backendNormalSuccessorPhase (Named JavaScript) = StopLn backendNormalSuccessorPhase (Named Interpreter) = StopLn-backendNormalSuccessorPhase (Named NoBackend) = StopLn+backendNormalSuccessorPhase (Named NoBackend) = StopLn -- | Name of the back end, if any. Used to migrate legacy -- clients of the GHC API. Code within the GHC source -- tree should not refer to a back end's name. backendName :: Backend -> BackendName-backendName (Named NCG) = NCG+backendName (Named NCG) = NCG backendName (Named LLVM) = LLVM backendName (Named ViaC) = ViaC+backendName (Named JavaScript) = JavaScript backendName (Named Interpreter) = Interpreter-backendName (Named NoBackend) = NoBackend+backendName (Named NoBackend) = NoBackend @@ -842,6 +901,7 @@ allBackends = [ ncgBackend , llvmBackend , viaCBackend+ , jsBackend , interpreterBackend , noBackend ]@@ -910,7 +970,7 @@ applyCDefs :: DefunctionalizedCDefs -> Logger -> DynFlags -> IO [String] @ - Function `applyCDefs` is defined in module "GHC.Driver.Pipeline.Execute".+ Function `applyCDefs` is defined in module "GHC.SysTools.Cpp". I don't love this solution, but defunctionalization is a standard thing, and it makes the meanings of the enumeration values clear.
compiler/GHC/Driver/Backend/Internal.hs view
@@ -27,6 +27,7 @@ = NCG -- ^ Names the native code generator backend. | LLVM -- ^ Names the LLVM backend. | ViaC -- ^ Names the Via-C backend.+ | JavaScript -- ^ Names the JS backend. | Interpreter -- ^ Names the ByteCode interpreter. | NoBackend -- ^ Names the `-fno-code` backend. deriving (Eq, Show)
compiler/GHC/Driver/Config/Core/Lint.hs view
@@ -37,18 +37,18 @@ endPass :: CoreToDo -> CoreProgram -> [CoreRule] -> CoreM () endPass pass binds rules = do { hsc_env <- getHscEnv- ; print_unqual <- getPrintUnqualified+ ; name_ppr_ctx <- getNamePprCtx ; liftIO $ endPassHscEnvIO hsc_env- print_unqual pass binds rules+ name_ppr_ctx pass binds rules } -endPassHscEnvIO :: HscEnv -> PrintUnqualified+endPassHscEnvIO :: HscEnv -> NamePprCtx -> CoreToDo -> CoreProgram -> [CoreRule] -> IO ()-endPassHscEnvIO hsc_env print_unqual pass binds rules+endPassHscEnvIO hsc_env name_ppr_ctx pass binds rules = do { let dflags = hsc_dflags hsc_env ; endPassIO (hsc_logger hsc_env)- (initEndPassConfig dflags (interactiveInScope $ hsc_IC hsc_env) print_unqual pass)+ (initEndPassConfig dflags (interactiveInScope $ hsc_IC hsc_env) name_ppr_ctx pass) binds rules } @@ -62,13 +62,13 @@ , l_vars = vars } -initEndPassConfig :: DynFlags -> [Var] -> PrintUnqualified -> CoreToDo -> EndPassConfig-initEndPassConfig dflags extra_vars print_unqual pass = EndPassConfig+initEndPassConfig :: DynFlags -> [Var] -> NamePprCtx -> CoreToDo -> EndPassConfig+initEndPassConfig dflags extra_vars name_ppr_ctx pass = EndPassConfig { ep_dumpCoreSizes = not (gopt Opt_SuppressCoreSizes dflags) , ep_lintPassResult = if gopt Opt_DoCoreLinting dflags then Just $ initLintPassResultConfig dflags extra_vars pass else Nothing- , ep_printUnqual = print_unqual+ , ep_namePprCtx = name_ppr_ctx , ep_dumpFlag = coreDumpFlag pass , ep_prettyPass = ppr pass , ep_passDetails = pprPassDetails pass
compiler/GHC/Driver/Env.hs view
@@ -81,7 +81,6 @@ import GHC.Utils.Panic import GHC.Utils.Misc import GHC.Utils.Logger-import GHC.Utils.Trace import Data.IORef import qualified Data.Set as Set
compiler/GHC/Driver/Errors.hs view
@@ -19,15 +19,15 @@ printMessages :: forall a . Diagnostic a => Logger -> DiagnosticOpts a -> DiagOpts -> Messages a -> IO () printMessages logger msg_opts opts msgs- = sequence_ [ let style = mkErrStyle unqual+ = sequence_ [ let style = mkErrStyle name_ppr_ctx ctx = (diag_ppr_ctx opts) { sdocStyle = style } in logMsg logger (MCDiagnostic sev (diagnosticReason dia) (diagnosticCode dia)) s $ withPprStyle style (messageWithHints ctx dia)- | MsgEnvelope { errMsgSpan = s,+ | MsgEnvelope { errMsgSpan = s, errMsgDiagnostic = dia,- errMsgSeverity = sev,- errMsgContext = unqual } <- sortMsgBag (Just opts)- (getMessages msgs) ]+ errMsgSeverity = sev,+ errMsgContext = name_ppr_ctx }+ <- sortMsgBag (Just opts) (getMessages msgs) ] where messageWithHints :: Diagnostic a => SDocContext -> a -> SDoc messageWithHints ctx e =
compiler/GHC/Driver/Errors/Ppr.hs view
compiler/GHC/Driver/Flags.hs view
@@ -77,6 +77,7 @@ | Opt_D_dump_asm_stats | Opt_D_dump_c_backend | Opt_D_dump_llvm+ | Opt_D_dump_js | Opt_D_dump_core_stats | Opt_D_dump_deriv | Opt_D_dump_ds@@ -219,6 +220,7 @@ | Opt_PrintUnicodeSyntax | Opt_PrintExpandedSynonyms | Opt_PrintPotentialInstances+ | Opt_PrintRedundantPromotionTicks | Opt_PrintTypecheckerElaboration -- optimisation opts@@ -423,6 +425,7 @@ -- variables that have otherwise identical names. | Opt_SuppressUniques | Opt_SuppressStgExts+ | Opt_SuppressStgReps | Opt_SuppressTicks -- Replaces Opt_PprShowTicks | Opt_SuppressTimestamps -- ^ Suppress timestamps in dumps | Opt_SuppressCoreSizes -- ^ Suppress per binding Core size stats in dumps
compiler/GHC/Driver/Phases.hs view
@@ -99,6 +99,7 @@ | CmmCpp -- pre-process Cmm source | Cmm -- parse & compile Cmm code | MergeForeign -- merge in the foreign object files+ | Js -- pre-process Js source -- The final phase is a pseudo-phase that tells the pipeline to stop. | StopLn -- Stop, but linking will follow, so generate .o file@@ -134,6 +135,7 @@ eqPhase StopLn StopLn = True eqPhase Ccxx Ccxx = True eqPhase Cobjcxx Cobjcxx = True+eqPhase Js Js = True eqPhase _ _ = False -- MP: happensBefore is only used in preprocessPipeline, that usage should@@ -165,6 +167,7 @@ Cmm -> maybeHCc HCc -> MergeForeign MergeForeign -> StopLn+ Js -> StopLn StopLn -> panic "nextPhase: nothing after StopLn" where maybeHCc = if platformUnregisterised platform then HCc@@ -198,6 +201,7 @@ startPhase "o" = StopLn startPhase "cmm" = CmmCpp startPhase "cmmcpp" = Cmm+startPhase "js" = Js startPhase _ = StopLn -- all unknown file types -- This is used to determine the extension for the output from the@@ -226,10 +230,11 @@ phaseInputExt CmmCpp = "cmmcpp" phaseInputExt Cmm = "cmm" phaseInputExt MergeForeign = "o"+phaseInputExt Js = "js" phaseInputExt StopLn = "o" haskellish_src_suffixes, backpackish_suffixes, haskellish_suffixes, cish_suffixes,- haskellish_user_src_suffixes, haskellish_sig_suffixes+ js_suffixes, haskellish_user_src_suffixes, haskellish_sig_suffixes :: [String] -- When a file with an extension in the haskellish_src_suffixes group is -- loaded in --make mode, its imports will be loaded too.@@ -238,6 +243,7 @@ haskellish_suffixes = haskellish_src_suffixes ++ [ "hc", "cmm", "cmmcpp" ] cish_suffixes = [ "c", "cpp", "C", "cc", "cxx", "s", "S", "ll", "bc", "lm_s", "m", "M", "mm" ]+js_suffixes = [ "js" ] -- Will not be deleted as temp files: haskellish_user_src_suffixes =@@ -259,13 +265,14 @@ _ -> ["so"] isHaskellishSuffix, isBackpackishSuffix, isHaskellSrcSuffix, isCishSuffix,- isHaskellUserSrcSuffix, isHaskellSigSuffix+ isHaskellUserSrcSuffix, isJsSuffix, isHaskellSigSuffix :: String -> Bool isHaskellishSuffix s = s `elem` haskellish_suffixes isBackpackishSuffix s = s `elem` backpackish_suffixes isHaskellSigSuffix s = s `elem` haskellish_sig_suffixes isHaskellSrcSuffix s = s `elem` haskellish_src_suffixes isCishSuffix s = s `elem` cish_suffixes+isJsSuffix s = s `elem` js_suffixes isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes isObjectSuffix, isDynLibSuffix :: Platform -> String -> Bool@@ -275,6 +282,7 @@ isSourceSuffix :: String -> Bool isSourceSuffix suff = isHaskellishSuffix suff || isCishSuffix suff+ || isJsSuffix suff || isBackpackishSuffix suff -- | When we are given files (modified by -x arguments) we need@@ -291,7 +299,7 @@ isHaskellishTarget (f,Nothing) = looksLikeModuleName f || isHaskellSrcFilename f || not (hasExtension f) isHaskellishTarget (_,Just phase) =- phase `notElem` [ As True, As False, Cc, Cobjc, Cobjcxx, CmmCpp, Cmm+ phase `notElem` [ As True, As False, Cc, Cobjc, Cobjcxx, CmmCpp, Cmm, Js , StopLn] isHaskellishFilename, isHaskellSrcFilename, isCishFilename,@@ -319,4 +327,5 @@ HCc -> Just LangC As _ -> Just LangAsm MergeForeign -> Just RawObject+ Js -> Just LangJs _ -> Nothing
compiler/GHC/Driver/Pipeline/Phases.hs view
@@ -44,6 +44,7 @@ T_Cmm :: PipeEnv -> HscEnv -> FilePath -> TPhase ([FilePath], FilePath) T_Cc :: Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> TPhase FilePath T_As :: Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> TPhase FilePath+ T_Js :: PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> TPhase FilePath T_LlvmOpt :: PipeEnv -> HscEnv -> FilePath -> TPhase FilePath T_LlvmLlc :: PipeEnv -> HscEnv -> FilePath -> TPhase FilePath T_LlvmMangle :: PipeEnv -> HscEnv -> FilePath -> TPhase FilePath
compiler/GHC/Driver/Ppr.hs view
@@ -26,14 +26,14 @@ showPpr :: Outputable a => DynFlags -> a -> String showPpr dflags thing = showSDoc dflags (ppr thing) --- | Allows caller to specify the PrintUnqualified to use-showSDocForUser :: DynFlags -> UnitState -> PrintUnqualified -> SDoc -> String-showSDocForUser dflags unit_state unqual doc = renderWithContext (initSDocContext dflags sty) doc'+-- | Allows caller to specify the NamePprCtx to use+showSDocForUser :: DynFlags -> UnitState -> NamePprCtx -> SDoc -> String+showSDocForUser dflags unit_state name_ppr_ctx doc = renderWithContext (initSDocContext dflags sty) doc' where- sty = mkUserStyle unqual AllTheWay+ sty = mkUserStyle name_ppr_ctx AllTheWay doc' = pprWithUnitState unit_state doc -printForUser :: DynFlags -> Handle -> PrintUnqualified -> Depth -> SDoc -> IO ()-printForUser dflags handle unqual depth doc+printForUser :: DynFlags -> Handle -> NamePprCtx -> Depth -> SDoc -> IO ()+printForUser dflags handle name_ppr_ctx depth doc = printSDocLn ctx (PageMode False) handle doc- where ctx = initSDocContext dflags (mkUserStyle unqual depth)+ where ctx = initSDocContext dflags (mkUserStyle name_ppr_ctx depth)
compiler/GHC/Driver/Session.hs view
@@ -215,6 +215,7 @@ -- * SDoc initSDocContext, initDefaultSDocContext,+ initPromotionTickContext, ) where import GHC.Prelude@@ -2395,6 +2396,7 @@ setGeneralFlag Opt_SuppressIdInfo setGeneralFlag Opt_SuppressTicks setGeneralFlag Opt_SuppressStgExts+ setGeneralFlag Opt_SuppressStgReps setGeneralFlag Opt_SuppressTypeSignatures setGeneralFlag Opt_SuppressCoreSizes setGeneralFlag Opt_SuppressTimestamps)@@ -2443,6 +2445,8 @@ (setDumpFlag Opt_D_dump_core_stats) , make_ord_flag defGhcFlag "ddump-asm" (setDumpFlag Opt_D_dump_asm)+ , make_ord_flag defGhcFlag "ddump-js"+ (setDumpFlag Opt_D_dump_js) , make_ord_flag defGhcFlag "ddump-asm-native" (setDumpFlag Opt_D_dump_asm_native) , make_ord_flag defGhcFlag "ddump-asm-liveness"@@ -3347,6 +3351,7 @@ depFlagSpec' "suppress-stg-free-vars" Opt_SuppressStgExts (useInstead "-d" "suppress-stg-exts"), flagSpec "suppress-stg-exts" Opt_SuppressStgExts,+ flagSpec "suppress-stg-reps" Opt_SuppressStgReps, flagSpec "suppress-coercions" Opt_SuppressCoercions, flagSpec "suppress-coercion-types" Opt_SuppressCoercionTypes, flagSpec "suppress-idinfo" Opt_SuppressIdInfo,@@ -3457,6 +3462,7 @@ flagSpec "print-unicode-syntax" Opt_PrintUnicodeSyntax, flagSpec "print-expanded-synonyms" Opt_PrintExpandedSynonyms, flagSpec "print-potential-instances" Opt_PrintPotentialInstances,+ flagSpec "print-redundant-promotion-ticks" Opt_PrintRedundantPromotionTicks, flagSpec "print-typechecker-elaboration" Opt_PrintTypecheckerElaboration, flagSpec "prof-cafs" Opt_AutoSccsOnIndividualCafs, flagSpec "prof-count-entries" Opt_ProfCountEntries,@@ -3805,8 +3811,8 @@ Opt_RPath, Opt_DumpWithWays, Opt_CompactUnwind,- Opt_ShowErrorContext-+ Opt_ShowErrorContext,+ Opt_SuppressStgReps ] ++ [f | (ns,f) <- optLevelFlags, 0 `elem` ns]@@ -4942,6 +4948,7 @@ | Clang | AppleClang | AppleClang51+ | Emscripten | UnknownCC deriving Eq @@ -5031,6 +5038,7 @@ , sdocSuppressUniques = gopt Opt_SuppressUniques dflags , sdocSuppressModulePrefixes = gopt Opt_SuppressModulePrefixes dflags , sdocSuppressStgExts = gopt Opt_SuppressStgExts dflags+ , sdocSuppressStgReps = gopt Opt_SuppressStgReps dflags , sdocErrorSpans = gopt Opt_ErrorSpans dflags , sdocStarIsType = xopt LangExt.StarIsType dflags , sdocLinearTypes = xopt LangExt.LinearTypes dflags@@ -5042,6 +5050,13 @@ -- | Initialize the pretty-printing options using the default user style initDefaultSDocContext :: DynFlags -> SDocContext initDefaultSDocContext dflags = initSDocContext dflags defaultUserStyle++initPromotionTickContext :: DynFlags -> PromotionTickContext+initPromotionTickContext dflags =+ PromTickCtx {+ ptcListTuplePuns = True,+ ptcPrintRedundantPromTicks = gopt Opt_PrintRedundantPromotionTicks dflags+ } outputFile :: DynFlags -> Maybe String outputFile dflags
compiler/GHC/Hs/Decls.hs view
@@ -16,9 +16,6 @@ (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 -} --{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}- -- | Abstract syntax of global declarations. -- -- Definitions for: @SynDecl@ and @ConDecl@, @ClassDecl@,
compiler/GHC/Hs/Expr.hs view
@@ -14,7 +14,6 @@ {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] -- in module Language.Haskell.Syntax.Extension -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} {-# OPTIONS_GHC -Wno-orphans #-} -- Outputable {-@@ -2079,6 +2078,16 @@ ifPprDebug (sep [text "transformed branch of", pprAStmtContext c]) (pprStmtContext c) +pprStmtCat :: Stmt (GhcPass p) body -> SDoc+pprStmtCat (TransStmt {}) = text "transform"+pprStmtCat (LastStmt {}) = text "return expression"+pprStmtCat (BodyStmt {}) = text "body"+pprStmtCat (BindStmt {}) = text "binding"+pprStmtCat (LetStmt {}) = text "let"+pprStmtCat (RecStmt {}) = text "rec"+pprStmtCat (ParStmt {}) = text "parallel"+pprStmtCat (ApplicativeStmt {}) = text "applicative"+ pprAHsDoFlavour, pprHsDoFlavour :: HsDoFlavour -> SDoc pprAHsDoFlavour flavour = article <+> pprHsDoFlavour flavour where@@ -2152,13 +2161,11 @@ type instance Anno (Match (GhcPass p) (LocatedA (HsCmd (GhcPass p)))) = SrcSpanAnnA type instance Anno (GRHS (GhcPass p) (LocatedA (HsExpr (GhcPass p)))) = SrcAnn NoEpAnns type instance Anno (GRHS (GhcPass p) (LocatedA (HsCmd (GhcPass p)))) = SrcAnn NoEpAnns-type instance Anno (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (HsExpr (GhcPass pr)))) = SrcSpanAnnA-type instance Anno (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (HsCmd (GhcPass pr)))) = SrcSpanAnnA+type instance Anno (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (body (GhcPass pr)))) = SrcSpanAnnA type instance Anno (HsUntypedSplice (GhcPass p)) = SrcSpanAnnA -type instance Anno [LocatedA (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (HsExpr (GhcPass pr))))] = SrcSpanAnnL-type instance Anno [LocatedA (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (HsCmd (GhcPass pr))))] = SrcSpanAnnL+type instance Anno [LocatedA (StmtLR (GhcPass pl) (GhcPass pr) (LocatedA (body (GhcPass pr))))] = SrcSpanAnnL type instance Anno (FieldLabelStrings (GhcPass p)) = SrcAnn NoEpAnns type instance Anno FieldLabelString = SrcSpanAnnN
compiler/GHC/Hs/Instances.hs view
@@ -388,11 +388,7 @@ deriving instance Data (HsUntypedSplice GhcRn) deriving instance Data (HsUntypedSplice GhcTc) -deriving instance Data (HsUntypedSpliceResult (HsExpr GhcRn))--deriving instance Data (HsUntypedSpliceResult (Pat GhcRn))--deriving instance Data (HsUntypedSpliceResult (HsType GhcRn))+deriving instance Data a => Data (HsUntypedSpliceResult a) -- deriving instance (DataIdLR p p) => Data (HsQuote p) deriving instance Data (HsQuote GhcPs)
compiler/GHC/Hs/Type.hs view
@@ -104,12 +104,12 @@ import GHC.Types.SourceText import GHC.Types.Name( Name, NamedThing(getName), tcName ) import GHC.Types.Name.Reader ( RdrName )-import GHC.Types.Var ( VarBndr )+import GHC.Types.Var ( VarBndr, visArgTypeLike ) import GHC.Core.TyCo.Rep ( Type(..) ) import GHC.Builtin.Types( manyDataConName, oneDataConName, mkTupleStr ) import GHC.Core.Ppr ( pprOccWithTick) import GHC.Core.Type-import GHC.Iface.Type+import GHC.Core.Multiplicity( pprArrowWithMultiplicity ) import GHC.Hs.Doc import GHC.Types.Basic import GHC.Types.SrcLoc@@ -315,7 +315,7 @@ type instance XAppKindTy (GhcPass _) = SrcSpan -- Where the `@` lives type instance XSpliceTy GhcPs = NoExtField-type instance XSpliceTy GhcRn = HsUntypedSpliceResult (HsType GhcRn)+type instance XSpliceTy GhcRn = HsUntypedSpliceResult (LHsType GhcRn) type instance XSpliceTy GhcTc = Kind type instance XDocTy (GhcPass _) = EpAnn [AddEpAnn]@@ -384,9 +384,9 @@ -- See #18846 pprHsArrow :: (OutputableBndrId pass) => HsArrow (GhcPass pass) -> SDoc-pprHsArrow (HsUnrestrictedArrow _) = arrow-pprHsArrow (HsLinearArrow _) = lollipop-pprHsArrow (HsExplicitMult _ p _) = mulArrow (const ppr) p+pprHsArrow (HsUnrestrictedArrow _) = pprArrowWithMultiplicity visArgTypeLike (Left False)+pprHsArrow (HsLinearArrow _) = pprArrowWithMultiplicity visArgTypeLike (Left True)+pprHsArrow (HsExplicitMult _ p _) = pprArrowWithMultiplicity visArgTypeLike (Right (ppr p)) type instance XConDeclField (GhcPass _) = EpAnn [AddEpAnn] type instance XXConDeclField (GhcPass _) = DataConCantHappen
compiler/GHC/Hs/Utils.hs view
@@ -55,10 +55,6 @@ mkLHsTupleExpr, mkLHsVarTuple, missingTupArg, mkLocatedList, - -- * Constructing general big tuples- -- $big_tuples- mkChunkified, chunkify,- -- * Bindings mkFunBind, mkVarBind, mkHsVarBind, mkSimpleGeneratedFunBind, mkTopFunBind, mkPatSynBind,@@ -122,12 +118,16 @@ import GHC.Parser.Annotation import GHC.Tc.Types.Evidence-import GHC.Core.TyCo.Rep-import GHC.Core.Multiplicity ( pattern Many )-import GHC.Builtin.Types ( unitTy )-import GHC.Tc.Utils.TcType++import GHC.Core.Coercion( isReflCo )+import GHC.Core.Multiplicity ( pattern ManyTy ) import GHC.Core.DataCon import GHC.Core.ConLike+import GHC.Core.Make ( mkChunkified )+import GHC.Core.Type ( Type, isUnliftedType )++import GHC.Builtin.Types ( unitTy )+ import GHC.Types.Id import GHC.Types.Name import GHC.Types.Name.Set hiding ( unitFV )@@ -138,9 +138,9 @@ import GHC.Types.SrcLoc import GHC.Types.Fixity import GHC.Types.SourceText+ import GHC.Data.FastString import GHC.Data.Bag-import GHC.Settings.Constants import GHC.Utils.Misc import GHC.Utils.Outputable@@ -268,7 +268,7 @@ mkHsLams :: [TyVar] -> [EvVar] -> LHsExpr GhcTc -> LHsExpr GhcTc mkHsLams tyvars dicts expr = mkLHsWrap (mkWpTyLams tyvars- <.> mkWpLams dicts) expr+ <.> mkWpEvLams dicts) expr -- |A simple case alternative with a single pattern, no binds, no guards; -- pre-typechecking@@ -414,7 +414,7 @@ xbstc_boundResultType = unitTy, -- unitTy is a dummy value -- can't panic here: it's forced during zonking- xbstc_boundResultMult = Many,+ xbstc_boundResultMult = ManyTy, xbstc_failOp = Nothing }) pat body emptyRecStmt' :: forall idL idR body .@@ -681,47 +681,6 @@ mkBigLHsPatTup :: [LPat GhcRn] -> LPat GhcRn mkBigLHsPatTup = mkChunkified mkLHsPatTup --- $big_tuples--- #big_tuples#------ GHCs built in tuples can only go up to 'mAX_TUPLE_SIZE' in arity, but--- we might conceivably want to build such a massive tuple as part of the--- output of a desugaring stage (notably that for list comprehensions).------ We call tuples above this size \"big tuples\", and emulate them by--- creating and pattern matching on >nested< tuples that are expressible--- by GHC.------ Nesting policy: it's better to have a 2-tuple of 10-tuples (3 objects)--- than a 10-tuple of 2-tuples (11 objects), so we want the leaves of any--- construction to be big.------ If you just use the 'mkBigCoreTup', 'mkBigCoreVarTupTy', 'mkTupleSelector'--- and 'mkTupleCase' functions to do all your work with tuples you should be--- fine, and not have to worry about the arity limitation at all.---- | Lifts a \"small\" constructor into a \"big\" constructor by recursive decomposition-mkChunkified :: ([a] -> a) -- ^ \"Small\" constructor function, of maximum input arity 'mAX_TUPLE_SIZE'- -> [a] -- ^ Possible \"big\" list of things to construct from- -> a -- ^ Constructed thing made possible by recursive decomposition-mkChunkified small_tuple as = mk_big_tuple (chunkify as)- where- -- Each sub-list is short enough to fit in a tuple- mk_big_tuple [as] = small_tuple as- mk_big_tuple as_s = mk_big_tuple (chunkify (map small_tuple as_s))--chunkify :: [a] -> [[a]]--- ^ Split a list into lists that are small enough to have a corresponding--- tuple arity. The sub-lists of the result all have length <= 'mAX_TUPLE_SIZE'--- But there may be more than 'mAX_TUPLE_SIZE' sub-lists-chunkify xs- | n_xs <= mAX_TUPLE_SIZE = [xs]- | otherwise = split xs- where- n_xs = length xs- split [] = []- split xs = take mAX_TUPLE_SIZE xs : split (drop mAX_TUPLE_SIZE xs)- {- ************************************************************************ * *@@ -815,7 +774,7 @@ | otherwise = XPat $ CoPat co_fn p ty mkHsWrapPatCo :: TcCoercionN -> Pat GhcTc -> Type -> Pat GhcTc-mkHsWrapPatCo co pat ty | isTcReflCo co = pat+mkHsWrapPatCo co pat ty | isReflCo co = pat | otherwise = XPat $ CoPat (mkWpCastN co) pat ty mkHsDictLet :: TcEvBinds -> LHsExpr GhcTc -> LHsExpr GhcTc
compiler/GHC/HsToCore/Errors/Ppr.hs view
@@ -86,7 +86,7 @@ hang (text "Top-level" <+> text desc <+> text "aren't allowed:") 2 (ppr bind) DsUselessSpecialiseForClassMethodSelector poly_id -> mkSimpleDecorated $- text "Ignoring useless SPECIALISE pragma for NOINLINE function:" <+> quotes (ppr poly_id)+ text "Ignoring useless SPECIALISE pragma for class selector:" <+> quotes (ppr poly_id) DsUselessSpecialiseForNoInlineFunction poly_id -> mkSimpleDecorated $ text "Ignoring useless SPECIALISE pragma for NOINLINE function:" <+> quotes (ppr poly_id)
compiler/GHC/HsToCore/Pmc/Ppr.hs view
@@ -1,6 +1,5 @@ -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- | Provides facilities for pretty-printing 'Nabla's in a way appropriate for -- user facing pattern match warnings.@@ -10,6 +9,8 @@ import GHC.Prelude +import GHC.Data.List.Infinite (Infinite (..))+import qualified GHC.Data.List.Infinite as Inf import GHC.Types.Basic import GHC.Types.Id import GHC.Types.Var.Env@@ -101,12 +102,11 @@ attach_refuts (u, (x, sdoc)) = (u, (sdoc, lookupRefuts nabla x)) -type PmPprM a = RWS Nabla () (DIdEnv (Id, SDoc), [SDoc]) a+type PmPprM a = RWS Nabla () (DIdEnv (Id, SDoc), Infinite SDoc) a -- Try nice names p,q,r,s,t before using the (ugly) t_i-nameList :: [SDoc]-nameList = map text ["p","q","r","s","t"] ++- [ text ('t':show u) | u <- [(0 :: Int)..] ]+nameList :: Infinite SDoc+nameList = map text ["p","q","r","s","t"] Inf.++ flip Inf.unfoldr (0 :: Int) (\ u -> (text ('t':show u), u+1)) runPmPpr :: Nabla -> PmPprM a -> (a, DIdEnv (Id, SDoc)) runPmPpr nabla m = case runRWS m nabla (emptyDVarEnv, nameList) of@@ -117,7 +117,7 @@ getCleanName :: Id -> PmPprM SDoc getCleanName x = do (renamings, name_supply) <- get- let (clean_name:name_supply') = name_supply+ let Inf clean_name name_supply' = name_supply case lookupDVarEnv renamings x of Just (_, nm) -> pure nm Nothing -> do
compiler/GHC/HsToCore/Pmc/Solver/Types.hs view
@@ -57,6 +57,7 @@ import GHC.Core.TyCon import GHC.Types.Literal import GHC.Core+import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.Map.Expr import GHC.Core.Utils (exprType) import GHC.Builtin.Names
compiler/GHC/Iface/Syntax.hs view
@@ -44,7 +44,8 @@ import GHC.Prelude -import GHC.Builtin.Names ( unrestrictedFunTyConKey, liftedTypeKindTyConKey )+import GHC.Builtin.Names ( unrestrictedFunTyConKey, liftedTypeKindTyConKey,+ constraintKindTyConKey ) import GHC.Types.Unique ( hasKey ) import GHC.Iface.Type import GHC.Iface.Recomp.Binary@@ -64,8 +65,8 @@ import GHC.Unit.Module import GHC.Types.SrcLoc import GHC.Data.BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue )-import GHC.Types.Var( VarBndr(..), binderVar, tyVarSpecToBinders )-import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag )+import GHC.Types.Var( VarBndr(..), binderVar, tyVarSpecToBinders, visArgTypeLike )+import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisForAllTyFlag ) import GHC.Core.DataCon (SrcStrictness(..), SrcUnpackedness(..)) import GHC.Builtin.Types ( constraintKindTyConName ) import GHC.Stg.InferTags.TagSig@@ -236,7 +237,9 @@ data IfaceConDecls = IfAbstractTyCon -- c.f TyCon.AbstractTyCon- | IfDataTyCon [IfaceConDecl] -- Data type decls+ | IfDataTyCon !Bool [IfaceConDecl] -- Data type decls+ -- The Bool is True for "type data" declarations.+ -- see Note [Type data declarations] in GHC.Rename.Module | IfNewTyCon IfaceConDecl -- Newtype decls -- For IfDataTyCon and IfNewTyCon we store:@@ -450,7 +453,7 @@ visibleIfConDecls :: IfaceConDecls -> [IfaceConDecl] visibleIfConDecls (IfAbstractTyCon {}) = []-visibleIfConDecls (IfDataTyCon cs) = cs+visibleIfConDecls (IfDataTyCon _ cs) = cs visibleIfConDecls (IfNewTyCon c) = [c] ifaceDeclImplicitBndrs :: IfaceDecl -> [OccName]@@ -459,18 +462,23 @@ -- especially the question of whether there's a wrapper for a datacon -- See Note [Implicit TyThings] in GHC.Driver.Env --- N.B. the set of names returned here *must* match the set of--- TyThings returned by GHC.Driver.Env.implicitTyThings, in the sense that+-- N.B. the set of names returned here *must* match the set of TyThings+-- returned by GHC.Types.TyThing.implicitTyThings, in the sense that -- TyThing.getOccName should define a bijection between the two lists.--- This invariant is used in GHC.IfaceToCore.tc_iface_decl_fingerprint (see note--- [Tricky iface loop])+-- This invariant is used in GHC.IfaceToCore.tc_iface_decl_fingerprint+-- (see Note [Tricky iface loop] in GHC.Types.TyThing.) -- The order of the list does not matter. ifaceDeclImplicitBndrs (IfaceData {ifName = tc_name, ifCons = cons }) = case cons of IfAbstractTyCon {} -> [] IfNewTyCon cd -> mkNewTyCoOcc (occName tc_name) : ifaceConDeclImplicitBndrs cd- IfDataTyCon cds -> concatMap ifaceConDeclImplicitBndrs cds+ IfDataTyCon type_data cds+ | type_data ->+ -- Constructors in "type data" declarations have no implicits.+ -- see Note [Type data declarations] in GHC.Rename.Module+ [occName con_name | IfCon { ifConName = con_name } <- cds]+ | otherwise -> concatMap ifaceConDeclImplicitBndrs cds ifaceDeclImplicitBndrs (IfaceClass { ifBody = IfAbstractClass }) = []@@ -553,8 +561,8 @@ | IfaceLet (IfaceBinding IfaceLetBndr) IfaceExpr | IfaceCast IfaceExpr IfaceCoercion | IfaceLit Literal- | IfaceLitRubbish IfaceType -- See GHC.Types.Literal- -- Note [Rubbish literals] item (6)+ | IfaceLitRubbish TypeOrConstraint IfaceType+ -- See GHC.Types.Literal Note [Rubbish literals] item (6) | IfaceFCall ForeignCall IfaceType | IfaceTick IfaceTickish IfaceExpr -- from Tick tickish E @@ -858,7 +866,7 @@ pp_where = ppWhen (gadt && not (null cons)) $ text "where" pp_cons = ppr_trim (map show_con cons) :: [SDoc] pp_kind = ppUnless (if ki_sig_printable- then isIfaceTauType kind+ then isIfaceRhoType kind -- Even in the presence of a standalone kind signature, a non-tau -- result kind annotation cannot be discarded as it determines the arity. -- See Note [Arity inference in kcCheckDeclHeader_sig] in GHC.Tc.Gen.HsType@@ -907,6 +915,7 @@ pp_nd = case condecls of IfAbstractTyCon{} -> text "data"+ IfDataTyCon True _ -> text "type data" IfDataTyCon{} -> text "data" IfNewTyCon{} -> text "newtype" @@ -980,7 +989,8 @@ -- See Note [Printing type abbreviations] in GHC.Iface.Type ppr_tau | tc `hasKey` liftedTypeKindTyConKey ||- tc `hasKey` unrestrictedFunTyConKey+ tc `hasKey` unrestrictedFunTyConKey ||+ tc `hasKey` constraintKindTyConKey = updSDocContext (\ctx -> ctx { sdocPrintTypeAbbreviations = False }) $ ppr tau | otherwise = ppr tau @@ -1065,7 +1075,8 @@ , ppWhen insert_empty_ctxt $ parens empty <+> darrow , ex_msg , pprIfaceContextArr prov_ctxt- , pprIfaceType $ foldr (IfaceFunTy VisArg many_ty) pat_ty arg_tys ])+ , pprIfaceType $ foldr (IfaceFunTy visArgTypeLike many_ty)+ pat_ty arg_tys ]) pat_body = braces $ sep $ punctuate comma $ map ppr pat_fldlbls univ_msg = pprUserIfaceForAll $ tyVarSpecToBinders univ_bndrs ex_msg = pprUserIfaceForAll $ tyVarSpecToBinders ex_bndrs@@ -1204,16 +1215,18 @@ -- because we don't have a Name for the tycon, only an OccName pp_tau | null fields = case pp_args ++ [pp_gadt_res_ty] of- (t:ts) -> fsep (t : zipWithEqual "pprIfaceConDecl" (\(w,_) d -> ppr_arr w <+> d) arg_tys ts)+ (t:ts) -> fsep (t : zipWithEqual "pprIfaceConDecl" (\(w,_) d -> ppr_arr w <+> d)+ arg_tys ts) [] -> panic "pp_con_taus" | otherwise = sep [pp_field_args, arrow <+> pp_gadt_res_ty] -- Constructors are linear by default, but we don't want to show -- linear arrows when -XLinearTypes is disabled- ppr_arr w = sdocOption sdocLinearTypes (\linearTypes -> if linearTypes- then ppr_fun_arrow w- else arrow)+ ppr_arr w = sdocOption sdocLinearTypes $ \linearTypes ->+ if linearTypes+ then pprTypeArrow visArgTypeLike w+ else arrow ppr_bang IfNoBang = whenPprDebug $ char '_' ppr_bang IfStrict = char '!'@@ -1303,7 +1316,7 @@ -- 3. Pretty-print the data type constructor applied to its arguments. -- This process will omit any invisible arguments, such as coercion -- variables, if necessary. (See Note- -- [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep.)+ -- [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep.) ppr_tc_app gadt_subst = pprPrefixIfDeclBndr how_much (occName tycon) <+> pprParendIfaceAppArgs@@ -1312,7 +1325,7 @@ mk_tc_app_args :: [IfaceTyConBinder] -> IfaceAppArgs mk_tc_app_args [] = IA_Nil mk_tc_app_args (Bndr bndr vis:tc_bndrs) =- IA_Arg (IfaceTyVar (ifaceBndrName bndr)) (tyConBndrVisArgFlag vis)+ IA_Arg (IfaceTyVar (ifaceBndrName bndr)) (tyConBndrVisForAllTyFlag vis) (mk_tc_app_args tc_bndrs) instance Outputable IfaceRule where@@ -1389,16 +1402,20 @@ -- an atomic value (e.g. function args) pprIfaceExpr :: (SDoc -> SDoc) -> IfaceExpr -> SDoc -pprIfaceExpr _ (IfaceLcl v) = ppr v-pprIfaceExpr _ (IfaceExt v) = ppr v-pprIfaceExpr _ (IfaceLit l) = ppr l-pprIfaceExpr _ (IfaceLitRubbish r) = text "RUBBISH" <> parens (ppr r)-pprIfaceExpr _ (IfaceFCall cc ty) = braces (ppr cc <+> ppr ty)-pprIfaceExpr _ (IfaceType ty) = char '@' <> pprParendIfaceType ty-pprIfaceExpr _ (IfaceCo co) = text "@~" <> pprParendIfaceCoercion co+pprIfaceExpr _ (IfaceLcl v) = ppr v+pprIfaceExpr _ (IfaceExt v) = ppr v+pprIfaceExpr _ (IfaceLit l) = ppr l+pprIfaceExpr _ (IfaceFCall cc ty) = braces (ppr cc <+> ppr ty)+pprIfaceExpr _ (IfaceType ty) = char '@' <> pprParendIfaceType ty+pprIfaceExpr _ (IfaceCo co) = text "@~" <> pprParendIfaceCoercion co+pprIfaceExpr _ (IfaceTuple c as) = tupleParens c (pprWithCommas ppr as) +pprIfaceExpr _ (IfaceLitRubbish tc r)+ = text "RUBBISH"+ <> (case tc of { TypeLike -> empty; ConstraintLike -> text "[c]" })+ <> parens (ppr r)+ pprIfaceExpr add_par app@(IfaceApp _ _) = add_par (pprIfaceApp app [])-pprIfaceExpr _ (IfaceTuple c as) = tupleParens c (pprWithCommas ppr as) pprIfaceExpr add_par i@(IfaceLam _ _) = add_par (sep [char '\\' <+> sep (map pprIfaceLamBndr bndrs) <+> arrow,@@ -1633,8 +1650,8 @@ freeNamesDM _ = emptyNameSet freeNamesIfConDecls :: IfaceConDecls -> NameSet-freeNamesIfConDecls (IfDataTyCon c) = fnList freeNamesIfConDecl c-freeNamesIfConDecls (IfNewTyCon c) = freeNamesIfConDecl c+freeNamesIfConDecls (IfDataTyCon _ cs) = fnList freeNamesIfConDecl cs+freeNamesIfConDecls (IfNewTyCon c) = freeNamesIfConDecl c freeNamesIfConDecls _ = emptyNameSet freeNamesIfConDecl :: IfaceConDecl -> NameSet@@ -1701,7 +1718,7 @@ = freeNamesIfCoercion c freeNamesIfCoercion (IfaceTransCo c1 c2) = freeNamesIfCoercion c1 &&& freeNamesIfCoercion c2-freeNamesIfCoercion (IfaceNthCo _ co)+freeNamesIfCoercion (IfaceSelCo _ co) = freeNamesIfCoercion co freeNamesIfCoercion (IfaceLRCo _ co) = freeNamesIfCoercion co@@ -2118,14 +2135,16 @@ instance Binary IfaceConDecls where put_ bh IfAbstractTyCon = putByte bh 0- put_ bh (IfDataTyCon cs) = putByte bh 1 >> put_ bh cs- put_ bh (IfNewTyCon c) = putByte bh 2 >> put_ bh c+ put_ bh (IfDataTyCon False cs) = putByte bh 1 >> put_ bh cs+ put_ bh (IfDataTyCon True cs) = putByte bh 2 >> put_ bh cs+ put_ bh (IfNewTyCon c) = putByte bh 3 >> put_ bh c get bh = do h <- getByte bh case h of 0 -> return IfAbstractTyCon- 1 -> liftM IfDataTyCon (get bh)- 2 -> liftM IfNewTyCon (get bh)+ 1 -> liftM (IfDataTyCon False) (get bh)+ 2 -> liftM (IfDataTyCon True) (get bh)+ 3 -> liftM IfNewTyCon (get bh) _ -> error "Binary(IfaceConDecls).get: Invalid IfaceConDecls" instance Binary IfaceConDecl where@@ -2378,9 +2397,12 @@ putByte bh 13 put_ bh a put_ bh b- put_ bh (IfaceLitRubbish r) = do+ put_ bh (IfaceLitRubbish TypeLike r) = do putByte bh 14 put_ bh r+ put_ bh (IfaceLitRubbish ConstraintLike r) = do+ putByte bh 15+ put_ bh r get bh = do h <- getByte bh case h of@@ -2424,7 +2446,9 @@ b <- get bh return (IfaceECase a b) 14 -> do r <- get bh- return (IfaceLitRubbish r)+ return (IfaceLitRubbish TypeLike r)+ 15 -> do r <- get bh+ return (IfaceLitRubbish ConstraintLike r) _ -> panic ("get IfaceExpr " ++ show h) instance Binary IfaceTickish where@@ -2624,7 +2648,7 @@ instance NFData IfaceConDecls where rnf = \case IfAbstractTyCon -> ()- IfDataTyCon f1 -> rnf f1+ IfDataTyCon _ f1 -> rnf f1 IfNewTyCon f1 -> rnf f1 instance NFData IfaceConDecl where@@ -2681,7 +2705,7 @@ IfaceLet bind e -> rnf bind `seq` rnf e IfaceCast e co -> rnf e `seq` rnf co IfaceLit l -> l `seq` () -- FIXME- IfaceLitRubbish r -> rnf r `seq` ()+ IfaceLitRubbish tc r -> tc `seq` rnf r `seq` () IfaceFCall fc ty -> fc `seq` rnf ty IfaceTick tick e -> rnf tick `seq` rnf e
compiler/GHC/Iface/Type.hs view
@@ -28,7 +28,7 @@ IfaceContext, IfaceBndr(..), IfaceOneShot(..), IfaceLamBndr, IfaceTvBndr, IfaceIdBndr, IfaceTyConBinder, IfaceForAllSpecBndr,- IfaceForAllBndr, ArgFlag(..), AnonArgFlag(..), ShowForAllFlag(..),+ IfaceForAllBndr, ForAllTyFlag(..), FunTyFlag(..), ShowForAllFlag(..), mkIfaceForAllTvBndr, mkIfaceTyConKind, ifaceForAllSpecToBndrs, ifaceForAllSpecToBndr,@@ -39,8 +39,8 @@ -- Equality testing isIfaceLiftedTypeKind, - -- Conversion from IfaceAppArgs to IfaceTypes/ArgFlags- appArgsIfaceTypes, appArgsIfaceTypesArgFlags,+ -- Conversion from IfaceAppArgs to IfaceTypes/ForAllTyFlags+ appArgsIfaceTypes, appArgsIfaceTypesForAllTyFlags, -- Printing SuppressBndrSig(..),@@ -55,9 +55,7 @@ pprIfaceCoercion, pprParendIfaceCoercion, splitIfaceSigmaTy, pprIfaceTypeApp, pprUserIfaceForAll, pprIfaceCoTcApp, pprTyTcApp, pprIfacePrefixApp,- mulArrow,- ppr_fun_arrow,- isIfaceTauType,+ isIfaceRhoType, suppressIfaceInvisibles, stripIfaceInvisVars,@@ -65,18 +63,20 @@ mkIfaceTySubst, substIfaceTyVar, substIfaceAppArgs, inDomIfaceTySubst, - many_ty+ many_ty, pprTypeArrow ) where import GHC.Prelude import {-# SOURCE #-} GHC.Builtin.Types ( coercibleTyCon, heqTyCon+ , constraintKindTyConName , tupleTyConName- , manyDataConTyCon, oneDataConTyCon+ , manyDataConTyCon , liftedRepTyCon, liftedDataConTyCon )-import GHC.Core.Type ( isRuntimeRepTy, isMultiplicityTy, isLevityTy )-+import GHC.Core.Type ( isRuntimeRepTy, isMultiplicityTy, isLevityTy, funTyFlagTyCon )+import GHC.Core.TyCo.Rep( CoSel )+import GHC.Core.TyCo.Compare( eqForAllVis ) import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom import GHC.Types.Var@@ -162,7 +162,7 @@ -- See Note [Suppressing invisible arguments] for -- an explanation of why the second field isn't -- IfaceType, analogous to AppTy.- | IfaceFunTy AnonArgFlag IfaceMult IfaceType IfaceType+ | IfaceFunTy FunTyFlag IfaceMult IfaceType IfaceType | IfaceForAllTy IfaceForAllBndr IfaceType | IfaceTyConApp IfaceTyCon IfaceAppArgs -- Not necessarily saturated -- Includes newtypes, synonyms, tuples@@ -192,11 +192,11 @@ deriving (Eq) type IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis-type IfaceForAllBndr = VarBndr IfaceBndr ArgFlag+type IfaceForAllBndr = VarBndr IfaceBndr ForAllTyFlag type IfaceForAllSpecBndr = VarBndr IfaceBndr Specificity -- | Make an 'IfaceForAllBndr' from an 'IfaceTvBndr'.-mkIfaceForAllTvBndr :: ArgFlag -> IfaceTvBndr -> IfaceForAllBndr+mkIfaceForAllTvBndr :: ForAllTyFlag -> IfaceTvBndr -> IfaceForAllBndr mkIfaceForAllTvBndr vis var = Bndr (IfaceTvBndr var) vis -- | Build the 'tyConKind' from the binders and the result kind.@@ -220,7 +220,7 @@ = IA_Nil | IA_Arg IfaceType -- The type argument - ArgFlag -- The argument's visibility. We store this here so+ ForAllTyFlag -- The argument's visibility. We store this here so -- that we can: -- -- 1. Avoid pretty-printing invisible (i.e., specified@@ -352,9 +352,13 @@ See Note [The equality types story] in GHC.Builtin.Types.Prim. -} -data IfaceTyConInfo -- Used to guide pretty-printing- -- and to disambiguate D from 'D (they share a name)+data IfaceTyConInfo -- Used only to guide pretty-printing = IfaceTyConInfo { ifaceTyConIsPromoted :: PromotionFlag+ -- A PromotionFlag value of IsPromoted indicates+ -- that the type constructor came from a data+ -- constructor promoted by -XDataKinds, and thus+ -- should be printed as 'D to distinguish it from+ -- an existing type constructor D. , ifaceTyConSort :: IfaceTyConSort } deriving (Eq) @@ -385,7 +389,7 @@ | IfaceUnivCo IfaceUnivCoProv Role IfaceType IfaceType | IfaceSymCo IfaceCoercion | IfaceTransCo IfaceCoercion IfaceCoercion- | IfaceNthCo Int IfaceCoercion+ | IfaceSelCo CoSel IfaceCoercion | IfaceLRCo LeftOrRight IfaceCoercion | IfaceInstCo IfaceCoercion IfaceCoercion | IfaceKindCo IfaceCoercion@@ -412,7 +416,7 @@ %************************************************************************ %* *- Functions over IFaceTypes+ Functions over IfaceTypes * * ************************************************************************ -}@@ -420,36 +424,56 @@ ifaceTyConHasKey :: IfaceTyCon -> Unique -> Bool ifaceTyConHasKey tc key = ifaceTyConName tc `hasKey` key --- | Given a kind K, is K of the form (TYPE ('BoxedRep 'LiftedRep))?+-- | Returns true for Type or (TYPE LiftedRep) isIfaceLiftedTypeKind :: IfaceKind -> Bool-isIfaceLiftedTypeKind (IfaceTyConApp tc IA_Nil)- = isLiftedTypeKindTyConName (ifaceTyConName tc)-isIfaceLiftedTypeKind (IfaceTyConApp tc1 args1)- = isIfaceTyConAppLiftedTypeKind tc1 args1+isIfaceLiftedTypeKind (IfaceTyConApp tc args)+ | tc `ifaceTyConHasKey` liftedTypeKindTyConKey+ , IA_Nil <- args+ = True -- Type++ | tc `ifaceTyConHasKey` tYPETyConKey+ , IA_Arg arg1 Required IA_Nil <- args+ , isIfaceLiftedRep arg1+ = True -- TYPE Lifted+ isIfaceLiftedTypeKind _ = False --- | Given a kind constructor K and arguments A, returns true if--- both of the following statements are true:------ * K is TYPE--- * A is a singleton IfaceAppArgs of the form ('BoxedRep 'Lifted)------ For the second condition, we must also check for the type--- synonym LiftedRep.-isIfaceTyConAppLiftedTypeKind :: IfaceTyCon -> IfaceAppArgs -> Bool-isIfaceTyConAppLiftedTypeKind tc1 args1- | tc1 `ifaceTyConHasKey` tYPETyConKey- , IA_Arg soleArg1 Required IA_Nil <- args1- , IfaceTyConApp rep args2 <- soleArg1 =- if | rep `ifaceTyConHasKey` boxedRepDataConKey- , IA_Arg soleArg2 Required IA_Nil <- args2- , IfaceTyConApp lev IA_Nil <- soleArg2- , lev `ifaceTyConHasKey` liftedDataConKey -> True- | rep `ifaceTyConHasKey` liftedRepTyConKey- , IA_Nil <- args2 -> True- | otherwise -> False- | otherwise = False+-- | Returns true for Constraint or (CONSTRAINT LiftedRep)+isIfaceConstraintKind :: IfaceKind -> Bool+isIfaceConstraintKind (IfaceTyConApp tc args)+ | tc `ifaceTyConHasKey` constraintKindTyConKey+ , IA_Nil <- args+ = True -- Type + | tc `ifaceTyConHasKey` cONSTRAINTTyConKey+ , IA_Arg arg1 Required IA_Nil <- args+ , isIfaceLiftedRep arg1+ = True -- TYPE Lifted++isIfaceConstraintKind _ = False++isIfaceLiftedRep :: IfaceKind -> Bool+-- Returns true for LiftedRep, or BoxedRep Lifted+isIfaceLiftedRep (IfaceTyConApp tc args)+ | tc `ifaceTyConHasKey` liftedRepTyConKey+ , IA_Nil <- args+ = True -- LiftedRep++ | tc `ifaceTyConHasKey` boxedRepDataConKey+ , IA_Arg arg1 Required IA_Nil <- args+ , isIfaceLifted arg1+ = True -- TYPE Lifted++isIfaceLiftedRep _ = False++isIfaceLifted :: IfaceKind -> Bool+-- Returns true for Lifted+isIfaceLifted (IfaceTyConApp tc args)+ | tc `ifaceTyConHasKey` liftedDataConKey+ , IA_Nil <- args+ = True+isIfaceLifted _ = False+ splitIfaceSigmaTy :: IfaceType -> ([IfaceForAllBndr], [IfacePredType], IfaceType) -- Mainly for printing purposes --@@ -474,17 +498,18 @@ (theta, tau) = split_rho rho split_foralls (IfaceForAllTy bndr ty)- | isInvisibleArgFlag (binderArgFlag bndr)+ | isInvisibleForAllTyFlag (binderFlag bndr) = case split_foralls ty of { (bndrs, rho) -> (bndr:bndrs, rho) } split_foralls rho = ([], rho) - split_rho (IfaceFunTy InvisArg _ ty1 ty2)+ split_rho (IfaceFunTy af _ ty1 ty2)+ | isInvisibleFunArg af = case split_rho ty2 of { (ps, tau) -> (ty1:ps, tau) } split_rho tau = ([], tau) splitIfaceReqForallTy :: IfaceType -> ([IfaceForAllBndr], IfaceType) splitIfaceReqForallTy (IfaceForAllTy bndr ty)- | isVisibleArgFlag (binderArgFlag bndr)+ | isVisibleForAllTyFlag (binderFlag bndr) = case splitIfaceReqForallTy ty of { (bndrs, rho) -> (bndr:bndrs, rho) } splitIfaceReqForallTy rho = ([], rho) @@ -586,7 +611,7 @@ go_co (IfaceUnivCo prov r t1 t2) = IfaceUnivCo (go_prov prov) r (go t1) (go t2) go_co (IfaceSymCo co) = IfaceSymCo (go_co co) go_co (IfaceTransCo co1 co2) = IfaceTransCo (go_co co1) (go_co co2)- go_co (IfaceNthCo n co) = IfaceNthCo n (go_co co)+ go_co (IfaceSelCo n co) = IfaceSelCo n (go_co co) go_co (IfaceLRCo lr co) = IfaceLRCo lr (go_co co) go_co (IfaceInstCo c1 c2) = IfaceInstCo (go_co c1) (go_co c2) go_co (IfaceKindCo co) = IfaceKindCo (go_co co)@@ -629,12 +654,12 @@ = case c of IA_Nil -> IA_Nil IA_Arg t argf ts- | isVisibleArgFlag argf+ | isVisibleForAllTyFlag argf -> IA_Arg t argf $ suppress_invis ts -- Keep recursing through the remainder of the arguments, as it's -- possible that there are remaining invisible ones. -- See the "In type declarations" section of Note [VarBndrs,- -- TyCoVarBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep.+ -- ForAllTyBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep. | otherwise -> suppress_invis ts @@ -642,17 +667,17 @@ appArgsIfaceTypes IA_Nil = [] appArgsIfaceTypes (IA_Arg t _ ts) = t : appArgsIfaceTypes ts -appArgsIfaceTypesArgFlags :: IfaceAppArgs -> [(IfaceType, ArgFlag)]-appArgsIfaceTypesArgFlags IA_Nil = []-appArgsIfaceTypesArgFlags (IA_Arg t a ts)- = (t, a) : appArgsIfaceTypesArgFlags ts+appArgsIfaceTypesForAllTyFlags :: IfaceAppArgs -> [(IfaceType, ForAllTyFlag)]+appArgsIfaceTypesForAllTyFlags IA_Nil = []+appArgsIfaceTypesForAllTyFlags (IA_Arg t a ts)+ = (t, a) : appArgsIfaceTypesForAllTyFlags ts ifaceVisAppArgsLength :: IfaceAppArgs -> Int ifaceVisAppArgsLength = go 0 where go !n IA_Nil = n go n (IA_Arg _ argf rest)- | isVisibleArgFlag argf = go (n+1) rest+ | isVisibleForAllTyFlag argf = go (n+1) rest | otherwise = go n rest {-@@ -742,7 +767,7 @@ Here, @{k} indicates that `k` is an inferred argument, and @k indicates that `k` is a specified argument. (See-Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep for+Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep for a lengthier explanation on what "inferred" and "specified" mean.) ************************************************************************@@ -774,10 +799,10 @@ | otherwise = maybeParen ctxt_prec appPrec $ hang pp_fun 2 (sep pp_tys) -isIfaceTauType :: IfaceType -> Bool-isIfaceTauType (IfaceForAllTy _ _) = False-isIfaceTauType (IfaceFunTy InvisArg _ _ _) = False-isIfaceTauType _ = True+isIfaceRhoType :: IfaceType -> Bool+isIfaceRhoType (IfaceForAllTy _ _) = False+isIfaceRhoType (IfaceFunTy af _ _ _) = isVisibleFunArg af+isIfaceRhoType _ = True -- ----------------------------- Printing binders ------------------------------------ @@ -819,19 +844,28 @@ Note [Printing type abbreviations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Normally, we pretty-print `TYPE 'LiftedRep` as `Type` (or `*`) and-`FUN 'Many` as `(->)`.+Normally, we pretty-print+ `TYPE 'LiftedRep` as `Type` (or `*`)+ `CONSTRAINT 'LiftedRep` as `Constraint`+ `FUN 'Many` as `(->)`. This way, error messages don't refer to representation polymorphism-or linearity if it is not necessary.+or linearity if it is not necessary. Normally we'd would represent+these types using their synonyms (see GHC.Core.Type+Note [Using synonyms to compress types]), but in the :kind! GHCi+command we specifically expand synonyms (see GHC.Tc.Module.tcRnExpr).+So here in the pretty-printing we effectively collapse back Type+and Constraint to their synonym forms. A bit confusing! -However, when printing the definition of Type or (->) with :info,+However, when printing the definition of Type, Constraint or (->) with :info, this would give confusing output: `type (->) = (->)` (#18594). Solution: detect when we are in :info and disable displaying the synonym with the SDoc option sdocPrintTypeAbbreviations.+If you are creating a similar synonym, make sure it is listed in pprIfaceDecl,+see reference to this Note. If there will be a need, in the future we could expose it as a flag--fprint-type-abbreviations or even two separate flags controlling-TYPE 'LiftedRep and FUN 'Many.+-fprint-type-abbreviations or even three separate flags controlling+TYPE 'LiftedRep, CONSTRAINT 'LiftedRep and FUN 'Many. -} -- | Do we want to suppress kind annotations on binders?@@ -858,9 +892,11 @@ go (Bndr (IfaceTvBndr bndr) vis) = -- See Note [Pretty-printing invisible arguments] case vis of- AnonTCB VisArg -> ppr_bndr (UseBndrParens True)- AnonTCB InvisArg -> char '@' <> braces (ppr_bndr (UseBndrParens False))- -- The above case is rare. (See Note [AnonTCB InvisArg] in GHC.Core.TyCon.)+ AnonTCB af+ | isVisibleFunArg af -> ppr_bndr (UseBndrParens True)+ | otherwise -> char '@' <> braces (ppr_bndr (UseBndrParens False))+ -- The above case is rare. (See Note [AnonTCB with constraint arg]+ -- in GHC.Core.TyCon.) -- Should we print these differently? NamedTCB Required -> ppr_bndr (UseBndrParens True) NamedTCB Specified -> char '@' <> ppr_bndr (UseBndrParens True)@@ -910,43 +946,51 @@ pprPrecIfaceType prec ty = hideNonStandardTypes (ppr_ty prec) ty --- mulArrow takes a pretty printer for the type it is being called on to--- allow type applications to be printed with the correct precedence inside--- the multiplicity e.g. a %(m n) -> b. See #20315.-mulArrow :: (PprPrec -> a -> SDoc) -> a -> SDoc-mulArrow ppr_mult mult = text "%" <> ppr_mult appPrec mult <+> arrow--ppr_fun_arrow :: IfaceMult -> SDoc-ppr_fun_arrow w- | (IfaceTyConApp tc _) <- w- , tc `ifaceTyConHasKey` (getUnique manyDataConTyCon) = arrow- | (IfaceTyConApp tc _) <- w- , tc `ifaceTyConHasKey` (getUnique oneDataConTyCon) = lollipop- | otherwise = mulArrow pprPrecIfaceType w+pprTypeArrow :: FunTyFlag -> IfaceMult -> SDoc+pprTypeArrow af mult+ = pprArrow (mb_conc, pprPrecIfaceType) af mult+ where+ mb_conc (IfaceTyConApp tc _) = Just tc+ mb_conc _ = Nothing -ppr_sigma :: PprPrec -> IfaceType -> SDoc-ppr_sigma ctxt_prec ty- = maybeParen ctxt_prec funPrec (pprIfaceSigmaType ShowForAllMust ty)+pprArrow :: (a -> Maybe IfaceTyCon, PprPrec -> a -> SDoc)+ -> FunTyFlag -> a -> SDoc+-- Prints a thin arrow (->) with its multiplicity+-- Used for both FunTy and FunCo, hence higher order arguments+pprArrow (mb_conc, ppr_mult) af mult+ | isFUNArg af+ = case mb_conc mult of+ Just tc | tc `ifaceTyConHasKey` manyDataConKey -> arrow+ | tc `ifaceTyConHasKey` oneDataConKey -> lollipop+ _ -> text "%" <> ppr_mult appPrec mult <+> arrow+ | otherwise+ = ppr (funTyFlagTyCon af) ppr_ty :: PprPrec -> IfaceType -> SDoc-ppr_ty ctxt_prec ty@(IfaceForAllTy {}) = ppr_sigma ctxt_prec ty-ppr_ty ctxt_prec ty@(IfaceFunTy InvisArg _ _ _) = ppr_sigma ctxt_prec ty-+ppr_ty ctxt_prec ty+ | not (isIfaceRhoType ty) = ppr_sigma ShowForAllMust ctxt_prec ty+ppr_ty _ (IfaceForAllTy {}) = panic "ppr_ty" -- Covered by not.isIfaceRhoType ppr_ty _ (IfaceFreeTyVar tyvar) = ppr tyvar -- This is the main reason for IfaceFreeTyVar! ppr_ty _ (IfaceTyVar tyvar) = ppr tyvar -- See Note [Free tyvars in IfaceType] ppr_ty ctxt_prec (IfaceTyConApp tc tys) = pprTyTcApp ctxt_prec tc tys ppr_ty ctxt_prec (IfaceTupleTy i p tys) = pprTuple ctxt_prec i p tys -- always fully saturated ppr_ty _ (IfaceLitTy n) = pprIfaceTyLit n+ -- Function types-ppr_ty ctxt_prec (IfaceFunTy _ w ty1 ty2) -- Should be VisArg- = -- We don't want to lose synonyms, so we mustn't use splitFunTys here.+ppr_ty ctxt_prec ty@(IfaceFunTy af w ty1 ty2) -- Should be a visible argument+ = assertPpr (isVisibleFunArg af) (ppr ty) $ -- Ensured by isIfaceRhoType above+ -- We want to print a chain of arrows in a column+ -- type1+ -- -> type2+ -- -> type3 maybeParen ctxt_prec funPrec $ sep [ppr_ty funPrec ty1, sep (ppr_fun_tail w ty2)] where- ppr_fun_tail wthis (IfaceFunTy VisArg wnext ty1 ty2)- = (ppr_fun_arrow wthis <+> ppr_ty funPrec ty1) : ppr_fun_tail wnext ty2+ ppr_fun_tail wthis (IfaceFunTy af wnext ty1 ty2)+ | isVisibleFunArg af+ = (pprTypeArrow af wthis <+> ppr_ty funPrec ty1) : ppr_fun_tail wnext ty2 ppr_fun_tail wthis other_ty- = [ppr_fun_arrow wthis <+> pprIfaceType other_ty]+ = [pprTypeArrow af wthis <+> pprIfaceType other_ty] ppr_ty ctxt_prec (IfaceAppTy t ts) = if_print_coercions@@ -955,7 +999,7 @@ where ppr_app_ty = sdocOption sdocPrintExplicitKinds $ \print_kinds ->- let tys_wo_kinds = appArgsIfaceTypesArgFlags $ stripInvisArgs+ let tys_wo_kinds = appArgsIfaceTypesForAllTyFlags $ stripInvisArgs (PrintExplicitKinds print_kinds) ts in pprIfacePrefixApp ctxt_prec (ppr_ty funPrec t)@@ -1062,7 +1106,7 @@ -> IfaceType -> IfaceType go subs (IfaceForAllTy (Bndr (IfaceTvBndr (var, var_kind)) argf) ty)- | isInvisibleArgFlag argf -- Don't default *visible* quantification+ | isInvisibleForAllTyFlag argf -- Don't default *visible* quantification -- or we get the mess in #13963 , Just substituted_ty <- check_substitution var_kind = let subs' = extendFsEnv subs var substituted_ty@@ -1157,9 +1201,8 @@ -- | The type 'Many :: Multiplicity'. many_ty :: IfaceType-many_ty =- IfaceTyConApp (IfaceTyCon dc_name (mkIfaceTyConInfo IsPromoted IfaceNormalTyCon))- IA_Nil+many_ty = IfaceTyConApp (IfaceTyCon dc_name (mkIfaceTyConInfo IsPromoted IfaceNormalTyCon))+ IA_Nil where dc_name = getName manyDataConTyCon hideNonStandardTypes :: (IfaceType -> SDoc) -> IfaceType -> SDoc@@ -1188,7 +1231,7 @@ go (IA_Arg t argf ts) = ppr_app_arg ctx_prec (t, argf) <+> go ts -- See Note [Pretty-printing invisible arguments]-ppr_app_arg :: PprPrec -> (IfaceType, ArgFlag) -> SDoc+ppr_app_arg :: PprPrec -> (IfaceType, ForAllTyFlag) -> SDoc ppr_app_arg ctx_prec (t, argf) = sdocOption sdocPrintExplicitKinds $ \print_kinds -> case argf of@@ -1240,12 +1283,12 @@ -- Returns both the list of not-yet-rendered binders and the doc. -- No anonymous binders here! ppr_itv_bndrs :: [IfaceForAllBndr]- -> ArgFlag -- ^ visibility of the first binder in the list+ -> ForAllTyFlag -- ^ visibility of the first binder in the list -> ([IfaceForAllBndr], [SDoc]) ppr_itv_bndrs all_bndrs@(bndr@(Bndr _ vis) : bndrs) vis1- | vis `sameVis` vis1 = let (bndrs', doc) = ppr_itv_bndrs bndrs vis1 in- (bndrs', pprIfaceForAllBndr bndr : doc)- | otherwise = (all_bndrs, [])+ | vis `eqForAllVis` vis1 = let (bndrs', doc) = ppr_itv_bndrs bndrs vis1 in+ (bndrs', pprIfaceForAllBndr bndr : doc)+ | otherwise = (all_bndrs, []) ppr_itv_bndrs [] _ = ([], []) pprIfaceForAllCo :: [(IfLclName, IfaceCoercion)] -> SDoc@@ -1280,11 +1323,13 @@ pprIfaceSigmaType :: ShowForAllFlag -> IfaceType -> SDoc pprIfaceSigmaType show_forall ty- = hideNonStandardTypes ppr_fn ty- where- ppr_fn iface_ty =- let (invis_tvs, theta, tau) = splitIfaceSigmaTy iface_ty- (req_tvs, tau') = splitIfaceReqForallTy tau+ = hideNonStandardTypes (ppr_sigma show_forall topPrec) ty++ppr_sigma :: ShowForAllFlag -> PprPrec -> IfaceType -> SDoc+ppr_sigma show_forall ctxt_prec iface_ty+ = maybeParen ctxt_prec funPrec $+ let (invis_tvs, theta, tau) = splitIfaceSigmaTy iface_ty+ (req_tvs, tau') = splitIfaceReqForallTy tau -- splitIfaceSigmaTy is recursive, so it will gather the binders after -- the theta, i.e. forall a. theta => forall b. tau -- will give you ([a,b], theta, tau).@@ -1298,8 +1343,8 @@ -- non-recursive (see #18458). -- Then it could handle both invisible and required binders, and -- splitIfaceReqForallTy wouldn't be necessary here.- in ppr_iface_forall_part show_forall invis_tvs theta $- sep [pprIfaceForAll req_tvs, ppr tau']+ in ppr_iface_forall_part show_forall invis_tvs theta $+ sep [pprIfaceForAll req_tvs, ppr tau'] pprUserIfaceForAll :: [IfaceForAllBndr] -> SDoc pprUserIfaceForAll tvs@@ -1314,7 +1359,7 @@ = not (ifTypeIsVarFree kind) tv_has_kind_var _ = False - tv_is_required = isVisibleArgFlag . binderArgFlag+ tv_is_required = isVisibleForAllTyFlag . binderFlag {- Note [When to print foralls]@@ -1344,7 +1389,7 @@ because omitting it and printing "T :: k -> Type" would be utterly misleading. - See Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility]+ See Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in GHC.Core.TyCo.Rep. N.B. Until now (Aug 2018) we didn't check anything for coercion variables.@@ -1405,23 +1450,20 @@ Found hole: _ :: Proxy '['True] This would be bad, because the '[' looks like a character literal.++A similar issue arises if the element is a character literal (#22488)+ ghci> type T = '[ 'x' ]+ ghci> :kind! T+ T :: [Char]+ = '['x']+ Solution: in type-level lists and tuples, add a leading space-if the first type is itself promoted. See pprSpaceIfPromotedTyCon.+if the first element is printed with a single quote. -} ------------------- --- | Prefix a space if the given 'IfaceType' is a promoted 'TyCon'.--- See Note [Printing promoted type constructors]-pprSpaceIfPromotedTyCon :: IfaceType -> SDoc -> SDoc-pprSpaceIfPromotedTyCon (IfaceTyConApp tyCon _)- = case ifaceTyConIsPromoted (ifaceTyConInfo tyCon) of- IsPromoted -> (space <>)- _ -> id-pprSpaceIfPromotedTyCon _- = id- -- See equivalent function in "GHC.Core.TyCo.Rep" pprIfaceTyList :: PprPrec -> IfaceType -> IfaceType -> SDoc -- Given a type-level list (t1 ': t2), see if we can print@@ -1430,8 +1472,19 @@ pprIfaceTyList ctxt_prec ty1 ty2 = case gather ty2 of (arg_tys, Nothing)- -> char '\'' <> brackets (pprSpaceIfPromotedTyCon ty1 (fsep- (punctuate comma (map (ppr_ty topPrec) (ty1:arg_tys)))))+ ->+ sdocWithContext $ \ctx ->+ let+ items = ty1:arg_tys+ eos = isListEmptyOrSingleton items+ ticked = promTick (sdocStyle ctx) (PromotedItemListSyntax eos)+ (preBracket, postBracket) =+ if ticked+ then (char '\'', spaceIfSingleQuote)+ else (empty, id)+ in+ preBracket <> brackets (postBracket (fsep+ (punctuate comma (map (ppr_ty topPrec) items)))) (arg_tys, Just tl) -> maybeParen ctxt_prec funPrec $ hang (ppr_ty funPrec ty1) 2 (fsep [ colon <+> ppr_ty funPrec ty | ty <- arg_tys ++ [tl]])@@ -1442,7 +1495,7 @@ gather (IfaceTyConApp tc tys) | tc `ifaceTyConHasKey` consDataConKey , IA_Arg _ argf (IA_Arg ty1 Required (IA_Arg ty2 Required IA_Nil)) <- tys- , isInvisibleArgFlag argf+ , isInvisibleForAllTyFlag argf , (args, tl) <- gather ty2 = (ty1:args, tl) | tc `ifaceTyConHasKey` nilDataConKey@@ -1479,20 +1532,25 @@ | tc `ifaceTyConHasKey` consDataConKey , False <- print_kinds , IA_Arg _ argf (IA_Arg ty1 Required (IA_Arg ty2 Required IA_Nil)) <- tys- , isInvisibleArgFlag argf+ , isInvisibleForAllTyFlag argf -> pprIfaceTyList ctxt_prec ty1 ty2 - | isIfaceTyConAppLiftedTypeKind tc tys+ | isIfaceLiftedTypeKind (IfaceTyConApp tc tys) , print_type_abbreviations -- See Note [Printing type abbreviations] -> ppr_kind_type ctxt_prec - | tc `ifaceTyConHasKey` funTyConKey+ | isIfaceConstraintKind (IfaceTyConApp tc tys)+ , print_type_abbreviations -- See Note [Printing type abbreviations]+ -> pprPrefixOcc constraintKindTyConName++ | tc `ifaceTyConHasKey` fUNTyConKey , IA_Arg (IfaceTyConApp rep IA_Nil) Required args <- tys , rep `ifaceTyConHasKey` manyDataConKey , print_type_abbreviations -- See Note [Printing type abbreviations] -> pprIfacePrefixApp ctxt_prec (parens arrow) (map (ppr_app_arg appPrec) $- appArgsIfaceTypesArgFlags $ stripInvisArgs (PrintExplicitKinds print_kinds) args)- -- Use appArgsIfaceTypesArgFlags to print invisible arguments+ appArgsIfaceTypesForAllTyFlags $+ stripInvisArgs (PrintExplicitKinds print_kinds) args)+ -- Use appArgsIfaceTypesForAllTyFlags to print invisible arguments -- correctly (#19310) | tc `ifaceTyConHasKey` errorMessageTypeErrorFamKey@@ -1505,7 +1563,7 @@ | otherwise -> ppr_iface_tc_app ppr_app_arg ctxt_prec tc $- appArgsIfaceTypesArgFlags $ stripInvisArgs (PrintExplicitKinds print_kinds) tys+ appArgsIfaceTypesForAllTyFlags $ stripInvisArgs (PrintExplicitKinds print_kinds) tys where info = ifaceTyConInfo tc @@ -1615,8 +1673,8 @@ -- 1. Types (from `pprTyTcApp'`) -- -- 2. Coercions (from 'pprIfaceCoTcApp')-ppr_iface_tc_app :: (PprPrec -> (a, ArgFlag) -> SDoc)- -> PprPrec -> IfaceTyCon -> [(a, ArgFlag)] -> SDoc+ppr_iface_tc_app :: (PprPrec -> (a, ForAllTyFlag) -> SDoc)+ -> PprPrec -> IfaceTyCon -> [(a, ForAllTyFlag)] -> SDoc ppr_iface_tc_app pp ctxt_prec tc tys = sdocOption sdocListTuplePuns $ \listTuplePuns ->@@ -1664,12 +1722,9 @@ IsPromoted -> let tys = appArgsIfaceTypes args args' = drop (length tys `div` 2) tys- spaceIfPromoted = case args' of- arg0:_ -> pprSpaceIfPromotedTyCon arg0- _ -> id in ppr_tuple_app args' $ pprPromotionQuoteI IsPromoted <>- tupleParens sort (spaceIfPromoted (pprWithCommas pprIfaceType args'))+ tupleParens sort (spaceIfSingleQuote (pprWithCommas pprIfaceType args')) NotPromoted | ConstraintTuple <- sort@@ -1717,16 +1772,21 @@ ppr_co ctxt_prec (IfaceGReflCo r ty (IfaceMCo co)) = ppr_special_co ctxt_prec (text "GRefl" <+> ppr r <+> pprParendIfaceType ty) [co]-ppr_co ctxt_prec (IfaceFunCo r cow co1 co2)++ppr_co ctxt_prec (IfaceFunCo r co_mult co1 co2) = maybeParen ctxt_prec funPrec $- sep (ppr_co funPrec co1 : ppr_fun_tail cow co2)+ sep (ppr_co funPrec co1 : ppr_fun_tail co_mult co2) where- ppr_fun_tail cow' (IfaceFunCo r cow co1 co2)- = (coercionArrow cow' <> ppr_role r <+> ppr_co funPrec co1) : ppr_fun_tail cow co2- ppr_fun_tail cow' other_co- = [coercionArrow cow' <> ppr_role r <+> pprIfaceCoercion other_co]- coercionArrow w = mulArrow ppr_co w+ ppr_fun_tail co_mult1 (IfaceFunCo r co_mult2 co1 co2)+ = (ppr_arrow co_mult1 <> ppr_role r <+> ppr_co funPrec co1)+ : ppr_fun_tail co_mult2 co2+ ppr_fun_tail co_mult1 other_co+ = [ppr_arrow co_mult1 <> ppr_role r <+> pprIfaceCoercion other_co] + ppr_arrow = pprArrow (mb_conc, ppr_co) visArgTypeLike+ mb_conc (IfaceTyConAppCo _ tc _) = Just tc+ mb_conc _ = Nothing+ ppr_co _ (IfaceTyConAppCo r tc cos) = parens (pprIfaceCoTcApp topPrec tc cos) <> ppr_role r ppr_co ctxt_prec (IfaceAppCo co1 co2)@@ -1772,8 +1832,8 @@ ppr_trans c = [semi <+> ppr_co opPrec c] in maybeParen ctxt_prec opPrec $ vcat (ppr_co topPrec co1 : ppr_trans co2)-ppr_co ctxt_prec (IfaceNthCo d co)- = ppr_special_co ctxt_prec (text "Nth:" <> int d) [co]+ppr_co ctxt_prec (IfaceSelCo d co)+ = ppr_special_co ctxt_prec (text "SelCo:" <> ppr d) [co] ppr_co ctxt_prec (IfaceLRCo lr co) = ppr_special_co ctxt_prec (ppr lr) [co] ppr_co ctxt_prec (IfaceSubCo co)@@ -1815,11 +1875,21 @@ pprPromotionQuote :: IfaceTyCon -> SDoc pprPromotionQuote tc =- pprPromotionQuoteI $ ifaceTyConIsPromoted $ ifaceTyConInfo tc+ getPprStyle $ \sty ->+ let+ name = getOccName (ifaceTyConName tc)+ ticked =+ case ifaceTyConIsPromoted (ifaceTyConInfo tc) of+ NotPromoted -> False+ IsPromoted -> promTick sty (PromotedItemDataCon name)+ in+ if ticked+ then char '\''+ else empty pprPromotionQuoteI :: PromotionFlag -> SDoc pprPromotionQuoteI NotPromoted = empty-pprPromotionQuoteI IsPromoted = char '\''+pprPromotionQuoteI IsPromoted = char '\'' instance Outputable IfaceCoercion where ppr = pprIfaceCoercion@@ -2063,7 +2133,7 @@ putByte bh 11 put_ bh a put_ bh b- put_ bh (IfaceNthCo a b) = do+ put_ bh (IfaceSelCo a b) = do putByte bh 12 put_ bh a put_ bh b@@ -2100,10 +2170,10 @@ b <- get bh c <- get bh return $ IfaceGReflCo a b c- 3 -> do a <- get bh- w <- get bh- b <- get bh- c <- get bh+ 3 -> do a <- get bh+ w <- get bh+ b <- get bh+ c <- get bh return $ IfaceFunCo a w b c 4 -> do a <- get bh b <- get bh@@ -2134,7 +2204,7 @@ return $ IfaceTransCo a b 12-> do a <- get bh b <- get bh- return $ IfaceNthCo a b+ return $ IfaceSelCo a b 13-> do a <- get bh b <- get bh return $ IfaceLRCo a b@@ -2220,7 +2290,7 @@ IfaceUnivCo f1 f2 f3 f4 -> rnf f1 `seq` f2 `seq` rnf f3 `seq` rnf f4 IfaceSymCo f1 -> rnf f1 IfaceTransCo f1 f2 -> rnf f1 `seq` rnf f2- IfaceNthCo f1 f2 -> rnf f1 `seq` rnf f2+ IfaceSelCo f1 f2 -> rnf f1 `seq` rnf f2 IfaceLRCo f1 f2 -> f1 `seq` rnf f2 IfaceInstCo f1 f2 -> rnf f1 `seq` rnf f2 IfaceKindCo f1 -> rnf f1
compiler/GHC/Linker/Static/Utils.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE MultiWayIf #-}+ module GHC.Linker.Static.Utils where import GHC.Prelude@@ -12,20 +14,18 @@ -- Use the provided filename (if any), otherwise use "main.exe" (Windows), -- "a.out (otherwise without StaticLink set), "liba.a". In every case, add the -- extension if it is missing.-exeFileName :: Platform -> Bool -> Maybe FilePath -> FilePath-exeFileName platform staticLink output_fn- | Just s <- output_fn =- case platformOS platform of- OSMinGW32 -> s <?.> "exe"- _ -> if staticLink- then s <?.> "a"- else s- | otherwise =- if platformOS platform == OSMinGW32- then "main.exe"- else if staticLink- then "liba.a"- else "a.out"+exeFileName :: ArchOS -> Bool -> Maybe FilePath -> FilePath+exeFileName (ArchOS arch os) staticLink output_fn+ | Just s <- output_fn = if+ | OSMinGW32 <- os -> s <?.> "exe"+ | ArchJavaScript <- arch -> s <?.> "jsexe"+ | staticLink -> s <?.> "a"+ | otherwise -> s+ | otherwise = if+ | OSMinGW32 <- os -> "main.exe"+ | ArchJavaScript <- arch -> "main.jsexe"+ | staticLink -> "liba.a"+ | otherwise -> "a.out" where s <?.> ext | null (takeExtension s) = s <.> ext | otherwise = s
compiler/GHC/Linker/Types.hs view
@@ -5,7 +5,7 @@ -- (c) The University of Glasgow 2019 -- ------------------------------------------------------------------------------+{-# LANGUAGE TypeApplications #-} module GHC.Linker.Types ( Loader (..) , LoaderState (..)@@ -254,7 +254,7 @@ | Framework String -- Only used for darwin, but does no harm instance Outputable LibrarySpec where- ppr (Objects objs) = text "Objects" <+> ppr (map text objs)+ ppr (Objects objs) = text "Objects" <+> ppr (map (text @SDoc) objs) ppr (Archive a) = text "Archive" <+> text a ppr (DLL s) = text "DLL" <+> text s ppr (DLLPath f) = text "DLLPath" <+> text f
compiler/GHC/Parser.y view
@@ -67,7 +67,7 @@ import qualified GHC.Data.Strict as Strict import GHC.Types.Name.Reader-import GHC.Types.Name.Occurrence ( varName, dataName, tcClsName, tvName, occNameFS, mkVarOccFS, occNameString)+import GHC.Types.Name.Occurrence ( varName, dataName, tcClsName, tvName, occNameFS, mkVarOccFS) import GHC.Types.SrcLoc import GHC.Types.Basic import GHC.Types.Error ( GhcHint(..) )@@ -77,7 +77,7 @@ import GHC.Types.SourceText import GHC.Types.PkgQual -import GHC.Core.Type ( unrestrictedFunTyCon, Specificity(..) )+import GHC.Core.Type ( Specificity(..) ) import GHC.Core.Class ( FunDep ) import GHC.Core.DataCon ( DataCon, dataConName ) @@ -92,7 +92,8 @@ import GHC.Builtin.Types ( unitTyCon, unitDataCon, sumTyCon, tupleTyCon, tupleDataCon, nilDataCon, unboxedUnitTyCon, unboxedUnitDataCon,- listTyCon_RDR, consDataCon_RDR)+ listTyCon_RDR, consDataCon_RDR,+ unrestrictedFunTyCon ) import Language.Haskell.Syntax.Basic (FieldLabelString(..)) @@ -824,7 +825,7 @@ litpkgname :: { Located FastString } : litpkgname_segment { $1 } -- a bit of a hack, means p - b is parsed same as p-b, enough for now.- | litpkgname_segment HYPHEN litpkgname { sLL $1 $> $ appendFS (unLoc $1) (consFS '-' (unLoc $3)) }+ | litpkgname_segment HYPHEN litpkgname { sLL $1 $> $ concatFS [unLoc $1, fsLit "-", (unLoc $3)] } mayberns :: { Maybe [LRenaming] } : {- empty -} { Nothing }@@ -3885,8 +3886,7 @@ : CONID { sL1a $1 $ mkModuleNameFS (getCONID $1) } | QCONID { sL1a $1 $ let (mod,c) = getQCONID $1 in mkModuleNameFS- (mkFastString- (unpackFS mod ++ '.':unpackFS c))+ (concatFS [mod, fsLit ".", c]) } commas :: { ([SrcSpan],Int) } -- One or more commas
compiler/GHC/Parser/Errors/Ppr.hs view
@@ -31,7 +31,7 @@ import GHC.Data.Maybe (catMaybes) import GHC.Hs.Expr (prependQualified, HsExpr(..), LamCaseVariant(..), lamCaseKeyword) import GHC.Hs.Type (pprLHsContext)-import GHC.Builtin.Names (allNameStrings)+import GHC.Builtin.Names (allNameStringList) import GHC.Builtin.Types (filterCTuple) import qualified GHC.LanguageExtensions as LangExt import Data.List.NonEmpty (NonEmpty((:|)))@@ -486,7 +486,7 @@ , nest 2 (what <+> tc'- <+> hsep (map text (takeList tparms allNameStrings))+ <+> hsep (map text (takeList tparms allNameStringList)) <+> equals_or_where) ] ] where -- Avoid printing a constraint tuple in the error message. Print@@ -513,6 +513,16 @@ , nest 2 $ text "but" <+> quotes (ppr tycon) <+> text "has" <+> speakN n ] , text "In the newtype declaration for" <+> quotes (ppr tycon) ] + PsErrUnicodeCharLooksLike bad_char looks_like_char looks_like_char_name+ -> mkSimpleDecorated $+ hsep [ text "Unicode character"+ -- purposefully not using `quotes (text [bad_char])`, because the quotes function adds smart quotes,+ -- and smart quotes may be the topic of this error message+ , text "'" <> text [bad_char] <> text "' (" <> text (show bad_char) <> text ")"+ , text "looks like"+ , text "'" <> text [looks_like_char] <> text "' (" <> text looks_like_char_name <> text ")" <> comma+ , text "but it is not" ]+ diagnosticReason = \case PsUnknownMessage m -> diagnosticReason m PsHeaderMessage m -> psHeaderMessageReason m@@ -630,6 +640,7 @@ PsErrIllegalGadtRecordMultiplicity{} -> ErrorWithoutFlag PsErrInvalidCApiImport {} -> ErrorWithoutFlag PsErrMultipleConForNewtype {} -> ErrorWithoutFlag+ PsErrUnicodeCharLooksLike{} -> ErrorWithoutFlag diagnosticHints = \case PsUnknownMessage m -> diagnosticHints m@@ -800,6 +811,7 @@ PsErrIllegalGadtRecordMultiplicity{} -> noHints PsErrInvalidCApiImport {} -> noHints PsErrMultipleConForNewtype {} -> noHints+ PsErrUnicodeCharLooksLike{} -> noHints diagnosticCode = constructorCode
compiler/GHC/Parser/Errors/Types.hs view
@@ -466,6 +466,11 @@ | PsErrMultipleConForNewtype !RdrName !Int + | PsErrUnicodeCharLooksLike+ Char -- ^ the problematic character+ Char -- ^ the character it looks like+ String -- ^ the name of the character that it looks like+ deriving Generic -- | Extra details about a parse error, which helps
compiler/GHC/Parser/Lexer.x view
@@ -274,6 +274,9 @@ "-- " / { atEOL } { lineCommentToken } +-- Everywhere: check for smart quotes--they are not allowed outside of strings+$unigraphic / { isSmartQuote } { smart_quote_error }+ -- 'bol' state: beginning of a line. Slurp up all the whitespace (including -- blank lines) until we find a non-whitespace character, then do layout -- processing.@@ -2037,7 +2040,8 @@ lex_quoted_label :: Action lex_quoted_label span _buf _len _buf2 = do- s <- lex_string_helper ""+ start <- getInput+ s <- lex_string_helper "" start (AI end _) <- getInput let token = ITlabelvarid (mkFastString s)@@ -2050,7 +2054,8 @@ lex_string :: P LexedString lex_string = do- s <- lex_string_helper ""+ start <- getInput+ s <- lex_string_helper "" start magicHash <- getBit MagicHashBit if magicHash then do@@ -2070,8 +2075,8 @@ return $ LexedRegularString s -lex_string_helper :: String -> P String-lex_string_helper s = do+lex_string_helper :: String -> AlexInput -> P String+lex_string_helper s start = do i <- getInput case alexGetChar' i of Nothing -> lit_error i@@ -2082,26 +2087,36 @@ Just ('\\',i) | Just ('&',i) <- next -> do- setInput i; lex_string_helper s+ setInput i; lex_string_helper s start | Just (c,i) <- next, c <= '\x7f' && is_space c -> do -- is_space only works for <= '\x7f' (#3751, #5425)- setInput i; lex_stringgap s+ setInput i; lex_stringgap s start where next = alexGetChar' i Just (c, i1) -> do case c of- '\\' -> do setInput i1; c' <- lex_escape; lex_string_helper (c':s)- c | isAny c -> do setInput i1; lex_string_helper (c:s)+ '\\' -> do setInput i1; c' <- lex_escape; lex_string_helper (c':s) start+ c | isAny c -> do setInput i1; lex_string_helper (c:s) start+ _other | any isDoubleSmartQuote s -> do+ -- if the built-up string s contains a smart double quote character, it was+ -- likely the reason why the string literal was not lexed correctly+ setInput start -- rewind to the first character in the string literal+ -- so we can find the smart quote character's location+ advance_to_smart_quote_character+ i2@(AI loc _) <- getInput+ case alexGetChar' i2 of+ Just (c, _) -> do add_nonfatal_smart_quote_error c loc; lit_error i+ Nothing -> lit_error i -- should never get here _other -> lit_error i -lex_stringgap :: String -> P String-lex_stringgap s = do+lex_stringgap :: String -> AlexInput -> P String+lex_stringgap s start = do i <- getInput c <- getCharOrFail i case c of- '\\' -> lex_string_helper s- c | c <= '\x7f' && is_space c -> lex_stringgap s+ '\\' -> lex_string_helper s start+ c | c <= '\x7f' && is_space c -> lex_stringgap s start -- is_space only works for <= '\x7f' (#3751, #5425) _other -> lit_error i @@ -2123,15 +2138,16 @@ setInput i2 return (L (mkPsSpan loc end2) ITtyQuote) - Just ('\\', i2@(AI _end2 _)) -> do -- We've seen 'backslash+ Just ('\\', i2@(AI end2 _)) -> do -- We've seen 'backslash setInput i2 lit_ch <- lex_escape i3 <- getInput mc <- getCharOrFail i3 -- Trailing quote if mc == '\'' then finish_char_tok buf loc lit_ch- else lit_error i3+ else if isSingleSmartQuote mc then add_smart_quote_error mc end2+ else lit_error i3 - Just (c, i2@(AI _end2 _))+ Just (c, i2@(AI end2 _)) | not (isAny c) -> lit_error i1 | otherwise -> @@ -2141,6 +2157,7 @@ Just ('\'', i3) -> do -- We've seen 'x' setInput i3 finish_char_tok buf loc c+ Just (c, _) | isSingleSmartQuote c -> add_smart_quote_error c end2 _other -> do -- We've seen 'x not followed by quote -- (including the possibility of EOF) -- Just parse the quote only@@ -2171,7 +2188,7 @@ lex_escape :: P Char lex_escape = do- i0 <- getInput+ i0@(AI loc _) <- getInput c <- getCharOrFail i0 case c of 'a' -> return '\a'@@ -2184,6 +2201,11 @@ '\\' -> return '\\' '"' -> return '\"' '\'' -> return '\''+ -- the next two patterns build up a Unicode smart quote error (#21843)+ smart_double_quote | isDoubleSmartQuote smart_double_quote ->+ add_smart_quote_error smart_double_quote loc+ smart_single_quote | isSingleSmartQuote smart_single_quote ->+ add_smart_quote_error smart_single_quote loc '^' -> do i1 <- getInput c <- getCharOrFail i1 if c >= '@' && c <= '_'@@ -2337,6 +2359,49 @@ (AI end buf) <- getInput reportLexError start (psRealLoc end) buf (\k srcLoc -> mkPlainErrorMsgEnvelope srcLoc (PsErrLexer LexUnterminatedQQ k))++-- -----------------------------------------------------------------------------+-- Unicode Smart Quote detection (#21843)++isDoubleSmartQuote :: Char -> Bool+isDoubleSmartQuote '“' = True+isDoubleSmartQuote '”' = True+isDoubleSmartQuote _ = False++isSingleSmartQuote :: Char -> Bool+isSingleSmartQuote '‘' = True+isSingleSmartQuote '’' = True+isSingleSmartQuote _ = False++isSmartQuote :: AlexAccPred ExtsBitmap+isSmartQuote _ _ _ (AI _ buf) = let c = prevChar buf ' ' in isSingleSmartQuote c || isDoubleSmartQuote c++smart_quote_error_message :: Char -> PsLoc -> MsgEnvelope PsMessage+smart_quote_error_message c loc =+ let (correct_char, correct_char_name) =+ if isSingleSmartQuote c then ('\'', "Single Quote") else ('"', "Quotation Mark")+ err = mkPlainErrorMsgEnvelope (mkSrcSpanPs (mkPsSpan loc loc)) $+ PsErrUnicodeCharLooksLike c correct_char correct_char_name in+ err++smart_quote_error :: Action+smart_quote_error span buf _len _buf2 = do+ let c = currentChar buf+ addFatalError (smart_quote_error_message c (psSpanStart span))++add_smart_quote_error :: Char -> PsLoc -> P a+add_smart_quote_error c loc = addFatalError (smart_quote_error_message c loc)++add_nonfatal_smart_quote_error :: Char -> PsLoc -> P ()+add_nonfatal_smart_quote_error c loc = addError (smart_quote_error_message c loc)++advance_to_smart_quote_character :: P ()+advance_to_smart_quote_character = do+ i <- getInput+ case alexGetChar' i of+ Just (c, _) | isDoubleSmartQuote c -> return ()+ Just (_, i2) -> do setInput i2; advance_to_smart_quote_character+ Nothing -> return () -- should never get here -- ----------------------------------------------------------------------------- -- Warnings
compiler/GHC/Parser/PostProcess.hs view
@@ -10,8 +10,6 @@ {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE DataKinds #-} -{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}- -- -- (c) The University of Glasgow 2002-2006 --@@ -137,10 +135,11 @@ import GHC.Parser.Errors.Ppr () import GHC.Utils.Lexeme ( okConOcc ) import GHC.Types.TyThing-import GHC.Core.Type ( unrestrictedFunTyCon, Specificity(..) )+import GHC.Core.Type ( Specificity(..) ) import GHC.Builtin.Types( cTupleTyConName, tupleTyCon, tupleDataCon, nilDataConName, nilDataConKey,- listTyConName, listTyConKey )+ listTyConName, listTyConKey,+ unrestrictedFunTyCon ) import GHC.Types.ForeignCall import GHC.Types.SrcLoc import GHC.Types.Unique ( hasKey )@@ -1816,7 +1815,7 @@ rejectPragmaPV _ = return () hsHoleExpr :: EpAnn EpAnnUnboundVar -> HsExpr GhcPs-hsHoleExpr anns = HsUnboundVar anns (mkVarOcc "_")+hsHoleExpr anns = HsUnboundVar anns (mkVarOccFS (fsLit "_")) type instance Anno (GRHS GhcPs (LocatedA (PatBuilder GhcPs))) = SrcAnn NoEpAnns type instance Anno [LocatedA (Match GhcPs (LocatedA (PatBuilder GhcPs)))] = SrcSpanAnnL
compiler/GHC/Platform.hs view
@@ -206,6 +206,7 @@ osElfTarget OSQNXNTO = False osElfTarget OSAIX = False osElfTarget OSHurd = True+osElfTarget OSWasi = False osElfTarget OSUnknown = False -- Defaulting to False is safe; it means don't rely on any -- ELF-specific functionality. It is important to have a default for
compiler/GHC/Platform/Regs.hs view
@@ -15,6 +15,7 @@ import qualified GHC.Platform.X86 as X86 import qualified GHC.Platform.X86_64 as X86_64 import qualified GHC.Platform.RISCV64 as RISCV64+import qualified GHC.Platform.Wasm32 as Wasm32 import qualified GHC.Platform.NoRegs as NoRegs -- | Returns 'True' if this global register is stored in a caller-saves@@ -31,6 +32,7 @@ ArchARM {} -> ARM.callerSaves ArchAArch64 -> AArch64.callerSaves ArchRISCV64 -> RISCV64.callerSaves+ ArchWasm32 -> Wasm32.callerSaves arch | arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] -> PPC.callerSaves@@ -53,6 +55,7 @@ ArchARM {} -> ARM.activeStgRegs ArchAArch64 -> AArch64.activeStgRegs ArchRISCV64 -> RISCV64.activeStgRegs+ ArchWasm32 -> Wasm32.activeStgRegs arch | arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] -> PPC.activeStgRegs@@ -70,6 +73,7 @@ ArchARM {} -> ARM.haveRegBase ArchAArch64 -> AArch64.haveRegBase ArchRISCV64 -> RISCV64.haveRegBase+ ArchWasm32 -> Wasm32.haveRegBase arch | arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] -> PPC.haveRegBase@@ -87,6 +91,7 @@ ArchARM {} -> ARM.globalRegMaybe ArchAArch64 -> AArch64.globalRegMaybe ArchRISCV64 -> RISCV64.globalRegMaybe+ ArchWasm32 -> Wasm32.globalRegMaybe arch | arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] -> PPC.globalRegMaybe@@ -104,6 +109,7 @@ ArchARM {} -> ARM.freeReg ArchAArch64 -> AArch64.freeReg ArchRISCV64 -> RISCV64.freeReg+ ArchWasm32 -> Wasm32.freeReg arch | arch `elem` [ArchPPC, ArchPPC_64 ELF_V1, ArchPPC_64 ELF_V2] -> PPC.freeReg
+ compiler/GHC/Platform/Wasm32.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE CPP #-}++module GHC.Platform.Wasm32 where++import GHC.Prelude++-- TODO+#define MACHREGS_NO_REGS 1+-- #define MACHREGS_wasm32 1+#include "CodeGen.Platform.h"
compiler/GHC/Prelude.hs view
@@ -13,10 +13,8 @@ -- * Explicitly imports GHC.Prelude module GHC.Prelude- (module X- ,Applicative (..)- ,module Bits- ,shiftL, shiftR+ (module GHC.Prelude+ ,module GHC.Utils.Trace ) where @@ -48,55 +46,7 @@ extensions. -} -import Prelude as X hiding ((<>), Applicative(..))-import Control.Applicative (Applicative(..))-import Data.Foldable as X (foldl')--#if MIN_VERSION_base(4,16,0)-import GHC.Bits as Bits hiding (shiftL, shiftR)-# if defined(DEBUG)-import qualified GHC.Bits as Bits (shiftL, shiftR)-# endif--#else---base <4.15-import Data.Bits as Bits hiding (shiftL, shiftR)-# if defined(DEBUG)-import qualified Data.Bits as Bits (shiftL, shiftR)-# endif-#endif--{- Note [Default to unsafe shifts inside GHC]- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The safe shifts can introduce branches which come-at the cost of performance. We still want the additional-debugability for debug builds. So we define it as one or the-other depending on the DEBUG setting.--Why do we then continue on to re-export the rest of Data.Bits?-If we would not what is likely to happen is:-* Someone imports Data.Bits, uses xor. Things are fine.-* They add a shift and get an ambiguous definition error.-* The are puzzled for a bit.-* They either:- + Remove the import of Data.Bits and get an error because xor is not in scope.- + Add the hiding clause to the Data.Bits import for the shifts.--Either is quite annoying. Simply re-exporting all of Data.Bits avoids this-making for a smoother developer experience. At the cost of having a few more-names in scope at all time. But that seems like a fair tradeoff.--See also #19618--}+import GHC.Prelude.Basic as GHC.Prelude --- We always want the Data.Bits method to show up for rules etc.-{-# INLINE shiftL #-}-{-# INLINE shiftR #-}-shiftL, shiftR :: Bits.Bits a => a -> Int -> a-#if defined(DEBUG)-shiftL = Bits.shiftL-shiftR = Bits.shiftR-#else-shiftL = Bits.unsafeShiftL-shiftR = Bits.unsafeShiftR-#endif+-- import {-# SOURCE #-} GHC.Utils.Trace+import GHC.Utils.Trace hiding ( trace )
+ compiler/GHC/Prelude/Basic.hs view
@@ -0,0 +1,104 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_HADDOCK not-home #-}+{-# OPTIONS_GHC -O2 #-} -- See Note [-O2 Prelude]++-- | Custom minimal GHC "Prelude"+--+-- This module serves as a replacement for the "Prelude" module+-- and abstracts over differences between the bootstrapping+-- GHC version, and may also provide a common default vocabulary.++-- Every module in GHC+-- * Is compiled with -XNoImplicitPrelude+-- * Explicitly imports GHC.BasicPrelude or GHC.Prelude+-- * The later provides some functionality with within ghc itself+-- like pprTrace.++module GHC.Prelude.Basic+ (module X+ ,Applicative (..)+ ,module Bits+ ,shiftL, shiftR+ ) where+++{- Note [-O2 Prelude]+~~~~~~~~~~~~~~~~~~~~~+There is some code in GHC that is *always* compiled with -O[2] because+of it's impact on compile time performance. Some of this code might depend+on the definitions like shiftL being defined here being performant.++So we always compile this module with -O2. It's (currently) tiny so I+have little reason to suspect this impacts overall GHC compile times+negatively.++-}+-- We export the 'Semigroup' class but w/o the (<>) operator to avoid+-- clashing with the (Outputable.<>) operator which is heavily used+-- through GHC's code-base.++{-+Note [Why do we import Prelude here?]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The files ghc-boot-th.cabal, ghc-boot.cabal, ghci.cabal and+ghc-heap.cabal contain the directive default-extensions:+NoImplicitPrelude. There are two motivations for this:+ - Consistency with the compiler directory, which enables+ NoImplicitPrelude;+ - Allows loading the above dependent packages with ghc-in-ghci,+ giving a smoother development experience when adding new+ extensions.+-}++import Prelude as X hiding ((<>), Applicative(..))+import Control.Applicative (Applicative(..))+import Data.Foldable as X (foldl')++#if MIN_VERSION_base(4,16,0)+import GHC.Bits as Bits hiding (shiftL, shiftR)+# if defined(DEBUG)+import qualified GHC.Bits as Bits (shiftL, shiftR)+# endif++#else+--base <4.15+import Data.Bits as Bits hiding (shiftL, shiftR)+# if defined(DEBUG)+import qualified Data.Bits as Bits (shiftL, shiftR)+# endif+#endif++{- Note [Default to unsafe shifts inside GHC]+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+The safe shifts can introduce branches which come+at the cost of performance. We still want the additional+debugability for debug builds. So we define it as one or the+other depending on the DEBUG setting.++Why do we then continue on to re-export the rest of Data.Bits?+If we would not what is likely to happen is:+* Someone imports Data.Bits, uses xor. Things are fine.+* They add a shift and get an ambiguous definition error.+* The are puzzled for a bit.+* They either:+ + Remove the import of Data.Bits and get an error because xor is not in scope.+ + Add the hiding clause to the Data.Bits import for the shifts.++Either is quite annoying. Simply re-exporting all of Data.Bits avoids this+making for a smoother developer experience. At the cost of having a few more+names in scope at all time. But that seems like a fair tradeoff.++See also #19618+-}++-- We always want the Data.Bits method to show up for rules etc.+{-# INLINE shiftL #-}+{-# INLINE shiftR #-}+shiftL, shiftR :: Bits.Bits a => a -> Int -> a+#if defined(DEBUG)+shiftL = Bits.shiftL+shiftR = Bits.shiftR+#else+shiftL = Bits.unsafeShiftL+shiftR = Bits.unsafeShiftR+#endif
compiler/GHC/Runtime/Context.hs view
@@ -10,7 +10,7 @@ , icReaderEnv , icInteractiveModule , icInScopeTTs- , icPrintUnqual+ , icNamePprCtx ) where @@ -349,9 +349,10 @@ ] --- | Get the PrintUnqualified function based on the flags and this InteractiveContext-icPrintUnqual :: UnitEnv -> InteractiveContext -> PrintUnqualified-icPrintUnqual unit_env ictxt = mkPrintUnqualified unit_env (icReaderEnv ictxt)+-- | Get the NamePprCtx function based on the flags and this InteractiveContext+icNamePprCtx :: UnitEnv -> InteractiveContext -> NamePprCtx+icNamePprCtx unit_env ictxt = mkNamePprCtx ptc unit_env (icReaderEnv ictxt)+ where ptc = initPromotionTickContext (ic_dflags ictxt) -- | extendInteractiveContext is called with new TyThings recently defined to update the -- InteractiveContext to include them. By putting new things first, unqualified
compiler/GHC/Settings/Constants.hs view
@@ -17,8 +17,8 @@ mAX_CTUPLE_SIZE :: Int -- Constraint tuples mAX_CTUPLE_SIZE = 64 -- Should match the number of decls in GHC.Classes -mAX_SUM_SIZE :: Int-mAX_SUM_SIZE = 64+mAX_SUM_SIZE :: Int -- We use 6 bits to record sum size,+mAX_SUM_SIZE = 63 -- so max sum size is 63. Sadly inconsistent. -- | Default maximum depth for both class instance search and type family -- reduction. See also #5395.
compiler/GHC/Stg/Syntax.hs view
@@ -61,7 +61,7 @@ -- ppr StgPprOpts(..), panicStgPprOpts, shortStgPprOpts,- pprStgArg, pprStgExpr, pprStgRhs, pprStgBinding,+ pprStgArg, pprStgExpr, pprStgRhs, pprStgBinding, pprStgAlt, pprGenStgTopBinding, pprStgTopBinding, pprGenStgTopBindings, pprStgTopBindings ) where@@ -87,7 +87,7 @@ import GHC.Builtin.PrimOps ( PrimOp, PrimCall ) import GHC.Core.TyCon ( PrimRep(..), TyCon ) import GHC.Core.Type ( Type )-import GHC.Types.RepType ( typePrimRep1 )+import GHC.Types.RepType ( typePrimRep1, typePrimRep ) import GHC.Utils.Panic.Plain {-@@ -740,12 +740,23 @@ pprStgTopBindings :: OutputablePass pass => StgPprOpts -> [GenStgTopBinding pass] -> SDoc pprStgTopBindings = pprGenStgTopBindings +pprIdWithRep :: Id -> SDoc+pprIdWithRep v = ppr v <> pprTypeRep (idType v)++pprTypeRep :: Type -> SDoc+pprTypeRep ty =+ ppUnlessOption sdocSuppressStgReps $+ char ':' <> case typePrimRep ty of+ [r] -> ppr r+ r -> ppr r++ instance Outputable StgArg where ppr = pprStgArg pprStgArg :: StgArg -> SDoc-pprStgArg (StgVarArg var) = ppr var-pprStgArg (StgLitArg con) = ppr con+pprStgArg (StgVarArg var) = pprIdWithRep var+pprStgArg (StgLitArg con) = ppr con <> pprTypeRep (literalType con) instance OutputablePass pass => Outputable (GenStgExpr pass) where ppr = pprStgExpr panicStgPprOpts
compiler/GHC/Tc/Errors/Ppr.hs view
@@ -25,8 +25,7 @@ import GHC.Prelude import GHC.Builtin.Names-import GHC.Builtin.Types (boxedRepDataConTyCon)-import GHC.Builtin.Types.Prim (tYPETyCon)+import GHC.Builtin.Types ( boxedRepDataConTyCon, tYPETyCon ) import GHC.Core.Coercion import GHC.Core.Unify ( tcMatchTys )@@ -1018,6 +1017,7 @@ TcRnTypeDataForbids feature -> mkSimpleDecorated $ ppr feature <+> text "are not allowed in type data declarations."+ TcRnIllegalNewtype con show_linear_types reason -> mkSimpleDecorated $ vcat [msg, additional]@@ -1036,7 +1036,8 @@ ppr con <+> dcolon <+> ppr (dataConDisplayType True con)) IsGADT -> (text "A newtype must not be a GADT",- ppr con <+> dcolon <+> pprWithExplicitKindsWhen sneaky_eq_spec (ppr $ dataConDisplayType show_linear_types con))+ ppr con <+> dcolon <+> pprWithExplicitKindsWhen sneaky_eq_spec+ (ppr $ dataConDisplayType show_linear_types con)) HasConstructorContext -> (text "A newtype constructor must not have a context in its type", ppr con <+> dcolon <+> ppr (dataConDisplayType show_linear_types con))@@ -1046,12 +1047,10 @@ HasStrictnessAnnotation -> (text "A newtype constructor must not have a strictness annotation", empty) - -- Is there an EqSpec involving an invisible binder? If so, print the- -- error message with explicit kinds.- invisible_binders = filter isInvisibleTyConBinder (tyConBinders $ dataConTyCon con)- sneaky_eq_spec- = any (\eq -> any (( == eqSpecTyVar eq) . binderVar) invisible_binders)- $ dataConEqSpec con+ -- Is the data con a "covert" GADT? See Note [isCovertGadtDataCon]+ -- in GHC.Core.DataCon+ sneaky_eq_spec = isCovertGadtDataCon con+ TcRnTypedTHWithPolyType ty -> mkSimpleDecorated $ vcat [ text "Illegal polytype:" <+> ppr ty@@ -1154,7 +1153,78 @@ False -> text (TH.pprint item)) TcRnReportCustomQuasiError _ msg -> mkSimpleDecorated $ text msg TcRnInterfaceLookupError _ sdoc -> mkSimpleDecorated sdoc+ TcRnUnsatisfiedMinimalDef mindef+ -> mkSimpleDecorated $+ vcat [text "No explicit implementation for"+ ,nest 2 $ pprBooleanFormulaNice mindef+ ]+ TcRnMisplacedInstSig name hs_ty+ -> mkSimpleDecorated $+ vcat [ hang (text "Illegal type signature in instance declaration:")+ 2 (hang (pprPrefixName name)+ 2 (dcolon <+> ppr hs_ty))+ ]+ TcRnBadBootFamInstDecl {}+ -> mkSimpleDecorated $+ text "Illegal family instance in hs-boot file"+ TcRnIllegalFamilyInstance tycon+ -> mkSimpleDecorated $+ vcat [ text "Illegal family instance for" <+> quotes (ppr tycon)+ , nest 2 $ parens (ppr tycon <+> text "is not an indexed type family")]+ TcRnMissingClassAssoc name+ -> mkSimpleDecorated $+ text "Associated type" <+> quotes (ppr name) <+>+ text "must be inside a class instance"+ TcRnBadFamInstDecl tc_name+ -> mkSimpleDecorated $+ text "Illegal family instance for" <+> quotes (ppr tc_name)+ TcRnNotOpenFamily tc+ -> mkSimpleDecorated $+ text "Illegal instance for closed family" <+> quotes (ppr tc)+ TcRnNoRebindableSyntaxRecordDot -> mkSimpleDecorated $+ text "RebindableSyntax is required if OverloadedRecordUpdate is enabled."+ TcRnNoFieldPunsRecordDot -> mkSimpleDecorated $+ text "For this to work enable NamedFieldPuns"+ TcRnIllegalStaticExpression e -> mkSimpleDecorated $+ text "Illegal static expression:" <+> ppr e+ TcRnIllegalStaticFormInSplice e -> mkSimpleDecorated $+ sep [ text "static forms cannot be used in splices:"+ , nest 2 $ ppr e+ ]+ TcRnListComprehensionDuplicateBinding n -> mkSimpleDecorated $+ (text "Duplicate binding in parallel list comprehension for:"+ <+> quotes (ppr n))+ TcRnEmptyStmtsGroup cause -> mkSimpleDecorated $ case cause of+ EmptyStmtsGroupInParallelComp ->+ text "Empty statement group in parallel comprehension"+ EmptyStmtsGroupInTransformListComp ->+ text "Empty statement group preceding 'group' or 'then'"+ EmptyStmtsGroupInDoNotation ctxt ->+ text "Empty" <+> pprHsDoFlavour ctxt+ EmptyStmtsGroupInArrowNotation ->+ text "Empty 'do' block in an arrow command"+ TcRnLastStmtNotExpr ctxt (UnexpectedStatement stmt) ->+ mkSimpleDecorated $ hang last_error 2 (ppr stmt)+ where+ last_error =+ text "The last statement in" <+> pprAStmtContext ctxt+ <+> text "must be an expression"+ TcRnUnexpectedStatementInContext ctxt (UnexpectedStatement stmt) _ -> mkSimpleDecorated $+ sep [ text "Unexpected" <+> pprStmtCat stmt <+> text "statement"+ , text "in" <+> pprAStmtContext ctxt ]+ TcRnIllegalTupleSection -> mkSimpleDecorated $+ text "Illegal tuple section"+ TcRnIllegalImplicitParameterBindings eBinds -> mkSimpleDecorated $+ either msg msg eBinds+ where+ msg binds = hang+ (text "Implicit-parameter bindings illegal in an mdo expression")+ 2 (ppr binds)+ TcRnSectionWithoutParentheses expr -> mkSimpleDecorated $+ hang (text "A section must be enclosed in parentheses")+ 2 (text "thus:" <+> (parens (ppr expr))) + diagnosticReason = \case TcRnUnknownMessage m -> diagnosticReason m@@ -1522,6 +1592,42 @@ -> if isError then ErrorWithoutFlag else WarningWithoutFlag TcRnInterfaceLookupError{} -> ErrorWithoutFlag+ TcRnUnsatisfiedMinimalDef{}+ -> WarningWithFlag (Opt_WarnMissingMethods)+ TcRnMisplacedInstSig{}+ -> ErrorWithoutFlag+ TcRnBadBootFamInstDecl{}+ -> ErrorWithoutFlag+ TcRnIllegalFamilyInstance{}+ -> ErrorWithoutFlag+ TcRnMissingClassAssoc{}+ -> ErrorWithoutFlag+ TcRnBadFamInstDecl{}+ -> ErrorWithoutFlag+ TcRnNotOpenFamily{}+ -> ErrorWithoutFlag+ TcRnNoRebindableSyntaxRecordDot{}+ -> ErrorWithoutFlag+ TcRnNoFieldPunsRecordDot{}+ -> ErrorWithoutFlag+ TcRnIllegalStaticExpression{}+ -> ErrorWithoutFlag+ TcRnIllegalStaticFormInSplice{}+ -> ErrorWithoutFlag+ TcRnListComprehensionDuplicateBinding{}+ -> ErrorWithoutFlag+ TcRnEmptyStmtsGroup{}+ -> ErrorWithoutFlag+ TcRnLastStmtNotExpr{}+ -> ErrorWithoutFlag+ TcRnUnexpectedStatementInContext{}+ -> ErrorWithoutFlag+ TcRnSectionWithoutParentheses{}+ -> ErrorWithoutFlag+ TcRnIllegalImplicitParameterBindings{}+ -> ErrorWithoutFlag+ TcRnIllegalTupleSection{}+ -> ErrorWithoutFlag diagnosticHints = \case TcRnUnknownMessage m@@ -1892,7 +1998,47 @@ -> noHints TcRnInterfaceLookupError{} -> noHints+ TcRnUnsatisfiedMinimalDef{}+ -> noHints+ TcRnMisplacedInstSig{}+ -> [suggestExtension LangExt.InstanceSigs]+ TcRnBadBootFamInstDecl{}+ -> noHints+ TcRnIllegalFamilyInstance{}+ -> noHints+ TcRnMissingClassAssoc{}+ -> noHints+ TcRnBadFamInstDecl{}+ -> [suggestExtension LangExt.TypeFamilies]+ TcRnNotOpenFamily{}+ -> noHints+ TcRnNoRebindableSyntaxRecordDot{}+ -> noHints+ TcRnNoFieldPunsRecordDot{}+ -> noHints+ TcRnIllegalStaticExpression{}+ -> [suggestExtension LangExt.StaticPointers]+ TcRnIllegalStaticFormInSplice{}+ -> noHints+ TcRnListComprehensionDuplicateBinding{}+ -> noHints+ TcRnEmptyStmtsGroup EmptyStmtsGroupInDoNotation{}+ -> [suggestExtension LangExt.NondecreasingIndentation]+ TcRnEmptyStmtsGroup{}+ -> noHints+ TcRnLastStmtNotExpr{}+ -> noHints+ TcRnUnexpectedStatementInContext _ _ mExt+ | Nothing <- mExt -> noHints+ | Just ext <- mExt -> [suggestExtension ext]+ TcRnSectionWithoutParentheses{}+ -> noHints+ TcRnIllegalImplicitParameterBindings{}+ -> noHints+ TcRnIllegalTupleSection{}+ -> [suggestExtension LangExt.TupleSections] + diagnosticCode = constructorCode -- | Change [x] to "x", [x, y] to "x and y", [x, y, z] to "x, y, and z",@@ -2023,7 +2169,7 @@ = (bullet <+> ppr tidy_ty <+> dcolon <+> ppr tidy_ki) where (tidy_env, tidy_ty) = tidyOpenType emptyTidyEnv ty- tidy_ki = tidyType tidy_env (tcTypeKind ty)+ tidy_ki = tidyType tidy_env (typeKind ty) pprField :: (FieldLabelString, TcType) -> SDoc pprField (f,ty) = ppr f <+> dcolon <+> ppr ty@@ -2322,8 +2468,8 @@ pprHoleError ctxt hole err pprTcSolverReportMsg ctxt (CannotUnifyVariable- { mismatchMsg = msg- , cannotUnifyReason = reason })+ { mismatchMsg = msg+ , cannotUnifyReason = reason }) = pprMismatchMsg ctxt msg $$ pprCannotUnifyVariableReason ctxt reason pprTcSolverReportMsg ctxt@@ -2522,7 +2668,7 @@ , not (isTypeFamilyTyCon tc) = hang (text "GHC can't yet do polykinded") 2 (text "Typeable" <+>- parens (ppr ty <+> dcolon <+> ppr (tcTypeKind ty)))+ parens (ppr ty <+> dcolon <+> ppr (typeKind ty))) | otherwise = empty @@ -2675,13 +2821,14 @@ pprMismatchMsg ctxt (BasicMismatch { mismatch_ea = ea , mismatch_item = item- , mismatch_ty1 = ty1- , mismatch_ty2 = ty2+ , mismatch_ty1 = ty1 -- Expected+ , mismatch_ty2 = ty2 -- Actual , mismatch_whenMatching = mb_match_txt , mismatch_mb_same_occ = same_occ_info })- = addArising (errorItemCtLoc item) msg- $$ maybe empty (pprWhenMatching ctxt) mb_match_txt- $$ maybe empty pprSameOccInfo same_occ_info+ = vcat [ addArising (errorItemCtLoc item) msg+ , ea_extra+ , maybe empty (pprWhenMatching ctxt) mb_match_txt+ , maybe empty pprSameOccInfo same_occ_info ] where msg | (isLiftedRuntimeRep ty1 && isUnliftedRuntimeRep ty2) ||@@ -2702,18 +2849,20 @@ , nest padding $ text herald2 <> colon <+> ppr ty2 ] - want_ea = case ea of { NoEA -> False; EA {} -> True }- herald1 = conc [ "Couldn't match" , if is_repr then "representation of" else "" , if want_ea then "expected" else "" , what ] herald2 = conc [ "with"- , if is_repr then "that of" else ""+ , if is_repr then "that of" else "" , if want_ea then ("actual " ++ what) else "" ] padding = length herald1 - length herald2 + (want_ea, ea_extra)+ = case ea of+ NoEA -> (False, empty)+ EA mb_extra -> (True , maybe empty (pprExpectedActualInfo ctxt) mb_extra) is_repr = case errorItemEqRel item of { ReprEq -> True; NomEq -> False } what = levelString (ctLocTypeOrKind_maybe (errorItemCtLoc item) `orElse` TypeLevel)@@ -2733,7 +2882,7 @@ 2 (text "but" <+> quotes (ppr thing) <+> text "has kind" <+> quotes (ppr act)) where- kind_desc | tcIsConstraintKind exp = text "a constraint"+ kind_desc | isConstraintLikeKind exp = text "a constraint" | Just arg <- kindRep_maybe exp -- TYPE t0 , tcIsTyVarTy arg = sdocOption sdocPrintExplicitRuntimeReps $ \case True -> text "kind" <+> quotes (ppr exp)@@ -2743,53 +2892,78 @@ pprMismatchMsg ctxt (TypeEqMismatch { teq_mismatch_ppr_explicit_kinds = ppr_explicit_kinds , teq_mismatch_item = item- , teq_mismatch_ty1 = ty1- , teq_mismatch_ty2 = ty2- , teq_mismatch_expected = exp- , teq_mismatch_actual = act+ , 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)+ = addArising ct_loc $ pprWithExplicitKindsWhen ppr_explicit_kinds msg $$ maybe empty pprSameOccInfo mb_same_occ where- msg- | isUnliftedTypeKind act, isLiftedTypeKind exp- = sep [ text "Expecting a lifted type, but"- , thing_msg mb_thing (text "an") (text "unlifted") ]- | isLiftedTypeKind act, isUnliftedTypeKind exp- = sep [ text "Expecting an unlifted type, but"- , thing_msg mb_thing (text "a") (text "lifted") ]- | tcIsLiftedTypeKind exp- = maybe_num_args_msg $$- sep [ text "Expected a type, but"- , case mb_thing of+ msg | Just (torc, rep) <- sORTKind_maybe exp+ = msg_for_exp_sort torc rep++ | Just nargs_msg <- num_args_msg+ , Right ea_msg <- mk_ea_msg ctxt (Just item) level orig+ = nargs_msg $$ pprMismatchMsg ctxt ea_msg++ | ea_looks_same ty1 ty2 exp act+ , Right ea_msg <- mk_ea_msg ctxt (Just item) level orig+ = pprMismatchMsg ctxt ea_msg++ | otherwise+ = bale_out_msg++ -- bale_out_msg: the mismatched types are /inside/ exp and act+ bale_out_msg = vcat errs+ where+ errs = case mk_ea_msg ctxt Nothing level orig of+ Left ea_info -> pprMismatchMsg ctxt mismatch_err+ : map (pprExpectedActualInfo ctxt) ea_info+ Right ea_err -> [ pprMismatchMsg ctxt mismatch_err+ , pprMismatchMsg ctxt ea_err ]+ mismatch_err = mkBasicMismatchMsg NoEA item ty1 ty2++ -- 'expected' is (TYPE rep) or (CONSTRAINT rep)+ msg_for_exp_sort exp_torc exp_rep+ | Just (act_torc, act_rep) <- sORTKind_maybe act+ = -- (TYPE exp_rep) ~ (CONSTRAINT act_rep) etc+ msg_torc_torc act_torc act_rep+ | otherwise+ = -- (TYPE _) ~ Bool, etc+ maybe_num_args_msg $$+ sep [ text "Expected a" <+> ppr_torc exp_torc <> comma+ , text "but" <+> case mb_thing of Nothing -> text "found something with kind" Just thing -> quotes (ppr thing) <+> text "has kind" , quotes (pprWithTYPE act) ]- | Just nargs_msg <- num_args_msg- , Right ea_msg <- mk_ea_msg ctxt (Just item) level orig- = nargs_msg $$ pprMismatchMsg ctxt ea_msg- | -- pprTrace "check" (ppr ea_looks_same $$ ppr exp $$ ppr act $$ ppr ty1 $$ ppr ty2) $- ea_looks_same ty1 ty2 exp act- , Right ea_msg <- mk_ea_msg ctxt (Just item) level orig- = pprMismatchMsg ctxt ea_msg - | otherwise- =- -- The mismatched types are /inside/ exp and act- let mismatch_err = mkBasicMismatchMsg NoEA item ty1 ty2- errs = case mk_ea_msg ctxt Nothing level orig of- Left ea_info -> pprMismatchMsg ctxt mismatch_err : map (pprExpectedActualInfo ctxt) ea_info- Right ea_err -> [ pprMismatchMsg ctxt mismatch_err, pprMismatchMsg ctxt ea_err ]- in vcat errs+ where+ msg_torc_torc act_torc act_rep+ | exp_torc == act_torc+ = msg_same_torc act_torc act_rep+ | otherwise+ = sep [ text "Expected a" <+> ppr_torc exp_torc <> comma+ , text "but" <+> case mb_thing of+ Nothing -> text "found a"+ Just thing -> quotes (ppr thing) <+> text "is a"+ <+> ppr_torc act_torc ] + msg_same_torc act_torc act_rep+ | Just exp_doc <- describe_rep exp_rep+ , Just act_doc <- describe_rep act_rep+ = sep [ text "Expected" <+> exp_doc <+> ppr_torc exp_torc <> comma+ , text "but" <+> case mb_thing of+ Just thing -> quotes (ppr thing) <+> text "is"+ Nothing -> text "got"+ <+> act_doc <+> ppr_torc act_torc ]+ msg_same_torc _ _ = bale_out_msg+ ct_loc = errorItemCtLoc item orig = errorItemOrigin item level = ctLocTypeOrKind_maybe ct_loc `orElse` TypeLevel - thing_msg (Just thing) _ levity = quotes (ppr thing) <+> text "is" <+> levity- thing_msg Nothing an levity = text "got" <+> an <+> levity <+> text "type"- num_args_msg = case level of KindLevel | not (isMetaTyVarTy exp) && not (isMetaTyVarTy act)@@ -2809,8 +2983,35 @@ maybe_num_args_msg = num_args_msg `orElse` empty - count_args ty = count isVisibleBinder $ fst $ splitPiTys ty+ count_args ty = count isVisiblePiTyBinder $ fst $ splitPiTys ty + ppr_torc TypeLike = text "type";+ ppr_torc ConstraintLike = text "constraint"++ describe_rep :: RuntimeRepType -> Maybe SDoc+ -- describe_rep IntRep = Just "an IntRep"+ -- describe_rep (BoxedRep Lifted) = Just "a lifted"+ -- etc+ describe_rep rep+ | Just (rr_tc, rr_args) <- splitRuntimeRep_maybe rep+ = case rr_args of+ [lev_ty] | rr_tc `hasKey` boxedRepDataConKey+ , Just lev <- levityType_maybe lev_ty+ -> case lev of+ Lifted -> Just (text "a lifted")+ Unlifted -> Just (text "a boxed unlifted")+ [] | rr_tc `hasKey` tupleRepDataConTyConKey -> Just (text "a zero-bit")+ | starts_with_vowel rr_occ -> Just (text "an" <+> text rr_occ)+ | otherwise -> Just (text "a" <+> text rr_occ)+ where+ rr_occ = occNameString (getOccName rr_tc)++ _ -> Nothing -- Must be TupleRep [r1..rn]+ | otherwise = Nothing++ starts_with_vowel (c:_) = c `elem` "AEIOU"+ starts_with_vowel [] = False+ pprMismatchMsg ctxt (CouldNotDeduce useful_givens (item :| others) mb_extra) = main_msg $$ case supplementary of@@ -3084,9 +3285,9 @@ || not (cty1 `pickyEqType` cty2) then vcat [ hang (text "When matching" <+> sub_whats) 2 (vcat [ ppr cty1 <+> dcolon <+>- ppr (tcTypeKind cty1)+ ppr (typeKind cty1) , ppr cty2 <+> dcolon <+>- ppr (tcTypeKind cty2) ])+ ppr (typeKind cty2) ]) , supplementary ] else text "When matching the kind of" <+> quotes (ppr cty1) where@@ -3186,7 +3387,7 @@ hang (text "Found extra-constraints wildcard standing for") 2 (quotes $ pprType hole_ty) -- always kind constraint - hole_kind = tcTypeKind hole_ty+ hole_kind = typeKind hole_ty pp_hole_type_with_kind | isLiftedTypeKind hole_kind@@ -3470,10 +3671,11 @@ where (env', tv') = tidy_tv_bndr env tv - tidy_ty env ty@(FunTy InvisArg w arg res) -- Look under c => t- = ty { ft_mult = tidy_ty env w,- ft_arg = tidyType env arg,- ft_res = tidy_ty env res }+ tidy_ty env ty@(FunTy af w arg res) -- Look under c => t+ | isInvisibleFunArg af+ = ty { ft_mult = tidy_ty env w+ , ft_arg = tidyType env arg+ , ft_res = tidy_ty env res } tidy_ty env ty = tidyType env ty @@ -3716,7 +3918,7 @@ -- -- `tyExpansions (M T10)` returns [Maybe T10] (T10 is not expanded) tyExpansions :: Type -> [Type]- tyExpansions = unfoldr (\t -> (\x -> (x, x)) `fmap` tcView t)+ tyExpansions = unfoldr (\t -> (\x -> (x, x)) `fmap` coreView t) -- Drop the type pairs until types in a pair look alike (i.e. the outer -- constructors are the same).
compiler/GHC/Tc/Errors/Types.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE KindSignatures #-} @@ -85,6 +86,8 @@ , RunSpliceFailReason(..) , ThingBeingConverted(..) , IllegalDecls(..)+ , EmptyStatementGroupErrReason(..)+ , UnexpectedStatement(..) ) where import GHC.Prelude@@ -2545,6 +2548,220 @@ -} TcRnInterfaceLookupError :: !Name -> !SDoc -> TcRnMessage + {- | TcRnUnsatisfiedMinimalDef is a warning that occurs when a class instance+ is missing methods that are required by the minimal definition.++ Example:+ class C a where+ foo :: a -> a+ instance C () -- | foo needs to be defined here++ Test cases:+ testsuite/tests/typecheck/prog001/typecheck.prog001+ testsuite/tests/typecheck/should_compile/tc126+ testsuite/tests/typecheck/should_compile/T7903+ testsuite/tests/typecheck/should_compile/tc116+ testsuite/tests/typecheck/should_compile/tc175+ testsuite/tests/typecheck/should_compile/HasKey+ testsuite/tests/typecheck/should_compile/tc125+ testsuite/tests/typecheck/should_compile/tc078+ testsuite/tests/typecheck/should_compile/tc161+ testsuite/tests/typecheck/should_fail/T5051+ testsuite/tests/typecheck/should_fail/T21583+ testsuite/tests/backpack/should_compile/bkp47+ testsuite/tests/backpack/should_fail/bkpfail25+ testsuite/tests/parser/should_compile/T2245+ testsuite/tests/parser/should_compile/read014+ testsuite/tests/indexed-types/should_compile/Class3+ testsuite/tests/indexed-types/should_compile/Simple2+ testsuite/tests/indexed-types/should_fail/T7862+ testsuite/tests/deriving/should_compile/deriving-1935+ testsuite/tests/deriving/should_compile/T9968a+ testsuite/tests/deriving/should_compile/drv003+ testsuite/tests/deriving/should_compile/T4966+ testsuite/tests/deriving/should_compile/T14094+ testsuite/tests/perf/compiler/T15304+ testsuite/tests/warnings/minimal/WarnMinimal+ testsuite/tests/simplCore/should_compile/simpl020+ testsuite/tests/deSugar/should_compile/T14546d+ testsuite/tests/ghci/scripts/T5820+ testsuite/tests/ghci/scripts/ghci019+ -}+ TcRnUnsatisfiedMinimalDef :: ClassMinimalDef -> TcRnMessage++ {- | 'TcRnMisplacedInstSig' is an error that happens when a method in+ a class instance is given a type signature, but the user has not+ enabled the @InstanceSigs@ extension.++ Test case:+ testsuite/tests/module/mod45+ -}+ TcRnMisplacedInstSig :: Name -> (LHsSigType GhcRn) -> TcRnMessage+ {- | 'TcRnBadBootFamInstDecl' is an error that is triggered by a+ type family instance being declared in an hs-boot file.++ Test case:+ testsuite/tests/indexed-types/should_fail/HsBootFam+ -}+ TcRnBadBootFamInstDecl :: {} -> TcRnMessage+ {- | 'TcRnIllegalFamilyInstance' is an error that occurs when an associated+ type or data family is given a top-level instance.++ Test case:+ testsuite/tests/indexed-types/should_fail/T3092+ -}+ TcRnIllegalFamilyInstance :: TyCon -> TcRnMessage+ {- | 'TcRnMissingClassAssoc' is an error that occurs when a class instance+ for a class with an associated type or data family is missing a corresponding+ family instance declaration.++ Test case:+ testsuite/tests/indexed-types/should_fail/SimpleFail7+ -}+ TcRnMissingClassAssoc :: TyCon -> TcRnMessage+ {- | 'TcRnBadFamInstDecl' is an error that is triggered by a type or data family+ instance without the @TypeFamilies@ extension.++ Test case:+ testsuite/tests/indexed-types/should_fail/BadFamInstDecl+ -}+ TcRnBadFamInstDecl :: TyCon -> TcRnMessage+ {- | 'TcRnNotOpenFamily' is an error that is triggered by attempting to give+ a top-level (open) type family instance for a closed type family.++ Test cases:+ testsuite/tests/indexed-types/should_fail/Overlap7+ testsuite/tests/indexed-types/should_fail/Overlap3+ -}+ TcRnNotOpenFamily :: TyCon -> TcRnMessage+ {-| TcRnNoRebindableSyntaxRecordDot is an error triggered by an overloaded record update+ without RebindableSyntax enabled.++ Example(s):++ Test cases: parser/should_fail/RecordDotSyntaxFail5+ -}+ TcRnNoRebindableSyntaxRecordDot :: TcRnMessage++ {-| TcRnNoFieldPunsRecordDot is an error triggered by the use of record field puns+ in an overloaded record update without enabling NamedFieldPuns.++ Example(s):+ print $ a{ foo.bar.baz.quux }++ Test cases: parser/should_fail/RecordDotSyntaxFail12+ -}+ TcRnNoFieldPunsRecordDot :: TcRnMessage++ {-| TcRnIllegalStaticExpression is an error thrown when user creates a static+ pointer via TemplateHaskell without enabling the StaticPointers extension.++ Example(s):++ Test cases: th/T14204+ -}+ TcRnIllegalStaticExpression :: HsExpr GhcPs -> TcRnMessage++ {-| TcRnIllegalStaticFormInSplice is an error when a user attempts to define+ a static pointer in a Template Haskell splice.++ Example(s):++ Test cases: th/TH_StaticPointers02+ -}+ TcRnIllegalStaticFormInSplice :: HsExpr GhcPs -> TcRnMessage++ {-| TcRnListComprehensionDuplicateBinding is an error triggered by duplicate+ let-bindings in a list comprehension.++ Example(s):+ [ () | let a = 13 | let a = 17 ]++ Test cases: typecheck/should_fail/tcfail092+ -}+ TcRnListComprehensionDuplicateBinding :: Name -> TcRnMessage++ {-| TcRnEmptyStmtsGroup is an error triggered by an empty list of statements+ in a statement block. For more information, see 'EmptyStatementGroupErrReason'++ Example(s):++ [() | then ()]++ do++ proc () -> do++ Test cases: rename/should_fail/RnEmptyStatementGroup1+ -}+ TcRnEmptyStmtsGroup:: EmptyStatementGroupErrReason -> TcRnMessage++ {-| TcRnLastStmtNotExpr is an error caused by the last statement+ in a statement block not being an expression.++ Example(s):++ do x <- pure ()++ do let x = 5++ Test cases: rename/should_fail/T6060+ parser/should_fail/T3811g+ parser/should_fail/readFail028+ -}+ TcRnLastStmtNotExpr+ :: HsStmtContext GhcRn+ -> UnexpectedStatement+ -> TcRnMessage++ {-| TcRnUnexpectedStatementInContext is an error when a statement appears+ in an unexpected context (e.g. an arrow statement appears in a list comprehension).++ Example(s):++ Test cases: parser/should_fail/readFail042+ parser/should_fail/readFail038+ parser/should_fail/readFail043+ -}+ TcRnUnexpectedStatementInContext+ :: HsStmtContext GhcRn+ -> UnexpectedStatement+ -> Maybe LangExt.Extension+ -> TcRnMessage++ {-| TcRnIllegalTupleSection is an error triggered by usage of a tuple section+ without enabling the TupleSections extension.++ Example(s):+ (5,)++ Test cases: rename/should_fail/rnfail056+ -}+ TcRnIllegalTupleSection :: TcRnMessage++ {-| TcRnIllegalImplicitParameterBindings is an error triggered by binding+ an implicit parameter in an mdo block.++ Example(s):+ mdo { let { ?x = 5 }; () }++ Test cases: rename/should_fail/RnImplicitBindInMdoNotation+ -}+ TcRnIllegalImplicitParameterBindings+ :: Either (HsLocalBindsLR GhcPs GhcPs) (HsLocalBindsLR GhcRn GhcPs)+ -> TcRnMessage++ {-| TcRnSectionWithoutParentheses is an error triggered by attempting to+ use an operator section without parentheses.++ Example(s):+ (`head` x, ())++ Test cases: rename/should_fail/T2490+ rename/should_fail/T5657+ -}+ TcRnSectionWithoutParentheses :: HsExpr GhcPs -> TcRnMessage+ deriving Generic -- | Things forbidden in @type data@ declarations.@@ -3201,8 +3418,8 @@ -- | Cannot unify a variable, because of a type mismatch. | CannotUnifyVariable- { mismatchMsg :: MismatchMsg- , cannotUnifyReason :: CannotUnifyVariableReason }+ { mismatchMsg :: MismatchMsg+ , cannotUnifyReason :: CannotUnifyVariableReason } -- | A mismatch between two types. | Mismatch@@ -3221,6 +3438,11 @@ -- -- Test cases: none. | BlockedEquality ErrorItem+ -- These are for the "blocked" equalities, as described in+ -- Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Canonical,+ -- wrinkle (2). There should always be another unsolved wanted around,+ -- which will ordinarily suppress this message. But this can still be printed out+ -- with -fdefer-type-errors (sigh), so we must produce a message. -- | Something was not applied to sufficiently many arguments. --@@ -3301,7 +3523,7 @@ -- 3 + 3# -- can't match a lifted type with an unlifted type -- -- Test cases: T1396, T8263, ...- BasicMismatch -- SLD TODO rename this+ BasicMismatch { mismatch_ea :: MismatchEA -- ^ Should this be phrased in terms of expected vs actual? , mismatch_item :: ErrorItem -- ^ The constraint in which the mismatch originated. , mismatch_ty1 :: Type -- ^ First type (the expected type if if mismatch_ea is True)@@ -3351,6 +3573,9 @@ } deriving Generic +-- | Construct a basic mismatch message between two types.+--+-- See 'pprMismatchMsg' for how such a message is displayed to users. mkBasicMismatchMsg :: MismatchEA -> ErrorItem -> Type -> Type -> MismatchMsg mkBasicMismatchMsg ea item ty1 ty2 = BasicMismatch@@ -3402,6 +3627,8 @@ | RepresentationalEq TyVarInfo (Maybe CoercibleMsg) deriving Generic +-- | Report a mismatch error without any extra+-- information. mkPlainMismatchMsg :: MismatchMsg -> TcSolverReportMsg mkPlainMismatchMsg msg = Mismatch@@ -3736,3 +3963,32 @@ data UnrepresentableTypeDescr = LinearInvisibleArgument | CoercionsInTypes++-- | The context for an "empty statement group" error.+data EmptyStatementGroupErrReason+ = EmptyStmtsGroupInParallelComp+ -- ^ Empty statement group in a parallel list comprehension+ | EmptyStmtsGroupInTransformListComp+ -- ^ Empty statement group in a transform list comprehension+ --+ -- Example:+ -- [() | then ()]+ | EmptyStmtsGroupInDoNotation HsDoFlavour+ -- ^ Empty statement group in do notation+ --+ -- Example:+ -- do+ | EmptyStmtsGroupInArrowNotation+ -- ^ Empty statement group in arrow notation+ --+ -- Example:+ -- proc () -> do++ deriving (Generic)++-- | An existential wrapper around @'StmtLR' GhcPs GhcPs body@.+data UnexpectedStatement where+ UnexpectedStatement+ :: Outputable (StmtLR GhcPs GhcPs body)+ => StmtLR GhcPs GhcPs body+ -> UnexpectedStatement
compiler/GHC/Tc/Solver/InertSet.hs view
@@ -20,7 +20,8 @@ emptyInert, addInertItem, - matchableGivens,+ noMatchableGivenDicts,+ noGivenIrreds, mightEqualLater, prohibitedSuperClassSolve, @@ -41,11 +42,11 @@ import GHC.Prelude -import GHC.Tc.Solver.Types- import GHC.Tc.Types.Constraint import GHC.Tc.Types.Origin+import GHC.Tc.Solver.Types import GHC.Tc.Utils.TcType+ import GHC.Types.Var import GHC.Types.Var.Env @@ -53,6 +54,7 @@ import GHC.Core.Predicate import GHC.Core.TyCo.FVs import qualified GHC.Core.TyCo.Rep as Rep+import GHC.Core.Class( Class ) import GHC.Core.TyCon import GHC.Core.Unify @@ -1535,25 +1537,20 @@ -- becomes "outer" even though its level numbers says it isn't. | otherwise = False -- Coercion variables; doesn't much matter --- | Returns Given constraints that might,--- potentially, match the given pred. This is used when checking to see if a+noGivenIrreds :: InertSet -> Bool+noGivenIrreds (IS { inert_cans = inert_cans })+ = isEmptyBag (inert_irreds inert_cans)++-- | Returns True iff there are no Given constraints that might,+-- potentially, match the given class consraint. This is used when checking to see if a -- Given might overlap with an instance. See Note [Instance and Given overlap] -- in "GHC.Tc.Solver.Interact"-matchableGivens :: CtLoc -> PredType -> InertSet -> Cts-matchableGivens loc_w pred_w inerts@(IS { inert_cans = inert_cans })- = filterBag matchable_given all_relevant_givens+noMatchableGivenDicts :: InertSet -> CtLoc -> Class -> [TcType] -> Bool+noMatchableGivenDicts inerts@(IS { inert_cans = inert_cans }) loc_w clas tys+ = not $ anyBag matchable_given $+ findDictsByClass (inert_dicts inert_cans) clas where- -- just look in class constraints and irreds. matchableGivens does get called- -- for ~R constraints, but we don't need to look through equalities, because- -- canonical equalities are used for rewriting. We'll only get caught by- -- non-canonical -- that is, irreducible -- equalities.- all_relevant_givens :: Cts- all_relevant_givens- | Just (clas, _) <- getClassPredTys_maybe pred_w- = findDictsByClass (inert_dicts inert_cans) clas- `unionBags` inert_irreds inert_cans- | otherwise- = inert_irreds inert_cans+ pred_w = mkClassPred clas tys matchable_given :: Ct -> Bool matchable_given ct@@ -1626,7 +1623,7 @@ -- like startSolvingByUnification, but allows cbv variables to unify can_unify :: TcTyVar -> MetaInfo -> Type -> Bool can_unify _lhs_tv TyVarTv rhs_ty -- see Example 3 from the Note- | Just rhs_tv <- tcGetTyVar_maybe rhs_ty+ | Just rhs_tv <- getTyVar_maybe rhs_ty = case tcTyVarDetails rhs_tv of MetaTv { mtv_info = TyVarTv } -> True MetaTv {} -> False -- could unify with anything
compiler/GHC/Tc/Solver/Types.hs view
@@ -1,8 +1,6 @@ {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE GADTs #-} -{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}- -- | Utility types used within the constraint solver module GHC.Tc.Solver.Types ( -- Inert CDictCans
compiler/GHC/Tc/Types.hs view
@@ -977,7 +977,7 @@ -- | Get target platform-getPlatform :: TcM Platform+getPlatform :: TcRnIf a b Platform getPlatform = targetPlatform <$> getDynFlags ---------------------------
compiler/GHC/Tc/Types/Constraint.hs view
@@ -3,20 +3,19 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TypeApplications #-} -{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}- -- | This module defines types and simple operations over constraints, as used -- in the type-checker and constraint solver. module GHC.Tc.Types.Constraint ( -- QCInst- QCInst(..), isPendingScInst,+ QCInst(..), pendingScInst_maybe, -- Canonical constraints Xi, Ct(..), Cts, emptyCts, andCts, andManyCts, pprCts, singleCt, listToCts, ctsElts, consCts, snocCts, extendCtsList, isEmptyCts,- isPendingScDict, superClassesMightHelp, getPendingWantedScs,+ isPendingScDict, pendingScDict_maybe,+ superClassesMightHelp, getPendingWantedScs, isWantedCt, isGivenCt, isUserTypeError, getUserTypeErrorMsg, ctEvidence, ctLoc, ctPred, ctFlavour, ctEqRel, ctOrigin,@@ -199,17 +198,11 @@ cc_class :: Class, cc_tyargs :: [Xi], -- cc_tyargs are rewritten w.r.t. inerts, so Xi - cc_pend_sc :: Bool,+ cc_pend_sc :: Bool -- See Note [The superclass story] in GHC.Tc.Solver.Canonical -- True <=> (a) cc_class has superclasses -- (b) we have not (yet) added those -- superclasses as Givens-- cc_fundeps :: Bool- -- See Note [Fundeps with instances] in GHC.Tc.Solver.Interact- -- True <=> the class has fundeps, and we have not yet- -- compared this constraint with the global- -- instances for fundep improvement } | CIrredCan { -- These stand for yet-unusable predicates@@ -234,7 +227,7 @@ -- Note [CEqCan occurs check] -- * (TyEq:F) rhs has no foralls -- (this avoids substituting a forall for the tyvar in other types)- -- * (TyEq:K) tcTypeKind lhs `tcEqKind` tcTypeKind rhs; Note [Ct kind invariant]+ -- * (TyEq:K) typeKind lhs `tcEqKind` typeKind rhs; Note [Ct kind invariant] -- * (TyEq:N) If the equality is representational, rhs is not headed by a saturated -- application of a newtype TyCon. -- See Note [No top-level newtypes on RHS of representational equalities]@@ -385,7 +378,7 @@ | ContainsCast TcType TcCoercionN -- | The type contains a forall.- | ContainsForall TyCoVarBinder TcType+ | ContainsForall ForAllTyBinder TcType -- | The type contains a 'CoercionTy'. | ContainsCoercionTy TcCoercion@@ -678,10 +671,8 @@ pp_sort = case ct of CEqCan {} -> text "CEqCan" CNonCanonical {} -> text "CNonCanonical"- CDictCan { cc_pend_sc = psc, cc_fundeps = fds }- | psc, fds -> text "CDictCan(psc,fds)"- | psc, not fds -> text "CDictCan(psc)"- | not psc, fds -> text "CDictCan(fds)"+ CDictCan { cc_pend_sc = psc }+ | psc -> text "CDictCan(psc)" | otherwise -> text "CDictCan" CIrredCan { cc_reason = reason } -> text "CIrredCan" <> ppr reason CQuantCan (QCI { qci_pend_sc = pend_sc })@@ -694,7 +685,7 @@ -- Does not look through type synonyms. canEqLHS_maybe :: Xi -> Maybe CanEqLHS canEqLHS_maybe xi- | Just tv <- tcGetTyVar_maybe xi+ | Just tv <- getTyVar_maybe xi = Just $ TyVarLHS tv | Just (tc, args) <- tcSplitTyConApp_maybe xi@@ -900,18 +891,24 @@ Just _ -> True _ -> False -isPendingScDict :: Ct -> Maybe Ct+isPendingScDict :: Ct -> Bool+isPendingScDict (CDictCan { cc_pend_sc = psc }) = psc+-- Says whether this is a CDictCan with cc_pend_sc is True;+-- i.e. pending un-expanded superclasses+isPendingScDict _ = False++pendingScDict_maybe :: Ct -> Maybe Ct -- Says whether this is a CDictCan with cc_pend_sc is True, -- AND if so flips the flag-isPendingScDict ct@(CDictCan { cc_pend_sc = True })- = Just (ct { cc_pend_sc = False })-isPendingScDict _ = Nothing+pendingScDict_maybe ct@(CDictCan { cc_pend_sc = True })+ = Just (ct { cc_pend_sc = False })+pendingScDict_maybe _ = Nothing -isPendingScInst :: QCInst -> Maybe QCInst+pendingScInst_maybe :: QCInst -> Maybe QCInst -- Same as isPendingScDict, but for QCInsts-isPendingScInst qci@(QCI { qci_pend_sc = True })- = Just (qci { qci_pend_sc = False })-isPendingScInst _ = Nothing+pendingScInst_maybe qci@(QCI { qci_pend_sc = True })+ = Just (qci { qci_pend_sc = False })+pendingScInst_maybe _ = Nothing superClassesMightHelp :: WantedConstraints -> Bool -- ^ True if taking superclasses of givens, or of wanteds (to perhaps@@ -933,7 +930,7 @@ getPendingWantedScs simples = mapAccumBagL get [] simples where- get acc ct | Just ct' <- isPendingScDict ct+ get acc ct | Just ct' <- pendingScDict_maybe ct = (ct':acc, ct') | otherwise = (acc, ct)@@ -1893,7 +1890,7 @@ ctEvCoercion :: HasDebugCallStack => CtEvidence -> TcCoercion ctEvCoercion (CtGiven { ctev_evar = ev_id })- = mkTcCoVarCo ev_id+ = mkCoVarCo ev_id ctEvCoercion (CtWanted { ctev_dest = dest }) | HoleDest hole <- dest = -- ctEvCoercion is only called on type equalities@@ -1927,23 +1924,17 @@ -- the evidence and the ctev_pred in sync with each other. -- See Note [CtEvidence invariants]. setCtEvPredType :: HasDebugCallStack => CtEvidence -> Type -> CtEvidence-setCtEvPredType old_ctev new_pred- = case old_ctev of- CtGiven { ctev_evar = ev, ctev_loc = loc } ->- CtGiven { ctev_pred = new_pred- , ctev_evar = setVarType ev new_pred- , ctev_loc = loc- }- CtWanted { ctev_dest = dest, ctev_loc = loc, ctev_rewriters = rewriters } ->- CtWanted { ctev_pred = new_pred- , ctev_dest = new_dest- , ctev_loc = loc- , ctev_rewriters = rewriters- }- where- new_dest = case dest of- EvVarDest ev -> EvVarDest (setVarType ev new_pred)- HoleDest h -> HoleDest (setCoHoleType h new_pred)+setCtEvPredType old_ctev@(CtGiven { ctev_evar = ev }) new_pred+ = old_ctev { ctev_pred = new_pred+ , ctev_evar = setVarType ev new_pred }++setCtEvPredType old_ctev@(CtWanted { ctev_dest = dest }) new_pred+ = old_ctev { ctev_pred = new_pred+ , ctev_dest = new_dest }+ where+ new_dest = case dest of+ EvVarDest ev -> EvVarDest (setVarType ev new_pred)+ HoleDest h -> HoleDest (setCoHoleType h new_pred) instance Outputable TcEvDest where ppr (HoleDest h) = text "hole" <> ppr h
compiler/GHC/Tc/Types/Evidence.hs view
@@ -8,7 +8,7 @@ -- * HsWrapper HsWrapper(..), (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams,- mkWpLams, mkWpLet, mkWpFun, mkWpCastN, mkWpCastR,+ mkWpEvLams, mkWpLet, mkWpFun, mkWpCastN, mkWpCastR, mkWpEta, collectHsWrapBinders, idHsWrapper, isIdHsWrapper, pprHsWrapper, hsWrapDictBinders,@@ -41,22 +41,7 @@ TcCoercion, TcCoercionR, TcCoercionN, TcCoercionP, CoercionHole, TcMCoercion, TcMCoercionN, TcMCoercionR, Role(..), LeftOrRight(..), pickLR,- mkTcReflCo, mkTcNomReflCo, mkTcRepReflCo,- mkTcTyConAppCo, mkTcAppCo, mkTcFunCo,- mkTcAxInstCo, mkTcUnbranchedAxInstCo, mkTcForAllCo, mkTcForAllCos,- mkTcSymCo, mkTcSymMCo,- mkTcTransCo,- mkTcNthCo, mkTcLRCo, mkTcSubCo, maybeTcSymCo,- maybeTcSubCo, tcDowngradeRole,- mkTcAxiomRuleCo, mkTcGReflRightCo, mkTcGReflRightMCo, mkTcGReflLeftCo, mkTcGReflLeftMCo,- mkTcPhantomCo,- mkTcCoherenceLeftCo,- mkTcCoherenceRightCo,- mkTcKindCo,- tcCoercionKind,- mkTcCoVarCo,- isTcReflCo, isTcReflexiveCo,- tcCoercionRole,+ maybeSymCo, unwrapIP, wrapIP, -- * QuoteWrapper@@ -68,6 +53,7 @@ import GHC.Types.Unique.DFM import GHC.Types.Unique.FM import GHC.Types.Var+import GHC.Types.Id( idScaledType ) import GHC.Core.Coercion.Axiom import GHC.Core.Coercion import GHC.Core.Ppr () -- Instance OutputableBndr TyVar@@ -79,15 +65,12 @@ import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Core.Predicate-import GHC.Data.Pair import GHC.Types.Basic import GHC.Core import GHC.Core.Class (Class, classSCSelId ) import GHC.Core.FVs ( exprSomeFreeVars ) -import GHC.Iface.Type- import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable@@ -118,97 +101,18 @@ -} -type TcCoercion = Coercion-type TcCoercionN = CoercionN -- A Nominal coercion ~N-type TcCoercionR = CoercionR -- A Representational coercion ~R-type TcCoercionP = CoercionP -- a phantom coercion+type TcCoercion = Coercion+type TcCoercionN = CoercionN -- A Nominal coercion ~N+type TcCoercionR = CoercionR -- A Representational coercion ~R+type TcCoercionP = CoercionP -- a phantom coercion type TcMCoercion = MCoercion type TcMCoercionN = MCoercionN -- nominal type TcMCoercionR = MCoercionR -- representational -mkTcReflCo :: Role -> TcType -> TcCoercion-mkTcSymCo :: TcCoercion -> TcCoercion-mkTcSymMCo :: TcMCoercion -> TcMCoercion-mkTcTransCo :: TcCoercion -> TcCoercion -> TcCoercion-mkTcNomReflCo :: TcType -> TcCoercionN-mkTcRepReflCo :: TcType -> TcCoercionR-mkTcTyConAppCo :: Role -> TyCon -> [TcCoercion] -> TcCoercion-mkTcAppCo :: TcCoercion -> TcCoercionN -> TcCoercion-mkTcFunCo :: Role -> TcCoercion -> TcCoercion -> TcCoercion -> TcCoercion-mkTcAxInstCo :: Role -> CoAxiom br -> BranchIndex- -> [TcType] -> [TcCoercion] -> TcCoercion-mkTcUnbranchedAxInstCo :: CoAxiom Unbranched -> [TcType]- -> [TcCoercion] -> TcCoercionR-mkTcForAllCo :: TyVar -> TcCoercionN -> TcCoercion -> TcCoercion-mkTcForAllCos :: [(TyVar, TcCoercionN)] -> TcCoercion -> TcCoercion-mkTcNthCo :: Role -> Int -> TcCoercion -> TcCoercion-mkTcLRCo :: LeftOrRight -> TcCoercion -> TcCoercion-mkTcSubCo :: HasDebugCallStack => TcCoercionN -> TcCoercionR-tcDowngradeRole :: Role -> Role -> TcCoercion -> TcCoercion-mkTcAxiomRuleCo :: CoAxiomRule -> [TcCoercion] -> TcCoercionR-mkTcGReflRightCo :: Role -> TcType -> TcCoercionN -> TcCoercion-mkTcGReflRightMCo :: Role -> TcType -> TcMCoercionN -> TcCoercion-mkTcGReflLeftCo :: Role -> TcType -> TcCoercionN -> TcCoercion-mkTcGReflLeftMCo :: Role -> TcType -> TcMCoercionN -> TcCoercion-mkTcCoherenceLeftCo :: Role -> TcType -> TcCoercionN- -> TcCoercion -> TcCoercion-mkTcCoherenceRightCo :: Role -> TcType -> TcCoercionN- -> TcCoercion -> TcCoercion-mkTcPhantomCo :: TcCoercionN -> TcType -> TcType -> TcCoercionP-mkTcKindCo :: TcCoercion -> TcCoercionN-mkTcCoVarCo :: CoVar -> TcCoercion--tcCoercionKind :: TcCoercion -> Pair TcType-tcCoercionRole :: TcCoercion -> Role-isTcReflCo :: TcCoercion -> Bool---- | This version does a slow check, calculating the related types and seeing--- if they are equal.-isTcReflexiveCo :: TcCoercion -> Bool--mkTcReflCo = mkReflCo-mkTcSymCo = mkSymCo-mkTcSymMCo = mkSymMCo-mkTcTransCo = mkTransCo-mkTcNomReflCo = mkNomReflCo-mkTcRepReflCo = mkRepReflCo-mkTcTyConAppCo = mkTyConAppCo-mkTcAppCo = mkAppCo-mkTcFunCo = mkFunCo-mkTcAxInstCo = mkAxInstCo-mkTcUnbranchedAxInstCo = mkUnbranchedAxInstCo Representational-mkTcForAllCo = mkForAllCo-mkTcForAllCos = mkForAllCos-mkTcNthCo = mkNthCo-mkTcLRCo = mkLRCo-mkTcSubCo = mkSubCo-tcDowngradeRole = downgradeRole-mkTcAxiomRuleCo = mkAxiomRuleCo-mkTcGReflRightCo = mkGReflRightCo-mkTcGReflRightMCo = mkGReflRightMCo-mkTcGReflLeftCo = mkGReflLeftCo-mkTcGReflLeftMCo = mkGReflLeftMCo-mkTcCoherenceLeftCo = mkCoherenceLeftCo-mkTcCoherenceRightCo = mkCoherenceRightCo-mkTcPhantomCo = mkPhantomCo-mkTcKindCo = mkKindCo-mkTcCoVarCo = mkCoVarCo--tcCoercionKind = coercionKind-tcCoercionRole = coercionRole-isTcReflCo = isReflCo-isTcReflexiveCo = isReflexiveCo---- | If the EqRel is ReprEq, makes a SubCo; otherwise, does nothing.--- Note that the input coercion should always be nominal.-maybeTcSubCo :: HasDebugCallStack => EqRel -> TcCoercionN -> TcCoercion-maybeTcSubCo NomEq = id-maybeTcSubCo ReprEq = mkTcSubCo- -- | If a 'SwapFlag' is 'IsSwapped', flip the orientation of a coercion-maybeTcSymCo :: SwapFlag -> TcCoercion -> TcCoercion-maybeTcSymCo IsSwapped co = mkTcSymCo co-maybeTcSymCo NotSwapped co = co+maybeSymCo :: SwapFlag -> TcCoercion -> TcCoercion+maybeSymCo IsSwapped co = mkSymCo co+maybeSymCo NotSwapped co = co {- %************************************************************************@@ -241,8 +145,11 @@ -- then WpFun wrap1 wrap2 : (act_arg -> arg_res) ~> (exp_arg -> exp_res) -- This isn't the same as for mkFunCo, but it has to be this way -- because we can't use 'sym' to flip around these HsWrappers- -- The TcType is the "from" type of the first wrapper+ -- The TcType is the "from" type of the first wrapper;+ -- it always a Type, not a Constraint --+ -- NB: a WpFun is always for a (->) function arrow+ -- -- Use 'mkWpFun' to construct such a wrapper. | WpCast TcCoercionR -- A cast: [] `cast` co@@ -251,8 +158,11 @@ -- Evidence abstraction and application -- (both dictionaries and coercions)+ -- Both WpEvLam and WpEvApp abstract and apply values+ -- of kind CONSTRAINT rep | WpEvLam EvVar -- \d. [] the 'd' is an evidence variable | WpEvApp EvTerm -- [] d the 'd' is evidence for a constraint+ -- Kind and Type abstraction and application | WpTyLam TyVar -- \a. [] the 'a' is a type/kind variable (not coercion var) | WpTyApp KindOrType -- [] t the 't' is a type (not coercion)@@ -297,29 +207,42 @@ mkWpFun :: HsWrapper -> HsWrapper -> Scaled TcTypeFRR -- ^ the "from" type of the first wrapper -- MUST have a fixed RuntimeRep- -> TcType -- ^ either type of the second wrapper (used only when the- -- second wrapper is the identity)+ -> TcType -- ^ Either "from" type or "to" type of the second wrapper+ -- (used only when the second wrapper is the identity) -> HsWrapper -- NB: we can't check that the argument type has a fixed RuntimeRep with an assertion, -- because of [Wrinkle: Typed Template Haskell] in Note [hasFixedRuntimeRep] -- in GHC.Tc.Utils.Concrete. mkWpFun WpHole WpHole _ _ = WpHole-mkWpFun WpHole (WpCast co2) (Scaled w t1) _ = WpCast (mkTcFunCo Representational (multToCo w) (mkTcRepReflCo t1) co2)-mkWpFun (WpCast co1) WpHole (Scaled w _) t2 = WpCast (mkTcFunCo Representational (multToCo w) (mkTcSymCo co1) (mkTcRepReflCo t2))-mkWpFun (WpCast co1) (WpCast co2) (Scaled w _) _ = WpCast (mkTcFunCo Representational (multToCo w) (mkTcSymCo co1) co2)+mkWpFun WpHole (WpCast co2) (Scaled w t1) _ = WpCast (mk_wp_fun_co w (mkRepReflCo t1) co2)+mkWpFun (WpCast co1) WpHole (Scaled w _) t2 = WpCast (mk_wp_fun_co w (mkSymCo co1) (mkRepReflCo t2))+mkWpFun (WpCast co1) (WpCast co2) (Scaled w _) _ = WpCast (mk_wp_fun_co w (mkSymCo co1) co2) mkWpFun co1 co2 t1 _ = WpFun co1 co2 t1 +mkWpEta :: [Id] -> HsWrapper -> HsWrapper+-- (mkWpEta [x1, x2] wrap) [e]+-- = \x1. \x2. wrap[e x1 x2]+-- Just generates a bunch of WpFuns+mkWpEta xs wrap = foldr eta_one wrap xs+ where+ eta_one x wrap = WpFun idHsWrapper wrap (idScaledType x)++mk_wp_fun_co :: Mult -> TcCoercionR -> TcCoercionR -> TcCoercionR+mk_wp_fun_co mult arg_co res_co+ = mkNakedFunCo1 Representational FTF_T_T (multToCo mult) arg_co res_co+ -- FTF_T_T: WpFun is always (->)+ mkWpCastR :: TcCoercionR -> HsWrapper mkWpCastR co- | isTcReflCo co = WpHole- | otherwise = assertPpr (tcCoercionRole co == Representational) (ppr co) $- WpCast co+ | isReflCo co = WpHole+ | otherwise = assertPpr (coercionRole co == Representational) (ppr co) $+ WpCast co mkWpCastN :: TcCoercionN -> HsWrapper mkWpCastN co- | isTcReflCo co = WpHole- | otherwise = assertPpr (tcCoercionRole co == Nominal) (ppr co) $- WpCast (mkTcSubCo co)+ | isReflCo co = WpHole+ | otherwise = assertPpr (coercionRole co == Nominal) (ppr co) $+ WpCast (mkSubCo co) -- The mkTcSubCo converts Nominal to Representational mkWpTyApps :: [Type] -> HsWrapper@@ -334,8 +257,8 @@ mkWpTyLams :: [TyVar] -> HsWrapper mkWpTyLams ids = mk_co_lam_fn WpTyLam ids -mkWpLams :: [Var] -> HsWrapper-mkWpLams ids = mk_co_lam_fn WpEvLam ids+mkWpEvLams :: [Var] -> HsWrapper+mkWpEvLams ids = mk_co_lam_fn WpEvLam ids mkWpLet :: TcEvBinds -> HsWrapper -- This no-op is a quite a common case@@ -857,10 +780,10 @@ mkEvCast :: EvExpr -> TcCoercion -> EvTerm mkEvCast ev lco- | assertPpr (tcCoercionRole lco == Representational)+ | assertPpr (coercionRole lco == Representational) (vcat [text "Coercion of wrong role passed to mkEvCast:", ppr ev, ppr lco]) $- isTcReflCo lco = EvExpr ev- | otherwise = evCast ev lco+ isReflCo lco = EvExpr ev+ | otherwise = evCast ev lco mkEvScSelectors -- Assume class (..., D ty, ...) => C a b@@ -1038,10 +961,12 @@ = ppr (orig,loc) <+> text ":" <+> ppr tm instance Outputable EvTypeable where- ppr (EvTypeableTyCon ts _) = text "TyCon" <+> ppr ts- ppr (EvTypeableTyApp t1 t2) = parens (ppr t1 <+> ppr t2)- ppr (EvTypeableTrFun tm t1 t2) = parens (ppr t1 <+> mulArrow (const ppr) tm <+> ppr t2)- ppr (EvTypeableTyLit t1) = text "TyLit" <> ppr t1+ ppr (EvTypeableTyCon ts _) = text "TyCon" <+> ppr ts+ ppr (EvTypeableTyApp t1 t2) = parens (ppr t1 <+> ppr t2)+ ppr (EvTypeableTyLit t1) = text "TyLit" <> ppr t1+ ppr (EvTypeableTrFun tm t1 t2) = parens (ppr t1 <+> arr <+> ppr t2)+ where+ arr = pprArrowWithMultiplicity visArgTypeLike (Right (ppr tm)) ----------------------------------------------------------------------
compiler/GHC/Tc/Types/Origin.hs view
@@ -3,9 +3,6 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE PolyKinds #-} -{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- -- | Describes the provenance of types as they flow through the type-checker. -- The datatypes here are mainly used for error message generation. module GHC.Tc.Types.Origin (
compiler/GHC/Tc/Utils/TcType.hs view
@@ -3,8 +3,6 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} -{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}- {- (c) The University of Glasgow 2006 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998@@ -36,10 +34,12 @@ SyntaxOpType(..), synKnownType, mkSynFunTys, + -------------------------------- -- TcLevel TcLevel(..), topTcLevel, pushTcLevel, isTopTcLevel, strictlyDeeperThan, deeperThanOrSame, sameDepthAs, tcTypeLevel, tcTyVarLevel, maxTcLevel,+ -------------------------------- -- MetaDetails TcTyVarDetails(..), pprTcTyVarDetails, vanillaSkolemTvUnk,@@ -56,13 +56,12 @@ -------------------------------- -- Builders- mkPhiTy, mkInfSigmaTy, mkSpecSigmaTy, mkSigmaTy,- mkTcAppTy, mkTcAppTys, mkTcCastTy,+ mkInfSigmaTy, mkSpecSigmaTy, mkSigmaTy, mkPhiTy, tcMkPhiTy,+ tcMkDFunSigmaTy, tcMkDFunPhiTy, -------------------------------- -- Splitters- -- These are important because they do not look through newtypes- getTyVar,+ getTyVar, getTyVar_maybe, getCastedTyVar_maybe, tcSplitForAllTyVarBinder_maybe, tcSplitForAllTyVars, tcSplitForAllInvisTyVars, tcSplitSomeForAllTyVars, tcSplitForAllReqTVBinders, tcSplitForAllInvisTVBinders,@@ -72,26 +71,27 @@ tcSplitFunTysN, tcSplitTyConApp, tcSplitTyConApp_maybe, tcTyConAppTyCon, tcTyConAppTyCon_maybe, tcTyConAppArgs,- tcSplitAppTy_maybe, tcSplitAppTy, tcSplitAppTys, tcRepSplitAppTy_maybe,- tcRepGetNumAppTys,- tcGetCastedTyVar_maybe, tcGetTyVar_maybe, tcGetTyVar,+ tcSplitAppTy_maybe, tcSplitAppTy, tcSplitAppTys, tcSplitAppTyNoView_maybe, tcSplitSigmaTy, tcSplitNestedSigmaTys, --------------------------------- -- Predicates. -- Again, newtypes are opaque- eqType, eqTypes, nonDetCmpType, nonDetCmpTypes, eqTypeX,- pickyEqType, tcEqType, tcEqKind, tcEqTypeNoKindCheck, tcEqTypeVis,- tcEqTyConApps, isSigmaTy, isRhoTy, isRhoExpTy, isOverloadedTy, isFloatingPrimTy, isDoubleTy, isFloatTy, isIntTy, isWordTy, isStringTy, isIntegerTy, isNaturalTy, isBoolTy, isUnitTy, isCharTy,- isTauTy, isTauTyCon, tcIsTyVarTy, tcIsForAllTy,+ isTauTy, isTauTyCon, tcIsTyVarTy, isPredTy, isTyVarClassPred, checkValidClsArgs, hasTyVarHead, isRigidTy, + -- Re-exported from GHC.Core.TyCo.Compare+ -- mainly just for back-compat reasons+ eqType, eqTypes, nonDetCmpType, nonDetCmpTypes, eqTypeX,+ pickyEqType, tcEqType, tcEqKind, tcEqTypeNoKindCheck, tcEqTypeVis,+ tcEqTyConApps, eqForAllVis, eqVarBndrs,+ --------------------------------- -- Misc type manipulators @@ -132,21 +132,20 @@ -------------------------------- -- Reexported from Kind- Kind, tcTypeKind,- liftedTypeKind,- constraintKind,- isLiftedTypeKind, isUnliftedTypeKind, classifiesTypeWithValues,+ Kind, liftedTypeKind, constraintKind,+ isLiftedTypeKind, isUnliftedTypeKind, isTYPEorCONSTRAINT, -------------------------------- -- Reexported from Type- Type, PredType, ThetaType, TyCoBinder,- ArgFlag(..), AnonArgFlag(..),+ Type, PredType, ThetaType, PiTyBinder,+ ForAllTyFlag(..), FunTyFlag(..), mkForAllTy, mkForAllTys, mkInvisForAllTys, mkTyCoInvForAllTys, mkSpecForAllTys, mkTyCoInvForAllTy, mkInfForAllTy, mkInfForAllTys,- mkVisFunTy, mkVisFunTys, mkInvisFunTy, mkInvisFunTyMany,- mkVisFunTyMany, mkVisFunTysMany, mkInvisFunTysMany,+ mkVisFunTy, mkVisFunTyMany, mkVisFunTysMany,+ mkScaledFunTys,+ mkInvisFunTy, mkInvisFunTys, mkTyConApp, mkAppTy, mkAppTys, mkTyConTy, mkTyVarTy, mkTyVarTys, mkTyCoVarTy, mkTyCoVarTys,@@ -155,7 +154,7 @@ mkClassPred, tcSplitDFunTy, tcSplitDFunHead, tcSplitMethodTy, isRuntimeRepVar, isFixedRuntimeRepKind,- isVisibleBinder, isInvisibleBinder,+ isVisiblePiTyBinder, isInvisiblePiTyBinder, -- Type substitutions Subst(..), -- Representation visible to a few friends@@ -179,7 +178,7 @@ isUnboxedTupleType, isPrimitiveType, - tcView, coreView,+ coreView, tyCoVarsOfType, tyCoVarsOfTypes, closeOverKinds, tyCoFVsOfType, tyCoFVsOfTypes,@@ -206,6 +205,7 @@ import GHC.Core.TyCo.Rep import GHC.Core.TyCo.Subst ( mkTvSubst, substTyWithCoVars )+import GHC.Core.TyCo.Compare import GHC.Core.TyCo.FVs import GHC.Core.TyCo.Ppr import GHC.Core.Class@@ -229,7 +229,6 @@ -- We use this to make dictionaries for type literals. -- Perhaps there's a better way to do this? import GHC.Types.Name.Set-import GHC.Types.Var.Env import GHC.Builtin.Names import GHC.Builtin.Types ( coercibleClass, eqClass, heqClass, unitTyCon, unitTyConKey , listTyCon, constraintKind )@@ -883,7 +882,7 @@ tcTyFamInstsAndVisX = go where go is_invis_arg ty- | Just exp_ty <- tcView ty = go is_invis_arg exp_ty+ | Just exp_ty <- coreView ty = go is_invis_arg exp_ty go _ (TyVarTy _) = [] go is_invis_arg (TyConApp tc tys) | isTypeFamilyTyCon tc@@ -898,9 +897,9 @@ ++ go is_invis_arg ty2 go is_invis_arg ty@(AppTy _ _) = let (ty_head, ty_args) = splitAppTys ty- ty_arg_flags = appTyArgFlags ty_head ty_args+ ty_arg_flags = appTyForAllTyFlags ty_head ty_args in go is_invis_arg ty_head- ++ concat (zipWith (\flag -> go (isInvisibleArgFlag flag))+ ++ concat (zipWith (\flag -> go (isInvisibleForAllTyFlag flag)) ty_arg_flags ty_args) go is_invis_arg (CastTy ty _) = go is_invis_arg ty go _ (CoercionTy _) = [] -- don't count tyfams in coercions,@@ -954,7 +953,7 @@ go rl bvs ty@(TyConApp tc tys) | isTypeSynonymTyCon tc , should_expand tc- , Just ty' <- tcView ty -- should always match+ , Just ty' <- coreView ty -- should always match = go rl bvs ty' | tc_pred rl tc tys@@ -976,7 +975,7 @@ go_tc NomEq bvs _ tys = any (go NomEq bvs) tys go_tc ReprEq bvs tc tys = any (go_arg bvs)- (tyConRolesRepresentational tc `zip` tys)+ (tyConRoleListRepresentational tc `zip` tys) go_arg bvs (Nominal, ty) = go NomEq bvs ty go_arg bvs (Representational, ty) = go ReprEq bvs ty@@ -1043,7 +1042,7 @@ occasionally -- see the calls to exactTyCoVarsOfType. We place this function here in GHC.Tc.Utils.TcType, not in GHC.Core.TyCo.FVs,-because we want to "see" tcView (efficiency issue only).+because we want to "see" coreView (efficiency issue only). -} exactTyCoVarsOfType :: Type -> TyCoVarSet@@ -1059,7 +1058,7 @@ (exact_ty, exact_tys, _, _) = foldTyCo exactTcvFolder emptyVarSet exactTcvFolder :: TyCoFolder TyCoVarSet (Endo TyCoVarSet)-exactTcvFolder = deepTcvFolder { tcf_view = tcView }+exactTcvFolder = deepTcvFolder { tcf_view = coreView } -- This is the key line {-@@ -1280,22 +1279,39 @@ ************************************************************************ -} -mkSigmaTy :: [TyCoVarBinder] -> [PredType] -> Type -> Type-mkSigmaTy bndrs theta tau = mkForAllTys bndrs (mkPhiTy theta tau)- -- | Make a sigma ty where all type variables are 'Inferred'. That is, -- they cannot be used with visible type application.-mkInfSigmaTy :: [TyCoVar] -> [PredType] -> Type -> Type-mkInfSigmaTy tyvars theta ty = mkSigmaTy (mkTyCoVarBinders Inferred tyvars) theta ty+mkInfSigmaTy :: HasDebugCallStack => [TyCoVar] -> [PredType] -> Type -> Type+mkInfSigmaTy tyvars theta ty = mkSigmaTy (mkForAllTyBinders Inferred tyvars) theta ty -- | Make a sigma ty where all type variables are "specified". That is, -- they can be used with visible type application-mkSpecSigmaTy :: [TyVar] -> [PredType] -> Type -> Type-mkSpecSigmaTy tyvars preds ty = mkSigmaTy (mkTyCoVarBinders Specified tyvars) preds ty+mkSpecSigmaTy :: HasDebugCallStack => [TyVar] -> [PredType] -> Type -> Type+mkSpecSigmaTy tyvars preds ty = mkSigmaTy (mkForAllTyBinders Specified tyvars) preds ty -mkPhiTy :: [PredType] -> Type -> Type-mkPhiTy = mkInvisFunTysMany+mkSigmaTy :: HasDebugCallStack => [ForAllTyBinder] -> [PredType] -> Type -> Type+-- Result is TypeLike+mkSigmaTy bndrs theta tau = mkForAllTys bndrs (mkPhiTy theta tau) +tcMkDFunSigmaTy :: [TyVar] -> ThetaType -> Type -> Type+tcMkDFunSigmaTy tvs theta res_ty+ = mkForAllTys (mkForAllTyBinders Specified tvs) $+ tcMkDFunPhiTy theta res_ty++mkPhiTy :: HasDebugCallStack => [PredType] -> Type -> Type+-- Result type is TypeLike+mkPhiTy = mkInvisFunTys++tcMkPhiTy :: HasDebugCallStack => [PredType] -> Type -> Type+-- Like mkPhiTy, but with no assertion checks; it is called+-- by the type checker and the result kind may not be zonked yet+-- But the result kind is TypeLike+tcMkPhiTy tys ty = foldr (tcMkInvisFunTy TypeLike) ty tys++tcMkDFunPhiTy :: HasDebugCallStack => [PredType] -> Type -> Type+-- Just like tcMkPhiTy, but result type is ConstraintLike+tcMkDFunPhiTy preds res = foldr (tcMkInvisFunTy ConstraintLike) res preds+ --------------- getDFunTyKey :: Type -> OccName -- Get some string from a type, to be used to -- construct a dictionary function name@@ -1304,7 +1320,7 @@ getDFunTyKey (TyConApp tc _) = getOccName tc getDFunTyKey (LitTy x) = getDFunTyLitKey x getDFunTyKey (AppTy fun _) = getDFunTyKey fun-getDFunTyKey (FunTy {}) = getOccName funTyCon+getDFunTyKey (FunTy { ft_af = af }) = getOccName (funTyFlagTyCon af) getDFunTyKey (ForAllTy _ t) = getDFunTyKey t getDFunTyKey (CastTy ty _) = getDFunTyKey ty getDFunTyKey t@(CoercionTy _) = pprPanic "getDFunTyKey" (ppr t)@@ -1314,58 +1330,34 @@ getDFunTyLitKey (StrTyLit n) = mkOccName Name.varName (show n) -- hm getDFunTyLitKey (CharTyLit n) = mkOccName Name.varName (show n) -{- *********************************************************************-* *- Building types-* *-********************************************************************* -}---- ToDo: I think we need Tc versions of these--- Reason: mkCastTy checks isReflexiveCastTy, which checks--- for equality; and that has a different answer--- depending on whether or not Type = Constraint--mkTcAppTys :: Type -> [Type] -> Type-mkTcAppTys = mkAppTys--mkTcAppTy :: Type -> Type -> Type-mkTcAppTy = mkAppTy--mkTcCastTy :: Type -> Coercion -> Type-mkTcCastTy = mkCastTy -- Do we need a tc version of mkCastTy?- {- ************************************************************************ * * Expanding and splitting * * ************************************************************************--These tcSplit functions are like their non-Tc analogues, but- *) they do not look through newtypes--However, they are non-monadic and do not follow through mutable type-variables. It's up to you to make sure this doesn't matter. -} --- | Splits a forall type into a list of 'TyBinder's and the inner type.+-- | Splits a forall type into a list of 'PiTyVarBinder's and the inner type. -- Always succeeds, even if it returns an empty list.-tcSplitPiTys :: Type -> ([TyBinder], Type)+tcSplitPiTys :: Type -> ([PiTyVarBinder], Type) tcSplitPiTys ty- = assert (all isTyBinder (fst sty) ) sty+ = assert (all isTyBinder (fst sty) ) -- No CoVar binders here+ sty where sty = splitPiTys ty --- | Splits a type into a TyBinder and a body, if possible. Panics otherwise-tcSplitPiTy_maybe :: Type -> Maybe (TyBinder, Type)+-- | Splits a type into a PiTyVarBinder and a body, if possible.+tcSplitPiTy_maybe :: Type -> Maybe (PiTyVarBinder, Type) tcSplitPiTy_maybe ty- = assert (isMaybeTyBinder sty ) sty+ = assert (isMaybeTyBinder sty) -- No CoVar binders here+ sty where sty = splitPiTy_maybe ty isMaybeTyBinder (Just (t,_)) = isTyBinder t isMaybeTyBinder _ = True tcSplitForAllTyVarBinder_maybe :: Type -> Maybe (TyVarBinder, Type)-tcSplitForAllTyVarBinder_maybe ty | Just ty' <- tcView ty = tcSplitForAllTyVarBinder_maybe ty'+tcSplitForAllTyVarBinder_maybe ty | Just ty' <- coreView ty = tcSplitForAllTyVarBinder_maybe ty' tcSplitForAllTyVarBinder_maybe (ForAllTy tv ty) = assert (isTyVarBinder tv ) Just (tv, ty) tcSplitForAllTyVarBinder_maybe _ = Nothing @@ -1379,13 +1371,13 @@ -- | Like 'tcSplitForAllTyVars', but only splits 'ForAllTy's with 'Invisible' -- type variable binders. tcSplitForAllInvisTyVars :: Type -> ([TyVar], Type)-tcSplitForAllInvisTyVars ty = tcSplitSomeForAllTyVars isInvisibleArgFlag ty+tcSplitForAllInvisTyVars ty = tcSplitSomeForAllTyVars isInvisibleForAllTyFlag ty -- | Like 'tcSplitForAllTyVars', but only splits a 'ForAllTy' if @argf_pred argf@ -- is 'True', where @argf@ is the visibility of the @ForAllTy@'s binder and -- @argf_pred@ is a predicate over visibilities provided as an argument to this -- function.-tcSplitSomeForAllTyVars :: (ArgFlag -> Bool) -> Type -> ([TyVar], Type)+tcSplitSomeForAllTyVars :: (ForAllTyFlag -> Bool) -> Type -> ([TyVar], Type) tcSplitSomeForAllTyVars argf_pred ty = split ty ty [] where@@ -1397,32 +1389,26 @@ -- | Like 'tcSplitForAllTyVars', but only splits 'ForAllTy's with 'Required' type -- variable binders. All split tyvars are annotated with '()'. tcSplitForAllReqTVBinders :: Type -> ([TcReqTVBinder], Type)-tcSplitForAllReqTVBinders ty = assert (all (isTyVar . binderVar) (fst sty) ) sty- where sty = splitForAllReqTVBinders ty+tcSplitForAllReqTVBinders ty = assert (all isTyVarBinder (fst sty) ) sty+ where sty = splitForAllReqTyBinders ty -- | Like 'tcSplitForAllTyVars', but only splits 'ForAllTy's with 'Invisible' type -- variable binders. All split tyvars are annotated with their 'Specificity'. tcSplitForAllInvisTVBinders :: Type -> ([TcInvisTVBinder], Type)-tcSplitForAllInvisTVBinders ty = assert (all (isTyVar . binderVar) (fst sty) ) sty- where sty = splitForAllInvisTVBinders ty+tcSplitForAllInvisTVBinders ty = assert (all (isTyVar . binderVar) (fst sty)) sty+ where sty = splitForAllInvisTyBinders ty -- | Like 'tcSplitForAllTyVars', but splits off only named binders. tcSplitForAllTyVarBinders :: Type -> ([TyVarBinder], Type) tcSplitForAllTyVarBinders ty = assert (all isTyVarBinder (fst sty)) sty- where sty = splitForAllTyCoVarBinders ty---- | Is this a ForAllTy with a named binder?-tcIsForAllTy :: Type -> Bool-tcIsForAllTy ty | Just ty' <- tcView ty = tcIsForAllTy ty'-tcIsForAllTy (ForAllTy {}) = True-tcIsForAllTy _ = False+ where sty = splitForAllForAllTyBinders ty tcSplitPredFunTy_maybe :: Type -> Maybe (PredType, Type) -- Split off the first predicate argument from a type tcSplitPredFunTy_maybe ty- | Just ty' <- tcView ty = tcSplitPredFunTy_maybe ty'-tcSplitPredFunTy_maybe (FunTy { ft_af = InvisArg- , ft_arg = arg, ft_res = res })+ | Just ty' <- coreView ty = tcSplitPredFunTy_maybe ty'+tcSplitPredFunTy_maybe (FunTy { ft_af = af, ft_arg = arg, ft_res = res })+ | isInvisibleFunArg af = Just (arg, res) tcSplitPredFunTy_maybe _ = Nothing@@ -1457,7 +1443,7 @@ , (tvs1, theta1, rho1) <- tcSplitSigmaTy body_ty , not (null tvs1 && null theta1) = let (tvs2, theta2, rho2) = tcSplitNestedSigmaTys rho1- in (tvs1 ++ tvs2, theta1 ++ theta2, mkVisFunTys arg_tys rho2)+ in (tvs1 ++ tvs2, theta1 ++ theta2, mkScaledFunTys arg_tys rho2) -- If there's no forall, we're done. | otherwise = ([], [], ty)@@ -1498,26 +1484,16 @@ -- | Like 'tcRepSplitTyConApp_maybe', but only returns the 'TyCon'. tcTyConAppTyCon_maybe :: Type -> Maybe TyCon-tcTyConAppTyCon_maybe ty- | Just ty' <- tcView ty = tcTyConAppTyCon_maybe ty'-tcTyConAppTyCon_maybe (TyConApp tc _)- = Just tc-tcTyConAppTyCon_maybe (FunTy { ft_af = VisArg })- = Just funTyCon -- (=>) is /not/ a TyCon in its own right- -- C.f. tcRepSplitAppTy_maybe-tcTyConAppTyCon_maybe _- = Nothing+tcTyConAppTyCon_maybe ty | Just ty' <- coreView ty = tcTyConAppTyCon_maybe ty'+tcTyConAppTyCon_maybe (TyConApp tc _) = Just tc+tcTyConAppTyCon_maybe (FunTy { ft_af = af }) = Just (funTyFlagTyCon af)+tcTyConAppTyCon_maybe _ = Nothing tcTyConAppArgs :: Type -> [Type] tcTyConAppArgs ty = case tcSplitTyConApp_maybe ty of Just (_, args) -> args Nothing -> pprPanic "tcTyConAppArgs" (pprType ty) -tcSplitTyConApp :: Type -> (TyCon, [Type])-tcSplitTyConApp ty = case tcSplitTyConApp_maybe ty of- Just stuff -> stuff- Nothing -> pprPanic "tcSplitTyConApp" (pprType ty)- ----------------------- tcSplitFunTys :: Type -> ([Scaled Type], Type) tcSplitFunTys ty = case tcSplitFunTy_maybe ty of@@ -1527,12 +1503,13 @@ (args,res') = tcSplitFunTys res tcSplitFunTy_maybe :: Type -> Maybe (Scaled Type, Type)+-- Only splits function (->) and (-=>), not (=>) or (==>) tcSplitFunTy_maybe ty- | Just ty' <- tcView ty = tcSplitFunTy_maybe ty'+ | Just ty' <- coreView ty = tcSplitFunTy_maybe ty' tcSplitFunTy_maybe (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res })- | VisArg <- af = Just (Scaled w arg, res)-tcSplitFunTy_maybe _ = Nothing- -- Note the VisArg guard+ | isVisibleFunArg af = Just (Scaled w arg, res)+tcSplitFunTy_maybe _ = Nothing+ -- Note the isVisibleFunArg guard -- Consider (?x::Int) => Bool -- We don't want to treat this as a function type! -- A concrete example is test tc230:@@ -1563,7 +1540,7 @@ tcSplitFunTy ty = expectJust "tcSplitFunTy" (tcSplitFunTy_maybe ty) tcFunArgTy :: Type -> Scaled Type-tcFunArgTy ty = fst (tcSplitFunTy ty)+tcFunArgTy ty = fst (tcSplitFunTy ty) tcFunResultTy :: Type -> Type tcFunResultTy ty = snd (tcSplitFunTy ty)@@ -1578,8 +1555,8 @@ ----------------------- tcSplitAppTy_maybe :: Type -> Maybe (Type, Type)-tcSplitAppTy_maybe ty | Just ty' <- tcView ty = tcSplitAppTy_maybe ty'-tcSplitAppTy_maybe ty = tcRepSplitAppTy_maybe ty+tcSplitAppTy_maybe ty | Just ty' <- coreView ty = tcSplitAppTy_maybe ty'+tcSplitAppTy_maybe ty = tcSplitAppTyNoView_maybe ty tcSplitAppTy :: Type -> (Type, Type) tcSplitAppTy ty = case tcSplitAppTy_maybe ty of@@ -1594,34 +1571,9 @@ Just (ty', arg) -> go ty' (arg:args) Nothing -> (ty,args) --- | Returns the number of arguments in the given type, without--- looking through synonyms. This is used only for error reporting.--- We don't look through synonyms because of #11313.-tcRepGetNumAppTys :: Type -> Arity-tcRepGetNumAppTys = length . snd . repSplitAppTys- -------------------------- | If the type is a tyvar, possibly under a cast, returns it, along--- with the coercion. Thus, the co is :: kind tv ~N kind type-tcGetCastedTyVar_maybe :: Type -> Maybe (TyVar, CoercionN)-tcGetCastedTyVar_maybe ty | Just ty' <- tcView ty = tcGetCastedTyVar_maybe ty'-tcGetCastedTyVar_maybe (CastTy (TyVarTy tv) co) = Just (tv, co)-tcGetCastedTyVar_maybe (TyVarTy tv) = Just (tv, mkNomReflCo (tyVarKind tv))-tcGetCastedTyVar_maybe _ = Nothing--tcGetTyVar_maybe :: Type -> Maybe TyVar-tcGetTyVar_maybe ty | Just ty' <- tcView ty = tcGetTyVar_maybe ty'-tcGetTyVar_maybe (TyVarTy tv) = Just tv-tcGetTyVar_maybe _ = Nothing--tcGetTyVar :: String -> Type -> TyVar-tcGetTyVar msg ty- = case tcGetTyVar_maybe ty of- Just tv -> tv- Nothing -> pprPanic msg (ppr ty)- tcIsTyVarTy :: Type -> Bool-tcIsTyVarTy ty | Just ty' <- tcView ty = tcIsTyVarTy ty'+tcIsTyVarTy ty | Just ty' <- coreView ty = tcIsTyVarTy ty' tcIsTyVarTy (CastTy ty _) = tcIsTyVarTy ty -- look through casts, as -- this is only used for -- e.g., FlexibleContexts@@ -1668,178 +1620,6 @@ {- ********************************************************************* * *- Type equalities-* *-********************************************************************* -}--tcEqKind :: HasDebugCallStack => TcKind -> TcKind -> Bool-tcEqKind = tcEqType--tcEqType :: HasDebugCallStack => TcType -> TcType -> Bool--- ^ tcEqType implements typechecker equality, as described in--- @Note [Typechecker equality vs definitional equality]@.-tcEqType ty1 ty2- = tcEqTypeNoSyns ki1 ki2- && tcEqTypeNoSyns ty1 ty2- where- ki1 = tcTypeKind ty1- ki2 = tcTypeKind ty2---- | Just like 'tcEqType', but will return True for types of different kinds--- as long as their non-coercion structure is identical.-tcEqTypeNoKindCheck :: TcType -> TcType -> Bool-tcEqTypeNoKindCheck ty1 ty2- = tcEqTypeNoSyns ty1 ty2---- | Check whether two TyConApps are the same; if the number of arguments--- are different, just checks the common prefix of arguments.-tcEqTyConApps :: TyCon -> [Type] -> TyCon -> [Type] -> Bool-tcEqTyConApps tc1 args1 tc2 args2- = tc1 == tc2 &&- and (zipWith tcEqTypeNoKindCheck args1 args2)- -- No kind check necessary: if both arguments are well typed, then- -- any difference in the kinds of later arguments would show up- -- as differences in earlier (dependent) arguments--{--Note [Specialising tc_eq_type]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The type equality predicates in TcType are hit pretty hard during typechecking.-Consequently we take pains to ensure that these paths are compiled to-efficient, minimally-allocating code.--To this end we place an INLINE on tc_eq_type, ensuring that it is inlined into-its publicly-visible interfaces (e.g. tcEqType). In addition to eliminating-some dynamic branches, this allows the simplifier to eliminate the closure-allocations that would otherwise be necessary to capture the two boolean "mode"-flags. This reduces allocations by a good fraction of a percent when compiling-Cabal.--See #19226.--}---- | Type equality comparing both visible and invisible arguments and expanding--- type synonyms.-tcEqTypeNoSyns :: TcType -> TcType -> 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 :: TcType -> TcType -> Bool-tcEqTypeVis ty1 ty2 = tc_eq_type False True ty1 ty2---- | Like 'pickyEqTypeVis', but returns a Bool for convenience-pickyEqType :: TcType -> TcType -> 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---- | 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- = go orig_env orig_ty1 orig_ty2- where- go :: RnEnv2 -> Type -> Type -> Bool- -- See Note [Comparing nullary type synonyms] in GHC.Core.Type.- go _ (TyConApp tc1 []) (TyConApp tc2 [])- | tc1 == tc2- = True-- go env t1 t2 | not keep_syns, Just t1' <- tcView t1 = go env t1' t2- go env t1 t2 | not keep_syns, Just t2' <- tcView 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 (ForAllTy (Bndr tv1 vis1) ty1)- (ForAllTy (Bndr tv2 vis2) ty2)- = vis1 `sameVis` vis2- -- See Note [ForAllTy and typechecker equality] in- -- GHC.Tc.Solver.Canonical for why we use `sameVis` here- && (vis_only || 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- -- AppTy case means that tcRepSplitAppTy_maybe may see an unzonked- -- kind variable, which causes things to blow up.- -- 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)-- -- See Note [Equality on AppTys] in GHC.Core.Type- go env (AppTy s1 t1) ty2- | Just (s2, t2) <- tcRepSplitAppTy_maybe ty2- = go env s1 s2 && go env t1 t2- go env ty1 (AppTy s2 t2)- | Just (s1, t1) <- tcRepSplitAppTy_maybe ty1- = 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-- go _ _ _ = False-- gos _ _ [] [] = True- gos env (ig:igs) (t1:ts1) (t2:ts2) = (ig || go env t1 t2)- && gos env igs 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].--{- Note [Typechecker equality vs definitional equality]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-GHC has two notions of equality over Core types:--* Definitional equality, as implemented by GHC.Core.Type.eqType.- See Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep.-* Typechecker equality, as implemented by tcEqType (in GHC.Tc.Utils.TcType).- GHC.Tc.Solver.Canonical.canEqNC also respects typechecker equality.--Typechecker equality implies definitional equality: if two types are equal-according to typechecker equality, then they are also equal according to-definitional equality. The converse is not always true, as typechecker equality-is more finer-grained than definitional equality in two places:--* Unlike definitional equality, which equates Type and Constraint, typechecker- treats them as distinct types. See Note [Kind Constraint and kind Type] in- GHC.Core.Type.-* Unlike definitional equality, which does not care about the ArgFlag of a- ForAllTy, typechecker equality treats Required type variable binders as- distinct from Invisible type variable binders.- See Note [ForAllTy and typechecker equality] in GHC.Tc.Solver.Canonical.--}--{- *********************************************************************-* * Predicate types * * ************************************************************************@@ -1905,8 +1685,8 @@ -- so we can't abstract over it -- Nothing fundamental: we could add it where- k1 = tcTypeKind ty1- k2 = tcTypeKind ty2+ k1 = typeKind ty1+ k2 = typeKind ty2 homo_kind = k1 `tcEqType` k2 pickCapturedPreds@@ -2077,15 +1857,15 @@ -- isSigmaTy returns true of any qualified type. It doesn't -- *necessarily* have any foralls. E.g -- f :: (?x::Int) => Int -> Int-isSigmaTy ty | Just ty' <- tcView ty = isSigmaTy ty'+isSigmaTy ty | Just ty' <- coreView ty = isSigmaTy ty' isSigmaTy (ForAllTy {}) = True-isSigmaTy (FunTy { ft_af = InvisArg }) = True+isSigmaTy (FunTy { ft_af = af }) = isInvisibleFunArg af isSigmaTy _ = False isRhoTy :: TcType -> Bool -- True of TcRhoTypes; see Note [TcRhoType]-isRhoTy ty | Just ty' <- tcView ty = isRhoTy ty'+isRhoTy ty | Just ty' <- coreView ty = isRhoTy ty' isRhoTy (ForAllTy {}) = False-isRhoTy (FunTy { ft_af = InvisArg }) = False+isRhoTy (FunTy { ft_af = af }) = isVisibleFunArg af isRhoTy _ = True -- | Like 'isRhoTy', but also says 'True' for 'Infer' types@@ -2096,9 +1876,9 @@ isOverloadedTy :: Type -> Bool -- Yes for a type of a function that might require evidence-passing -- Used only by bindLocalMethods-isOverloadedTy ty | Just ty' <- tcView ty = isOverloadedTy ty'+isOverloadedTy ty | Just ty' <- coreView ty = isOverloadedTy ty' isOverloadedTy (ForAllTy _ ty) = isOverloadedTy ty-isOverloadedTy (FunTy { ft_af = InvisArg }) = True+isOverloadedTy (FunTy { ft_af = af }) = isInvisibleFunArg af isOverloadedTy _ = False isFloatTy, isDoubleTy,@@ -2196,7 +1976,7 @@ visible type application. Tracking specified vs. inferred variables is done conveniently by a field-in TyBinder.+in PiTyVarBinder. -} @@ -2522,8 +2302,8 @@ -- Ignore kinds altogether sizeType = go where- go ty | Just exp_ty <- tcView ty = go exp_ty- go (TyVarTy {}) = 1+ go ty | Just exp_ty <- coreView ty = go exp_ty+ go (TyVarTy {}) = 1 go (TyConApp tc tys) | isTypeFamilyTyCon tc = infinity -- Type-family applications can -- expand to any arbitrary size@@ -2535,10 +2315,10 @@ go (FunTy _ w arg res) = go w + go arg + go res + 1 go (AppTy fun arg) = go fun + go arg go (ForAllTy (Bndr tv vis) ty)- | isVisibleArgFlag vis = go (tyVarKind tv) + go ty + 1- | otherwise = go ty + 1- go (CastTy ty _) = go ty- go (CoercionTy {}) = 0+ | isVisibleForAllTyFlag vis = go (tyVarKind tv) + go ty + 1+ | otherwise = go ty + 1+ go (CastTy ty _) = go ty+ go (CoercionTy {}) = 0 sizeTypes :: [Type] -> TypeSize sizeTypes tys = sum (map sizeType tys)@@ -2553,7 +2333,7 @@ tcTyConVisibilities tc = tc_binder_viss ++ tc_return_kind_viss ++ repeat True where tc_binder_viss = map isVisibleTyConBinder (tyConBinders tc)- tc_return_kind_viss = map isVisibleBinder (fst $ tcSplitPiTys (tyConResKind tc))+ tc_return_kind_viss = map isVisiblePiTyBinder (fst $ tcSplitPiTys (tyConResKind tc)) -- | If the tycon is applied to the types, is the next argument visible? isNextTyConArgVisible :: TyCon -> [Type] -> Bool@@ -2563,7 +2343,7 @@ -- | Should this type be applied to a visible argument? isNextArgVisible :: TcType -> Bool isNextArgVisible ty- | Just (bndr, _) <- tcSplitPiTy_maybe ty = isVisibleBinder bndr+ | Just (bndr, _) <- tcSplitPiTy_maybe ty = isVisiblePiTyBinder bndr | otherwise = True -- this second case might happen if, say, we have an unzonked TauTv. -- But TauTvs can't range over types that take invisible arguments
compiler/GHC/Tc/Utils/TcType.hs-boot view
@@ -2,8 +2,6 @@ import GHC.Utils.Outputable( SDoc ) import GHC.Prelude ( Bool ) import {-# SOURCE #-} GHC.Types.Var ( TcTyVar )-import {-# SOURCE #-} GHC.Core.TyCo.Rep-import GHC.Utils.Misc ( HasDebugCallStack ) import GHC.Stack data MetaDetails@@ -14,6 +12,4 @@ isMetaTyVar :: TcTyVar -> Bool isTyConableTyVar :: TcTyVar -> Bool isConcreteTyVar :: TcTyVar -> Bool--tcEqType :: HasDebugCallStack => Type -> Type -> Bool
compiler/GHC/Types/Basic.hs view
@@ -20,8 +20,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} -{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}- module GHC.Types.Basic ( LeftOrRight(..), pickLR,@@ -49,7 +47,8 @@ CbvMark(..), isMarkedCbv, - PprPrec(..), topPrec, sigPrec, opPrec, funPrec, starPrec, appPrec,+ PprPrec(..), topPrec, sigPrec, opPrec, funPrec,+ starPrec, appPrec, maxPrec, maybeParen, TupleSort(..), tupleSortBoxity, boxityTupleSort,@@ -108,6 +107,7 @@ TypeOrKind(..), isTypeLevel, isKindLevel, Levity(..), mightBeLifted, mightBeUnlifted,+ TypeOrConstraint(..), NonStandardDefaultingStrategy(..), DefaultingStrategy(..), defaultNonStandardTyVars,@@ -129,13 +129,11 @@ import {-# SOURCE #-} Language.Haskell.Syntax.Type (PromotionFlag(..), isPromoted) import Language.Haskell.Syntax.Basic (Boxity(..), isBoxed, ConTag) -{--************************************************************************+{- ********************************************************************* * * Binary choice * *-************************************************************************--}+********************************************************************* -} data LeftOrRight = CLeft | CRight deriving( Eq, Data )@@ -748,16 +746,17 @@ newtype PprPrec = PprPrec Int deriving (Eq, Ord, Show) -- See Note [Precedence in types] -topPrec, sigPrec, funPrec, opPrec, starPrec, appPrec :: PprPrec-topPrec = PprPrec 0 -- No parens-sigPrec = PprPrec 1 -- Explicit type signatures-funPrec = PprPrec 2 -- Function args; no parens for constructor apps- -- See [Type operator precedence] for why both- -- funPrec and opPrec exist.-opPrec = PprPrec 2 -- Infix operator+topPrec, sigPrec, funPrec, opPrec, starPrec, appPrec, maxPrec :: PprPrec+topPrec = PprPrec 0 -- No parens+sigPrec = PprPrec 1 -- Explicit type signatures+funPrec = PprPrec 2 -- Function args; no parens for constructor apps+ -- See [Type operator precedence] for why both+ -- funPrec and opPrec exist.+opPrec = PprPrec 2 -- Infix operator starPrec = PprPrec 3 -- Star syntax for the type of types, i.e. the * in (* -> *) -- See Note [Star kind precedence] appPrec = PprPrec 4 -- Constructor args; no parens for atomic+maxPrec = appPrec -- Maximum precendence maybeParen :: PprPrec -> PprPrec -> SDoc -> SDoc maybeParen ctxt_prec inner_prec pretty@@ -1936,10 +1935,17 @@ {- ********************************************************************* * *- Levity information+ Levity and TypeOrConstraint * * ********************************************************************* -} +{- The types `Levity` and `TypeOrConstraint` are internal to GHC.+ They have the same shape as the eponymous types in the library+ ghc-prim:GHC.Types+ but they aren't the same types -- after all, they are defined in a+ different module.+-}+ data Levity = Lifted | Unlifted@@ -1956,6 +1962,11 @@ mightBeUnlifted :: Maybe Levity -> Bool mightBeUnlifted (Just Lifted) = False mightBeUnlifted _ = True++data TypeOrConstraint+ = TypeLike | ConstraintLike+ deriving( Eq, Ord, Data )+ {- ********************************************************************* * *
compiler/GHC/Types/CostCentre.hs view
@@ -3,7 +3,9 @@ CostCentre(..), CcName, CCFlavour(..), -- All abstract except to friend: ParseIface.y + pprCostCentre, CostCentreStack,+ pprCostCentreStack, CollectedCCs, emptyCollectedCCs, collectCC, currentCCS, dontCareCCS, isCurrentCCS,@@ -159,9 +161,9 @@ -- Unique. -- See bug #249, tests prof001, prof002, also #2411 str | isExternalName name = occNameFS (getOccName id)- | otherwise = occNameFS (getOccName id)- `appendFS`- mkFastString ('_' : show (getUnique name))+ | otherwise = concatFS [occNameFS (getOccName id),+ fsLit "_",+ mkFastString (show (getUnique name))] mkAllCafsCC :: Module -> SrcSpan -> CostCentre mkAllCafsCC m loc = AllCafsCC { cc_mod = m, cc_loc = loc } @@ -236,10 +238,14 @@ -- expression. instance Outputable CostCentreStack where- ppr CurrentCCS = text "CCCS"- ppr DontCareCCS = text "CCS_DONT_CARE"- ppr (SingletonCCS cc) = ppr cc <> text "_ccs"+ ppr = pprCostCentreStack +pprCostCentreStack :: IsLine doc => CostCentreStack -> doc+pprCostCentreStack CurrentCCS = text "CCCS"+pprCostCentreStack DontCareCCS = text "CCS_DONT_CARE"+pprCostCentreStack (SingletonCCS cc) = pprCostCentre cc <> text "_ccs"+{-# SPECIALISE pprCostCentreStack :: CostCentreStack -> SDoc #-}+{-# SPECIALISE pprCostCentreStack :: CostCentreStack -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable ----------------------------------------------------------------------------- -- Printing Cost Centres@@ -256,11 +262,16 @@ -- by costCentreName. instance Outputable CostCentre where- ppr cc = getPprStyle $ \ sty ->- if codeStyle sty- then ppCostCentreLbl cc- else ftext (costCentreUserNameFS cc)+ ppr = pprCostCentre +pprCostCentre :: IsLine doc => CostCentre -> doc+pprCostCentre cc = docWithContext $ \ sty ->+ if codeStyle (sdocStyle sty)+ then ppCostCentreLbl cc+ else ftext (costCentreUserNameFS cc)+{-# SPECIALISE pprCostCentre :: CostCentre -> SDoc #-}+{-# SPECIALISE pprCostCentre :: CostCentre -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable+ -- Printing in Core pprCostCentreCore :: CostCentre -> SDoc pprCostCentreCore (AllCafsCC {cc_mod = m})@@ -284,26 +295,32 @@ pprIdxCore idx = whenPprDebug $ ppr idx -- Printing as a C label-ppCostCentreLbl :: CostCentre -> SDoc-ppCostCentreLbl (AllCafsCC {cc_mod = m}) = ppr m <> text "_CAFs_cc"+ppCostCentreLbl :: IsLine doc => CostCentre -> doc+ppCostCentreLbl (AllCafsCC {cc_mod = m}) = pprModule m <> text "_CAFs_cc" ppCostCentreLbl (NormalCC {cc_flavour = f, cc_name = n, cc_mod = m})- = ppr m <> char '_' <> ztext (zEncodeFS n) <> char '_' <>+ = pprModule m <> char '_' <> ztext (zEncodeFS n) <> char '_' <> ppFlavourLblComponent f <> text "_cc"+{-# SPECIALISE ppCostCentreLbl :: CostCentre -> SDoc #-}+{-# SPECIALISE ppCostCentreLbl :: CostCentre -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -- ^ Print the flavour component of a C label-ppFlavourLblComponent :: CCFlavour -> SDoc+ppFlavourLblComponent :: IsLine doc => CCFlavour -> doc ppFlavourLblComponent CafCC = text "CAF" ppFlavourLblComponent (ExprCC i) = text "EXPR" <> ppIdxLblComponent i ppFlavourLblComponent (DeclCC i) = text "DECL" <> ppIdxLblComponent i ppFlavourLblComponent (HpcCC i) = text "HPC" <> ppIdxLblComponent i ppFlavourLblComponent (LateCC i) = text "LATECC" <> ppIdxLblComponent i+{-# SPECIALISE ppFlavourLblComponent :: CCFlavour -> SDoc #-}+{-# SPECIALISE ppFlavourLblComponent :: CCFlavour -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -- ^ Print the flavour index component of a C label-ppIdxLblComponent :: CostCentreIndex -> SDoc+ppIdxLblComponent :: IsLine doc => CostCentreIndex -> doc ppIdxLblComponent n = case unCostCentreIndex n of 0 -> empty- n -> ppr n+ n -> int n+{-# SPECIALISE ppIdxLblComponent :: CostCentreIndex -> SDoc #-}+{-# SPECIALISE ppIdxLblComponent :: CostCentreIndex -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -- This is the name to go in the user-displayed string, -- recorded in the cost centre declaration
compiler/GHC/Types/Demand.hs view
@@ -94,7 +94,7 @@ import GHC.Core.Type ( Type ) import GHC.Core.TyCon ( isNewTyCon, isClassTyCon )-import GHC.Core.DataCon ( splitDataProductType_maybe )+import GHC.Core.DataCon ( splitDataProductType_maybe, StrictnessMark, isMarkedStrict ) import GHC.Core.Multiplicity ( scaledThing ) import GHC.Utils.Binary@@ -106,9 +106,6 @@ import Data.Coerce (coerce) import Data.Function -import GHC.Utils.Trace-_ = pprTrace -- Tired of commenting out the import all the time- {- ************************************************************************ * *@@ -1035,10 +1032,13 @@ -- whether it was unsaturated in the form of a 'Card'inality, denoting -- how many times the lambda body was entered. -- See Note [Demands from unsaturated function calls].-peelManyCalls :: Int -> SubDemand -> Card-peelManyCalls 0 _ = C_11-peelManyCalls n (viewCall -> Just (m, sd)) = m `multCard` peelManyCalls (n-1) sd-peelManyCalls _ _ = C_0N+peelManyCalls :: Arity -> SubDemand -> (Card, SubDemand)+peelManyCalls k sd = go k C_11 sd+ where+ go 0 !n !sd = (n, sd)+ go k !n (viewCall -> Just (m, sd)) = go (k-1) (n `multCard` m) sd+ go _ _ _ = (topCard, topSubDmd)+{-# INLINE peelManyCalls #-} -- so that the pair cancels away in a `fst _` context -- | Extract the 'SubDemand' of a 'Demand'. -- PRECONDITION: The SubDemand must be used in a context where the expression@@ -1088,7 +1088,7 @@ saturatedByOneShots :: Int -> Demand -> Bool saturatedByOneShots _ AbsDmd = True saturatedByOneShots _ BotDmd = True-saturatedByOneShots n (_ :* sd) = isUsedOnce (peelManyCalls n sd)+saturatedByOneShots n (_ :* sd) = isUsedOnce $ fst $ peelManyCalls n sd {- Note [Strict demands] ~~~~~~~~~~~~~~~~~~~~~~~~@@ -1377,6 +1377,46 @@ the boxity info has to be stored in the *sub-demand* `sd`! There's no demand to store the boxity in. So we bit the bullet and now we store Boxity in 'SubDemand', both in 'Prod' *and* 'Poly'. See also Note [Boxity in Poly].++Note [Demand transformer for data constructors]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider the expression (x,y) with sub-demand P(SL,A). What is the demand on+x,y? Obviously `x` is used strictly, and `y` not at all. So we want to+decompose a product demand, and feed its components demands into the+arguments. That is the job of dmdTransformDataConSig. More precisely,++ * it gets the demand on the data constructor itself;+ in the above example that is C(1,C(1,P(SL,A)))+ * it returns the demands on the arguments;+ in the above example that is [SL, A]++Nasty wrinkle. Consider this code (#22475 has more realistic examples but+assume this is what the demand analyser sees)++ data T = MkT !Int Bool+ get :: T -> Bool+ get (MkT _ b) = b++ foo = let v::Int = I# 7+ t::T = MkT v True+ in get t++Now `v` is unused by `get`, /but/ we can't give `v` an Absent demand,+else we'll drop the binding and replace it with an error thunk.+Then the code generator (more specifically GHC.Stg.InferTags.Rewrite)+will add an extra eval of MkT's argument to give+ foo = let v::Int = error "absent"+ t::T = case v of v' -> MkT v' True+ in get t++Boo! Because of this extra eval (added in STG-land), the truth is that `MkT`+may (or may not) evaluate its arguments (as established in #21497). Hence the+use of `bump` in dmdTransformDataConSig, which adds in a `C_01` eval. The+`C_01` says "may or may not evaluate" which is absolutely faithful to what+InferTags.Rewrite does.++In particular it is very important /not/ to make that a `C_11` eval,+see Note [Data-con worker strictness]. -} {- *********************************************************************@@ -2269,20 +2309,24 @@ -- return how the function evaluates its free variables and arguments. dmdTransformSig :: DmdSig -> DmdTransformer dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds _)) sd- = multDmdType (peelManyCalls (length arg_ds) sd) dmd_ty+ = multDmdType (fst $ peelManyCalls (length arg_ds) sd) dmd_ty -- see Note [Demands from unsaturated function calls] -- and Note [What are demand signatures?] -- | A special 'DmdTransformer' for data constructors that feeds product -- demands into the constructor arguments.-dmdTransformDataConSig :: Arity -> DmdTransformer-dmdTransformDataConSig arity sd = case go arity sd of- Just dmds -> DmdType emptyDmdEnv dmds topDiv- Nothing -> nopDmdType -- Not saturated+dmdTransformDataConSig :: [StrictnessMark] -> DmdTransformer+-- See Note [Demand transformer for data constructors]+dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of+ Just (_, dmds) -> mk_body_ty n dmds+ Nothing -> nopDmdType where- go 0 sd = snd <$> viewProd arity sd- go n (Call C_11 sd) = go (n-1) sd -- strict calls only!- go _ _ = Nothing+ arity = length str_marks+ (n, body_sd) = peelManyCalls arity sd+ mk_body_ty n dmds = DmdType emptyDmdEnv (zipWith (bump n) str_marks dmds) topDiv+ bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd)+ | otherwise = multDmd n dmd+ str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] -- | A special 'DmdTransformer' for dictionary selectors that feeds the demand -- on the result into the indicated dictionary component (if saturated).
compiler/GHC/Types/Error.hs view
@@ -351,7 +351,7 @@ data MsgEnvelope e = MsgEnvelope { errMsgSpan :: SrcSpan -- ^ The SrcSpan is used for sorting errors into line-number order- , errMsgContext :: PrintUnqualified+ , errMsgContext :: NamePprCtx , errMsgDiagnostic :: e , errMsgSeverity :: Severity } deriving (Functor, Foldable, Traversable)
compiler/GHC/Types/Error/Codes.hs view
@@ -267,6 +267,7 @@ GhcDiagnosticCode "PsErrIllegalGadtRecordMultiplicity" = 37475 GhcDiagnosticCode "PsErrInvalidCApiImport" = 72744 GhcDiagnosticCode "PsErrMultipleConForNewtype" = 05380+ GhcDiagnosticCode "PsErrUnicodeCharLooksLike" = 31623 -- Driver diagnostic codes GhcDiagnosticCode "DriverMissingHomeModules" = 32850@@ -421,6 +422,16 @@ GhcDiagnosticCode "TcRnIllegalTypeOperator" = 62547 GhcDiagnosticCode "TcRnGADTMonoLocalBinds" = 58008 GhcDiagnosticCode "TcRnIncorrectNameSpace" = 31891+ GhcDiagnosticCode "TcRnNoRebindableSyntaxRecordDot" = 65945+ GhcDiagnosticCode "TcRnNoFieldPunsRecordDot" = 57365+ GhcDiagnosticCode "TcRnIllegalStaticExpression" = 23800+ GhcDiagnosticCode "TcRnIllegalStaticFormInSplice" = 12219+ GhcDiagnosticCode "TcRnListComprehensionDuplicateBinding" = 81232+ GhcDiagnosticCode "TcRnLastStmtNotExpr" = 55814+ GhcDiagnosticCode "TcRnUnexpectedStatementInContext" = 42026+ GhcDiagnosticCode "TcRnSectionWithoutParentheses" = 95880+ GhcDiagnosticCode "TcRnIllegalImplicitParameterBindings" = 50730+ GhcDiagnosticCode "TcRnIllegalTupleSection" = 59155 GhcDiagnosticCode "TcRnUntickedPromotedThing" = 49957 GhcDiagnosticCode "TcRnIllegalBuiltinSyntax" = 39716@@ -482,6 +493,13 @@ GhcDiagnosticCode "TcRnCannotRepresentType" = 75721 GhcDiagnosticCode "TcRnReportCustomQuasiError" = 39584 GhcDiagnosticCode "TcRnInterfaceLookupError" = 52243+ GhcDiagnosticCode "TcRnUnsatisfiedMinimalDef" = 06201+ GhcDiagnosticCode "TcRnMisplacedInstSig" = 06202+ GhcDiagnosticCode "TcRnBadBootFamInstDecl" = 06203+ GhcDiagnosticCode "TcRnIllegalFamilyInstance" = 06204+ GhcDiagnosticCode "TcRnMissingClassAssoc" = 06205+ GhcDiagnosticCode "TcRnBadFamInstDecl" = 06206+ GhcDiagnosticCode "TcRnNotOpenFamily" = 06207 -- IllegalNewtypeReason GhcDiagnosticCode "DoesNotHaveSingleField" = 23517@@ -572,6 +590,12 @@ GhcDiagnosticCode "DerivErrGenerics" = 30367 GhcDiagnosticCode "DerivErrEnumOrProduct" = 58291 + -- TcRnEmptyStmtsGroupError/EmptyStatementGroupErrReason+ GhcDiagnosticCode "EmptyStmtsGroupInParallelComp" = 41242+ GhcDiagnosticCode "EmptyStmtsGroupInTransformListComp" = 92693+ GhcDiagnosticCode "EmptyStmtsGroupInDoNotation" = 82311+ GhcDiagnosticCode "EmptyStmtsGroupInArrowNotation" = 19442+ -- To generate new random numbers: -- https://www.random.org/integers/?num=10&min=1&max=99999&col=1&base=10&format=plain --@@ -663,6 +687,8 @@ -- Recur inside Mismatch to get the underlying reason ConRecursInto "Mismatch" = 'Just MismatchMsg + -- Recur inside empty statements groups to get the underlying statements block+ ConRecursInto "TcRnEmptyStmtsGroup" = 'Just EmptyStatementGroupErrReason ---------------------------------- -- Constructors of DsMessage
compiler/GHC/Types/ForeignStubs.hs view
@@ -1,5 +1,6 @@ -- | Foreign export stubs {-# LANGUAGE DerivingVia #-}+{-# LANGUAGE TypeApplications #-} module GHC.Types.ForeignStubs ( ForeignStubs (..) , CHeader(..)@@ -68,10 +69,10 @@ instance Monoid CHeader where mempty = CHeader empty- mconcat = coerce vcat+ mconcat = coerce (vcat @SDoc) instance Semigroup CHeader where- (<>) = coerce ($$)+ (<>) = coerce (($$) @SDoc) -- | Foreign export stubs data ForeignStubs
compiler/GHC/Types/Id.hs view
@@ -163,7 +163,6 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Panic.Plain-import GHC.Utils.Trace import GHC.Stg.InferTags.TagSig -- infixl so you can say (id `set` a `set` b)@@ -310,7 +309,7 @@ mkLocalCoVar :: Name -> Type -> CoVar mkLocalCoVar name ty = assert (isCoVarType ty) $- Var.mkLocalVar CoVarId name Many ty vanillaIdInfo+ 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@@ -378,7 +377,7 @@ -- | Workers get local names. "CoreTidy" will externalise these if necessary mkWorkerId :: Unique -> Id -> Type -> Id mkWorkerId uniq unwrkr ty- = mkLocalId (mkDerivedInternalName mkWorkerOcc uniq (getName unwrkr)) Many ty+ = mkLocalId (mkDerivedInternalName mkWorkerOcc uniq (getName unwrkr)) ManyTy ty -- | Create a /template local/: a family of system local 'Id's in bijection with @Int@s, typically used in unfoldings mkTemplateLocal :: Int -> Type -> Id
compiler/GHC/Types/Id/Make.hs view
@@ -17,7 +17,7 @@ {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module GHC.Types.Id.Make (- mkDictFunId, mkDictFunTy, mkDictSelId, mkDictSelRhs,+ mkDictFunId, mkDictSelId, mkDictSelRhs, mkFCallId, @@ -33,7 +33,10 @@ voidPrimId, voidArgId, nullAddrId, seqId, lazyId, lazyIdKey, coercionTokenId, coerceId,- proxyHashId, noinlineId, noinlineIdName, nospecId, nospecIdName,+ proxyHashId,+ nospecId, nospecIdName,+ noinlineId, noinlineIdName,+ noinlineConstraintId, noinlineConstraintIdName, coerceName, leftSectionName, rightSectionName, ) where @@ -53,7 +56,7 @@ import GHC.Core.Reduction import GHC.Core.Make import GHC.Core.FVs ( mkRuleInfo )-import GHC.Core.Utils ( exprType, mkCast, mkDefaultCase )+import GHC.Core.Utils ( exprType, mkCast, mkDefaultCase, coreAltsType ) import GHC.Core.Unfold.Make import GHC.Core.SimpleOpt import GHC.Core.TyCon@@ -71,7 +74,7 @@ import GHC.Types.Cpr import GHC.Types.Unique.Supply import GHC.Types.Basic hiding ( SuccessFlag(..) )-import GHC.Types.Var (VarBndr(Bndr))+import GHC.Types.Var (VarBndr(Bndr), visArgConstraintLike) import GHC.Tc.Utils.TcType as TcType @@ -82,6 +85,7 @@ import GHC.Data.FastString import GHC.Data.List.SetOps+import Data.List ( zipWith4 ) {- ************************************************************************@@ -160,7 +164,7 @@ ++ errorIds -- Defined in GHC.Core.Make magicIds :: [Id] -- See Note [magicIds]-magicIds = [lazyId, oneShotId, noinlineId, nospecId]+magicIds = [lazyId, oneShotId, noinlineId, noinlineConstraintId, nospecId] ghcPrimIds :: [Id] -- See Note [ghcPrimIds (aka pseudoops)] ghcPrimIds@@ -308,14 +312,15 @@ Note [Newtype datacons] ~~~~~~~~~~~~~~~~~~~~~~~-The "data constructor" for a newtype should always be vanilla. At one-point this wasn't true, because the newtype arising from+The "data constructor" for a newtype should have no existentials. It's+not quite a "vanilla" data constructor, because the newtype arising from class C a => D a-looked like- newtype T:D a = D:D (C a)-so the data constructor for T:C had a single argument, namely the-predicate (C a). But now we treat that as an ordinary argument, not-part of the theta-type, so all is well.+looks like+ newtype T:D a = C:D (C a)+so the data constructor for T:C has a single argument, namely the+predicate (C a). That ends up in the dcOtherTheta for the data con,+which makes it not vanilla. So the assert just tests for existentials.+The rest is checked by having a singleton arg_tys. Note [Newtype workers] ~~~~~~~~~~~~~~~~~~~~~~@@ -472,7 +477,7 @@ val_index = assoc "MkId.mkDictSelId" (sel_names `zip` [0..]) name sel_ty = mkInvisForAllTys tyvars $- mkInvisFunTyMany (mkClassPred clas (mkTyVarTys (binderVars tyvars))) $+ mkFunctionType ManyTy (mkClassPred clas (mkTyVarTys (binderVars tyvars))) $ scaledThing (getNth arg_tys val_index) -- See Note [Type classes and linear types] @@ -585,11 +590,14 @@ `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0+ -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con+ ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con+ ex_tcvs = dataConExTyCoVars data_con arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo `setArityInfo` 1 -- Arity 1@@ -597,8 +605,8 @@ `setUnfoldingInfo` newtype_unf id_arg1 = mkScaledTemplateLocal 1 (head arg_tys) res_ty_args = mkTyCoVarTys univ_tvs- newtype_unf = assertPpr (isVanillaDataCon data_con && isSingleton arg_tys)- (ppr data_con) $+ newtype_unf = assertPpr (null ex_tcvs && isSingleton arg_tys)+ (ppr data_con) -- Note [Newtype datacons] mkCompulsoryUnfolding $ mkLams univ_tvs $ Lam id_arg1 $@@ -692,7 +700,7 @@ -- applications are treated as values `setInlinePragInfo` wrap_prag `setUnfoldingInfo` wrap_unf- `setDmdSigInfo` wrap_sig+ `setDmdSigInfo` wrap_sig -- We need to get the CAF info right here because GHC.Iface.Tidy -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane@@ -739,10 +747,10 @@ where (univ_tvs, ex_tvs, eq_spec, theta, orig_arg_tys, _orig_res_ty)- = dataConFullSig data_con+ = dataConFullSig data_con stupid_theta = dataConStupidTheta data_con wrap_tvs = dataConUserTyVars data_con- res_ty_args = substTyVars (mkTvSubstPrs (map eqSpecPair eq_spec)) univ_tvs+ res_ty_args = dataConResRepTyArgs data_con tycon = dataConTyCon data_con -- The representation TyCon (not family) wrap_ty = dataConWrapperType data_con@@ -780,16 +788,16 @@ (not new_tycon -- (Most) newtypes have only a worker, with the exception -- of some newtypes written with GADT syntax. See below.- && (any isBanged (ev_ibangs ++ arg_ibangs)+ && (any isBanged (ev_ibangs ++ arg_ibangs))) -- Some forcing/unboxing (includes eq_spec)- || (not $ null eq_spec))) -- GADT || isFamInstTyCon tycon -- Cast result- || dataConUserTyVarsArePermuted 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 -- the type variables. -- See Note [Data con wrappers and GADT syntax].+ -- NB: All GADTs return true from this function || not (null stupid_theta) -- If the data constructor has a datatype context, -- we need a wrapper in order to drop the stupid arguments.@@ -1021,14 +1029,8 @@ arg_ty' = case mb_co of { Just redn -> scaledSet arg_ty (reductionReducedType redn) ; Nothing -> arg_ty }- , isUnpackableType bang_opts fam_envs (scaledThing arg_ty')- , (rep_tys, _) <- dataConArgUnpack arg_ty'- , case unpk_prag of- NoSrcUnpack ->- bang_opt_unbox_strict bang_opts- || (bang_opt_unbox_small bang_opts- && rep_tys `lengthAtMost` 1) -- See Note [Unpack one-wide fields]- srcUnpack -> isSrcUnpacked srcUnpack+ , all (not . isNewTyCon . fst) (splitTyConApp_maybe $ scaledThing arg_ty')+ , shouldUnpackTy bang_opts unpk_prag fam_envs arg_ty' = case mb_co of Nothing -> HsUnpack Nothing Just redn -> HsUnpack (Just $ reductionCoercion redn)@@ -1036,7 +1038,6 @@ | otherwise -- Record the strict-but-no-unpack decision = HsStrict - -- | Wrappers/Workers and representation following Unpack/Strictness -- decisions dataConArgRep@@ -1052,8 +1053,7 @@ = ([(arg_ty, MarkedStrict)], (seqUnboxer, unitBoxer)) dataConArgRep arg_ty (HsUnpack Nothing)- | (rep_tys, wrappers) <- dataConArgUnpack arg_ty- = (rep_tys, wrappers)+ = dataConArgUnpack arg_ty dataConArgRep (Scaled w _) (HsUnpack (Just co)) | let co_rep_ty = coercionRKind co@@ -1090,50 +1090,231 @@ unitBoxer = UnitBox -------------------------++{- Note [UNPACK for sum types]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose we have a data type D, for example:+ data D = D1 [Int] [Bool]+ | D2++and another data type which unpacks a field of type D:+ data U a = MkU {-# UNPACK #-} !D+ {-# UNPACK #-} !(a,a)+ {-# UNPACK #-} !D++Then the wrapper and worker for MkU have these types++ -- Wrapper+ $WMkU :: D -> (a,a) -> D -> U a++ -- Worker+ MkU :: (# (# [Int],[Bool] #) | (# #) #)+ -> a+ -> a+ -> (# (# [Int],[Bool] #) | (# #) #)+ -> U a++For each unpacked /sum/-type argument, the worker gets one argument.+But for each unpacked /product/-type argument, the worker gets N+arguments (here two).++Why treat them differently? See Note [Why sums and products are treated differently].++The wrapper $WMkU looks like this:++ $WMkU :: D -> (a,a) -> D -> U a+ $WMkU x1 y x2+ = case (case x1 of {+ D1 a b -> (# (# a,b #) | #)+ D2 -> (# | (# #) #) }) of { x1_ubx ->+ case y of { (y1, y2) ->+ case (case x2 of {+ D1 a b -> (# (# a,b #) | #)+ D2 -> (# | (# #) #) }) of { x2_ubx ->+ MkU x1_ubx y1 y2 x2_ubx++Notice the nested case needed for sums.++This different treatment for sums and product is implemented in+dataConArgUnpackSum and dataConArgUnpackProduct respectively.++Note [Why sums and products are treated differently]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Can we handle sums like products, with each wrapper argument+occupying multiple argument slots in the worker? No: for a sum+type the number of argument slots varies, and that's exactly what+unboxed sums are designed for.++Can we handle products like sums, with each wrapper argument occupying+exactly one argument slot (and unboxed tuple) in the worker? Yes,+we could. For example+ data P = MkP {-# UNPACK #-} !Q+ data Q = MkQ {-# NOUNPACK #-} !Int+ {-# NOUNPACK #-} Int++Currently could unpack P thus, taking two slots in the worker+ $WMkP :: Q -> P+ $WMkP x = case x of { MkQ a b -> MkP a b }+ MkP :: Int -> Int -> P -- Worker++We could instead do this (uniformly with sums)++ $WMkP1 :: Q -> P+ $WMkP1 x = case (case x of { MkQ a b -> (# a, b #) }) of ubx_x+ MkP1 ubx_x+ MkP1 :: (# Int, Int #) -> P -- Worker++The representation of MkP and MkP1 would be identical (a constructor+with two fields).++BUT, with MkP (as with every data constructor) we record its argument+strictness as a bit-vector, actually [StrictnessMark]+ MkP strictness: SL+This information is used in Core to record which fields are sure to+be evaluated. (Look for calls to dataConRepStrictness.) E.g. in Core+ case v of MkP x y -> ....<here x is known to be evald>....++Alas, with MkP1 this information is hidden by the unboxed pair,+In Core there will be an auxiliary case expression to take apart the pair:+ case v of MkP1 xy -> case xy of (# x,y #) -> ...+And now we have no easy way to know that x is evaluated in the "...".++Fixing this might be possible, but it'd be tricky. So we avoid the+problem entirely by treating sums and products differently here.+-}+ dataConArgUnpack :: Scaled Type -> ( [(Scaled Type, StrictnessMark)] -- Rep types , (Unboxer, Boxer) )--dataConArgUnpack (Scaled arg_mult arg_ty)+dataConArgUnpack scaledTy@(Scaled _ arg_ty) | Just (tc, tc_args) <- splitTyConApp_maybe arg_ty- , Just con <- tyConSingleAlgDataCon_maybe tc- -- NB: check for an *algebraic* data type- -- A recursive newtype might mean that- -- 'arg_ty' is a newtype- , let rep_tys = map (scaleScaled arg_mult) $ dataConInstArgTys con tc_args- = assert (null (dataConExTyCoVars con))- -- Note [Unpacking GADTs and existentials]- ( rep_tys `zip` dataConRepStrictness con- ,( \ arg_id ->- do { rep_ids <- mapM (newLocal (fsLit "unbx")) rep_tys- ; let r_mult = idMult arg_id- ; let rep_ids' = map (scaleIdBy r_mult) rep_ids- ; let unbox_fn body- = mkSingleAltCase (Var arg_id) arg_id- (DataAlt con) rep_ids' body- ; return (rep_ids, unbox_fn) }- , Boxer $ \ subst ->- do { rep_ids <- mapM (newLocal (fsLit "bx") . TcType.substScaledTyUnchecked subst) rep_tys- ; return (rep_ids, Var (dataConWorkId con)- `mkTyApps` (substTysUnchecked subst tc_args)- `mkVarApps` rep_ids ) } ) )+ = assert (not (isNewTyCon tc)) $+ case tyConDataCons tc of+ [con] -> dataConArgUnpackProduct scaledTy tc_args con+ cons -> dataConArgUnpackSum scaledTy tc_args cons | otherwise = pprPanic "dataConArgUnpack" (ppr arg_ty) -- An interface file specified Unpacked, but we couldn't unpack it -isUnpackableType :: BangOpts -> FamInstEnvs -> Type -> Bool--- True if we can unpack the UNPACK the argument type+dataConArgUnpackProduct+ :: Scaled Type+ -> [Type]+ -> DataCon+ -> ( [(Scaled Type, StrictnessMark)] -- Rep types+ , (Unboxer, Boxer) )+dataConArgUnpackProduct (Scaled arg_mult _) tc_args con =+ assert (null (dataConExTyCoVars con)) $+ -- Note [Unpacking GADTs and existentials]+ let rep_tys = map (scaleScaled arg_mult) $ dataConInstArgTys con tc_args+ in ( rep_tys `zip` dataConRepStrictness con+ , ( \ arg_id ->+ do { rep_ids <- mapM (newLocal (fsLit "unbx")) rep_tys+ ; let r_mult = idMult arg_id+ ; let rep_ids' = map (scaleIdBy r_mult) rep_ids+ ; let unbox_fn body+ = mkSingleAltCase (Var arg_id) arg_id+ (DataAlt con) rep_ids' body+ ; return (rep_ids, unbox_fn) }+ , Boxer $ \ subst ->+ do { rep_ids <- mapM (newLocal (fsLit "bx") . TcType.substScaledTyUnchecked subst) rep_tys+ ; return (rep_ids, Var (dataConWorkId con)+ `mkTyApps` (substTysUnchecked subst tc_args)+ `mkVarApps` rep_ids ) } ) )++dataConArgUnpackSum+ :: Scaled Type+ -> [Type]+ -> [DataCon]+ -> ( [(Scaled Type, StrictnessMark)] -- Rep types+ , (Unboxer, Boxer) )+dataConArgUnpackSum (Scaled arg_mult arg_ty) tc_args cons =+ ( [ (sum_ty, MarkedStrict) ] -- The idea: Unpacked variant will+ -- be one field only, and the type of the+ -- field will be an unboxed sum.+ , ( unboxer, boxer ) )+ where+ !ubx_sum_arity = length cons+ src_tys = map (\con -> map scaledThing $ dataConInstArgTys con tc_args) cons+ sum_alt_tys = map mkUbxSumAltTy src_tys+ sum_ty_unscaled = mkSumTy sum_alt_tys+ sum_ty = Scaled arg_mult sum_ty_unscaled+ newLocal' fs = newLocal fs . Scaled arg_mult++ -- See Note [UNPACK for sum types]+ unboxer :: Unboxer+ unboxer arg_id = do+ con_arg_binders <- mapM (mapM (newLocal' (fsLit "unbx"))) src_tys+ ubx_sum_bndr <- newLocal (fsLit "unbx") sum_ty++ let+ mk_ubx_sum_alt :: Int -> DataCon -> [Var] -> CoreAlt+ mk_ubx_sum_alt alt con [bndr] = Alt (DataAlt con) [bndr]+ (mkCoreUnboxedSum ubx_sum_arity alt sum_alt_tys (Var bndr))++ mk_ubx_sum_alt alt con bndrs =+ let tuple = mkCoreUnboxedTuple (map Var bndrs)+ in Alt (DataAlt con) bndrs (mkCoreUnboxedSum ubx_sum_arity alt sum_alt_tys tuple )++ ubx_sum :: CoreExpr+ ubx_sum =+ let alts = zipWith3 mk_ubx_sum_alt [ 1 .. ] cons con_arg_binders+ in Case (Var arg_id) arg_id (coreAltsType alts) alts++ unbox_fn :: CoreExpr -> CoreExpr+ unbox_fn body =+ mkSingleAltCase ubx_sum ubx_sum_bndr DEFAULT [] body++ return ([ubx_sum_bndr], unbox_fn)++ boxer :: Boxer+ boxer = Boxer $ \ subst -> do+ unboxed_field_id <- newLocal' (fsLit "bx") (TcType.substTy subst sum_ty_unscaled)+ tuple_bndrs <- mapM (newLocal' (fsLit "bx") . TcType.substTy subst) sum_alt_tys++ let tc_args' = substTys subst tc_args+ arg_ty' = substTy subst arg_ty++ con_arg_binders <-+ mapM (mapM (newLocal' (fsLit "bx")) . map (TcType.substTy subst)) src_tys++ let mk_sum_alt :: Int -> DataCon -> Var -> [Var] -> CoreAlt+ mk_sum_alt alt con _ [datacon_bndr] =+ ( Alt (DataAlt (sumDataCon alt ubx_sum_arity)) [datacon_bndr]+ (Var (dataConWorkId con) `mkTyApps` tc_args'+ `mkVarApps` [datacon_bndr] ))++ mk_sum_alt alt con tuple_bndr datacon_bndrs =+ ( Alt (DataAlt (sumDataCon alt ubx_sum_arity)) [tuple_bndr] (+ Case (Var tuple_bndr) tuple_bndr arg_ty'+ [ Alt (DataAlt (tupleDataCon Unboxed (length datacon_bndrs))) datacon_bndrs+ (Var (dataConWorkId con) `mkTyApps` tc_args'+ `mkVarApps` datacon_bndrs ) ] ))++ return ( [unboxed_field_id],+ Case (Var unboxed_field_id) unboxed_field_id arg_ty'+ (zipWith4 mk_sum_alt [ 1 .. ] cons tuple_bndrs con_arg_binders) )++-- | Every alternative of an unboxed sum has exactly one field, and we use+-- unboxed tuples when we need more than one field. This generates an unboxed+-- tuple when necessary, to be used in unboxed sum alts.+mkUbxSumAltTy :: [Type] -> Type+mkUbxSumAltTy [ty] = ty+mkUbxSumAltTy tys = mkTupleTy Unboxed tys++shouldUnpackTy :: BangOpts -> SrcUnpackedness -> FamInstEnvs -> Scaled Type -> Bool+-- True if we ought to unpack the UNPACK the argument type -- See Note [Recursive unboxing] -- We look "deeply" inside rather than relying on the DataCons -- we encounter on the way, because otherwise we might well -- end up relying on ourselves!-isUnpackableType bang_opts fam_envs ty- | Just data_con <- unpackable_type ty- = ok_con_args emptyNameSet data_con+shouldUnpackTy bang_opts prag fam_envs ty+ | Just data_cons <- unpackable_type_datacons (scaledThing ty)+ = all (ok_con_args emptyNameSet) data_cons && should_unpack data_cons | otherwise = False where+ ok_con_args :: NameSet -> DataCon -> Bool ok_con_args dcs con | dc_name `elemNameSet` dcs = False@@ -1146,17 +1327,20 @@ dc_name = getName con dcs' = dcs `extendNameSet` dc_name + ok_arg :: NameSet -> (Scaled Type, HsSrcBang) -> Bool ok_arg dcs (Scaled _ ty, bang) = not (attempt_unpack bang) || ok_ty dcs norm_ty where norm_ty = topNormaliseType fam_envs ty + ok_ty :: NameSet -> Type -> Bool ok_ty dcs ty- | Just data_con <- unpackable_type ty- = ok_con_args dcs data_con+ | Just data_cons <- unpackable_type_datacons ty+ = all (ok_con_args dcs) data_cons | otherwise = True -- NB True here, in contrast to False at top level + attempt_unpack :: HsSrcBang -> Bool attempt_unpack (HsSrcBang _ SrcUnpack NoSrcStrict) = bang_opt_strict_data bang_opts attempt_unpack (HsSrcBang _ SrcUnpack SrcStrict)@@ -1167,17 +1351,41 @@ = bang_opt_strict_data bang_opts -- Be conservative attempt_unpack _ = False - unpackable_type :: Type -> Maybe DataCon- -- Works just on a single level- unpackable_type ty- | Just (tc, _) <- splitTyConApp_maybe ty- , Just data_con <- tyConSingleAlgDataCon_maybe tc- , null (dataConExTyCoVars data_con)- -- See Note [Unpacking GADTs and existentials]- = Just data_con- | otherwise- = Nothing+ -- Determine whether we ought to unpack a field based on user annotations if present and heuristics if not.+ should_unpack data_cons =+ case prag of+ SrcNoUnpack -> False -- {-# NOUNPACK #-}+ SrcUnpack -> True -- {-# UNPACK #-}+ NoSrcUnpack -- No explicit unpack pragma, so use heuristics+ | (_:_:_) <- data_cons+ -> False -- don't unpack sum types automatically, but they can be unpacked with an explicit source UNPACK.+ | otherwise+ -> bang_opt_unbox_strict bang_opts+ || (bang_opt_unbox_small bang_opts+ && rep_tys `lengthAtMost` 1) -- See Note [Unpack one-wide fields]+ where (rep_tys, _) = dataConArgUnpack ty ++-- Given a type already assumed to have been normalized by topNormaliseType,+-- unpackable_type_datacons ty = Just datacons+-- iff ty is of the form+-- T ty1 .. tyn+-- and T is an algebraic data type (not newtype), in which no data+-- constructors have existentials, and datacons is the list of data+-- constructors of T.+unpackable_type_datacons :: Type -> Maybe [DataCon]+unpackable_type_datacons ty+ | Just (tc, _) <- splitTyConApp_maybe ty+ , not (isNewTyCon tc)+ -- Even though `ty` has been normalised, it could still+ -- be a /recursive/ newtype, so we must check for that+ , Just cons <- tyConDataCons_maybe tc+ , not (null cons)+ , all (null . dataConExTyCoVars) cons+ = Just cons -- See Note [Unpacking GADTs and existentials]+ | otherwise+ = Nothing+ {- Note [Unpacking GADTs and existentials] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@@ -1320,7 +1528,7 @@ -- The "occurrence name" of a ccall is the full info about the -- ccall; it is encoded, but may have embedded spaces etc! - name = mkFCallName uniq occ_str+ name = mkFCallName uniq (mkFastString occ_str) info = noCafIdInfo `setArityInfo` arity@@ -1328,7 +1536,7 @@ `setCprSigInfo` topCprSig (bndrs, _) = tcSplitPiTys ty- arity = count isAnonTyCoBinder bndrs+ arity = count isAnonPiTyBinder bndrs strict_sig = mkVanillaDmdSig arity topDiv -- the call does not claim to be strict in its arguments, since they -- may be lifted (foreign import prim) and the called code doesn't@@ -1364,11 +1572,7 @@ dfun_ty where is_nt = isNewTyCon (classTyCon clas)- dfun_ty = mkDictFunTy tvs theta clas tys--mkDictFunTy :: [TyVar] -> ThetaType -> Class -> [Type] -> Type-mkDictFunTy tvs theta clas tys- = mkSpecSigmaTy tvs theta (mkClassPred clas tys)+ dfun_ty = TcType.tcMkDFunSigmaTy tvs theta (mkClassPred clas tys) {- ************************************************************************@@ -1404,10 +1608,9 @@ rightSectionName = mkWiredInIdName gHC_PRIM (fsLit "rightSection") rightSectionKey rightSectionId -- Names listed in magicIds; see Note [magicIds]-lazyIdName, oneShotName, noinlineIdName, nospecIdName :: Name+lazyIdName, oneShotName, nospecIdName :: Name lazyIdName = mkWiredInIdName gHC_MAGIC (fsLit "lazy") lazyIdKey lazyId oneShotName = mkWiredInIdName gHC_MAGIC (fsLit "oneShot") oneShotKey oneShotId-noinlineIdName = mkWiredInIdName gHC_MAGIC (fsLit "noinline") noinlineIdKey noinlineId nospecIdName = mkWiredInIdName gHC_MAGIC (fsLit "nospec") nospecIdKey nospecId ------------------------------------------------@@ -1470,12 +1673,28 @@ info = noCafIdInfo ty = mkSpecForAllTys [alphaTyVar] (mkVisFunTyMany alphaTy alphaTy) +------------------------------------------------+noinlineIdName, noinlineConstraintIdName :: Name+noinlineIdName = mkWiredInIdName gHC_MAGIC (fsLit "noinline")+ noinlineIdKey noinlineId+noinlineConstraintIdName = mkWiredInIdName gHC_MAGIC (fsLit "noinlineConstraint")+ noinlineConstraintIdKey noinlineConstraintId+ noinlineId :: Id -- See Note [noinlineId magic] noinlineId = pcMiscPrelId noinlineIdName ty info where info = noCafIdInfo- ty = mkSpecForAllTys [alphaTyVar] (mkVisFunTyMany alphaTy alphaTy)+ ty = mkSpecForAllTys [alphaTyVar] $+ mkVisFunTyMany alphaTy alphaTy +noinlineConstraintId :: Id -- See Note [noinlineId magic]+noinlineConstraintId = pcMiscPrelId noinlineConstraintIdName ty info+ where+ info = noCafIdInfo+ ty = mkSpecForAllTys [alphaConstraintTyVar] $+ mkFunTy visArgConstraintLike ManyTy alphaTy alphaConstraintTy++------------------------------------------------ nospecId :: Id -- See Note [nospecId magic] nospecId = pcMiscPrelId nospecIdName ty info where@@ -1561,8 +1780,8 @@ mult1 = mkTyVarTy multiplicityTyVar1 mult2 = mkTyVarTy multiplicityTyVar2 - [f,x,y] = mkTemplateLocals [ mkVisFunTys [ Scaled mult1 openAlphaTy- , Scaled mult2 openBetaTy ] openGammaTy+ [f,x,y] = mkTemplateLocals [ mkScaledFunTys [ Scaled mult1 openAlphaTy+ , Scaled mult2 openBetaTy ] openGammaTy , openAlphaTy, openBetaTy ] xmult = setIdMult x mult1 ymult = setIdMult y mult2@@ -1585,7 +1804,7 @@ ty = mkInvisForAllTys [ Bndr rv InferredSpec , Bndr av SpecifiedSpec , Bndr bv SpecifiedSpec ] $- mkInvisFunTyMany eqRTy $+ mkInvisFunTy eqRTy $ mkVisFunTyMany a b bndrs@[rv,av,bv] = mkTemplateKiTyVar runtimeRepTy@@ -1722,21 +1941,32 @@ noinline foo x xs where x::Int, will naturally desugar to noinline @Int (foo @Int dEqInt) x xs- But now it's entirely possible htat (foo @Int dEqInt) will inline foo,+ But now it's entirely possible that (foo @Int dEqInt) will inline foo, since 'foo' is no longer a lone variable -- see #18995 Solution: in the desugarer, rewrite noinline (f x y) ==> noinline f x y This is done in GHC.HsToCore.Utils.mkCoreAppDs.+ This is only needed for noinlineId, not noInlineConstraintId (wrinkle+ (W1) below), because the latter never shows up in user code. -Note that noinline as currently implemented can hide some simplifications since-it hides strictness from the demand analyser. Specifically, the demand analyser-will treat 'noinline f x' as lazy in 'x', even if the demand signature of 'f'-specifies that it is strict in its argument. We considered fixing this this by adding a-special case to the demand analyser to address #16588. However, the special-case seemed like a large and expensive hammer to address a rare case and-consequently we rather opted to use a more minimal solution.+Wrinkles +(W1) Sometimes case (2) above needs to apply `noinline` to a type of kind+ Constraint; e.g.+ noinline @(Eq Int) $dfEqInt+ We don't have type-or-kind polymorphism, so we simply have two `inline`+ Ids, namely `noinlineId` and `noinlineConstraintId`.++(W2) Note that noinline as currently implemented can hide some simplifications+ since it hides strictness from the demand analyser. Specifically, the+ demand analyser will treat 'noinline f x' as lazy in 'x', even if the+ demand signature of 'f' specifies that it is strict in its argument. We+ considered fixing this this by adding a special case to the demand+ analyser to address #16588. However, the special case seemed like a large+ and expensive hammer to address a rare case and consequently we rather+ opted to use a more minimal solution.+ Note [nospecId magic] ~~~~~~~~~~~~~~~~~~~~~ The 'nospec' magic Id is used to ensure to make a value opaque to the typeclass@@ -1821,7 +2051,7 @@ unboxedUnitExpr = Var (dataConWorkId unboxedUnitDataCon) voidArgId :: Id -- Local lambda-bound :: Void#-voidArgId = mkSysLocal (fsLit "void") voidArgIdKey Many unboxedUnitTy+voidArgId = mkSysLocal (fsLit "void") voidArgIdKey ManyTy unboxedUnitTy coercionTokenId :: Id -- :: () ~# () coercionTokenId -- See Note [Coercion tokens] in "GHC.CoreToStg"
compiler/GHC/Types/Literal.hs view
@@ -67,8 +67,9 @@ import GHC.Prelude import GHC.Builtin.Types.Prim-import GHC.Core.TyCo.Rep ( RuntimeRepType )-import GHC.Core.Type+import GHC.Core.Type( Type, RuntimeRepType, mkForAllTy, mkTyVarTy, typeOrConstraintKind )+import GHC.Core.TyCo.Compare( nonDetCmpType )+import GHC.Types.Var import GHC.Utils.Outputable import GHC.Data.FastString import GHC.Types.Basic@@ -83,7 +84,7 @@ import Data.Word import Data.Char import Data.Data ( Data )-import GHC.Exts+import GHC.Exts( isTrue#, dataToTag#, (<#) ) import Numeric ( fromRat ) {-@@ -132,15 +133,14 @@ -- that can be represented as a Literal. Create -- with 'nullAddrLit' - | LitRubbish RuntimeRepType -- ^ A nonsense value of the given- -- representation. See Note [Rubbish literals].- --- -- The Type argument, rr, is of kind RuntimeRep.- -- The type of the literal is forall (a:TYPE rr). a- --- -- INVARIANT: the Type has no free variables- -- and so substitution etc can ignore it- --+ | LitRubbish -- ^ A nonsense value; See Note [Rubbish literals].+ TypeOrConstraint -- t_or_c: whether this is a type or a constraint+ RuntimeRepType -- rr: a type of kind RuntimeRep+ -- The type of the literal is forall (a:TYPE rr). a+ -- or forall (a:CONSTRAINT rr). a+ --+ -- INVARIANT: the Type has no free variables+ -- and so substitution etc can ignore it | LitFloat Rational -- ^ @Float#@. Create with 'mkLitFloat' | LitDouble Rational -- ^ @Double#@. Create with 'mkLitDouble'@@ -268,7 +268,7 @@ = do putByte bh 6 put_ bh nt put_ bh i- put_ _ (LitRubbish b) = pprPanic "Binary LitRubbish" (ppr b)+ put_ _ lit@(LitRubbish {}) = pprPanic "Binary LitRubbish" (ppr lit) -- We use IfaceLitRubbish; see Note [Rubbish literals], item (6) get bh = do@@ -298,6 +298,7 @@ return (LitNumber nt i) _ -> pprPanic "Binary:Literal" (int (fromIntegral h)) + instance Outputable Literal where ppr = pprLiteral id @@ -851,10 +852,10 @@ LitNumWord64 -> word64PrimTy -- LitRubbish: see Note [Rubbish literals]-literalType (LitRubbish rep)- = mkForAllTy a Inferred (mkTyVarTy a)+literalType (LitRubbish torc rep)+ = mkForAllTy (Bndr a Inferred) (mkTyVarTy a) where- a = mkTemplateKindVar (mkTYPEapp rep)+ a = mkTemplateKindVar (typeOrConstraintKind torc rep) {- Comparison@@ -870,7 +871,8 @@ cmpLit (LitLabel a _ _) (LitLabel b _ _) = a `lexicalCompareFS` b cmpLit (LitNumber nt1 a) (LitNumber nt2 b) = (nt1 `compare` nt2) `mappend` (a `compare` b)-cmpLit (LitRubbish b1) (LitRubbish b2) = b1 `nonDetCmpType` b2+cmpLit (LitRubbish tc1 b1) (LitRubbish tc2 b2) = (tc1 `compare` tc2) `mappend`+ (b1 `nonDetCmpType` b2) cmpLit lit1 lit2 | isTrue# (dataToTag# lit1 <# dataToTag# lit2) = LT | otherwise = GT@@ -905,8 +907,12 @@ where b = case mb of Nothing -> pprHsString l Just x -> doubleQuotes (ftext l <> text ('@':show x))-pprLiteral _ (LitRubbish rep)- = text "RUBBISH" <> parens (ppr rep)+pprLiteral _ (LitRubbish torc rep)+ = text "RUBBISH" <> pp_tc <> parens (ppr rep)+ where+ pp_tc = case torc of+ TypeLike -> empty+ ConstraintLike -> text "[c]" {- Note [Printing of literals in Core]@@ -1005,7 +1011,7 @@ all boxed to the host GC anyway. 6. IfaceSyn: `Literal` is part of `IfaceSyn`, but `Type` really isn't. So in- the passage from Core to Iface I put LitRubbish into its owns IfaceExpr data+ the passage from Core to Iface we put LitRubbish into its own IfaceExpr data constructor, IfaceLitRubbish. The remaining constructors of Literal are fine as IfaceSyn.
compiler/GHC/Types/Name.hs view
@@ -56,6 +56,7 @@ localiseName, namePun_maybe, + pprName, nameSrcLoc, nameSrcSpan, pprNameDefnLoc, pprDefinedAt, pprFullName, pprTickyName, @@ -493,8 +494,8 @@ mkSysTvName uniq fs = mkSystemName uniq (mkTyVarOccFS fs) -- | Make a name for a foreign call-mkFCallName :: Unique -> String -> Name-mkFCallName uniq str = mkInternalName uniq (mkVarOcc str) noSrcSpan+mkFCallName :: Unique -> FastString -> Name+mkFCallName uniq str = mkInternalName uniq (mkVarOccFS str) noSrcSpan -- The encoded string completely describes the ccall -- When we renumber/rename things, we need to be@@ -624,12 +625,13 @@ pprInfixOcc = pprInfixName pprPrefixOcc = pprPrefixName -pprName :: Name -> SDoc+pprName :: forall doc. IsLine doc => Name -> doc pprName name@(Name {n_sort = sort, n_uniq = uniq, n_occ = occ})- = getPprStyle $ \sty ->- getPprDebug $ \debug ->- sdocOption sdocListTuplePuns $ \listTuplePuns ->- handlePuns listTuplePuns (namePun_maybe name) $+ = docWithContext $ \ctx ->+ let sty = sdocStyle ctx+ debug = sdocPprDebug ctx+ listTuplePuns = sdocListTuplePuns ctx+ in handlePuns listTuplePuns (namePun_maybe name) $ case sort of WiredIn mod _ builtin -> pprExternal debug sty uniq mod occ True builtin External mod -> pprExternal debug sty uniq mod occ False UserSyntax@@ -637,9 +639,11 @@ Internal -> pprInternal debug sty uniq occ where -- Print GHC.Types.List as [], etc.- handlePuns :: Bool -> Maybe FastString -> SDoc -> SDoc+ handlePuns :: Bool -> Maybe FastString -> doc -> doc handlePuns True (Just pun) _ = ftext pun handlePuns _ _ r = r+{-# SPECIALISE pprName :: Name -> SDoc #-}+{-# SPECIALISE pprName :: Name -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -- | Print fully qualified name (with unit-id, module and unique) pprFullName :: Module -> Name -> SDoc@@ -670,9 +674,9 @@ pprNameUnqualified :: Name -> SDoc pprNameUnqualified Name { n_occ = occ } = ppr_occ_name occ -pprExternal :: Bool -> PprStyle -> Unique -> Module -> OccName -> Bool -> BuiltInSyntax -> SDoc+pprExternal :: IsLine doc => Bool -> PprStyle -> Unique -> Module -> OccName -> Bool -> BuiltInSyntax -> doc pprExternal debug sty uniq mod occ is_wired is_builtin- | codeStyle sty = ppr mod <> char '_' <> ppr_z_occ_name occ+ | codeStyle sty = pprModule mod <> char '_' <> ppr_z_occ_name occ -- In code style, always qualify -- ToDo: maybe we could print all wired-in things unqualified -- in code style, to reduce symbol table bloat?@@ -685,13 +689,13 @@ if isHoleModule mod then case qualName sty mod occ of NameUnqual -> ppr_occ_name occ- _ -> braces (ppr (moduleName mod) <> dot <> ppr_occ_name occ)+ _ -> braces (pprModuleName (moduleName mod) <> dot <> ppr_occ_name occ) else pprModulePrefix sty mod occ <> ppr_occ_name occ where pp_mod = ppUnlessOption sdocSuppressModulePrefixes- (ppr mod <> dot)+ (pprModule mod <> dot) -pprInternal :: Bool -> PprStyle -> Unique -> OccName -> SDoc+pprInternal :: IsLine doc => Bool -> PprStyle -> Unique -> OccName -> doc pprInternal debug sty uniq occ | codeStyle sty = pprUniqueAlways uniq | debug = ppr_occ_name occ <> braces (hsep [pprNameSpaceBrief (occNameSpace occ),@@ -702,7 +706,7 @@ | otherwise = ppr_occ_name occ -- User style -- Like Internal, except that we only omit the unique in Iface style-pprSystem :: Bool -> PprStyle -> Unique -> OccName -> SDoc+pprSystem :: IsLine doc => Bool -> PprStyle -> Unique -> OccName -> doc pprSystem debug sty uniq occ | codeStyle sty = pprUniqueAlways uniq | debug = ppr_occ_name occ <> ppr_underscore_unique uniq@@ -713,38 +717,38 @@ -- so print the unique -pprModulePrefix :: PprStyle -> Module -> OccName -> SDoc+pprModulePrefix :: IsLine doc => PprStyle -> Module -> OccName -> doc -- Print the "M." part of a name, based on whether it's in scope or not -- See Note [Printing original names] in GHC.Types.Name.Ppr pprModulePrefix sty mod occ = ppUnlessOption sdocSuppressModulePrefixes $ case qualName sty mod occ of -- See Outputable.QualifyName:- NameQual modname -> ppr modname <> dot -- Name is in scope- NameNotInScope1 -> ppr mod <> dot -- Not in scope- NameNotInScope2 -> ppr (moduleUnit mod) <> colon -- Module not in- <> ppr (moduleName mod) <> dot -- scope either+ NameQual modname -> pprModuleName modname <> dot -- Name is in scope+ NameNotInScope1 -> pprModule mod <> dot -- Not in scope+ NameNotInScope2 -> pprUnit (moduleUnit mod) <> colon -- Module not in+ <> pprModuleName (moduleName mod) <> dot -- scope either NameUnqual -> empty -- In scope unqualified -pprUnique :: Unique -> SDoc+pprUnique :: IsLine doc => Unique -> doc -- Print a unique unless we are suppressing them pprUnique uniq = ppUnlessOption sdocSuppressUniques $ pprUniqueAlways uniq -ppr_underscore_unique :: Unique -> SDoc+ppr_underscore_unique :: IsLine doc => Unique -> doc -- Print an underscore separating the name from its unique -- But suppress it if we aren't printing the uniques anyway ppr_underscore_unique uniq = ppUnlessOption sdocSuppressUniques $ char '_' <> pprUniqueAlways uniq -ppr_occ_name :: OccName -> SDoc+ppr_occ_name :: IsLine doc => OccName -> doc ppr_occ_name occ = ftext (occNameFS occ) -- Don't use pprOccName; instead, just print the string of the OccName; -- we print the namespace in the debug stuff above -- In code style, we Z-encode the strings. The results of Z-encoding each FastString are -- cached behind the scenes in the FastString implementation.-ppr_z_occ_name :: OccName -> SDoc+ppr_z_occ_name :: IsLine doc => OccName -> doc ppr_z_occ_name occ = ztext (zEncodeFS (occNameFS occ)) -- Prints (if mod information is available) "Defined at <loc>" or
compiler/GHC/Types/Name/Occurrence.hs view
@@ -200,7 +200,7 @@ pprNonVarNameSpace VarName = empty pprNonVarNameSpace ns = pprNameSpace ns -pprNameSpaceBrief :: NameSpace -> SDoc+pprNameSpaceBrief :: IsLine doc => NameSpace -> doc pprNameSpaceBrief DataName = char 'd' pprNameSpaceBrief VarName = char 'v' pprNameSpaceBrief TvName = text "tv"@@ -276,10 +276,10 @@ pprInfixOcc n = pprInfixVar (isSymOcc n) (ppr n) pprPrefixOcc n = pprPrefixVar (isSymOcc n) (ppr n) -pprOccName :: OccName -> SDoc+pprOccName :: IsLine doc => OccName -> doc pprOccName (OccName sp occ)- = getPprStyle $ \ sty ->- if codeStyle sty+ = docWithContext $ \ sty ->+ if codeStyle (sdocStyle sty) then ztext (zEncodeFS occ) else ftext occ <> whenPprDebug (braces (pprNameSpaceBrief sp)) @@ -519,9 +519,9 @@ startsWithUnderscore :: OccName -> Bool -- ^ Haskell 98 encourages compilers to suppress warnings about unused -- names in a pattern if they start with @_@: this implements that test-startsWithUnderscore occ = case unconsFS (occNameFS occ) of- Just ('_', _) -> True- _ -> False+startsWithUnderscore occ = case unpackFS (occNameFS occ) of+ '_':_ -> True+ _ -> False {- ************************************************************************@@ -793,7 +793,6 @@ Note [Tidying multiple names at once] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~- Consider > :t (id,id,id)@@ -861,13 +860,13 @@ base1 = mkFastString (base ++ "1") find !k !n- = case lookupUFM env new_fs of- Just {} -> find (k+1 :: Int) (n+k)+ = case elemUFM new_fs env of+ True -> find (k+1 :: Int) (n+k) -- By using n+k, the n argument to find goes -- 1, add 1, add 2, add 3, etc which -- moves at quadratic speed through a dense patch - Nothing -> (new_env, OccName occ_sp new_fs)+ False -> (new_env, OccName occ_sp new_fs) where new_fs = mkFastString (base ++ show n) new_env = addToUFM (addToUFM env new_fs 1) base1 (n+1)
compiler/GHC/Types/Name/Occurrence.hs-boot view
@@ -1,6 +1,6 @@ module GHC.Types.Name.Occurrence where -import GHC.Data.FastString+import GHC.Data.FastString ( FastString ) data OccName
compiler/GHC/Types/Name/Ppr.hs view
@@ -1,7 +1,7 @@ module GHC.Types.Name.Ppr- ( mkPrintUnqualified+ ( mkNamePprCtx , mkQualModule , mkQualPackage , pkgQual@@ -9,6 +9,7 @@ where import GHC.Prelude+import GHC.Data.FastString import GHC.Unit import GHC.Unit.Env@@ -16,12 +17,12 @@ import GHC.Types.Name import GHC.Types.Name.Reader -import GHC.Builtin.Types import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Misc-import GHC.Builtin.Types.Prim (tYPETyConName, funTyConName)+import GHC.Builtin.Types.Prim ( fUNTyConName )+import GHC.Builtin.Types {-@@ -52,7 +53,7 @@ things around, P1:M.T and P2:M.T? Then we don't want to print both of them as M.T! However only one of the modules P1:M and P2:M can be exposed (say P2), so we use M.T for that, and P1:M.T for the other one.-This is handled by the qual_mod component of PrintUnqualified, inside+This is handled by the qual_mod component of NamePprCtx, inside the (ppr mod) of case (3), in Name.pprModulePrefix Note [Printing unit ids]@@ -66,14 +67,19 @@ -- | Creates some functions that work out the best ways to format -- names for the user according to a set of heuristics.-mkPrintUnqualified :: UnitEnv -> GlobalRdrEnv -> PrintUnqualified-mkPrintUnqualified unit_env env- = QueryQualify qual_name+mkNamePprCtx :: PromotionTickContext -> UnitEnv -> GlobalRdrEnv -> NamePprCtx+mkNamePprCtx ptc unit_env env+ = QueryQualify+ (mkQualName env) (mkQualModule unit_state home_unit) (mkQualPackage unit_state)+ (mkPromTick ptc env) where unit_state = ue_units unit_env home_unit = ue_homeUnit unit_env++mkQualName :: GlobalRdrEnv -> QueryQualifyName+mkQualName env = qual_name where qual_name mod occ | [gre] <- unqual_gres , right_name gre@@ -112,7 +118,7 @@ , coercibleTyConName , eqTyConName , tYPETyConName- , funTyConName+ , fUNTyConName, unrestrictedFunTyConName , oneDataConName , manyDataConName ] @@ -125,8 +131,38 @@ -- "import M" would resolve unambiguously to P:M. (if P is the -- current package we can just assume it is unqualified). +mkPromTick :: PromotionTickContext -> GlobalRdrEnv -> QueryPromotionTick+mkPromTick ptc env+ | ptcPrintRedundantPromTicks ptc = alwaysPrintPromTick+ | otherwise = print_prom_tick+ where+ print_prom_tick (PromotedItemListSyntax (IsEmptyOrSingleton eos)) =+ -- Ticked: '[], '[x]+ -- Unticked: [x,y], [x,y,z], and so on+ ptcListTuplePuns ptc && eos+ print_prom_tick PromotedItemTupleSyntax =+ ptcListTuplePuns ptc+ print_prom_tick (PromotedItemDataCon occ)+ | isPunnedDataConName occ -- '[], '(,), ''(,,)+ = ptcListTuplePuns ptc++ | Just occ' <- promoteOccName occ+ , [] <- lookupGRE_RdrName (mkRdrUnqual occ') env+ = -- Could not find a corresponding type name in the environment,+ -- so the data name is unambiguous. Promotion tick not needed.+ False+ | otherwise = True++isPunnedDataConName :: OccName -> Bool+isPunnedDataConName occ =+ isDataOcc occ && case unpackFS (occNameFS occ) of+ '[':_ -> True+ '(':_ -> True+ _ -> False+ {- Note [pretendNameIsInScopeForPpr] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+c.f. Note [pretendNameIsInScope] in GHC.Builtin.Names Normally, a name is printed unqualified if it's in scope and unambiguous: ghci> :t not not :: Bool -> Bool@@ -199,5 +235,5 @@ -- | A function which only qualifies package names if necessary; but -- qualifies all other identifiers.-pkgQual :: UnitState -> PrintUnqualified+pkgQual :: UnitState -> NamePprCtx pkgQual pkgs = alwaysQualify { queryQualifyPackage = mkQualPackage pkgs }
compiler/GHC/Types/RepType.hs view
@@ -31,7 +31,6 @@ import GHC.Types.Basic (Arity, RepArity) import GHC.Core.DataCon-import GHC.Builtin.Names import GHC.Core.Coercion import GHC.Core.TyCon import GHC.Core.TyCon.RecWalk@@ -56,8 +55,8 @@ import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic-import GHC.Utils.Panic.Plain +import Data.List.NonEmpty (NonEmpty (..)) import Data.List (sort) import qualified Data.IntSet as IS @@ -205,14 +204,14 @@ -- -- INVARIANT: Result slots are sorted (via Ord SlotTy), except that at the head -- of the list we have the slot for the tag.-ubxSumRepType :: [[PrimRep]] -> [SlotTy]+ubxSumRepType :: [[PrimRep]] -> NonEmpty SlotTy ubxSumRepType constrs0 -- These first two cases never classify an actual unboxed sum, which always -- has at least two disjuncts. But it could happen if a user writes, e.g., -- forall (a :: TYPE (SumRep [IntRep])). ... -- which could never be instantiated. We still don't want to panic. | constrs0 `lengthLessThan` 2- = [WordSlot]+ = WordSlot :| [] | otherwise = let@@ -240,12 +239,13 @@ rep :: [PrimRep] -> SortedSlotTys rep ty = sort (map primRepSlot ty) - sumRep = WordSlot : combine_alts (map rep constrs0)+ sumRep = WordSlot :| combine_alts (map rep constrs0) -- WordSlot: for the tag of the sum in sumRep -layoutUbxSum :: SortedSlotTys -- Layout of sum. Does not include tag.+layoutUbxSum :: HasDebugCallStack+ => SortedSlotTys -- Layout of sum. Does not include tag. -- We assume that they are in increasing order -> [SlotTy] -- Slot types of things we want to map to locations in the -- sum layout@@ -268,7 +268,8 @@ | otherwise = findSlot arg (slot_idx + 1) slots useds findSlot _ _ [] _- = pprPanic "findSlot" (text "Can't find slot" $$ ppr sum_slots0 $$ ppr arg_slots0)+ = pprPanic "findSlot" (text "Can't find slot" $$ text "sum_slots:" <> ppr sum_slots0+ $$ text "arg_slots:" <> ppr arg_slots0 ) -------------------------------------------------------------------------------- @@ -304,11 +305,10 @@ ppr (VecSlot n e) = text "VecSlot" <+> ppr n <+> ppr e typeSlotTy :: UnaryType -> Maybe SlotTy-typeSlotTy ty- | isZeroBitTy ty- = Nothing- | otherwise- = Just (primRepSlot (typePrimRep1 ty))+typeSlotTy ty = case typePrimRep ty of+ [] -> Nothing+ [rep] -> Just (primRepSlot rep)+ reps -> pprPanic "typeSlotTy" (ppr ty $$ ppr reps) primRepSlot :: PrimRep -> SlotTy primRepSlot VoidRep = pprPanic "primRepSlot" (text "No slot for VoidRep")@@ -349,18 +349,17 @@ = Just ty1 | isWordSlot ty1 && isWordSlot ty2 = Just (max ty1 ty2)- | isFloatSlot ty1 && isFloatSlot ty2- = Just (max ty1 ty2) | otherwise = Nothing+ -- We used to share slots between Float/Double but currently we can't easily+ -- covert between float/double in a way that is both work free and safe.+ -- So we put them in different slots.+ -- See Note [Casting slot arguments] where isWordSlot Word64Slot = True isWordSlot WordSlot = True isWordSlot _ = False - isFloatSlot DoubleSlot = True- isFloatSlot FloatSlot = True- isFloatSlot _ = False {- **********************************************************************@@ -591,19 +590,16 @@ -- NB: We could implement the partial methods by calling into the maybe -- variants here. But then both would need to pass around the doc argument. --- | Take a kind (of shape @TYPE rr@) and produce the 'PrimRep's+-- | Take a kind (of shape `TYPE rr` or `CONSTRAINT rr`) and produce the 'PrimRep's -- of values of types of this kind. -- See also Note [Getting from RuntimeRep to PrimRep] -- Returns Nothing if rep can't be determined. Eg. levity polymorphic types. kindPrimRep_maybe :: HasDebugCallStack => Kind -> Maybe [PrimRep] kindPrimRep_maybe ki- | Just ki' <- coreView ki- = kindPrimRep_maybe ki'-kindPrimRep_maybe (TyConApp typ [runtime_rep])- = assert (typ `hasKey` tYPETyConKey) $- runtimeRepPrimRep_maybe runtime_rep-kindPrimRep_maybe _ki- = Nothing+ | Just (_torc, rep) <- sORTKind_maybe ki+ = runtimeRepPrimRep_maybe rep+ | otherwise+ = pprPanic "kindPrimRep" (ppr ki) -- | Take a type of kind RuntimeRep and extract the list of 'PrimRep' that -- it encodes. See also Note [Getting from RuntimeRep to PrimRep]@@ -613,7 +609,7 @@ | Just rr_ty' <- coreView rr_ty = runtimeRepPrimRep doc rr_ty' | TyConApp rr_dc args <- rr_ty- , RuntimeRep fun <- tyConRuntimeRepInfo rr_dc+ , RuntimeRep fun <- tyConPromDataConInfo rr_dc = fun args | otherwise = pprPanic "runtimeRepPrimRep" (doc $$ ppr rr_ty)@@ -627,7 +623,7 @@ | Just rr_ty' <- coreView rr_ty = runtimeRepPrimRep_maybe rr_ty' | TyConApp rr_dc args <- rr_ty- , RuntimeRep fun <- tyConRuntimeRepInfo rr_dc+ , RuntimeRep fun <- tyConPromDataConInfo rr_dc = Just $! fun args | otherwise = Nothing
compiler/GHC/Types/TyThing.hs view
@@ -184,7 +184,7 @@ -- for each data constructor in order, -- the constructor and associated implicit 'Id's- concatMap datacon_stuff (tyConDataCons tc)+ datacon_stuff -- NB. record selectors are *not* implicit, they have fully-fledged -- bindings that pass through the compilation pipeline as normal. where@@ -192,16 +192,22 @@ Nothing -> [] Just cl -> implicitClassThings cl - -- For each data constructor,+ -- For each data constructor in order, -- the constructor, worker, and (possibly) wrapper -- -- If the data constructor is in a "type data" declaration, -- promote it to the type level now. -- See Note [Type data declarations] in GHC.Rename.Module.- datacon_stuff dc- | isTypeDataCon dc = [ATyCon (promoteDataCon dc)]+ datacon_stuff :: [TyThing]+ datacon_stuff+ | isTypeDataTyCon tc = [ATyCon (promoteDataCon dc) | dc <- cons] | otherwise- = AConLike (RealDataCon dc) : dataConImplicitTyThings dc+ = [ty_thing | dc <- cons,+ ty_thing <- AConLike (RealDataCon dc) :+ dataConImplicitTyThings dc]++ cons :: [DataCon]+ cons = tyConDataCons tc -- For newtypes and closed type families (only) add the implicit coercion tycon implicitCoTyCon :: TyCon -> [TyThing]
compiler/GHC/Types/Unique.hs view
@@ -281,13 +281,15 @@ = case unpkUnique uniq of (tag, u) -> tag : iToBase62 u -pprUniqueAlways :: Unique -> SDoc+pprUniqueAlways :: IsLine doc => Unique -> doc -- The "always" means regardless of -dsuppress-uniques -- It replaces the old pprUnique to remind callers that -- they should consider whether they want to consult -- Opt_SuppressUniques pprUniqueAlways u = text (showUnique u)+{-# SPECIALIZE pprUniqueAlways :: Unique -> SDoc #-}+{-# SPECIALIZE pprUniqueAlways :: Unique -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable instance Outputable Unique where ppr = pprUniqueAlways
compiler/GHC/Types/Unique/DFM.hs view
@@ -302,8 +302,12 @@ k' acc (TaggedVal v _) = k v acc eltsUDFM :: UniqDFM key elt -> [elt]-eltsUDFM (UDFM m _i) =- map taggedFst $ sortBy (compare `on` taggedSnd) $ M.elems m+{-# INLINE eltsUDFM #-}+-- The INLINE makes it a good producer (from the map)+eltsUDFM (UDFM m _i) = map taggedFst (sort_it m)++sort_it :: M.IntMap (TaggedVal elt) -> [TaggedVal elt]+sort_it m = sortBy (compare `on` taggedSnd) (M.elems m) filterUDFM :: (elt -> Bool) -> UniqDFM key elt -> UniqDFM key elt filterUDFM p (UDFM m i) = UDFM (M.filter (\(TaggedVal v _) -> p v) m) i
compiler/GHC/Types/Unique/FM.hs view
@@ -40,7 +40,7 @@ listToUFM_Directly, listToUFM_C, listToIdentityUFM,- addToUFM,addToUFM_C,addToUFM_Acc,+ addToUFM,addToUFM_C,addToUFM_Acc,addToUFM_L, addListToUFM,addListToUFM_C, addToUFM_Directly, addListToUFM_Directly,@@ -182,6 +182,24 @@ -> UniqFM key elts -- result addToUFM_Acc exi new (UFM m) k v = UFM (M.insertWith (\_new old -> exi v old) (getKey $ getUnique k) (new v) m)++-- | Add an element, returns previous lookup result and new map. If+-- old element doesn't exist, add the passed element directly,+-- otherwise compute the element to add using the passed function.+addToUFM_L+ :: Uniquable key+ => (key -> elt -> elt -> elt) -- key,old,new+ -> key+ -> elt -- new+ -> UniqFM key elt+ -> (Maybe elt, UniqFM key elt) -- old, result+addToUFM_L f k v (UFM m) =+ coerce $+ M.insertLookupWithKey+ (\_ _n _o -> f k _o _n)+ (getKey $ getUnique k)+ v+ m alterUFM :: Uniquable key
compiler/GHC/Types/Unique/Map.hs view
@@ -20,6 +20,7 @@ addListToUniqMap, addToUniqMap_C, addToUniqMap_Acc,+ addToUniqMap_L, alterUniqMap, addListToUniqMap_C, adjustUniqMap,@@ -31,6 +32,7 @@ plusUniqMapList, minusUniqMap, intersectUniqMap,+ intersectUniqMap_C, disjointUniqMap, mapUniqMap, filterUniqMap,@@ -59,7 +61,7 @@ import Data.Data -- | Maps indexed by 'Uniquable' keys-newtype UniqMap k a = UniqMap (UniqFM k (k, a))+newtype UniqMap k a = UniqMap { getUniqMap :: UniqFM k (k, a) } deriving (Data, Eq, Functor) type role UniqMap nominal representational @@ -123,6 +125,22 @@ (\b -> (k0, new b)) m k0 v0 +-- | Add an element, returns previous lookup result and new map. If+-- old element doesn't exist, add the passed element directly,+-- otherwise compute the element to add using the passed function.+addToUniqMap_L :: Uniquable k+ => (k -> a -> a -> a) -- key,old,new+ -> k+ -> a -- new+ -> UniqMap k a+ -> (Maybe a, UniqMap k a)+addToUniqMap_L f k v (UniqMap m) = case addToUFM_L+ (\_k (_, _o) (_, _n) -> (_k, f _k _o _n))+ k+ (k, v)+ m of+ (_maybe, _ufm) -> (snd <$> _maybe, UniqMap _ufm)+ alterUniqMap :: Uniquable k => (Maybe a -> Maybe a) -> UniqMap k a@@ -175,6 +193,10 @@ intersectUniqMap :: UniqMap k a -> UniqMap k b -> UniqMap k a intersectUniqMap (UniqMap m1) (UniqMap m2) = UniqMap $ intersectUFM m1 m2++-- | Intersection with a combining function.+intersectUniqMap_C :: (a -> b -> c) -> UniqMap k a -> UniqMap k b -> UniqMap k c+intersectUniqMap_C f (UniqMap m1) (UniqMap m2) = UniqMap $ intersectUFM_C (\(k, a) (_, b) -> (k, f a b)) m1 m2 disjointUniqMap :: UniqMap k a -> UniqMap k b -> Bool disjointUniqMap (UniqMap m1) (UniqMap m2) = disjointUFM m1 m2
compiler/GHC/Types/Var.hs view
@@ -7,7 +7,6 @@ {-# LANGUAGE FlexibleContexts, MultiWayIf, FlexibleInstances, DeriveDataTypeable, PatternSynonyms, BangPatterns #-}-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} -- |@@ -66,16 +65,30 @@ isGlobalId, isExportedId, mustHaveLocalBinding, - -- * ArgFlags- ArgFlag(Invisible,Required,Specified,Inferred),- AnonArgFlag(..), Specificity(..),- isVisibleArgFlag, isInvisibleArgFlag, isInferredArgFlag,- sameVis,+ -- * ForAllTyFlags+ ForAllTyFlag(Invisible,Required,Specified,Inferred),+ Specificity(..),+ isVisibleForAllTyFlag, isInvisibleForAllTyFlag, isInferredForAllTyFlag, + -- * FunTyFlag+ FunTyFlag(..), isVisibleFunArg, isInvisibleFunArg, isFUNArg,+ mkFunTyFlag, visArg, invisArg,+ visArgTypeLike, visArgConstraintLike,+ invisArgTypeLike, invisArgConstraintLike,+ funTyFlagResultTypeOrConstraint,+ TypeOrConstraint(..), -- Re-export this: it's an argument of FunTyFlag++ -- * PiTyBinder+ PiTyBinder(..), PiTyVarBinder,+ isInvisiblePiTyBinder, isVisiblePiTyBinder,+ isTyBinder, isNamedPiTyBinder, isAnonPiTyBinder,+ namedPiTyBinder_maybe, anonPiTyBinderType_maybe, piTyBinderType,+ -- * TyVar's- VarBndr(..), TyCoVarBinder, TyVarBinder, InvisTVBinder, ReqTVBinder,- binderVar, binderVars, binderArgFlag, binderType,- mkTyCoVarBinder, mkTyCoVarBinders,+ VarBndr(..), ForAllTyBinder, TyVarBinder,+ InvisTyBinder, InvisTVBinder, ReqTyBinder, ReqTVBinder,+ binderVar, binderVars, binderFlag, binderFlags, binderType,+ mkForAllTyBinder, mkForAllTyBinders, mkTyVarBinder, mkTyVarBinders, isTyVarBinder, tyVarSpecToBinder, tyVarSpecToBinders, tyVarReqToBinder, tyVarReqToBinders,@@ -96,7 +109,7 @@ import GHC.Prelude -import {-# SOURCE #-} GHC.Core.TyCo.Rep( Type, Kind, Mult )+import {-# SOURCE #-} GHC.Core.TyCo.Rep( Type, Kind, Mult, Scaled, scaledThing ) import {-# SOURCE #-} GHC.Core.TyCo.Ppr( pprKind ) import {-# SOURCE #-} GHC.Tc.Utils.TcType( TcTyVarDetails, pprTcTyVarDetails, vanillaSkolemTvUnk ) import {-# SOURCE #-} GHC.Types.Id.Info( IdDetails, IdInfo, coVarDetails, isCoVarDetails,@@ -105,6 +118,7 @@ import GHC.Types.Name hiding (varName) import GHC.Types.Unique ( Uniquable, Unique, getKey, getUnique , mkUniqueGrimily, nonDetCmpUnique )+import GHC.Types.Basic( TypeOrConstraint(..) ) import GHC.Utils.Misc import GHC.Utils.Binary import GHC.Utils.Outputable@@ -429,20 +443,20 @@ {- ********************************************************************* * *-* ArgFlag+* ForAllTyFlag * * ********************************************************************* -} --- | Argument Flag+-- | ForAllTyFlag -- -- Is something required to appear in source Haskell ('Required'), -- permitted by request ('Specified') (visible type application), or -- prohibited entirely from appearing in source Haskell ('Inferred')?--- See Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in "GHC.Core.TyCo.Rep"-data ArgFlag = Invisible Specificity- | Required+-- See Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in "GHC.Core.TyCo.Rep"+data ForAllTyFlag = Invisible Specificity+ | Required deriving (Eq, Ord, Data)- -- (<) on ArgFlag means "is less visible than"+ -- (<) on ForAllTyFlag means "is less visible than" -- | Whether an 'Invisible' argument may appear in source Haskell. data Specificity = InferredSpec@@ -453,35 +467,27 @@ -- required. deriving (Eq, Ord, Data) -pattern Inferred, Specified :: ArgFlag+pattern Inferred, Specified :: ForAllTyFlag pattern Inferred = Invisible InferredSpec pattern Specified = Invisible SpecifiedSpec {-# COMPLETE Required, Specified, Inferred #-} --- | Does this 'ArgFlag' classify an argument that is written in Haskell?-isVisibleArgFlag :: ArgFlag -> Bool-isVisibleArgFlag af = not (isInvisibleArgFlag af)---- | Does this 'ArgFlag' classify an argument that is not written in Haskell?-isInvisibleArgFlag :: ArgFlag -> Bool-isInvisibleArgFlag (Invisible {}) = True-isInvisibleArgFlag Required = False+-- | Does this 'ForAllTyFlag' classify an argument that is written in Haskell?+isVisibleForAllTyFlag :: ForAllTyFlag -> Bool+isVisibleForAllTyFlag af = not (isInvisibleForAllTyFlag af) -isInferredArgFlag :: ArgFlag -> Bool--- More restrictive than isInvisibleArgFlag-isInferredArgFlag (Invisible InferredSpec) = True-isInferredArgFlag _ = False+-- | Does this 'ForAllTyFlag' classify an argument that is not written in Haskell?+isInvisibleForAllTyFlag :: ForAllTyFlag -> Bool+isInvisibleForAllTyFlag (Invisible {}) = True+isInvisibleForAllTyFlag Required = False --- | Do these denote the same level of visibility? 'Required'--- arguments are visible, others are not. So this function--- equates 'Specified' and 'Inferred'. Used for printing.-sameVis :: ArgFlag -> ArgFlag -> Bool-sameVis Required Required = True-sameVis (Invisible _) (Invisible _) = True-sameVis _ _ = False+isInferredForAllTyFlag :: ForAllTyFlag -> Bool+-- More restrictive than isInvisibleForAllTyFlag+isInferredForAllTyFlag (Invisible InferredSpec) = True+isInferredForAllTyFlag _ = False -instance Outputable ArgFlag where+instance Outputable ForAllTyFlag where ppr Required = text "[req]" ppr Specified = text "[spec]" ppr Inferred = text "[infrd]"@@ -496,7 +502,7 @@ 0 -> return SpecifiedSpec _ -> return InferredSpec -instance Binary ArgFlag where+instance Binary ForAllTyFlag where put_ bh Required = putByte bh 0 put_ bh Specified = putByte bh 1 put_ bh Inferred = putByte bh 2@@ -508,54 +514,111 @@ 1 -> return Specified _ -> return Inferred --- | The non-dependent version of 'ArgFlag'.--- See Note [AnonArgFlag]--- Appears here partly so that it's together with its friends ArgFlag+{- *********************************************************************+* *+* FunTyFlag+* *+********************************************************************* -}++-- | The non-dependent version of 'ForAllTyFlag'.+-- See Note [FunTyFlag]+-- Appears here partly so that it's together with its friends ForAllTyFlag -- and ForallVisFlag, but also because it is used in IfaceType, rather -- early in the compilation chain-data AnonArgFlag- = VisArg -- ^ Used for @(->)@: an ordinary non-dependent arrow.- -- The argument is visible in source code.- | InvisArg -- ^ Used for @(=>)@: a non-dependent predicate arrow.- -- The argument is invisible in source code.+data FunTyFlag+ = FTF_T_T -- (->) Type -> Type+ | FTF_T_C -- (-=>) Type -> Constraint+ | FTF_C_T -- (=>) Constraint -> Type+ | FTF_C_C -- (==>) Constraint -> Constraint deriving (Eq, Ord, Data) -instance Outputable AnonArgFlag where- ppr VisArg = text "[vis]"- ppr InvisArg = text "[invis]"+instance Outputable FunTyFlag where+ ppr FTF_T_T = text "[->]"+ ppr FTF_T_C = text "[-=>]"+ ppr FTF_C_T = text "[=>]"+ ppr FTF_C_C = text "[==>]" -instance Binary AnonArgFlag where- put_ bh VisArg = putByte bh 0- put_ bh InvisArg = putByte bh 1+instance Binary FunTyFlag where+ put_ bh FTF_T_T = putByte bh 0+ put_ bh FTF_T_C = putByte bh 1+ put_ bh FTF_C_T = putByte bh 2+ put_ bh FTF_C_C = putByte bh 3 get bh = do h <- getByte bh case h of- 0 -> return VisArg- _ -> return InvisArg+ 0 -> return FTF_T_T+ 1 -> return FTF_T_C+ 2 -> return FTF_C_T+ _ -> return FTF_C_C -{- Note [AnonArgFlag]+mkFunTyFlag :: TypeOrConstraint -> TypeOrConstraint -> FunTyFlag+mkFunTyFlag TypeLike torc = visArg torc+mkFunTyFlag ConstraintLike torc = invisArg torc++visArg :: TypeOrConstraint -> FunTyFlag+visArg TypeLike = FTF_T_T+visArg ConstraintLike = FTF_T_C++visArgTypeLike :: FunTyFlag+visArgTypeLike = FTF_T_T++visArgConstraintLike :: FunTyFlag+visArgConstraintLike = FTF_T_C++invisArg :: TypeOrConstraint -> FunTyFlag+invisArg TypeLike = FTF_C_T+invisArg ConstraintLike = FTF_C_C++invisArgTypeLike :: FunTyFlag+invisArgTypeLike = FTF_C_T++invisArgConstraintLike :: FunTyFlag+invisArgConstraintLike = FTF_C_C++isInvisibleFunArg :: FunTyFlag -> Bool+isInvisibleFunArg af = not (isVisibleFunArg af)++isVisibleFunArg :: FunTyFlag -> Bool+isVisibleFunArg FTF_T_T = True+isVisibleFunArg FTF_T_C = True+isVisibleFunArg _ = False++isFUNArg :: FunTyFlag -> Bool+-- This one, FUN, or (->), has an extra multiplicity argument+isFUNArg FTF_T_T = True+isFUNArg _ = False++funTyFlagResultTypeOrConstraint :: FunTyFlag -> TypeOrConstraint+-- Whether it /returns/ a type or a constraint+funTyFlagResultTypeOrConstraint FTF_T_T = TypeLike+funTyFlagResultTypeOrConstraint FTF_C_T = TypeLike+funTyFlagResultTypeOrConstraint _ = ConstraintLike++{- Note [FunTyFlag] ~~~~~~~~~~~~~~~~~~~~~-AnonArgFlag is used principally in the FunTy constructor of Type.- FunTy VisArg t1 t2 means t1 -> t2- FunTy InvisArg t1 t2 means t1 => t2+FunTyFlag is used principally in the FunTy constructor of Type.+ FunTy FTF_T_T t1 t2 means t1 -> t2+ FunTy FTF_C_T t1 t2 means t1 => t2+ FunTy FTF_T_C t1 t2 means t1 -=> t2+ FunTy FTF_C_C t1 t2 means t1 ==> t2 -However, the AnonArgFlag in a FunTy is just redundant, cached+However, the FunTyFlag in a FunTy is just redundant, cached information. In (FunTy { ft_af = af, ft_arg = t1, ft_res = t2 })- * if (isPredTy t1 = True) then af = InvisArg- * if (isPredTy t1 = False) then af = VisArg+ ---------------------------------------------+ (isPredTy t1) (isPredTy ty) FunTyFlag+ ---------------------------------------------+ False False FTF_T_T+ False True FTF_T_C+ True False FTF_C_T+ True True FTF_C_C where isPredTy is defined in GHC.Core.Type, and sees if t1's-kind is Constraint. See GHC.Core.TyCo.Rep-Note [Types for coercions, predicates, and evidence]--GHC.Core.Utils.mkFunctionType :: Mult -> Type -> Type -> Type-uses isPredTy to decide the AnonArgFlag for the FunTy.+kind is Constraint. See GHC.Core.Type.chooseFunTyFlag, and+GHC.Core.TyCo.Rep Note [Types for coercions, predicates, and evidence] -The term (Lam b e), and coercion (FunCo co1 co2) don't carry-AnonArgFlags; instead they use mkFunctionType when we want to-get their types; see mkLamType and coercionLKind/RKind resp.-This is just an engineering choice; we could cache here too-if we wanted.+The term (Lam b e) donesn't carry an FunTyFlag; instead it uses+mkFunctionType when we want to get its types; see mkLamType. This is+just an engineering choice; we could cache here too if we wanted. Why bother with all this? After all, we are in Core, where (=>) and (->) behave the same. We maintain this distinction throughout Core so@@ -591,7 +654,7 @@ {- ********************************************************************* * *-* VarBndr, TyCoVarBinder+* VarBndr, ForAllTyBinder * * ********************************************************************* -} @@ -600,29 +663,29 @@ VarBndr is polymorphic in both var and visibility fields. Currently there are nine different uses of 'VarBndr': -* Var.TyCoVarBinder = VarBndr TyCoVar ArgFlag+* Var.ForAllTyBinder = VarBndr TyCoVar ForAllTyFlag Binder of a forall-type; see ForAllTy in GHC.Core.TyCo.Rep -* Var.TyVarBinder = VarBndr TyVar ArgFlag- Subset of TyCoVarBinder when we are sure the binder is a TyVar+* Var.TyVarBinder = VarBndr TyVar ForAllTyFlag+ Subset of ForAllTyBinder when we are sure the binder is a TyVar * Var.InvisTVBinder = VarBndr TyVar Specificity- Specialised form of TyVarBinder, when ArgFlag = Invisible s+ Specialised form of TyVarBinder, when ForAllTyFlag = Invisible s See GHC.Core.Type.splitForAllInvisTVBinders * Var.ReqTVBinder = VarBndr TyVar ()- Specialised form of TyVarBinder, when ArgFlag = Required+ Specialised form of TyVarBinder, when ForAllTyFlag = Required See GHC.Core.Type.splitForAllReqTVBinders This one is barely used * TyCon.TyConBinder = VarBndr TyVar TyConBndrVis Binders of a TyCon; see TyCon in GHC.Core.TyCon -* TyCon.TyConTyCoBinder = VarBndr TyCoVar TyConBndrVis+* TyCon.TyConPiTyBinder = VarBndr TyCoVar TyConBndrVis Binders of a PromotedDataCon See Note [Promoted GADT data constructors] in GHC.Core.TyCon -* IfaceType.IfaceForAllBndr = VarBndr IfaceBndr ArgFlag+* IfaceType.IfaceForAllBndr = VarBndr IfaceBndr ForAllTyFlag * IfaceType.IfaceForAllSpecBndr = VarBndr IfaceBndr Specificity * IfaceType.IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis -}@@ -633,26 +696,29 @@ -- | Variable Binder ----- A 'TyCoVarBinder' is the binder of a ForAllTy+-- A 'ForAllTyBinder' is the binder of a ForAllTy -- It's convenient to define this synonym here rather its natural -- home in "GHC.Core.TyCo.Rep", because it's used in GHC.Core.DataCon.hs-boot -- -- A 'TyVarBinder' is a binder with only TyVar-type TyCoVarBinder = VarBndr TyCoVar ArgFlag-type TyVarBinder = VarBndr TyVar ArgFlag-type InvisTVBinder = VarBndr TyVar Specificity-type ReqTVBinder = VarBndr TyVar ()+type ForAllTyBinder = VarBndr TyCoVar ForAllTyFlag+type InvisTyBinder = VarBndr TyCoVar Specificity+type ReqTyBinder = VarBndr TyCoVar () -tyVarSpecToBinders :: [VarBndr a Specificity] -> [VarBndr a ArgFlag]+type TyVarBinder = VarBndr TyVar ForAllTyFlag+type InvisTVBinder = VarBndr TyVar Specificity+type ReqTVBinder = VarBndr TyVar ()++tyVarSpecToBinders :: [VarBndr a Specificity] -> [VarBndr a ForAllTyFlag] tyVarSpecToBinders = map tyVarSpecToBinder -tyVarSpecToBinder :: VarBndr a Specificity -> VarBndr a ArgFlag+tyVarSpecToBinder :: VarBndr a Specificity -> VarBndr a ForAllTyFlag tyVarSpecToBinder (Bndr tv vis) = Bndr tv (Invisible vis) -tyVarReqToBinders :: [VarBndr a ()] -> [VarBndr a ArgFlag]+tyVarReqToBinders :: [VarBndr a ()] -> [VarBndr a ForAllTyFlag] tyVarReqToBinders = map tyVarReqToBinder -tyVarReqToBinder :: VarBndr a () -> VarBndr a ArgFlag+tyVarReqToBinder :: VarBndr a () -> VarBndr a ForAllTyFlag tyVarReqToBinder (Bndr tv _) = Bndr tv Required binderVar :: VarBndr tv argf -> tv@@ -661,15 +727,21 @@ binderVars :: [VarBndr tv argf] -> [tv] binderVars tvbs = map binderVar tvbs -binderArgFlag :: VarBndr tv argf -> argf-binderArgFlag (Bndr _ argf) = argf+binderFlag :: VarBndr tv argf -> argf+binderFlag (Bndr _ argf) = argf +binderFlags :: [VarBndr tv argf] -> [argf]+binderFlags tvbs = map binderFlag tvbs+ binderType :: VarBndr TyCoVar argf -> Type binderType (Bndr tv _) = varType tv +isTyVarBinder :: VarBndr TyCoVar vis -> Bool+isTyVarBinder (Bndr tcv _) = isTyVar tcv+ -- | Make a named binder-mkTyCoVarBinder :: vis -> TyCoVar -> VarBndr TyCoVar vis-mkTyCoVarBinder vis var = Bndr var vis+mkForAllTyBinder :: vis -> TyCoVar -> VarBndr TyCoVar vis+mkForAllTyBinder vis var = Bndr var vis -- | Make a named binder -- 'var' should be a type variable@@ -679,24 +751,21 @@ Bndr var vis -- | Make many named binders-mkTyCoVarBinders :: vis -> [TyCoVar] -> [VarBndr TyCoVar vis]-mkTyCoVarBinders vis = map (mkTyCoVarBinder vis)+mkForAllTyBinders :: vis -> [TyCoVar] -> [VarBndr TyCoVar vis]+mkForAllTyBinders vis = map (mkForAllTyBinder vis) -- | Make many named binders -- Input vars should be type variables mkTyVarBinders :: vis -> [TyVar] -> [VarBndr TyVar vis] mkTyVarBinders vis = map (mkTyVarBinder vis) -isTyVarBinder :: TyCoVarBinder -> Bool-isTyVarBinder (Bndr v _) = isTyVar v- mapVarBndr :: (var -> var') -> (VarBndr var flag) -> (VarBndr var' flag) mapVarBndr f (Bndr v fl) = Bndr (f v) fl mapVarBndrs :: (var -> var') -> [VarBndr var flag] -> [VarBndr var' flag] mapVarBndrs f = map (mapVarBndr f) -instance Outputable tv => Outputable (VarBndr tv ArgFlag) where+instance Outputable tv => Outputable (VarBndr tv ForAllTyFlag) where ppr (Bndr v Required) = ppr v ppr (Bndr v Specified) = char '@' <> ppr v ppr (Bndr v Inferred) = braces (ppr v)@@ -711,6 +780,270 @@ instance NamedThing tv => NamedThing (VarBndr tv flag) where getName (Bndr tv _) = getName tv+++{- **********************************************************************+* *+ PiTyBinder+* *+********************************************************************** -}++-- | A 'PiTyBinder' represents an argument to a function. PiTyBinders can be+-- dependent ('Named') or nondependent ('Anon'). They may also be visible or+-- not. See Note [PiTyBinders]+data PiTyBinder+ = Named ForAllTyBinder -- A type-lambda binder, with a ForAllTyFlag+ | Anon (Scaled Type) FunTyFlag -- A term-lambda binder. Type here can be CoercionTy.+ -- The arrow is described by the FunTyFlag+ deriving Data++instance Outputable PiTyBinder where+ ppr (Anon ty af) = ppr af <+> ppr ty+ ppr (Named (Bndr v Required)) = ppr v+ ppr (Named (Bndr v Specified)) = char '@' <> ppr v+ ppr (Named (Bndr v Inferred)) = braces (ppr v)+++-- | 'PiTyVarBinder' is like 'PiTyBinder', but there can only be 'TyVar'+-- in the 'Named' field.+type PiTyVarBinder = PiTyBinder++-- | Does this binder bind an invisible argument?+isInvisiblePiTyBinder :: PiTyBinder -> Bool+isInvisiblePiTyBinder (Named (Bndr _ vis)) = isInvisibleForAllTyFlag vis+isInvisiblePiTyBinder (Anon _ af) = isInvisibleFunArg af++-- | Does this binder bind a visible argument?+isVisiblePiTyBinder :: PiTyBinder -> Bool+isVisiblePiTyBinder = not . isInvisiblePiTyBinder++isNamedPiTyBinder :: PiTyBinder -> Bool+isNamedPiTyBinder (Named {}) = True+isNamedPiTyBinder (Anon {}) = False++namedPiTyBinder_maybe :: PiTyBinder -> Maybe TyCoVar+namedPiTyBinder_maybe (Named tv) = Just $ binderVar tv+namedPiTyBinder_maybe _ = Nothing++-- | Does this binder bind a variable that is /not/ erased? Returns+-- 'True' for anonymous binders.+isAnonPiTyBinder :: PiTyBinder -> Bool+isAnonPiTyBinder (Named {}) = False+isAnonPiTyBinder (Anon {}) = True++-- | Extract a relevant type, if there is one.+anonPiTyBinderType_maybe :: PiTyBinder -> Maybe Type+anonPiTyBinderType_maybe (Named {}) = Nothing+anonPiTyBinderType_maybe (Anon ty _) = Just (scaledThing ty)++-- | If its a named binder, is the binder a tyvar?+-- Returns True for nondependent binder.+-- This check that we're really returning a *Ty*Binder (as opposed to a+-- coercion binder). That way, if/when we allow coercion quantification+-- in more places, we'll know we missed updating some function.+isTyBinder :: PiTyBinder -> Bool+isTyBinder (Named bnd) = isTyVarBinder bnd+isTyBinder _ = True++piTyBinderType :: PiTyBinder -> Type+piTyBinderType (Named (Bndr tv _)) = varType tv+piTyBinderType (Anon ty _) = scaledThing ty++{- Note [PiTyBinders]+~~~~~~~~~~~~~~~~~~~+But a type like+ forall a. Maybe a -> forall b. (a,b) -> b++can be decomposed to a telescope of type [PiTyBinder], using splitPiTys.+That function splits off all leading foralls and arrows, giving+ ([Named a, Anon (Maybe a), Named b, Anon (a,b)], b)++A PiTyBinder represents the type of binders -- that is, the type of an+argument to a Pi-type. GHC Core currently supports two different+Pi-types:++ * Anon ty1 fun_flag: a non-dependent function type,+ written with ->, e.g. ty1 -> ty2+ represented as FunTy ty1 ty2. These are+ lifted to Coercions with the corresponding FunCo.++ * Named (Var tv forall_flag)+ A dependent compile-time-only polytype,+ written with forall, e.g. forall (a:*). ty+ represented as ForAllTy (Bndr a v) ty++Both forms of Pi-types classify terms/types that take an argument. In other+words, if `x` is either a function or a polytype, `x arg` makes sense+(for an appropriate `arg`).++Wrinkles++* The Anon constructor of PiTyBinder contains a FunTyFlag. Since+ the PiTyBinder really only describes the /argument/ it should perhaps+ only have a TypeOrConstraint rather than a full FunTyFlag. But it's+ very convenient to have the full FunTyFlag, say in mkPiTys, so that's+ what we do.+++Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+* A ForAllTy (used for both types and kinds) contains a ForAllTyBinder.+ Each ForAllTyBinder+ Bndr a tvis+ is equipped with tvis::ForAllTyFlag, which says whether or not arguments+ for this binder should be visible (explicit) in source Haskell.++* A TyCon contains a list of TyConBinders. Each TyConBinder+ Bndr a cvis+ is equipped with cvis::TyConBndrVis, which says whether or not type+ and kind arguments for this TyCon should be visible (explicit) in+ source Haskell.++This table summarises the visibility rules:+---------------------------------------------------------------------------------------+| Occurrences look like this+| GHC displays type as in Haskell source code+|--------------------------------------------------------------------------------------+| Bndr a tvis :: ForAllTyBinder, in the binder of ForAllTy for a term+| tvis :: ForAllTyFlag+| tvis = Inferred: f :: forall {a}. type Arg not allowed: f+ f :: forall {co}. type Arg not allowed: f+| tvis = Specified: f :: forall a. type Arg optional: f or f @Int+| tvis = Required: T :: forall k -> type Arg required: T *+| This last form is illegal in terms: See Note [No Required PiTyBinder in terms]+|+| Bndr k cvis :: TyConBinder, in the TyConBinders of a TyCon+| cvis :: TyConBndrVis+| cvis = AnonTCB: T :: kind -> kind Required: T *+| cvis = NamedTCB Inferred: T :: forall {k}. kind Arg not allowed: T+| T :: forall {co}. kind Arg not allowed: T+| cvis = NamedTCB Specified: T :: forall k. kind Arg not allowed[1]: T+| cvis = NamedTCB Required: T :: forall k -> kind Required: T *+---------------------------------------------------------------------------------------++[1] In types, in the Specified case, it would make sense to allow+ optional kind applications, thus (T @*), but we have not+ yet implemented that++---- In term declarations ----++* Inferred. Function defn, with no signature: f1 x = x+ We infer f1 :: forall {a}. a -> a, with 'a' Inferred+ It's Inferred because it doesn't appear in any+ user-written signature for f1++* Specified. Function defn, with signature (implicit forall):+ f2 :: a -> a; f2 x = x+ So f2 gets the type f2 :: forall a. a -> a, with 'a' Specified+ even though 'a' is not bound in the source code by an explicit forall++* Specified. Function defn, with signature (explicit forall):+ f3 :: forall a. a -> a; f3 x = x+ So f3 gets the type f3 :: forall a. a -> a, with 'a' Specified++* Inferred. Function defn, with signature (explicit forall), marked as inferred:+ f4 :: forall {a}. a -> a; f4 x = x+ So f4 gets the type f4 :: forall {a}. a -> a, with 'a' Inferred+ It's Inferred because the user marked it as such, even though it does appear+ in the user-written signature for f4++* Inferred/Specified. Function signature with inferred kind polymorphism.+ f5 :: a b -> Int+ So 'f5' gets the type f5 :: forall {k} (a:k->*) (b:k). a b -> Int+ Here 'k' is Inferred (it's not mentioned in the type),+ but 'a' and 'b' are Specified.++* Specified. Function signature with explicit kind polymorphism+ f6 :: a (b :: k) -> Int+ This time 'k' is Specified, because it is mentioned explicitly,+ so we get f6 :: forall (k:*) (a:k->*) (b:k). a b -> Int++* Similarly pattern synonyms:+ Inferred - from inferred types (e.g. no pattern type signature)+ - or from inferred kind polymorphism++---- In type declarations ----++* Inferred (k)+ data T1 a b = MkT1 (a b)+ Here T1's kind is T1 :: forall {k:*}. (k->*) -> k -> *+ The kind variable 'k' is Inferred, since it is not mentioned++ Note that 'a' and 'b' correspond to /Anon/ PiTyBinders in T1's kind,+ and Anon binders don't have a visibility flag. (Or you could think+ of Anon having an implicit Required flag.)++* Specified (k)+ data T2 (a::k->*) b = MkT (a b)+ Here T's kind is T :: forall (k:*). (k->*) -> k -> *+ The kind variable 'k' is Specified, since it is mentioned in+ the signature.++* Required (k)+ data T k (a::k->*) b = MkT (a b)+ Here T's kind is T :: forall k:* -> (k->*) -> k -> *+ The kind is Required, since it bound in a positional way in T's declaration+ Every use of T must be explicitly applied to a kind++* Inferred (k1), Specified (k)+ data T a b (c :: k) = MkT (a b) (Proxy c)+ Here T's kind is T :: forall {k1:*} (k:*). (k1->*) -> k1 -> k -> *+ So 'k' is Specified, because it appears explicitly,+ but 'k1' is Inferred, because it does not++Generally, in the list of TyConBinders for a TyCon,++* Inferred arguments always come first+* Specified, Anon and Required can be mixed++e.g.+ data Foo (a :: Type) :: forall b. (a -> b -> Type) -> Type where ...++Here Foo's TyConBinders are+ [Required 'a', Specified 'b', Anon]+and its kind prints as+ Foo :: forall a -> forall b. (a -> b -> Type) -> Type++See also Note [Required, Specified, and Inferred for types] in GHC.Tc.TyCl++---- Printing -----++ We print forall types with enough syntax to tell you their visibility+ flag. But this is not source Haskell, and these types may not all+ be parsable.++ Specified: a list of Specified binders is written between `forall` and `.`:+ const :: forall a b. a -> b -> a++ Inferred: like Specified, but every binder is written in braces:+ f :: forall {k} (a:k). S k a -> Int++ Required: binders are put between `forall` and `->`:+ T :: forall k -> *++---- Other points -----++* In classic Haskell, all named binders (that is, the type variables in+ a polymorphic function type f :: forall a. a -> a) have been Inferred.++* Inferred variables correspond to "generalized" variables from the+ Visible Type Applications paper (ESOP'16).++Note [No Required PiTyBinder in terms]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+We don't allow Required foralls for term variables, including pattern+synonyms and data constructors. Why? Because then an application+would need a /compulsory/ type argument (possibly without an "@"?),+thus (f Int); and we don't have concrete syntax for that.++We could change this decision, but Required, Named PiTyBinders are rare+anyway. (Most are Anons.)++However the type of a term can (just about) have a required quantifier;+see Note [Required quantifiers in the type of a term] in GHC.Tc.Gen.Expr.+-}++ {- ************************************************************************
compiler/GHC/Types/Var.hs-boot view
@@ -9,8 +9,8 @@ -- otherwise-unnecessary import tells the build system that this module -- depends on GhcPrelude, which ensures that GHC.Type is built first. -data ArgFlag-data AnonArgFlag+data ForAllTyFlag+data FunTyFlag data Var instance NamedThing Var data VarBndr var argf
compiler/GHC/Types/Var/Env.hs view
@@ -23,7 +23,7 @@ isEmptyVarEnv, elemVarEnvByKey, filterVarEnv, restrictVarEnv,- partitionVarEnv,+ partitionVarEnv, varEnvDomain, -- * Deterministic Var environments (maps) DVarEnv, DIdEnv, DTyVarEnv,@@ -83,6 +83,7 @@ import GHC.Types.Name import GHC.Types.Var as Var import GHC.Types.Var.Set+import GHC.Data.Graph.UnVar -- UnVarSet import GHC.Types.Unique.Set import GHC.Types.Unique.FM import GHC.Types.Unique.DFM@@ -505,6 +506,7 @@ plusVarEnv :: VarEnv a -> VarEnv a -> VarEnv a plusVarEnvList :: [VarEnv a] -> VarEnv a extendVarEnvList :: VarEnv a -> [(Var, a)] -> VarEnv a+varEnvDomain :: VarEnv elt -> UnVarSet partitionVarEnv :: (a -> Bool) -> VarEnv a -> (VarEnv a, VarEnv a) -- | Only keep variables contained in the VarSet@@ -561,7 +563,9 @@ emptyVarEnv = emptyUFM unitVarEnv = unitUFM isEmptyVarEnv = isNullUFM-partitionVarEnv = partitionUFM+partitionVarEnv = partitionUFM+varEnvDomain = domUFMUnVarSet+ restrictVarEnv env vs = filterUFM_Directly keep env where
compiler/GHC/Unit/External.hs view
@@ -21,11 +21,10 @@ import GHC.Unit import GHC.Unit.Module.ModIface -import GHC.Core ( RuleBase ) import GHC.Core.FamInstEnv import GHC.Core.InstEnv ( InstEnv, emptyInstEnv ) import GHC.Core.Opt.ConstantFold-import GHC.Core.Rules (mkRuleBase)+import GHC.Core.Rules ( RuleBase, mkRuleBase) import GHC.Types.Annotations ( AnnEnv, emptyAnnEnv ) import GHC.Types.CompleteMatch
compiler/GHC/Unit/Module/Graph.hs view
@@ -42,6 +42,7 @@ where import GHC.Prelude+import GHC.Platform import qualified GHC.LanguageExtensions as LangExt @@ -49,7 +50,6 @@ import GHC.Data.Graph.Directed import GHC.Driver.Backend-import GHC.Driver.Ppr import GHC.Driver.Session import GHC.Types.SourceFile ( hscSourceString )@@ -263,7 +263,8 @@ _ -> False platform = targetPlatform dflags- exe_file = exeFileName platform staticLink (outputFile_ dflags)+ arch_os = platformArchOS platform+ exe_file = exeFileName arch_os staticLink (outputFile_ dflags) in text exe_file showModMsg _ _ (InstantiationNode _uid indef_unit) = ppr $ instUnitInstanceOf indef_unit@@ -278,8 +279,8 @@ where op = normalise- mod = moduleName (ms_mod mod_summary)- mod_str = showPpr dflags mod ++ hscSourceString (ms_hsc_src mod_summary)+ mod_str = moduleNameString (moduleName (ms_mod mod_summary)) +++ hscSourceString (ms_hsc_src mod_summary) dyn_file = op $ msDynObjFilePath mod_summary obj_file = op $ msObjFilePath mod_summary files = [ obj_file ]
compiler/GHC/Unit/Module/WholeCoreBindings.hs view
@@ -57,7 +57,7 @@ -} data WholeCoreBindings = WholeCoreBindings- { wcb_bindings :: [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo]- , wcb_module :: Module- , wcb_mod_location :: ModLocation+ { wcb_bindings :: [IfaceBindingX IfaceMaybeRhs IfaceTopBndrInfo] -- ^ serialised tidied core bindings.+ , wcb_module :: Module -- ^ The module which the bindings are for+ , wcb_mod_location :: ModLocation -- ^ The location where the sources reside. }
compiler/GHC/Unit/Types.hs view
@@ -50,6 +50,7 @@ , stableUnitCmp , unitIsDefinite , isHoleUnit+ , pprUnit -- * Unit Ids , unitIdString@@ -89,6 +90,7 @@ where import GHC.Prelude+ import GHC.Types.Unique import GHC.Types.Unique.DSet import GHC.Utils.Binary@@ -162,19 +164,24 @@ ppr = pprInstantiatedModule instance Outputable InstantiatedUnit where- ppr uid =+ ppr = pprInstantiatedUnit++pprInstantiatedUnit :: IsLine doc => InstantiatedUnit -> doc+pprInstantiatedUnit uid = -- getPprStyle $ \sty ->- ppr cid <>+ pprUnitId cid <> (if not (null insts) -- pprIf then brackets (hcat (punctuate comma $- [ ppr modname <> text "=" <> pprModule m+ [ pprModuleName modname <> text "=" <> pprModule m | (modname, m) <- insts])) else empty) where cid = instUnitInstanceOf uid insts = instUnitInsts uid+{-# SPECIALIZE pprInstantiatedUnit :: InstantiatedUnit -> SDoc #-}+{-# SPECIALIZE pprInstantiatedUnit :: InstantiatedUnit -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -- | Class for types that are used as unit identifiers (UnitKey, UnitId, Unit) --@@ -195,8 +202,8 @@ unitFS (RealUnit (Definite x)) = unitFS x unitFS HoleUnit = holeFS -pprModule :: Module -> SDoc-pprModule mod@(Module p n) = getPprStyle doc+pprModule :: IsLine doc => Module -> doc+pprModule mod@(Module p n) = docWithContext (doc . sdocStyle) where doc sty | codeStyle sty =@@ -207,10 +214,11 @@ | qualModule sty mod = case p of HoleUnit -> angleBrackets (pprModuleName n)- _ -> ppr p <> char ':' <> pprModuleName n+ _ -> pprUnit p <> char ':' <> pprModuleName n | otherwise = pprModuleName n-+{-# SPECIALIZE pprModule :: Module -> SDoc #-}+{-# SPECIALIZE pprModule :: Module -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable pprInstantiatedModule :: InstantiatedModule -> SDoc pprInstantiatedModule (Module uid m) =@@ -344,10 +352,12 @@ instance Outputable Unit where ppr pk = pprUnit pk -pprUnit :: Unit -> SDoc-pprUnit (RealUnit uid) = ppr uid-pprUnit (VirtUnit uid) = ppr uid+pprUnit :: IsLine doc => Unit -> doc+pprUnit (RealUnit (Definite d)) = pprUnitId d+pprUnit (VirtUnit uid) = pprInstantiatedUnit uid pprUnit HoleUnit = ftext holeFS+{-# SPECIALIZE pprUnit :: Unit -> SDoc #-}+{-# SPECIALIZE pprUnit :: Unit -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable instance Show Unit where show = unitString@@ -523,8 +533,14 @@ getUnique = getUnique . unitIdFS instance Outputable UnitId where- ppr (UnitId fs) = sdocOption sdocUnitIdForUser ($ fs) -- see Note [Pretty-printing UnitId]- -- in "GHC.Unit"+ ppr = pprUnitId++pprUnitId :: IsLine doc => UnitId -> doc+pprUnitId (UnitId fs) = dualLine (sdocOption sdocUnitIdForUser ($ fs)) (ftext fs)+ -- see Note [Pretty-printing UnitId] in GHC.Unit+ -- also see Note [dualLine and dualDoc] in GHC.Utils.Outputable+{-# SPECIALIZE pprUnitId :: UnitId -> SDoc #-}+{-# SPECIALIZE pprUnitId :: UnitId -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -- | A 'DefUnitId' is an 'UnitId' with the invariant that -- it only refers to a definite library; i.e., one we have generated
compiler/GHC/Unit/Types.hs-boot view
@@ -1,7 +1,7 @@ {-# LANGUAGE KindSignatures #-} module GHC.Unit.Types where -import GHC.Prelude ()+-- No Prelude. See Note [Exporting pprTrace from GHC.Prelude] import Language.Haskell.Syntax.Module.Name (ModuleName) import Data.Kind (Type)
compiler/GHC/Utils/Binary.hs view
@@ -34,6 +34,7 @@ SymbolTable, Dictionary, BinData(..), dataHandle, handleData,+ unsafeUnpackBinBuffer, openBinMem, -- closeBin,@@ -47,8 +48,10 @@ writeBinMem, readBinMem,+ readBinMemN, putAt, getAt,+ forwardPut, forwardPut_, forwardGet, -- * For writing instances putByte,@@ -71,8 +74,11 @@ -- * User data UserData(..), getUserData, setUserData,- newReadState, newWriteState,+ newReadState, newWriteState, noUserData,++ -- * String table ("dictionary") putDictionary, getDictionary, putFS,+ FSTable, initFSTable, getDictFastString, putDictFastString, -- * Newtype wrappers BinSpan(..), BinSrcSpan(..), BinLocated(..)@@ -89,10 +95,11 @@ import GHC.Data.FastMutInt import GHC.Utils.Fingerprint import GHC.Types.SrcLoc+import GHC.Types.Unique import qualified GHC.Data.Strict as Strict import Control.DeepSeq-import Foreign hiding (shiftL, shiftR)+import Foreign hiding (shiftL, shiftR, void) import Data.Array import Data.Array.IO import Data.Array.Unsafe@@ -107,7 +114,7 @@ import qualified Data.Set as Set import Data.Time import Data.List (unfoldr)-import Control.Monad ( when, (<$!>), unless, forM_ )+import Control.Monad ( when, (<$!>), unless, forM_, void ) import System.IO as IO import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO.Error ( mkIOError, eofErrorType )@@ -186,6 +193,12 @@ ix <- readFastMutInt ix_r action $ BS.fromForeignPtr arr 0 ix +unsafeUnpackBinBuffer :: ByteString -> IO BinHandle+unsafeUnpackBinBuffer (BS.BS arr len) = do+ arr_r <- newIORef arr+ ix_r <- newFastMutInt 0+ sz_r <- newFastMutInt len+ return (BinMem noUserData ix_r sz_r arr_r) --------------------------------------------------------------- -- Bin@@ -222,7 +235,7 @@ openBinMem :: Int -> IO BinHandle openBinMem size- | size <= 0 = error "Data.Binary.openBinMem: size must be >= 0"+ | size <= 0 = error "GHC.Utils.Binary.openBinMem: size must be >= 0" | otherwise = do arr <- mallocForeignPtrBytes size arr_r <- newIORef arr@@ -240,6 +253,14 @@ then do expandBin h p; writeFastMutInt ix_r p else writeFastMutInt ix_r p +-- | SeekBin but without calling expandBin+seekBinNoExpand :: BinHandle -> Bin a -> IO ()+seekBinNoExpand (BinMem _ ix_r sz_r _) (BinPtr !p) = do+ sz <- readFastMutInt sz_r+ if (p >= sz)+ then panic "seekBinNoExpand: seek out of range"+ else writeFastMutInt ix_r p+ writeBinMem :: BinHandle -> FilePath -> IO () writeBinMem (BinMem _ ix_r _ arr_r) fn = do h <- openBinaryFile fn WriteMode@@ -249,16 +270,27 @@ hClose h readBinMem :: FilePath -> IO BinHandle--- Return a BinHandle with a totally undefined State readBinMem filename = do- h <- openBinaryFile filename ReadMode- filesize' <- hFileSize h- let filesize = fromIntegral filesize'+ withBinaryFile filename ReadMode $ \h -> do+ filesize' <- hFileSize h+ let filesize = fromIntegral filesize'+ readBinMem_ filesize h++readBinMemN :: Int -> FilePath -> IO (Maybe BinHandle)+readBinMemN size filename = do+ withBinaryFile filename ReadMode $ \h -> do+ filesize' <- hFileSize h+ let filesize = fromIntegral filesize'+ if filesize < size+ then pure Nothing+ else Just <$> readBinMem_ size h++readBinMem_ :: Int -> Handle -> IO BinHandle+readBinMem_ filesize h = do arr <- mallocForeignPtrBytes filesize count <- unsafeWithForeignPtr arr $ \p -> hGetBuf h p filesize when (count /= filesize) $ error ("Binary.readBinMem: only read " ++ show count ++ " bytes")- hClose h arr_r <- newIORef arr ix_r <- newFastMutInt 0 sz_r <- newFastMutInt filesize@@ -557,7 +589,9 @@ -- | Encode the argument in it's full length. This is different from many default -- binary instances which make no guarantee about the actual encoding and -- might do things use variable length encoding.-newtype FixedLengthEncoding a = FixedLengthEncoding { unFixedLength :: a }+newtype FixedLengthEncoding a+ = FixedLengthEncoding { unFixedLength :: a }+ deriving (Eq,Ord,Show) instance Binary (FixedLengthEncoding Word8) where put_ h (FixedLengthEncoding x) = putByte h x@@ -920,6 +954,45 @@ -- -----------------------------------------------------------------------------+-- Forward reading/writing++-- | "forwardPut put_A put_B" outputs A after B but allows A to be read before B+-- by using a forward reference+forwardPut :: BinHandle -> (b -> IO a) -> IO b -> IO (a,b)+forwardPut bh put_A put_B = do+ -- write placeholder pointer to A+ pre_a <- tellBin bh+ put_ bh pre_a++ -- write B+ r_b <- put_B++ -- update A's pointer+ a <- tellBin bh+ putAt bh pre_a a+ seekBinNoExpand bh a++ -- write A+ r_a <- put_A r_b+ pure (r_a,r_b)++forwardPut_ :: BinHandle -> (b -> IO a) -> IO b -> IO ()+forwardPut_ bh put_A put_B = void $ forwardPut bh put_A put_B++-- | Read a value stored using a forward reference+forwardGet :: BinHandle -> IO a -> IO a+forwardGet bh get_A = do+ -- read forward reference+ p <- get bh -- a BinPtr+ -- store current position+ p_a <- tellBin bh+ -- go read the forward value, then seek back+ seekBinNoExpand bh p+ r <- get_A+ seekBinNoExpand bh p_a+ pure r++-- ----------------------------------------------------------------------------- -- Lazy reading/writing lazyPut :: Binary a => BinHandle -> a -> IO ()@@ -1026,8 +1099,14 @@ ud_put_fs = put_fs } -noUserData :: a-noUserData = undef "UserData"+noUserData :: UserData+noUserData = UserData+ { ud_get_name = undef "get_name"+ , ud_get_fs = undef "get_fs"+ , ud_put_nonbinding_name = undef "put_nonbinding_name"+ , ud_put_binding_name = undef "put_binding_name"+ , ud_put_fs = undef "put_fs"+ } undef :: String -> a undef s = panic ("Binary.UserData: no " ++ s)@@ -1054,6 +1133,58 @@ fs <- getFS bh writeArray mut_arr i fs unsafeFreeze mut_arr++getDictFastString :: Dictionary -> BinHandle -> IO FastString+getDictFastString dict bh = do+ j <- get bh+ return $! (dict ! fromIntegral (j :: Word32))+++initFSTable :: BinHandle -> IO (BinHandle, FSTable, IO Int)+initFSTable bh = do+ dict_next_ref <- newFastMutInt 0+ dict_map_ref <- newIORef emptyUFM+ let bin_dict = FSTable+ { fs_tab_next = dict_next_ref+ , fs_tab_map = dict_map_ref+ }+ let put_dict = do+ fs_count <- readFastMutInt dict_next_ref+ dict_map <- readIORef dict_map_ref+ putDictionary bh fs_count dict_map+ pure fs_count++ -- BinHandle with FastString writing support+ let ud = getUserData bh+ let ud_fs = ud { ud_put_fs = putDictFastString bin_dict }+ let bh_fs = setUserData bh ud_fs++ return (bh_fs,bin_dict,put_dict)++putDictFastString :: FSTable -> BinHandle -> FastString -> IO ()+putDictFastString dict bh fs = allocateFastString dict fs >>= put_ bh++allocateFastString :: FSTable -> FastString -> IO Word32+allocateFastString FSTable { fs_tab_next = j_r+ , fs_tab_map = out_r+ } f = do+ out <- readIORef out_r+ let !uniq = getUnique f+ case lookupUFM_Directly out uniq of+ Just (j, _) -> return (fromIntegral j :: Word32)+ Nothing -> do+ j <- readFastMutInt j_r+ writeFastMutInt j_r (j + 1)+ writeIORef out_r $! addToUFM_Directly out uniq (j, f)+ return (fromIntegral j :: Word32)++-- FSTable is an exact copy of Haddock.InterfaceFile.BinDictionary. We rename to+-- avoid a collision and copy to avoid a dependency.+data FSTable = FSTable { fs_tab_next :: !FastMutInt -- The next index to use+ , fs_tab_map :: !(IORef (UniqFM FastString (Int,FastString)))+ -- indexed by FastString+ }+ --------------------------------------------------------- -- The Symbol Table
compiler/GHC/Utils/BufHandle.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE MagicHash #-} ----------------------------------------------------------------------------- --@@ -24,7 +25,7 @@ bFlush, ) where -import GHC.Prelude+import GHC.Prelude.Basic import GHC.Data.FastString import GHC.Data.FastMutInt@@ -37,6 +38,10 @@ import Foreign.C.String import System.IO +-- for RULES+import GHC.Exts (unpackCString#, unpackNBytes#, Int(..))+import GHC.Ptr (Ptr(..))+ -- ----------------------------------------------------------------------------- data BufHandle = BufHandle {-#UNPACK#-}!(Ptr Word8)@@ -61,6 +66,22 @@ bPutChar b c else do pokeElemOff buf i (fromIntegral (ord c) :: Word8) writeFastMutInt r (i+1)++-- Equivalent of the text/str, text/unpackNBytes#, text/[] rules+-- in GHC.Utils.Ppr.+{-# RULES "hdoc/str"+ forall a h. bPutStr h (unpackCString# a) = bPutPtrString h (mkPtrString# a)+ #-}+{-# RULES "hdoc/unpackNBytes#"+ forall p n h. bPutStr h (unpackNBytes# p n) = bPutPtrString h (PtrString (Ptr p) (I# n))+ #-}+{-# RULES "hdoc/[]#"+ forall h. bPutStr h [] = return ()+ #-}++{-# NOINLINE [0] bPutStr #-} -- Give the RULE a chance to fire+ -- It must wait till after phase 1 when+ -- the unpackCString first is manifested bPutStr :: BufHandle -> String -> IO () bPutStr (BufHandle buf r hdl) !str = do
compiler/GHC/Utils/Constants.hs view
@@ -8,7 +8,7 @@ ) where -import GHC.Prelude+import GHC.Prelude.Basic {-
compiler/GHC/Utils/Error.hs view
@@ -141,12 +141,12 @@ :: Diagnostic e => Severity -> SrcSpan- -> PrintUnqualified+ -> NamePprCtx -> e -> MsgEnvelope e-mk_msg_envelope severity locn print_unqual err+mk_msg_envelope severity locn name_ppr_ctx err = MsgEnvelope { errMsgSpan = locn- , errMsgContext = print_unqual+ , errMsgContext = name_ppr_ctx , errMsgDiagnostic = err , errMsgSeverity = severity }@@ -158,22 +158,22 @@ :: Diagnostic e => DiagOpts -> SrcSpan- -> PrintUnqualified+ -> NamePprCtx -> e -> MsgEnvelope e-mkMsgEnvelope opts locn print_unqual err- = mk_msg_envelope (diagReasonSeverity opts (diagnosticReason err)) locn print_unqual err+mkMsgEnvelope opts locn name_ppr_ctx err+ = mk_msg_envelope (diagReasonSeverity opts (diagnosticReason err)) locn name_ppr_ctx err -- | Wrap a 'Diagnostic' in a 'MsgEnvelope', recording its location. -- Precondition: the diagnostic is, in fact, an error. That is, -- @diagnosticReason msg == ErrorWithoutFlag@. mkErrorMsgEnvelope :: Diagnostic e => SrcSpan- -> PrintUnqualified+ -> NamePprCtx -> e -> MsgEnvelope e-mkErrorMsgEnvelope locn unqual msg =- assert (diagnosticReason msg == ErrorWithoutFlag) $ mk_msg_envelope SevError locn unqual msg+mkErrorMsgEnvelope locn name_ppr_ctx msg =+ assert (diagnosticReason msg == ErrorWithoutFlag) $ mk_msg_envelope SevError locn name_ppr_ctx msg -- | Variant that doesn't care about qualified/unqualified names. mkPlainMsgEnvelope :: Diagnostic e@@ -247,9 +247,9 @@ pprLocMsgEnvelope opts (MsgEnvelope { errMsgSpan = s , errMsgDiagnostic = e , errMsgSeverity = sev- , errMsgContext = unqual })+ , errMsgContext = name_ppr_ctx }) = sdocWithContext $ \ctx ->- withErrStyle unqual $+ withErrStyle name_ppr_ctx $ mkLocMessage (MCDiagnostic sev (diagnosticReason e) (diagnosticCode e)) s@@ -430,13 +430,13 @@ putMsg :: Logger -> SDoc -> IO () putMsg logger msg = logInfo logger (withPprStyle defaultUserStyle msg) -printInfoForUser :: Logger -> PrintUnqualified -> SDoc -> IO ()-printInfoForUser logger print_unqual msg- = logInfo logger (withUserStyle print_unqual AllTheWay msg)+printInfoForUser :: Logger -> NamePprCtx -> SDoc -> IO ()+printInfoForUser logger name_ppr_ctx msg+ = logInfo logger (withUserStyle name_ppr_ctx AllTheWay msg) -printOutputForUser :: Logger -> PrintUnqualified -> SDoc -> IO ()-printOutputForUser logger print_unqual msg- = logOutput logger (withUserStyle print_unqual AllTheWay msg)+printOutputForUser :: Logger -> NamePprCtx -> SDoc -> IO ()+printOutputForUser logger name_ppr_ctx msg+ = logOutput logger (withUserStyle name_ppr_ctx AllTheWay msg) logInfo :: Logger -> SDoc -> IO () logInfo logger msg = logMsg logger MCInfo noSrcSpan msg
compiler/GHC/Utils/Exception.hs view
@@ -8,7 +8,7 @@ ) where -import GHC.Prelude+import GHC.Prelude.Basic import GHC.IO (catchException) import Control.Exception as CE hiding (assert)
compiler/GHC/Utils/Fingerprint.hs view
@@ -22,7 +22,7 @@ getFileHash ) where -import GHC.Prelude+import GHC.Prelude.Basic import Foreign import GHC.IO
compiler/GHC/Utils/GlobalVars.hs view
@@ -22,7 +22,7 @@ ) where -import GHC.Prelude+import GHC.Prelude.Basic import GHC.Conc.Sync ( sharedCAF )
compiler/GHC/Utils/IO/Unsafe.hs view
@@ -9,7 +9,7 @@ ) where -import GHC.Prelude ()+import GHC.Prelude.Basic () import GHC.Exts import GHC.IO (IO(..))
compiler/GHC/Utils/Json.hs view
@@ -24,7 +24,7 @@ renderJSON d = case d of JSNull -> text "null"- JSBool b -> text $ if b then "true" else "false"+ JSBool b -> if b then text "true" else text "false" JSInt n -> ppr n JSString s -> doubleQuotes $ text $ escapeJsonString s JSArray as -> brackets $ pprList renderJSON as
compiler/GHC/Utils/Lexeme.hs view
@@ -67,17 +67,17 @@ isLexSym cs = isLexConSym cs || isLexVarSym cs --------------isLexConId cs = case unconsFS cs of -- Prefix type or data constructors- Nothing -> False -- e.g. "Foo", "[]", "(,)"- Just (c, _) -> cs == fsLit "[]" || startsConId c+isLexConId cs = case unpackFS cs of -- Prefix type or data constructors+ [] -> False -- e.g. "Foo", "[]", "(,)"+ c:_ -> cs == fsLit "[]" || startsConId c -isLexVarId cs = case unconsFS cs of -- Ordinary prefix identifiers- Nothing -> False -- e.g. "x", "_x"- Just (c, _) -> startsVarId c+isLexVarId cs = case unpackFS cs of -- Ordinary prefix identifiers+ [] -> False -- e.g. "x", "_x"+ c:_ -> startsVarId c -isLexConSym cs = case unconsFS cs of -- Infix type or data constructors- Nothing -> False -- e.g. ":-:", ":", "->"- Just (c, _) -> cs == fsLit "->" || startsConSym c+isLexConSym cs = case unpackFS cs of -- Infix type or data constructors+ [] -> False -- e.g. ":-:", ":", "->"+ c:_ -> cs == fsLit "->" || startsConSym c isLexVarSym fs -- Infix identifiers e.g. "+" | fs == (fsLit "~R#") = True
compiler/GHC/Utils/Logger.hs view
@@ -202,6 +202,7 @@ | FormatASM -- ^ Assembly code | FormatC -- ^ C code/header | FormatLLVM -- ^ LLVM bytecode+ | FormatJS -- ^ JavaScript code | FormatText -- ^ Unstructured dump deriving (Show,Eq) @@ -553,29 +554,29 @@ -- | Dump if the given DumpFlag is set ----- Unlike 'putDumpFileMaybe', has a PrintUnqualified argument+-- Unlike 'putDumpFileMaybe', has a NamePprCtx argument putDumpFileMaybe' :: Logger- -> PrintUnqualified+ -> NamePprCtx -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()-putDumpFileMaybe' logger printer flag hdr fmt doc+putDumpFileMaybe' logger name_ppr_ctx flag hdr fmt doc = when (logHasDumpFlag logger flag) $- logDumpFile' logger printer flag hdr fmt doc+ logDumpFile' logger name_ppr_ctx flag hdr fmt doc {-# INLINE putDumpFileMaybe' #-} -- see Note [INLINE conditional tracing utilities] -logDumpFile' :: Logger -> PrintUnqualified -> DumpFlag+logDumpFile' :: Logger -> NamePprCtx -> DumpFlag -> String -> DumpFormat -> SDoc -> IO () {-# NOINLINE logDumpFile' #-} -- NOINLINE: Now we are past the conditional, into the "cold" path, -- don't inline, to reduce code size at the call site -- See Note [INLINE conditional tracing utilities]-logDumpFile' logger printer flag hdr fmt doc- = logDumpFile logger (mkDumpStyle printer) flag hdr fmt doc+logDumpFile' logger name_ppr_ctx flag hdr fmt doc+ = logDumpFile logger (mkDumpStyle name_ppr_ctx) flag hdr fmt doc -- | Ensure that a dump file is created even if it stays empty touchDumpFile :: Logger -> DumpFlag -> IO ()
compiler/GHC/Utils/Misc.hs view
@@ -7,8 +7,6 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE MagicHash #-} -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- -- | Highly random utility functions -- module GHC.Utils.Misc (@@ -17,9 +15,7 @@ -- * General list processing zipEqual, zipWithEqual, zipWith3Equal, zipWith4Equal,- zipLazy, stretchZipWith, zipWithAndUnzip, zipAndUnzip,-- zipWithLazy, zipWith3Lazy,+ stretchZipWith, zipWithAndUnzip, zipAndUnzip, filterByList, filterByLists, partitionByList, @@ -124,7 +120,7 @@ HasDebugCallStack, ) where -import GHC.Prelude hiding ( head, init, last, tail )+import GHC.Prelude.Basic hiding ( head, init, last, tail ) import GHC.Utils.Exception import GHC.Utils.Panic.Plain@@ -232,10 +228,10 @@ DEBUGging on; hey, why not? -} -zipEqual :: String -> [a] -> [b] -> [(a,b)]-zipWithEqual :: String -> (a->b->c) -> [a]->[b]->[c]-zipWith3Equal :: String -> (a->b->c->d) -> [a]->[b]->[c]->[d]-zipWith4Equal :: String -> (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]+zipEqual :: HasDebugCallStack => String -> [a] -> [b] -> [(a,b)]+zipWithEqual :: HasDebugCallStack => String -> (a->b->c) -> [a]->[b]->[c]+zipWith3Equal :: HasDebugCallStack => String -> (a->b->c->d) -> [a]->[b]->[c]->[d]+zipWith4Equal :: HasDebugCallStack => String -> (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e] #if !defined(DEBUG) zipEqual _ = zip@@ -261,25 +257,6 @@ zipWith4Equal _ _ [] [] [] [] = [] zipWith4Equal msg _ _ _ _ _ = panic ("zipWith4Equal: unequal lists: "++msg) #endif---- | 'zipLazy' is a kind of 'zip' that is lazy in the second list (observe the ~)-zipLazy :: [a] -> [b] -> [(a,b)]-zipLazy [] _ = []-zipLazy (x:xs) ~(y:ys) = (x,y) : zipLazy xs ys---- | 'zipWithLazy' is like 'zipWith' but is lazy in the second list.--- The length of the output is always the same as the length of the first--- list.-zipWithLazy :: (a -> b -> c) -> [a] -> [b] -> [c]-zipWithLazy _ [] _ = []-zipWithLazy f (a:as) ~(b:bs) = f a b : zipWithLazy f as bs---- | 'zipWith3Lazy' is like 'zipWith3' but is lazy in the second and third lists.--- The length of the output is always the same as the length of the first--- list.-zipWith3Lazy :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]-zipWith3Lazy _ [] _ _ = []-zipWith3Lazy f (a:as) ~(b:bs) ~(c:cs) = f a b c : zipWith3Lazy f as bs cs -- | 'filterByList' takes a list of Bools and a list of some elements and -- filters out these elements for which the corresponding value in the list of
compiler/GHC/Utils/Monad.hs view
@@ -19,6 +19,8 @@ , anyM, allM, orM , foldlM, foldlM_, foldrM , whenM, unlessM+ , filterOutM+ , partitionM ) where -------------------------------------------------------------------------------@@ -225,6 +227,19 @@ unlessM :: Monad m => m Bool -> m () -> m () unlessM condM acc = do { cond <- condM ; unless cond acc }++-- | Like 'filterM', only it reverses the sense of the test.+filterOutM :: (Applicative m) => (a -> m Bool) -> [a] -> m [a]+filterOutM p =+ foldr (\ x -> liftA2 (\ flg -> if flg then id else (x:)) (p x)) (pure [])++-- | Monadic version of @partition@+partitionM :: Monad m => (a -> m Bool) -> [a] -> m ([a], [a])+partitionM _ [] = pure ([], [])+partitionM f (x:xs) = do+ res <- f x+ (as,bs) <- partitionM f xs+ pure ([x | res]++as, [x | not res]++bs) {- Note [The one-shot state monad trick] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compiler/GHC/Utils/Outputable.hs view
@@ -5,6 +5,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilyDependencies #-}+{-# LANGUAGE FlexibleContexts #-} {- (c) The University of Glasgow 2006-2012@@ -21,15 +23,18 @@ -- * Type classes Outputable(..), OutputableBndr(..), OutputableP(..), + IsOutput(..), IsLine(..), IsDoc(..),+ HLine, HDoc,+ -- * Pretty printing combinators SDoc, runSDoc, PDoc(..), docToSDoc, interppSP, interpp'SP, interpp'SP', pprQuotedList, pprWithCommas, quotedListWithOr, quotedListWithNor, pprWithBars,- empty, isEmpty, nest,- char,- text, ftext, ptext, ztext,+ spaceIfSingleQuote,+ isEmpty, nest,+ ptext, int, intWithCommas, integer, word, float, double, rational, doublePrec, parens, cparen, brackets, braces, quotes, quote, doubleQuotes, angleBrackets,@@ -38,10 +43,8 @@ lambda, lparen, rparen, lbrack, rbrack, lbrace, rbrace, underscore, blankLine, forAllLit, bullet,- (<>), (<+>), hcat, hsep,- ($$), ($+$), vcat,- sep, cat,- fsep, fcat,+ ($+$),+ cat, fcat, hang, hangNotEmpty, punctuate, ppWhen, ppUnless, ppWhenOption, ppUnlessOption, speakNth, speakN, speakNOf, plural, singular,@@ -83,12 +86,15 @@ -- * Controlling the style in which output is printed BindingSite(..), - PprStyle(..), PrintUnqualified(..),- QueryQualifyName, QueryQualifyModule, QueryQualifyPackage,+ PprStyle(..), NamePprCtx(..),+ QueryQualifyName, QueryQualifyModule, QueryQualifyPackage, QueryPromotionTick,+ PromotedItem(..), IsEmptyOrSingleton(..), isListEmptyOrSingleton,+ PromotionTickContext(..), reallyAlwaysQualify, reallyAlwaysQualifyNames, alwaysQualify, alwaysQualifyNames, alwaysQualifyModules, neverQualify, neverQualifyNames, neverQualifyModules, alwaysQualifyPackages, neverQualifyPackages,+ alwaysPrintPromTick, QualifyName(..), queryQual, sdocOption, updSDocContext,@@ -97,23 +103,24 @@ getPprStyle, withPprStyle, setStyleColoured, pprDeeper, pprDeeperList, pprSetDepth, codeStyle, userStyle, dumpStyle,- qualName, qualModule, qualPackage,+ qualName, qualModule, qualPackage, promTick, mkErrStyle, defaultErrStyle, defaultDumpStyle, mkDumpStyle, defaultUserStyle, mkUserStyle, cmdlineParserStyle, Depth(..), withUserStyle, withErrStyle, ifPprDebug, whenPprDebug, getPprDebug, + bPutHDoc ) where import Language.Haskell.Syntax.Module.Name ( ModuleName(..) ) -import GHC.Prelude+import GHC.Prelude.Basic import {-# SOURCE #-} GHC.Unit.Types ( Unit, Module, moduleName ) import {-# SOURCE #-} GHC.Types.Name.Occurrence( OccName ) -import GHC.Utils.BufHandle (BufHandle)+import GHC.Utils.BufHandle (BufHandle, bPutChar, bPutStr, bPutFS, bPutFZS) import GHC.Data.FastString import qualified GHC.Utils.Ppr as Pretty import qualified GHC.Utils.Ppr.Colour as Col@@ -159,14 +166,14 @@ -} data PprStyle- = PprUser PrintUnqualified Depth Coloured+ = PprUser NamePprCtx Depth Coloured -- Pretty-print in a way that will make sense to the -- ordinary user; must be very close to Haskell -- syntax, etc. -- Assumes printing tidied code: non-system names are -- printed without uniques. - | PprDump PrintUnqualified+ | PprDump NamePprCtx -- For -ddump-foo; less verbose than in ppr-debug mode, but more than PprUser -- Does not assume tidied code: non-external names -- are printed with uniques.@@ -189,10 +196,11 @@ -- original names back to something the user understands. This is the -- purpose of the triple of functions that gets passed around -- when rendering 'SDoc'.-data PrintUnqualified = QueryQualify {+data NamePprCtx = QueryQualify { queryQualifyName :: QueryQualifyName, queryQualifyModule :: QueryQualifyModule,- queryQualifyPackage :: QueryQualifyPackage+ queryQualifyPackage :: QueryQualifyPackage,+ queryPromotionTick :: QueryPromotionTick } -- | Given a `Name`'s `Module` and `OccName`, decide whether and how to qualify@@ -207,6 +215,31 @@ -- the component id to disambiguate it. type QueryQualifyPackage = Unit -> Bool +-- | Given a promoted data constructor,+-- decide whether to print a tick to disambiguate the namespace.+type QueryPromotionTick = PromotedItem -> Bool++-- | Flags that affect whether a promotion tick is printed.+data PromotionTickContext =+ PromTickCtx {+ ptcListTuplePuns :: !Bool,+ ptcPrintRedundantPromTicks :: !Bool+ }++data PromotedItem =+ PromotedItemListSyntax IsEmptyOrSingleton -- '[x]+ | PromotedItemTupleSyntax -- '(x, y)+ | PromotedItemDataCon OccName -- 'MkT++newtype IsEmptyOrSingleton = IsEmptyOrSingleton Bool++isListEmptyOrSingleton :: [a] -> IsEmptyOrSingleton+isListEmptyOrSingleton xs =+ IsEmptyOrSingleton $ case xs of+ [] -> True+ [_] -> True+ _ -> False+ -- See Note [Printing original names] in GHC.Types.Name.Ppr data QualifyName -- Given P:M.T = NameUnqual -- It's in scope unqualified as "T"@@ -248,17 +281,23 @@ neverQualifyPackages :: QueryQualifyPackage neverQualifyPackages _ = False -reallyAlwaysQualify, alwaysQualify, neverQualify :: PrintUnqualified+alwaysPrintPromTick :: QueryPromotionTick+alwaysPrintPromTick _ = True++reallyAlwaysQualify, alwaysQualify, neverQualify :: NamePprCtx reallyAlwaysQualify = QueryQualify reallyAlwaysQualifyNames alwaysQualifyModules alwaysQualifyPackages+ alwaysPrintPromTick alwaysQualify = QueryQualify alwaysQualifyNames alwaysQualifyModules alwaysQualifyPackages+ alwaysPrintPromTick neverQualify = QueryQualify neverQualifyNames neverQualifyModules neverQualifyPackages+ alwaysPrintPromTick defaultUserStyle :: PprStyle defaultUserStyle = mkUserStyle neverQualify AllTheWay@@ -267,31 +306,31 @@ -- Print without qualifiers to reduce verbosity, unless -dppr-debug defaultDumpStyle = PprDump neverQualify -mkDumpStyle :: PrintUnqualified -> PprStyle-mkDumpStyle print_unqual = PprDump print_unqual+mkDumpStyle :: NamePprCtx -> PprStyle+mkDumpStyle name_ppr_ctx = PprDump name_ppr_ctx --- | Default style for error messages, when we don't know PrintUnqualified+-- | Default style for error messages, when we don't know NamePprCtx -- It's a bit of a hack because it doesn't take into account what's in scope -- Only used for desugarer warnings, and typechecker errors in interface sigs defaultErrStyle :: PprStyle defaultErrStyle = mkErrStyle neverQualify -- | Style for printing error messages-mkErrStyle :: PrintUnqualified -> PprStyle-mkErrStyle unqual = mkUserStyle unqual DefaultDepth+mkErrStyle :: NamePprCtx -> PprStyle+mkErrStyle name_ppr_ctx = mkUserStyle name_ppr_ctx DefaultDepth cmdlineParserStyle :: PprStyle cmdlineParserStyle = mkUserStyle alwaysQualify AllTheWay -mkUserStyle :: PrintUnqualified -> Depth -> PprStyle-mkUserStyle unqual depth = PprUser unqual depth Uncoloured+mkUserStyle :: NamePprCtx -> Depth -> PprStyle+mkUserStyle name_ppr_ctx depth = PprUser name_ppr_ctx depth Uncoloured -withUserStyle :: PrintUnqualified -> Depth -> SDoc -> SDoc-withUserStyle unqual depth doc = withPprStyle (PprUser unqual depth Uncoloured) doc+withUserStyle :: NamePprCtx -> Depth -> SDoc -> SDoc+withUserStyle name_ppr_ctx depth doc = withPprStyle (PprUser name_ppr_ctx depth Uncoloured) doc -withErrStyle :: PrintUnqualified -> SDoc -> SDoc-withErrStyle unqual doc =- withPprStyle (mkErrStyle unqual) doc+withErrStyle :: NamePprCtx -> SDoc -> SDoc+withErrStyle name_ppr_ctx doc =+ withPprStyle (mkErrStyle name_ppr_ctx) doc setStyleColoured :: Bool -> PprStyle -> PprStyle setStyleColoured col style =@@ -375,6 +414,7 @@ , sdocSuppressUniques :: !Bool , sdocSuppressModulePrefixes :: !Bool , sdocSuppressStgExts :: !Bool+ , sdocSuppressStgReps :: !Bool , sdocErrorSpans :: !Bool , sdocStarIsType :: !Bool , sdocLinearTypes :: !Bool@@ -435,6 +475,7 @@ , sdocSuppressUniques = False , sdocSuppressModulePrefixes = False , sdocSuppressStgExts = False+ , sdocSuppressStgReps = True , sdocErrorSpans = False , sdocStarIsType = False , sdocLinearTypes = False@@ -530,10 +571,16 @@ qualPackage (PprDump q) m = queryQualifyPackage q m qualPackage _other _m = True -queryQual :: PprStyle -> PrintUnqualified+promTick :: PprStyle -> QueryPromotionTick+promTick (PprUser q _ _) occ = queryPromotionTick q occ+promTick (PprDump q) occ = queryPromotionTick q occ+promTick _ _ = True++queryQual :: PprStyle -> NamePprCtx queryQual s = QueryQualify (qualName s) (qualModule s) (qualPackage s)+ (promTick s) codeStyle :: PprStyle -> Bool codeStyle PprCode = True@@ -548,17 +595,17 @@ userStyle _other = False -- | Indicate if -dppr-debug mode is enabled-getPprDebug :: (Bool -> SDoc) -> SDoc+getPprDebug :: IsOutput doc => (Bool -> doc) -> doc {-# INLINE CONLIKE getPprDebug #-}-getPprDebug d = sdocWithContext $ \ctx -> d (sdocPprDebug ctx)+getPprDebug d = docWithContext $ \ctx -> d (sdocPprDebug ctx) -- | Says what to do with and without -dppr-debug-ifPprDebug :: SDoc -> SDoc -> SDoc+ifPprDebug :: IsOutput doc => doc -> doc -> doc {-# INLINE CONLIKE ifPprDebug #-} ifPprDebug yes no = getPprDebug $ \dbg -> if dbg then yes else no -- | Says what to do with -dppr-debug; without, return empty-whenPprDebug :: SDoc -> SDoc -- Empty for non-debug style+whenPprDebug :: IsOutput doc => doc -> doc -- Empty for non-debug style {-# INLINE CONLIKE whenPprDebug #-} whenPprDebug d = ifPprDebug d empty @@ -625,43 +672,26 @@ docToSDoc :: Doc -> SDoc docToSDoc d = SDoc (\_ -> d) -empty :: SDoc-char :: Char -> SDoc-text :: String -> SDoc-ftext :: FastString -> SDoc-ptext :: PtrString -> SDoc-ztext :: FastZString -> SDoc-int :: Int -> SDoc-integer :: Integer -> SDoc-word :: Integer -> SDoc-float :: Float -> SDoc-double :: Double -> SDoc-rational :: Rational -> SDoc--{-# INLINE CONLIKE empty #-}-empty = docToSDoc $ Pretty.empty-{-# INLINE CONLIKE char #-}-char c = docToSDoc $ Pretty.char c--{-# INLINE CONLIKE text #-} -- Inline so that the RULE Pretty.text will fire-text s = docToSDoc $ Pretty.text s+ptext :: PtrString -> SDoc+int :: IsLine doc => Int -> doc+integer :: IsLine doc => Integer -> doc+word :: Integer -> SDoc+float :: IsLine doc => Float -> doc+double :: IsLine doc => Double -> doc+rational :: Rational -> SDoc -{-# INLINE CONLIKE ftext #-}-ftext s = docToSDoc $ Pretty.ftext s {-# INLINE CONLIKE ptext #-} ptext s = docToSDoc $ Pretty.ptext s-{-# INLINE CONLIKE ztext #-}-ztext s = docToSDoc $ Pretty.ztext s {-# INLINE CONLIKE int #-}-int n = docToSDoc $ Pretty.int n+int n = text $ show n {-# INLINE CONLIKE integer #-}-integer n = docToSDoc $ Pretty.integer n+integer n = text $ show n {-# INLINE CONLIKE float #-}-float n = docToSDoc $ Pretty.float n+float n = text $ show n {-# INLINE CONLIKE double #-}-double n = docToSDoc $ Pretty.double n+double n = text $ show n {-# INLINE CONLIKE rational #-}-rational n = docToSDoc $ Pretty.rational n+rational n = text $ show n -- See Note [Print Hexadecimal Literals] in GHC.Utils.Ppr {-# INLINE CONLIKE word #-} word n = sdocOption sdocHexWordLiterals $ \case@@ -673,19 +703,19 @@ doublePrec :: Int -> Double -> SDoc doublePrec p n = text (showFFloat (Just p) n "") -parens, braces, brackets, quotes, quote,- doubleQuotes, angleBrackets :: SDoc -> SDoc+quotes, quote :: SDoc -> SDoc+parens, brackets, braces, doubleQuotes, angleBrackets :: IsLine doc => doc -> doc {-# INLINE CONLIKE parens #-}-parens d = SDoc $ Pretty.parens . runSDoc d+parens d = char '(' <> d <> char ')' {-# INLINE CONLIKE braces #-}-braces d = SDoc $ Pretty.braces . runSDoc d+braces d = char '{' <> d <> char '}' {-# INLINE CONLIKE brackets #-}-brackets d = SDoc $ Pretty.brackets . runSDoc d+brackets d = char '[' <> d <> char ']' {-# INLINE CONLIKE quote #-} quote d = SDoc $ Pretty.quote . runSDoc d {-# INLINE CONLIKE doubleQuotes #-}-doubleQuotes d = SDoc $ Pretty.doubleQuotes . runSDoc d+doubleQuotes d = char '"' <> d <> char '"' {-# INLINE CONLIKE angleBrackets #-} angleBrackets d = char '<' <> d <> char '>' @@ -707,35 +737,37 @@ _ | Just '\'' <- lastMaybe str -> pp_d | otherwise -> Pretty.quotes pp_d -semi, comma, colon, equals, space, dcolon, underscore, dot, vbar :: SDoc-arrow, lollipop, larrow, darrow, arrowt, larrowt, arrowtt, larrowtt, lambda :: SDoc-lparen, rparen, lbrack, rbrack, lbrace, rbrace, blankLine :: SDoc+blankLine, dcolon, arrow, lollipop, larrow, darrow, arrowt, larrowt, arrowtt,+ larrowtt, lambda :: SDoc blankLine = docToSDoc Pretty.emptyText-dcolon = unicodeSyntax (char '∷') (docToSDoc $ Pretty.text "::")-arrow = unicodeSyntax (char '→') (docToSDoc $ Pretty.text "->")-lollipop = unicodeSyntax (char '⊸') (docToSDoc $ Pretty.text "%1 ->")-larrow = unicodeSyntax (char '←') (docToSDoc $ Pretty.text "<-")-darrow = unicodeSyntax (char '⇒') (docToSDoc $ Pretty.text "=>")-arrowt = unicodeSyntax (char '⤚') (docToSDoc $ Pretty.text ">-")-larrowt = unicodeSyntax (char '⤙') (docToSDoc $ Pretty.text "-<")-arrowtt = unicodeSyntax (char '⤜') (docToSDoc $ Pretty.text ">>-")-larrowtt = unicodeSyntax (char '⤛') (docToSDoc $ Pretty.text "-<<")+dcolon = unicodeSyntax (char '∷') (text "::")+arrow = unicodeSyntax (char '→') (text "->")+lollipop = unicodeSyntax (char '⊸') (text "%1 ->")+larrow = unicodeSyntax (char '←') (text "<-")+darrow = unicodeSyntax (char '⇒') (text "=>")+arrowt = unicodeSyntax (char '⤚') (text ">-")+larrowt = unicodeSyntax (char '⤙') (text "-<")+arrowtt = unicodeSyntax (char '⤜') (text ">>-")+larrowtt = unicodeSyntax (char '⤛') (text "-<<") lambda = unicodeSyntax (char 'λ') (char '\\')-semi = docToSDoc $ Pretty.semi-comma = docToSDoc $ Pretty.comma-colon = docToSDoc $ Pretty.colon-equals = docToSDoc $ Pretty.equals-space = docToSDoc $ Pretty.space++semi, comma, colon, equals, space, underscore, dot, vbar :: IsLine doc => doc+lparen, rparen, lbrack, rbrack, lbrace, rbrace :: IsLine doc => doc+semi = char ';'+comma = char ','+colon = char ':'+equals = char '='+space = char ' ' underscore = char '_' dot = char '.' vbar = char '|'-lparen = docToSDoc $ Pretty.lparen-rparen = docToSDoc $ Pretty.rparen-lbrack = docToSDoc $ Pretty.lbrack-rbrack = docToSDoc $ Pretty.rbrack-lbrace = docToSDoc $ Pretty.lbrace-rbrace = docToSDoc $ Pretty.rbrace+lparen = char '('+rparen = char ')'+lbrack = char '['+rbrack = char ']'+lbrace = char '{'+rbrace = char '}' forAllLit :: SDoc forAllLit = unicodeSyntax (char '∀') (text "forall")@@ -758,38 +790,15 @@ nest :: Int -> SDoc -> SDoc -- ^ Indent 'SDoc' some specified amount-(<>) :: SDoc -> SDoc -> SDoc--- ^ Join two 'SDoc' together horizontally without a gap-(<+>) :: SDoc -> SDoc -> SDoc--- ^ Join two 'SDoc' together horizontally with a gap between them-($$) :: SDoc -> SDoc -> SDoc--- ^ Join two 'SDoc' together vertically; if there is--- no vertical overlap it "dovetails" the two onto one line ($+$) :: SDoc -> SDoc -> SDoc -- ^ Join two 'SDoc' together vertically {-# INLINE CONLIKE nest #-} nest n d = SDoc $ Pretty.nest n . runSDoc d-{-# INLINE CONLIKE (<>) #-}-(<>) d1 d2 = SDoc $ \ctx -> (Pretty.<>) (runSDoc d1 ctx) (runSDoc d2 ctx)-{-# INLINE CONLIKE (<+>) #-}-(<+>) d1 d2 = SDoc $ \ctx -> (Pretty.<+>) (runSDoc d1 ctx) (runSDoc d2 ctx)-{-# INLINE CONLIKE ($$) #-}-($$) d1 d2 = SDoc $ \ctx -> (Pretty.$$) (runSDoc d1 ctx) (runSDoc d2 ctx) {-# INLINE CONLIKE ($+$) #-} ($+$) d1 d2 = SDoc $ \ctx -> (Pretty.$+$) (runSDoc d1 ctx) (runSDoc d2 ctx) -hcat :: [SDoc] -> SDoc--- ^ Concatenate 'SDoc' horizontally-hsep :: [SDoc] -> SDoc--- ^ Concatenate 'SDoc' horizontally with a space between each one-vcat :: [SDoc] -> SDoc--- ^ Concatenate 'SDoc' vertically with dovetailing-sep :: [SDoc] -> SDoc--- ^ Separate: is either like 'hsep' or like 'vcat', depending on what fits cat :: [SDoc] -> SDoc--- ^ Concatenate: is either like 'hcat' or like 'vcat', depending on what fits-fsep :: [SDoc] -> SDoc -- ^ A paragraph-fill combinator. It's much like sep, only it -- keeps fitting things on one line until it can't fit any more. fcat :: [SDoc] -> SDoc@@ -799,18 +808,8 @@ -- Inline all those wrappers to help ensure we create lists of Doc, not of SDoc -- later applied to the same SDocContext. It helps the worker/wrapper -- transformation extracting only the required fields from the SDocContext.-{-# INLINE CONLIKE hcat #-}-hcat ds = SDoc $ \ctx -> Pretty.hcat [runSDoc d ctx | d <- ds]-{-# INLINE CONLIKE hsep #-}-hsep ds = SDoc $ \ctx -> Pretty.hsep [runSDoc d ctx | d <- ds]-{-# INLINE CONLIKE vcat #-}-vcat ds = SDoc $ \ctx -> Pretty.vcat [runSDoc d ctx | d <- ds]-{-# INLINE CONLIKE sep #-}-sep ds = SDoc $ \ctx -> Pretty.sep [runSDoc d ctx | d <- ds] {-# INLINE CONLIKE cat #-} cat ds = SDoc $ \ctx -> Pretty.cat [runSDoc d ctx | d <- ds]-{-# INLINE CONLIKE fsep #-}-fsep ds = SDoc $ \ctx -> Pretty.fsep [runSDoc d ctx | d <- ds] {-# INLINE CONLIKE fcat #-} fcat ds = SDoc $ \ctx -> Pretty.fcat [runSDoc d ctx | d <- ds] @@ -828,16 +827,17 @@ hangNotEmpty d1 n d2 = SDoc $ \ctx -> Pretty.hangNotEmpty (runSDoc d1 ctx) n (runSDoc d2 ctx) -punctuate :: SDoc -- ^ The punctuation- -> [SDoc] -- ^ The list that will have punctuation added between every adjacent pair of elements- -> [SDoc] -- ^ Punctuated list+punctuate :: IsLine doc+ => doc -- ^ The punctuation+ -> [doc] -- ^ The list that will have punctuation added between every adjacent pair of elements+ -> [doc] -- ^ Punctuated list punctuate _ [] = [] punctuate p (d:ds) = go d ds where go d [] = [d] go d (e:es) = (d <> p) : go e es -ppWhen, ppUnless :: Bool -> SDoc -> SDoc+ppWhen, ppUnless :: IsOutput doc => Bool -> doc -> doc {-# INLINE CONLIKE ppWhen #-} ppWhen True doc = doc ppWhen False _ = empty@@ -853,10 +853,9 @@ False -> empty {-# INLINE CONLIKE ppUnlessOption #-}-ppUnlessOption :: (SDocContext -> Bool) -> SDoc -> SDoc-ppUnlessOption f doc = sdocOption f $ \case- True -> empty- False -> doc+ppUnlessOption :: IsLine doc => (SDocContext -> Bool) -> doc -> doc+ppUnlessOption f doc = docWithContext $+ \ctx -> if f ctx then empty else doc -- | Apply the given colour\/style for the argument. --@@ -1028,12 +1027,14 @@ instance Outputable ModuleName where ppr = pprModuleName -pprModuleName :: ModuleName -> SDoc+pprModuleName :: IsLine doc => ModuleName -> doc pprModuleName (ModuleName nm) =- getPprStyle $ \ sty ->- if codeStyle sty+ docWithContext $ \ctx ->+ if codeStyle (sdocStyle ctx) then ztext (zEncodeFS nm) else ftext nm+{-# SPECIALIZE pprModuleName :: ModuleName -> SDoc #-}+{-# SPECIALIZE pprModuleName :: ModuleName -> HLine #-} -- see Note [SPECIALIZE to HDoc] ----------------------------------------------------------------------- -- The @OutputableP@ class@@ -1252,14 +1253,14 @@ primIntSuffix = char '#' primDoubleSuffix = text "##" primWordSuffix = text "##"-primInt8Suffix = text "#8"-primWord8Suffix = text "##8"-primInt16Suffix = text "#16"-primWord16Suffix = text "##16"-primInt32Suffix = text "#32"-primWord32Suffix = text "##32"-primInt64Suffix = text "#64"-primWord64Suffix = text "##64"+primInt8Suffix = text "#Int8"+primWord8Suffix = text "#Word8"+primInt16Suffix = text "#Int16"+primWord16Suffix = text "#Word16"+primInt32Suffix = text "#Int32"+primWord32Suffix = text "#Word32"+primInt64Suffix = text "#Int64"+primWord64Suffix = text "#Word64" -- | Special combinator for showing unboxed literals. pprPrimChar :: Char -> SDoc@@ -1301,12 +1302,14 @@ -- | Normalise, escape and render a string representing a path -- -- e.g. "c:\\whatever"-pprFilePathString :: FilePath -> SDoc+pprFilePathString :: IsLine doc => FilePath -> doc pprFilePathString path = doubleQuotes $ text (escape (normalise path)) where escape [] = [] escape ('\\':xs) = '\\':'\\':escape xs escape (x:xs) = x:escape xs+{-# SPECIALIZE pprFilePathString :: FilePath -> SDoc #-}+{-# SPECIALIZE pprFilePathString :: FilePath -> HLine #-} -- see Note [SPECIALIZE to HDoc] {- ************************************************************************@@ -1328,6 +1331,16 @@ -- bar-separated and finally packed into a paragraph. pprWithBars pp xs = fsep (intersperse vbar (map pp xs)) +-- Prefix the document with a space if it starts with a single quote.+-- See Note [Printing promoted type constructors] in GHC.Iface.Type+spaceIfSingleQuote :: SDoc -> SDoc+spaceIfSingleQuote (SDoc m) =+ SDoc $ \ctx ->+ let (mHead, d) = Pretty.docHead (m ctx)+ in if mHead == Just '\''+ then Pretty.space Pretty.<> d+ else d+ -- | Returns the separated concatenation of the pretty printed things. interppSP :: Outputable a => [a] -> SDoc interppSP xs = sep (map ppr xs)@@ -1485,3 +1498,352 @@ hasOrHave :: [a] -> SDoc hasOrHave [_] = text "has" hasOrHave _ = text "have"++{- Note [SDoc versus HDoc]+~~~~~~~~~~~~~~~~~~~~~~~~~~+The SDoc type is used pervasively throughout the compiler to represent pretty-+printable output. Almost all text written by GHC, from the Haskell types and+expressions included in error messages to debug dumps, is assembled using SDoc.+SDoc is nice because it handles multiline layout in a semi-automatic fashion,+enabling printed expressions to wrap to fit a given line width while correctly+indenting the following lines to preserve alignment.++SDoc’s niceties necessarily have some performance cost, but this is normally+okay, as printing output is rarely a performance bottleneck. However, one+notable exception to this is code generation: GHC must sometimes write+megabytes’ worth of generated assembly when compiling a single module, in which+case the overhead of SDoc has a significant cost (see #21853 for some numbers).+Moreover, generated assembly does not have the complex layout requirements of+pretty-printed Haskell code, so using SDoc does not buy us much, anyway.++Nevertheless, we do still want to be able to share some logic between writing+assembly and pretty-printing. For example, the logic for printing basic block+labels (GHC.Cmm.CLabel.pprCLabel) is nontrivial, so we want to have a single+implementation that can be used both when generating code and when generating+Cmm dumps. This is where HDoc comes in: HDoc provides a subset of the SDoc+interface, but it is implemented in a far more efficient way, writing directly+to a `Handle` (via a `BufHandle`) without building any intermediate structures.+We can then use typeclasses to parameterize functions like `pprCLabel` over the+printing implementation.++One might imagine this would result in one IsDoc typeclass, and two instances,+one for SDoc and one for HDoc. However, in fact, we need two *variants* of HDoc,+as described in Note [HLine versus HDoc], and this gives rise to a small+typeclass hierarchy consisting of IsOutput, IsLine, and IsDoc;+see Note [The outputable class hierarchy] for details.++Note [HLine versus HDoc]+~~~~~~~~~~~~~~~~~~~~~~~~+As described in Note [SDoc versus HDoc], HDoc does not support any of the layout+niceties of SDoc for efficiency. However, this presents a small problem if we+want to be compatible with the SDoc API, as expressions like++ text "foo" <+> (text "bar" $$ text "baz")++are expected to produce++ foo bar+ baz++which requires tracking line widths to know how far to indent the second line.+We can’t throw out vertical composition altogether, as we need to be able to+construct multiline HDocs, but we *can* restrict vertical composition to+concatenating whole lines at a time, as this is all that is necessary to+generate assembly in the code generator.++To implement this restriction, we provide two distinct types: HLine and HDoc.+As their names suggests, an HLine represents a single line of output, while an+HDoc represents a multiline document. Atoms formed from `char` and `text` begin+their lives as HLines, which can be horizontally (but not vertically) composed:++ char :: Char -> HLine+ text :: String -> HLine+ (<+>) :: HLine -> HLine -> HLine++Once a line has been fully assembled, it can be “locked up” into a single-line+HDoc via `line`, and HDocs can be vertically (but not horizontally) composed:++ line :: HLine -> HDoc+ ($$) :: HLine -> HLine -> HLine++Note that, at runtime, HLine and HDoc use exactly the same representation. This+distinction only exists in the type system to rule out the cases we don’t want+to have to handle.++Note [The outputable class hierarchy]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+As described in Note [SDoc versus HDoc], we want to be able to parameterize over+the choice of printing implementation when implementing common bits of printing+logic. However, as described in Note [HLine versus HDoc], we also want to+distinguish code that does single-line printing from code that does multi-line+printing. Therefore, code that is parameterized over the choice of printer must+respect this single- versus multi-line distinction. This naturally leads to two+typeclasses:++ class IsLine doc where+ char :: Char -> doc+ text :: String -> doc+ (<>) :: doc -> doc -> doc+ ...++ class IsLine (Line doc) => IsDoc doc where+ type Line doc = r | r -> doc+ line :: Line doc -> doc+ ($$) :: doc -> doc -> doc+ ...++These classes support the following instances:++ instance IsLine SDoc+ instance IsLine SDoc where+ type Line SDoc = SDoc++ instance IsLine HLine+ instance IsDoc HDoc where+ type Line HDoc = HLine++However, we run into a new problem: we provide many useful combinators on docs+that don’t care at all about the single-/multi-line distinction. For example,+ppWhen and ppUnless provide conditional logic, and docWithContext provides+access to the ambient SDocContext. Given the above classes, we would need two+variants of each of these combinators:++ ppWhenL :: IsLine doc => Bool -> doc -> doc+ ppWhenL c d = if c then d else emptyL++ ppWhenD :: IsDoc doc => Bool -> doc -> doc+ ppWhenD c d = if c then d else emptyD++This is a needlessly annoying distinction, so we introduce a common superclass,+IsOutput, that allows these combinators to be generic over both variants:++ class IsOutput doc where+ empty :: doc+ docWithContext :: (SDocContext -> doc) -> doc++ class IsOutput doc => IsLine doc+ class (IsOutput doc, IsLine (Line doc)) => IsDoc doc++In practice, IsOutput isn’t used explicitly very often, but it makes code that+uses the combinators derived from it significantly less noisy.++Note [SPECIALIZE to HDoc]+~~~~~~~~~~~~~~~~~~~~~~~~~+The IsLine and IsDoc classes are useful to share printing logic between code+that uses SDoc and code that uses HDoc, but we must take some care when doing+so. Much HDoc’s efficiency comes from GHC’s ability to optimize code that uses+it to eliminate unnecessary indirection, but the HDoc primitives must be inlined+before these opportunities can be exposed. Therefore, we want to explicitly+request that GHC generate HDoc (or HLine) specializations of any polymorphic+printing functions used by the code generator.++In code generators (CmmToAsm.{AArch64,PPC,X86}.Ppr) we add a specialize+pragma just to the entry point pprNatCmmDecl, to avoid cluttering+the entire module. Because specialization is transitive, this makes sure+that other functions in that module are specialized too.++Note [dualLine and dualDoc]+~~~~~~~~~~~~~~~~~~~~~~~~~~~+The IsLine and IsDoc classes provide the dualLine and dualDoc methods,+respectively, which have the following types:++ dualLine :: IsLine doc => SDoc -> HLine -> doc+ dualDoc :: IsDoc doc => SDoc -> HDoc -> doc++These are effectively a form of type-`case`, selecting between each of their two+arguments depending on the type they are instantiated at. They serve as a+“nuclear option” for code that is, for some reason or another, unreasonably+difficult to make completely equivalent under both printer implementations.++These operations should generally be avoided, as they can result in surprising+changes in behavior when the printer implementation is changed. However, in+certain cases, the alternative is even worse. For example, we use dualLine in+the implementation of pprUnitId, as the hack we use for printing unit ids+(see Note [Pretty-printing UnitId] in GHC.Unit) is difficult to adapt to HLine+and is not necessary for code paths that use it, anyway.++Use these operations wisely. -}++-- | Represents a single line of output that can be efficiently printed directly+-- to a 'System.IO.Handle' (actually a 'BufHandle').+-- See Note [SDoc versus HDoc] and Note [HLine versus HDoc] for more details.+newtype HLine = HLine' { runHLine :: SDocContext -> BufHandle -> IO () }++-- | Represents a (possibly empty) sequence of lines that can be efficiently+-- printed directly to a 'System.IO.Handle' (actually a 'BufHandle').+-- See Note [SDoc versus HDoc] and Note [HLine versus HDoc] for more details.+newtype HDoc = HDoc' { runHDoc :: SDocContext -> BufHandle -> IO () }++-- See Note [The one-shot state monad trick] in GHC.Utils.Monad+pattern HLine :: (SDocContext -> BufHandle -> IO ()) -> HLine+pattern HLine f <- HLine' f+ where HLine f = HLine' (oneShot (\ctx -> oneShot (\h -> f ctx h)))+{-# COMPLETE HLine #-}++-- See Note [The one-shot state monad trick] in GHC.Utils.Monad+pattern HDoc :: (SDocContext -> BufHandle -> IO ()) -> HDoc+pattern HDoc f <- HDoc' f+ where HDoc f = HDoc' (oneShot (\ctx -> oneShot (\h -> f ctx h)))+{-# COMPLETE HDoc #-}++bPutHDoc :: BufHandle -> SDocContext -> HDoc -> IO ()+bPutHDoc h ctx (HDoc f) = f ctx h++-- | A superclass for 'IsLine' and 'IsDoc' that provides an identity, 'empty',+-- as well as access to the shared 'SDocContext'.+--+-- See Note [The outputable class hierarchy] for more details.+class IsOutput doc where+ empty :: doc+ docWithContext :: (SDocContext -> doc) -> doc++-- | A class of types that represent a single logical line of text, with support+-- for horizontal composition.+--+-- See Note [HLine versus HDoc] and Note [The outputable class hierarchy] for+-- more details.+class IsOutput doc => IsLine doc where+ char :: Char -> doc+ text :: String -> doc+ ftext :: FastString -> doc+ ztext :: FastZString -> doc++ -- | Join two @doc@s together horizontally without a gap.+ (<>) :: doc -> doc -> doc+ -- | Join two @doc@s together horizontally with a gap between them.+ (<+>) :: doc -> doc -> doc+ -- | Separate: is either like 'hsep' or like 'vcat', depending on what fits.+ sep :: [doc] -> doc+ -- | A paragraph-fill combinator. It's much like 'sep', only it keeps fitting+ -- things on one line until it can't fit any more.+ fsep :: [doc] -> doc++ -- | Concatenate @doc@s horizontally without gaps.+ hcat :: [doc] -> doc+ hcat docs = foldr (<>) empty docs+ {-# INLINE CONLIKE hcat #-}++ -- | Concatenate @doc@s horizontally with a space between each one.+ hsep :: [doc] -> doc+ hsep docs = foldr (<+>) empty docs+ {-# INLINE CONLIKE hsep #-}++ -- | Prints as either the given 'SDoc' or the given 'HLine', depending on+ -- which type the result is instantiated to. This should generally be avoided;+ -- see Note [dualLine and dualDoc] for details.+ dualLine :: SDoc -> HLine -> doc+++-- | A class of types that represent a multiline document, with support for+-- vertical composition.+--+-- See Note [HLine versus HDoc] and Note [The outputable class hierarchy] for+-- more details.+class (IsOutput doc, IsLine (Line doc)) => IsDoc doc where+ type Line doc = r | r -> doc+ line :: Line doc -> doc++ -- | Join two @doc@s together vertically. If there is no vertical overlap it+ -- "dovetails" the two onto one line.+ ($$) :: doc -> doc -> doc++ lines_ :: [Line doc] -> doc+ lines_ = vcat . map line+ {-# INLINE CONLIKE lines_ #-}++ -- | Concatenate @doc@s vertically with dovetailing.+ vcat :: [doc] -> doc+ vcat ls = foldr ($$) empty ls+ {-# INLINE CONLIKE vcat #-}++ -- | Prints as either the given 'SDoc' or the given 'HDoc', depending on+ -- which type the result is instantiated to. This should generally be avoided;+ -- see Note [dualLine and dualDoc] for details.+ dualDoc :: SDoc -> HDoc -> doc++instance IsOutput SDoc where+ empty = docToSDoc $ Pretty.empty+ {-# INLINE CONLIKE empty #-}+ docWithContext = sdocWithContext+ {-# INLINE docWithContext #-}++instance IsLine SDoc where+ char c = docToSDoc $ Pretty.char c+ {-# INLINE CONLIKE char #-}+ text s = docToSDoc $ Pretty.text s+ {-# INLINE CONLIKE text #-} -- Inline so that the RULE Pretty.text will fire+ ftext s = docToSDoc $ Pretty.ftext s+ {-# INLINE CONLIKE ftext #-}+ ztext s = docToSDoc $ Pretty.ztext s+ {-# INLINE CONLIKE ztext #-}+ (<>) d1 d2 = SDoc $ \ctx -> (Pretty.<>) (runSDoc d1 ctx) (runSDoc d2 ctx)+ {-# INLINE CONLIKE (<>) #-}+ (<+>) d1 d2 = SDoc $ \ctx -> (Pretty.<+>) (runSDoc d1 ctx) (runSDoc d2 ctx)+ {-# INLINE CONLIKE (<+>) #-}+ hcat ds = SDoc $ \ctx -> Pretty.hcat [runSDoc d ctx | d <- ds]+ {-# INLINE CONLIKE hcat #-}+ hsep ds = SDoc $ \ctx -> Pretty.hsep [runSDoc d ctx | d <- ds]+ {-# INLINE CONLIKE hsep #-}+ sep ds = SDoc $ \ctx -> Pretty.sep [runSDoc d ctx | d <- ds]+ {-# INLINE CONLIKE sep #-}+ fsep ds = SDoc $ \ctx -> Pretty.fsep [runSDoc d ctx | d <- ds]+ {-# INLINE CONLIKE fsep #-}+ dualLine s _ = s+ {-# INLINE CONLIKE dualLine #-}++instance IsDoc SDoc where+ type Line SDoc = SDoc+ line = id+ {-# INLINE line #-}+ lines_ = vcat+ {-# INLINE lines_ #-}++ ($$) d1 d2 = SDoc $ \ctx -> (Pretty.$$) (runSDoc d1 ctx) (runSDoc d2 ctx)+ {-# INLINE CONLIKE ($$) #-}+ vcat ds = SDoc $ \ctx -> Pretty.vcat [runSDoc d ctx | d <- ds]+ {-# INLINE CONLIKE vcat #-}+ dualDoc s _ = s+ {-# INLINE CONLIKE dualDoc #-}++instance IsOutput HLine where+ empty = HLine (\_ _ -> pure ())+ {-# INLINE empty #-}+ docWithContext f = HLine $ \ctx h -> runHLine (f ctx) ctx h+ {-# INLINE CONLIKE docWithContext #-}++instance IsOutput HDoc where+ empty = HDoc (\_ _ -> pure ())+ {-# INLINE empty #-}+ docWithContext f = HDoc $ \ctx h -> runHDoc (f ctx) ctx h+ {-# INLINE CONLIKE docWithContext #-}++instance IsLine HLine where+ char c = HLine (\_ h -> bPutChar h c)+ {-# INLINE CONLIKE char #-}+ text str = HLine (\_ h -> bPutStr h str)+ {-# INLINE CONLIKE text #-}+ ftext fstr = HLine (\_ h -> bPutFS h fstr)+ {-# INLINE CONLIKE ftext #-}+ ztext fstr = HLine (\_ h -> bPutFZS h fstr)+ {-# INLINE CONLIKE ztext #-}++ HLine f <> HLine g = HLine (\ctx h -> f ctx h *> g ctx h)+ {-# INLINE CONLIKE (<>) #-}+ f <+> g = f <> char ' ' <> g+ {-# INLINE CONLIKE (<+>) #-}+ sep = hsep+ {-# INLINE sep #-}+ fsep = hsep+ {-# INLINE fsep #-}++ dualLine _ h = h+ {-# INLINE CONLIKE dualLine #-}++instance IsDoc HDoc where+ type Line HDoc = HLine+ line (HLine f) = HDoc (\ctx h -> f ctx h *> bPutChar h '\n')+ {-# INLINE CONLIKE line #-}+ HDoc f $$ HDoc g = HDoc (\ctx h -> f ctx h *> g ctx h)+ {-# INLINE CONLIKE ($$) #-}+ dualDoc _ h = h+ {-# INLINE CONLIKE dualDoc #-}
compiler/GHC/Utils/Panic.hs view
@@ -34,6 +34,7 @@ , assertPanic , assertPprPanic , assertPpr+ , assertPprMaybe , assertPprM , massertPpr @@ -52,7 +53,7 @@ ) where -import GHC.Prelude+import GHC.Prelude.Basic import GHC.Stack import GHC.Utils.Outputable@@ -315,6 +316,12 @@ if debugIsOn && not cond then withFrozenCallStack (assertPprPanic msg) else a++assertPprMaybe :: HasCallStack => Maybe SDoc -> a -> a+{-# INLINE assertPprMaybe #-}+assertPprMaybe mb_msg a+ | debugIsOn, Just msg <- mb_msg = withFrozenCallStack (assertPprPanic msg)+ | otherwise = a massertPpr :: (HasCallStack, Applicative m) => Bool -> SDoc -> m () {-# INLINE massertPpr #-}
compiler/GHC/Utils/Panic/Plain.hs view
@@ -28,7 +28,7 @@ import GHC.Utils.Constants import GHC.Utils.Exception as Exception import GHC.Stack-import GHC.Prelude+import GHC.Prelude.Basic import System.IO.Unsafe -- | This type is very similar to 'GHC.Utils.Panic.GhcException', but it omits@@ -101,11 +101,12 @@ throwPlainGhcException = Exception.throw -- | Panics and asserts.-panic, sorry, pgmError :: String -> a+panic, sorry, pgmError :: HasCallStack => String -> a panic x = unsafeDupablePerformIO $ do stack <- ccsToStrings =<< getCurrentCCS x+ let doc = unlines $ fmap (" "++) $ lines (prettyCallStack callStack) if null stack- then throwPlainGhcException (PlainPanic x)+ then throwPlainGhcException (PlainPanic (x ++ '\n' : doc)) else throwPlainGhcException (PlainPanic (x ++ '\n' : renderStack stack)) sorry x = throwPlainGhcException (PlainSorry x)
compiler/GHC/Utils/Ppr.hs view
@@ -79,7 +79,7 @@ lparen, rparen, lbrack, rbrack, lbrace, rbrace, -- ** Wrapping documents in delimiters- parens, brackets, braces, quotes, quote, doubleQuotes,+ parens, brackets, braces, quotes, squotes, quote, doubleQuotes, maybeParens, -- ** Combining documents@@ -93,6 +93,7 @@ -- * Predicates on documents isEmpty,+ docHead, -- * Rendering documents @@ -107,11 +108,12 @@ -- ** GHC-specific rendering printDoc, printDoc_,- bufLeftRender -- performance hack+ bufLeftRender, printLeftRender -- performance hack ) where -import GHC.Prelude hiding (error)+import GHC.Prelude.Basic hiding (error)+import Control.Applicative ((<|>)) import GHC.Utils.BufHandle import GHC.Data.FastString@@ -350,6 +352,37 @@ isEmpty Empty = True isEmpty _ = False +-- | Get the first character of a document. We also return a new document,+-- equivalent to the original one but faster to render. Use it to avoid work+-- duplication.+docHead :: Doc -> (Maybe Char, Doc)+docHead d = (headChar, rdoc)+ where+ rdoc = reduceDoc d+ headChar = go rdoc++ go :: RDoc -> Maybe Char+ go (Union p q) = go (first p q)+ go (Nest _ p) = go p+ go Empty = Nothing+ go (NilAbove _) = Just '\n'+ go (TextBeside td _ p) = go_td td <|> go p+ go NoDoc = error "docHead: NoDoc"+ go (Above {}) = error "docHead: Above"+ go (Beside {}) = error "docHead: Beside"++ go_td :: TextDetails -> Maybe Char+ go_td (Chr c) = Just c+ go_td (Str s) = go_str s+ go_td (PStr s) = go_str (unpackFS s) -- O(1) because unpackFS is lazy+ go_td (ZStr s) = go_str (zStringTakeN 1 s)+ go_td (LStr s) = go_str (unpackPtrStringTakeN 1 s)+ go_td (RStr n c) = if n > 0 then Just c else Nothing++ go_str :: String -> Maybe Char+ go_str [] = Nothing+ go_str (c:_) = Just c+ {- Q: What is the reason for negative indentation (i.e. argument to indent is < 0) ?@@ -429,10 +462,12 @@ parens :: Doc -> Doc -- ^ Wrap document in @(...)@ brackets :: Doc -> Doc -- ^ Wrap document in @[...]@ braces :: Doc -> Doc -- ^ Wrap document in @{...}@-quotes :: Doc -> Doc -- ^ Wrap document in @\'...\'@+quotes :: Doc -> Doc -- ^ Wrap document in @\`...\'@+squotes :: Doc -> Doc -- ^ Wrap document in @\'...\'@ quote :: Doc -> Doc doubleQuotes :: Doc -> Doc -- ^ Wrap document in @\"...\"@ quotes p = char '`' <> p <> char '\''+squotes p = char '\'' <> p <> char '\'' quote p = char '\'' <> p doubleQuotes p = char '"' <> p <> char '"' parens p = char '(' <> p <> char ')'@@ -1137,16 +1172,14 @@ bufLeftRender b doc = layLeft b (reduceDoc doc) layLeft :: BufHandle -> Doc -> IO ()-layLeft b _ | b `seq` False = undefined -- make it strict in b-layLeft _ NoDoc = error "layLeft: NoDoc"+layLeft !_ NoDoc = error "layLeft: NoDoc" layLeft b (Union p q) = layLeft b $! first p q layLeft b (Nest _ p) = layLeft b $! p layLeft b Empty = bPutChar b '\n'-layLeft b (NilAbove p) = p `seq` (bPutChar b '\n' >> layLeft b p)-layLeft b (TextBeside s _ p) = s `seq` (put b s >> layLeft b p)+layLeft b (NilAbove p) = bPutChar b '\n' >> layLeft b p+layLeft b (TextBeside s _ p) = put b s >> layLeft b p where- put b _ | b `seq` False = undefined- put b (Chr c) = bPutChar b c+ put !b (Chr c) = bPutChar b c put b (Str s) = bPutStr b s put b (PStr s) = bPutFS b s put b (ZStr s) = bPutFZS b s
compiler/GHC/Utils/Ppr/Colour.hs view
@@ -1,5 +1,5 @@ module GHC.Utils.Ppr.Colour where-import GHC.Prelude+import GHC.Prelude.Basic import Data.Maybe (fromMaybe) import GHC.Data.Bool
compiler/GHC/Utils/Trace.hs view
@@ -13,7 +13,18 @@ ) where -import GHC.Prelude+{- Note [Exporting pprTrace from GHC.Prelude]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+For our own sanity we want to export pprTrace from GHC.Prelude.+Since calls to traces should never be performance sensitive it's okay for these+to be source imports/exports. However we still need to make sure that all+transitive imports from Trace.hs-boot do not import GHC.Prelude.++To get there we import the basic GHC.Prelude.Basic prelude instead of GHC.Prelude+within the transitive dependencies of Trace.hs+-}++import GHC.Prelude.Basic import GHC.Utils.Outputable import GHC.Utils.Exception import GHC.Utils.Panic
compiler/Language/Haskell/Syntax/Decls.hs view
@@ -19,9 +19,6 @@ (c) The GRASP/@type@AQUA Project, Glasgow University, 1992-1998 -} --{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}- -- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.* -- | Abstract syntax of global declarations.
compiler/Language/Haskell/Syntax/Expr.hs view
@@ -10,8 +10,6 @@ {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] -- in module Language.Haskell.Syntax.Extension -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}- {- (c) The University of Glasgow 2006 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
compiler/Language/Haskell/Syntax/Type.hs view
@@ -906,8 +906,10 @@ data HsArrow pass = HsUnrestrictedArrow !(LHsUniToken "->" "→" pass) -- ^ a -> b or a → b+ | HsLinearArrow !(HsLinearArrowTokens pass) -- ^ a %1 -> b or a %1 → b, or a ⊸ b+ | HsExplicitMult !(LHsToken "%" pass) !(LHsType pass) !(LHsUniToken "->" "→" pass) -- ^ a %m -> b or a %m → b (very much including `a %Many -> b`! -- This is how the programmer wrote it). It is stored as an
compiler/MachRegs.h view
@@ -591,6 +591,41 @@ #define MAX_REAL_FLOAT_REG 6 #define MAX_REAL_DOUBLE_REG 6 +#elif defined(MACHREGS_wasm32)++#define REG_R1 1+#define REG_R2 2+#define REG_R3 3+#define REG_R4 4+#define REG_R5 5+#define REG_R6 6+#define REG_R7 7+#define REG_R8 8+#define REG_R9 9+#define REG_R10 10++#define REG_F1 11+#define REG_F2 12+#define REG_F3 13+#define REG_F4 14+#define REG_F5 15+#define REG_F6 16++#define REG_D1 17+#define REG_D2 18+#define REG_D3 19+#define REG_D4 20+#define REG_D5 21+#define REG_D6 22++#define REG_L1 23++#define REG_Sp 24+#define REG_SpLim 25+#define REG_Hp 26+#define REG_HpLim 27+#define REG_CCCS 28+ #else #error Cannot find platform to give register info for
compiler/ghc-llvm-version.h view
@@ -3,7 +3,7 @@ #define __GHC_LLVM_VERSION_H__ /* The maximum supported LLVM version number */-#define sUPPORTED_LLVM_VERSION_MAX (14)+#define sUPPORTED_LLVM_VERSION_MAX (15) /* The minimum supported LLVM version number */ #define sUPPORTED_LLVM_VERSION_MIN (10)
+ compiler/ghc.cabal view
@@ -0,0 +1,883 @@+Cabal-Version: 2.2+-- WARNING: ghc.cabal is automatically generated from ghc.cabal.in by+-- ./configure. Make sure you are editing ghc.cabal.in, not ghc.cabal.++Name: ghc+Version: 9.5+License: BSD-3-Clause+License-File: LICENSE+Author: The GHC Team+Maintainer: glasgow-haskell-users@haskell.org+Homepage: http://www.haskell.org/ghc/+Synopsis: The GHC API+Description:+ GHC's functionality can be useful for more things than just+ compiling Haskell programs. Important use cases are programs+ that analyse (and perhaps transform) Haskell code. Others+ include loading Haskell code dynamically in a GHCi-like manner.+ For this reason, a lot of GHC's functionality is made available+ through this package.+ .+ See <https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/compiler>+ for more information.+Category: Development+Build-Type: Custom++extra-source-files:+ GHC/Builtin/primops.txt.pp+ GHC/Builtin/bytearray-ops.txt.pp+ Unique.h+ CodeGen.Platform.h+ -- Shared with rts via hard-link at configure time. This is safer+ -- for Windows, where symlinks don't work out of the box, so we+ -- can't just commit some in git.+ Bytecodes.h+ ClosureTypes.h+ FunTypes.h+ MachRegs.h+ ghc-llvm-version.h+++custom-setup+ setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.9, directory, process, filepath++Flag internal-interpreter+ Description: Build with internal interpreter support.+ Default: False+ Manual: True++Flag terminfo+ Description: Build GHC with terminfo support on non-Windows platforms.+ Default: True+ Manual: True++Flag dynamic-system-linker+ Description: The system can load dynamic code. This is not the case for musl.+ Default: True+ Manual: True++-- hadrian disables this flag because the user may be building from a source+-- distribution where the parser has already been generated.+Flag build-tool-depends+ Description: Use build-tool-depends+ Default: True++Library+ Default-Language: Haskell2010+ Exposed: False+ Includes: Unique.h+ -- CodeGen.Platform.h -- invalid as C, skip+ -- shared with rts via symlink+ Bytecodes.h+ ClosureTypes.h+ FunTypes.h+ ghc-llvm-version.h++ if flag(build-tool-depends)+ build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants++ Build-Depends: base >= 4.11 && < 4.18,+ deepseq >= 1.4 && < 1.5,+ directory >= 1 && < 1.4,+ process >= 1 && < 1.7,+ bytestring >= 0.9 && < 0.12,+ binary == 0.8.*,+ time >= 1.4 && < 1.13,+ containers >= 0.6.2.1 && < 0.7,+ array >= 0.1 && < 0.6,+ filepath >= 1 && < 1.5,+ template-haskell == 2.19.*,+ hpc == 0.6.*,+ transformers == 0.5.*,+ exceptions == 0.10.*,+ stm,+ ghc-boot == 9.5,+ ghc-heap == 9.5,+ ghci == 9.5++ if os(windows)+ Build-Depends: Win32 >= 2.3 && < 2.14+ else+ if flag(terminfo)+ Build-Depends: terminfo == 0.4.*+ Build-Depends: unix >= 2.7 && < 2.9++ GHC-Options: -Wall+ -Wno-name-shadowing+ -Wnoncanonical-monad-instances+ -Wnoncanonical-monoid-instances++ if flag(internal-interpreter)+ CPP-Options: -DHAVE_INTERNAL_INTERPRETER++ -- if no dynamic system linker is available, don't try DLLs.+ if flag(dynamic-system-linker)+ CPP-Options: -DCAN_LOAD_DLL++ Other-Extensions:+ CPP+ DataKinds+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveTraversable+ DisambiguateRecordFields+ ExplicitForAll+ FlexibleContexts+ FlexibleInstances+ GADTs+ GeneralizedNewtypeDeriving+ MagicHash+ MultiParamTypeClasses+ NamedFieldPuns+ NondecreasingIndentation+ RankNTypes+ RecordWildCards+ StandaloneDeriving+ Trustworthy+ TupleSections+ TypeFamilies+ TypeSynonymInstances+ UnboxedTuples+ UndecidableInstances++ Include-Dirs: .++ -- We need to set the unit id to ghc (without a version number)+ -- as it's magic.+ GHC-Options: -this-unit-id ghc++ c-sources:+ cbits/cutils.c+ cbits/genSym.c+ cbits/keepCAFsForGHCi.c++ hs-source-dirs:+ .++ -- we use an explicit Prelude+ Default-Extensions:+ NoImplicitPrelude+ ,BangPatterns+ ,ScopedTypeVariables+ ,MonoLocalBinds+ ,TypeOperators++ Exposed-Modules:+ GHC+ GHC.Builtin.Names+ GHC.Builtin.Names.TH+ GHC.Builtin.PrimOps+ GHC.Builtin.PrimOps.Casts+ GHC.Builtin.PrimOps.Ids+ GHC.Builtin.Types+ GHC.Builtin.Types.Literals+ GHC.Builtin.Types.Prim+ GHC.Builtin.Uniques+ GHC.Builtin.Utils+ GHC.ByteCode.Asm+ GHC.ByteCode.InfoTable+ GHC.ByteCode.Instr+ GHC.ByteCode.Linker+ GHC.ByteCode.Types+ GHC.Cmm+ GHC.Cmm.BlockId+ GHC.Cmm.CallConv+ GHC.Cmm.CLabel+ GHC.Cmm.CommonBlockElim+ GHC.Cmm.Config+ GHC.Cmm.ContFlowOpt+ GHC.Cmm.Dataflow+ GHC.Cmm.Dataflow.Block+ GHC.Cmm.Dataflow.Collections+ GHC.Cmm.Dataflow.Graph+ GHC.Cmm.Dataflow.Label+ GHC.Cmm.DebugBlock+ GHC.Cmm.Expr+ GHC.Cmm.Graph+ GHC.Cmm.Info+ GHC.Cmm.Info.Build+ GHC.Cmm.InitFini+ GHC.Cmm.LayoutStack+ GHC.Cmm.Lexer+ GHC.Cmm.Lint+ GHC.Cmm.Liveness+ GHC.Cmm.MachOp+ GHC.Cmm.Node+ GHC.Cmm.Opt+ GHC.Cmm.Parser+ GHC.Cmm.Parser.Config+ GHC.Cmm.Parser.Monad+ GHC.Cmm.Pipeline+ GHC.Cmm.ProcPoint+ GHC.Cmm.Reg+ GHC.Cmm.Sink+ GHC.Cmm.Switch+ GHC.Cmm.Switch.Implement+ GHC.CmmToAsm+ GHC.Cmm.LRegSet+ GHC.CmmToAsm.AArch64+ GHC.CmmToAsm.AArch64.CodeGen+ GHC.CmmToAsm.AArch64.Cond+ GHC.CmmToAsm.AArch64.Instr+ GHC.CmmToAsm.AArch64.Ppr+ GHC.CmmToAsm.AArch64.RegInfo+ GHC.CmmToAsm.AArch64.Regs+ GHC.CmmToAsm.BlockLayout+ GHC.CmmToAsm.CFG+ GHC.CmmToAsm.CFG.Dominators+ GHC.CmmToAsm.CFG.Weight+ GHC.CmmToAsm.Config+ GHC.CmmToAsm.CPrim+ GHC.CmmToAsm.Dwarf+ GHC.CmmToAsm.Dwarf.Constants+ GHC.CmmToAsm.Dwarf.Types+ GHC.CmmToAsm.Format+ GHC.CmmToAsm.Instr+ GHC.CmmToAsm.Monad+ GHC.CmmToAsm.PIC+ GHC.CmmToAsm.PPC+ GHC.CmmToAsm.PPC.CodeGen+ GHC.CmmToAsm.PPC.Cond+ GHC.CmmToAsm.PPC.Instr+ GHC.CmmToAsm.PPC.Ppr+ GHC.CmmToAsm.PPC.RegInfo+ GHC.CmmToAsm.PPC.Regs+ GHC.CmmToAsm.Ppr+ GHC.CmmToAsm.Reg.Graph+ GHC.CmmToAsm.Reg.Graph.Base+ GHC.CmmToAsm.Reg.Graph.Coalesce+ GHC.CmmToAsm.Reg.Graph.Spill+ GHC.CmmToAsm.Reg.Graph.SpillClean+ GHC.CmmToAsm.Reg.Graph.SpillCost+ GHC.CmmToAsm.Reg.Graph.Stats+ GHC.CmmToAsm.Reg.Graph.TrivColorable+ GHC.CmmToAsm.Reg.Graph.X86+ GHC.CmmToAsm.Reg.Linear+ GHC.CmmToAsm.Reg.Linear.AArch64+ GHC.CmmToAsm.Reg.Linear.Base+ GHC.CmmToAsm.Reg.Linear.FreeRegs+ GHC.CmmToAsm.Reg.Linear.JoinToTargets+ GHC.CmmToAsm.Reg.Linear.PPC+ GHC.CmmToAsm.Reg.Linear.StackMap+ GHC.CmmToAsm.Reg.Linear.State+ GHC.CmmToAsm.Reg.Linear.Stats+ GHC.CmmToAsm.Reg.Linear.X86+ GHC.CmmToAsm.Reg.Linear.X86_64+ GHC.CmmToAsm.Reg.Liveness+ GHC.CmmToAsm.Reg.Target+ GHC.CmmToAsm.Reg.Utils+ GHC.CmmToAsm.Types+ GHC.CmmToAsm.Utils+ GHC.CmmToAsm.X86+ GHC.CmmToAsm.X86.CodeGen+ GHC.CmmToAsm.X86.Cond+ GHC.CmmToAsm.X86.Instr+ GHC.CmmToAsm.X86.Ppr+ GHC.CmmToAsm.X86.RegInfo+ GHC.CmmToAsm.X86.Regs+ GHC.CmmToC+ GHC.CmmToLlvm+ GHC.CmmToLlvm.Base+ GHC.CmmToLlvm.CodeGen+ GHC.CmmToLlvm.Config+ GHC.CmmToLlvm.Data+ GHC.CmmToLlvm.Mangler+ GHC.CmmToLlvm.Ppr+ GHC.CmmToLlvm.Regs+ GHC.Cmm.Dominators+ GHC.Cmm.Reducibility+ GHC.Cmm.Type+ GHC.Cmm.Utils+ GHC.Core+ GHC.Core.Class+ GHC.Core.Coercion+ GHC.Core.Coercion.Axiom+ GHC.Core.Coercion.Opt+ GHC.Core.ConLike+ GHC.Core.DataCon+ GHC.Core.FamInstEnv+ GHC.Core.FVs+ GHC.Core.InstEnv+ GHC.Core.Lint+ GHC.Core.Lint.Interactive+ GHC.Core.LateCC+ GHC.Core.Make+ GHC.Core.Map.Expr+ GHC.Core.Map.Type+ GHC.Core.Multiplicity+ GHC.Core.Opt.Arity+ GHC.Core.Opt.CallArity+ GHC.Core.Opt.CallerCC+ GHC.Core.Opt.ConstantFold+ GHC.Core.Opt.CprAnal+ GHC.Core.Opt.CSE+ GHC.Core.Opt.DmdAnal+ GHC.Core.Opt.Exitify+ GHC.Core.Opt.FloatIn+ GHC.Core.Opt.FloatOut+ GHC.Core.Opt.LiberateCase+ GHC.Core.Opt.Monad+ GHC.Core.Opt.OccurAnal+ GHC.Core.Opt.Pipeline+ GHC.Core.Opt.Pipeline.Types+ GHC.Core.Opt.SetLevels+ GHC.Core.Opt.Simplify+ GHC.Core.Opt.Simplify.Env+ GHC.Core.Opt.Simplify.Iteration+ GHC.Core.Opt.Simplify.Monad+ GHC.Core.Opt.Simplify.Utils+ GHC.Core.Opt.SpecConstr+ GHC.Core.Opt.Specialise+ GHC.Core.Opt.StaticArgs+ GHC.Core.Opt.Stats+ GHC.Core.Opt.WorkWrap+ GHC.Core.Opt.WorkWrap.Utils+ GHC.Core.PatSyn+ GHC.Core.Ppr+ GHC.Types.TyThing.Ppr+ GHC.Core.Predicate+ GHC.Core.Reduction+ GHC.Core.Rules+ GHC.Core.Rules.Config+ GHC.Core.Seq+ GHC.Core.SimpleOpt+ GHC.Core.Stats+ GHC.Core.Subst+ GHC.Core.Tidy+ GHC.CoreToIface+ GHC.CoreToStg+ GHC.CoreToStg.Prep+ GHC.Core.TyCo.FVs+ GHC.Core.TyCo.Compare+ GHC.Core.TyCon+ GHC.Core.TyCon.Env+ GHC.Core.TyCon.RecWalk+ GHC.Core.TyCon.Set+ GHC.Core.TyCo.Ppr+ GHC.Core.TyCo.Rep+ GHC.Core.TyCo.Subst+ GHC.Core.TyCo.Tidy+ GHC.Core.Type+ GHC.Core.RoughMap+ GHC.Core.Unfold+ GHC.Core.Unfold.Make+ GHC.Core.Unify+ GHC.Core.UsageEnv+ GHC.Core.Utils+ GHC.Data.Bag+ GHC.Data.Bitmap+ GHC.Data.Bool+ GHC.Data.BooleanFormula+ GHC.Data.EnumSet+ GHC.Data.FastMutInt+ GHC.Data.FastString+ GHC.Data.FastString.Env+ GHC.Data.FiniteMap+ GHC.Data.Graph.Base+ GHC.Data.Graph.Color+ GHC.Data.Graph.Collapse+ GHC.Data.Graph.Directed+ GHC.Data.Graph.Inductive.Graph+ GHC.Data.Graph.Inductive.PatriciaTree+ GHC.Data.Graph.Ops+ GHC.Data.Graph.Ppr+ GHC.Data.Graph.UnVar+ GHC.Data.IOEnv+ GHC.Data.List.Infinite+ GHC.Data.List.SetOps+ GHC.Data.Maybe+ GHC.Data.OrdList+ GHC.Data.Pair+ GHC.Data.SmallArray+ GHC.Data.Stream+ GHC.Data.Strict+ GHC.Data.StringBuffer+ GHC.Data.TrieMap+ GHC.Data.Unboxed+ GHC.Data.UnionFind+ GHC.Driver.Backend+ GHC.Driver.Backend.Internal+ GHC.Driver.Backpack+ GHC.Driver.Backpack.Syntax+ GHC.Driver.CmdLine+ GHC.Driver.CodeOutput+ GHC.Driver.Config+ GHC.Driver.Config.Cmm+ GHC.Driver.Config.Cmm.Parser+ GHC.Driver.Config.CmmToAsm+ GHC.Driver.Config.CmmToLlvm+ GHC.Driver.Config.Core.Lint+ GHC.Driver.Config.Core.Lint.Interactive+ GHC.Driver.Config.Core.Opt.Arity+ GHC.Driver.Config.Core.Opt.LiberateCase+ GHC.Driver.Config.Core.Opt.Simplify+ GHC.Driver.Config.Core.Opt.WorkWrap+ GHC.Driver.Config.Core.Rules+ GHC.Driver.Config.CoreToStg+ GHC.Driver.Config.CoreToStg.Prep+ GHC.Driver.Config.Diagnostic+ GHC.Driver.Config.Finder+ GHC.Driver.Config.HsToCore+ GHC.Driver.Config.HsToCore.Ticks+ GHC.Driver.Config.HsToCore.Usage+ GHC.Driver.Config.Logger+ GHC.Driver.Config.Parser+ GHC.Driver.Config.Stg.Debug+ GHC.Driver.Config.Stg.Lift+ GHC.Driver.Config.Stg.Pipeline+ GHC.Driver.Config.Stg.Ppr+ GHC.Driver.Config.StgToCmm+ GHC.Driver.Config.Tidy+ GHC.Driver.Config.StgToJS+ GHC.Driver.Env+ GHC.Driver.Env.KnotVars+ GHC.Driver.Env.Types+ GHC.Driver.Errors+ GHC.Driver.Errors.Ppr+ GHC.Driver.Errors.Types+ GHC.Driver.Flags+ GHC.Driver.GenerateCgIPEStub+ GHC.Driver.Hooks+ GHC.Driver.LlvmConfigCache+ GHC.Driver.Main+ GHC.Driver.Make+ GHC.Driver.MakeFile+ GHC.Driver.Monad+ GHC.Driver.Phases+ GHC.Driver.Pipeline+ GHC.Driver.Pipeline.Execute+ GHC.Driver.Pipeline.LogQueue+ GHC.Driver.Pipeline.Phases+ GHC.Driver.Pipeline.Monad+ GHC.Driver.Plugins+ GHC.Driver.Plugins.External+ GHC.Driver.Ppr+ GHC.Driver.Session+ GHC.Hs+ GHC.Hs.Binds+ GHC.Hs.Decls+ GHC.Hs.Doc+ GHC.Hs.DocString+ GHC.Hs.Dump+ GHC.Hs.Expr+ GHC.Hs.Syn.Type+ GHC.Hs.Extension+ GHC.Hs.ImpExp+ GHC.Hs.Instances+ GHC.Hs.Lit+ GHC.Hs.Pat+ GHC.Hs.Stats+ GHC.HsToCore+ GHC.HsToCore.Arrows+ GHC.HsToCore.Binds+ GHC.HsToCore.Breakpoints+ GHC.HsToCore.Coverage+ GHC.HsToCore.Docs+ GHC.HsToCore.Errors.Ppr+ GHC.HsToCore.Errors.Types+ GHC.HsToCore.Expr+ GHC.HsToCore.Foreign.C+ GHC.HsToCore.Foreign.Call+ GHC.HsToCore.Foreign.Decl+ GHC.HsToCore.Foreign.JavaScript+ GHC.HsToCore.Foreign.Prim+ GHC.HsToCore.Foreign.Utils+ GHC.HsToCore.GuardedRHSs+ GHC.HsToCore.ListComp+ GHC.HsToCore.Match+ GHC.HsToCore.Match.Constructor+ GHC.HsToCore.Match.Literal+ GHC.HsToCore.Monad+ GHC.HsToCore.Pmc+ GHC.HsToCore.Pmc.Check+ GHC.HsToCore.Pmc.Desugar+ GHC.HsToCore.Pmc.Ppr+ GHC.HsToCore.Pmc.Solver+ GHC.HsToCore.Pmc.Solver.Types+ GHC.HsToCore.Pmc.Types+ GHC.HsToCore.Pmc.Utils+ GHC.HsToCore.Quote+ GHC.HsToCore.Ticks+ GHC.HsToCore.Types+ GHC.HsToCore.Usage+ GHC.HsToCore.Utils+ GHC.Hs.Type+ GHC.Hs.Utils+ GHC.Iface.Binary+ GHC.Iface.Env+ GHC.Iface.Errors+ GHC.Iface.Ext.Ast+ GHC.Iface.Ext.Binary+ GHC.Iface.Ext.Debug+ GHC.Iface.Ext.Fields+ GHC.Iface.Ext.Types+ GHC.Iface.Ext.Utils+ GHC.Iface.Load+ GHC.Iface.Make+ GHC.Iface.Recomp+ GHC.Iface.Recomp.Binary+ GHC.Iface.Recomp.Flags+ GHC.Iface.Rename+ GHC.Iface.Syntax+ GHC.Iface.Tidy+ GHC.Iface.Tidy.StaticPtrTable+ GHC.IfaceToCore+ GHC.Iface.Type+ GHC.JS.Make+ GHC.JS.Ppr+ GHC.JS.Syntax+ GHC.JS.Transform+ GHC.Linker+ GHC.Linker.Dynamic+ GHC.Linker.ExtraObj+ GHC.Linker.Loader+ GHC.Linker.MacOS+ GHC.Linker.Static+ GHC.Linker.Static.Utils+ GHC.Linker.Types+ GHC.Linker.Unit+ GHC.Linker.Windows+ GHC.Llvm+ GHC.Llvm.MetaData+ GHC.Llvm.Ppr+ GHC.Llvm.Syntax+ GHC.Llvm.Types+ GHC.Parser+ GHC.Parser.Annotation+ GHC.Parser.CharClass+ GHC.Parser.Errors.Basic+ GHC.Parser.Errors.Ppr+ GHC.Parser.Errors.Types+ GHC.Parser.Header+ GHC.Parser.Lexer+ GHC.Parser.HaddockLex+ GHC.Parser.PostProcess+ GHC.Parser.PostProcess.Haddock+ GHC.Parser.Types+ GHC.Parser.Utils+ GHC.Platform+ GHC.Platform.ARM+ GHC.Platform.AArch64+ GHC.Platform.Constants+ GHC.Platform.NoRegs+ GHC.Platform.PPC+ GHC.Platform.Profile+ GHC.Platform.Reg+ GHC.Platform.Reg.Class+ GHC.Platform.Regs+ GHC.Platform.RISCV64+ GHC.Platform.S390X+ GHC.Platform.Wasm32+ GHC.Platform.Ways+ GHC.Platform.X86+ GHC.Platform.X86_64+ GHC.Plugins+ GHC.Prelude+ GHC.Prelude.Basic+ GHC.Rename.Bind+ GHC.Rename.Doc+ GHC.Rename.Env+ GHC.Rename.Expr+ GHC.Rename.Fixity+ GHC.Rename.HsType+ GHC.Rename.Module+ GHC.Rename.Names+ GHC.Rename.Pat+ GHC.Rename.Splice+ GHC.Rename.Unbound+ GHC.Rename.Utils+ GHC.Runtime.Context+ GHC.Runtime.Debugger+ GHC.Runtime.Eval+ GHC.Runtime.Eval.Types+ GHC.Runtime.Heap.Inspect+ GHC.Runtime.Heap.Layout+ GHC.Runtime.Interpreter+ GHC.Runtime.Interpreter.Types+ GHC.Runtime.Loader+ GHC.Settings+ GHC.Settings.Config+ GHC.Settings.Constants+ GHC.Settings.IO+ GHC.Stg.BcPrep+ GHC.Stg.CSE+ GHC.Stg.Debug+ GHC.Stg.FVs+ GHC.Stg.Lift+ GHC.Stg.Lift.Analysis+ GHC.Stg.Lift.Config+ GHC.Stg.Lift.Monad+ GHC.Stg.Lint+ GHC.Stg.InferTags+ GHC.Stg.InferTags.Rewrite+ GHC.Stg.InferTags.TagSig+ GHC.Stg.InferTags.Types+ GHC.Stg.Pipeline+ GHC.Stg.Stats+ GHC.Stg.Subst+ GHC.Stg.Syntax+ GHC.Stg.Utils+ GHC.StgToByteCode+ GHC.StgToCmm+ GHC.StgToCmm.ArgRep+ GHC.StgToCmm.Bind+ GHC.StgToCmm.CgUtils+ GHC.StgToCmm.Closure+ GHC.StgToCmm.Config+ GHC.StgToCmm.DataCon+ GHC.StgToCmm.Env+ GHC.StgToCmm.Expr+ GHC.StgToCmm.ExtCode+ GHC.StgToCmm.Foreign+ GHC.StgToCmm.Heap+ GHC.StgToCmm.Hpc+ GHC.StgToCmm.InfoTableProv+ GHC.StgToCmm.Layout+ GHC.StgToCmm.Lit+ GHC.StgToCmm.Monad+ GHC.StgToCmm.Prim+ GHC.StgToCmm.Prof+ GHC.StgToCmm.Sequel+ GHC.StgToCmm.TagCheck+ GHC.StgToCmm.Ticky+ GHC.StgToCmm.Types+ GHC.StgToCmm.Utils+ GHC.StgToJS+ GHC.StgToJS.Apply+ GHC.StgToJS.Arg+ GHC.StgToJS.Closure+ GHC.StgToJS.CodeGen+ GHC.StgToJS.CoreUtils+ GHC.StgToJS.DataCon+ GHC.StgToJS.Deps+ GHC.StgToJS.Expr+ GHC.StgToJS.ExprCtx+ GHC.StgToJS.FFI+ GHC.StgToJS.Heap+ GHC.StgToJS.Ids+ GHC.StgToJS.Literal+ GHC.StgToJS.Monad+ GHC.StgToJS.Object+ GHC.StgToJS.Prim+ GHC.StgToJS.Profiling+ GHC.StgToJS.Printer+ GHC.StgToJS.Regs+ GHC.StgToJS.Rts.Types+ GHC.StgToJS.Rts.Rts+ GHC.StgToJS.Sinker+ GHC.StgToJS.Stack+ GHC.StgToJS.StaticPtr+ GHC.StgToJS.StgUtils+ GHC.StgToJS.Symbols+ GHC.StgToJS.Types+ GHC.StgToJS.Utils+ GHC.StgToJS.Linker.Linker+ GHC.StgToJS.Linker.Types+ GHC.StgToJS.Linker.Utils+ GHC.Stg.Unarise+ GHC.SysTools+ GHC.SysTools.Ar+ GHC.SysTools.BaseDir+ GHC.SysTools.Cpp+ GHC.SysTools.Elf+ GHC.SysTools.Info+ GHC.SysTools.Process+ GHC.SysTools.Tasks+ GHC.SysTools.Terminal+ GHC.Tc.Deriv+ GHC.Tc.Deriv.Functor+ GHC.Tc.Deriv.Generate+ GHC.Tc.Deriv.Generics+ GHC.Tc.Deriv.Infer+ GHC.Tc.Deriv.Utils+ GHC.Tc.Errors+ GHC.Tc.Errors.Hole+ GHC.Tc.Errors.Hole.FitTypes+ GHC.Tc.Errors.Ppr+ GHC.Tc.Errors.Types+ GHC.Tc.Gen.Annotation+ GHC.Tc.Gen.App+ GHC.Tc.Gen.Arrow+ GHC.Tc.Gen.Bind+ GHC.Tc.Gen.Default+ GHC.Tc.Gen.Export+ GHC.Tc.Gen.Expr+ GHC.Tc.Gen.Foreign+ GHC.Tc.Gen.Head+ GHC.Tc.Gen.HsType+ GHC.Tc.Gen.Match+ GHC.Tc.Gen.Pat+ GHC.Tc.Gen.Rule+ GHC.Tc.Gen.Sig+ GHC.Tc.Gen.Splice+ GHC.Tc.Instance.Class+ GHC.Tc.Instance.Family+ GHC.Tc.Instance.FunDeps+ GHC.Tc.Instance.Typeable+ GHC.Tc.Module+ GHC.Tc.Plugin+ GHC.Tc.Solver+ GHC.Tc.Solver.Canonical+ GHC.Tc.Solver.Rewrite+ GHC.Tc.Solver.InertSet+ GHC.Tc.Solver.Interact+ GHC.Tc.Solver.Monad+ GHC.Tc.Solver.Types+ GHC.Tc.TyCl+ GHC.Tc.TyCl.Build+ GHC.Tc.TyCl.Class+ GHC.Tc.TyCl.Instance+ GHC.Tc.TyCl.PatSyn+ GHC.Tc.TyCl.Utils+ GHC.Tc.Types+ GHC.Tc.Types.Constraint+ GHC.Tc.Types.Evidence+ GHC.Tc.Types.EvTerm+ GHC.Tc.Types.Origin+ GHC.Tc.Types.Rank+ GHC.Tc.Utils.Backpack+ GHC.Tc.Utils.Concrete+ GHC.Tc.Utils.Env+ GHC.Tc.Utils.Instantiate+ GHC.Tc.Utils.Monad+ GHC.Tc.Utils.TcMType+ GHC.Tc.Utils.TcType+ GHC.Tc.Utils.Unify+ GHC.Tc.Utils.Zonk+ GHC.Tc.Validity+ GHC.ThToHs+ GHC.Types.Annotations+ GHC.Types.Avail+ GHC.Types.Basic+ GHC.Types.BreakInfo+ GHC.Types.CompleteMatch+ GHC.Types.CostCentre+ GHC.Types.CostCentre.State+ GHC.Types.Cpr+ GHC.Types.Demand+ GHC.Types.Error+ GHC.Types.Error.Codes+ GHC.Types.FieldLabel+ GHC.Types.Fixity+ GHC.Types.Fixity.Env+ GHC.Types.ForeignCall+ GHC.Types.ForeignStubs+ GHC.Types.Hint+ GHC.Types.Hint.Ppr+ GHC.Types.HpcInfo+ GHC.Types.Id+ GHC.Types.IPE+ GHC.Types.Id.Info+ GHC.Types.Id.Make+ GHC.Types.Literal+ GHC.Types.Meta+ GHC.Types.Name+ GHC.Types.Name.Cache+ GHC.Types.Name.Env+ GHC.Types.Name.Occurrence+ GHC.Types.Name.Reader+ GHC.Types.Name.Set+ GHC.Types.Name.Shape+ GHC.Types.Name.Ppr+ GHC.Types.PkgQual+ GHC.Types.ProfAuto+ GHC.Types.RepType+ GHC.Types.SafeHaskell+ GHC.Types.SourceError+ GHC.Types.SourceFile+ GHC.Types.SourceText+ GHC.Types.SrcLoc+ GHC.Types.Target+ GHC.Types.Tickish+ GHC.Types.TypeEnv+ GHC.Types.TyThing+ GHC.Types.Unique+ GHC.Types.Unique.DFM+ GHC.Types.Unique.DSet+ GHC.Types.Unique.FM+ GHC.Types.Unique.Map+ GHC.Types.Unique.MemoFun+ GHC.Types.Unique.SDFM+ GHC.Types.Unique.Set+ GHC.Types.Unique.Supply+ GHC.Types.Var+ GHC.Types.Var.Env+ GHC.Types.Var.Set+ GHC.Unit+ GHC.Unit.Env+ GHC.Unit.External+ GHC.Unit.Finder+ GHC.Unit.Finder.Types+ GHC.Unit.Home+ GHC.Unit.Home.ModInfo+ GHC.Unit.Info+ GHC.Unit.Module+ GHC.Unit.Module.Deps+ GHC.Unit.Module.Env+ GHC.Unit.Module.Graph+ GHC.Unit.Module.Imported+ GHC.Unit.Module.Location+ GHC.Unit.Module.ModDetails+ GHC.Unit.Module.ModGuts+ GHC.Unit.Module.ModIface+ GHC.Unit.Module.WholeCoreBindings+ GHC.Unit.Module.ModSummary+ GHC.Unit.Module.Status+ GHC.Unit.Module.Warnings+ GHC.Unit.Parser+ GHC.Unit.Ppr+ GHC.Unit.State+ GHC.Unit.Types+ GHC.Utils.Asm+ GHC.Utils.Binary+ GHC.Utils.Binary.Typeable+ GHC.Utils.BufHandle+ GHC.Utils.CliOption+ GHC.Utils.Constants+ GHC.Utils.Error+ GHC.Utils.Exception+ GHC.Utils.Fingerprint+ GHC.Utils.FV+ GHC.Utils.GlobalVars+ GHC.Utils.IO.Unsafe+ GHC.Utils.Json+ GHC.Utils.Lexeme+ GHC.Utils.Logger+ GHC.Utils.Misc+ GHC.Utils.Monad+ GHC.Utils.Monad.State.Strict+ GHC.Utils.Outputable+ GHC.Utils.Panic+ GHC.Utils.Panic.Plain+ GHC.Utils.Ppr+ GHC.Utils.Ppr.Colour+ GHC.Utils.TmpFs+ GHC.Utils.Trace+ GHC.Wasm.ControlFlow+ GHC.Wasm.ControlFlow.FromCmm+ GHC.CmmToAsm.Wasm+ GHC.CmmToAsm.Wasm.Asm+ GHC.CmmToAsm.Wasm.FromCmm+ GHC.CmmToAsm.Wasm.Types+ GHC.CmmToAsm.Wasm.Utils++ Language.Haskell.Syntax+ Language.Haskell.Syntax.Basic+ Language.Haskell.Syntax.Binds+ Language.Haskell.Syntax.Concrete+ Language.Haskell.Syntax.Decls+ Language.Haskell.Syntax.Expr+ Language.Haskell.Syntax.Extension+ Language.Haskell.Syntax.ImpExp+ Language.Haskell.Syntax.Lit+ Language.Haskell.Syntax.Module.Name+ Language.Haskell.Syntax.Pat+ Language.Haskell.Syntax.Type++ autogen-modules: GHC.Platform.Constants+ GHC.Settings.Config++ reexported-modules:+ GHC.Platform.ArchOS+ , GHC.Platform.Host
ghc-lib-parser.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.0 build-type: Simple name: ghc-lib-parser-version: 0.20221101+version: 0.20221201 license: BSD3 license-file: LICENSE category: Development@@ -17,6 +17,13 @@ llvm-targets llvm-passes extra-source-files:+ ghc/ghc-bin.cabal+ libraries/template-haskell/template-haskell.cabal+ libraries/ghc-heap/ghc-heap.cabal+ libraries/ghc-boot-th/ghc-boot-th.cabal+ libraries/ghc-boot/ghc-boot.cabal+ libraries/ghci/ghci.cabal+ compiler/ghc.cabal ghc-lib/stage0/rts/build/include/ghcautoconf.h ghc-lib/stage0/rts/build/include/ghcplatform.h ghc-lib/stage0/rts/build/include/GhclibDerivedConstants.h@@ -208,6 +215,7 @@ GHC.Core.Stats GHC.Core.Subst GHC.Core.Tidy+ GHC.Core.TyCo.Compare GHC.Core.TyCo.FVs GHC.Core.TyCo.Ppr GHC.Core.TyCo.Rep@@ -234,6 +242,7 @@ GHC.Data.Graph.Directed GHC.Data.Graph.UnVar GHC.Data.IOEnv+ GHC.Data.List.Infinite GHC.Data.List.SetOps GHC.Data.Maybe GHC.Data.OrdList@@ -342,10 +351,12 @@ GHC.Platform.Reg.Class GHC.Platform.Regs GHC.Platform.S390X+ GHC.Platform.Wasm32 GHC.Platform.Ways GHC.Platform.X86 GHC.Platform.X86_64 GHC.Prelude+ GHC.Prelude.Basic GHC.Runtime.Context GHC.Runtime.Eval.Types GHC.Runtime.Heap.Layout
ghc-lib/stage0/compiler/build/GHC/Settings/Config.hs view
@@ -7,7 +7,7 @@ , cStage ) where -import GHC.Prelude+import GHC.Prelude.Basic import GHC.Version @@ -21,7 +21,7 @@ cProjectName = "The Glorious Glasgow Haskell Compilation System" cBooterVersion :: String-cBooterVersion = "9.0.2"+cBooterVersion = "9.2.2" cStage :: String cStage = show (1 :: Int)
ghc-lib/stage0/lib/settings view
@@ -44,7 +44,7 @@ ,("Use inplace MinGW toolchain", "NO") ,("Use interpreter", "YES") ,("Support SMP", "YES")-,("RTS ways", "v thr")+,("RTS ways", "v") ,("Tables next to code", "YES") ,("Leading underscore", "YES") ,("Use LibFFI", "NO")
ghc-lib/stage0/libraries/ghc-boot/build/GHC/Version.hs view
@@ -3,19 +3,19 @@ import Prelude -- See Note [Why do we import Prelude here?] cProjectGitCommitId :: String-cProjectGitCommitId = "4521f6498d09f48a775a028efdd763c874da3451"+cProjectGitCommitId = "b4cfa8e235715d8c73b2ba0ba05ed8ef92629218" cProjectVersion :: String-cProjectVersion = "9.5.20221101"+cProjectVersion = "9.5.20221130" cProjectVersionInt :: String cProjectVersionInt = "905" cProjectPatchLevel :: String-cProjectPatchLevel = "20221101"+cProjectPatchLevel = "20221130" cProjectPatchLevel1 :: String-cProjectPatchLevel1 = "20221101"+cProjectPatchLevel1 = "20221130" cProjectPatchLevel2 :: String cProjectPatchLevel2 = "0"
ghc-lib/stage0/rts/build/include/ghcautoconf.h view
@@ -132,6 +132,10 @@ don't. */ /* #undef HAVE_DECL_MAP_NORESERVE */ +/* Define to 1 if you have the declaration of `program_invocation_short_name',+ and to 0 if you don't. */+#define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 0+ /* Define to 1 if you have the <dirent.h> header file. */ #define HAVE_DIRENT_H 1 @@ -165,12 +169,18 @@ /* Define to 1 if you have the `GetModuleFileName' function. */ /* #undef HAVE_GETMODULEFILENAME */ +/* Define to 1 if you have the `getpid' function. */+#define HAVE_GETPID 1+ /* Define to 1 if you have the `getrusage' function. */ #define HAVE_GETRUSAGE 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 +/* Define to 1 if you have the `getuid' function. */+#define HAVE_GETUID 1+ /* Define to 1 if you have the <grp.h> header file. */ #define HAVE_GRP_H 1 @@ -249,6 +259,9 @@ /* Define to 1 if you have the <pwd.h> header file. */ #define HAVE_PWD_H 1 +/* Define to 1 if you have the `raise' function. */+#define HAVE_RAISE 1+ /* Define to 1 if you have the `sched_getaffinity' function. */ /* #undef HAVE_SCHED_GETAFFINITY */ @@ -622,7 +635,7 @@ /* #undef pid_t */ /* The maximum supported LLVM version number */-#define sUPPORTED_LLVM_VERSION_MAX (14)+#define sUPPORTED_LLVM_VERSION_MAX (15) /* The minimum supported LLVM version number */ #define sUPPORTED_LLVM_VERSION_MIN (10)
+ ghc/ghc-bin.cabal view
@@ -0,0 +1,98 @@+-- WARNING: ghc-bin.cabal is automatically generated from ghc-bin.cabal.in by+-- ./configure. Make sure you are editing ghc-bin.cabal.in, not ghc-bin.cabal.++Name: ghc-bin+Version: 9.5.20221130+Copyright: XXX+-- License: XXX+-- License-File: XXX+Author: XXX+Maintainer: glasgow-haskell-users@haskell.org+Homepage: http://www.haskell.org/ghc/+Synopsis: The Glorious Glasgow Haskell Compiler.+Description:+ This package contains the @ghc@ executable, the user facing front-end+ to the Glasgow Haskell Compiler.+Category: Development+Build-Type: Simple+Cabal-Version: >=1.10++Flag internal-interpreter+ Description: Build with internal interpreter support.+ Default: False+ Manual: True++Flag threaded+ Description: Link the ghc executable against the threaded RTS+ Default: True+ Manual: True++Executable ghc+ Default-Language: Haskell2010++ Main-Is: Main.hs+ Build-Depends: base >= 4 && < 5,+ array >= 0.1 && < 0.6,+ bytestring >= 0.9 && < 0.12,+ directory >= 1 && < 1.4,+ process >= 1 && < 1.7,+ filepath >= 1 && < 1.5,+ containers >= 0.5 && < 0.7,+ transformers == 0.5.*,+ ghc-boot == 9.5,+ ghc == 9.5++ if os(windows)+ Build-Depends: Win32 >= 2.3 && < 2.14+ else+ Build-Depends: unix >= 2.7 && < 2.9++ GHC-Options: -Wall+ -Wnoncanonical-monad-instances+ -Wnoncanonical-monoid-instances+ -rtsopts=all+ "-with-rtsopts=-K512M -H -I5 -T"++ if flag(internal-interpreter)+ -- NB: this is never built by the bootstrapping GHC+libraries+ Build-depends:+ deepseq == 1.4.*,+ ghc-prim >= 0.5.0 && < 0.11,+ ghci == 9.5,+ haskeline == 0.8.*,+ exceptions == 0.10.*,+ time >= 1.8 && < 1.13+ CPP-Options: -DHAVE_INTERNAL_INTERPRETER+ Other-Modules:+ GHCi.Leak+ GHCi.UI+ GHCi.UI.Info+ GHCi.UI.Monad+ GHCi.UI.Tags+ GHCi.Util+ Other-Extensions:+ FlexibleInstances+ LambdaCase+ MagicHash+ MultiWayIf+ OverloadedStrings+ RankNTypes+ RecordWildCards+ ScopedTypeVariables+ UnboxedTuples+ ViewPatterns++ if flag(threaded)+ ghc-options: -threaded++ Other-Extensions:+ CPP+ NondecreasingIndentation+ TupleSections++ -- This should match the default-extensions used in 'ghc.cabal'. This way,+ -- GHCi can be used to load it all at once.+ Default-Extensions:+ NoImplicitPrelude+ , ScopedTypeVariables+ , BangPatterns
libraries/ghc-boot-th/GHC/ForeignSrcLang/Type.hs view
@@ -13,5 +13,6 @@ | LangObjc -- ^ Objective C | LangObjcxx -- ^ Objective C++ | LangAsm -- ^ Assembly language (.s)+ | LangJs -- ^ JavaScript | RawObject -- ^ Object (.o) deriving (Eq, Show, Generic)
+ libraries/ghc-boot-th/ghc-boot-th.cabal view
@@ -0,0 +1,39 @@+-- WARNING: ghc-boot-th.cabal is automatically generated from+-- ghc-boot-th.cabal.in by ../../configure. Make sure you are editing+-- ghc-boot-th.cabal.in, not ghc-boot-th.cabal.++name: ghc-boot-th+version: 9.5+license: BSD3+license-file: LICENSE+category: GHC+maintainer: ghc-devs@haskell.org+bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new+synopsis: Shared functionality between GHC and the @template-haskell@+ library+description: This library contains various bits shared between the @ghc@ and+ @template-haskell@ libraries.+ .+ This package exists to ensure that @template-haskell@ has a+ minimal set of transitive dependencies, since it is intended to+ be depended upon by user code.+cabal-version: >=1.10+build-type: Simple+extra-source-files: changelog.md++source-repository head+ type: git+ location: https://gitlab.haskell.org/ghc/ghc.git+ subdir: libraries/ghc-boot-th++Library+ default-language: Haskell2010+ other-extensions: DeriveGeneric+ default-extensions: NoImplicitPrelude++ exposed-modules:+ GHC.LanguageExtensions.Type+ GHC.ForeignSrcLang.Type+ GHC.Lexeme++ build-depends: base >= 4.7 && < 4.18
libraries/ghc-boot/GHC/BaseDir.hs view
@@ -17,6 +17,7 @@ import Prelude -- See Note [Why do we import Prelude here?] import Data.List (stripPrefix)+import Data.Maybe (listToMaybe) import System.FilePath -- Windows@@ -37,7 +38,7 @@ expandPathVar :: String -> FilePath -> String -> String expandPathVar var value str | Just str' <- stripPrefix ('$':var) str- , null str' || isPathSeparator (head str')+ , maybe True isPathSeparator (listToMaybe str') = value ++ expandPathVar var value str' expandPathVar var value (x:xs) = x : expandPathVar var value xs expandPathVar _ _ [] = []
libraries/ghc-boot/GHC/Data/ShortText.hs view
@@ -29,6 +29,7 @@ -- * ShortText ShortText(..), -- ** Conversion to and from String+ singleton, pack, unpack, -- ** Operations@@ -77,6 +78,10 @@ pack :: String -> ShortText pack s = ShortText $ utf8EncodeShortByteString s +-- | Create a singleton+singleton :: Char -> ShortText+singleton s = pack [s]+ -- | /O(n)/ Convert a 'ShortText' into a 'String'. unpack :: ShortText -> String unpack st = utf8DecodeShortByteString $ contents st@@ -101,8 +106,10 @@ -- non-printable characters. head :: ShortText -> Char head st- | SBS.null $ contents st = error "head: Empty ShortText"- | otherwise = Prelude.head $ unpack st+ | hd:_ <- unpack st+ = hd+ | otherwise+ = error "head: Empty ShortText" -- | /O(n)/ The 'stripPrefix' function takes two 'ShortText's and returns 'Just' the remainder of -- the second iff the first is its prefix, and otherwise Nothing.
libraries/ghc-boot/GHC/Platform/ArchOS.hs view
@@ -45,6 +45,7 @@ | ArchMipsel | ArchRISCV64 | ArchJavaScript+ | ArchWasm32 deriving (Read, Show, Eq, Ord) -- | ARM Instruction Set Architecture@@ -95,6 +96,7 @@ | OSQNXNTO | OSAIX | OSHurd+ | OSWasi deriving (Read, Show, Eq, Ord) @@ -133,6 +135,7 @@ ArchMipsel -> "mipsel" ArchRISCV64 -> "riscv64" ArchJavaScript -> "js"+ ArchWasm32 -> "wasm32" -- | See Note [Platform Syntax]. stringEncodeOS :: OS -> String@@ -151,3 +154,4 @@ OSQNXNTO -> "nto-qnx" OSAIX -> "aix" OSHurd -> "hurd"+ OSWasi -> "wasi"
libraries/ghc-boot/GHC/Utils/Encoding.hs view
@@ -145,8 +145,10 @@ encode_ch c = encode_as_unicode_char c encode_as_unicode_char :: Char -> EncodedString-encode_as_unicode_char c = 'z' : if isDigit (head hex_str) then hex_str- else '0':hex_str+encode_as_unicode_char c = 'z' : case hex_str of+ hd : _+ | isDigit hd -> hex_str+ _ -> '0' : hex_str where hex_str = showHex (ord c) "U" -- ToDo: we could improve the encoding here in various ways. -- eg. strings of unicode characters come out as 'z1234Uz5678U', we
+ libraries/ghc-boot/ghc-boot.cabal view
@@ -0,0 +1,83 @@+cabal-version: 3.0++-- WARNING: ghc-boot.cabal is automatically generated from ghc-boot.cabal.in by+-- ../../configure. Make sure you are editing ghc-boot.cabal.in, not+-- ghc-boot.cabal.++name: ghc-boot+version: 9.5+license: BSD-3-Clause+license-file: LICENSE+category: GHC+maintainer: ghc-devs@haskell.org+bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new+synopsis: Shared functionality between GHC and its boot libraries+description: This library is shared between GHC, ghc-pkg, and other boot+ libraries.+ .+ A note about "GHC.Unit.Database": it only deals with the subset of+ the package database that the compiler cares about: modules+ paths etc and not package metadata like description, authors+ etc. It is thus not a library interface to ghc-pkg and is *not*+ suitable for modifying GHC package databases.+ .+ The package database format and this library are constructed in+ such a way that while ghc-pkg depends on Cabal, the GHC library+ and program do not have to depend on Cabal.+build-type: Custom+extra-source-files: changelog.md++custom-setup+ setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.9, directory, filepath++source-repository head+ type: git+ location: https://gitlab.haskell.org/ghc/ghc.git+ subdir: libraries/ghc-boot++Library+ default-language: Haskell2010+ other-extensions: DeriveGeneric, RankNTypes, ScopedTypeVariables+ default-extensions: NoImplicitPrelude++ exposed-modules:+ GHC.BaseDir+ GHC.Data.ShortText+ GHC.Data.SizedSeq+ GHC.Utils.Encoding+ GHC.Utils.Encoding.UTF8+ GHC.LanguageExtensions+ GHC.Unit.Database+ GHC.Serialized+ GHC.ForeignSrcLang+ GHC.HandleEncoding+ GHC.Platform.ArchOS+ GHC.Platform.Host+ GHC.Settings.Utils+ GHC.UniqueSubdir+ GHC.Version++ -- reexport modules from ghc-boot-th so that packages don't have to import+ -- both ghc-boot and ghc-boot-th. It makes the dependency graph easier to+ -- understand and to refactor.+ reexported-modules:+ GHC.LanguageExtensions.Type+ , GHC.ForeignSrcLang.Type+ , GHC.Lexeme++ -- but done by Hadrian+ autogen-modules:+ GHC.Version+ GHC.Platform.Host++ build-depends: base >= 4.7 && < 4.18,+ binary == 0.8.*,+ bytestring >= 0.10 && < 0.12,+ containers >= 0.5 && < 0.7,+ directory >= 1.2 && < 1.4,+ filepath >= 1.3 && < 1.5,+ deepseq >= 1.4 && < 1.5,+ ghc-boot-th == 9.5+ if !os(windows)+ build-depends:+ unix >= 2.7 && < 2.9
+ libraries/ghc-heap/ghc-heap.cabal view
@@ -0,0 +1,50 @@+cabal-version: 3.0+name: ghc-heap+version: 9.5+license: BSD-3-Clause+license-file: LICENSE+maintainer: libraries@haskell.org+bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new+synopsis: Functions for walking GHC's heap+category: GHC+description:+ This package provides functions for walking the GHC heap data structures+ and retrieving information about those data structures.++build-type: Simple+tested-with: GHC==7.11++source-repository head+ type: git+ location: https://gitlab.haskell.org/ghc/ghc.git+ subdir: libraries/ghc-heap++library+ default-language: Haskell2010++ build-depends: base >= 4.9.0 && < 5.0+ , ghc-prim > 0.2 && < 0.11+ , rts == 1.0.*+ , containers >= 0.6.2.1 && < 0.7++ ghc-options: -Wall+ if !os(ghcjs)+ cmm-sources: cbits/HeapPrim.cmm++ default-extensions: NoImplicitPrelude++ exposed-modules: GHC.Exts.Heap+ GHC.Exts.Heap.Closures+ GHC.Exts.Heap.ClosureTypes+ GHC.Exts.Heap.Constants+ GHC.Exts.Heap.InfoTable+ GHC.Exts.Heap.InfoTable.Types+ GHC.Exts.Heap.InfoTableProf+ GHC.Exts.Heap.Utils+ GHC.Exts.Heap.FFIClosures+ GHC.Exts.Heap.FFIClosures_ProfilingDisabled+ GHC.Exts.Heap.FFIClosures_ProfilingEnabled+ GHC.Exts.Heap.ProfInfo.Types+ GHC.Exts.Heap.ProfInfo.PeekProfInfo+ GHC.Exts.Heap.ProfInfo.PeekProfInfo_ProfilingDisabled+ GHC.Exts.Heap.ProfInfo.PeekProfInfo_ProfilingEnabled
libraries/ghci/GHCi/FFI.hsc view
@@ -6,7 +6,24 @@ -- ----------------------------------------------------------------------------- +{- Note [FFI for the JS-Backend]+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++ The JS-backend does not use GHC's native rts, as such you might think that it+ doesn't require ghci. However, that is not true, because we need ghci in+ order to interoperate with iserv even if we do not use any of the FFI stuff+ in this file. So obviously we do not require libffi, but we still need to be+ able to build ghci in order for the JS-Backend to supply its own iserv+ interop solution. Thus we bite the bullet and wrap all the unneeded bits in a+ CPP conditional compilation blocks that detect the JS-backend. A necessary+ evil to be sure; notice that the only symbols remaining the JS_HOST_ARCH case+ are those that are explicitly exported by this module and set to error if+ they are every used.+-}++#if !defined(js_HOST_ARCH) #include <ffi.h>+#endif {-# LANGUAGE CPP, DeriveGeneric, DeriveAnyClass #-} module GHCi.FFI@@ -18,11 +35,13 @@ ) where import Prelude -- See note [Why do we import Prelude here?]+#if !defined(js_HOST_ARCH) import Control.Exception+import Foreign.C+#endif import Data.Binary import GHC.Generics import Foreign-import Foreign.C data FFIType = FFIVoid@@ -51,6 +70,7 @@ -> FFIType -- result type -> IO (Ptr C_ffi_cif) -- token for making calls (must be freed by caller) +#if !defined(js_HOST_ARCH) prepForeignCall cconv arg_types result_type = do let n_args = length arg_types arg_arr <- mallocArray n_args@@ -66,12 +86,27 @@ " res ty: ", show result_type, ")" ] else return (castPtr cif)+#else+prepForeignCall _ _ _ =+ error "GHCi.FFI.prepForeignCall: Called with JS_HOST_ARCH! Perhaps you need to run configure?"+#endif + freeForeignCallInfo :: Ptr C_ffi_cif -> IO ()+#if !defined(js_HOST_ARCH) freeForeignCallInfo p = do free ((#ptr ffi_cif, arg_types) p) free p+#else+freeForeignCallInfo _ =+ error "GHCi.FFI.freeForeignCallInfo: Called with JS_HOST_ARCH! Perhaps you need to run configure?"+#endif +data C_ffi_cif++#if !defined(js_HOST_ARCH)+data C_ffi_type+ strError :: C_ffi_status -> String strError r | r == fFI_BAD_ABI@@ -103,9 +138,6 @@ ffiType FFIUInt32 = ffi_type_uint32 ffiType FFIUInt64 = ffi_type_uint64 -data C_ffi_type-data C_ffi_cif- type C_ffi_status = (#type ffi_status) type C_ffi_abi = (#type ffi_abi) @@ -161,3 +193,4 @@ -- -> Ptr () -- put result here -- -> Ptr (Ptr ()) -- arg values -- -> IO ()+#endif
libraries/ghci/GHCi/Message.hs view
@@ -465,7 +465,7 @@ #define MIN_VERSION_ghc_heap(major1,major2,minor) (\ (major1) < 9 || \ (major1) == 9 && (major2) < 5 || \- (major1) == 9 && (major2) == 5 && (minor) <= 20221101)+ (major1) == 9 && (major2) == 5 && (minor) <= 20221130) #endif /* MIN_VERSION_ghc_heap */ #if MIN_VERSION_ghc_heap(8,11,0) instance Binary Heap.StgTSOProfInfo
+ libraries/ghci/ghci.cabal view
@@ -0,0 +1,86 @@+-- WARNING: ghci.cabal is automatically generated from ghci.cabal.in by+-- ../../configure. Make sure you are editing ghci.cabal.in, not ghci.cabal.++name: ghci+version: 9.5+license: BSD3+license-file: LICENSE+category: GHC+maintainer: ghc-devs@haskell.org+bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new+synopsis: The library supporting GHC's interactive interpreter+description:+ This library offers interfaces which mediate interactions between the+ @ghci@ interactive shell and @iserv@, GHC's out-of-process interpreter+ backend.+cabal-version: >=1.10+build-type: Simple+extra-source-files: changelog.md++Flag internal-interpreter+ Description: Build with internal interpreter support.+ Default: False+ Manual: True++source-repository head+ type: git+ location: https://gitlab.haskell.org/ghc/ghc.git+ subdir: libraries/ghci++library+ default-language: Haskell2010+ default-extensions: NoImplicitPrelude+ other-extensions:+ BangPatterns+ CPP+ DeriveGeneric+ ExistentialQuantification+ FlexibleInstances+ GADTs+ GeneralizedNewtypeDeriving+ InstanceSigs+ MagicHash+ MultiParamTypeClasses+ RecordWildCards+ ScopedTypeVariables+ StandaloneDeriving+ TupleSections+ UnboxedTuples++ if flag(internal-interpreter)+ CPP-Options: -DHAVE_INTERNAL_INTERPRETER+ exposed-modules:+ GHCi.InfoTable+ GHCi.Run+ GHCi.CreateBCO+ GHCi.ObjLink+ GHCi.Signals+ GHCi.StaticPtrTable+ GHCi.TH++ exposed-modules:+ GHCi.BreakArray+ GHCi.BinaryArray+ GHCi.Message+ GHCi.ResolvedBCO+ GHCi.RemoteTypes+ GHCi.FFI+ GHCi.TH.Binary++ Build-Depends:+ rts,+ array == 0.5.*,+ base >= 4.8 && < 4.18,+ ghc-prim >= 0.5.0 && < 0.11,+ binary == 0.8.*,+ bytestring >= 0.10 && < 0.12,+ containers >= 0.5 && < 0.7,+ deepseq == 1.4.*,+ filepath == 1.4.*,+ ghc-boot == 9.5,+ ghc-heap == 9.5,+ template-haskell == 2.19.*,+ transformers == 0.5.*++ if !os(windows)+ Build-Depends: unix >= 2.7 && < 2.9
libraries/template-haskell/Language/Haskell/TH/Syntax.hs view
@@ -827,6 +827,7 @@ LangObjc -> "m" LangObjcxx -> "mm" LangAsm -> "s"+ LangJs -> "js" RawObject -> "a" path <- addTempFile suffix runIO $ writeFile path src@@ -1133,8 +1134,9 @@ where helper :: HasCallStack => Name helper =- case head (getCallStack ?callStack) of- (_, SrcLoc{..}) -> mkNameG_v srcLocPackage srcLocModule "addrToByteArray"+ case getCallStack ?callStack of+ [] -> error "addrToByteArrayName: empty call stack"+ (_, SrcLoc{..}) : _ -> mkNameG_v srcLocPackage srcLocModule "addrToByteArray" addrToByteArray :: Int -> Addr# -> ByteArray
+ libraries/template-haskell/template-haskell.cabal view
@@ -0,0 +1,73 @@+-- WARNING: template-haskell.cabal is automatically generated from template-haskell.cabal.in by+-- ../../configure. Make sure you are editing template-haskell.cabal.in, not+-- template-haskell.cabal.++name: template-haskell+version: 2.19.0.0+-- NOTE: Don't forget to update ./changelog.md+license: BSD3+license-file: LICENSE+category: Template Haskell+maintainer: libraries@haskell.org+bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new+synopsis: Support library for Template Haskell+build-type: Simple+Cabal-Version: >= 1.10+description:+ This package provides modules containing facilities for manipulating+ Haskell source code using Template Haskell.+ .+ See <http://www.haskell.org/haskellwiki/Template_Haskell> for more+ information.++extra-source-files: changelog.md++source-repository head+ type: git+ location: https://gitlab.haskell.org/ghc/ghc.git+ subdir: libraries/template-haskell++Library+ default-language: Haskell2010+ other-extensions:+ BangPatterns+ CPP+ DefaultSignatures+ DeriveDataTypeable+ DeriveGeneric+ FlexibleInstances+ RankNTypes+ RoleAnnotations+ ScopedTypeVariables++ exposed-modules:+ Language.Haskell.TH+ Language.Haskell.TH.Lib+ Language.Haskell.TH.Ppr+ Language.Haskell.TH.PprLib+ Language.Haskell.TH.Quote+ Language.Haskell.TH.Syntax+ Language.Haskell.TH.LanguageExtensions+ Language.Haskell.TH.CodeDo+ Language.Haskell.TH.Lib.Internal++ other-modules:+ Language.Haskell.TH.Lib.Map++ build-depends:+ base >= 4.11 && < 4.18,+ ghc-boot-th == 9.5,+ ghc-prim,+ pretty == 1.1.*++ build-depends:+ filepath+ hs-source-dirs: .+ default-extensions:+ ImplicitPrelude++ ghc-options: -Wall++ -- We need to set the unit ID to template-haskell (without a+ -- version number) as it's magic.+ ghc-options: -this-unit-id template-haskell