HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Moduleghc-9.10.3GHC2021

GHC.Core

GHC.Core holds all the main data types for use by for the Glasgow Haskell Compiler midsection

  • 56 types
  • 110 values
  • Packageghc-9.10.3
  • Exports166
  • LanguageGHC2021
  • LicenceBSD-3-Clause
  • SourceCore.hs

Main data types

17 declarations
datadata Expr b
#

This is the data type that represents GHCs core intermediate language. Currently GHC uses System FC https://www.microsoft.com/en-us/research/publication/system-f-with-type-equality-coercions/ for this purpose, which is closely related to the simpler and better known System F http://en.wikipedia.org/wiki/System_F.

We get from Haskell source to this Core language in a number of stages:

  1. The source code is parsed into an abstract syntax tree, which is represented by the data type GHC.Hs.Expr.HsExpr with the names being GHC.Types.Name.Reader.RdrNames

  2. This syntax tree is renamed, which attaches a Unique to every RdrName (yielding a Name) to disambiguate identifiers which are lexically identical. For example, this program:

     f x = let f x = x + 1
           in f (x - 2)

Would be renamed by having Uniques attached so it looked something like this:

     f_1 x_2 = let f_3 x_4 = x_4 + 1
               in f_3 (x_2 - 2)

But see Note [Shadowing in Core] below.

  1. The resulting syntax tree undergoes type checking (which also deals with instantiating type class arguments) to yield a GHC.Hs.Expr.HsExpr type that has GHC.Types.Id.Id as it's names.

  2. Finally the syntax tree is desugared from the expressive GHC.Hs.Expr.HsExpr type into this Expr type, which has far fewer constructors and hence is easier to perform optimization, analysis and code generation on.

The type parameter b is for the type of binders in the expression tree.

The language consists of the following elements:

  • Variables See Note [Variable occurrences in Core]

  • Primitive literals

  • Applications: note that the argument may be a Type. See Note [Representation polymorphism invariants]

  • Lambda abstraction See Note [Representation polymorphism invariants]

  • Recursive and non recursive lets. Operationally this corresponds to allocating a thunk for the things bound and then executing the sub-expression.

See Note [Core letrec invariant] See Note [Core let-can-float invariant] See Note [Representation polymorphism invariants] See Note [Core type and coercion invariant]

  • Case expression. Operationally this corresponds to evaluating the scrutinee (expression examined) to weak head normal form and then examining at most one level of resulting constructor (i.e. you cannot do nested pattern matching directly with this).

The binder gets bound to the value of the scrutinee, and the Type must be that of all the case alternatives

IMPORTANT: see Note [Case expression invariants]

  • Cast an expression to a particular type. This is used to implement newtypes (a newtype constructor or destructor just becomes a Cast in Core) and GADTs.

  • Ticks. These are used to represent all the source annotation we support: profiling SCCs, HPC ticks, and GHCi breakpoints.

  • A type: this should only show up at the top level of an Arg

  • A coercion

Instances3Eq, Data, Outputable
datadata Alt b
#

A case split alternative. Consists of the constructor leading to the alternative, the variables bound from the constructor, and the expression to be executed given that binding. The default alternative is (DEFAULT, [], rhs)

Constructors

Instances3Eq, Data, Outputable
datadata Bind b
#

Binding, used for top level bindings in a module and local bindings in a let.

Constructors

Instances2Data, Outputable
datadata AltCon
#

A case alternative constructor (i.e. pattern match)

Constructors

  • DataAlt DataCon
  • LitAlt Literal

    A literal: case e of { 1 -> ... } Invariant: always an *unlifted* literal See Note [Literal alternatives]

  • DEFAULT

    Trivial alternative: case e of { _ -> ... }

Instances4Eq, Data, Ord, Outputable
typetype Arg b = Expr b
#

Type synonym for expressions that occur in function argument positions. Only Arg should contain a Type at top level, general Expr should not

typetype CoreBndr = Var
#

The common case for the type of binders and variables when we are manipulating the Core language within GHC

In/Out type synonyms

25 declarations

Expr construction

valuemkLets :: [Bind b] -> Expr b -> Expr b
#

Bind all supplied binding groups over an expression in a nested let expression. Assumes that the rhs satisfies the let-can-float invariant. Prefer to use mkCoreLets if possible, which does guarantee the invariant

