summaryrefslogtreecommitdiff
path: root/compiler/Language/Haskell
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/Language/Haskell')
-rw-r--r--compiler/Language/Haskell/Syntax.hs58
-rw-r--r--compiler/Language/Haskell/Syntax/Binds.hs944
-rw-r--r--compiler/Language/Haskell/Syntax/Decls.hs1804
-rw-r--r--compiler/Language/Haskell/Syntax/Expr.hs1776
-rw-r--r--compiler/Language/Haskell/Syntax/Expr.hs-boot22
-rw-r--r--compiler/Language/Haskell/Syntax/Extension.hs665
-rw-r--r--compiler/Language/Haskell/Syntax/Lit.hs204
-rw-r--r--compiler/Language/Haskell/Syntax/Pat.hs374
-rw-r--r--compiler/Language/Haskell/Syntax/Pat.hs-boot13
-rw-r--r--compiler/Language/Haskell/Syntax/Type.hs1304
10 files changed, 7164 insertions, 0 deletions
diff --git a/compiler/Language/Haskell/Syntax.hs b/compiler/Language/Haskell/Syntax.hs
new file mode 100644
index 0000000000..9da54cd8ed
--- /dev/null
+++ b/compiler/Language/Haskell/Syntax.hs
@@ -0,0 +1,58 @@
+{-
+(c) The University of Glasgow 2006
+(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
+
+\section{Haskell abstract syntax definition}
+
+This module glues together the pieces of the Haskell abstract syntax,
+which is declared in the various \tr{Hs*} modules. This module,
+therefore, is almost nothing but re-exporting.
+-}
+
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow]
+ -- in module Language.Haskell.Syntax.Extension
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE FlexibleInstances #-} -- For deriving instance Data
+
+-- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.*
+module Language.Haskell.Syntax (
+ module Language.Haskell.Syntax.Binds,
+ module Language.Haskell.Syntax.Decls,
+ module Language.Haskell.Syntax.Expr,
+ module Language.Haskell.Syntax.Lit,
+ module Language.Haskell.Syntax.Pat,
+ module Language.Haskell.Syntax.Type,
+ module Language.Haskell.Syntax.Extension,
+) where
+
+import Language.Haskell.Syntax.Decls
+import Language.Haskell.Syntax.Binds
+import Language.Haskell.Syntax.Expr
+import Language.Haskell.Syntax.Lit
+import Language.Haskell.Syntax.Extension
+import Language.Haskell.Syntax.Pat
+import Language.Haskell.Syntax.Type
+
+{-
+Note [Language.Haskell.Syntax.* Hierarchy]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Why are these modules not 'GHC.Hs.*', or some other 'GHC.*'? The answer
+is that they are to be separated from GHC and put into another package,
+in accordance with the final goals of Trees that Grow. (See Note [Trees
+that grow] in 'Language.Haskell.Syntax.Extension'.)
+
+We cannot separate them yet, but by giving them names like so, we hope
+to remind others that the goal is to factor them out, and therefore
+dependencies on the rest of GHC should never be added, only removed.
+
+For more details, see
+https://gitlab.haskell.org/ghc/ghc/-/wikis/implementing-trees-that-grow
+-}
+
+
+-- TODO Add TTG parameter to 'HsModule' and move here.
diff --git a/compiler/Language/Haskell/Syntax/Binds.hs b/compiler/Language/Haskell/Syntax/Binds.hs
new file mode 100644
index 0000000000..6f7283be86
--- /dev/null
+++ b/compiler/Language/Haskell/Syntax/Binds.hs
@@ -0,0 +1,944 @@
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow]
+ -- in module Language.Haskell.Syntax.Extension
+{-# LANGUAGE ViewPatterns #-}
+
+
+{-
+(c) The University of Glasgow 2006
+(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
+
+\section[HsBinds]{Abstract syntax: top-level bindings and signatures}
+
+Datatype for: @BindGroup@, @Bind@, @Sig@, @Bind@.
+-}
+
+-- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.*
+module Language.Haskell.Syntax.Binds where
+
+import GHC.Prelude
+
+import {-# SOURCE #-} Language.Haskell.Syntax.Expr
+ ( LHsExpr
+ , MatchGroup
+ , GRHSs )
+import {-# SOURCE #-} Language.Haskell.Syntax.Pat
+ ( LPat )
+
+import Language.Haskell.Syntax.Extension
+import Language.Haskell.Syntax.Type
+import GHC.Core
+import GHC.Tc.Types.Evidence
+import GHC.Core.Type
+import GHC.Types.Basic
+import GHC.Types.SourceText
+import GHC.Types.SrcLoc as SrcLoc
+import GHC.Types.Var
+import GHC.Types.Fixity
+import GHC.Data.Bag
+import GHC.Data.BooleanFormula (LBooleanFormula)
+
+import GHC.Utils.Outputable
+
+import Data.Data hiding ( Fixity )
+import Data.Void
+
+{-
+************************************************************************
+* *
+\subsection{Bindings: @BindGroup@}
+* *
+************************************************************************
+
+Global bindings (where clauses)
+-}
+
+-- During renaming, we need bindings where the left-hand sides
+-- have been renamed but the right-hand sides have not.
+-- Other than during renaming, these will be the same.
+
+-- | Haskell Local Bindings
+type HsLocalBinds id = HsLocalBindsLR id id
+
+-- | Located Haskell local bindings
+type LHsLocalBinds id = XRec id (HsLocalBinds id)
+
+-- | Haskell Local Bindings with separate Left and Right identifier types
+--
+-- Bindings in a 'let' expression
+-- or a 'where' clause
+data HsLocalBindsLR idL idR
+ = HsValBinds
+ (XHsValBinds idL idR)
+ (HsValBindsLR idL idR)
+ -- ^ Haskell Value Bindings
+
+ -- There should be no pattern synonyms in the HsValBindsLR
+ -- These are *local* (not top level) bindings
+ -- The parser accepts them, however, leaving the
+ -- renamer to report them
+
+ | HsIPBinds
+ (XHsIPBinds idL idR)
+ (HsIPBinds idR)
+ -- ^ Haskell Implicit Parameter Bindings
+
+ | EmptyLocalBinds (XEmptyLocalBinds idL idR)
+ -- ^ Empty Local Bindings
+
+ | XHsLocalBindsLR
+ !(XXHsLocalBindsLR idL idR)
+
+type LHsLocalBindsLR idL idR = XRec idL (HsLocalBindsLR idL idR)
+
+
+-- | Haskell Value Bindings
+type HsValBinds id = HsValBindsLR id id
+
+-- | Haskell Value bindings with separate Left and Right identifier types
+-- (not implicit parameters)
+-- Used for both top level and nested bindings
+-- May contain pattern synonym bindings
+data HsValBindsLR idL idR
+ = -- | Value Bindings In
+ --
+ -- Before renaming RHS; idR is always RdrName
+ -- Not dependency analysed
+ -- Recursive by default
+ ValBinds
+ (XValBinds idL idR)
+ (LHsBindsLR idL idR) [LSig idR]
+
+ -- | Value Bindings Out
+ --
+ -- After renaming RHS; idR can be Name or Id Dependency analysed,
+ -- later bindings in the list may depend on earlier ones.
+ | XValBindsLR
+ !(XXValBindsLR idL idR)
+
+-- ---------------------------------------------------------------------
+
+-- | Located Haskell Binding
+type LHsBind id = LHsBindLR id id
+
+-- | Located Haskell Bindings
+type LHsBinds id = LHsBindsLR id id
+
+-- | Haskell Binding
+type HsBind id = HsBindLR id id
+
+-- | Located Haskell Bindings with separate Left and Right identifier types
+type LHsBindsLR idL idR = Bag (LHsBindLR idL idR)
+
+-- | Located Haskell Binding with separate Left and Right identifier types
+type LHsBindLR idL idR = XRec idL (HsBindLR idL idR)
+
+{- Note [FunBind vs PatBind]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+The distinction between FunBind and PatBind is a bit subtle. FunBind covers
+patterns which resemble function bindings and simple variable bindings.
+
+ f x = e
+ f !x = e
+ f = e
+ !x = e -- FunRhs has SrcStrict
+ x `f` y = e -- FunRhs has Infix
+
+The actual patterns and RHSs of a FunBind are encoding in fun_matches.
+The m_ctxt field of each Match in fun_matches will be FunRhs and carries
+two bits of information about the match,
+
+ * The mc_fixity field on each Match describes the fixity of the
+ function binder in that match. E.g. this is legal:
+ f True False = e1
+ True `f` True = e2
+
+ * The mc_strictness field is used /only/ for nullary FunBinds: ones
+ with one Match, which has no pats. For these, it describes whether
+ the match is decorated with a bang (e.g. `!x = e`).
+
+By contrast, PatBind represents data constructor patterns, as well as a few
+other interesting cases. Namely,
+
+ Just x = e
+ (x) = e
+ x :: Ty = e
+-}
+
+-- | Haskell Binding with separate Left and Right id's
+data HsBindLR idL idR
+ = -- | Function-like Binding
+ --
+ -- FunBind is used for both functions @f x = e@
+ -- and variables @f = \x -> e@
+ -- and strict variables @!x = x + 1@
+ --
+ -- Reason 1: Special case for type inference: see 'GHC.Tc.Gen.Bind.tcMonoBinds'.
+ --
+ -- Reason 2: Instance decls can only have FunBinds, which is convenient.
+ -- If you change this, you'll need to change e.g. rnMethodBinds
+ --
+ -- But note that the form @f :: a->a = ...@
+ -- parses as a pattern binding, just like
+ -- @(f :: a -> a) = ... @
+ --
+ -- Strict bindings have their strictness recorded in the 'SrcStrictness' of their
+ -- 'MatchContext'. See Note [FunBind vs PatBind] for
+ -- details about the relationship between FunBind and PatBind.
+ --
+ -- 'GHC.Parser.Annotation.AnnKeywordId's
+ --
+ -- - 'GHC.Parser.Annotation.AnnFunId', attached to each element of fun_matches
+ --
+ -- - 'GHC.Parser.Annotation.AnnEqual','GHC.Parser.Annotation.AnnWhere',
+ -- 'GHC.Parser.Annotation.AnnOpen','GHC.Parser.Annotation.AnnClose',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ FunBind {
+
+ fun_ext :: XFunBind idL idR,
+
+ -- ^ After the renamer (but before the type-checker), this contains the
+ -- locally-bound free variables of this defn. See Note [Bind free vars]
+ --
+ -- After the type-checker, this contains a coercion from the type of
+ -- the MatchGroup to the type of the Id. Example:
+ --
+ -- @
+ -- f :: Int -> forall a. a -> a
+ -- f x y = y
+ -- @
+ --
+ -- Then the MatchGroup will have type (Int -> a' -> a')
+ -- (with a free type variable a'). The coercion will take
+ -- a CoreExpr of this type and convert it to a CoreExpr of
+ -- type Int -> forall a'. a' -> a'
+ -- Notice that the coercion captures the free a'.
+
+ fun_id :: LIdP idL, -- Note [fun_id in Match] in GHC.Hs.Expr
+
+ fun_matches :: MatchGroup idR (LHsExpr idR), -- ^ The payload
+
+ fun_tick :: [Tickish Id] -- ^ Ticks to put on the rhs, if any
+ }
+
+ -- | Pattern Binding
+ --
+ -- The pattern is never a simple variable;
+ -- That case is done by FunBind.
+ -- See Note [FunBind vs PatBind] for details about the
+ -- relationship between FunBind and PatBind.
+
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnBang',
+ -- 'GHC.Parser.Annotation.AnnEqual','GHC.Parser.Annotation.AnnWhere',
+ -- 'GHC.Parser.Annotation.AnnOpen','GHC.Parser.Annotation.AnnClose',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | PatBind {
+ pat_ext :: XPatBind idL idR, -- ^ See Note [Bind free vars]
+ pat_lhs :: LPat idL,
+ pat_rhs :: GRHSs idR (LHsExpr idR),
+ pat_ticks :: ([Tickish Id], [[Tickish Id]])
+ -- ^ Ticks to put on the rhs, if any, and ticks to put on
+ -- the bound variables.
+ }
+
+ -- | Variable Binding
+ --
+ -- Dictionary binding and suchlike.
+ -- All VarBinds are introduced by the type checker
+ | VarBind {
+ var_ext :: XVarBind idL idR,
+ var_id :: IdP idL,
+ var_rhs :: LHsExpr idR -- ^ Located only for consistency
+ }
+
+ -- | Abstraction Bindings
+ | AbsBinds { -- Binds abstraction; TRANSLATION
+ abs_ext :: XAbsBinds idL idR,
+ abs_tvs :: [TyVar],
+ abs_ev_vars :: [EvVar], -- ^ Includes equality constraints
+
+ -- | AbsBinds only gets used when idL = idR after renaming,
+ -- but these need to be idL's for the collect... code in HsUtil
+ -- to have the right type
+ abs_exports :: [ABExport idL],
+
+ -- | Evidence bindings
+ -- Why a list? See "GHC.Tc.TyCl.Instance"
+ -- Note [Typechecking plan for instance declarations]
+ abs_ev_binds :: [TcEvBinds],
+
+ -- | Typechecked user bindings
+ abs_binds :: LHsBinds idL,
+
+ abs_sig :: Bool -- See Note [The abs_sig field of AbsBinds]
+ }
+
+ -- | Patterns Synonym Binding
+ | PatSynBind
+ (XPatSynBind idL idR)
+ (PatSynBind idL idR)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnPattern',
+ -- 'GHC.Parser.Annotation.AnnLarrow','GHC.Parser.Annotation.AnnEqual',
+ -- 'GHC.Parser.Annotation.AnnWhere'
+ -- 'GHC.Parser.Annotation.AnnOpen' @'{'@,'GHC.Parser.Annotation.AnnClose' @'}'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | XHsBindsLR !(XXHsBindsLR idL idR)
+
+
+ -- Consider (AbsBinds tvs ds [(ftvs, poly_f, mono_f) binds]
+ --
+ -- Creates bindings for (polymorphic, overloaded) poly_f
+ -- in terms of monomorphic, non-overloaded mono_f
+ --
+ -- Invariants:
+ -- 1. 'binds' binds mono_f
+ -- 2. ftvs is a subset of tvs
+ -- 3. ftvs includes all tyvars free in ds
+ --
+ -- See Note [AbsBinds]
+
+-- | Abstraction Bindings Export
+data ABExport p
+ = ABE { abe_ext :: XABE p
+ , abe_poly :: IdP p -- ^ Any INLINE pragma is attached to this Id
+ , abe_mono :: IdP p
+ , abe_wrap :: HsWrapper -- ^ See Note [ABExport wrapper]
+ -- Shape: (forall abs_tvs. abs_ev_vars => abe_mono) ~ abe_poly
+ , abe_prags :: TcSpecPrags -- ^ SPECIALISE pragmas
+ }
+ | XABExport !(XXABExport p)
+
+
+-- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnPattern',
+-- 'GHC.Parser.Annotation.AnnEqual','GHC.Parser.Annotation.AnnLarrow',
+-- 'GHC.Parser.Annotation.AnnWhere','GHC.Parser.Annotation.AnnOpen' @'{'@,
+-- 'GHC.Parser.Annotation.AnnClose' @'}'@,
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-- | Pattern Synonym binding
+data PatSynBind idL idR
+ = PSB { psb_ext :: XPSB idL idR, -- ^ Post renaming, FVs.
+ -- See Note [Bind free vars]
+ psb_id :: LIdP idL, -- ^ Name of the pattern synonym
+ psb_args :: HsPatSynDetails idR, -- ^ Formal parameter names
+ psb_def :: LPat idR, -- ^ Right-hand side
+ psb_dir :: HsPatSynDir idR -- ^ Directionality
+ }
+ | XPatSynBind !(XXPatSynBind idL idR)
+
+{-
+Note [AbsBinds]
+~~~~~~~~~~~~~~~
+The AbsBinds constructor is used in the output of the type checker, to
+record *typechecked* and *generalised* bindings. Specifically
+
+ AbsBinds { abs_tvs = tvs
+ , abs_ev_vars = [d1,d2]
+ , abs_exports = [ABE { abe_poly = fp, abe_mono = fm
+ , abe_wrap = fwrap }
+ ABE { slly for g } ]
+ , abs_ev_binds = DBINDS
+ , abs_binds = BIND[fm,gm] }
+
+where 'BIND' binds the monomorphic Ids 'fm' and 'gm', means
+
+ fp = fwrap [/\ tvs. \d1 d2. letrec { DBINDS ]
+ [ ; BIND[fm,gm] } ]
+ [ in fm ]
+
+ gp = ...same again, with gm instead of fm
+
+The 'fwrap' is an impedance-matcher that typically does nothing; see
+Note [ABExport wrapper].
+
+This is a pretty bad translation, because it duplicates all the bindings.
+So the desugarer tries to do a better job:
+
+ fp = /\ [a,b] -> \ [d1,d2] -> case tp [a,b] [d1,d2] of
+ (fm,gm) -> fm
+ ..ditto for gp..
+
+ tp = /\ [a,b] -> \ [d1,d2] -> letrec { DBINDS; BIND }
+ in (fm,gm)
+
+In general:
+
+ * abs_tvs are the type variables over which the binding group is
+ generalised
+ * abs_ev_var are the evidence variables (usually dictionaries)
+ over which the binding group is generalised
+ * abs_binds are the monomorphic bindings
+ * abs_ex_binds are the evidence bindings that wrap the abs_binds
+ * abs_exports connects the monomorphic Ids bound by abs_binds
+ with the polymorphic Ids bound by the AbsBinds itself.
+
+For example, consider a module M, with this top-level binding, where
+there is no type signature for M.reverse,
+ M.reverse [] = []
+ M.reverse (x:xs) = M.reverse xs ++ [x]
+
+In Hindley-Milner, a recursive binding is typechecked with the
+*recursive* uses being *monomorphic*. So after typechecking *and*
+desugaring we will get something like this
+
+ M.reverse :: forall a. [a] -> [a]
+ = /\a. letrec
+ reverse :: [a] -> [a] = \xs -> case xs of
+ [] -> []
+ (x:xs) -> reverse xs ++ [x]
+ in reverse
+
+Notice that 'M.reverse' is polymorphic as expected, but there is a local
+definition for plain 'reverse' which is *monomorphic*. The type variable
+'a' scopes over the entire letrec.
+
+That's after desugaring. What about after type checking but before
+desugaring? That's where AbsBinds comes in. It looks like this:
+
+ AbsBinds { abs_tvs = [a]
+ , abs_ev_vars = []
+ , abs_exports = [ABE { abe_poly = M.reverse :: forall a. [a] -> [a],
+ , abe_mono = reverse :: [a] -> [a]}]
+ , abs_ev_binds = {}
+ , abs_binds = { reverse :: [a] -> [a]
+ = \xs -> case xs of
+ [] -> []
+ (x:xs) -> reverse xs ++ [x] } }
+
+Here,
+
+ * abs_tvs says what type variables are abstracted over the binding
+ group, just 'a' in this case.
+ * abs_binds is the *monomorphic* bindings of the group
+ * abs_exports describes how to get the polymorphic Id 'M.reverse'
+ from the monomorphic one 'reverse'
+
+Notice that the *original* function (the polymorphic one you thought
+you were defining) appears in the abe_poly field of the
+abs_exports. The bindings in abs_binds are for fresh, local, Ids with
+a *monomorphic* Id.
+
+If there is a group of mutually recursive (see Note [Polymorphic
+recursion]) functions without type signatures, we get one AbsBinds
+with the monomorphic versions of the bindings in abs_binds, and one
+element of abe_exports for each variable bound in the mutually
+recursive group. This is true even for pattern bindings. Example:
+ (f,g) = (\x -> x, f)
+After type checking we get
+ AbsBinds { abs_tvs = [a]
+ , abs_exports = [ ABE { abe_poly = M.f :: forall a. a -> a
+ , abe_mono = f :: a -> a }
+ , ABE { abe_poly = M.g :: forall a. a -> a
+ , abe_mono = g :: a -> a }]
+ , abs_binds = { (f,g) = (\x -> x, f) }
+
+Note [Polymorphic recursion]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider
+ Rec { f x = ...(g ef)...
+
+ ; g :: forall a. [a] -> [a]
+ ; g y = ...(f eg)... }
+
+These bindings /are/ mutually recursive (f calls g, and g calls f).
+But we can use the type signature for g to break the recursion,
+like this:
+
+ 1. Add g :: forall a. [a] -> [a] to the type environment
+
+ 2. Typecheck the definition of f, all by itself,
+ including generalising it to find its most general
+ type, say f :: forall b. b -> b -> [b]
+
+ 3. Extend the type environment with that type for f
+
+ 4. Typecheck the definition of g, all by itself,
+ checking that it has the type claimed by its signature
+
+Steps 2 and 4 each generate a separate AbsBinds, so we end
+up with
+ Rec { AbsBinds { ...for f ... }
+ ; AbsBinds { ...for g ... } }
+
+This approach allows both f and to call each other
+polymorphically, even though only g has a signature.
+
+We get an AbsBinds that encompasses multiple source-program
+bindings only when
+ * Each binding in the group has at least one binder that
+ lacks a user type signature
+ * The group forms a strongly connected component
+
+
+Note [The abs_sig field of AbsBinds]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The abs_sig field supports a couple of special cases for bindings.
+Consider
+
+ x :: Num a => (# a, a #)
+ x = (# 3, 4 #)
+
+The general desugaring for AbsBinds would give
+
+ x = /\a. \ ($dNum :: Num a) ->
+ letrec xm = (# fromInteger $dNum 3, fromInteger $dNum 4 #) in
+ xm
+
+But that has an illegal let-binding for an unboxed tuple. In this
+case we'd prefer to generate the (more direct)
+
+ x = /\ a. \ ($dNum :: Num a) ->
+ (# fromInteger $dNum 3, fromInteger $dNum 4 #)
+
+A similar thing happens with representation-polymorphic defns
+(#11405):
+
+ undef :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a
+ undef = error "undef"
+
+Again, the vanilla desugaring gives a local let-binding for a
+representation-polymorphic (undefm :: a), which is illegal. But
+again we can desugar without a let:
+
+ undef = /\ a. \ (d:HasCallStack) -> error a d "undef"
+
+The abs_sig field supports this direct desugaring, with no local
+let-binding. When abs_sig = True
+
+ * the abs_binds is single FunBind
+
+ * the abs_exports is a singleton
+
+ * we have a complete type sig for binder
+ and hence the abs_binds is non-recursive
+ (it binds the mono_id but refers to the poly_id
+
+These properties are exploited in GHC.HsToCore.Binds.dsAbsBinds to
+generate code without a let-binding.
+
+Note [ABExport wrapper]
+~~~~~~~~~~~~~~~~~~~~~~~
+Consider
+ (f,g) = (\x.x, \y.y)
+This ultimately desugars to something like this:
+ tup :: forall a b. (a->a, b->b)
+ tup = /\a b. (\x:a.x, \y:b.y)
+ f :: forall a. a -> a
+ f = /\a. case tup a Any of
+ (fm::a->a,gm:Any->Any) -> fm
+ ...similarly for g...
+
+The abe_wrap field deals with impedance-matching between
+ (/\a b. case tup a b of { (f,g) -> f })
+and the thing we really want, which may have fewer type
+variables. The action happens in GHC.Tc.Gen.Bind.mkExport.
+
+Note [Bind free vars]
+~~~~~~~~~~~~~~~~~~~~~
+The bind_fvs field of FunBind and PatBind records the free variables
+of the definition. It is used for the following purposes
+
+a) Dependency analysis prior to type checking
+ (see GHC.Tc.Gen.Bind.tc_group)
+
+b) Deciding whether we can do generalisation of the binding
+ (see GHC.Tc.Gen.Bind.decideGeneralisationPlan)
+
+c) Deciding whether the binding can be used in static forms
+ (see GHC.Tc.Gen.Expr.checkClosedInStaticForm for the HsStatic case and
+ GHC.Tc.Gen.Bind.isClosedBndrGroup).
+
+Specifically,
+
+ * bind_fvs includes all free vars that are defined in this module
+ (including top-level things and lexically scoped type variables)
+
+ * bind_fvs excludes imported vars; this is just to keep the set smaller
+
+ * Before renaming, and after typechecking, the field is unused;
+ it's just an error thunk
+-}
+
+
+{-
+************************************************************************
+* *
+ Implicit parameter bindings
+* *
+************************************************************************
+-}
+
+-- | Haskell Implicit Parameter Bindings
+data HsIPBinds id
+ = IPBinds
+ (XIPBinds id)
+ [LIPBind id]
+ -- TcEvBinds -- Only in typechecker output; binds
+ -- -- uses of the implicit parameters
+ | XHsIPBinds !(XXHsIPBinds id)
+
+
+-- | Located Implicit Parameter Binding
+type LIPBind id = XRec id (IPBind id)
+-- ^ May have 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnSemi' when in a
+-- list
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-- | Implicit parameter bindings.
+--
+-- These bindings start off as (Left "x") in the parser and stay
+-- that way until after type-checking when they are replaced with
+-- (Right d), where "d" is the name of the dictionary holding the
+-- evidence for the implicit parameter.
+--
+-- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnEqual'
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+data IPBind id
+ = IPBind
+ (XCIPBind id)
+ (Either (XRec id HsIPName) (IdP id))
+ (LHsExpr id)
+ | XIPBind !(XXIPBind id)
+
+{-
+************************************************************************
+* *
+\subsection{@Sig@: type signatures and value-modifying user pragmas}
+* *
+************************************************************************
+
+It is convenient to lump ``value-modifying'' user-pragmas (e.g.,
+``specialise this function to these four types...'') in with type
+signatures. Then all the machinery to move them into place, etc.,
+serves for both.
+-}
+
+-- | Located Signature
+type LSig pass = XRec pass (Sig pass)
+
+-- | Signatures and pragmas
+data Sig pass
+ = -- | An ordinary type signature
+ --
+ -- > f :: Num a => a -> a
+ --
+ -- After renaming, this list of Names contains the named
+ -- wildcards brought into scope by this signature. For a signature
+ -- @_ -> _a -> Bool@, the renamer will leave the unnamed wildcard @_@
+ -- untouched, and the named wildcard @_a@ is then replaced with
+ -- fresh meta vars in the type. Their names are stored in the type
+ -- signature that brought them into scope, in this third field to be
+ -- more specific.
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnDcolon',
+ -- 'GHC.Parser.Annotation.AnnComma'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ TypeSig
+ (XTypeSig pass)
+ [LIdP pass] -- LHS of the signature; e.g. f,g,h :: blah
+ (LHsSigWcType pass) -- RHS of the signature; can have wildcards
+
+ -- | A pattern synonym type signature
+ --
+ -- > pattern Single :: () => (Show a) => a -> [a]
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnPattern',
+ -- 'GHC.Parser.Annotation.AnnDcolon','GHC.Parser.Annotation.AnnForall'
+ -- 'GHC.Parser.Annotation.AnnDot','GHC.Parser.Annotation.AnnDarrow'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | PatSynSig (XPatSynSig pass) [LIdP pass] (LHsSigType pass)
+ -- P :: forall a b. Req => Prov => ty
+
+ -- | A signature for a class method
+ -- False: ordinary class-method signature
+ -- True: generic-default class method signature
+ -- e.g. class C a where
+ -- op :: a -> a -- Ordinary
+ -- default op :: Eq a => a -> a -- Generic default
+ -- No wildcards allowed here
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnDefault',
+ -- 'GHC.Parser.Annotation.AnnDcolon'
+ | ClassOpSig (XClassOpSig pass) Bool [LIdP pass] (LHsSigType pass)
+
+ -- | A type signature in generated code, notably the code
+ -- generated for record selectors. We simply record
+ -- the desired Id itself, replete with its name, type
+ -- and IdDetails. Otherwise it's just like a type
+ -- signature: there should be an accompanying binding
+ | IdSig (XIdSig pass) Id
+
+ -- | An ordinary fixity declaration
+ --
+ -- > infixl 8 ***
+ --
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnInfix',
+ -- 'GHC.Parser.Annotation.AnnVal'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | FixSig (XFixSig pass) (FixitySig pass)
+
+ -- | An inline pragma
+ --
+ -- > {#- INLINE f #-}
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' :
+ -- 'GHC.Parser.Annotation.AnnOpen' @'{-\# INLINE'@ and @'['@,
+ -- 'GHC.Parser.Annotation.AnnClose','GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnVal','GHC.Parser.Annotation.AnnTilde',
+ -- 'GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | InlineSig (XInlineSig pass)
+ (LIdP pass) -- Function name
+ InlinePragma -- Never defaultInlinePragma
+
+ -- | A specialisation pragma
+ --
+ -- > {-# SPECIALISE f :: Int -> Int #-}
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnOpen' @'{-\# SPECIALISE'@ and @'['@,
+ -- 'GHC.Parser.Annotation.AnnTilde',
+ -- 'GHC.Parser.Annotation.AnnVal',
+ -- 'GHC.Parser.Annotation.AnnClose' @']'@ and @'\#-}'@,
+ -- 'GHC.Parser.Annotation.AnnDcolon'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | SpecSig (XSpecSig pass)
+ (LIdP pass) -- Specialise a function or datatype ...
+ [LHsSigType pass] -- ... to these types
+ InlinePragma -- The pragma on SPECIALISE_INLINE form.
+ -- If it's just defaultInlinePragma, then we said
+ -- SPECIALISE, not SPECIALISE_INLINE
+
+ -- | A specialisation pragma for instance declarations only
+ --
+ -- > {-# SPECIALISE instance Eq [Int] #-}
+ --
+ -- (Class tys); should be a specialisation of the
+ -- current instance declaration
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnInstance','GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | SpecInstSig (XSpecInstSig pass) SourceText (LHsSigType pass)
+ -- Note [Pragma source text] in GHC.Types.SourceText
+
+ -- | A minimal complete definition pragma
+ --
+ -- > {-# MINIMAL a | (b, c | (d | e)) #-}
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnVbar','GHC.Parser.Annotation.AnnComma',
+ -- 'GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | MinimalSig (XMinimalSig pass)
+ SourceText (LBooleanFormula (LIdP pass))
+ -- Note [Pragma source text] in GHC.Types.SourceText
+
+ -- | A "set cost centre" pragma for declarations
+ --
+ -- > {-# SCC funName #-}
+ --
+ -- or
+ --
+ -- > {-# SCC funName "cost_centre_name" #-}
+
+ | SCCFunSig (XSCCFunSig pass)
+ SourceText -- Note [Pragma source text] in GHC.Types.SourceText
+ (LIdP pass) -- Function name
+ (Maybe (XRec pass StringLiteral))
+ -- | A complete match pragma
+ --
+ -- > {-# COMPLETE C, D [:: T] #-}
+ --
+ -- Used to inform the pattern match checker about additional
+ -- complete matchings which, for example, arise from pattern
+ -- synonym definitions.
+ | CompleteMatchSig (XCompleteMatchSig pass)
+ SourceText
+ (XRec pass [LIdP pass])
+ (Maybe (LIdP pass))
+ | XSig !(XXSig pass)
+
+-- | Located Fixity Signature
+type LFixitySig pass = XRec pass (FixitySig pass)
+
+-- | Fixity Signature
+data FixitySig pass = FixitySig (XFixitySig pass) [LIdP pass] Fixity
+ | XFixitySig !(XXFixitySig pass)
+
+-- | Type checker Specialisation Pragmas
+--
+-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer
+data TcSpecPrags
+ = IsDefaultMethod -- ^ Super-specialised: a default method should
+ -- be macro-expanded at every call site
+ | SpecPrags [LTcSpecPrag]
+ deriving Data
+
+-- | Located Type checker Specification Pragmas
+type LTcSpecPrag = Located TcSpecPrag
+
+-- | Type checker Specification Pragma
+data TcSpecPrag
+ = SpecPrag
+ Id
+ HsWrapper
+ InlinePragma
+ -- ^ The Id to be specialised, a wrapper that specialises the
+ -- polymorphic function, and inlining spec for the specialised function
+ deriving Data
+
+noSpecPrags :: TcSpecPrags
+noSpecPrags = SpecPrags []
+
+hasSpecPrags :: TcSpecPrags -> Bool
+hasSpecPrags (SpecPrags ps) = not (null ps)
+hasSpecPrags IsDefaultMethod = False
+
+isDefaultMethod :: TcSpecPrags -> Bool
+isDefaultMethod IsDefaultMethod = True
+isDefaultMethod (SpecPrags {}) = False
+
+isFixityLSig :: forall p. UnXRec p => LSig p -> Bool
+isFixityLSig (unXRec @p -> FixSig {}) = True
+isFixityLSig _ = False
+
+isTypeLSig :: forall p. UnXRec p => LSig p -> Bool -- Type signatures
+isTypeLSig (unXRec @p -> TypeSig {}) = True
+isTypeLSig (unXRec @p -> ClassOpSig {}) = True
+isTypeLSig (unXRec @p -> IdSig {}) = True
+isTypeLSig _ = False
+
+isSpecLSig :: forall p. UnXRec p => LSig p -> Bool
+isSpecLSig (unXRec @p -> SpecSig {}) = True
+isSpecLSig _ = False
+
+isSpecInstLSig :: forall p. UnXRec p => LSig p -> Bool
+isSpecInstLSig (unXRec @p -> SpecInstSig {}) = True
+isSpecInstLSig _ = False
+
+isPragLSig :: forall p. UnXRec p => LSig p -> Bool
+-- Identifies pragmas
+isPragLSig (unXRec @p -> SpecSig {}) = True
+isPragLSig (unXRec @p -> InlineSig {}) = True
+isPragLSig (unXRec @p -> SCCFunSig {}) = True
+isPragLSig (unXRec @p -> CompleteMatchSig {}) = True
+isPragLSig _ = False
+
+isInlineLSig :: forall p. UnXRec p => LSig p -> Bool
+-- Identifies inline pragmas
+isInlineLSig (unXRec @p -> InlineSig {}) = True
+isInlineLSig _ = False
+
+isMinimalLSig :: forall p. UnXRec p => LSig p -> Bool
+isMinimalLSig (unXRec @p -> MinimalSig {}) = True
+isMinimalLSig _ = False
+
+isSCCFunSig :: forall p. UnXRec p => LSig p -> Bool
+isSCCFunSig (unXRec @p -> SCCFunSig {}) = True
+isSCCFunSig _ = False
+
+isCompleteMatchSig :: forall p. UnXRec p => LSig p -> Bool
+isCompleteMatchSig (unXRec @p -> CompleteMatchSig {} ) = True
+isCompleteMatchSig _ = False
+
+hsSigDoc :: Sig name -> SDoc
+hsSigDoc (TypeSig {}) = text "type signature"
+hsSigDoc (PatSynSig {}) = text "pattern synonym signature"
+hsSigDoc (ClassOpSig _ is_deflt _ _)
+ | is_deflt = text "default type signature"
+ | otherwise = text "class method signature"
+hsSigDoc (IdSig {}) = text "id signature"
+hsSigDoc (SpecSig _ _ _ inl)
+ = ppr inl <+> text "pragma"
+hsSigDoc (InlineSig _ _ prag) = ppr (inlinePragmaSpec prag) <+> text "pragma"
+hsSigDoc (SpecInstSig _ src _)
+ = pprWithSourceText src empty <+> text "instance pragma"
+hsSigDoc (FixSig {}) = text "fixity declaration"
+hsSigDoc (MinimalSig {}) = text "MINIMAL pragma"
+hsSigDoc (SCCFunSig {}) = text "SCC pragma"
+hsSigDoc (CompleteMatchSig {}) = text "COMPLETE pragma"
+hsSigDoc (XSig {}) = text "XSIG TTG extension"
+
+{-
+************************************************************************
+* *
+\subsection[PatSynBind]{A pattern synonym definition}
+* *
+************************************************************************
+-}
+
+-- | Haskell Pattern Synonym Details
+type HsPatSynDetails pass = HsConDetails Void (LIdP pass) [RecordPatSynField pass]
+
+-- See Note [Record PatSyn Fields]
+-- | Record Pattern Synonym Field
+data RecordPatSynField pass
+ = RecordPatSynField
+ { recordPatSynField :: FieldOcc pass
+ -- ^ Field label visible in rest of the file
+ , recordPatSynPatVar :: LIdP pass
+ -- ^ Filled in by renamer, the name used internally by the pattern
+ }
+
+
+{-
+Note [Record PatSyn Fields]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Consider the following two pattern synonyms.
+
+ pattern P x y = ([x,True], [y,'v'])
+ pattern Q{ x, y } =([x,True], [y,'v'])
+
+In P, we just have two local binders, x and y.
+
+In Q, we have local binders but also top-level record selectors
+ x :: ([Bool], [Char]) -> Bool
+ y :: ([Bool], [Char]) -> Char
+
+Both are recorded in the `RecordPatSynField`s for `x` and `y`:
+* recordPatSynField: the top-level record selector
+* recordPatSynPatVar: the local `x`, bound only in the RHS of the pattern synonym.
+
+It would make sense to support record-like syntax
+
+ pattern Q{ x=x1, y=y1 } = ([x1,True], [y1,'v'])
+
+when we have a different name for the local and top-level binder,
+making the distinction between the two names clear.
+
+-}
+instance Outputable (RecordPatSynField a) where
+ ppr (RecordPatSynField { recordPatSynField = v }) = ppr v
+
+
+-- | Haskell Pattern Synonym Direction
+data HsPatSynDir id
+ = Unidirectional
+ | ImplicitBidirectional
+ | ExplicitBidirectional (MatchGroup id (LHsExpr id))
diff --git a/compiler/Language/Haskell/Syntax/Decls.hs b/compiler/Language/Haskell/Syntax/Decls.hs
new file mode 100644
index 0000000000..ff65d085c7
--- /dev/null
+++ b/compiler/Language/Haskell/Syntax/Decls.hs
@@ -0,0 +1,1804 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow]
+ -- in module Language.Haskell.Syntax.Extension
+
+{-
+(c) The University of Glasgow 2006
+(c) The GRASP/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.
+--
+-- Definitions for: @SynDecl@ and @ConDecl@, @ClassDecl@,
+-- @InstDecl@, @DefaultDecl@ and @ForeignDecl@.
+module Language.Haskell.Syntax.Decls (
+ -- * Toplevel declarations
+ HsDecl(..), LHsDecl, HsDataDefn(..), HsDeriving, LHsFunDep,
+ HsDerivingClause(..), LHsDerivingClause, DerivClauseTys(..), LDerivClauseTys,
+ NewOrData(..), newOrDataToFlavour,
+ StandaloneKindSig(..), LStandaloneKindSig,
+
+ -- ** Class or type declarations
+ TyClDecl(..), LTyClDecl, DataDeclRn(..),
+ TyClGroup(..),
+ tyClGroupTyClDecls, tyClGroupInstDecls, tyClGroupRoleDecls,
+ tyClGroupKindSigs,
+ isClassDecl, isDataDecl, isSynDecl,
+ isFamilyDecl, isTypeFamilyDecl, isDataFamilyDecl,
+ isOpenTypeFamilyInfo, isClosedTypeFamilyInfo,
+ countTyClDecls,
+ tyClDeclTyVars,
+ FamilyDecl(..), LFamilyDecl,
+
+ -- ** Instance declarations
+ InstDecl(..), LInstDecl, FamilyInfo(..), pprFlavour,
+ TyFamInstDecl(..), LTyFamInstDecl,
+ TyFamDefltDecl, LTyFamDefltDecl,
+ DataFamInstDecl(..), LDataFamInstDecl,
+ FamEqn(..), TyFamInstEqn, LTyFamInstEqn, HsTyPats,
+ LClsInstDecl, ClsInstDecl(..),
+
+ -- ** Standalone deriving declarations
+ DerivDecl(..), LDerivDecl,
+ -- ** Deriving strategies
+ DerivStrategy(..), LDerivStrategy,
+ derivStrategyName,
+ -- ** @RULE@ declarations
+ LRuleDecls,RuleDecls(..),RuleDecl(..),LRuleDecl,HsRuleRn(..),
+ RuleBndr(..),LRuleBndr,
+ collectRuleBndrSigTys,
+ pprFullRuleName,
+ -- ** @default@ declarations
+ DefaultDecl(..), LDefaultDecl,
+ -- ** Template haskell declaration splice
+ SpliceExplicitFlag(..),
+ SpliceDecl(..), LSpliceDecl,
+ -- ** Foreign function interface declarations
+ ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..),
+ CImportSpec(..),
+ -- ** Data-constructor declarations
+ ConDecl(..), LConDecl,
+ HsConDeclH98Details, HsConDeclGADTDetails(..),
+ -- ** Document comments
+ DocDecl(..), LDocDecl, docDeclDoc,
+ -- ** Deprecations
+ WarnDecl(..), LWarnDecl,
+ WarnDecls(..), LWarnDecls,
+ -- ** Annotations
+ AnnDecl(..), LAnnDecl,
+ AnnProvenance(..), annProvenanceName_maybe,
+ -- ** Role annotations
+ RoleAnnotDecl(..), LRoleAnnotDecl,
+ -- ** Injective type families
+ FamilyResultSig(..), LFamilyResultSig, InjectivityAnn(..), LInjectivityAnn,
+
+ -- * Grouping
+ HsGroup(..), hsGroupInstDecls,
+ ) where
+
+-- friends:
+import GHC.Prelude
+
+import {-# SOURCE #-} Language.Haskell.Syntax.Expr
+ ( HsExpr, HsSplice )
+ -- Because Expr imports Decls via HsBracket
+
+import Language.Haskell.Syntax.Binds
+import Language.Haskell.Syntax.Type
+import GHC.Hs.Doc
+import GHC.Core.TyCon
+import GHC.Types.Basic
+import GHC.Types.ForeignCall
+import Language.Haskell.Syntax.Extension
+import GHC.Types.Name.Set
+import GHC.Types.Fixity
+
+-- others:
+import GHC.Core.Class
+import GHC.Utils.Outputable
+import GHC.Utils.Misc
+import GHC.Types.SrcLoc
+import GHC.Types.SourceText
+import GHC.Core.Type
+import GHC.Unit.Module.Warnings
+
+import GHC.Data.Maybe
+import Data.Data hiding (TyCon,Fixity, Infix)
+import Data.Void
+
+{-
+************************************************************************
+* *
+\subsection[HsDecl]{Declarations}
+* *
+************************************************************************
+-}
+
+type LHsDecl p = XRec p (HsDecl p)
+ -- ^ When in a list this may have
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnSemi'
+ --
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-- | A Haskell Declaration
+data HsDecl p
+ = TyClD (XTyClD p) (TyClDecl p) -- ^ Type or Class Declaration
+ | InstD (XInstD p) (InstDecl p) -- ^ Instance declaration
+ | DerivD (XDerivD p) (DerivDecl p) -- ^ Deriving declaration
+ | ValD (XValD p) (HsBind p) -- ^ Value declaration
+ | SigD (XSigD p) (Sig p) -- ^ Signature declaration
+ | KindSigD (XKindSigD p) (StandaloneKindSig p) -- ^ Standalone kind signature
+ | DefD (XDefD p) (DefaultDecl p) -- ^ 'default' declaration
+ | ForD (XForD p) (ForeignDecl p) -- ^ Foreign declaration
+ | WarningD (XWarningD p) (WarnDecls p) -- ^ Warning declaration
+ | AnnD (XAnnD p) (AnnDecl p) -- ^ Annotation declaration
+ | RuleD (XRuleD p) (RuleDecls p) -- ^ Rule declaration
+ | SpliceD (XSpliceD p) (SpliceDecl p) -- ^ Splice declaration
+ -- (Includes quasi-quotes)
+ | DocD (XDocD p) (DocDecl) -- ^ Documentation comment declaration
+ | RoleAnnotD (XRoleAnnotD p) (RoleAnnotDecl p) -- ^Role annotation declaration
+ | XHsDecl !(XXHsDecl p)
+
+{-
+Note [Top-level fixity signatures in an HsGroup]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+An `HsGroup p` stores every top-level fixity declarations in one of two places:
+
+1. hs_fixds :: [LFixitySig p]
+
+ This stores fixity signatures for top-level declarations (e.g., functions,
+ data constructors, classes, type families, etc.) as well as fixity
+ signatures for class methods written outside of the class, as in this
+ example:
+
+ infixl 4 `m1`
+ class C1 a where
+ m1 :: a -> a -> a
+
+2. hs_tyclds :: [TyClGroup p]
+
+ Each type class can be found in a TyClDecl inside a TyClGroup, and that
+ TyClDecl stores the fixity signatures for its methods written inside of the
+ class, as in this example:
+
+ class C2 a where
+ infixl 4 `m2`
+ m2 :: a -> a -> a
+
+The story for fixity signatures for class methods is made slightly complicated
+by the fact that they can appear both inside and outside of the class itself,
+and both forms of fixity signatures are considered top-level. This matters
+in `GHC.Rename.Module.rnSrcDecls`, which must create a fixity environment out
+of all top-level fixity signatures before doing anything else. Therefore,
+`rnSrcDecls` must be aware of both (1) and (2) above. The
+`hsGroupTopLevelFixitySigs` function is responsible for collecting this
+information from an `HsGroup`.
+
+One might wonder why we even bother separating top-level fixity signatures
+into two places at all. That is, why not just take the fixity signatures
+from `hs_tyclds` and put them into `hs_fixds` so that they are all in one
+location? This ends up causing problems for `GHC.HsToCore.Quote.repTopDs`,
+which translates each fixity signature in `hs_fixds` and `hs_tyclds` into a
+Template Haskell `Dec`. If there are any duplicate signatures between the two
+fields, this will result in an error (#17608).
+-}
+
+-- | Haskell Group
+--
+-- A 'HsDecl' is categorised into a 'HsGroup' before being
+-- fed to the renamer.
+data HsGroup p
+ = HsGroup {
+ hs_ext :: XCHsGroup p,
+ hs_valds :: HsValBinds p,
+ hs_splcds :: [LSpliceDecl p],
+
+ hs_tyclds :: [TyClGroup p],
+ -- A list of mutually-recursive groups;
+ -- This includes `InstDecl`s as well;
+ -- Parser generates a singleton list;
+ -- renamer does dependency analysis
+
+ hs_derivds :: [LDerivDecl p],
+
+ hs_fixds :: [LFixitySig p],
+ -- A list of fixity signatures defined for top-level
+ -- declarations and class methods (defined outside of the class
+ -- itself).
+ -- See Note [Top-level fixity signatures in an HsGroup]
+
+ hs_defds :: [LDefaultDecl p],
+ hs_fords :: [LForeignDecl p],
+ hs_warnds :: [LWarnDecls p],
+ hs_annds :: [LAnnDecl p],
+ hs_ruleds :: [LRuleDecls p],
+
+ hs_docs :: [LDocDecl]
+ }
+ | XHsGroup !(XXHsGroup p)
+
+
+hsGroupInstDecls :: HsGroup id -> [LInstDecl id]
+hsGroupInstDecls = (=<<) group_instds . hs_tyclds
+
+-- | Located Splice Declaration
+type LSpliceDecl pass = XRec pass (SpliceDecl pass)
+
+-- | Splice Declaration
+data SpliceDecl p
+ = SpliceDecl -- Top level splice
+ (XSpliceDecl p)
+ (XRec p (HsSplice p))
+ SpliceExplicitFlag
+ | XSpliceDecl !(XXSpliceDecl p)
+
+{-
+************************************************************************
+* *
+ Type and class declarations
+* *
+************************************************************************
+
+Note [The Naming story]
+~~~~~~~~~~~~~~~~~~~~~~~
+Here is the story about the implicit names that go with type, class,
+and instance decls. It's a bit tricky, so pay attention!
+
+"Implicit" (or "system") binders
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ Each data type decl defines
+ a worker name for each constructor
+ to-T and from-T convertors
+ Each class decl defines
+ a tycon for the class
+ a data constructor for that tycon
+ the worker for that constructor
+ a selector for each superclass
+
+All have occurrence names that are derived uniquely from their parent
+declaration.
+
+None of these get separate definitions in an interface file; they are
+fully defined by the data or class decl. But they may *occur* in
+interface files, of course. Any such occurrence must haul in the
+relevant type or class decl.
+
+Plan of attack:
+ - Ensure they "point to" the parent data/class decl
+ when loading that decl from an interface file
+ (See RnHiFiles.getSysBinders)
+
+ - When typechecking the decl, we build the implicit TyCons and Ids.
+ When doing so we look them up in the name cache (GHC.Rename.Env.lookupSysName),
+ to ensure correct module and provenance is set
+
+These are the two places that we have to conjure up the magic derived
+names. (The actual magic is in GHC.Types.Name.Occurrence.mkWorkerOcc, etc.)
+
+Default methods
+~~~~~~~~~~~~~~~
+ - Occurrence name is derived uniquely from the method name
+ E.g. $dmmax
+
+ - If there is a default method name at all, it's recorded in
+ the ClassOpSig (in GHC.Hs.Binds), in the DefMethInfo field.
+ (DefMethInfo is defined in GHC.Core.Class)
+
+Source-code class decls and interface-code class decls are treated subtly
+differently, which has given me a great deal of confusion over the years.
+Here's the deal. (We distinguish the two cases because source-code decls
+have (Just binds) in the tcdMeths field, whereas interface decls have Nothing.
+
+In *source-code* class declarations:
+
+ - When parsing, every ClassOpSig gets a DefMeth with a suitable RdrName
+ This is done by GHC.Parser.PostProcess.mkClassOpSigDM
+
+ - The renamer renames it to a Name
+
+ - During typechecking, we generate a binding for each $dm for
+ which there's a programmer-supplied default method:
+ class Foo a where
+ op1 :: <type>
+ op2 :: <type>
+ op1 = ...
+ We generate a binding for $dmop1 but not for $dmop2.
+ The Class for Foo has a Nothing for op2 and
+ a Just ($dm_op1, VanillaDM) for op1.
+ The Name for $dmop2 is simply discarded.
+
+In *interface-file* class declarations:
+ - When parsing, we see if there's an explicit programmer-supplied default method
+ because there's an '=' sign to indicate it:
+ class Foo a where
+ op1 = :: <type> -- NB the '='
+ op2 :: <type>
+ We use this info to generate a DefMeth with a suitable RdrName for op1,
+ and a NoDefMeth for op2
+ - The interface file has a separate definition for $dmop1, with unfolding etc.
+ - The renamer renames it to a Name.
+ - The renamer treats $dmop1 as a free variable of the declaration, so that
+ the binding for $dmop1 will be sucked in. (See RnHsSyn.tyClDeclFVs)
+ This doesn't happen for source code class decls, because they *bind* the default method.
+
+Dictionary functions
+~~~~~~~~~~~~~~~~~~~~
+Each instance declaration gives rise to one dictionary function binding.
+
+The type checker makes up new source-code instance declarations
+(e.g. from 'deriving' or generic default methods --- see
+GHC.Tc.TyCl.Instance.tcInstDecls1). So we can't generate the names for
+dictionary functions in advance (we don't know how many we need).
+
+On the other hand for interface-file instance declarations, the decl
+specifies the name of the dictionary function, and it has a binding elsewhere
+in the interface file:
+ instance {Eq Int} = dEqInt
+ dEqInt :: {Eq Int} <pragma info>
+
+So again we treat source code and interface file code slightly differently.
+
+Source code:
+ - Source code instance decls have a Nothing in the (Maybe name) field
+ (see data InstDecl below)
+
+ - The typechecker makes up a Local name for the dict fun for any source-code
+ instance decl, whether it comes from a source-code instance decl, or whether
+ the instance decl is derived from some other construct (e.g. 'deriving').
+
+ - The occurrence name it chooses is derived from the instance decl (just for
+ documentation really) --- e.g. dNumInt. Two dict funs may share a common
+ occurrence name, but will have different uniques. E.g.
+ instance Foo [Int] where ...
+ instance Foo [Bool] where ...
+ These might both be dFooList
+
+ - The CoreTidy phase externalises the name, and ensures the occurrence name is
+ unique (this isn't special to dict funs). So we'd get dFooList and dFooList1.
+
+ - We can take this relaxed approach (changing the occurrence name later)
+ because dict fun Ids are not captured in a TyCon or Class (unlike default
+ methods, say). Instead, they are kept separately in the InstEnv. This
+ makes it easy to adjust them after compiling a module. (Once we've finished
+ compiling that module, they don't change any more.)
+
+
+Interface file code:
+ - The instance decl gives the dict fun name, so the InstDecl has a (Just name)
+ in the (Maybe name) field.
+
+ - RnHsSyn.instDeclFVs treats the dict fun name as free in the decl, so that we
+ suck in the dfun binding
+-}
+
+-- | Located Declaration of a Type or Class
+type LTyClDecl pass = XRec pass (TyClDecl pass)
+
+-- | A type or class declaration.
+data TyClDecl pass
+ = -- | @type/data family T :: *->*@
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnType',
+ -- 'GHC.Parser.Annotation.AnnData',
+ -- 'GHC.Parser.Annotation.AnnFamily','GHC.Parser.Annotation.AnnDcolon',
+ -- 'GHC.Parser.Annotation.AnnWhere','GHC.Parser.Annotation.AnnOpenP',
+ -- 'GHC.Parser.Annotation.AnnDcolon','GHC.Parser.Annotation.AnnCloseP',
+ -- 'GHC.Parser.Annotation.AnnEqual','GHC.Parser.Annotation.AnnRarrow',
+ -- 'GHC.Parser.Annotation.AnnVbar'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ FamDecl { tcdFExt :: XFamDecl pass, tcdFam :: FamilyDecl pass }
+
+ | -- | @type@ declaration
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnType',
+ -- 'GHC.Parser.Annotation.AnnEqual',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ SynDecl { tcdSExt :: XSynDecl pass -- ^ Post renameer, FVs
+ , tcdLName :: LIdP pass -- ^ Type constructor
+ , tcdTyVars :: LHsQTyVars pass -- ^ Type variables; for an
+ -- associated type these
+ -- include outer binders
+ , tcdFixity :: LexicalFixity -- ^ Fixity used in the declaration
+ , tcdRhs :: LHsType pass } -- ^ RHS of type declaration
+
+ | -- | @data@ declaration
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnData',
+ -- 'GHC.Parser.Annotation.AnnFamily',
+ -- 'GHC.Parser.Annotation.AnnNewType',
+ -- 'GHC.Parser.Annotation.AnnNewType','GHC.Parser.Annotation.AnnDcolon'
+ -- 'GHC.Parser.Annotation.AnnWhere',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ DataDecl { tcdDExt :: XDataDecl pass -- ^ Post renamer, CUSK flag, FVs
+ , tcdLName :: LIdP pass -- ^ Type constructor
+ , tcdTyVars :: LHsQTyVars pass -- ^ Type variables
+ -- See Note [TyVar binders for associated declarations]
+ , tcdFixity :: LexicalFixity -- ^ Fixity used in the declaration
+ , tcdDataDefn :: HsDataDefn pass }
+
+ | ClassDecl { tcdCExt :: XClassDecl pass, -- ^ Post renamer, FVs
+ tcdCtxt :: LHsContext pass, -- ^ Context...
+ tcdLName :: LIdP pass, -- ^ Name of the class
+ tcdTyVars :: LHsQTyVars pass, -- ^ Class type variables
+ tcdFixity :: LexicalFixity, -- ^ Fixity used in the declaration
+ tcdFDs :: [LHsFunDep pass], -- ^ Functional deps
+ tcdSigs :: [LSig pass], -- ^ Methods' signatures
+ tcdMeths :: LHsBinds pass, -- ^ Default methods
+ tcdATs :: [LFamilyDecl pass], -- ^ Associated types;
+ tcdATDefs :: [LTyFamDefltDecl pass], -- ^ Associated type defaults
+ tcdDocs :: [LDocDecl] -- ^ Haddock docs
+ }
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnClass',
+ -- 'GHC.Parser.Annotation.AnnWhere','GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnClose'
+ -- - The tcdFDs will have 'GHC.Parser.Annotation.AnnVbar',
+ -- 'GHC.Parser.Annotation.AnnComma'
+ -- 'GHC.Parser.Annotation.AnnRarrow'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | XTyClDecl !(XXTyClDecl pass)
+
+type LHsFunDep pass = XRec pass (FunDep (LIdP pass))
+
+data DataDeclRn = DataDeclRn
+ { tcdDataCusk :: Bool -- ^ does this have a CUSK?
+ -- See Note [CUSKs: complete user-supplied kind signatures]
+ , tcdFVs :: NameSet }
+ deriving Data
+
+{- Note [TyVar binders for associated decls]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+For an /associated/ data, newtype, or type-family decl, the LHsQTyVars
+/includes/ outer binders. For example
+ class T a where
+ data D a c
+ type F a b :: *
+ type F a b = a -> a
+Here the data decl for 'D', and type-family decl for 'F', both include 'a'
+in their LHsQTyVars (tcdTyVars and fdTyVars resp).
+
+Ditto any implicit binders in the hsq_implicit field of the LHSQTyVars.
+
+The idea is that the associated type is really a top-level decl in its
+own right. However we are careful to use the same name 'a', so that
+we can match things up.
+
+c.f. Note [Associated type tyvar names] in GHC.Core.Class
+ Note [Family instance declaration binders]
+-}
+
+{- Note [Class LayoutInfo]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+The LayoutInfo is used to associate Haddock comments with parts of the declaration.
+Compare the following examples:
+
+ class C a where
+ f :: a -> Int
+ -- ^ comment on f
+
+ class C a where
+ f :: a -> Int
+ -- ^ comment on C
+
+Notice how "comment on f" and "comment on C" differ only by indentation level.
+Thus we have to record the indentation level of the class declarations.
+
+See also Note [Adding Haddock comments to the syntax tree] in GHC.Parser.PostProcess.Haddock
+-}
+
+-- Simple classifiers for TyClDecl
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+-- | @True@ <=> argument is a @data@\/@newtype@
+-- declaration.
+isDataDecl :: TyClDecl pass -> Bool
+isDataDecl (DataDecl {}) = True
+isDataDecl _other = False
+
+-- | type or type instance declaration
+isSynDecl :: TyClDecl pass -> Bool
+isSynDecl (SynDecl {}) = True
+isSynDecl _other = False
+
+-- | type class
+isClassDecl :: TyClDecl pass -> Bool
+isClassDecl (ClassDecl {}) = True
+isClassDecl _ = False
+
+-- | type/data family declaration
+isFamilyDecl :: TyClDecl pass -> Bool
+isFamilyDecl (FamDecl {}) = True
+isFamilyDecl _other = False
+
+-- | type family declaration
+isTypeFamilyDecl :: TyClDecl pass -> Bool
+isTypeFamilyDecl (FamDecl _ (FamilyDecl { fdInfo = info })) = case info of
+ OpenTypeFamily -> True
+ ClosedTypeFamily {} -> True
+ _ -> False
+isTypeFamilyDecl _ = False
+
+-- | open type family info
+isOpenTypeFamilyInfo :: FamilyInfo pass -> Bool
+isOpenTypeFamilyInfo OpenTypeFamily = True
+isOpenTypeFamilyInfo _ = False
+
+-- | closed type family info
+isClosedTypeFamilyInfo :: FamilyInfo pass -> Bool
+isClosedTypeFamilyInfo (ClosedTypeFamily {}) = True
+isClosedTypeFamilyInfo _ = False
+
+-- | data family declaration
+isDataFamilyDecl :: TyClDecl pass -> Bool
+isDataFamilyDecl (FamDecl _ (FamilyDecl { fdInfo = DataFamily })) = True
+isDataFamilyDecl _other = False
+
+-- Dealing with names
+
+tyClDeclTyVars :: TyClDecl pass -> LHsQTyVars pass
+tyClDeclTyVars (FamDecl { tcdFam = FamilyDecl { fdTyVars = tvs } }) = tvs
+tyClDeclTyVars d = tcdTyVars d
+
+countTyClDecls :: [TyClDecl pass] -> (Int, Int, Int, Int, Int)
+ -- class, synonym decls, data, newtype, family decls
+countTyClDecls decls
+ = (count isClassDecl decls,
+ count isSynDecl decls, -- excluding...
+ count isDataTy decls, -- ...family...
+ count isNewTy decls, -- ...instances
+ count isFamilyDecl decls)
+ where
+ isDataTy DataDecl{ tcdDataDefn = HsDataDefn { dd_ND = DataType } } = True
+ isDataTy _ = False
+
+ isNewTy DataDecl{ tcdDataDefn = HsDataDefn { dd_ND = NewType } } = True
+ isNewTy _ = False
+
+
+{- Note [CUSKs: complete user-supplied kind signatures]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We kind-check declarations differently if they have a complete, user-supplied
+kind signature (CUSK). This is because we can safely generalise a CUSKed
+declaration before checking all of the others, supporting polymorphic recursion.
+See https://gitlab.haskell.org/ghc/ghc/wikis/ghc-kinds/kind-inference#proposed-new-strategy
+and #9200 for lots of discussion of how we got here.
+
+The detection of CUSKs is enabled by the -XCUSKs extension, switched on by default.
+Under -XNoCUSKs, all declarations are treated as if they have no CUSK.
+See https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0036-kind-signatures.rst
+
+PRINCIPLE:
+ a type declaration has a CUSK iff we could produce a separate kind signature
+ for it, just like a type signature for a function,
+ looking only at the header of the declaration.
+
+Examples:
+ * data T1 (a :: *->*) (b :: *) = ....
+ -- Has CUSK; equivalant to T1 :: (*->*) -> * -> *
+
+ * data T2 a b = ...
+ -- No CUSK; we do not want to guess T2 :: * -> * -> *
+ -- because the full decl might be data T a b = MkT (a b)
+
+ * data T3 (a :: k -> *) (b :: *) = ...
+ -- CUSK; equivalent to T3 :: (k -> *) -> * -> *
+ -- We lexically generalise over k to get
+ -- T3 :: forall k. (k -> *) -> * -> *
+ -- The generalisation is here is purely lexical, just like
+ -- f3 :: a -> a
+ -- means
+ -- f3 :: forall a. a -> a
+
+ * data T4 (a :: j k) = ...
+ -- CUSK; equivalent to T4 :: j k -> *
+ -- which we lexically generalise to T4 :: forall j k. j k -> *
+ -- and then, if PolyKinds is on, we further generalise to
+ -- T4 :: forall kk (j :: kk -> *) (k :: kk). j k -> *
+ -- Again this is exactly like what happens as the term level
+ -- when you write
+ -- f4 :: forall a b. a b -> Int
+
+NOTE THAT
+ * A CUSK does /not/ mean that everything about the kind signature is
+ fully specified by the user. Look at T4 and f4: we had to do kind
+ inference to figure out the kind-quantification. But in both cases
+ (T4 and f4) that inference is done looking /only/ at the header of T4
+ (or signature for f4), not at the definition thereof.
+
+ * The CUSK completely fixes the kind of the type constructor, forever.
+
+ * The precise rules, for each declaration form, for whether a declaration
+ has a CUSK are given in the user manual section "Complete user-supplied
+ kind signatures and polymorphic recursion". But they simply implement
+ PRINCIPLE above.
+
+ * Open type families are interesting:
+ type family T5 a b :: *
+ There simply /is/ no accompanying declaration, so that info is all
+ we'll ever get. So we it has a CUSK by definition, and we default
+ any un-fixed kind variables to *.
+
+ * Associated types are a bit tricker:
+ class C6 a where
+ type family T6 a b :: *
+ op :: a Int -> Int
+ Here C6 does not have a CUSK (in fact we ultimately discover that
+ a :: * -> *). And hence neither does T6, the associated family,
+ because we can't fix its kind until we have settled C6. Another
+ way to say it: unlike a top-level, we /may/ discover more about
+ a's kind from C6's definition.
+
+ * A data definition with a top-level :: must explicitly bind all
+ kind variables to the right of the ::. See test
+ dependent/should_compile/KindLevels, which requires this
+ case. (Naturally, any kind variable mentioned before the :: should
+ not be bound after it.)
+
+ This last point is much more debatable than the others; see
+ #15142 comment:22
+
+ Because this is fiddly to check, there is a field in the DataDeclRn
+ structure (included in a DataDecl after the renamer) that stores whether
+ or not the declaration has a CUSK.
+-}
+
+
+{- *********************************************************************
+* *
+ TyClGroup
+ Strongly connected components of
+ type, class, instance, and role declarations
+* *
+********************************************************************* -}
+
+{- Note [TyClGroups and dependency analysis]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A TyClGroup represents a strongly connected components of type/class/instance
+decls, together with the role annotations for the type/class declarations.
+
+The hs_tyclds :: [TyClGroup] field of a HsGroup is a dependency-order
+sequence of strongly-connected components.
+
+Invariants
+ * The type and class declarations, group_tyclds, may depend on each
+ other, or earlier TyClGroups, but not on later ones
+
+ * The role annotations, group_roles, are role-annotations for some or
+ all of the types and classes in group_tyclds (only).
+
+ * The instance declarations, group_instds, may (and usually will)
+ depend on group_tyclds, or on earlier TyClGroups, but not on later
+ ones.
+
+See Note [Dependency analysis of type, class, and instance decls]
+in GHC.Rename.Module for more info.
+-}
+
+-- | Type or Class Group
+data TyClGroup pass -- See Note [TyClGroups and dependency analysis]
+ = TyClGroup { group_ext :: XCTyClGroup pass
+ , group_tyclds :: [LTyClDecl pass]
+ , group_roles :: [LRoleAnnotDecl pass]
+ , group_kisigs :: [LStandaloneKindSig pass]
+ , group_instds :: [LInstDecl pass] }
+ | XTyClGroup !(XXTyClGroup pass)
+
+
+tyClGroupTyClDecls :: [TyClGroup pass] -> [LTyClDecl pass]
+tyClGroupTyClDecls = concatMap group_tyclds
+
+tyClGroupInstDecls :: [TyClGroup pass] -> [LInstDecl pass]
+tyClGroupInstDecls = concatMap group_instds
+
+tyClGroupRoleDecls :: [TyClGroup pass] -> [LRoleAnnotDecl pass]
+tyClGroupRoleDecls = concatMap group_roles
+
+tyClGroupKindSigs :: [TyClGroup pass] -> [LStandaloneKindSig pass]
+tyClGroupKindSigs = concatMap group_kisigs
+
+
+{- *********************************************************************
+* *
+ Data and type family declarations
+* *
+********************************************************************* -}
+
+{- Note [FamilyResultSig]
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This data type represents the return signature of a type family. Possible
+values are:
+
+ * NoSig - the user supplied no return signature:
+ type family Id a where ...
+
+ * KindSig - the user supplied the return kind:
+ type family Id a :: * where ...
+
+ * TyVarSig - user named the result with a type variable and possibly
+ provided a kind signature for that variable:
+ type family Id a = r where ...
+ type family Id a = (r :: *) where ...
+
+ Naming result of a type family is required if we want to provide
+ injectivity annotation for a type family:
+ type family Id a = r | r -> a where ...
+
+See also: Note [Injectivity annotation]
+
+Note [Injectivity annotation]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A user can declare a type family to be injective:
+
+ type family Id a = r | r -> a where ...
+
+ * The part after the "|" is called "injectivity annotation".
+ * "r -> a" part is called "injectivity condition"; at the moment terms
+ "injectivity annotation" and "injectivity condition" are synonymous
+ because we only allow a single injectivity condition.
+ * "r" is the "LHS of injectivity condition". LHS can only contain the
+ variable naming the result of a type family.
+
+ * "a" is the "RHS of injectivity condition". RHS contains space-separated
+ type and kind variables representing the arguments of a type
+ family. Variables can be omitted if a type family is not injective in
+ these arguments. Example:
+ type family Foo a b c = d | d -> a c where ...
+
+Note that:
+ (a) naming of type family result is required to provide injectivity
+ annotation
+ (b) for associated types if the result was named then injectivity annotation
+ is mandatory. Otherwise result type variable is indistinguishable from
+ associated type default.
+
+It is possible that in the future this syntax will be extended to support
+more complicated injectivity annotations. For example we could declare that
+if we know the result of Plus and one of its arguments we can determine the
+other argument:
+
+ type family Plus a b = (r :: Nat) | r a -> b, r b -> a where ...
+
+Here injectivity annotation would consist of two comma-separated injectivity
+conditions.
+
+See also Note [Injective type families] in GHC.Core.TyCon
+-}
+
+-- | Located type Family Result Signature
+type LFamilyResultSig pass = XRec pass (FamilyResultSig pass)
+
+-- | type Family Result Signature
+data FamilyResultSig pass = -- see Note [FamilyResultSig]
+ NoSig (XNoSig pass)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' :
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | KindSig (XCKindSig pass) (LHsKind pass)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' :
+ -- 'GHC.Parser.Annotation.AnnOpenP','GHC.Parser.Annotation.AnnDcolon',
+ -- 'GHC.Parser.Annotation.AnnCloseP'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | TyVarSig (XTyVarSig pass) (LHsTyVarBndr () pass)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' :
+ -- 'GHC.Parser.Annotation.AnnOpenP','GHC.Parser.Annotation.AnnDcolon',
+ -- 'GHC.Parser.Annotation.AnnCloseP', 'GHC.Parser.Annotation.AnnEqual'
+ | XFamilyResultSig !(XXFamilyResultSig pass)
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+
+-- | Located type Family Declaration
+type LFamilyDecl pass = XRec pass (FamilyDecl pass)
+
+-- | type Family Declaration
+data FamilyDecl pass = FamilyDecl
+ { fdExt :: XCFamilyDecl pass
+ , fdInfo :: FamilyInfo pass -- type/data, closed/open
+ , fdLName :: LIdP pass -- type constructor
+ , fdTyVars :: LHsQTyVars pass -- type variables
+ -- See Note [TyVar binders for associated declarations]
+ , fdFixity :: LexicalFixity -- Fixity used in the declaration
+ , fdResultSig :: LFamilyResultSig pass -- result signature
+ , fdInjectivityAnn :: Maybe (LInjectivityAnn pass) -- optional injectivity ann
+ }
+ | XFamilyDecl !(XXFamilyDecl pass)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnType',
+ -- 'GHC.Parser.Annotation.AnnData', 'GHC.Parser.Annotation.AnnFamily',
+ -- 'GHC.Parser.Annotation.AnnWhere', 'GHC.Parser.Annotation.AnnOpenP',
+ -- 'GHC.Parser.Annotation.AnnDcolon', 'GHC.Parser.Annotation.AnnCloseP',
+ -- 'GHC.Parser.Annotation.AnnEqual', 'GHC.Parser.Annotation.AnnRarrow',
+ -- 'GHC.Parser.Annotation.AnnVbar'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+
+-- | Located Injectivity Annotation
+type LInjectivityAnn pass = XRec pass (InjectivityAnn pass)
+
+-- | If the user supplied an injectivity annotation it is represented using
+-- InjectivityAnn. At the moment this is a single injectivity condition - see
+-- Note [Injectivity annotation]. `Located name` stores the LHS of injectivity
+-- condition. `[Located name]` stores the RHS of injectivity condition. Example:
+--
+-- type family Foo a b c = r | r -> a c where ...
+--
+-- This will be represented as "InjectivityAnn `r` [`a`, `c`]"
+data InjectivityAnn pass
+ = InjectivityAnn (LIdP pass) [LIdP pass]
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' :
+ -- 'GHC.Parser.Annotation.AnnRarrow', 'GHC.Parser.Annotation.AnnVbar'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+data FamilyInfo pass
+ = DataFamily
+ | OpenTypeFamily
+ -- | 'Nothing' if we're in an hs-boot file and the user
+ -- said "type family Foo x where .."
+ | ClosedTypeFamily (Maybe [LTyFamInstEqn pass])
+
+
+------------- Pretty printing FamilyDecls -----------
+
+pprFlavour :: FamilyInfo pass -> SDoc
+pprFlavour DataFamily = text "data"
+pprFlavour OpenTypeFamily = text "type"
+pprFlavour (ClosedTypeFamily {}) = text "type"
+
+instance Outputable (FamilyInfo pass) where
+ ppr info = pprFlavour info <+> text "family"
+
+
+
+{- *********************************************************************
+* *
+ Data types and data constructors
+* *
+********************************************************************* -}
+
+-- | Haskell Data type Definition
+data HsDataDefn pass -- The payload of a data type defn
+ -- Used *both* for vanilla data declarations,
+ -- *and* for data family instances
+ = -- | Declares a data type or newtype, giving its constructors
+ -- @
+ -- data/newtype T a = <constrs>
+ -- data/newtype instance T [a] = <constrs>
+ -- @
+ HsDataDefn { dd_ext :: XCHsDataDefn pass,
+ dd_ND :: NewOrData,
+ dd_ctxt :: LHsContext pass, -- ^ Context
+ dd_cType :: Maybe (XRec pass CType),
+ dd_kindSig:: Maybe (LHsKind pass),
+ -- ^ Optional kind signature.
+ --
+ -- @(Just k)@ for a GADT-style @data@,
+ -- or @data instance@ decl, with explicit kind sig
+ --
+ -- Always @Nothing@ for H98-syntax decls
+
+ dd_cons :: [LConDecl pass],
+ -- ^ Data constructors
+ --
+ -- For @data T a = T1 | T2 a@
+ -- the 'LConDecl's all have 'ConDeclH98'.
+ -- For @data T a where { T1 :: T a }@
+ -- the 'LConDecls' all have 'ConDeclGADT'.
+
+ dd_derivs :: HsDeriving pass -- ^ Optional 'deriving' clause
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ }
+ | XHsDataDefn !(XXHsDataDefn pass)
+
+-- | Haskell Deriving clause
+type HsDeriving pass = XRec pass [LHsDerivingClause pass]
+ -- ^ The optional @deriving@ clauses of a data declaration. "Clauses" is
+ -- plural because one can specify multiple deriving clauses using the
+ -- @-XDerivingStrategies@ language extension.
+ --
+ -- The list of 'LHsDerivingClause's corresponds to exactly what the user
+ -- requested to derive, in order. If no deriving clauses were specified,
+ -- the list is empty.
+
+type LHsDerivingClause pass = XRec pass (HsDerivingClause pass)
+
+-- | A single @deriving@ clause of a data declaration.
+--
+-- - 'GHC.Parser.Annotation.AnnKeywordId' :
+-- 'GHC.Parser.Annotation.AnnDeriving', 'GHC.Parser.Annotation.AnnStock',
+-- 'GHC.Parser.Annotation.AnnAnyClass', 'Api.AnnNewtype',
+-- 'GHC.Parser.Annotation.AnnOpen','GHC.Parser.Annotation.AnnClose'
+data HsDerivingClause pass
+ -- See Note [Deriving strategies] in GHC.Tc.Deriv
+ = HsDerivingClause
+ { deriv_clause_ext :: XCHsDerivingClause pass
+ , deriv_clause_strategy :: Maybe (LDerivStrategy pass)
+ -- ^ The user-specified strategy (if any) to use when deriving
+ -- 'deriv_clause_tys'.
+ , deriv_clause_tys :: LDerivClauseTys pass
+ -- ^ The types to derive.
+ }
+ | XHsDerivingClause !(XXHsDerivingClause pass)
+
+type LDerivClauseTys pass = XRec pass (DerivClauseTys pass)
+
+-- | The types mentioned in a single @deriving@ clause. This can come in two
+-- forms, 'DctSingle' or 'DctMulti', depending on whether the types are
+-- surrounded by enclosing parentheses or not. These parentheses are
+-- semantically differnt than 'HsParTy'. For example, @deriving ()@ means
+-- \"derive zero classes\" rather than \"derive an instance of the 0-tuple\".
+--
+-- 'DerivClauseTys' use 'LHsSigType' because @deriving@ clauses can mention
+-- type variables that aren't bound by the datatype, e.g.
+--
+-- > data T b = ... deriving (C [a])
+--
+-- should produce a derived instance for @C [a] (T b)@.
+data DerivClauseTys pass
+ = -- | A @deriving@ clause with a single type. Moreover, that type can only
+ -- be a type constructor without any arguments.
+ --
+ -- Example: @deriving Eq@
+ DctSingle (XDctSingle pass) (LHsSigType pass)
+
+ -- | A @deriving@ clause with a comma-separated list of types, surrounded
+ -- by enclosing parentheses.
+ --
+ -- Example: @deriving (Eq, C a)@
+ | DctMulti (XDctMulti pass) [LHsSigType pass]
+
+ | XDerivClauseTys !(XXDerivClauseTys pass)
+
+-- | Located Standalone Kind Signature
+type LStandaloneKindSig pass = XRec pass (StandaloneKindSig pass)
+
+data StandaloneKindSig pass
+ = StandaloneKindSig (XStandaloneKindSig pass)
+ (LIdP pass) -- Why a single binder? See #16754
+ (LHsSigType pass) -- Why not LHsSigWcType? See Note [Wildcards in standalone kind signatures]
+ | XStandaloneKindSig !(XXStandaloneKindSig pass)
+
+{- Note [Wildcards in standalone kind signatures]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Standalone kind signatures enable polymorphic recursion, and it is unclear how
+to reconcile this with partial type signatures, so we disallow wildcards in
+them.
+
+We reject wildcards in 'rnStandaloneKindSignature' by returning False for
+'StandaloneKindSigCtx' in 'wildCardsAllowed'.
+
+The alternative design is to have special treatment for partial standalone kind
+signatures, much like we have special treatment for partial type signatures in
+terms. However, partial standalone kind signatures are not a proper replacement
+for CUSKs, so this would be a separate feature.
+-}
+
+data NewOrData
+ = NewType -- ^ @newtype Blah ...@
+ | DataType -- ^ @data Blah ...@
+ deriving( Eq, Data ) -- Needed because Demand derives Eq
+
+-- | Convert a 'NewOrData' to a 'TyConFlavour'
+newOrDataToFlavour :: NewOrData -> TyConFlavour
+newOrDataToFlavour NewType = NewtypeFlavour
+newOrDataToFlavour DataType = DataTypeFlavour
+
+
+-- | Located data Constructor Declaration
+type LConDecl pass = XRec pass (ConDecl pass)
+ -- ^ May have 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnSemi' when
+ -- in a GADT constructor list
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-- |
+--
+-- @
+-- data T b = forall a. Eq a => MkT a b
+-- MkT :: forall b a. Eq a => MkT a b
+--
+-- data T b where
+-- MkT1 :: Int -> T Int
+--
+-- data T = Int `MkT` Int
+-- | MkT2
+--
+-- data T a where
+-- Int `MkT` Int :: T Int
+-- @
+--
+-- - 'GHC.Parser.Annotation.AnnKeywordId's : 'GHC.Parser.Annotation.AnnOpen',
+-- 'GHC.Parser.Annotation.AnnDotdot','GHC.Parser.Annotation.AnnCLose',
+-- 'GHC.Parser.Annotation.AnnEqual','GHC.Parser.Annotation.AnnVbar',
+-- 'GHC.Parser.Annotation.AnnDarrow','GHC.Parser.Annotation.AnnDarrow',
+-- 'GHC.Parser.Annotation.AnnForall','GHC.Parser.Annotation.AnnDot'
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-- | data Constructor Declaration
+data ConDecl pass
+ = ConDeclGADT
+ { con_g_ext :: XConDeclGADT pass
+ , con_names :: [LIdP pass]
+
+ -- The following fields describe the type after the '::'
+ -- See Note [GADT abstract syntax]
+ , con_bndrs :: XRec pass (HsOuterSigTyVarBndrs pass)
+ -- ^ The outermost type variable binders, be they explicit or implicit.
+ -- The 'XRec' is used to anchor API annotations, AnnForall and AnnDot.
+ , con_mb_cxt :: Maybe (LHsContext pass) -- ^ User-written context (if any)
+ , con_g_args :: HsConDeclGADTDetails pass -- ^ Arguments; never infix
+ , con_res_ty :: LHsType pass -- ^ Result type
+
+ , con_doc :: Maybe LHsDocString
+ -- ^ A possible Haddock comment.
+ }
+
+ | ConDeclH98
+ { con_ext :: XConDeclH98 pass
+ , con_name :: LIdP pass
+
+ , con_forall :: XRec pass Bool
+ -- ^ True <=> explicit user-written forall
+ -- e.g. data T a = forall b. MkT b (b->a)
+ -- con_ex_tvs = {b}
+ -- False => con_ex_tvs is empty
+ , con_ex_tvs :: [LHsTyVarBndr Specificity pass] -- ^ Existentials only
+ , con_mb_cxt :: Maybe (LHsContext pass) -- ^ User-written context (if any)
+ , con_args :: HsConDeclH98Details pass -- ^ Arguments; can be infix
+
+ , con_doc :: Maybe LHsDocString
+ -- ^ A possible Haddock comment.
+ }
+ | XConDecl !(XXConDecl pass)
+
+{- Note [GADT abstract syntax]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The types of both forms of GADT constructors are very structured, as they
+must consist of the quantified type variables (if provided), followed by the
+context (if provided), followed by the argument types (if provided), followed
+by the result type. (See "Wrinkle: No nested foralls or contexts" below for
+more discussion on the restrictions imposed here.) As a result, instead of
+storing the type of a GADT constructor as a single LHsType, we split it up
+into its constituent components for easier access.
+
+There are two broad ways to classify GADT constructors:
+
+* Record-syntax constructors. For example:
+
+ data T a where
+ K :: forall a. Ord a => { x :: [a], ... } -> T a
+
+* Prefix constructors, which do not use record syntax. For example:
+
+ data T a where
+ K :: forall a. Ord a => [a] -> ... -> T a
+
+This distinction is recorded in the `con_args :: HsConDetails pass`, which
+tracks if we're dealing with a RecCon or PrefixCon. It is easy to distinguish
+the two in the AST since record GADT constructors use HsRecTy. This distinction
+is made in GHC.Parser.PostProcess.mkGadtDecl.
+
+It is worth elaborating a bit more on the process of splitting the argument
+types of a GADT constructor, since there are some non-obvious details involved.
+While splitting the argument types of a record GADT constructor is easy (they
+are stored in an HsRecTy), splitting the arguments of a prefix GADT constructor
+is trickier. The basic idea is that we must split along the outermost function
+arrows ((->) and (%1 ->)) in the type, which GHC.Hs.Type.splitHsFunType
+accomplishes. But what about type operators? Consider:
+
+ C :: a :*: b -> a :*: b -> a :+: b
+
+This could parse in many different ways depending on the precedences of each
+type operator. In particular, if (:*:) were to have lower precedence than (->),
+then it could very well parse like this:
+
+ a :*: ((b -> a) :*: ((b -> a) :+: b)))
+
+This would give the false impression that the whole type is part of one large
+return type, with no arguments. Note that we do not fully resolve the exact
+precedences of each user-defined type operator until the renamer, so this a
+more difficult task for the parser.
+
+Fortunately, there is no risk of the above happening. GHC's parser gives
+special treatment to function arrows, and as a result, they are always parsed
+with a lower precedence than any other type operator. As a result, the type
+above is actually parsed like this:
+
+ (a :*: b) -> ((a :*: b) -> (a :+: b))
+
+While we won't know the exact precedences of (:*:) and (:+:) until the renamer,
+all we are concerned about in the parser is identifying the overall shape of
+the argument and result types, which we can accomplish by piggybacking on the
+special treatment given to function arrows. In a future where function arrows
+aren't given special status in the parser, we will likely have to modify
+GHC.Parser.PostProcess.mkHsOpTyPV to preserve this trick.
+
+-----
+-- Wrinkle: No nested foralls or contexts
+-----
+
+GADT constructors provide some freedom to change the order of foralls in their
+types (see Note [DataCon user type variable binders] in GHC.Core.DataCon), but
+this freedom is still limited. GADTs still require that all quantification
+occurs "prenex". That is, any explicitly quantified type variables must occur
+at the front of the GADT type, followed by any contexts, followed by the body of
+the GADT type, in precisely that order. For instance:
+
+ data T where
+ MkT1 :: forall a b. (Eq a, Eq b) => a -> b -> T
+ -- OK
+ MkT2 :: forall a. Eq a => forall b. a -> b -> T
+ -- Rejected, `forall b` is nested
+ MkT3 :: forall a b. Eq a => Eq b => a -> b -> T
+ -- Rejected, `Eq b` is nested
+ MkT4 :: Int -> forall a. a -> T
+ -- Rejected, `forall a` is nested
+ MkT5 :: forall a. Int -> Eq a => a -> T
+ -- Rejected, `Eq a` is nested
+ MkT6 :: (forall a. a -> T)
+ -- Rejected, `forall a` is nested due to the surrounding parentheses
+ MkT7 :: (Eq a => a -> t)
+ -- Rejected, `Eq a` is nested due to the surrounding parentheses
+
+For the full details, see the "Formal syntax for GADTs" section of the GHC
+User's Guide. GHC enforces that GADT constructors do not have nested `forall`s
+or contexts in two parts:
+
+1. GHC, in the process of splitting apart a GADT's type,
+ extracts out the leading `forall` and context (if they are provided). To
+ accomplish this splitting, the renamer uses the
+ GHC.Hs.Type.splitLHsGADTPrefixTy function, which is careful not to remove
+ parentheses surrounding the leading `forall` or context (as these
+ parentheses can be syntactically significant). If the third result returned
+ by splitLHsGADTPrefixTy contains any `forall`s or contexts, then they must
+ be nested, so they will be rejected.
+
+ Note that this step applies to both prefix and record GADTs alike, as they
+ both have syntax which permits `forall`s and contexts. The difference is
+ where this step happens:
+
+ * For prefix GADTs, this happens in the renamer (in rnConDecl), as we cannot
+ split until after the type operator fixities have been resolved.
+ * For record GADTs, this happens in the parser (in mkGadtDecl).
+2. If the GADT type is prefix, the renamer (in the ConDeclGADTPrefixPs case of
+ rnConDecl) will then check for nested `forall`s/contexts in the body of a
+ prefix GADT type, after it has determined what all of the argument types are.
+ This step is necessary to catch examples like MkT4 above, where the nested
+ quantification occurs after a visible argument type.
+-}
+
+-- | The arguments in a Haskell98-style data constructor.
+type HsConDeclH98Details pass
+ = HsConDetails Void (HsScaled pass (LBangType pass)) (XRec pass [LConDeclField pass])
+-- The Void argument to HsConDetails here is a reflection of the fact that
+-- type applications are not allowed in data constructor declarations.
+
+-- | The arguments in a GADT constructor. Unlike Haskell98-style constructors,
+-- GADT constructors cannot be declared with infix syntax. As a result, we do
+-- not use 'HsConDetails' here, as 'InfixCon' would be an unrepresentable
+-- state. (There is a notion of infix GADT constructors for the purposes of
+-- derived Show instances—see Note [Infix GADT constructors] in
+-- GHC.Tc.TyCl—but that is an orthogonal concern.)
+data HsConDeclGADTDetails pass
+ = PrefixConGADT [HsScaled pass (LBangType pass)]
+ | RecConGADT (XRec pass [LConDeclField pass])
+
+instance Outputable NewOrData where
+ ppr NewType = text "newtype"
+ ppr DataType = text "data"
+
+{-
+************************************************************************
+* *
+ Instance declarations
+* *
+************************************************************************
+
+Note [Type family instance declarations in HsSyn]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The data type FamEqn represents one equation of a type family instance.
+Aside from the pass, it is also parameterised over another field, feqn_rhs.
+feqn_rhs is either an HsDataDefn (for data family instances) or an LHsType
+(for type family instances).
+
+Type family instances also include associated type family default equations.
+That is because a default for a type family looks like this:
+
+ class C a where
+ type family F a b :: Type
+ type F c d = (c,d) -- Default instance
+
+The default declaration is really just a `type instance` declaration, but one
+with particularly simple patterns: they must all be distinct type variables.
+That's because we will instantiate it (in an instance declaration for `C`) if
+we don't give an explicit instance for `F`. Note that the names of the
+variables don't need to match those of the class: it really is like a
+free-standing `type instance` declaration.
+-}
+
+----------------- Type synonym family instances -------------
+
+-- | Located Type Family Instance Equation
+type LTyFamInstEqn pass = XRec pass (TyFamInstEqn pass)
+ -- ^ May have 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnSemi'
+ -- when in a list
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-- | Haskell Type Patterns
+type HsTyPats pass = [LHsTypeArg pass]
+
+{- Note [Family instance declaration binders]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The feqn_pats field of FamEqn (family instance equation) stores the LHS type
+(and kind) patterns. Any type (and kind) variables contained
+in these type patterns are bound in the feqn_bndrs field.
+Note that in particular:
+
+* The feqn_bndrs *include* any anonymous wildcards. For example
+ type instance F a _ = a
+ The feqn_bndrs will be HsOuterImplicit {a, _}. Remember that each separate
+ wildcard '_' gets its own unique. In this context wildcards behave just like
+ an ordinary type variable, only anonymous.
+
+* The feqn_bndrs *include* type variables that are already in scope
+
+ Eg class C s t where
+ type F t p :: *
+ instance C w (a,b) where
+ type F (a,b) x = x->a
+ The feqn_bndrs of the F decl is HsOuterImplicit {a,b,x}, even though the
+ F decl is nested inside the 'instance' decl.
+
+ However after the renamer, the uniques will match up:
+ instance C w7 (a8,b9) where
+ type F (a8,b9) x10 = x10->a8
+ so that we can compare the type pattern in the 'instance' decl and
+ in the associated 'type' decl
+
+c.f. Note [TyVar binders for associated decls]
+-}
+
+-- | Type Family Instance Equation
+type TyFamInstEqn pass = FamEqn pass (LHsType pass)
+ -- Here, the @pats@ are type patterns (with kind and type bndrs).
+ -- See Note [Family instance declaration binders]
+
+-- | Type family default declarations.
+-- A convenient synonym for 'TyFamInstDecl'.
+-- See @Note [Type family instance declarations in HsSyn]@.
+type TyFamDefltDecl = TyFamInstDecl
+
+-- | Located type family default declarations.
+type LTyFamDefltDecl pass = XRec pass (TyFamDefltDecl pass)
+
+-- | Located Type Family Instance Declaration
+type LTyFamInstDecl pass = XRec pass (TyFamInstDecl pass)
+
+-- | Type Family Instance Declaration
+newtype TyFamInstDecl pass = TyFamInstDecl { tfid_eqn :: TyFamInstEqn pass }
+ -- ^
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnType',
+ -- 'GHC.Parser.Annotation.AnnInstance',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+----------------- Data family instances -------------
+
+-- | Located Data Family Instance Declaration
+type LDataFamInstDecl pass = XRec pass (DataFamInstDecl pass)
+
+-- | Data Family Instance Declaration
+newtype DataFamInstDecl pass
+ = DataFamInstDecl { dfid_eqn :: FamEqn pass (HsDataDefn pass) }
+ -- ^
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnData',
+ -- 'GHC.Parser.Annotation.AnnNewType','GHC.Parser.Annotation.AnnInstance',
+ -- 'GHC.Parser.Annotation.AnnDcolon'
+ -- 'GHC.Parser.Annotation.AnnWhere','GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+----------------- Family instances (common types) -------------
+
+-- | Family Equation
+--
+-- One equation in a type family instance declaration, data family instance
+-- declaration, or type family default.
+-- See Note [Type family instance declarations in HsSyn]
+-- See Note [Family instance declaration binders]
+data FamEqn pass rhs
+ = FamEqn
+ { feqn_ext :: XCFamEqn pass rhs
+ , feqn_tycon :: LIdP pass
+ , feqn_bndrs :: HsOuterFamEqnTyVarBndrs pass -- ^ Optional quantified type vars
+ , feqn_pats :: HsTyPats pass
+ , feqn_fixity :: LexicalFixity -- ^ Fixity used in the declaration
+ , feqn_rhs :: rhs
+ }
+ -- ^
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnEqual'
+ | XFamEqn !(XXFamEqn pass rhs)
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+----------------- Class instances -------------
+
+-- | Located Class Instance Declaration
+type LClsInstDecl pass = XRec pass (ClsInstDecl pass)
+
+-- | Class Instance Declaration
+data ClsInstDecl pass
+ = ClsInstDecl
+ { cid_ext :: XCClsInstDecl pass
+ , cid_poly_ty :: LHsSigType pass -- Context => Class Instance-type
+ -- Using a polytype means that the renamer conveniently
+ -- figures out the quantified type variables for us.
+ , cid_binds :: LHsBinds pass -- Class methods
+ , cid_sigs :: [LSig pass] -- User-supplied pragmatic info
+ , cid_tyfam_insts :: [LTyFamInstDecl pass] -- Type family instances
+ , cid_datafam_insts :: [LDataFamInstDecl pass] -- Data family instances
+ , cid_overlap_mode :: Maybe (XRec pass OverlapMode)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnClose',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ }
+ -- ^
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnInstance',
+ -- 'GHC.Parser.Annotation.AnnWhere',
+ -- 'GHC.Parser.Annotation.AnnOpen','GHC.Parser.Annotation.AnnClose',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | XClsInstDecl !(XXClsInstDecl pass)
+
+----------------- Instances of all kinds -------------
+
+-- | Located Instance Declaration
+type LInstDecl pass = XRec pass (InstDecl pass)
+
+-- | Instance Declaration
+data InstDecl pass -- Both class and family instances
+ = ClsInstD
+ { cid_d_ext :: XClsInstD pass
+ , cid_inst :: ClsInstDecl pass }
+ | DataFamInstD -- data family instance
+ { dfid_ext :: XDataFamInstD pass
+ , dfid_inst :: DataFamInstDecl pass }
+ | TyFamInstD -- type family instance
+ { tfid_ext :: XTyFamInstD pass
+ , tfid_inst :: TyFamInstDecl pass }
+ | XInstDecl !(XXInstDecl pass)
+
+{-
+************************************************************************
+* *
+\subsection[DerivDecl]{A stand-alone instance deriving declaration}
+* *
+************************************************************************
+-}
+
+-- | Located stand-alone 'deriving instance' declaration
+type LDerivDecl pass = XRec pass (DerivDecl pass)
+
+-- | Stand-alone 'deriving instance' declaration
+data DerivDecl pass = DerivDecl
+ { deriv_ext :: XCDerivDecl pass
+ , deriv_type :: LHsSigWcType pass
+ -- ^ The instance type to derive.
+ --
+ -- It uses an 'LHsSigWcType' because the context is allowed to be a
+ -- single wildcard:
+ --
+ -- > deriving instance _ => Eq (Foo a)
+ --
+ -- Which signifies that the context should be inferred.
+
+ -- See Note [Inferring the instance context] in GHC.Tc.Deriv.Infer.
+
+ , deriv_strategy :: Maybe (LDerivStrategy pass)
+ , deriv_overlap_mode :: Maybe (XRec pass OverlapMode)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnDeriving',
+ -- 'GHC.Parser.Annotation.AnnInstance', 'GHC.Parser.Annotation.AnnStock',
+ -- 'GHC.Parser.Annotation.AnnAnyClass', 'Api.AnnNewtype',
+ -- 'GHC.Parser.Annotation.AnnOpen','GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ }
+ | XDerivDecl !(XXDerivDecl pass)
+
+{-
+************************************************************************
+* *
+ Deriving strategies
+* *
+************************************************************************
+-}
+
+-- | A 'Located' 'DerivStrategy'.
+type LDerivStrategy pass = XRec pass (DerivStrategy pass)
+
+-- | Which technique the user explicitly requested when deriving an instance.
+data DerivStrategy pass
+ -- See Note [Deriving strategies] in GHC.Tc.Deriv
+ = StockStrategy -- ^ GHC's \"standard\" strategy, which is to implement a
+ -- custom instance for the data type. This only works
+ -- for certain types that GHC knows about (e.g., 'Eq',
+ -- 'Show', 'Functor' when @-XDeriveFunctor@ is enabled,
+ -- etc.)
+ | AnyclassStrategy -- ^ @-XDeriveAnyClass@
+ | NewtypeStrategy -- ^ @-XGeneralizedNewtypeDeriving@
+ | ViaStrategy (XViaStrategy pass)
+ -- ^ @-XDerivingVia@
+
+-- | A short description of a @DerivStrategy'@.
+derivStrategyName :: DerivStrategy a -> SDoc
+derivStrategyName = text . go
+ where
+ go StockStrategy = "stock"
+ go AnyclassStrategy = "anyclass"
+ go NewtypeStrategy = "newtype"
+ go (ViaStrategy {}) = "via"
+
+{-
+************************************************************************
+* *
+\subsection[DefaultDecl]{A @default@ declaration}
+* *
+************************************************************************
+
+There can only be one default declaration per module, but it is hard
+for the parser to check that; we pass them all through in the abstract
+syntax, and that restriction must be checked in the front end.
+-}
+
+-- | Located Default Declaration
+type LDefaultDecl pass = XRec pass (DefaultDecl pass)
+
+-- | Default Declaration
+data DefaultDecl pass
+ = DefaultDecl (XCDefaultDecl pass) [LHsType pass]
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId's : 'GHC.Parser.Annotation.AnnDefault',
+ -- 'GHC.Parser.Annotation.AnnOpen','GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | XDefaultDecl !(XXDefaultDecl pass)
+
+{-
+************************************************************************
+* *
+\subsection{Foreign function interface declaration}
+* *
+************************************************************************
+-}
+
+-- foreign declarations are distinguished as to whether they define or use a
+-- Haskell name
+--
+-- * the Boolean value indicates whether the pre-standard deprecated syntax
+-- has been used
+
+-- | Located Foreign Declaration
+type LForeignDecl pass = XRec pass (ForeignDecl pass)
+
+-- | Foreign Declaration
+data ForeignDecl pass
+ = ForeignImport
+ { fd_i_ext :: XForeignImport pass -- Post typechecker, rep_ty ~ sig_ty
+ , fd_name :: LIdP pass -- defines this name
+ , fd_sig_ty :: LHsSigType pass -- sig_ty
+ , fd_fi :: ForeignImport }
+
+ | ForeignExport
+ { fd_e_ext :: XForeignExport pass -- Post typechecker, rep_ty ~ sig_ty
+ , fd_name :: LIdP pass -- uses this name
+ , fd_sig_ty :: LHsSigType pass -- sig_ty
+ , fd_fe :: ForeignExport }
+ -- ^
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnForeign',
+ -- 'GHC.Parser.Annotation.AnnImport','GHC.Parser.Annotation.AnnExport',
+ -- 'GHC.Parser.Annotation.AnnDcolon'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | XForeignDecl !(XXForeignDecl pass)
+
+{-
+ In both ForeignImport and ForeignExport:
+ sig_ty is the type given in the Haskell code
+ rep_ty is the representation for this type, i.e. with newtypes
+ coerced away and type functions evaluated.
+ Thus if the declaration is valid, then rep_ty will only use types
+ such as Int and IO that we know how to make foreign calls with.
+-}
+
+-- Specification Of an imported external entity in dependence on the calling
+-- convention
+--
+data ForeignImport = -- import of a C entity
+ --
+ -- * the two strings specifying a header file or library
+ -- may be empty, which indicates the absence of a
+ -- header or object specification (both are not used
+ -- in the case of `CWrapper' and when `CFunction'
+ -- has a dynamic target)
+ --
+ -- * the calling convention is irrelevant for code
+ -- generation in the case of `CLabel', but is needed
+ -- for pretty printing
+ --
+ -- * `Safety' is irrelevant for `CLabel' and `CWrapper'
+ --
+ CImport (Located CCallConv) -- ccall or stdcall
+ (Located Safety) -- interruptible, safe or unsafe
+ (Maybe Header) -- name of C header
+ CImportSpec -- details of the C entity
+ (Located SourceText) -- original source text for
+ -- the C entity
+ deriving Data
+
+-- details of an external C entity
+--
+data CImportSpec = CLabel CLabelString -- import address of a C label
+ | CFunction CCallTarget -- static or dynamic function
+ | CWrapper -- wrapper to expose closures
+ -- (former f.e.d.)
+ deriving Data
+
+-- specification of an externally exported entity in dependence on the calling
+-- convention
+--
+data ForeignExport = CExport (Located CExportSpec) -- contains the calling
+ -- convention
+ (Located SourceText) -- original source text for
+ -- the C entity
+ deriving Data
+
+-- pretty printing of foreign declarations
+--
+
+instance Outputable ForeignImport where
+ ppr (CImport cconv safety mHeader spec (L _ srcText)) =
+ ppr cconv <+> ppr safety
+ <+> pprWithSourceText srcText (pprCEntity spec "")
+ where
+ pp_hdr = case mHeader of
+ Nothing -> empty
+ Just (Header _ header) -> ftext header
+
+ pprCEntity (CLabel lbl) _ =
+ doubleQuotes $ text "static" <+> pp_hdr <+> char '&' <> ppr lbl
+ pprCEntity (CFunction (StaticTarget st _lbl _ isFun)) src =
+ if dqNeeded then doubleQuotes ce else empty
+ where
+ dqNeeded = (take 6 src == "static")
+ || isJust mHeader
+ || not isFun
+ || st /= NoSourceText
+ ce =
+ -- We may need to drop leading spaces first
+ (if take 6 src == "static" then text "static" else empty)
+ <+> pp_hdr
+ <+> (if isFun then empty else text "value")
+ <+> (pprWithSourceText st empty)
+ pprCEntity (CFunction DynamicTarget) _ =
+ doubleQuotes $ text "dynamic"
+ pprCEntity CWrapper _ = doubleQuotes $ text "wrapper"
+
+instance Outputable ForeignExport where
+ ppr (CExport (L _ (CExportStatic _ lbl cconv)) _) =
+ ppr cconv <+> char '"' <> ppr lbl <> char '"'
+
+{-
+************************************************************************
+* *
+\subsection{Rewrite rules}
+* *
+************************************************************************
+-}
+
+-- | Located Rule Declarations
+type LRuleDecls pass = XRec pass (RuleDecls pass)
+
+ -- Note [Pragma source text] in GHC.Types.SourceText
+-- | Rule Declarations
+data RuleDecls pass = HsRules { rds_ext :: XCRuleDecls pass
+ , rds_src :: SourceText
+ , rds_rules :: [LRuleDecl pass] }
+ | XRuleDecls !(XXRuleDecls pass)
+
+-- | Located Rule Declaration
+type LRuleDecl pass = XRec pass (RuleDecl pass)
+
+-- | Rule Declaration
+data RuleDecl pass
+ = HsRule -- Source rule
+ { rd_ext :: XHsRule pass
+ -- ^ After renamer, free-vars from the LHS and RHS
+ , rd_name :: XRec pass (SourceText,RuleName)
+ -- ^ Note [Pragma source text] in "GHC.Types.Basic"
+ , rd_act :: Activation
+ , rd_tyvs :: Maybe [LHsTyVarBndr () (NoGhcTc pass)]
+ -- ^ Forall'd type vars
+ , rd_tmvs :: [LRuleBndr pass]
+ -- ^ Forall'd term vars, before typechecking; after typechecking
+ -- this includes all forall'd vars
+ , rd_lhs :: XRec pass (HsExpr pass)
+ , rd_rhs :: XRec pass (HsExpr pass)
+ }
+ -- ^
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' :
+ -- 'GHC.Parser.Annotation.AnnOpen','GHC.Parser.Annotation.AnnTilde',
+ -- 'GHC.Parser.Annotation.AnnVal',
+ -- 'GHC.Parser.Annotation.AnnClose',
+ -- 'GHC.Parser.Annotation.AnnForall','GHC.Parser.Annotation.AnnDot',
+ -- 'GHC.Parser.Annotation.AnnEqual',
+ | XRuleDecl !(XXRuleDecl pass)
+
+data HsRuleRn = HsRuleRn NameSet NameSet -- Free-vars from the LHS and RHS
+ deriving Data
+
+-- | Located Rule Binder
+type LRuleBndr pass = XRec pass (RuleBndr pass)
+
+-- | Rule Binder
+data RuleBndr pass
+ = RuleBndr (XCRuleBndr pass) (LIdP pass)
+ | RuleBndrSig (XRuleBndrSig pass) (LIdP pass) (HsPatSigType pass)
+ | XRuleBndr !(XXRuleBndr pass)
+ -- ^
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnDcolon','GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+collectRuleBndrSigTys :: [RuleBndr pass] -> [HsPatSigType pass]
+collectRuleBndrSigTys bndrs = [ty | RuleBndrSig _ _ ty <- bndrs]
+
+pprFullRuleName :: Located (SourceText, RuleName) -> SDoc
+pprFullRuleName (L _ (st, n)) = pprWithSourceText st (doubleQuotes $ ftext n)
+
+{-
+************************************************************************
+* *
+\subsection[DocDecl]{Document comments}
+* *
+************************************************************************
+-}
+
+-- | Located Documentation comment Declaration
+type LDocDecl = Located (DocDecl)
+
+-- | Documentation comment Declaration
+data DocDecl
+ = DocCommentNext HsDocString
+ | DocCommentPrev HsDocString
+ | DocCommentNamed String HsDocString
+ | DocGroup Int HsDocString
+ deriving Data
+
+-- Okay, I need to reconstruct the document comments, but for now:
+instance Outputable DocDecl where
+ ppr _ = text "<document comment>"
+
+docDeclDoc :: DocDecl -> HsDocString
+docDeclDoc (DocCommentNext d) = d
+docDeclDoc (DocCommentPrev d) = d
+docDeclDoc (DocCommentNamed _ d) = d
+docDeclDoc (DocGroup _ d) = d
+
+{-
+************************************************************************
+* *
+\subsection[DeprecDecl]{Deprecations}
+* *
+************************************************************************
+
+We use exported entities for things to deprecate.
+-}
+
+-- | Located Warning Declarations
+type LWarnDecls pass = XRec pass (WarnDecls pass)
+
+ -- Note [Pragma source text] in GHC.Types.SourceText
+-- | Warning pragma Declarations
+data WarnDecls pass = Warnings { wd_ext :: XWarnings pass
+ , wd_src :: SourceText
+ , wd_warnings :: [LWarnDecl pass]
+ }
+ | XWarnDecls !(XXWarnDecls pass)
+
+-- | Located Warning pragma Declaration
+type LWarnDecl pass = XRec pass (WarnDecl pass)
+
+-- | Warning pragma Declaration
+data WarnDecl pass = Warning (XWarning pass) [LIdP pass] WarningTxt
+ | XWarnDecl !(XXWarnDecl pass)
+
+{-
+************************************************************************
+* *
+\subsection[AnnDecl]{Annotations}
+* *
+************************************************************************
+-}
+
+-- | Located Annotation Declaration
+type LAnnDecl pass = XRec pass (AnnDecl pass)
+
+-- | Annotation Declaration
+data AnnDecl pass = HsAnnotation
+ (XHsAnnotation pass)
+ SourceText -- Note [Pragma source text] in GHC.Types.SourceText
+ (AnnProvenance (IdP pass)) (XRec pass (HsExpr pass))
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnType'
+ -- 'GHC.Parser.Annotation.AnnModule'
+ -- 'GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | XAnnDecl !(XXAnnDecl pass)
+
+-- | Annotation Provenance
+data AnnProvenance name = ValueAnnProvenance (Located name)
+ | TypeAnnProvenance (Located name)
+ | ModuleAnnProvenance
+deriving instance Functor AnnProvenance
+deriving instance Foldable AnnProvenance
+deriving instance Traversable AnnProvenance
+deriving instance (Data pass) => Data (AnnProvenance pass)
+
+annProvenanceName_maybe :: AnnProvenance name -> Maybe name
+annProvenanceName_maybe (ValueAnnProvenance (L _ name)) = Just name
+annProvenanceName_maybe (TypeAnnProvenance (L _ name)) = Just name
+annProvenanceName_maybe ModuleAnnProvenance = Nothing
+
+{-
+************************************************************************
+* *
+\subsection[RoleAnnot]{Role annotations}
+* *
+************************************************************************
+-}
+
+-- | Located Role Annotation Declaration
+type LRoleAnnotDecl pass = XRec pass (RoleAnnotDecl pass)
+
+-- See #8185 for more info about why role annotations are
+-- top-level declarations
+-- | Role Annotation Declaration
+data RoleAnnotDecl pass
+ = RoleAnnotDecl (XCRoleAnnotDecl pass)
+ (LIdP pass) -- type constructor
+ [XRec pass (Maybe Role)] -- optional annotations
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnType',
+ -- 'GHC.Parser.Annotation.AnnRole'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | XRoleAnnotDecl !(XXRoleAnnotDecl pass)
diff --git a/compiler/Language/Haskell/Syntax/Expr.hs b/compiler/Language/Haskell/Syntax/Expr.hs
new file mode 100644
index 0000000000..ecc7c9f828
--- /dev/null
+++ b/compiler/Language/Haskell/Syntax/Expr.hs
@@ -0,0 +1,1776 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilyDependencies #-}
+{-# 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
+-}
+
+-- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.*
+
+-- | Abstract Haskell syntax for expressions.
+module Language.Haskell.Syntax.Expr where
+
+#include "HsVersions.h"
+
+-- friends:
+import GHC.Prelude
+
+import Language.Haskell.Syntax.Decls
+import Language.Haskell.Syntax.Pat
+import Language.Haskell.Syntax.Lit
+import Language.Haskell.Syntax.Extension
+import Language.Haskell.Syntax.Type
+import Language.Haskell.Syntax.Binds
+
+-- others:
+import GHC.Tc.Types.Evidence
+import GHC.Core
+import GHC.Types.Name
+import GHC.Types.Basic
+import GHC.Types.Fixity
+import GHC.Types.SourceText
+import GHC.Types.SrcLoc
+import GHC.Core.ConLike
+import GHC.Unit.Module (ModuleName)
+import GHC.Utils.Outputable
+import GHC.Utils.Panic
+import GHC.Data.FastString
+import GHC.Core.Type
+
+-- libraries:
+import Data.Data hiding (Fixity(..))
+import qualified Data.Data as Data (Fixity(..))
+
+import GHCi.RemoteTypes ( ForeignRef )
+import qualified Language.Haskell.TH as TH (Q)
+
+{-
+************************************************************************
+* *
+\subsection{Expressions proper}
+* *
+************************************************************************
+-}
+
+-- * Expressions proper
+
+-- | Located Haskell Expression
+type LHsExpr p = XRec p (HsExpr p)
+ -- ^ May have 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnComma' when
+ -- in a list
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-------------------------
+{- Note [NoSyntaxExpr]
+~~~~~~~~~~~~~~~~~~~~~~
+Syntax expressions can be missing (NoSyntaxExprRn or NoSyntaxExprTc)
+for several reasons:
+
+ 1. As described in Note [Rebindable if]
+
+ 2. In order to suppress "not in scope: xyz" messages when a bit of
+ rebindable syntax does not apply. For example, when using an irrefutable
+ pattern in a BindStmt, we don't need a `fail` operator.
+
+ 3. Rebindable syntax might just not make sense. For example, a BodyStmt
+ contains the syntax for `guard`, but that's used only in monad comprehensions.
+ If we had more of a whiz-bang type system, we might be able to rule this
+ case out statically.
+-}
+
+-- | Syntax Expression
+--
+-- SyntaxExpr is represents the function used in interpreting rebindable
+-- syntax. In the parser, we have no information to supply; in the renamer,
+-- we have the name of the function (but see
+-- Note [Monad fail : Rebindable syntax, overloaded strings] for a wrinkle)
+-- and in the type-checker we have a more elaborate structure 'SyntaxExprTc'.
+--
+-- In some contexts, rebindable syntax is not implemented, and so we have
+-- constructors to represent that possibility in both the renamer and
+-- typechecker instantiations.
+--
+-- E.g. @(>>=)@ is filled in before the renamer by the appropriate 'Name' for
+-- @(>>=)@, and then instantiated by the type checker with its type args
+-- etc
+type family SyntaxExpr p
+
+-- | Command Syntax Table (for Arrow syntax)
+type CmdSyntaxTable p = [(Name, HsExpr p)]
+-- See Note [CmdSyntaxTable]
+
+{-
+Note [CmdSyntaxTable]
+~~~~~~~~~~~~~~~~~~~~~
+Used only for arrow-syntax stuff (HsCmdTop), the CmdSyntaxTable keeps
+track of the methods needed for a Cmd.
+
+* Before the renamer, this list is an empty list
+
+* After the renamer, it takes the form @[(std_name, HsVar actual_name)]@
+ For example, for the 'arr' method
+ * normal case: (GHC.Control.Arrow.arr, HsVar GHC.Control.Arrow.arr)
+ * with rebindable syntax: (GHC.Control.Arrow.arr, arr_22)
+ where @arr_22@ is whatever 'arr' is in scope
+
+* After the type checker, it takes the form [(std_name, <expression>)]
+ where <expression> is the evidence for the method. This evidence is
+ instantiated with the class, but is still polymorphic in everything
+ else. For example, in the case of 'arr', the evidence has type
+ forall b c. (b->c) -> a b c
+ where 'a' is the ambient type of the arrow. This polymorphism is
+ important because the desugarer uses the same evidence at multiple
+ different types.
+
+This is Less Cool than what we normally do for rebindable syntax, which is to
+make fully-instantiated piece of evidence at every use site. The Cmd way
+is Less Cool because
+ * The renamer has to predict which methods are needed.
+ See the tedious GHC.Rename.Expr.methodNamesCmd.
+
+ * The desugarer has to know the polymorphic type of the instantiated
+ method. This is checked by Inst.tcSyntaxName, but is less flexible
+ than the rest of rebindable syntax, where the type is less
+ pre-ordained. (And this flexibility is useful; for example we can
+ typecheck do-notation with (>>=) :: m1 a -> (a -> m2 b) -> m2 b.)
+-}
+
+-- | A Haskell expression.
+data HsExpr p
+ = HsVar (XVar p)
+ (LIdP p) -- ^ Variable
+ -- See Note [Located RdrNames]
+
+ | HsUnboundVar (XUnboundVar p)
+ OccName -- ^ Unbound variable; also used for "holes"
+ -- (_ or _x).
+ -- Turned from HsVar to HsUnboundVar by the
+ -- renamer, when it finds an out-of-scope
+ -- variable or hole.
+ -- The (XUnboundVar p) field becomes an HoleExprRef
+ -- after typechecking; this is where the
+ -- erroring expression will be written after
+ -- solving. See Note [Holes] in GHC.Tc.Types.Constraint.
+
+ | HsConLikeOut (XConLikeOut p)
+ ConLike -- ^ After typechecker only; must be different
+ -- HsVar for pretty printing
+
+ | HsRecFld (XRecFld p)
+ (AmbiguousFieldOcc p) -- ^ Variable pointing to record selector
+ -- The parser produces HsVars
+ -- The renamer renames record-field selectors to HsRecFld
+ -- The typechecker preserves HsRecFld
+
+ | HsOverLabel (XOverLabel p)
+ (Maybe (IdP p)) FastString
+ -- ^ Overloaded label (Note [Overloaded labels] in GHC.OverloadedLabels)
+ -- @Just id@ means @RebindableSyntax@ is in use, and gives the id of the
+ -- in-scope 'fromLabel'.
+ -- NB: Not in use after typechecking
+
+ | HsIPVar (XIPVar p)
+ HsIPName -- ^ Implicit parameter (not in use after typechecking)
+ | HsOverLit (XOverLitE p)
+ (HsOverLit p) -- ^ Overloaded literals
+
+ | HsLit (XLitE p)
+ (HsLit p) -- ^ Simple (non-overloaded) literals
+
+ | HsLam (XLam p)
+ (MatchGroup p (LHsExpr p))
+ -- ^ Lambda abstraction. Currently always a single match
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnLam',
+ -- 'GHC.Parser.Annotation.AnnRarrow',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsLamCase (XLamCase p) (MatchGroup p (LHsExpr p)) -- ^ Lambda-case
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnLam',
+ -- 'GHC.Parser.Annotation.AnnCase','GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsApp (XApp p) (LHsExpr p) (LHsExpr p) -- ^ Application
+
+ | HsAppType (XAppTypeE p) -- After typechecking: the type argument
+ (LHsExpr p)
+ (LHsWcType (NoGhcTc p)) -- ^ Visible type application
+ --
+ -- Explicit type argument; e.g f @Int x y
+ -- NB: Has wildcards, but no implicit quantification
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnAt',
+
+ -- | Operator applications:
+ -- NB Bracketed ops such as (+) come out as Vars.
+
+ -- NB We need an expr for the operator in an OpApp/Section since
+ -- the typechecker may need to apply the operator to a few types.
+
+ | OpApp (XOpApp p)
+ (LHsExpr p) -- left operand
+ (LHsExpr p) -- operator
+ (LHsExpr p) -- right operand
+
+ -- | Negation operator. Contains the negated expression and the name
+ -- of 'negate'
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnMinus'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | NegApp (XNegApp p)
+ (LHsExpr p)
+ (SyntaxExpr p)
+
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'('@,
+ -- 'GHC.Parser.Annotation.AnnClose' @')'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsPar (XPar p)
+ (LHsExpr p) -- ^ Parenthesised expr; see Note [Parens in HsSyn]
+
+ | SectionL (XSectionL p)
+ (LHsExpr p) -- operand; see Note [Sections in HsSyn]
+ (LHsExpr p) -- operator
+ | SectionR (XSectionR p)
+ (LHsExpr p) -- operator; see Note [Sections in HsSyn]
+ (LHsExpr p) -- operand
+
+ -- | Used for explicit tuples and sections thereof
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ -- Note [ExplicitTuple]
+ | ExplicitTuple
+ (XExplicitTuple p)
+ [LHsTupArg p]
+ Boxity
+
+ -- | Used for unboxed sum types
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'(#'@,
+ -- 'GHC.Parser.Annotation.AnnVbar', 'GHC.Parser.Annotation.AnnClose' @'#)'@,
+ --
+ -- There will be multiple 'GHC.Parser.Annotation.AnnVbar', (1 - alternative) before
+ -- the expression, (arity - alternative) after it
+ | ExplicitSum
+ (XExplicitSum p)
+ ConTag -- Alternative (one-based)
+ Arity -- Sum arity
+ (LHsExpr p)
+
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnCase',
+ -- 'GHC.Parser.Annotation.AnnOf','GHC.Parser.Annotation.AnnOpen' @'{'@,
+ -- 'GHC.Parser.Annotation.AnnClose' @'}'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsCase (XCase p)
+ (LHsExpr p)
+ (MatchGroup p (LHsExpr p))
+
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnIf',
+ -- 'GHC.Parser.Annotation.AnnSemi',
+ -- 'GHC.Parser.Annotation.AnnThen','GHC.Parser.Annotation.AnnSemi',
+ -- 'GHC.Parser.Annotation.AnnElse',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsIf (XIf p) -- GhcPs: this is a Bool; False <=> do not use
+ -- rebindable syntax
+ (LHsExpr p) -- predicate
+ (LHsExpr p) -- then part
+ (LHsExpr p) -- else part
+
+ -- | Multi-way if
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnIf'
+ -- 'GHC.Parser.Annotation.AnnOpen','GHC.Parser.Annotation.AnnClose',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsMultiIf (XMultiIf p) [LGRHS p (LHsExpr p)]
+
+ -- | let(rec)
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnLet',
+ -- 'GHC.Parser.Annotation.AnnOpen' @'{'@,
+ -- 'GHC.Parser.Annotation.AnnClose' @'}'@,'GHC.Parser.Annotation.AnnIn'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsLet (XLet p)
+ (LHsLocalBinds p)
+ (LHsExpr p)
+
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnDo',
+ -- 'GHC.Parser.Annotation.AnnOpen', 'GHC.Parser.Annotation.AnnSemi',
+ -- 'GHC.Parser.Annotation.AnnVbar',
+ -- 'GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsDo (XDo p) -- Type of the whole expression
+ (HsStmtContext (HsDoRn p))
+ -- The parameterisation of the above is unimportant
+ -- because in this context we never use
+ -- the PatGuard or ParStmt variant
+ (XRec p [ExprLStmt p]) -- "do":one or more stmts
+
+ -- | Syntactic list: [a,b,c,...]
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'['@,
+ -- 'GHC.Parser.Annotation.AnnClose' @']'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ -- See Note [Empty lists]
+ | ExplicitList
+ (XExplicitList p) -- Gives type of components of list
+ (Maybe (SyntaxExpr p))
+ -- For OverloadedLists, the fromListN witness
+ [LHsExpr p]
+
+ -- | Record construction
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'{'@,
+ -- 'GHC.Parser.Annotation.AnnDotdot','GHC.Parser.Annotation.AnnClose' @'}'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | RecordCon
+ { rcon_ext :: XRecordCon p
+ , rcon_con_name :: LIdP p -- The constructor name;
+ -- not used after type checking
+ , rcon_flds :: HsRecordBinds p } -- The fields
+
+ -- | Record update
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'{'@,
+ -- 'GHC.Parser.Annotation.AnnDotdot','GHC.Parser.Annotation.AnnClose' @'}'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | RecordUpd
+ { rupd_ext :: XRecordUpd p
+ , rupd_expr :: LHsExpr p
+ , rupd_flds :: [LHsRecUpdField p]
+ }
+ -- For a type family, the arg types are of the *instance* tycon,
+ -- not the family tycon
+
+ -- | Expression with an explicit type signature. @e :: type@
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnDcolon'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | ExprWithTySig
+ (XExprWithTySig p)
+
+ (LHsExpr p)
+ (LHsSigWcType (NoGhcTc p))
+
+ -- | Arithmetic sequence
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'['@,
+ -- 'GHC.Parser.Annotation.AnnComma','GHC.Parser.Annotation.AnnDotdot',
+ -- 'GHC.Parser.Annotation.AnnClose' @']'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | ArithSeq
+ (XArithSeq p)
+ (Maybe (SyntaxExpr p))
+ -- For OverloadedLists, the fromList witness
+ (ArithSeqInfo p)
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ -----------------------------------------------------------
+ -- MetaHaskell Extensions
+
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnOpenE','GHC.Parser.Annotation.AnnOpenEQ',
+ -- 'GHC.Parser.Annotation.AnnClose','GHC.Parser.Annotation.AnnCloseQ'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsBracket (XBracket p) (HsBracket p)
+
+ -- See Note [Pending Splices]
+ | HsRnBracketOut
+ (XRnBracketOut p)
+ (HsBracket (HsBracketRn p)) -- Output of the renamer is the *original* renamed
+ -- expression, plus
+ [PendingRnSplice' p] -- _renamed_ splices to be type checked
+
+ | HsTcBracketOut
+ (XTcBracketOut p)
+ (Maybe QuoteWrapper) -- The wrapper to apply type and dictionary argument
+ -- to the quote.
+ (HsBracket (HsBracketRn p)) -- Output of the type checker is the *original*
+ -- renamed expression, plus
+ [PendingTcSplice' p] -- _typechecked_ splices to be
+ -- pasted back in by the desugarer
+
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsSpliceE (XSpliceE p) (HsSplice p)
+
+ -----------------------------------------------------------
+ -- Arrow notation extension
+
+ -- | @proc@ notation for Arrows
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnProc',
+ -- 'GHC.Parser.Annotation.AnnRarrow'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsProc (XProc p)
+ (LPat p) -- arrow abstraction, proc
+ (LHsCmdTop p) -- body of the abstraction
+ -- always has an empty stack
+
+ ---------------------------------------
+ -- static pointers extension
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnStatic',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsStatic (XStatic p) -- Free variables of the body
+ (LHsExpr p) -- Body
+
+ ---------------------------------------
+ -- Haskell program coverage (Hpc) Support
+
+ | HsTick
+ (XTick p)
+ (Tickish (IdP p))
+ (LHsExpr p) -- sub-expression
+
+ | HsBinTick
+ (XBinTick p)
+ Int -- module-local tick number for True
+ Int -- module-local tick number for False
+ (LHsExpr p) -- sub-expression
+
+ ---------------------------------------
+ -- Expressions annotated with pragmas, written as {-# ... #-}
+ | HsPragE (XPragE p) (HsPragE p) (LHsExpr p)
+
+ | XExpr !(XXExpr p)
+ -- Note [Trees that Grow] extension constructor for the
+ -- general idea, and Note [Rebindable syntax and HsExpansion]
+ -- for an example of how we use it.
+
+-- | The AST used to hard-refer to GhcPass, which was a layer violation. For now,
+-- we paper it over with this new extension point.
+type family HsDoRn p
+type family HsBracketRn p
+type family PendingRnSplice' p
+type family PendingTcSplice' p
+
+-- ---------------------------------------------------------------------
+
+{-
+Note [Rebindable syntax and HsExpansion]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We implement rebindable syntax (RS) support by performing a desugaring
+in the renamer. We transform GhcPs expressions affected by RS into the
+appropriate desugared form, but **annotated with the original expression**.
+
+Let us consider a piece of code like:
+
+ {-# LANGUAGE RebindableSyntax #-}
+ ifThenElse :: Char -> () -> () -> ()
+ ifThenElse _ _ _ = ()
+ x = if 'a' then () else True
+
+The parsed AST for the RHS of x would look something like (slightly simplified):
+
+ L locif (HsIf (L loca 'a') (L loctrue ()) (L locfalse True))
+
+Upon seeing such an AST with RS on, we could transform it into a
+mere function call, as per the RS rules, equivalent to the
+following function application:
+
+ ifThenElse 'a' () True
+
+which doesn't typecheck. But GHC would report an error about
+not being able to match the third argument's type (Bool) with the
+expected type: (), in the expression _as desugared_, i.e in
+the aforementioned function application. But the user never
+wrote a function application! This would be pretty bad.
+
+To remedy this, instead of transforming the original HsIf
+node into mere applications of 'ifThenElse', we keep the
+original 'if' expression around too, using the TTG
+XExpr extension point to allow GHC to construct an
+'HsExpansion' value that will keep track of the original
+expression in its first field, and the desugared one in the
+second field. The resulting renamed AST would look like:
+
+ L locif (XExpr
+ (HsExpanded
+ (HsIf (L loca 'a')
+ (L loctrue ())
+ (L locfalse True)
+ )
+ (App (L generatedSrcSpan
+ (App (L generatedSrcSpan
+ (App (L generatedSrcSpan (Var ifThenElse))
+ (L loca 'a')
+ )
+ )
+ (L loctrue ())
+ )
+ )
+ (L locfalse True)
+ )
+ )
+ )
+
+When comes the time to typecheck the program, we end up calling
+tcMonoExpr on the AST above. If this expression gives rise to
+a type error, then it will appear in a context line and GHC
+will pretty-print it using the 'Outputable (HsExpansion a b)'
+instance defined below, which *only prints the original
+expression*. This is the gist of the idea, but is not quite
+enough to recover the error messages that we had with the
+SyntaxExpr-based, typechecking/desugaring-to-core time
+implementation of rebindable syntax. The key idea is to decorate
+some elements of the desugared expression so as to be able to
+give them a special treatment when typechecking the desugared
+expression, to print a different context line or skip one
+altogether.
+
+Whenever we 'setSrcSpan' a 'generatedSrcSpan', we update a field in
+TcLclEnv called 'tcl_in_gen_code', setting it to True, which indicates that we
+entered generated code, i.e code fabricated by the compiler when rebinding some
+syntax. If someone tries to push some error context line while that field is set
+to True, the pushing won't actually happen and the context line is just dropped.
+Once we 'setSrcSpan' a real span (for an expression that was in the original
+source code), we set 'tcl_in_gen_code' back to False, indicating that we
+"emerged from the generated code tunnel", and that the expressions we will be
+processing are relevant to report in context lines again.
+
+You might wonder why we store a RealSrcSpan in addition to a Bool in
+the TcLclEnv: could we not store a Maybe RealSrcSpan? The problem is
+that we still generate constraints when processing generated code,
+and a CtLoc must contain a RealSrcSpan -- otherwise, error messages
+might appear without source locations. So we keep the RealSrcSpan of
+the last location spotted that wasn't generated; it's as good as
+we're going to get in generated code. Once we get to sub-trees that
+are not generated, then we update the RealSrcSpan appropriately, and
+set the tcl_in_gen_code Bool to False.
+
+---
+
+A general recipe to follow this approach for new constructs could go as follows:
+
+- Remove any GhcRn-time SyntaxExpr extensions to the relevant constructor for your
+ construct, in HsExpr or related syntax data types.
+- At renaming-time:
+ - take your original node of interest (HsIf above)
+ - rename its subexpressions (condition, true branch, false branch above)
+ - construct the suitable "rebound"-and-renamed result (ifThenElse call
+ above), where the 'SrcSpan' attached to any _fabricated node_ (the
+ HsVar/HsApp nodes, above) is set to 'generatedSrcSpan'
+ - take both the original node and that rebound-and-renamed result and wrap
+ them in an XExpr: XExpr (HsExpanded <original node> <desugared>)
+ - At typechecking-time:
+ - remove any logic that was previously dealing with your rebindable
+ construct, typically involving [tc]SyntaxOp, SyntaxExpr and friends.
+ - the XExpr (HsExpanded ... ...) case in tcExpr already makes sure that we
+ typecheck the desugared expression while reporting the original one in
+ errors
+
+-}
+
+-- See Note [Rebindable syntax and HsExpansion] just above.
+data HsExpansion a b
+ = HsExpanded a b
+ deriving Data
+
+-- | Build a "wrapped" 'HsExpansion' out of an extension constructor,
+-- and the two components of the expansion: original and desugared
+-- expressions.
+--
+-- See Note [Rebindable Syntax and HsExpansion] above for more details.
+mkExpanded
+ :: (HsExpansion a b -> b) -- ^ XExpr, XCmd, ...
+ -> a -- ^ source expression ('GhcPs')
+ -> b -- ^ "desugared" expression
+ -- ('GhcRn')
+ -> b -- ^ suitably wrapped
+ -- 'HsExpansion'
+mkExpanded xwrap a b = xwrap (HsExpanded a b)
+
+-- | Just print the original expression (the @a@).
+instance (Outputable a, Outputable b) => Outputable (HsExpansion a b) where
+ ppr (HsExpanded a b) = ifPprDebug (vcat [ppr a, ppr b]) (ppr a)
+
+-- ---------------------------------------------------------------------
+
+-- | A pragma, written as {-# ... #-}, that may appear within an expression.
+data HsPragE p
+ = HsPragSCC (XSCC p)
+ SourceText -- Note [Pragma source text] in GHC.Types.SourceText
+ StringLiteral -- "set cost centre" SCC pragma
+
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnOpen' @'{-\# GENERATED'@,
+ -- 'GHC.Parser.Annotation.AnnVal','GHC.Parser.Annotation.AnnVal',
+ -- 'GHC.Parser.Annotation.AnnColon','GHC.Parser.Annotation.AnnVal',
+ -- 'GHC.Parser.Annotation.AnnMinus',
+ -- 'GHC.Parser.Annotation.AnnVal','GHC.Parser.Annotation.AnnColon',
+ -- 'GHC.Parser.Annotation.AnnVal',
+ -- 'GHC.Parser.Annotation.AnnClose' @'\#-}'@
+
+ | XHsPragE !(XXPragE p)
+
+-- | Located Haskell Tuple Argument
+--
+-- 'HsTupArg' is used for tuple sections
+-- @(,a,)@ is represented by
+-- @ExplicitTuple [Missing ty1, Present a, Missing ty3]@
+-- Which in turn stands for @(\x:ty1 \y:ty2. (x,a,y))@
+type LHsTupArg id = XRec id (HsTupArg id)
+-- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnComma'
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-- | Haskell Tuple Argument
+data HsTupArg id
+ = Present (XPresent id) (LHsExpr id) -- ^ The argument
+ | Missing (XMissing id) -- ^ The argument is missing, but this is its type
+ | XTupArg !(XXTupArg id) -- ^ Note [Trees that Grow] extension point
+
+{-
+Note [Parens in HsSyn]
+~~~~~~~~~~~~~~~~~~~~~~
+HsPar (and ParPat in patterns, HsParTy in types) is used as follows
+
+ * HsPar is required; the pretty printer does not add parens.
+
+ * HsPars are respected when rearranging operator fixities.
+ So a * (b + c) means what it says (where the parens are an HsPar)
+
+ * For ParPat and HsParTy the pretty printer does add parens but this should be
+ a no-op for ParsedSource, based on the pretty printer round trip feature
+ introduced in
+ https://phabricator.haskell.org/rGHC499e43824bda967546ebf95ee33ec1f84a114a7c
+
+ * ParPat and HsParTy are pretty printed as '( .. )' regardless of whether or
+ not they are strictly necessary. This should be addressed when #13238 is
+ completed, to be treated the same as HsPar.
+
+
+Note [Sections in HsSyn]
+~~~~~~~~~~~~~~~~~~~~~~~~
+Sections should always appear wrapped in an HsPar, thus
+ HsPar (SectionR ...)
+The parser parses sections in a wider variety of situations
+(See Note [Parsing sections]), but the renamer checks for those
+parens. This invariant makes pretty-printing easier; we don't need
+a special case for adding the parens round sections.
+
+Note [Rebindable if]
+~~~~~~~~~~~~~~~~~~~~
+The rebindable syntax for 'if' is a bit special, because when
+rebindable syntax is *off* we do not want to treat
+ (if c then t else e)
+as if it was an application (ifThenElse c t e). Why not?
+Because we allow an 'if' to return *unboxed* results, thus
+ if blah then 3# else 4#
+whereas that would not be possible using a all to a polymorphic function
+(because you can't call a polymorphic function at an unboxed type).
+
+So we use NoSyntaxExpr to mean "use the old built-in typing rule".
+
+A further complication is that, in the `deriving` code, we never want
+to use rebindable syntax. So, even in GhcPs, we want to denote whether
+to use rebindable syntax or not. This is done via the type instance
+for XIf GhcPs.
+
+Note [Record Update HsWrapper]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+There is a wrapper in RecordUpd which is used for the *required*
+constraints for pattern synonyms. This wrapper is created in the
+typechecking and is then directly used in the desugaring without
+modification.
+
+For example, if we have the record pattern synonym P,
+ pattern P :: (Show a) => a -> Maybe a
+ pattern P{x} = Just x
+
+ foo = (Just True) { x = False }
+then `foo` desugars to something like
+ foo = case Just True of
+ P x -> P False
+hence we need to provide the correct dictionaries to P's matcher on
+the RHS so that we can build the expression.
+
+Note [Located RdrNames]
+~~~~~~~~~~~~~~~~~~~~~~~
+A number of syntax elements have seemingly redundant locations attached to them.
+This is deliberate, to allow transformations making use of the API Annotations
+to easily correlate a Located Name in the RenamedSource with a Located RdrName
+in the ParsedSource.
+
+There are unfortunately enough differences between the ParsedSource and the
+RenamedSource that the API Annotations cannot be used directly with
+RenamedSource, so this allows a simple mapping to be used based on the location.
+
+Note [ExplicitTuple]
+~~~~~~~~~~~~~~~~~~~~
+An ExplicitTuple is never just a data constructor like (,,,).
+That is, the `[LHsTupArg p]` argument of `ExplicitTuple` has at least
+one `Present` member (and is thus never empty).
+
+A tuple data constructor like () or (,,,) is parsed as an `HsVar`, not an
+`ExplicitTuple`, and stays that way. This is important for two reasons:
+
+ 1. We don't need -XTupleSections for (,,,)
+ 2. The type variables in (,,,) can be instantiated with visible type application.
+ That is,
+
+ (,,) :: forall a b c. a -> b -> c -> (a,b,c)
+ (True,,) :: forall {b} {c}. b -> c -> (Bool,b,c)
+
+ Note that the tuple section has *inferred* arguments, while the data
+ constructor has *specified* ones.
+ (See Note [Required, Specified, and Inferred for types] in GHC.Tc.TyCl
+ for background.)
+
+Sadly, the grammar for this is actually ambiguous, and it's only thanks to the
+preference of a shift in a shift/reduce conflict that the parser works as this
+Note details. Search for a reference to this Note in GHC.Parser for further
+explanation.
+
+Note [Empty lists]
+~~~~~~~~~~~~~~~~~~
+An empty list could be considered either a data constructor (stored with
+HsVar) or an ExplicitList. This Note describes how empty lists flow through the
+various phases and why.
+
+Parsing
+-------
+An empty list is parsed by the sysdcon nonterminal. It thus comes to life via
+HsVar nilDataCon (defined in GHC.Builtin.Types). A freshly-parsed (HsExpr GhcPs) empty list
+is never a ExplicitList.
+
+Renaming
+--------
+If -XOverloadedLists is enabled, we must type-check the empty list as if it
+were a call to fromListN. (This is true regardless of the setting of
+-XRebindableSyntax.) This is very easy if the empty list is an ExplicitList,
+but an annoying special case if it's an HsVar. So the renamer changes a
+HsVar nilDataCon to an ExplicitList [], but only if -XOverloadedLists is on.
+(Why not always? Read on, dear friend.) This happens in the HsVar case of rnExpr.
+
+Type-checking
+-------------
+We want to accept an expression like [] @Int. To do this, we must infer that
+[] :: forall a. [a]. This is easy if [] is a HsVar with the right DataCon inside.
+However, the type-checking for explicit lists works differently: [x,y,z] is never
+polymorphic. Instead, we unify the types of x, y, and z together, and use the
+unified type as the argument to the cons and nil constructors. Thus, treating
+[] as an empty ExplicitList in the type-checker would prevent [] @Int from working.
+
+However, if -XOverloadedLists is on, then [] @Int really shouldn't be allowed:
+it's just like fromListN 0 [] @Int. Since
+ fromListN :: forall list. IsList list => Int -> [Item list] -> list
+that expression really should be rejected. Thus, the renamer's behaviour is
+exactly what we want: treat [] as a datacon when -XNoOverloadedLists, and as
+an empty ExplicitList when -XOverloadedLists.
+
+See also #13680, which requested [] @Int to work.
+-}
+
+
+-----------------------
+pprExternalSrcLoc :: (StringLiteral,(Int,Int),(Int,Int)) -> SDoc
+pprExternalSrcLoc (StringLiteral _ src,(n1,n2),(n3,n4))
+ = ppr (src,(n1,n2),(n3,n4))
+
+{-
+HsSyn records exactly where the user put parens, with HsPar.
+So generally speaking we print without adding any parens.
+However, some code is internally generated, and in some places
+parens are absolutely required; so for these places we use
+pprParendLExpr (but don't print double parens of course).
+
+For operator applications we don't add parens, because the operator
+fixities should do the job, except in debug mode (-dppr-debug) so we
+can see the structure of the parse tree.
+-}
+
+{-
+************************************************************************
+* *
+\subsection{Commands (in arrow abstractions)}
+* *
+************************************************************************
+
+We re-use HsExpr to represent these.
+-}
+
+-- | Located Haskell Command (for arrow syntax)
+type LHsCmd id = XRec id (HsCmd id)
+
+-- | Haskell Command (e.g. a "statement" in an Arrow proc block)
+data HsCmd id
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.Annlarrowtail',
+ -- 'GHC.Parser.Annotation.Annrarrowtail','GHC.Parser.Annotation.AnnLarrowtail',
+ -- 'GHC.Parser.Annotation.AnnRarrowtail'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ = HsCmdArrApp -- Arrow tail, or arrow application (f -< arg)
+ (XCmdArrApp id) -- type of the arrow expressions f,
+ -- of the form a t t', where arg :: t
+ (LHsExpr id) -- arrow expression, f
+ (LHsExpr id) -- input expression, arg
+ HsArrAppType -- higher-order (-<<) or first-order (-<)
+ Bool -- True => right-to-left (f -< arg)
+ -- False => left-to-right (arg >- f)
+
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpenB' @'(|'@,
+ -- 'GHC.Parser.Annotation.AnnCloseB' @'|)'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | HsCmdArrForm -- Command formation, (| e cmd1 .. cmdn |)
+ (XCmdArrForm id)
+ (LHsExpr id) -- The operator.
+ -- After type-checking, a type abstraction to be
+ -- applied to the type of the local environment tuple
+ LexicalFixity -- Whether the operator appeared prefix or infix when
+ -- parsed.
+ (Maybe Fixity) -- fixity (filled in by the renamer), for forms that
+ -- were converted from OpApp's by the renamer
+ [LHsCmdTop id] -- argument commands
+
+ | HsCmdApp (XCmdApp id)
+ (LHsCmd id)
+ (LHsExpr id)
+
+ | HsCmdLam (XCmdLam id)
+ (MatchGroup id (LHsCmd id)) -- kappa
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnLam',
+ -- 'GHC.Parser.Annotation.AnnRarrow',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsCmdPar (XCmdPar id)
+ (LHsCmd id) -- parenthesised command
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'('@,
+ -- 'GHC.Parser.Annotation.AnnClose' @')'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsCmdCase (XCmdCase id)
+ (LHsExpr id)
+ (MatchGroup id (LHsCmd id)) -- bodies are HsCmd's
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnCase',
+ -- 'GHC.Parser.Annotation.AnnOf','GHC.Parser.Annotation.AnnOpen' @'{'@,
+ -- 'GHC.Parser.Annotation.AnnClose' @'}'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsCmdLamCase (XCmdLamCase id)
+ (MatchGroup id (LHsCmd id)) -- bodies are HsCmd's
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnLam',
+ -- 'GHC.Parser.Annotation.AnnCase','GHC.Parser.Annotation.AnnOpen' @'{'@,
+ -- 'GHC.Parser.Annotation.AnnClose' @'}'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsCmdIf (XCmdIf id)
+ (SyntaxExpr id) -- cond function
+ (LHsExpr id) -- predicate
+ (LHsCmd id) -- then part
+ (LHsCmd id) -- else part
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnIf',
+ -- 'GHC.Parser.Annotation.AnnSemi',
+ -- 'GHC.Parser.Annotation.AnnThen','GHC.Parser.Annotation.AnnSemi',
+ -- 'GHC.Parser.Annotation.AnnElse',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsCmdLet (XCmdLet id)
+ (LHsLocalBinds id) -- let(rec)
+ (LHsCmd id)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnLet',
+ -- 'GHC.Parser.Annotation.AnnOpen' @'{'@,
+ -- 'GHC.Parser.Annotation.AnnClose' @'}'@,'GHC.Parser.Annotation.AnnIn'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsCmdDo (XCmdDo id) -- Type of the whole expression
+ (XRec id [CmdLStmt id])
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnDo',
+ -- 'GHC.Parser.Annotation.AnnOpen', 'GHC.Parser.Annotation.AnnSemi',
+ -- 'GHC.Parser.Annotation.AnnVbar',
+ -- 'GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | XCmd !(XXCmd id) -- Note [Trees that Grow] extension point
+
+
+-- | Haskell Array Application Type
+data HsArrAppType = HsHigherOrderApp | HsFirstOrderApp
+ deriving Data
+
+
+{- | Top-level command, introducing a new arrow.
+This may occur inside a proc (where the stack is empty) or as an
+argument of a command-forming operator.
+-}
+
+-- | Located Haskell Top-level Command
+type LHsCmdTop p = XRec p (HsCmdTop p)
+
+-- | Haskell Top-level Command
+data HsCmdTop p
+ = HsCmdTop (XCmdTop p)
+ (LHsCmd p)
+ | XCmdTop !(XXCmdTop p) -- Note [Trees that Grow] extension point
+
+-----------------------
+
+{-
+************************************************************************
+* *
+\subsection{Record binds}
+* *
+************************************************************************
+-}
+
+-- | Haskell Record Bindings
+type HsRecordBinds p = HsRecFields p (LHsExpr p)
+
+{-
+************************************************************************
+* *
+\subsection{@Match@, @GRHSs@, and @GRHS@ datatypes}
+* *
+************************************************************************
+
+@Match@es are sets of pattern bindings and right hand sides for
+functions, patterns or case branches. For example, if a function @g@
+is defined as:
+\begin{verbatim}
+g (x,y) = y
+g ((x:ys),y) = y+1,
+\end{verbatim}
+then \tr{g} has two @Match@es: @(x,y) = y@ and @((x:ys),y) = y+1@.
+
+It is always the case that each element of an @[Match]@ list has the
+same number of @pats@s inside it. This corresponds to saying that
+a function defined by pattern matching must have the same number of
+patterns in each equation.
+-}
+
+data MatchGroup p body
+ = MG { mg_ext :: XMG p body -- Post-typechecker, types of args and result
+ , mg_alts :: XRec p [LMatch p body] -- The alternatives
+ , mg_origin :: Origin }
+ -- The type is the type of the entire group
+ -- t1 -> ... -> tn -> tr
+ -- where there are n patterns
+ | XMatchGroup !(XXMatchGroup p body)
+
+data MatchGroupTc
+ = MatchGroupTc
+ { mg_arg_tys :: [Scaled Type] -- Types of the arguments, t1..tn
+ , mg_res_ty :: Type -- Type of the result, tr
+ } deriving Data
+
+-- | Located Match
+type LMatch id body = XRec id (Match id body)
+-- ^ May have 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnSemi' when in a
+-- list
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+data Match p body
+ = Match {
+ m_ext :: XCMatch p body,
+ m_ctxt :: HsMatchContext (NoGhcTc p),
+ -- See note [m_ctxt in Match]
+ m_pats :: [LPat p], -- The patterns
+ m_grhss :: (GRHSs p body)
+ }
+ | XMatch !(XXMatch p body)
+
+{-
+Note [m_ctxt in Match]
+~~~~~~~~~~~~~~~~~~~~~~
+
+A Match can occur in a number of contexts, such as a FunBind, HsCase, HsLam and
+so on.
+
+In order to simplify tooling processing and pretty print output, the provenance
+is captured in an HsMatchContext.
+
+This is particularly important for the API Annotations for a multi-equation
+FunBind.
+
+The parser initially creates a FunBind with a single Match in it for
+every function definition it sees.
+
+These are then grouped together by getMonoBind into a single FunBind,
+where all the Matches are combined.
+
+In the process, all the original FunBind fun_id's bar one are
+discarded, including the locations.
+
+This causes a problem for source to source conversions via API
+Annotations, so the original fun_ids and infix flags are preserved in
+the Match, when it originates from a FunBind.
+
+Example infix function definition requiring individual API Annotations
+
+ (&&& ) [] [] = []
+ xs &&& [] = xs
+ ( &&& ) [] ys = ys
+
+
+
+-}
+
+
+isInfixMatch :: Match id body -> Bool
+isInfixMatch match = case m_ctxt match of
+ FunRhs {mc_fixity = Infix} -> True
+ _ -> False
+
+-- | Guarded Right-Hand Sides
+--
+-- GRHSs are used both for pattern bindings and for Matches
+--
+-- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnVbar',
+-- 'GHC.Parser.Annotation.AnnEqual','GHC.Parser.Annotation.AnnWhere',
+-- 'GHC.Parser.Annotation.AnnOpen','GHC.Parser.Annotation.AnnClose'
+-- 'GHC.Parser.Annotation.AnnRarrow','GHC.Parser.Annotation.AnnSemi'
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+data GRHSs p body
+ = GRHSs {
+ grhssExt :: XCGRHSs p body,
+ grhssGRHSs :: [LGRHS p body], -- ^ Guarded RHSs
+ grhssLocalBinds :: LHsLocalBinds p -- ^ The where clause
+ }
+ | XGRHSs !(XXGRHSs p body)
+
+-- | Located Guarded Right-Hand Side
+type LGRHS id body = XRec id (GRHS id body)
+
+-- | Guarded Right Hand Side.
+data GRHS p body = GRHS (XCGRHS p body)
+ [GuardLStmt p] -- Guards
+ body -- Right hand side
+ | XGRHS !(XXGRHS p body)
+
+-- We know the list must have at least one @Match@ in it.
+
+{-
+************************************************************************
+* *
+\subsection{Do stmts and list comprehensions}
+* *
+************************************************************************
+-}
+
+-- | Located @do@ block Statement
+type LStmt id body = XRec id (StmtLR id id body)
+
+-- | Located Statement with separate Left and Right id's
+type LStmtLR idL idR body = XRec idL (StmtLR idL idR body)
+
+-- | @do@ block Statement
+type Stmt id body = StmtLR id id body
+
+-- | Command Located Statement
+type CmdLStmt id = LStmt id (LHsCmd id)
+
+-- | Command Statement
+type CmdStmt id = Stmt id (LHsCmd id)
+
+-- | Expression Located Statement
+type ExprLStmt id = LStmt id (LHsExpr id)
+
+-- | Expression Statement
+type ExprStmt id = Stmt id (LHsExpr id)
+
+-- | Guard Located Statement
+type GuardLStmt id = LStmt id (LHsExpr id)
+
+-- | Guard Statement
+type GuardStmt id = Stmt id (LHsExpr id)
+
+-- | Ghci Located Statement
+type GhciLStmt id = LStmt id (LHsExpr id)
+
+-- | Ghci Statement
+type GhciStmt id = Stmt id (LHsExpr id)
+
+-- The SyntaxExprs in here are used *only* for do-notation and monad
+-- comprehensions, which have rebindable syntax. Otherwise they are unused.
+-- | API Annotations when in qualifier lists or guards
+-- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnVbar',
+-- 'GHC.Parser.Annotation.AnnComma','GHC.Parser.Annotation.AnnThen',
+-- 'GHC.Parser.Annotation.AnnBy','GHC.Parser.Annotation.AnnBy',
+-- 'GHC.Parser.Annotation.AnnGroup','GHC.Parser.Annotation.AnnUsing'
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+data StmtLR idL idR body -- body should always be (LHs**** idR)
+ = LastStmt -- Always the last Stmt in ListComp, MonadComp,
+ -- and (after the renamer, see GHC.Rename.Expr.checkLastStmt) DoExpr, MDoExpr
+ -- Not used for GhciStmtCtxt, PatGuard, which scope over other stuff
+ (XLastStmt idL idR body)
+ body
+ (Maybe Bool) -- Whether return was stripped
+ -- Just True <=> return with a dollar was stripped by ApplicativeDo
+ -- Just False <=> return without a dollar was stripped by ApplicativeDo
+ -- Nothing <=> Nothing was stripped
+ (SyntaxExpr idR) -- The return operator
+ -- The return operator is used only for MonadComp
+ -- For ListComp we use the baked-in 'return'
+ -- For DoExpr, MDoExpr, we don't apply a 'return' at all
+ -- See Note [Monad Comprehensions]
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnLarrow'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | BindStmt (XBindStmt idL idR body)
+ -- ^ Post renaming has optional fail and bind / (>>=) operator.
+ -- Post typechecking, also has multiplicity of the argument
+ -- and the result type of the function passed to bind;
+ -- that is, (P, S) in (>>=) :: Q -> (R # P -> S) -> T
+ -- See Note [The type of bind in Stmts]
+ (LPat idL)
+ body
+
+ -- | 'ApplicativeStmt' represents an applicative expression built with
+ -- '<$>' and '<*>'. It is generated by the renamer, and is desugared into the
+ -- appropriate applicative expression by the desugarer, but it is intended
+ -- to be invisible in error messages.
+ --
+ -- For full details, see Note [ApplicativeDo] in "GHC.Rename.Expr"
+ --
+ | ApplicativeStmt
+ (XApplicativeStmt idL idR body) -- Post typecheck, Type of the body
+ [ ( SyntaxExpr idR
+ , ApplicativeArg idL) ]
+ -- [(<$>, e1), (<*>, e2), ..., (<*>, en)]
+ (Maybe (SyntaxExpr idR)) -- 'join', if necessary
+
+ | BodyStmt (XBodyStmt idL idR body) -- Post typecheck, element type
+ -- of the RHS (used for arrows)
+ body -- See Note [BodyStmt]
+ (SyntaxExpr idR) -- The (>>) operator
+ (SyntaxExpr idR) -- The `guard` operator; used only in MonadComp
+ -- See notes [Monad Comprehensions]
+
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnLet'
+ -- 'GHC.Parser.Annotation.AnnOpen' @'{'@,'GHC.Parser.Annotation.AnnClose' @'}'@,
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | LetStmt (XLetStmt idL idR body) (LHsLocalBindsLR idL idR)
+
+ -- ParStmts only occur in a list/monad comprehension
+ | ParStmt (XParStmt idL idR body) -- Post typecheck,
+ -- S in (>>=) :: Q -> (R -> S) -> T
+ [ParStmtBlock idL idR]
+ (HsExpr idR) -- Polymorphic `mzip` for monad comprehensions
+ (SyntaxExpr idR) -- The `>>=` operator
+ -- See notes [Monad Comprehensions]
+ -- After renaming, the ids are the binders
+ -- bound by the stmts and used after themp
+
+ | TransStmt {
+ trS_ext :: XTransStmt idL idR body, -- Post typecheck,
+ -- R in (>>=) :: Q -> (R -> S) -> T
+ trS_form :: TransForm,
+ trS_stmts :: [ExprLStmt idL], -- Stmts to the *left* of the 'group'
+ -- which generates the tuples to be grouped
+
+ trS_bndrs :: [(IdP idR, IdP idR)], -- See Note [TransStmt binder map]
+
+ trS_using :: LHsExpr idR,
+ trS_by :: Maybe (LHsExpr idR), -- "by e" (optional)
+ -- Invariant: if trS_form = GroupBy, then grp_by = Just e
+
+ trS_ret :: SyntaxExpr idR, -- The monomorphic 'return' function for
+ -- the inner monad comprehensions
+ trS_bind :: SyntaxExpr idR, -- The '(>>=)' operator
+ trS_fmap :: HsExpr idR -- The polymorphic 'fmap' function for desugaring
+ -- Only for 'group' forms
+ -- Just a simple HsExpr, because it's
+ -- too polymorphic for tcSyntaxOp
+ } -- See Note [Monad Comprehensions]
+
+ -- Recursive statement (see Note [How RecStmt works] below)
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnRec'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | RecStmt
+ { recS_ext :: XRecStmt idL idR body
+ , recS_stmts :: [LStmtLR idL idR body]
+
+ -- The next two fields are only valid after renaming
+ , recS_later_ids :: [IdP idR]
+ -- The ids are a subset of the variables bound by the
+ -- stmts that are used in stmts that follow the RecStmt
+
+ , recS_rec_ids :: [IdP idR]
+ -- Ditto, but these variables are the "recursive" ones,
+ -- that are used before they are bound in the stmts of
+ -- the RecStmt.
+ -- An Id can be in both groups
+ -- Both sets of Ids are (now) treated monomorphically
+ -- See Note [How RecStmt works] for why they are separate
+
+ -- Rebindable syntax
+ , recS_bind_fn :: SyntaxExpr idR -- The bind function
+ , recS_ret_fn :: SyntaxExpr idR -- The return function
+ , recS_mfix_fn :: SyntaxExpr idR -- The mfix function
+ }
+ | XStmtLR !(XXStmtLR idL idR body)
+
+data TransForm -- The 'f' below is the 'using' function, 'e' is the by function
+ = ThenForm -- then f or then f by e (depending on trS_by)
+ | GroupForm -- then group using f or then group by e using f (depending on trS_by)
+ deriving Data
+
+-- | Parenthesised Statement Block
+data ParStmtBlock idL idR
+ = ParStmtBlock
+ (XParStmtBlock idL idR)
+ [ExprLStmt idL]
+ [IdP idR] -- The variables to be returned
+ (SyntaxExpr idR) -- The return operator
+ | XParStmtBlock !(XXParStmtBlock idL idR)
+
+-- | The fail operator
+--
+-- This is used for `.. <-` "bind statments" in do notation, including
+-- non-monadic "binds" in applicative.
+--
+-- The fail operator is 'Just expr' if it potentially fail monadically. if the
+-- pattern match cannot fail, or shouldn't fail monadically (regular incomplete
+-- pattern exception), it is 'Nothing'.
+--
+-- See Note [Monad fail : Rebindable syntax, overloaded strings] for the type of
+-- expression in the 'Just' case, and why it is so.
+--
+-- See Note [Failing pattern matches in Stmts] for which contexts for
+-- '@BindStmt@'s should use the monadic fail and which shouldn't.
+type FailOperator id = Maybe (SyntaxExpr id)
+
+-- | Applicative Argument
+data ApplicativeArg idL
+ = ApplicativeArgOne -- A single statement (BindStmt or BodyStmt)
+ { xarg_app_arg_one :: XApplicativeArgOne idL
+ -- ^ The fail operator, after renaming
+ --
+ -- The fail operator is needed if this is a BindStmt
+ -- where the pattern can fail. E.g.:
+ -- (Just a) <- stmt
+ -- The fail operator will be invoked if the pattern
+ -- match fails.
+ -- It is also used for guards in MonadComprehensions.
+ -- The fail operator is Nothing
+ -- if the pattern match can't fail
+ , app_arg_pattern :: LPat idL -- WildPat if it was a BodyStmt (see below)
+ , arg_expr :: LHsExpr idL
+ , is_body_stmt :: Bool
+ -- ^ True <=> was a BodyStmt,
+ -- False <=> was a BindStmt.
+ -- See Note [Applicative BodyStmt]
+ }
+ | ApplicativeArgMany -- do { stmts; return vars }
+ { xarg_app_arg_many :: XApplicativeArgMany idL
+ , app_stmts :: [ExprLStmt idL] -- stmts
+ , final_expr :: HsExpr idL -- return (v1,..,vn), or just (v1,..,vn)
+ , bv_pattern :: LPat idL -- (v1,...,vn)
+ , stmt_context :: HsStmtContext (ApplicativeArgStmCtxPass idL)
+ -- ^ context of the do expression, used in pprArg
+ }
+ | XApplicativeArg !(XXApplicativeArg idL)
+
+type family ApplicativeArgStmCtxPass idL
+
+{-
+Note [The type of bind in Stmts]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Some Stmts, notably BindStmt, keep the (>>=) bind operator.
+We do NOT assume that it has type
+ (>>=) :: m a -> (a -> m b) -> m b
+In some cases (see #303, #1537) it might have a more
+exotic type, such as
+ (>>=) :: m i j a -> (a -> m j k b) -> m i k b
+So we must be careful not to make assumptions about the type.
+In particular, the monad may not be uniform throughout.
+
+Note [TransStmt binder map]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The [(idR,idR)] in a TransStmt behaves as follows:
+
+ * Before renaming: []
+
+ * After renaming:
+ [ (x27,x27), ..., (z35,z35) ]
+ These are the variables
+ bound by the stmts to the left of the 'group'
+ and used either in the 'by' clause,
+ or in the stmts following the 'group'
+ Each item is a pair of identical variables.
+
+ * After typechecking:
+ [ (x27:Int, x27:[Int]), ..., (z35:Bool, z35:[Bool]) ]
+ Each pair has the same unique, but different *types*.
+
+Note [BodyStmt]
+~~~~~~~~~~~~~~~
+BodyStmts are a bit tricky, because what they mean
+depends on the context. Consider the following contexts:
+
+ A do expression of type (m res_ty)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * BodyStmt E any_ty: do { ....; E; ... }
+ E :: m any_ty
+ Translation: E >> ...
+
+ A list comprehensions of type [elt_ty]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * BodyStmt E Bool: [ .. | .... E ]
+ [ .. | ..., E, ... ]
+ [ .. | .... | ..., E | ... ]
+ E :: Bool
+ Translation: if E then fail else ...
+
+ A guard list, guarding a RHS of type rhs_ty
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * BodyStmt E BooParStmtBlockl: f x | ..., E, ... = ...rhs...
+ E :: Bool
+ Translation: if E then fail else ...
+
+ A monad comprehension of type (m res_ty)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * BodyStmt E Bool: [ .. | .... E ]
+ E :: Bool
+ Translation: guard E >> ...
+
+Array comprehensions are handled like list comprehensions.
+
+Note [How RecStmt works]
+~~~~~~~~~~~~~~~~~~~~~~~~
+Example:
+ HsDo [ BindStmt x ex
+
+ , RecStmt { recS_rec_ids = [a, c]
+ , recS_stmts = [ BindStmt b (return (a,c))
+ , LetStmt a = ...b...
+ , BindStmt c ec ]
+ , recS_later_ids = [a, b]
+
+ , return (a b) ]
+
+Here, the RecStmt binds a,b,c; but
+ - Only a,b are used in the stmts *following* the RecStmt,
+ - Only a,c are used in the stmts *inside* the RecStmt
+ *before* their bindings
+
+Why do we need *both* rec_ids and later_ids? For monads they could be
+combined into a single set of variables, but not for arrows. That
+follows from the types of the respective feedback operators:
+
+ mfix :: MonadFix m => (a -> m a) -> m a
+ loop :: ArrowLoop a => a (b,d) (c,d) -> a b c
+
+* For mfix, the 'a' covers the union of the later_ids and the rec_ids
+* For 'loop', 'c' is the later_ids and 'd' is the rec_ids
+
+Note [Typing a RecStmt]
+~~~~~~~~~~~~~~~~~~~~~~~
+A (RecStmt stmts) types as if you had written
+
+ (v1,..,vn, _, ..., _) <- mfix (\~(_, ..., _, r1, ..., rm) ->
+ do { stmts
+ ; return (v1,..vn, r1, ..., rm) })
+
+where v1..vn are the later_ids
+ r1..rm are the rec_ids
+
+Note [Monad Comprehensions]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Monad comprehensions require separate functions like 'return' and
+'>>=' for desugaring. These functions are stored in the statements
+used in monad comprehensions. For example, the 'return' of the 'LastStmt'
+expression is used to lift the body of the monad comprehension:
+
+ [ body | stmts ]
+ =>
+ stmts >>= \bndrs -> return body
+
+In transform and grouping statements ('then ..' and 'then group ..') the
+'return' function is required for nested monad comprehensions, for example:
+
+ [ body | stmts, then f, rest ]
+ =>
+ f [ env | stmts ] >>= \bndrs -> [ body | rest ]
+
+BodyStmts require the 'Control.Monad.guard' function for boolean
+expressions:
+
+ [ body | exp, stmts ]
+ =>
+ guard exp >> [ body | stmts ]
+
+Parallel statements require the 'Control.Monad.Zip.mzip' function:
+
+ [ body | stmts1 | stmts2 | .. ]
+ =>
+ mzip stmts1 (mzip stmts2 (..)) >>= \(bndrs1, (bndrs2, ..)) -> return body
+
+In any other context than 'MonadComp', the fields for most of these
+'SyntaxExpr's stay bottom.
+
+
+Note [Applicative BodyStmt]
+
+(#12143) For the purposes of ApplicativeDo, we treat any BodyStmt
+as if it was a BindStmt with a wildcard pattern. For example,
+
+ do
+ x <- A
+ B
+ return x
+
+is transformed as if it were
+
+ do
+ x <- A
+ _ <- B
+ return x
+
+so it transforms to
+
+ (\(x,_) -> x) <$> A <*> B
+
+But we have to remember when we treat a BodyStmt like a BindStmt,
+because in error messages we want to emit the original syntax the user
+wrote, not our internal representation. So ApplicativeArgOne has a
+Bool flag that is True when the original statement was a BodyStmt, so
+that we can pretty-print it correctly.
+-}
+
+
+{-
+************************************************************************
+* *
+ Template Haskell quotation brackets
+* *
+************************************************************************
+-}
+
+-- | Haskell Splice
+data HsSplice id
+ = HsTypedSplice -- $$z or $$(f 4)
+ (XTypedSplice id)
+ SpliceDecoration -- Whether $$( ) variant found, for pretty printing
+ (IdP id) -- A unique name to identify this splice point
+ (LHsExpr id) -- See Note [Pending Splices]
+
+ | HsUntypedSplice -- $z or $(f 4)
+ (XUntypedSplice id)
+ SpliceDecoration -- Whether $( ) variant found, for pretty printing
+ (IdP id) -- A unique name to identify this splice point
+ (LHsExpr id) -- See Note [Pending Splices]
+
+ | HsQuasiQuote -- See Note [Quasi-quote overview] in GHC.Tc.Gen.Splice
+ (XQuasiQuote id)
+ (IdP id) -- Splice point
+ (IdP id) -- Quoter
+ SrcSpan -- The span of the enclosed string
+ FastString -- The enclosed string
+
+ -- AZ:TODO: use XSplice instead of HsSpliced
+ | HsSpliced -- See Note [Delaying modFinalizers in untyped splices] in
+ -- GHC.Rename.Splice.
+ -- This is the result of splicing a splice. It is produced by
+ -- the renamer and consumed by the typechecker. It lives only
+ -- between the two.
+ (XSpliced id)
+ ThModFinalizers -- TH finalizers produced by the splice.
+ (HsSplicedThing id) -- The result of splicing
+ | XSplice !(XXSplice id) -- Note [Trees that Grow] extension point
+
+-- | A splice can appear with various decorations wrapped around it. This data
+-- type captures explicitly how it was originally written, for use in the pretty
+-- printer.
+data SpliceDecoration
+ = DollarSplice -- ^ $splice or $$splice
+ | BareSplice -- ^ bare splice
+ deriving (Data, Eq, Show)
+
+instance Outputable SpliceDecoration where
+ ppr x = text $ show x
+
+
+isTypedSplice :: HsSplice id -> Bool
+isTypedSplice (HsTypedSplice {}) = True
+isTypedSplice _ = False -- Quasi-quotes are untyped splices
+
+-- | Finalizers produced by a splice with
+-- 'Language.Haskell.TH.Syntax.addModFinalizer'
+--
+-- See Note [Delaying modFinalizers in untyped splices] in GHC.Rename.Splice. For how
+-- this is used.
+--
+newtype ThModFinalizers = ThModFinalizers [ForeignRef (TH.Q ())]
+
+-- A Data instance which ignores the argument of 'ThModFinalizers'.
+instance Data ThModFinalizers where
+ gunfold _ z _ = z $ ThModFinalizers []
+ toConstr a = mkConstr (dataTypeOf a) "ThModFinalizers" [] Data.Prefix
+ dataTypeOf a = mkDataType "HsExpr.ThModFinalizers" [toConstr a]
+
+-- | Haskell Spliced Thing
+--
+-- Values that can result from running a splice.
+data HsSplicedThing id
+ = HsSplicedExpr (HsExpr id) -- ^ Haskell Spliced Expression
+ | HsSplicedTy (HsType id) -- ^ Haskell Spliced Type
+ | HsSplicedPat (Pat id) -- ^ Haskell Spliced Pattern
+
+
+-- See Note [Pending Splices]
+type SplicePointName = Name
+
+data UntypedSpliceFlavour
+ = UntypedExpSplice
+ | UntypedPatSplice
+ | UntypedTypeSplice
+ | UntypedDeclSplice
+ deriving Data
+
+-- | Haskell Bracket
+data HsBracket p
+ = ExpBr (XExpBr p) (LHsExpr p) -- [| expr |]
+ | PatBr (XPatBr p) (LPat p) -- [p| pat |]
+ | DecBrL (XDecBrL p) [LHsDecl p] -- [d| decls |]; result of parser
+ | DecBrG (XDecBrG p) (HsGroup p) -- [d| decls |]; result of renamer
+ | TypBr (XTypBr p) (LHsType p) -- [t| type |]
+ | VarBr (XVarBr p) Bool (IdP p) -- True: 'x, False: ''T
+ -- (The Bool flag is used only in pprHsBracket)
+ | TExpBr (XTExpBr p) (LHsExpr p) -- [|| expr ||]
+ | XBracket !(XXBracket p) -- Note [Trees that Grow] extension point
+
+isTypedBracket :: HsBracket id -> Bool
+isTypedBracket (TExpBr {}) = True
+isTypedBracket _ = False
+
+{-
+************************************************************************
+* *
+\subsection{Enumerations and list comprehensions}
+* *
+************************************************************************
+-}
+
+-- | Arithmetic Sequence Information
+data ArithSeqInfo id
+ = From (LHsExpr id)
+ | FromThen (LHsExpr id)
+ (LHsExpr id)
+ | FromTo (LHsExpr id)
+ (LHsExpr id)
+ | FromThenTo (LHsExpr id)
+ (LHsExpr id)
+ (LHsExpr id)
+-- AZ: Should ArithSeqInfo have a TTG extension?
+
+{-
+************************************************************************
+* *
+\subsection{HsMatchCtxt}
+* *
+************************************************************************
+-}
+
+-- | Haskell Match Context
+--
+-- Context of a pattern match. This is more subtle than it would seem. See Note
+-- [Varieties of pattern matches].
+data HsMatchContext p
+ = FunRhs { mc_fun :: LIdP p -- ^ function binder of @f@
+ , mc_fixity :: LexicalFixity -- ^ fixing of @f@
+ , mc_strictness :: SrcStrictness -- ^ was @f@ banged?
+ -- See Note [FunBind vs PatBind]
+ }
+ -- ^A pattern matching on an argument of a
+ -- function binding
+ | LambdaExpr -- ^Patterns of a lambda
+ | CaseAlt -- ^Patterns and guards on a case alternative
+ | IfAlt -- ^Guards of a multi-way if alternative
+ | ProcExpr -- ^Patterns of a proc
+ | PatBindRhs -- ^A pattern binding eg [y] <- e = e
+ | PatBindGuards -- ^Guards of pattern bindings, e.g.,
+ -- (Just b) | Just _ <- x = e
+ -- | otherwise = e'
+
+ | RecUpd -- ^Record update [used only in GHC.HsToCore.Expr to
+ -- tell matchWrapper what sort of
+ -- runtime error message to generate]
+
+ | StmtCtxt (HsStmtContext p) -- ^Pattern of a do-stmt, list comprehension,
+ -- pattern guard, etc
+
+ | ThPatSplice -- ^A Template Haskell pattern splice
+ | ThPatQuote -- ^A Template Haskell pattern quotation [p| (a,b) |]
+ | PatSyn -- ^A pattern synonym declaration
+
+isPatSynCtxt :: HsMatchContext p -> Bool
+isPatSynCtxt ctxt =
+ case ctxt of
+ PatSyn -> True
+ _ -> False
+
+-- | Haskell Statement Context.
+data HsStmtContext p
+ = ListComp
+ | MonadComp
+
+ | DoExpr (Maybe ModuleName) -- ^[ModuleName.]do { ... }
+ | MDoExpr (Maybe ModuleName) -- ^[ModuleName.]mdo { ... } ie recursive do-expression
+ | ArrowExpr -- ^do-notation in an arrow-command context
+
+ | GhciStmtCtxt -- ^A command-line Stmt in GHCi pat <- rhs
+ | PatGuard (HsMatchContext p) -- ^Pattern guard for specified thing
+ | ParStmtCtxt (HsStmtContext p) -- ^A branch of a parallel stmt
+ | TransStmtCtxt (HsStmtContext p) -- ^A branch of a transform stmt
+
+qualifiedDoModuleName_maybe :: HsStmtContext p -> Maybe ModuleName
+qualifiedDoModuleName_maybe ctxt = case ctxt of
+ DoExpr m -> m
+ MDoExpr m -> m
+ _ -> Nothing
+
+isComprehensionContext :: HsStmtContext id -> Bool
+-- Uses comprehension syntax [ e | quals ]
+isComprehensionContext ListComp = True
+isComprehensionContext MonadComp = True
+isComprehensionContext (ParStmtCtxt c) = isComprehensionContext c
+isComprehensionContext (TransStmtCtxt c) = isComprehensionContext c
+isComprehensionContext _ = False
+
+-- | Is this a monadic context?
+isMonadStmtContext :: HsStmtContext id -> Bool
+isMonadStmtContext MonadComp = True
+isMonadStmtContext DoExpr{} = True
+isMonadStmtContext MDoExpr{} = True
+isMonadStmtContext GhciStmtCtxt = True
+isMonadStmtContext (ParStmtCtxt ctxt) = isMonadStmtContext ctxt
+isMonadStmtContext (TransStmtCtxt ctxt) = isMonadStmtContext ctxt
+isMonadStmtContext _ = False -- ListComp, PatGuard, ArrowExpr
+
+isMonadCompContext :: HsStmtContext id -> Bool
+isMonadCompContext MonadComp = True
+isMonadCompContext _ = False
+
+matchSeparator :: HsMatchContext p -> SDoc
+matchSeparator (FunRhs {}) = text "="
+matchSeparator CaseAlt = text "->"
+matchSeparator IfAlt = text "->"
+matchSeparator LambdaExpr = text "->"
+matchSeparator ProcExpr = text "->"
+matchSeparator PatBindRhs = text "="
+matchSeparator PatBindGuards = text "="
+matchSeparator (StmtCtxt _) = text "<-"
+matchSeparator RecUpd = text "=" -- This can be printed by the pattern
+ -- match checker trace
+matchSeparator ThPatSplice = panic "unused"
+matchSeparator ThPatQuote = panic "unused"
+matchSeparator PatSyn = panic "unused"
+
+pprMatchContext :: (Outputable (IdP p), UnXRec p)
+ => HsMatchContext p -> SDoc
+pprMatchContext ctxt
+ | want_an ctxt = text "an" <+> pprMatchContextNoun ctxt
+ | otherwise = text "a" <+> pprMatchContextNoun ctxt
+ where
+ want_an (FunRhs {}) = True -- Use "an" in front
+ want_an ProcExpr = True
+ want_an _ = False
+
+pprMatchContextNoun :: forall p. (Outputable (IdP p), UnXRec p)
+ => HsMatchContext p -> SDoc
+pprMatchContextNoun (FunRhs {mc_fun=fun})
+ = text "equation for"
+ <+> quotes (ppr (unXRec @p fun))
+pprMatchContextNoun CaseAlt = text "case alternative"
+pprMatchContextNoun IfAlt = text "multi-way if alternative"
+pprMatchContextNoun RecUpd = text "record-update construct"
+pprMatchContextNoun ThPatSplice = text "Template Haskell pattern splice"
+pprMatchContextNoun ThPatQuote = text "Template Haskell pattern quotation"
+pprMatchContextNoun PatBindRhs = text "pattern binding"
+pprMatchContextNoun PatBindGuards = text "pattern binding guards"
+pprMatchContextNoun LambdaExpr = text "lambda abstraction"
+pprMatchContextNoun ProcExpr = text "arrow abstraction"
+pprMatchContextNoun (StmtCtxt ctxt) = text "pattern binding in"
+ $$ pprAStmtContext ctxt
+pprMatchContextNoun PatSyn = text "pattern synonym declaration"
+
+-----------------
+pprAStmtContext, pprStmtContext :: (Outputable (IdP p), UnXRec p)
+ => HsStmtContext p -> SDoc
+pprAStmtContext ctxt = article <+> pprStmtContext ctxt
+ where
+ pp_an = text "an"
+ pp_a = text "a"
+ article = case ctxt of
+ MDoExpr Nothing -> pp_an
+ GhciStmtCtxt -> pp_an
+ _ -> pp_a
+
+
+-----------------
+pprStmtContext GhciStmtCtxt = text "interactive GHCi command"
+pprStmtContext (DoExpr m) = prependQualified m (text "'do' block")
+pprStmtContext (MDoExpr m) = prependQualified m (text "'mdo' block")
+pprStmtContext ArrowExpr = text "'do' block in an arrow command"
+pprStmtContext ListComp = text "list comprehension"
+pprStmtContext MonadComp = text "monad comprehension"
+pprStmtContext (PatGuard ctxt) = text "pattern guard for" $$ pprMatchContext ctxt
+
+-- Drop the inner contexts when reporting errors, else we get
+-- Unexpected transform statement
+-- in a transformed branch of
+-- transformed branch of
+-- transformed branch of monad comprehension
+pprStmtContext (ParStmtCtxt c) =
+ ifPprDebug (sep [text "parallel branch of", pprAStmtContext c])
+ (pprStmtContext c)
+pprStmtContext (TransStmtCtxt c) =
+ ifPprDebug (sep [text "transformed branch of", pprAStmtContext c])
+ (pprStmtContext c)
+
+prependQualified :: Maybe ModuleName -> SDoc -> SDoc
+prependQualified Nothing t = t
+prependQualified (Just _) t = text "qualified" <+> t
diff --git a/compiler/Language/Haskell/Syntax/Expr.hs-boot b/compiler/Language/Haskell/Syntax/Expr.hs-boot
new file mode 100644
index 0000000000..3ea7e32708
--- /dev/null
+++ b/compiler/Language/Haskell/Syntax/Expr.hs-boot
@@ -0,0 +1,22 @@
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE RoleAnnotations #-}
+{-# LANGUAGE TypeFamilies #-}
+
+-- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.*
+module Language.Haskell.Syntax.Expr where
+
+import Language.Haskell.Syntax.Extension ( XRec )
+import Data.Kind ( Type )
+
+type role HsExpr nominal
+type role MatchGroup nominal nominal
+type role GRHSs nominal nominal
+type role HsSplice nominal
+data HsExpr (i :: Type)
+data HsSplice (i :: Type)
+data MatchGroup (a :: Type) (body :: Type)
+data GRHSs (a :: Type) (body :: Type)
+type family SyntaxExpr (i :: Type)
+
+type LHsExpr a = XRec a (HsExpr a)
diff --git a/compiler/Language/Haskell/Syntax/Extension.hs b/compiler/Language/Haskell/Syntax/Extension.hs
new file mode 100644
index 0000000000..16b11b3e30
--- /dev/null
+++ b/compiler/Language/Haskell/Syntax/Extension.hs
@@ -0,0 +1,665 @@
+{-# LANGUAGE AllowAmbiguousTypes #-} -- for unXRec, etc.
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE EmptyCase #-}
+{-# LANGUAGE EmptyDataDeriving #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilyDependencies #-}
+{-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow]
+ -- in module Language.Haskell.Syntax.Extension
+
+-- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.*
+module Language.Haskell.Syntax.Extension where
+
+-- This module captures the type families to precisely identify the extension
+-- points for GHC.Hs syntax
+
+import GHC.Prelude
+
+import Data.Data hiding ( Fixity )
+import Data.Kind (Type)
+import GHC.Utils.Outputable
+
+{-
+Note [Trees that grow]
+~~~~~~~~~~~~~~~~~~~~~~
+
+See https://gitlab.haskell.org/ghc/ghc/wikis/implementing-trees-that-grow
+
+The hsSyn AST is reused across multiple compiler passes. We also have the
+Template Haskell AST, and the haskell-src-exts one (outside of GHC)
+
+Supporting multiple passes means the AST has various warts on it to cope with
+the specifics for the phases, such as the 'ValBindsOut', 'ConPatOut',
+'SigPatOut' etc.
+
+The growable AST will allow each of these variants to be captured explicitly,
+such that they only exist in the given compiler pass AST, as selected by the
+type parameter to the AST.
+
+In addition it will allow tool writers to define their own extensions to capture
+additional information for the tool, in a natural way.
+
+A further goal is to provide a means to harmonise the Template Haskell and
+haskell-src-exts ASTs as well.
+
+Wrinkle: In order to print out the AST, we need to know it is Outputable.
+We also sometimes need to branch on the particular pass that we're in
+(e.g. to print out type information once we know it). In order to allow
+both of these actions, we define OutputableBndrId, which gathers the necessary
+OutputableBndr and IsPass constraints. The use of this constraint in instances
+generally requires UndecidableInstances.
+
+See also Note [IsPass] and Note [NoGhcTc] in GHC.Hs.Extension.
+
+-}
+
+-- | A placeholder type for TTG extension points that are not currently
+-- unused to represent any particular value.
+--
+-- This should not be confused with 'NoExtCon', which are found in unused
+-- extension /constructors/ and therefore should never be inhabited. In
+-- contrast, 'NoExtField' is used in extension /points/ (e.g., as the field of
+-- some constructor), so it must have an inhabitant to construct AST passes
+-- that manipulate fields with that extension point as their type.
+data NoExtField = NoExtField
+ deriving (Data,Eq,Ord)
+
+instance Outputable NoExtField where
+ ppr _ = text "NoExtField"
+
+-- | Used when constructing a term with an unused extension point.
+noExtField :: NoExtField
+noExtField = NoExtField
+
+-- | Used in TTG extension constructors that have yet to be extended with
+-- anything. If an extension constructor has 'NoExtCon' as its field, it is
+-- not intended to ever be constructed anywhere, and any function that consumes
+-- the extension constructor can eliminate it by way of 'noExtCon'.
+--
+-- This should not be confused with 'NoExtField', which are found in unused
+-- extension /points/ (not /constructors/) and therefore can be inhabited.
+
+-- See also [NoExtCon and strict fields].
+data NoExtCon
+ deriving (Data,Eq,Ord)
+
+instance Outputable NoExtCon where
+ ppr = noExtCon
+
+-- | Eliminate a 'NoExtCon'. Much like 'Data.Void.absurd'.
+noExtCon :: NoExtCon -> a
+noExtCon x = case x of {}
+
+-- | GHC's L prefixed variants wrap their vanilla variant in this type family,
+-- to add 'SrcLoc' info via 'Located'. Other passes than 'GhcPass' not
+-- interested in location information can define this as
+-- @type instance XRec NoLocated a = a@.
+-- See Note [XRec and SrcSpans in the AST]
+type family XRec p a = r | r -> a
+
+{-
+Note [XRec and SrcSpans in the AST]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+XRec is meant to replace most of the uses of `Located` in the AST. It is another
+extension point meant to make it easier for non-GHC applications to reuse the
+AST for their own purposes, and not have to deal the hassle of (perhaps) useless
+SrcSpans everywhere.
+
+instead of `Located (HsExpr p)` or similar types, we will now have `XRec p
+(HsExpr p)`
+
+XRec allows annotating certain points in the AST with extra information. This
+maybe be source spans (for GHC), nothing (for TH), types (for HIE files), api
+annotations (for exactprint) or anything else.
+
+This should hopefully bring us one step closer to sharing the AST between GHC
+and TH.
+
+We use the `UnXRec`, `MapXRec` and `WrapXRec` type classes to aid us in writing
+pass-polymorphic code that deals with `XRec`s
+-}
+
+-- | We can strip off the XRec to access the underlying data.
+-- See Note [XRec and SrcSpans in the AST]
+class UnXRec p where
+ unXRec :: XRec p a -> a
+
+-- | We can map over the underlying type contained in an @XRec@ while preserving
+-- the annotation as is.
+-- See Note [XRec and SrcSpans in the AST]
+class MapXRec p where
+ mapXRec :: (a -> b) -> XRec p a -> XRec p b
+
+-- | The trivial wrapper that carries no additional information
+-- See Note [XRec and SrcSpans in the AST]
+class WrapXRec p where
+ wrapXRec :: a -> XRec p a
+
+-- | Maps the "normal" id type for a given pass
+type family IdP p
+
+type LIdP p = XRec p (IdP p)
+
+-- =====================================================================
+-- Type families for the HsBinds extension points
+
+-- HsLocalBindsLR type families
+type family XHsValBinds x x'
+type family XHsIPBinds x x'
+type family XEmptyLocalBinds x x'
+type family XXHsLocalBindsLR x x'
+
+-- HsValBindsLR type families
+type family XValBinds x x'
+type family XXValBindsLR x x'
+
+-- HsBindLR type families
+type family XFunBind x x'
+type family XPatBind x x'
+type family XVarBind x x'
+type family XAbsBinds x x'
+type family XPatSynBind x x'
+type family XXHsBindsLR x x'
+
+-- ABExport type families
+type family XABE x
+type family XXABExport x
+
+-- PatSynBind type families
+type family XPSB x x'
+type family XXPatSynBind x x'
+
+-- HsIPBinds type families
+type family XIPBinds x
+type family XXHsIPBinds x
+
+-- IPBind type families
+type family XCIPBind x
+type family XXIPBind x
+
+-- Sig type families
+type family XTypeSig x
+type family XPatSynSig x
+type family XClassOpSig x
+type family XIdSig x
+type family XFixSig x
+type family XInlineSig x
+type family XSpecSig x
+type family XSpecInstSig x
+type family XMinimalSig x
+type family XSCCFunSig x
+type family XCompleteMatchSig x
+type family XXSig x
+
+-- FixitySig type families
+type family XFixitySig x
+type family XXFixitySig x
+
+-- StandaloneKindSig type families
+type family XStandaloneKindSig x
+type family XXStandaloneKindSig x
+
+-- =====================================================================
+-- Type families for the HsDecls extension points
+
+-- HsDecl type families
+type family XTyClD x
+type family XInstD x
+type family XDerivD x
+type family XValD x
+type family XSigD x
+type family XKindSigD x
+type family XDefD x
+type family XForD x
+type family XWarningD x
+type family XAnnD x
+type family XRuleD x
+type family XSpliceD x
+type family XDocD x
+type family XRoleAnnotD x
+type family XXHsDecl x
+
+-- -------------------------------------
+-- HsGroup type families
+type family XCHsGroup x
+type family XXHsGroup x
+
+-- -------------------------------------
+-- SpliceDecl type families
+type family XSpliceDecl x
+type family XXSpliceDecl x
+
+-- -------------------------------------
+-- TyClDecl type families
+type family XFamDecl x
+type family XSynDecl x
+type family XDataDecl x
+type family XClassDecl x
+type family XXTyClDecl x
+
+-- -------------------------------------
+-- TyClGroup type families
+type family XCTyClGroup x
+type family XXTyClGroup x
+
+-- -------------------------------------
+-- FamilyResultSig type families
+type family XNoSig x
+type family XCKindSig x -- Clashes with XKindSig above
+type family XTyVarSig x
+type family XXFamilyResultSig x
+
+-- -------------------------------------
+-- FamilyDecl type families
+type family XCFamilyDecl x
+type family XXFamilyDecl x
+
+-- -------------------------------------
+-- HsDataDefn type families
+type family XCHsDataDefn x
+type family XXHsDataDefn x
+
+-- -------------------------------------
+-- HsDerivingClause type families
+type family XCHsDerivingClause x
+type family XXHsDerivingClause x
+
+-- -------------------------------------
+-- DerivClauseTys type families
+type family XDctSingle x
+type family XDctMulti x
+type family XXDerivClauseTys x
+
+-- -------------------------------------
+-- ConDecl type families
+type family XConDeclGADT x
+type family XConDeclH98 x
+type family XXConDecl x
+
+-- -------------------------------------
+-- FamEqn type families
+type family XCFamEqn x r
+type family XXFamEqn x r
+
+-- -------------------------------------
+-- ClsInstDecl type families
+type family XCClsInstDecl x
+type family XXClsInstDecl x
+
+-- -------------------------------------
+-- InstDecl type families
+type family XClsInstD x
+type family XDataFamInstD x
+type family XTyFamInstD x
+type family XXInstDecl x
+
+-- -------------------------------------
+-- DerivDecl type families
+type family XCDerivDecl x
+type family XXDerivDecl x
+
+-- -------------------------------------
+-- DerivStrategy type family
+type family XViaStrategy x
+
+-- -------------------------------------
+-- DefaultDecl type families
+type family XCDefaultDecl x
+type family XXDefaultDecl x
+
+-- -------------------------------------
+-- ForeignDecl type families
+type family XForeignImport x
+type family XForeignExport x
+type family XXForeignDecl x
+
+-- -------------------------------------
+-- RuleDecls type families
+type family XCRuleDecls x
+type family XXRuleDecls x
+
+-- -------------------------------------
+-- RuleDecl type families
+type family XHsRule x
+type family XXRuleDecl x
+
+-- -------------------------------------
+-- RuleBndr type families
+type family XCRuleBndr x
+type family XRuleBndrSig x
+type family XXRuleBndr x
+
+-- -------------------------------------
+-- WarnDecls type families
+type family XWarnings x
+type family XXWarnDecls x
+
+-- -------------------------------------
+-- WarnDecl type families
+type family XWarning x
+type family XXWarnDecl x
+
+-- -------------------------------------
+-- AnnDecl type families
+type family XHsAnnotation x
+type family XXAnnDecl x
+
+-- -------------------------------------
+-- RoleAnnotDecl type families
+type family XCRoleAnnotDecl x
+type family XXRoleAnnotDecl x
+
+-- =====================================================================
+-- Type families for the HsExpr extension points
+
+type family XVar x
+type family XUnboundVar x
+type family XConLikeOut x
+type family XRecFld x
+type family XOverLabel x
+type family XIPVar x
+type family XOverLitE x
+type family XLitE x
+type family XLam x
+type family XLamCase x
+type family XApp x
+type family XAppTypeE x
+type family XOpApp x
+type family XNegApp x
+type family XPar x
+type family XSectionL x
+type family XSectionR x
+type family XExplicitTuple x
+type family XExplicitSum x
+type family XCase x
+type family XIf x
+type family XMultiIf x
+type family XLet x
+type family XDo x
+type family XExplicitList x
+type family XRecordCon x
+type family XRecordUpd x
+type family XExprWithTySig x
+type family XArithSeq x
+type family XBracket x
+type family XRnBracketOut x
+type family XTcBracketOut x
+type family XSpliceE x
+type family XProc x
+type family XStatic x
+type family XTick x
+type family XBinTick x
+type family XPragE x
+type family XXExpr x
+
+-- -------------------------------------
+-- HsPragE type families
+type family XSCC x
+type family XXPragE x
+
+
+-- -------------------------------------
+-- AmbiguousFieldOcc type families
+type family XUnambiguous x
+type family XAmbiguous x
+type family XXAmbiguousFieldOcc x
+
+-- -------------------------------------
+-- HsTupArg type families
+type family XPresent x
+type family XMissing x
+type family XXTupArg x
+
+-- -------------------------------------
+-- HsSplice type families
+type family XTypedSplice x
+type family XUntypedSplice x
+type family XQuasiQuote x
+type family XSpliced x
+type family XXSplice x
+
+-- -------------------------------------
+-- HsBracket type families
+type family XExpBr x
+type family XPatBr x
+type family XDecBrL x
+type family XDecBrG x
+type family XTypBr x
+type family XVarBr x
+type family XTExpBr x
+type family XXBracket x
+
+-- -------------------------------------
+-- HsCmdTop type families
+type family XCmdTop x
+type family XXCmdTop x
+
+-- -------------------------------------
+-- MatchGroup type families
+type family XMG x b
+type family XXMatchGroup x b
+
+-- -------------------------------------
+-- Match type families
+type family XCMatch x b
+type family XXMatch x b
+
+-- -------------------------------------
+-- GRHSs type families
+type family XCGRHSs x b
+type family XXGRHSs x b
+
+-- -------------------------------------
+-- GRHS type families
+type family XCGRHS x b
+type family XXGRHS x b
+
+-- -------------------------------------
+-- StmtLR type families
+type family XLastStmt x x' b
+type family XBindStmt x x' b
+type family XApplicativeStmt x x' b
+type family XBodyStmt x x' b
+type family XLetStmt x x' b
+type family XParStmt x x' b
+type family XTransStmt x x' b
+type family XRecStmt x x' b
+type family XXStmtLR x x' b
+
+-- -------------------------------------
+-- HsCmd type families
+type family XCmdArrApp x
+type family XCmdArrForm x
+type family XCmdApp x
+type family XCmdLam x
+type family XCmdPar x
+type family XCmdCase x
+type family XCmdLamCase x
+type family XCmdIf x
+type family XCmdLet x
+type family XCmdDo x
+type family XCmdWrap x
+type family XXCmd x
+
+-- -------------------------------------
+-- ParStmtBlock type families
+type family XParStmtBlock x x'
+type family XXParStmtBlock x x'
+
+-- -------------------------------------
+-- ApplicativeArg type families
+type family XApplicativeArgOne x
+type family XApplicativeArgMany x
+type family XXApplicativeArg x
+
+-- =====================================================================
+-- Type families for the HsImpExp extension points
+
+-- TODO
+
+-- =====================================================================
+-- Type families for the HsLit extension points
+
+-- We define a type family for each extension point. This is based on prepending
+-- 'X' to the constructor name, for ease of reference.
+type family XHsChar x
+type family XHsCharPrim x
+type family XHsString x
+type family XHsStringPrim x
+type family XHsInt x
+type family XHsIntPrim x
+type family XHsWordPrim x
+type family XHsInt64Prim x
+type family XHsWord64Prim x
+type family XHsInteger x
+type family XHsRat x
+type family XHsFloatPrim x
+type family XHsDoublePrim x
+type family XXLit x
+
+-- -------------------------------------
+-- HsOverLit type families
+type family XOverLit x
+type family XXOverLit x
+
+-- =====================================================================
+-- Type families for the HsPat extension points
+
+type family XWildPat x
+type family XVarPat x
+type family XLazyPat x
+type family XAsPat x
+type family XParPat x
+type family XBangPat x
+type family XListPat x
+type family XTuplePat x
+type family XSumPat x
+type family XConPat x
+type family XViewPat x
+type family XSplicePat x
+type family XLitPat x
+type family XNPat x
+type family XNPlusKPat x
+type family XSigPat x
+type family XCoPat x
+type family XXPat x
+
+-- =====================================================================
+-- Type families for the HsTypes type families
+
+
+-- -------------------------------------
+-- LHsQTyVars type families
+type family XHsQTvs x
+type family XXLHsQTyVars x
+
+-- -------------------------------------
+-- HsOuterTyVarBndrs type families
+type family XHsOuterImplicit x
+type family XHsOuterExplicit x flag
+type family XXHsOuterTyVarBndrs x
+
+-- -------------------------------------
+-- HsSigType type families
+type family XHsSig x
+type family XXHsSigType x
+
+-- -------------------------------------
+-- HsWildCardBndrs type families
+type family XHsWC x b
+type family XXHsWildCardBndrs x b
+
+-- -------------------------------------
+-- HsPatSigType type families
+type family XHsPS x
+type family XXHsPatSigType x
+
+-- -------------------------------------
+-- HsType type families
+type family XForAllTy x
+type family XQualTy x
+type family XTyVar x
+type family XAppTy x
+type family XAppKindTy x
+type family XFunTy x
+type family XListTy x
+type family XTupleTy x
+type family XSumTy x
+type family XOpTy x
+type family XParTy x
+type family XIParamTy x
+type family XStarTy x
+type family XKindSig x
+type family XSpliceTy x
+type family XDocTy x
+type family XBangTy x
+type family XRecTy x
+type family XExplicitListTy x
+type family XExplicitTupleTy x
+type family XTyLit x
+type family XWildCardTy x
+type family XXType x
+
+-- ---------------------------------------------------------------------
+-- HsForAllTelescope type families
+type family XHsForAllVis x
+type family XHsForAllInvis x
+type family XXHsForAllTelescope x
+
+-- ---------------------------------------------------------------------
+-- HsTyVarBndr type families
+type family XUserTyVar x
+type family XKindedTyVar x
+type family XXTyVarBndr x
+
+-- ---------------------------------------------------------------------
+-- ConDeclField type families
+type family XConDeclField x
+type family XXConDeclField x
+
+-- ---------------------------------------------------------------------
+-- FieldOcc type families
+type family XCFieldOcc x
+type family XXFieldOcc x
+
+-- =====================================================================
+-- Type families for the HsImpExp type families
+
+-- -------------------------------------
+-- ImportDecl type families
+type family XCImportDecl x
+type family XXImportDecl x
+
+-- -------------------------------------
+-- IE type families
+type family XIEVar x
+type family XIEThingAbs x
+type family XIEThingAll x
+type family XIEThingWith x
+type family XIEModuleContents x
+type family XIEGroup x
+type family XIEDoc x
+type family XIEDocNamed x
+type family XXIE x
+
+-- -------------------------------------
+
+-- =====================================================================
+-- Misc
+
+-- | See Note [NoGhcTc] in GHC.Hs.Extension. It has to be in this
+-- module because it is used like an extension point (in the data definitions
+-- of types that should be parameter-agnostic.
+type family NoGhcTc (p :: Type)
+
+-- =====================================================================
+-- End of Type family definitions
+-- =====================================================================
diff --git a/compiler/Language/Haskell/Syntax/Lit.hs b/compiler/Language/Haskell/Syntax/Lit.hs
new file mode 100644
index 0000000000..c5dd7ec45b
--- /dev/null
+++ b/compiler/Language/Haskell/Syntax/Lit.hs
@@ -0,0 +1,204 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow]
+ -- in module Language.Haskell.Syntax.Extension
+
+{-
+(c) The University of Glasgow 2006
+(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
+
+-}
+
+-- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.*
+
+-- | Source-language literals
+module Language.Haskell.Syntax.Lit where
+
+#include "HsVersions.h"
+
+import GHC.Prelude
+
+import {-# SOURCE #-} Language.Haskell.Syntax.Expr ( HsExpr )
+import GHC.Types.Basic (PprPrec(..), topPrec )
+import GHC.Types.SourceText
+import GHC.Core.Type
+import GHC.Utils.Outputable
+import GHC.Utils.Panic
+import GHC.Data.FastString
+import Language.Haskell.Syntax.Extension
+
+import Data.ByteString (ByteString)
+import Data.Data hiding ( Fixity )
+
+{-
+************************************************************************
+* *
+\subsection[HsLit]{Literals}
+* *
+************************************************************************
+-}
+
+-- Note [Literal source text] in GHC.Types.Basic for SourceText fields in
+-- the following
+-- Note [Trees that grow] in Language.Haskell.Syntax.Extension for the Xxxxx fields in the following
+-- | Haskell Literal
+data HsLit x
+ = HsChar (XHsChar x) {- SourceText -} Char
+ -- ^ Character
+ | HsCharPrim (XHsCharPrim x) {- SourceText -} Char
+ -- ^ Unboxed character
+ | HsString (XHsString x) {- SourceText -} FastString
+ -- ^ String
+ | HsStringPrim (XHsStringPrim x) {- SourceText -} !ByteString
+ -- ^ Packed bytes
+ | HsInt (XHsInt x) IntegralLit
+ -- ^ Genuinely an Int; arises from
+ -- "GHC.Tc.Deriv.Generate", and from TRANSLATION
+ | HsIntPrim (XHsIntPrim x) {- SourceText -} Integer
+ -- ^ literal @Int#@
+ | HsWordPrim (XHsWordPrim x) {- SourceText -} Integer
+ -- ^ literal @Word#@
+ | HsInt64Prim (XHsInt64Prim x) {- SourceText -} Integer
+ -- ^ literal @Int64#@
+ | HsWord64Prim (XHsWord64Prim x) {- SourceText -} Integer
+ -- ^ literal @Word64#@
+ | HsInteger (XHsInteger x) {- SourceText -} Integer Type
+ -- ^ Genuinely an integer; arises only
+ -- from TRANSLATION (overloaded
+ -- literals are done with HsOverLit)
+ | HsRat (XHsRat x) FractionalLit Type
+ -- ^ Genuinely a rational; arises only from
+ -- TRANSLATION (overloaded literals are
+ -- done with HsOverLit)
+ | HsFloatPrim (XHsFloatPrim x) FractionalLit
+ -- ^ Unboxed Float
+ | HsDoublePrim (XHsDoublePrim x) FractionalLit
+ -- ^ Unboxed Double
+
+ | XLit !(XXLit x)
+
+instance Eq (HsLit x) where
+ (HsChar _ x1) == (HsChar _ x2) = x1==x2
+ (HsCharPrim _ x1) == (HsCharPrim _ x2) = x1==x2
+ (HsString _ x1) == (HsString _ x2) = x1==x2
+ (HsStringPrim _ x1) == (HsStringPrim _ x2) = x1==x2
+ (HsInt _ x1) == (HsInt _ x2) = x1==x2
+ (HsIntPrim _ x1) == (HsIntPrim _ x2) = x1==x2
+ (HsWordPrim _ x1) == (HsWordPrim _ x2) = x1==x2
+ (HsInt64Prim _ x1) == (HsInt64Prim _ x2) = x1==x2
+ (HsWord64Prim _ x1) == (HsWord64Prim _ x2) = x1==x2
+ (HsInteger _ x1 _) == (HsInteger _ x2 _) = x1==x2
+ (HsRat _ x1 _) == (HsRat _ x2 _) = x1==x2
+ (HsFloatPrim _ x1) == (HsFloatPrim _ x2) = x1==x2
+ (HsDoublePrim _ x1) == (HsDoublePrim _ x2) = x1==x2
+ _ == _ = False
+
+-- | Haskell Overloaded Literal
+data HsOverLit p
+ = OverLit {
+ ol_ext :: (XOverLit p),
+ ol_val :: OverLitVal,
+ ol_witness :: HsExpr p} -- Note [Overloaded literal witnesses]
+
+ | XOverLit
+ !(XXOverLit p)
+
+-- Note [Literal source text] in GHC.Types.Basic for SourceText fields in
+-- the following
+-- | Overloaded Literal Value
+data OverLitVal
+ = HsIntegral !IntegralLit -- ^ Integer-looking literals;
+ | HsFractional !FractionalLit -- ^ Frac-looking literals
+ | HsIsString !SourceText !FastString -- ^ String-looking literals
+ deriving Data
+
+negateOverLitVal :: OverLitVal -> OverLitVal
+negateOverLitVal (HsIntegral i) = HsIntegral (negateIntegralLit i)
+negateOverLitVal (HsFractional f) = HsFractional (negateFractionalLit f)
+negateOverLitVal _ = panic "negateOverLitVal: argument is not a number"
+
+{-
+Note [Overloaded literal witnesses]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*Before* type checking, the HsExpr in an HsOverLit is the
+name of the coercion function, 'fromInteger' or 'fromRational'.
+*After* type checking, it is a witness for the literal, such as
+ (fromInteger 3) or lit_78
+This witness should replace the literal.
+
+This dual role is unusual, because we're replacing 'fromInteger' with
+a call to fromInteger. Reason: it allows commoning up of the fromInteger
+calls, which wouldn't be possible if the desugarer made the application.
+
+The PostTcType in each branch records the type the overload literal is
+found to have.
+-}
+
+-- Comparison operations are needed when grouping literals
+-- for compiling pattern-matching (module GHC.HsToCore.Match.Literal)
+instance (Eq (XXOverLit p)) => Eq (HsOverLit p) where
+ (OverLit _ val1 _) == (OverLit _ val2 _) = val1 == val2
+ (XOverLit val1) == (XOverLit val2) = val1 == val2
+ _ == _ = panic "Eq HsOverLit"
+
+instance Eq OverLitVal where
+ (HsIntegral i1) == (HsIntegral i2) = i1 == i2
+ (HsFractional f1) == (HsFractional f2) = f1 == f2
+ (HsIsString _ s1) == (HsIsString _ s2) = s1 == s2
+ _ == _ = False
+
+instance (Ord (XXOverLit p)) => Ord (HsOverLit p) where
+ compare (OverLit _ val1 _) (OverLit _ val2 _) = val1 `compare` val2
+ compare (XOverLit val1) (XOverLit val2) = val1 `compare` val2
+ compare _ _ = panic "Ord HsOverLit"
+
+instance Ord OverLitVal where
+ compare (HsIntegral i1) (HsIntegral i2) = i1 `compare` i2
+ compare (HsIntegral _) (HsFractional _) = LT
+ compare (HsIntegral _) (HsIsString _ _) = LT
+ compare (HsFractional f1) (HsFractional f2) = f1 `compare` f2
+ compare (HsFractional _) (HsIntegral _) = GT
+ compare (HsFractional _) (HsIsString _ _) = LT
+ compare (HsIsString _ s1) (HsIsString _ s2) = s1 `uniqCompareFS` s2
+ compare (HsIsString _ _) (HsIntegral _) = GT
+ compare (HsIsString _ _) (HsFractional _) = GT
+
+instance Outputable OverLitVal where
+ ppr (HsIntegral i) = pprWithSourceText (il_text i) (integer (il_value i))
+ ppr (HsFractional f) = ppr f
+ ppr (HsIsString st s) = pprWithSourceText st (pprHsString s)
+
+-- | @'hsLitNeedsParens' p l@ returns 'True' if a literal @l@ needs
+-- to be parenthesized under precedence @p@.
+hsLitNeedsParens :: PprPrec -> HsLit x -> Bool
+hsLitNeedsParens p = go
+ where
+ go (HsChar {}) = False
+ go (HsCharPrim {}) = False
+ go (HsString {}) = False
+ go (HsStringPrim {}) = False
+ go (HsInt _ x) = p > topPrec && il_neg x
+ go (HsIntPrim _ x) = p > topPrec && x < 0
+ go (HsWordPrim {}) = False
+ go (HsInt64Prim _ x) = p > topPrec && x < 0
+ go (HsWord64Prim {}) = False
+ go (HsInteger _ x _) = p > topPrec && x < 0
+ go (HsRat _ x _) = p > topPrec && fl_neg x
+ go (HsFloatPrim _ x) = p > topPrec && fl_neg x
+ go (HsDoublePrim _ x) = p > topPrec && fl_neg x
+ go (XLit _) = False
+
+-- | @'hsOverLitNeedsParens' p ol@ returns 'True' if an overloaded literal
+-- @ol@ needs to be parenthesized under precedence @p@.
+hsOverLitNeedsParens :: PprPrec -> HsOverLit x -> Bool
+hsOverLitNeedsParens p (OverLit { ol_val = olv }) = go olv
+ where
+ go :: OverLitVal -> Bool
+ go (HsIntegral x) = p > topPrec && il_neg x
+ go (HsFractional x) = p > topPrec && fl_neg x
+ go (HsIsString {}) = False
+hsOverLitNeedsParens _ (XOverLit { }) = False
diff --git a/compiler/Language/Haskell/Syntax/Pat.hs b/compiler/Language/Haskell/Syntax/Pat.hs
new file mode 100644
index 0000000000..8de0cc96d3
--- /dev/null
+++ b/compiler/Language/Haskell/Syntax/Pat.hs
@@ -0,0 +1,374 @@
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow]
+ -- in module Language.Haskell.Syntax.Extension
+{-# LANGUAGE ViewPatterns #-}
+{-
+(c) The University of Glasgow 2006
+(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
+
+\section[PatSyntax]{Abstract Haskell syntax---patterns}
+-}
+
+-- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.*
+module Language.Haskell.Syntax.Pat (
+ Pat(..), LPat,
+ ConLikeP,
+
+ HsConPatDetails, hsConPatArgs,
+ HsRecFields(..), HsRecField'(..), LHsRecField',
+ HsRecField, LHsRecField,
+ HsRecUpdField, LHsRecUpdField,
+ hsRecFields, hsRecFieldSel, hsRecFieldsArgs,
+ ) where
+
+import GHC.Prelude
+
+import {-# SOURCE #-} Language.Haskell.Syntax.Expr (SyntaxExpr, LHsExpr, HsSplice)
+
+-- friends:
+import Language.Haskell.Syntax.Lit
+import Language.Haskell.Syntax.Extension
+import Language.Haskell.Syntax.Type
+import GHC.Types.Basic
+-- others:
+import GHC.Core.Ppr ( {- instance OutputableBndr TyVar -} )
+import GHC.Utils.Outputable
+import GHC.Types.SrcLoc
+-- libraries:
+import Data.Data hiding (TyCon,Fixity)
+
+type LPat p = XRec p (Pat p)
+
+-- | Pattern
+--
+-- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnBang'
+
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+data Pat p
+ = ------------ Simple patterns ---------------
+ WildPat (XWildPat p) -- ^ Wildcard Pattern
+ -- The sole reason for a type on a WildPat is to
+ -- support hsPatType :: Pat Id -> Type
+
+ -- AZ:TODO above comment needs to be updated
+ | VarPat (XVarPat p)
+ (LIdP p) -- ^ Variable Pattern
+
+ -- See Note [Located RdrNames] in GHC.Hs.Expr
+ | LazyPat (XLazyPat p)
+ (LPat p) -- ^ Lazy Pattern
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnTilde'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | AsPat (XAsPat p)
+ (LIdP p) (LPat p) -- ^ As pattern
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnAt'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | ParPat (XParPat p)
+ (LPat p) -- ^ Parenthesised pattern
+ -- See Note [Parens in HsSyn] in GHC.Hs.Expr
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'('@,
+ -- 'GHC.Parser.Annotation.AnnClose' @')'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | BangPat (XBangPat p)
+ (LPat p) -- ^ Bang pattern
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnBang'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ ------------ Lists, tuples, arrays ---------------
+ | ListPat (XListPat p)
+ [LPat p]
+ -- For OverloadedLists a Just (ty,fn) gives
+ -- overall type of the pattern, and the toList
+-- function to convert the scrutinee to a list value
+
+ -- ^ Syntactic List
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'['@,
+ -- 'GHC.Parser.Annotation.AnnClose' @']'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | TuplePat (XTuplePat p)
+ -- after typechecking, holds the types of the tuple components
+ [LPat p] -- Tuple sub-patterns
+ Boxity -- UnitPat is TuplePat []
+ -- You might think that the post typechecking Type was redundant,
+ -- because we can get the pattern type by getting the types of the
+ -- sub-patterns.
+ -- But it's essential
+ -- data T a where
+ -- T1 :: Int -> T Int
+ -- f :: (T a, a) -> Int
+ -- f (T1 x, z) = z
+ -- When desugaring, we must generate
+ -- f = /\a. \v::a. case v of (t::T a, w::a) ->
+ -- case t of (T1 (x::Int)) ->
+ -- Note the (w::a), NOT (w::Int), because we have not yet
+ -- refined 'a' to Int. So we must know that the second component
+ -- of the tuple is of type 'a' not Int. See selectMatchVar
+ -- (June 14: I'm not sure this comment is right; the sub-patterns
+ -- will be wrapped in CoPats, no?)
+ -- ^ Tuple sub-patterns
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' :
+ -- 'GHC.Parser.Annotation.AnnOpen' @'('@ or @'(#'@,
+ -- 'GHC.Parser.Annotation.AnnClose' @')'@ or @'#)'@
+
+ | SumPat (XSumPat p) -- after typechecker, types of the alternative
+ (LPat p) -- Sum sub-pattern
+ ConTag -- Alternative (one-based)
+ Arity -- Arity (INVARIANT: ≥ 2)
+ -- ^ Anonymous sum pattern
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' :
+ -- 'GHC.Parser.Annotation.AnnOpen' @'(#'@,
+ -- 'GHC.Parser.Annotation.AnnClose' @'#)'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ ------------ Constructor patterns ---------------
+ | ConPat {
+ pat_con_ext :: XConPat p,
+ pat_con :: XRec p (ConLikeP p),
+ pat_args :: HsConPatDetails p
+ }
+ -- ^ Constructor Pattern
+
+ ------------ View patterns ---------------
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnRarrow'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | ViewPat (XViewPat p) -- The overall type of the pattern
+ -- (= the argument type of the view function)
+ -- for hsPatType.
+ (LHsExpr p)
+ (LPat p)
+ -- ^ View Pattern
+
+ ------------ Pattern splices ---------------
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'$('@
+ -- 'GHC.Parser.Annotation.AnnClose' @')'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | SplicePat (XSplicePat p)
+ (HsSplice p) -- ^ Splice Pattern (Includes quasi-quotes)
+
+ ------------ Literal and n+k patterns ---------------
+ | LitPat (XLitPat p)
+ (HsLit p) -- ^ Literal Pattern
+ -- Used for *non-overloaded* literal patterns:
+ -- Int#, Char#, Int, Char, String, etc.
+
+ | NPat -- Natural Pattern
+ -- Used for all overloaded literals,
+ -- including overloaded strings with -XOverloadedStrings
+ (XNPat p) -- Overall type of pattern. Might be
+ -- different than the literal's type
+ -- if (==) or negate changes the type
+ (XRec p (HsOverLit p)) -- ALWAYS positive
+ (Maybe (SyntaxExpr p)) -- Just (Name of 'negate') for
+ -- negative patterns, Nothing
+ -- otherwise
+ (SyntaxExpr p) -- Equality checker, of type t->t->Bool
+
+ -- ^ Natural Pattern
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnVal' @'+'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | NPlusKPat (XNPlusKPat p) -- Type of overall pattern
+ (LIdP p) -- n+k pattern
+ (XRec p (HsOverLit p)) -- It'll always be an HsIntegral
+ (HsOverLit p) -- See Note [NPlusK patterns] in GHC.Tc.Gen.Pat
+ -- NB: This could be (PostTc ...), but that induced a
+ -- a new hs-boot file. Not worth it.
+
+ (SyntaxExpr p) -- (>=) function, of type t1->t2->Bool
+ (SyntaxExpr p) -- Name of '-' (see GHC.Rename.Env.lookupSyntax)
+ -- ^ n+k pattern
+
+ ------------ Pattern type signatures ---------------
+ -- | - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnDcolon'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | SigPat (XSigPat p) -- After typechecker: Type
+ (LPat p) -- Pattern with a type signature
+ (HsPatSigType (NoGhcTc p)) -- Signature can bind both
+ -- kind and type vars
+
+ -- ^ Pattern with a type signature
+
+ -- | Trees that Grow extension point for new constructors
+ | XPat
+ !(XXPat p)
+
+type family ConLikeP x
+
+
+-- ---------------------------------------------------------------------
+
+
+-- | Haskell Constructor Pattern Details
+type HsConPatDetails p = HsConDetails (HsPatSigType (NoGhcTc p)) (LPat p) (HsRecFields p (LPat p))
+
+hsConPatArgs :: HsConPatDetails p -> [LPat p]
+hsConPatArgs (PrefixCon _ ps) = ps
+hsConPatArgs (RecCon fs) = map (hsRecFieldArg . unLoc) (rec_flds fs)
+hsConPatArgs (InfixCon p1 p2) = [p1,p2]
+
+-- | Haskell Record Fields
+--
+-- HsRecFields is used only for patterns and expressions (not data type
+-- declarations)
+data HsRecFields p arg -- A bunch of record fields
+ -- { x = 3, y = True }
+ -- Used for both expressions and patterns
+ = HsRecFields { rec_flds :: [LHsRecField p arg],
+ rec_dotdot :: Maybe (Located Int) } -- Note [DotDot fields]
+ deriving (Functor, Foldable, Traversable)
+
+
+-- Note [DotDot fields]
+-- ~~~~~~~~~~~~~~~~~~~~
+-- The rec_dotdot field means this:
+-- Nothing => the normal case
+-- Just n => the group uses ".." notation,
+--
+-- In the latter case:
+--
+-- *before* renamer: rec_flds are exactly the n user-written fields
+--
+-- *after* renamer: rec_flds includes *all* fields, with
+-- the first 'n' being the user-written ones
+-- and the remainder being 'filled in' implicitly
+
+-- | Located Haskell Record Field
+type LHsRecField' p arg = Located (HsRecField' p arg)
+
+-- | Located Haskell Record Field
+type LHsRecField p arg = Located (HsRecField p arg)
+
+-- | Located Haskell Record Update Field
+type LHsRecUpdField p = Located (HsRecUpdField p)
+
+-- | Haskell Record Field
+type HsRecField p arg = HsRecField' (FieldOcc p) arg
+
+-- | Haskell Record Update Field
+type HsRecUpdField p = HsRecField' (AmbiguousFieldOcc p) (LHsExpr p)
+
+-- | Haskell Record Field
+--
+-- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnEqual',
+--
+-- For details on above see note [Api annotations] in GHC.Parser.Annotation
+data HsRecField' id arg = HsRecField {
+ hsRecFieldLbl :: Located id,
+ hsRecFieldArg :: arg, -- ^ Filled in by renamer when punning
+ hsRecPun :: Bool -- ^ Note [Punning]
+ } deriving (Data, Functor, Foldable, Traversable)
+
+
+-- Note [Punning]
+-- ~~~~~~~~~~~~~~
+-- If you write T { x, y = v+1 }, the HsRecFields will be
+-- HsRecField x x True ...
+-- HsRecField y (v+1) False ...
+-- That is, for "punned" field x is expanded (in the renamer)
+-- to x=x; but with a punning flag so we can detect it later
+-- (e.g. when pretty printing)
+--
+-- If the original field was qualified, we un-qualify it, thus
+-- T { A.x } means T { A.x = x }
+
+
+-- Note [HsRecField and HsRecUpdField]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+-- A HsRecField (used for record construction and pattern matching)
+-- contains an unambiguous occurrence of a field (i.e. a FieldOcc).
+-- We can't just store the Name, because thanks to
+-- DuplicateRecordFields this may not correspond to the label the user
+-- wrote.
+--
+-- A HsRecUpdField (used for record update) contains a potentially
+-- ambiguous occurrence of a field (an AmbiguousFieldOcc). The
+-- renamer will fill in the selector function if it can, but if the
+-- selector is ambiguous the renamer will defer to the typechecker.
+-- After the typechecker, a unique selector will have been determined.
+--
+-- The renamer produces an Unambiguous result if it can, rather than
+-- just doing the lookup in the typechecker, so that completely
+-- unambiguous updates can be represented by 'GHC.HsToCore.Quote.repUpdFields'.
+--
+-- For example, suppose we have:
+--
+-- data S = MkS { x :: Int }
+-- data T = MkT { x :: Int }
+--
+-- f z = (z { x = 3 }) :: S
+--
+-- The parsed HsRecUpdField corresponding to the record update will have:
+--
+-- hsRecFieldLbl = Unambiguous "x" noExtField :: AmbiguousFieldOcc RdrName
+--
+-- After the renamer, this will become:
+--
+-- hsRecFieldLbl = Ambiguous "x" noExtField :: AmbiguousFieldOcc Name
+--
+-- (note that the Unambiguous constructor is not type-correct here).
+-- The typechecker will determine the particular selector:
+--
+-- hsRecFieldLbl = Unambiguous "x" $sel:x:MkS :: AmbiguousFieldOcc Id
+--
+-- See also Note [Disambiguating record fields] in GHC.Tc.Gen.Head.
+
+hsRecFields :: HsRecFields p arg -> [XCFieldOcc p]
+hsRecFields rbinds = map (unLoc . hsRecFieldSel . unLoc) (rec_flds rbinds)
+
+-- Probably won't typecheck at once, things have changed :/
+hsRecFieldsArgs :: HsRecFields p arg -> [arg]
+hsRecFieldsArgs rbinds = map (hsRecFieldArg . unLoc) (rec_flds rbinds)
+
+hsRecFieldSel :: HsRecField pass arg -> Located (XCFieldOcc pass)
+hsRecFieldSel = fmap extFieldOcc . hsRecFieldLbl
+
+
+{-
+************************************************************************
+* *
+* Printing patterns
+* *
+************************************************************************
+-}
+
+instance (Outputable arg)
+ => Outputable (HsRecFields p arg) where
+ ppr (HsRecFields { rec_flds = flds, rec_dotdot = Nothing })
+ = braces (fsep (punctuate comma (map ppr flds)))
+ ppr (HsRecFields { rec_flds = flds, rec_dotdot = Just (unLoc -> n) })
+ = braces (fsep (punctuate comma (map ppr (take n flds) ++ [dotdot])))
+ where
+ dotdot = text ".." <+> whenPprDebug (ppr (drop n flds))
+
+instance (Outputable p, Outputable arg)
+ => Outputable (HsRecField' p arg) where
+ ppr (HsRecField { hsRecFieldLbl = f, hsRecFieldArg = arg,
+ hsRecPun = pun })
+ = ppr f <+> (ppUnless pun $ equals <+> ppr arg)
diff --git a/compiler/Language/Haskell/Syntax/Pat.hs-boot b/compiler/Language/Haskell/Syntax/Pat.hs-boot
new file mode 100644
index 0000000000..4ff0371e39
--- /dev/null
+++ b/compiler/Language/Haskell/Syntax/Pat.hs-boot
@@ -0,0 +1,13 @@
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE RoleAnnotations #-}
+{-# LANGUAGE TypeFamilies #-}
+
+-- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.*
+module Language.Haskell.Syntax.Pat where
+
+import Language.Haskell.Syntax.Extension ( XRec )
+import Data.Kind
+
+type role Pat nominal
+data Pat (i :: Type)
+type LPat i = XRec i (Pat i)
diff --git a/compiler/Language/Haskell/Syntax/Type.hs b/compiler/Language/Haskell/Syntax/Type.hs
new file mode 100644
index 0000000000..6b0d61d025
--- /dev/null
+++ b/compiler/Language/Haskell/Syntax/Type.hs
@@ -0,0 +1,1304 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow]
+ -- in module Language.Haskell.Syntax.Extension
+{-
+(c) The University of Glasgow 2006
+(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
+
+
+GHC.Hs.Type: Abstract syntax: user-defined types
+-}
+
+-- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.*
+module Language.Haskell.Syntax.Type (
+ Mult, HsScaled(..),
+ hsMult, hsScaledThing,
+ HsArrow(..),
+ hsLinear, hsUnrestricted,
+
+ HsType(..), HsCoreTy, LHsType, HsKind, LHsKind,
+ HsForAllTelescope(..), HsTyVarBndr(..), LHsTyVarBndr,
+ LHsQTyVars(..),
+ HsOuterTyVarBndrs(..), HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs,
+ HsWildCardBndrs(..),
+ HsPatSigType(..), HsPSRn(..),
+ HsSigType(..), LHsSigType, LHsSigWcType, LHsWcType,
+ HsTupleSort(..),
+ HsContext, LHsContext,
+ HsTyLit(..),
+ HsIPName(..), hsIPNameFS,
+ HsArg(..), numVisibleArgs,
+ LHsTypeArg,
+
+ LBangType, BangType,
+ HsSrcBang(..), HsImplBang(..),
+ SrcStrictness(..), SrcUnpackedness(..),
+
+ ConDeclField(..), LConDeclField,
+
+ HsConDetails(..), noTypeArgs,
+
+ FieldOcc(..), LFieldOcc,
+ AmbiguousFieldOcc(..),
+
+ mapHsOuterImplicit,
+ hsQTvExplicit,
+ isHsKindedTyVar,
+ hsPatSigType,
+ ) where
+
+#include "HsVersions.h"
+
+import GHC.Prelude
+
+import {-# SOURCE #-} Language.Haskell.Syntax.Expr ( HsSplice )
+
+import Language.Haskell.Syntax.Extension
+
+import GHC.Types.SourceText
+import GHC.Types.Name( Name )
+import GHC.Types.Name.Reader ( RdrName )
+import GHC.Core.DataCon( HsSrcBang(..), HsImplBang(..),
+ SrcStrictness(..), SrcUnpackedness(..) )
+import GHC.Core.Type
+import GHC.Hs.Doc
+import GHC.Types.Basic
+import GHC.Types.SrcLoc
+import GHC.Utils.Outputable
+import GHC.Data.FastString
+import GHC.Utils.Misc ( count )
+import GHC.Parser.Annotation
+
+import Data.Data hiding ( Fixity, Prefix, Infix )
+import Data.Void
+
+{-
+************************************************************************
+* *
+\subsection{Bang annotations}
+* *
+************************************************************************
+-}
+
+-- | Located Bang Type
+type LBangType pass = XRec pass (BangType pass)
+
+-- | Bang Type
+--
+-- In the parser, strictness and packedness annotations bind more tightly
+-- than docstrings. This means that when consuming a 'BangType' (and looking
+-- for 'HsBangTy') we must be ready to peer behind a potential layer of
+-- 'HsDocTy'. See #15206 for motivation and 'getBangType' for an example.
+type BangType pass = HsType pass -- Bangs are in the HsType data type
+
+{-
+************************************************************************
+* *
+\subsection{Data types}
+* *
+************************************************************************
+
+This is the syntax for types as seen in type signatures.
+
+Note [HsBSig binder lists]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider a binder (or pattern) decorated with a type or kind,
+ \ (x :: a -> a). blah
+ forall (a :: k -> *) (b :: k). blah
+Then we use a LHsBndrSig on the binder, so that the
+renamer can decorate it with the variables bound
+by the pattern ('a' in the first example, 'k' in the second),
+assuming that neither of them is in scope already
+See also Note [Kind and type-variable binders] in GHC.Rename.HsType
+
+Note [HsType binders]
+~~~~~~~~~~~~~~~~~~~~~
+The system for recording type and kind-variable binders in HsTypes
+is a bit complicated. Here's how it works.
+
+* In a HsType,
+ HsForAllTy represents an /explicit, user-written/ 'forall' that
+ is nested within another HsType
+ e.g. forall a b. {...} or
+ forall a b -> {...}
+
+ Note that top-level 'forall's are represented with a
+ different AST form. See the description of HsOuterTyVarBndrs
+ below.
+ HsQualTy represents an /explicit, user-written/ context
+ e.g. (Eq a, Show a) => ...
+ The context can be empty if that's what the user wrote
+ These constructors represent what the user wrote, no more
+ and no less.
+
+* The ForAllTelescope field of HsForAllTy represents whether a forall is
+ invisible (e.g., forall a b. {...}, with a dot) or visible
+ (e.g., forall a b -> {...}, with an arrow).
+
+* HsTyVarBndr describes a quantified type variable written by the
+ user. For example
+ f :: forall a (b :: *). blah
+ here 'a' and '(b::*)' are each a HsTyVarBndr. A HsForAllTy has
+ a list of LHsTyVarBndrs.
+
+* HsOuterTyVarBndrs is used to represent the outermost quantified type
+ variables in a type that obeys the forall-or-nothing rule. An
+ HsOuterTyVarBndrs can be one of the following:
+
+ HsOuterImplicit (implicit quantification, added by renamer)
+ f :: a -> a -- Desugars to f :: forall {a}. a -> a
+ HsOuterExplicit (explicit user quantifiation):
+ f :: forall a. a -> a
+
+ See Note [forall-or-nothing rule].
+
+* An HsSigType is an LHsType with an accompanying HsOuterTyVarBndrs that
+ represents the presence (or absence) of its outermost 'forall'.
+ See Note [Representing type signatures].
+
+* HsWildCardBndrs is a wrapper that binds the wildcard variables
+ of the wrapped thing. It is filled in by the renamer
+ f :: _a -> _
+ The enclosing HsWildCardBndrs binds the wildcards _a and _.
+
+* HsSigPatType describes types that appear in pattern signatures and
+ the signatures of term-level binders in RULES. Like
+ HsWildCardBndrs/HsOuterTyVarBndrs, they track the names of wildcard
+ variables and implicitly bound type variables. Unlike
+ HsOuterTyVarBndrs, however, HsSigPatTypes do not obey the
+ forall-or-nothing rule. See Note [Pattern signature binders and scoping].
+
+* The explicit presence of these wrappers specifies, in the HsSyn,
+ exactly where implicit quantification is allowed, and where
+ wildcards are allowed.
+
+* LHsQTyVars is used in data/class declarations, where the user gives
+ explicit *type* variable bindings, but we need to implicitly bind
+ *kind* variables. For example
+ class C (a :: k -> *) where ...
+ The 'k' is implicitly bound in the hsq_tvs field of LHsQTyVars
+
+Note [The wildcard story for types]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Types can have wildcards in them, to support partial type signatures,
+like f :: Int -> (_ , _a) -> _a
+
+A wildcard in a type can be
+
+ * An anonymous wildcard,
+ written '_'
+ In HsType this is represented by HsWildCardTy.
+ The renamer leaves it untouched, and it is later given a fresh
+ meta tyvar in the typechecker.
+
+ * A named wildcard,
+ written '_a', '_foo', etc
+ In HsType this is represented by (HsTyVar "_a")
+ i.e. a perfectly ordinary type variable that happens
+ to start with an underscore
+
+Note carefully:
+
+* When NamedWildCards is off, type variables that start with an
+ underscore really /are/ ordinary type variables. And indeed, even
+ when NamedWildCards is on you can bind _a explicitly as an ordinary
+ type variable:
+ data T _a _b = MkT _b _a
+ Or even:
+ f :: forall _a. _a -> _b
+ Here _a is an ordinary forall'd binder, but (With NamedWildCards)
+ _b is a named wildcard. (See the comments in #10982)
+
+* Named wildcards are bound by the HsWildCardBndrs (for types that obey the
+ forall-or-nothing rule) and HsPatSigType (for type signatures in patterns
+ and term-level binders in RULES), which wrap types that are allowed to have
+ wildcards. Unnamed wildcards, however are left unchanged until typechecking,
+ where we give them fresh wild tyvars and determine whether or not to emit
+ hole constraints on each wildcard (we don't if it's a visible type/kind
+ argument or a type family pattern). See related notes
+ Note [Wildcards in visible kind application] and
+ Note [Wildcards in visible type application] in GHC.Tc.Gen.HsType.
+
+* After type checking is done, we report what types the wildcards
+ got unified with.
+
+Note [Ordering of implicit variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Since the advent of -XTypeApplications, GHC makes promises about the ordering
+of implicit variable quantification. Specifically, we offer that implicitly
+quantified variables (such as those in const :: a -> b -> a, without a `forall`)
+will occur in left-to-right order of first occurrence. Here are a few examples:
+
+ const :: a -> b -> a -- forall a b. ...
+ f :: Eq a => b -> a -> a -- forall a b. ... contexts are included
+
+ type a <-< b = b -> a
+ g :: a <-< b -- forall a b. ... type synonyms matter
+
+ class Functor f where
+ fmap :: (a -> b) -> f a -> f b -- forall f a b. ...
+ -- The f is quantified by the class, so only a and b are considered in fmap
+
+This simple story is complicated by the possibility of dependency: all variables
+must come after any variables mentioned in their kinds.
+
+ typeRep :: Typeable a => TypeRep (a :: k) -- forall k a. ...
+
+The k comes first because a depends on k, even though the k appears later than
+the a in the code. Thus, GHC does a *stable topological sort* on the variables.
+By "stable", we mean that any two variables who do not depend on each other
+preserve their existing left-to-right ordering.
+
+Implicitly bound variables are collected by the extract- family of functions
+(extractHsTysRdrTyVars, extractHsTyVarBndrsKVs, etc.) in GHC.Rename.HsType.
+These functions thus promise to keep left-to-right ordering.
+Look for pointers to this note to see the places where the action happens.
+
+Note that we also maintain this ordering in kind signatures. Even though
+there's no visible kind application (yet), having implicit variables be
+quantified in left-to-right order in kind signatures is nice since:
+
+* It's consistent with the treatment for type signatures.
+* It can affect how types are displayed with -fprint-explicit-kinds (see
+ #15568 for an example), which is a situation where knowing the order in
+ which implicit variables are quantified can be useful.
+* In the event that visible kind application is implemented, the order in
+ which we would expect implicit variables to be ordered in kinds will have
+ already been established.
+-}
+
+-- | Located Haskell Context
+type LHsContext pass = XRec pass (HsContext pass)
+ -- ^ 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnUnit'
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-- | Haskell Context
+type HsContext pass = [LHsType pass]
+
+-- | Located Haskell Type
+type LHsType pass = XRec pass (HsType pass)
+ -- ^ May have 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnComma' when
+ -- in a list
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-- | Haskell Kind
+type HsKind pass = HsType pass
+
+-- | Located Haskell Kind
+type LHsKind pass = XRec pass (HsKind pass)
+ -- ^ 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnDcolon'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+--------------------------------------------------
+-- LHsQTyVars
+-- The explicitly-quantified binders in a data/type declaration
+
+-- | The type variable binders in an 'HsForAllTy'.
+-- See also @Note [Variable Specificity and Forall Visibility]@ in
+-- "GHC.Tc.Gen.HsType".
+data HsForAllTelescope pass
+ = HsForAllVis -- ^ A visible @forall@ (e.g., @forall a -> {...}@).
+ -- These do not have any notion of specificity, so we use
+ -- '()' as a placeholder value.
+ { hsf_xvis :: XHsForAllVis pass
+ , hsf_vis_bndrs :: [LHsTyVarBndr () pass]
+ }
+ | HsForAllInvis -- ^ An invisible @forall@ (e.g., @forall a {b} c. {...}@),
+ -- where each binder has a 'Specificity'.
+ { hsf_xinvis :: XHsForAllInvis pass
+ , hsf_invis_bndrs :: [LHsTyVarBndr Specificity pass]
+ }
+ | XHsForAllTelescope !(XXHsForAllTelescope pass)
+
+-- | Located Haskell Type Variable Binder
+type LHsTyVarBndr flag pass = XRec pass (HsTyVarBndr flag pass)
+ -- See Note [HsType binders]
+
+-- | Located Haskell Quantified Type Variables
+data LHsQTyVars pass -- See Note [HsType binders]
+ = HsQTvs { hsq_ext :: XHsQTvs pass
+
+ , hsq_explicit :: [LHsTyVarBndr () pass]
+ -- Explicit variables, written by the user
+ }
+ | XLHsQTyVars !(XXLHsQTyVars pass)
+
+hsQTvExplicit :: LHsQTyVars pass -> [LHsTyVarBndr () pass]
+hsQTvExplicit = hsq_explicit
+
+------------------------------------------------
+-- HsOuterTyVarBndrs
+-- Used to quantify the outermost type variable binders of a type that obeys
+-- the forall-or-nothing rule. These are used to represent the outermost
+-- quantification in:
+-- * Type signatures (LHsSigType/LHsSigWcType)
+-- * Patterns in a type/data family instance (HsTyPats)
+--
+-- We support two forms:
+-- HsOuterImplicit (implicit quantification, added by renamer)
+-- f :: a -> a -- Desugars to f :: forall {a}. a -> a
+-- type instance F (a,b) = a->b
+-- HsOuterExplicit (explicit user quantifiation):
+-- f :: forall a. a -> a
+-- type instance forall a b. F (a,b) = a->b
+--
+-- In constrast, when the user writes /visible/ quanitification
+-- T :: forall k -> k -> Type
+-- we use use HsOuterImplicit, wrapped around a HsForAllTy
+-- for the visible quantification
+--
+-- See Note [forall-or-nothing rule]
+
+-- | The outermost type variables in a type that obeys the @forall@-or-nothing
+-- rule. See @Note [forall-or-nothing rule]@.
+data HsOuterTyVarBndrs flag pass
+ = HsOuterImplicit -- ^ Implicit forall, e.g.,
+ -- @f :: a -> b -> b@
+ { hso_ximplicit :: XHsOuterImplicit pass
+ }
+ | HsOuterExplicit -- ^ Explicit forall, e.g.,
+ -- @f :: forall a b. a -> b -> b@
+ { hso_xexplicit :: XHsOuterExplicit pass flag
+ , hso_bndrs :: [LHsTyVarBndr flag (NoGhcTc pass)]
+ }
+ | XHsOuterTyVarBndrs !(XXHsOuterTyVarBndrs pass)
+
+-- | Used for signatures, e.g.,
+--
+-- @
+-- f :: forall a {b}. blah
+-- @
+--
+-- We use 'Specificity' for the 'HsOuterTyVarBndrs' @flag@ to allow
+-- distinguishing between specified and inferred type variables.
+type HsOuterSigTyVarBndrs = HsOuterTyVarBndrs Specificity
+
+-- | Used for type-family instance equations, e.g.,
+--
+-- @
+-- type instance forall a. F [a] = Tree a
+-- @
+--
+-- The notion of specificity is irrelevant in type family equations, so we use
+-- @()@ for the 'HsOuterTyVarBndrs' @flag@.
+type HsOuterFamEqnTyVarBndrs = HsOuterTyVarBndrs ()
+
+-- | Haskell Wildcard Binders
+data HsWildCardBndrs pass thing
+ -- See Note [HsType binders]
+ -- See Note [The wildcard story for types]
+ = HsWC { hswc_ext :: XHsWC pass thing
+ -- after the renamer
+ -- Wild cards, only named
+ -- See Note [Wildcards in visible kind application]
+
+ , hswc_body :: thing
+ -- Main payload (type or list of types)
+ -- If there is an extra-constraints wildcard,
+ -- it's still there in the hsc_body.
+ }
+ | XHsWildCardBndrs !(XXHsWildCardBndrs pass thing)
+
+-- | Types that can appear in pattern signatures, as well as the signatures for
+-- term-level binders in RULES.
+-- See @Note [Pattern signature binders and scoping]@.
+--
+-- This is very similar to 'HsSigWcType', but with
+-- slightly different semantics: see @Note [HsType binders]@.
+-- See also @Note [The wildcard story for types]@.
+data HsPatSigType pass
+ = HsPS { hsps_ext :: XHsPS pass -- ^ After renamer: 'HsPSRn'
+ , hsps_body :: LHsType pass -- ^ Main payload (the type itself)
+ }
+ | XHsPatSigType !(XXHsPatSigType pass)
+
+-- | The extension field for 'HsPatSigType', which is only used in the
+-- renamer onwards. See @Note [Pattern signature binders and scoping]@.
+data HsPSRn = HsPSRn
+ { hsps_nwcs :: [Name] -- ^ Wildcard names
+ , hsps_imp_tvs :: [Name] -- ^ Implicitly bound variable names
+ }
+ deriving Data
+
+-- | Located Haskell Signature Type
+type LHsSigType pass = Located (HsSigType pass) -- Implicit only
+
+-- | Located Haskell Wildcard Type
+type LHsWcType pass = HsWildCardBndrs pass (LHsType pass) -- Wildcard only
+
+-- | Located Haskell Signature Wildcard Type
+type LHsSigWcType pass = HsWildCardBndrs pass (LHsSigType pass) -- Both
+
+-- | A type signature that obeys the @forall@-or-nothing rule. In other
+-- words, an 'LHsType' that uses an 'HsOuterSigTyVarBndrs' to represent its
+-- outermost type variable quantification.
+-- See @Note [Representing type signatures]@.
+data HsSigType pass
+ = HsSig { sig_ext :: XHsSig pass
+ , sig_bndrs :: HsOuterSigTyVarBndrs pass
+ , sig_body :: LHsType pass
+ }
+ | XHsSigType !(XXHsSigType pass)
+
+hsPatSigType :: HsPatSigType pass -> LHsType pass
+hsPatSigType = hsps_body
+
+{-
+Note [forall-or-nothing rule]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Free variables in signatures are usually bound in an implicit 'forall' at the
+beginning of user-written signatures. However, if the signature has an
+explicit, invisible forall at the beginning, this is disabled. This is referred
+to as the forall-or-nothing rule.
+
+The idea is nested foralls express something which is only expressible
+explicitly, while a top level forall could (usually) be replaced with an
+implicit binding. Top-level foralls alone ("forall.") are therefore an
+indication that the user is trying to be fastidious, so we don't implicitly
+bind any variables.
+
+Note that this rule only applies to outermost /in/visible 'forall's, and not
+outermost visible 'forall's. See #18660 for more on this point.
+
+Here are some concrete examples to demonstrate the forall-or-nothing rule in
+action:
+
+ type F1 :: a -> b -> b -- Legal; a,b are implicitly quantified.
+ -- Equivalently: forall a b. a -> b -> b
+
+ type F2 :: forall a b. a -> b -> b -- Legal; explicitly quantified
+
+ type F3 :: forall a. a -> b -> b -- Illegal; the forall-or-nothing rule says that
+ -- if you quantify a, you must also quantify b
+
+ type F4 :: forall a -> b -> b -- Legal; the top quantifier (forall a) is a /visible/
+ -- quantifer, so the "nothing" part of the forall-or-nothing
+ -- rule applies, and b is therefore implicitly quantified.
+ -- Equivalently: forall b. forall a -> b -> b
+
+ type F5 :: forall b. forall a -> b -> c -- Illegal; the forall-or-nothing rule says that
+ -- if you quantify b, you must also quantify c
+
+ type F6 :: forall a -> forall b. b -> c -- Legal: just like F4.
+
+For a complete list of all places where the forall-or-nothing rule applies, see
+"The `forall`-or-nothing rule" section of the GHC User's Guide.
+
+Any type that obeys the forall-or-nothing rule is represented in the AST with
+an HsOuterTyVarBndrs:
+
+* If the type has an outermost, invisible 'forall', it uses HsOuterExplicit,
+ which contains a list of the explicitly quantified type variable binders in
+ `hso_bndrs`. After typechecking, HsOuterExplicit also stores a list of the
+ explicitly quantified `InvisTVBinder`s in
+ `hso_xexplicit :: XHsOuterExplicit GhcTc`.
+
+* Otherwise, it uses HsOuterImplicit. HsOuterImplicit is used for different
+ things depending on the phase:
+
+ * After parsing, it does not store anything in particular.
+ * After renaming, it stores the implicitly bound type variable `Name`s in
+ `hso_ximplicit :: XHsOuterImplicit GhcRn`.
+ * After typechecking, it stores the implicitly bound `TyVar`s in
+ `hso_ximplicit :: XHsOuterImplicit GhcTc`.
+
+ NB: this implicit quantification is purely lexical: we bind any
+ type or kind variables that are not in scope. The type checker
+ may subsequently quantify over further kind variables.
+ See Note [Binding scoped type variables] in GHC.Tc.Gen.Sig.
+
+HsOuterTyVarBndrs GhcTc is used in the typechecker as an intermediate data type
+for storing the outermost TyVars/InvisTVBinders in a type.
+See GHC.Tc.Gen.HsType.bindOuterTKBndrsX for an example of this.
+
+Note [Representing type signatures]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+HsSigType is used to represent an explicit user type signature. These are
+used in a variety of places. Some examples include:
+
+* Type signatures (e.g., f :: a -> a)
+* Standalone kind signatures (e.g., type G :: a -> a)
+* GADT constructor types (e.g., data T where MkT :: a -> T)
+
+A HsSigType is the combination of an HsOuterSigTyVarBndrs and an LHsType:
+
+* The HsOuterSigTyVarBndrs binds the /explicitly/ quantified type variables
+ when the type signature has an outermost, user-written 'forall' (i.e,
+ the HsOuterExplicit constructor is used). If there is no outermost 'forall',
+ then it binds the /implicitly/ quantified type variables instead (i.e.,
+ the HsOuterImplicit constructor is used).
+* The LHsType represents the rest of the type.
+
+E.g. For a signature like
+ f :: forall k (a::k). blah
+we get
+ HsSig { sig_bndrs = HsOuterExplicit { hso_bndrs = [k, (a :: k)] }
+ , sig_body = blah }
+
+Note [Pattern signature binders and scoping]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider the pattern signatures like those on `t` and `g` in:
+
+ f = let h = \(t :: (b, b) ->
+ \(g :: forall a. a -> b) ->
+ ...(t :: (Int,Int))...
+ in woggle
+
+* The `b` in t's pattern signature is implicitly bound and scopes over
+ the signature and the body of the lambda. It stands for a type (any type);
+ indeed we subsequently discover that b=Int.
+ (See Note [TyVarTv] in GHC.Tc.Utils.TcMType for more on this point.)
+* The `b` in g's pattern signature is an /occurrence/ of the `b` bound by
+ t's pattern signature.
+* The `a` in `forall a` scopes only over the type `a -> b`, not over the body
+ of the lambda.
+* There is no forall-or-nothing rule for pattern signatures, which is why the
+ type `forall a. a -> b` is permitted in `g`'s pattern signature, even though
+ `b` is not explicitly bound. See Note [forall-or-nothing rule].
+
+Similar scoping rules apply to term variable binders in RULES, like in the
+following example:
+
+ {-# RULES "h" forall (t :: (b, b)) (g :: forall a. a -> b). h t g = ... #-}
+
+Just like in pattern signatures, the `b` in t's signature is implicitly bound
+and scopes over the remainder of the RULE. As a result, the `b` in g's
+signature is an occurrence. Moreover, the `a` in `forall a` scopes only over
+the type `a -> b`, and the forall-or-nothing rule does not apply.
+
+While quite similar, RULE term binder signatures behave slightly differently
+from pattern signatures in two ways:
+
+1. Unlike in pattern signatures, where type variables can stand for any type,
+ type variables in RULE term binder signatures are skolems.
+ See Note [Typechecking pattern signature binders] in GHC.Tc.Gen.HsType for
+ more on this point.
+
+ In this sense, type variables in pattern signatures are quite similar to
+ named wildcards, as both can refer to arbitrary types. The main difference
+ lies in error reporting: if a named wildcard `_a` in a pattern signature
+ stands for Int, then by default GHC will emit a warning stating as much.
+ Changing `_a` to `a`, on the other hand, will cause it not to be reported.
+2. In the `h` RULE above, only term variables are explicitly bound, so any free
+ type variables in the term variables' signatures are implicitly bound.
+ This is just like how the free type variables in pattern signatures are
+ implicitly bound. If a RULE explicitly binds both term and type variables,
+ however, then free type variables in term signatures are /not/ implicitly
+ bound. For example, this RULE would be ill scoped:
+
+ {-# RULES "h2" forall b. forall (t :: (b, c)) (g :: forall a. a -> b).
+ h2 t g = ... #-}
+
+ This is because `b` and `c` occur free in the signature for `t`, but only
+ `b` was explicitly bound, leaving `c` out of scope. If the RULE had started
+ with `forall b c.`, then it would have been accepted.
+
+The types in pattern signatures and RULE term binder signatures are represented
+in the AST by HsSigPatType. From the renamer onward, the hsps_ext field (of
+type HsPSRn) tracks the names of named wildcards and implicitly bound type
+variables so that they can be brought into scope during renaming and
+typechecking.
+
+Note [Lexically scoped type variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The ScopedTypeVariables extension does two things:
+
+* It allows the use of type signatures in patterns
+ (e.g., `f (x :: a -> a) = ...`). See
+ Note [Pattern signature binders and scoping] for more on this point.
+* It brings lexically scoped type variables into scope for certain type
+ signatures with outermost invisible 'forall's.
+
+This Note concerns the latter bullet point. Per the
+"Lexically scoped type variables" section of the GHC User's Guide, the
+following forms of type signatures can have lexically scoped type variables:
+
+* In declarations with type signatures, e.g.,
+
+ f :: forall a. a -> a
+ f x = e @a
+
+ Here, the 'forall a' brings 'a' into scope over the body of 'f'.
+
+ Note that ScopedTypeVariables does /not/ interact with standalone kind
+ signatures, only type signatures.
+
+* In explicit type annotations in expressions, e.g.,
+
+ id @a :: forall a. a -> a
+
+* In instance declarations, e.g.,
+
+ instance forall a. C [a] where
+ m = e @a
+
+ Note that unlike the examples above, the use of an outermost 'forall' isn't
+ required to bring 'a' into scope. That is, the following would also work:
+
+ instance forall a. C [a] where
+ m = e @a
+
+Note that all of the types above obey the forall-or-nothing rule. As a result,
+the places in the AST that can have lexically scoped type variables are a
+subset of the places that use HsOuterTyVarBndrs
+(See Note [forall-or-nothing rule].)
+
+Some other observations about lexically scoped type variables:
+
+* Only type variables bound by an /invisible/ forall can be lexically scoped.
+ See Note [hsScopedTvs and visible foralls].
+* The lexically scoped type variables may be a strict subset of the type
+ variables brought into scope by a type signature.
+ See Note [Binding scoped type variables] in GHC.Tc.Gen.Sig.
+-}
+
+mapHsOuterImplicit :: (XHsOuterImplicit pass -> XHsOuterImplicit pass)
+ -> HsOuterTyVarBndrs flag pass
+ -> HsOuterTyVarBndrs flag pass
+mapHsOuterImplicit f (HsOuterImplicit{hso_ximplicit = imp}) =
+ HsOuterImplicit{hso_ximplicit = f imp}
+mapHsOuterImplicit _ hso@(HsOuterExplicit{}) = hso
+mapHsOuterImplicit _ hso@(XHsOuterTyVarBndrs{}) = hso
+
+
+--------------------------------------------------
+-- | These names are used early on to store the names of implicit
+-- parameters. They completely disappear after type-checking.
+newtype HsIPName = HsIPName FastString
+ deriving( Eq, Data )
+
+hsIPNameFS :: HsIPName -> FastString
+hsIPNameFS (HsIPName n) = n
+
+instance Outputable HsIPName where
+ ppr (HsIPName n) = char '?' <> ftext n -- Ordinary implicit parameters
+
+instance OutputableBndr HsIPName where
+ pprBndr _ n = ppr n -- Simple for now
+ pprInfixOcc n = ppr n
+ pprPrefixOcc n = ppr n
+
+--------------------------------------------------
+
+-- | Haskell Type Variable Binder
+-- The flag annotates the binder. It is 'Specificity' in places where
+-- explicit specificity is allowed (e.g. x :: forall {a} b. ...) or
+-- '()' in other places.
+data HsTyVarBndr flag pass
+ = UserTyVar -- no explicit kinding
+ (XUserTyVar pass)
+ flag
+ (LIdP pass)
+ -- See Note [Located RdrNames] in GHC.Hs.Expr
+
+ | KindedTyVar
+ (XKindedTyVar pass)
+ flag
+ (LIdP pass)
+ (LHsKind pass) -- The user-supplied kind signature
+ -- ^
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen',
+ -- 'GHC.Parser.Annotation.AnnDcolon', 'GHC.Parser.Annotation.AnnClose'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | XTyVarBndr
+ !(XXTyVarBndr pass)
+
+-- | Does this 'HsTyVarBndr' come with an explicit kind annotation?
+isHsKindedTyVar :: HsTyVarBndr flag pass -> Bool
+isHsKindedTyVar (UserTyVar {}) = False
+isHsKindedTyVar (KindedTyVar {}) = True
+isHsKindedTyVar (XTyVarBndr {}) = False
+
+-- | Haskell Type
+data HsType pass
+ = HsForAllTy -- See Note [HsType binders]
+ { hst_xforall :: XForAllTy pass
+ , hst_tele :: HsForAllTelescope pass
+ -- Explicit, user-supplied 'forall a {b} c'
+ , hst_body :: LHsType pass -- body type
+ }
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnForall',
+ -- 'GHC.Parser.Annotation.AnnDot','GHC.Parser.Annotation.AnnDarrow'
+ -- For details on above see note [Api annotations] in "GHC.Parser.Annotation"
+
+ | HsQualTy -- See Note [HsType binders]
+ { hst_xqual :: XQualTy pass
+ , hst_ctxt :: LHsContext pass -- Context C => blah
+ , hst_body :: LHsType pass }
+
+ | HsTyVar (XTyVar pass)
+ PromotionFlag -- Whether explicitly promoted,
+ -- for the pretty printer
+ (LIdP pass)
+ -- Type variable, type constructor, or data constructor
+ -- see Note [Promotions (HsTyVar)]
+ -- See Note [Located RdrNames] in GHC.Hs.Expr
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : None
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsAppTy (XAppTy pass)
+ (LHsType pass)
+ (LHsType pass)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : None
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsAppKindTy (XAppKindTy pass) -- type level type app
+ (LHsType pass)
+ (LHsKind pass)
+
+ | HsFunTy (XFunTy pass)
+ (HsArrow pass)
+ (LHsType pass) -- function type
+ (LHsType pass)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnRarrow',
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsListTy (XListTy pass)
+ (LHsType pass) -- Element type
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'['@,
+ -- 'GHC.Parser.Annotation.AnnClose' @']'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsTupleTy (XTupleTy pass)
+ HsTupleSort
+ [LHsType pass] -- Element types (length gives arity)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'(' or '(#'@,
+ -- 'GHC.Parser.Annotation.AnnClose' @')' or '#)'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsSumTy (XSumTy pass)
+ [LHsType pass] -- Element types (length gives arity)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'(#'@,
+ -- 'GHC.Parser.Annotation.AnnClose' '#)'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsOpTy (XOpTy pass)
+ (LHsType pass) (LIdP pass) (LHsType pass)
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : None
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsParTy (XParTy pass)
+ (LHsType pass) -- See Note [Parens in HsSyn] in GHC.Hs.Expr
+ -- Parenthesis preserved for the precedence re-arrangement in
+ -- GHC.Rename.HsType
+ -- It's important that a * (b + c) doesn't get rearranged to (a*b) + c!
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'('@,
+ -- 'GHC.Parser.Annotation.AnnClose' @')'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsIParamTy (XIParamTy pass)
+ (XRec pass HsIPName) -- (?x :: ty)
+ (LHsType pass) -- Implicit parameters as they occur in
+ -- contexts
+ -- ^
+ -- > (?x :: ty)
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnDcolon'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsStarTy (XStarTy pass)
+ Bool -- Is this the Unicode variant?
+ -- Note [HsStarTy]
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : None
+
+ | HsKindSig (XKindSig pass)
+ (LHsType pass) -- (ty :: kind)
+ (LHsKind pass) -- A type with a kind signature
+ -- ^
+ -- > (ty :: kind)
+ --
+ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'('@,
+ -- 'GHC.Parser.Annotation.AnnDcolon','GHC.Parser.Annotation.AnnClose' @')'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsSpliceTy (XSpliceTy pass)
+ (HsSplice pass) -- Includes quasi-quotes
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'$('@,
+ -- 'GHC.Parser.Annotation.AnnClose' @')'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsDocTy (XDocTy pass)
+ (LHsType pass) LHsDocString -- A documented type
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : None
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsBangTy (XBangTy pass)
+ HsSrcBang (LHsType pass) -- Bang-style type annotations
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' :
+ -- 'GHC.Parser.Annotation.AnnOpen' @'{-\# UNPACK' or '{-\# NOUNPACK'@,
+ -- 'GHC.Parser.Annotation.AnnClose' @'#-}'@
+ -- 'GHC.Parser.Annotation.AnnBang' @\'!\'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsRecTy (XRecTy pass)
+ [LConDeclField pass] -- Only in data type declarations
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @'{'@,
+ -- 'GHC.Parser.Annotation.AnnClose' @'}'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsExplicitListTy -- A promoted explicit list
+ (XExplicitListTy pass)
+ PromotionFlag -- whether explicitly promoted, for pretty printer
+ [LHsType pass]
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @"'["@,
+ -- 'GHC.Parser.Annotation.AnnClose' @']'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsExplicitTupleTy -- A promoted explicit tuple
+ (XExplicitTupleTy pass)
+ [LHsType pass]
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnOpen' @"'("@,
+ -- 'GHC.Parser.Annotation.AnnClose' @')'@
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsTyLit (XTyLit pass) HsTyLit -- A promoted numeric literal.
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : None
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ | HsWildCardTy (XWildCardTy pass) -- A type wildcard
+ -- See Note [The wildcard story for types]
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : None
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+ -- For adding new constructors via Trees that Grow
+ | XHsType
+ (XXType pass)
+
+-- An escape hatch for tunnelling a Core 'Type' through 'HsType'.
+-- For more details on how this works, see:
+--
+-- * @Note [Renaming HsCoreTys]@ in "GHC.Rename.HsType"
+--
+-- * @Note [Typechecking HsCoreTys]@ in "GHC.Tc.Gen.HsType"
+type HsCoreTy = Type
+
+
+-- Note [Literal source text] in GHC.Types.Basic for SourceText fields in
+-- the following
+-- | Haskell Type Literal
+data HsTyLit
+ = HsNumTy SourceText Integer
+ | HsStrTy SourceText FastString
+ deriving Data
+
+-- | Denotes the type of arrows in the surface language
+data HsArrow pass
+ = HsUnrestrictedArrow IsUnicodeSyntax
+ -- ^ a -> b or a → b
+ | HsLinearArrow IsUnicodeSyntax
+ -- ^ a %1 -> b or a %1 → b, or a ⊸ b
+ | HsExplicitMult IsUnicodeSyntax (LHsType 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
+ -- `HsType` so as to preserve the syntax as written in the
+ -- program.
+
+-- | This is used in the syntax. In constructor declaration. It must keep the
+-- arrow representation.
+data HsScaled pass a = HsScaled (HsArrow pass) a
+
+hsMult :: HsScaled pass a -> HsArrow pass
+hsMult (HsScaled m _) = m
+
+hsScaledThing :: HsScaled pass a -> a
+hsScaledThing (HsScaled _ t) = t
+
+-- | When creating syntax we use the shorthands. It's better for printing, also,
+-- the shorthands work trivially at each pass.
+hsUnrestricted, hsLinear :: a -> HsScaled pass a
+hsUnrestricted = HsScaled (HsUnrestrictedArrow NormalSyntax)
+hsLinear = HsScaled (HsLinearArrow NormalSyntax)
+
+instance Outputable a => Outputable (HsScaled pass a) where
+ ppr (HsScaled _cnt t) = -- ppr cnt <> ppr t
+ ppr t
+
+{-
+Note [Unit tuples]
+~~~~~~~~~~~~~~~~~~
+Consider the type
+ type instance F Int = ()
+We want to parse that "()"
+ as HsTupleTy HsBoxedOrConstraintTuple [],
+NOT as HsTyVar unitTyCon
+
+Why? Because F might have kind (* -> Constraint), so we when parsing we
+don't know if that tuple is going to be a constraint tuple or an ordinary
+unit tuple. The HsTupleSort flag is specifically designed to deal with
+that, but it has to work for unit tuples too.
+
+Note [Promotions (HsTyVar)]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+HsTyVar: A name in a type or kind.
+ Here are the allowed namespaces for the name.
+ In a type:
+ Var: not allowed
+ Data: promoted data constructor
+ Tv: type variable
+ TcCls before renamer: type constructor, class constructor, or promoted data constructor
+ TcCls after renamer: type constructor or class constructor
+ In a kind:
+ Var, Data: not allowed
+ Tv: kind variable
+ TcCls: kind constructor or promoted type constructor
+
+ The 'Promoted' field in an HsTyVar captures whether the type was promoted in
+ the source code by prefixing an apostrophe.
+
+Note [HsStarTy]
+~~~~~~~~~~~~~~~
+When the StarIsType extension is enabled, we want to treat '*' and its Unicode
+variant identically to 'Data.Kind.Type'. Unfortunately, doing so in the parser
+would mean that when we pretty-print it back, we don't know whether the user
+wrote '*' or 'Type', and lose the parse/ppr roundtrip property.
+
+As a workaround, we parse '*' as HsStarTy (if it stands for 'Data.Kind.Type')
+and then desugar it to 'Data.Kind.Type' in the typechecker (see tc_hs_type).
+When '*' is a regular type operator (StarIsType is disabled), HsStarTy is not
+involved.
+
+
+Note [Promoted lists and tuples]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Notice the difference between
+ HsListTy HsExplicitListTy
+ HsTupleTy HsExplicitListTupleTy
+
+E.g. f :: [Int] HsListTy
+
+ g3 :: T '[] All these use
+ g2 :: T '[True] HsExplicitListTy
+ g1 :: T '[True,False]
+ g1a :: T [True,False] (can omit ' where unambiguous)
+
+ kind of T :: [Bool] -> * This kind uses HsListTy!
+
+E.g. h :: (Int,Bool) HsTupleTy; f is a pair
+ k :: S '(True,False) HsExplicitTypleTy; S is indexed by
+ a type-level pair of booleans
+ kind of S :: (Bool,Bool) -> * This kind uses HsExplicitTupleTy
+
+Note [Distinguishing tuple kinds]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Apart from promotion, tuples can have one of three different kinds:
+
+ x :: (Int, Bool) -- Regular boxed tuples
+ f :: Int# -> (# Int#, Int# #) -- Unboxed tuples
+ g :: (Eq a, Ord a) => a -- Constraint tuples
+
+For convenience, internally we use a single constructor for all of these,
+namely HsTupleTy, but keep track of the tuple kind (in the first argument to
+HsTupleTy, a HsTupleSort). We can tell if a tuple is unboxed while parsing,
+because of the #. However, with -XConstraintKinds we can only distinguish
+between constraint and boxed tuples during type checking, in general. Hence the
+two constructors of HsTupleSort:
+
+ HsUnboxedTuple -> Produced by the parser
+ HsBoxedOrConstraintTuple -> Could be a boxed or a constraint
+ tuple. Produced by the parser only,
+ disappears after type checking
+
+After typechecking, we use TupleSort (which clearly distinguishes between
+constraint tuples and boxed tuples) rather than HsTupleSort.
+-}
+
+-- | Haskell Tuple Sort
+data HsTupleSort = HsUnboxedTuple
+ | HsBoxedOrConstraintTuple
+ deriving Data
+
+-- | Located Constructor Declaration Field
+type LConDeclField pass = XRec pass (ConDeclField pass)
+ -- ^ May have 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnComma' when
+ -- in a list
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+
+-- | Constructor Declaration Field
+data ConDeclField pass -- Record fields have Haddock docs on them
+ = ConDeclField { cd_fld_ext :: XConDeclField pass,
+ cd_fld_names :: [LFieldOcc pass],
+ -- ^ See Note [ConDeclField passs]
+ cd_fld_type :: LBangType pass,
+ cd_fld_doc :: Maybe LHsDocString }
+ -- ^ - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnDcolon'
+
+ -- For details on above see note [Api annotations] in GHC.Parser.Annotation
+ | XConDeclField !(XXConDeclField pass)
+
+-- | Describes the arguments to a data constructor. This is a common
+-- representation for several constructor-related concepts, including:
+--
+-- * The arguments in a Haskell98-style constructor declaration
+-- (see 'HsConDeclH98Details' in "GHC.Hs.Decls").
+--
+-- * The arguments in constructor patterns in @case@/function definitions
+-- (see 'HsConPatDetails' in "GHC.Hs.Pat").
+--
+-- * The left-hand side arguments in a pattern synonym binding
+-- (see 'HsPatSynDetails' in "GHC.Hs.Binds").
+--
+-- One notable exception is the arguments in a GADT constructor, which uses
+-- a separate data type entirely (see 'HsConDeclGADTDetails' in
+-- "GHC.Hs.Decls"). This is because GADT constructors cannot be declared with
+-- infix syntax, unlike the concepts above (#18844).
+data HsConDetails tyarg arg rec
+ = PrefixCon [tyarg] [arg] -- C @t1 @t2 p1 p2 p3
+ | RecCon rec -- C { x = p1, y = p2 }
+ | InfixCon arg arg -- p1 `C` p2
+ deriving Data
+
+-- | An empty list that can be used to indicate that there are no
+-- type arguments allowed in cases where HsConDetails is applied to Void.
+noTypeArgs :: [Void]
+noTypeArgs = []
+
+instance (Outputable tyarg, Outputable arg, Outputable rec)
+ => Outputable (HsConDetails tyarg arg rec) where
+ ppr (PrefixCon tyargs args) = text "PrefixCon:" <+> hsep (map (\t -> text "@" <> ppr t) tyargs) <+> ppr args
+ ppr (RecCon rec) = text "RecCon:" <+> ppr rec
+ ppr (InfixCon l r) = text "InfixCon:" <+> ppr [l, r]
+
+{-
+Note [ConDeclField passs]
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A ConDeclField contains a list of field occurrences: these always
+include the field label as the user wrote it. After the renamer, it
+will additionally contain the identity of the selector function in the
+second component.
+
+Due to DuplicateRecordFields, the OccName of the selector function
+may have been mangled, which is why we keep the original field label
+separately. For example, when DuplicateRecordFields is enabled
+
+ data T = MkT { x :: Int }
+
+gives
+
+ ConDeclField { cd_fld_names = [L _ (FieldOcc "x" $sel:x:MkT)], ... }.
+-}
+
+-----------------------
+-- A valid type must have a for-all at the top of the type, or of the fn arg
+-- types
+
+---------------------
+
+{- Note [Scoping of named wildcards]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider
+ f :: _a -> _a
+ f x = let g :: _a -> _a
+ g = ...
+ in ...
+
+Currently, for better or worse, the "_a" variables are all the same. So
+although there is no explicit forall, the "_a" scopes over the definition.
+I don't know if this is a good idea, but there it is.
+-}
+
+{- Note [hsScopedTvs and visible foralls]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-XScopedTypeVariables can be defined in terms of a desugaring to
+-XTypeAbstractions (GHC Proposal #50):
+
+ fn :: forall a b c. tau(a,b,c) fn :: forall a b c. tau(a,b,c)
+ fn = defn(a,b,c) ==> fn @x @y @z = defn(x,y,z)
+
+That is, for every type variable of the leading 'forall' in the type signature,
+we add an invisible binder at term level.
+
+This model does not extend to visible forall, as discussed here:
+
+* https://gitlab.haskell.org/ghc/ghc/issues/16734#note_203412
+* https://github.com/ghc-proposals/ghc-proposals/pull/238
+
+The conclusion of these discussions can be summarized as follows:
+
+ > Assuming support for visible 'forall' in terms, consider this example:
+ >
+ > vfn :: forall x y -> tau(x,y)
+ > vfn = \a b -> ...
+ >
+ > The user has written their own binders 'a' and 'b' to stand for 'x' and
+ > 'y', and we definitely should not desugar this into:
+ >
+ > vfn :: forall x y -> tau(x,y)
+ > vfn x y = \a b -> ... -- bad!
+
+This design choice is reflected in the design of HsOuterSigTyVarBndrs, which are
+used in every place that ScopedTypeVariables takes effect:
+
+ data HsOuterTyVarBndrs flag pass
+ = HsOuterImplicit { ... }
+ | HsOuterExplicit { ..., hso_bndrs :: [LHsTyVarBndr flag pass] }
+ | ...
+ type HsOuterSigTyVarBndrs = HsOuterTyVarBndrs Specificity
+
+The HsOuterExplicit constructor is only used in type signatures with outermost,
+/invisible/ 'forall's. Any other type—including those with outermost,
+/visible/ 'forall's—will use HsOuterImplicit. Therefore, when we determine
+which type variables to bring into scope over the body of a function
+(in hsScopedTvs), we /only/ bring the type variables bound by the hso_bndrs in
+an HsOuterExplicit into scope. If we have an HsOuterImplicit instead, then we
+do not bring any type variables into scope over the body of a function at all.
+
+At the moment, GHC does not support visible 'forall' in terms. Nevertheless,
+it is still possible to write erroneous programs that use visible 'forall's in
+terms, such as this example:
+
+ x :: forall a -> a -> a
+ x = x
+
+Previous versions of GHC would bring `a` into scope over the body of `x` in the
+hopes that the typechecker would error out later
+(see `GHC.Tc.Validity.vdqAllowed`). However, this can wreak havoc in the
+renamer before GHC gets to that point (see #17687 for an example of this).
+Bottom line: nip problems in the bud by refraining from bringing any type
+variables in an HsOuterImplicit into scope over the body of a function, even
+if they correspond to a visible 'forall'.
+-}
+
+{-
+************************************************************************
+* *
+ Decomposing HsTypes
+* *
+************************************************************************
+-}
+
+-- Arguments in an expression/type after splitting
+data HsArg tm ty
+ = HsValArg tm -- Argument is an ordinary expression (f arg)
+ | HsTypeArg SrcSpan ty -- Argument is a visible type application (f @ty)
+ -- SrcSpan is location of the `@`
+ | HsArgPar SrcSpan -- See Note [HsArgPar]
+
+numVisibleArgs :: [HsArg tm ty] -> Arity
+numVisibleArgs = count is_vis
+ where is_vis (HsValArg _) = True
+ is_vis _ = False
+
+-- type level equivalent
+type LHsTypeArg p = HsArg (LHsType p) (LHsKind p)
+
+instance (Outputable tm, Outputable ty) => Outputable (HsArg tm ty) where
+ ppr (HsValArg tm) = ppr tm
+ ppr (HsTypeArg _ ty) = char '@' <> ppr ty
+ ppr (HsArgPar sp) = text "HsArgPar" <+> ppr sp
+{-
+Note [HsArgPar]
+A HsArgPar indicates that everything to the left of this in the argument list is
+enclosed in parentheses together with the function itself. It is necessary so
+that we can recreate the parenthesis structure in the original source after
+typechecking the arguments.
+
+The SrcSpan is the span of the original HsPar
+
+((f arg1) arg2 arg3) results in an input argument list of
+[HsValArg arg1, HsArgPar span1, HsValArg arg2, HsValArg arg3, HsArgPar span2]
+
+-}
+
+--------------------------------
+
+
+{-
+************************************************************************
+* *
+ FieldOcc
+* *
+************************************************************************
+-}
+
+-- | Located Field Occurrence
+type LFieldOcc pass = XRec pass (FieldOcc pass)
+
+-- | Field Occurrence
+--
+-- Represents an *occurrence* of an unambiguous field. This may or may not be a
+-- binding occurrence (e.g. this type is used in 'ConDeclField' and
+-- 'RecordPatSynField' which bind their fields, but also in 'HsRecField' for
+-- record construction and patterns, which do not).
+--
+-- We store both the 'RdrName' the user originally wrote, and after the renamer,
+-- the selector function.
+data FieldOcc pass = FieldOcc { extFieldOcc :: XCFieldOcc pass
+ , rdrNameFieldOcc :: Located RdrName
+ -- ^ See Note [Located RdrNames] in "GHC.Hs.Expr"
+ }
+
+ | XFieldOcc
+ !(XXFieldOcc pass)
+
+deriving instance (Eq (XCFieldOcc pass), Eq (XXFieldOcc pass)) => Eq (FieldOcc pass)
+
+instance Outputable (FieldOcc pass) where
+ ppr = ppr . rdrNameFieldOcc
+
+
+-- | Ambiguous Field Occurrence
+--
+-- Represents an *occurrence* of a field that is potentially
+-- ambiguous after the renamer, with the ambiguity resolved by the
+-- typechecker. We always store the 'RdrName' that the user
+-- originally wrote, and store the selector function after the renamer
+-- (for unambiguous occurrences) or the typechecker (for ambiguous
+-- occurrences).
+--
+-- See Note [HsRecField and HsRecUpdField] in "GHC.Hs.Pat" and
+-- Note [Disambiguating record fields] in "GHC.Tc.Gen.Head".
+-- See Note [Located RdrNames] in "GHC.Hs.Expr"
+data AmbiguousFieldOcc pass
+ = Unambiguous (XUnambiguous pass) (Located RdrName)
+ | Ambiguous (XAmbiguous pass) (Located RdrName)
+ | XAmbiguousFieldOcc !(XXAmbiguousFieldOcc pass)
+
+
+{-
+************************************************************************
+* *
+\subsection{Pretty printing}
+* *
+************************************************************************
+-}
+
+instance Outputable HsTyLit where
+ ppr = ppr_tylit
+--------------------------
+ppr_tylit :: HsTyLit -> SDoc
+ppr_tylit (HsNumTy source i) = pprWithSourceText source (integer i)
+ppr_tylit (HsStrTy source s) = pprWithSourceText source (text (show s))