valuemkLetRec :: [(b, Expr b)] -> Expr b -> Expr b
#

mkLetRec binds body wraps body in a let rec with the given set of binds if binds is non-empty.

valuemkLams :: [b] -> Expr b -> Expr b
#

Bind all supplied binders over an expression in a nested lambda expression. Prefer to use mkCoreLams if possible

valuemkApps :: Expr b -> [Arg b] -> Expr b
#

Apply a list of argument expressions to a function expression in a nested fashion. Prefer to use mkCoreApps if possible

valuemkTyApps :: Expr b -> [Type] -> Expr b
#

Apply a list of type argument expressions to a function expression in a nested fashion

valuemkCoApps :: Expr b -> [Coercion] -> Expr b
#

Apply a list of coercion argument expressions to a function expression in a nested fashion

valuemkVarApps :: Expr b -> [Var] -> Expr b
#

Apply a list of type or value variables to a function expression in a nested fashion

valuemkCharLit :: Char -> Expr b
#

Create a machine character literal expression of type Char#. If you want an expression of type Char use mkCharExpr

valuemkFloatLit :: Rational -> Expr b
#

Create a machine single precision literal expression of type Float# from a Rational. If you want an expression of type Float use mkFloatExpr

valuemkFloatLitFloat :: Float -> Expr b
#

Create a machine single precision literal expression of type Float# from a Float. If you want an expression of type Float use mkFloatExpr

valuemkDoubleLit :: Rational -> Expr b
#

Create a machine double precision literal expression of type Double# from a Rational. If you want an expression of type Double use mkDoubleExpr

valuemkTyBind :: TyVar -> Type -> CoreBind
#

Create a binding group where a type variable is bound to a type. Per Note [Core type and coercion invariant], this can only be used to bind something in a non-recursive let expression

valuemkCoBind :: CoVar -> Coercion -> CoreBind
#

Create a binding group where a type variable is bound to a type. Per Note [Core type and coercion invariant], this can only be used to bind something in a non-recursive let expression

valueisId :: Var -> Bool
#

Is this a value-level (i.e., computationally relevant) Identifier? Satisfies isId = not . isTyVar.

valuecmpAltCon :: AltCon -> AltCon -> Ordering
#

Compares AltCons within a single list of alternatives DEFAULT comes out smallest, so that sorting by AltCon puts alternatives in the order required: see Note [Case expression invariants]

Simple Expr access functions and predicates

valuebindersOf :: Bind b -> [b]
#

Extract every variable by this group

valuecollectNBinders :: JoinArity -> Expr b -> ([b], Expr b)
#

Strip off exactly N leading lambdas (type or value). Good for use with join points. Panic if there aren't enough

valuecollectArgs :: Expr b -> (Expr b, [Arg b])
#

Takes a nested application expression and returns the function being applied and the arguments to which it is applied

valuestripNArgs :: Word -> Expr a -> Maybe (Expr a)
#

Attempt to remove the last N arguments of a function call. Strip off any ticks or coercions encountered along the way and any at the end.

valueflattenBinds :: [Bind b] -> [(b, Expr b)]
#

Collapse all the bindings in the supplied groups into a single list of lhs/rhs pairs suitable for binding in a Rec binding group

valuecollectFunSimple :: Expr b -> Expr b
#

Takes a nested application expression and returns the function being applied. Looking through casts and ticks to find it.

valueisValArg :: Expr b -> Bool
#

Returns True for value arguments, false for type args NB: coercions are value arguments (zero width, to be sure, like State#, but still value args).

valuevalArgCount :: [Arg b] -> Int
#

The number of argument expressions that are values rather than types at their top level

Unfolding data types

4 declarations
datadata Unfolding
#

Records the unfolding of an identifier, which is approximately the form the identifier would have if we substituted its definition in for the identifier. This type should be treated as abstract everywhere except in GHC.Core.Unfold

Constructors

  • NoUnfolding

    We have no information about the unfolding.

  • BootUnfolding

    We have no information about the unfolding, because this Id came from an hi-boot file. See Note [Inlining and hs-boot files] in GHC.CoreToIface for what this is used for.

  • OtherCon [AltCon]

    It ain't one of these constructors. OtherCon xs also indicates that something has been evaluated and hence there's no point in re-evaluating it. OtherCon [] is used even for non-data-type values to indicated evaluated-ness. Notably:

    data C = C !(Int -> Int)
    case x of { C f -> ... }

    Here, f gets an OtherCon [] unfolding.

  • DFunUnfolding
  • CoreUnfolding

    An unfolding with redundant cached information. Parameters:

    uf_tmpl: Template used to perform unfolding; NB: Occurrence info is guaranteed correct: see Note [OccInfo in unfoldings and rules]

    uf_is_top: Is this a top level binding?

    uf_is_value: exprIsHNF template (cached); it is ok to discard a seq on this variable

    uf_is_work_free: Does this waste only a little work if we expand it inside an inlining? Basically this is a cached version of exprIsWorkFree

    uf_guidance: Tells us about the size of the unfolding template

Instances1Outputable

Constructing Unfoldings

Predicates and deconstruction on Unfolding

Retrieves the template of an unfolding if possible maybeUnfoldingTemplate is used mainly when specialising, and we do want to specialise DFuns, so it's important to return a template for DFunUnfoldings

valueotherCons :: Unfolding -> [AltCon]
#

The constructors that the unfolding could never be: returns [] if no information is available

Determines if it is certainly the case that the unfolding will yield a value (something in HNF): returns False if unsure

True of a stable unfolding that is (a) always inlined; that is, with an UnfWhen guidance, or (b) a DFunUnfolding which never needs to be inlined

Annotated expression data types

4 declarations
typetype AnnExpr bndr annot = (annot, AnnExpr' bndr annot)
#

Annotated core: allows annotation at every node in the tree

datadata AnnAlt bndr annot
#

A clone of the Alt type but allowing annotation at every tree node

Constructors

Operations on annotated expressions

valuecollectAnnArgs :: AnnExpr b a -> (AnnExpr b a, [AnnExpr b a])
#

Takes a nested application expression and returns the function being applied and the arguments to which it is applied

Operations on annotations

Orphanhood

4 declarations

Core rule data types

6 declarations
datadata CoreRule
#

A CoreRule is:

  • "Local" if the function it is a rule for is defined in the same module as the rule itself.

  • "Orphan" if nothing on the LHS is defined in the same module as the rule itself

Constructors

  • Rule
    • ru_name :: RuleName

      Name of the rule, for communication with the user

    • ru_act :: Activation

      When the rule is active

    • ru_fn :: !Name

      Name of the GHC.Types.Id.Id at the head of this rule

    • ru_rough :: [Maybe Name]

      Name at the head of each argument to the left hand side

    • ru_bndrs :: [CoreBndr]

      Variables quantified over

    • ru_args :: [CoreExpr]

      Left hand side arguments

    • ru_rhs :: CoreExpr

      Right hand side of the rule Occurrence info is guaranteed correct See Note [OccInfo in unfoldings and rules]

    • ru_auto :: Bool

      True = this rule is auto-generated (notably by Specialise or SpecConstr) False = generated at the user's behest See Note [Trimming auto-rules] in GHC.Iface.Tidy for the sole purpose of this field.

    • ru_origin :: !Module

      Module the rule was defined in, used to test if we should see an orphan rule.

    • ru_orphan :: !IsOrphan

      Whether or not the rule is an orphan.

    • ru_local :: Bool

      True iff the fn at the head of the rule is defined in the same module as the rule and is not an implicit Id (like a record selector, class operation, or data constructor). This is different from ru_orphan, where a rule can avoid being an orphan if *any* Name in LHS of the rule was defined in the same module as the rule.

  • BuiltinRule

    Built-in rules are used for constant folding and suchlike. They have no free variables. A built-in rule is always visible (there is no such thing as an orphan built-in rule.)

    • ru_name :: RuleName

      Name of the rule, for communication with the user

    • ru_fn :: Name

      Name of the GHC.Types.Id.Id at the head of this rule

    • ru_nargs :: Int

      Number of arguments that ru_try consumes, if it fires, including type arguments

    • ru_try :: RuleFun

      This function does the rewrite. It given too many arguments, it simply discards them; the returned CoreExpr is just the rewrite of ru_fn applied to the first ru_nargs args

Instances1Outputable

Operations on CoreRules