diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2021-01-10 02:01:43 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-01-23 21:32:47 -0500 |
commit | 81f0665513d65c2d7e544cbe8adeff4b0d6fdfff (patch) | |
tree | 9e55698fc5cc041e8623eff2978eb94b72894130 /compiler/GHC/Hs | |
parent | e6e1cf743c6de87c376c32d2279e2d684151f3d7 (diff) | |
download | haskell-81f0665513d65c2d7e544cbe8adeff4b0d6fdfff.tar.gz |
Separate AST from GhcPass (#18936)
----------------
What:
There are two splits.
The first spit is:
- `Language.Haskell.Syntax.Extension`
- `GHC.Hs.Extension`
where the former now just contains helpers like `NoExtCon` and all the
families, and the latter is everything having to do with `GhcPass`.
The second split is:
- `Language.Haskell.Syntax.<mod>`
- `GHC.Hs.<mod>`
Where the former contains all the data definitions, and the few helpers
that don't use `GhcPass`, and the latter contains everything else. The
second modules also reexport the former.
----------------
Why:
See the issue for more details, but in short answer is we're trying to
grasp at the modularity TTG is supposed to offer, after a long time of
mainly just getting the safety benefits of more complete pattern
matching on the AST.
Now, we have an AST datatype which, without `GhcPass` is decently
stripped of GHC-specific concerns. Whereas before, not was it
GHC-specific, it was aware of all the GHC phases despite the
parameterization, with the instances and parametric data structure
side-by-side.
For what it's worth there are also some smaller, imminent benefits:
- The latter change also splits a strongly connected component in two,
since none of the `Language.Haskell.Syntax.*` modules import the older
ones.
- A few TTG violations (Using GhcPass directly in the AST) in `Expr` are
now more explicitly accounted for with new type families to provide the
necessary indirection.
-----------------
Future work:
- I don't see why all the type families should live in
`Language.Haskell.Syntax.Extension`. That seems anti-modular for
little benefit. All the ones used just once can be moved next to the
AST type they serve as an extension point for.
- Decide what to do with the `Outputable` instances. Some of these are
no orphans because they referred to `GhcPass`, and had to be moved. I
think the types could be generalized so they don't refer to `GhcPass`
and therefore can be moved back, but having gotten flak for increasing
the size and complexity types when generalizing before, I did *not*
want to do this.
- We should triage the remaining contents of `GHC.Hs.<mod>`. The
renaming helpers are somewhat odd for needing `GhcPass`. We might
consider if they are a) in fact only needed by one phase b) can be
generalized to be non-GhcPass-specific (e.g. take a callback rather
than GADT-match with `IsPass`) and then they can live in
`Language.Haskell.Syntax.<mod>`.
For more details, see
https://gitlab.haskell.org/ghc/ghc/-/wikis/implementing-trees-that-grow
Bumps Haddock submodule
Diffstat (limited to 'compiler/GHC/Hs')
-rw-r--r-- | compiler/GHC/Hs/Binds.hs | 655 | ||||
-rw-r--r-- | compiler/GHC/Hs/Decls.hs | 1578 | ||||
-rw-r--r-- | compiler/GHC/Hs/Expr.hs | 1655 | ||||
-rw-r--r-- | compiler/GHC/Hs/Expr.hs-boot | 38 | ||||
-rw-r--r-- | compiler/GHC/Hs/Extension.hs | 639 | ||||
-rw-r--r-- | compiler/GHC/Hs/ImpExp.hs | 3 | ||||
-rw-r--r-- | compiler/GHC/Hs/Lit.hs | 178 | ||||
-rw-r--r-- | compiler/GHC/Hs/Pat.hs | 330 | ||||
-rw-r--r-- | compiler/GHC/Hs/Pat.hs-boot | 15 | ||||
-rw-r--r-- | compiler/GHC/Hs/Type.hs | 1186 | ||||
-rw-r--r-- | compiler/GHC/Hs/Utils.hs | 1 |
11 files changed, 89 insertions, 6189 deletions
diff --git a/compiler/GHC/Hs/Binds.hs b/compiler/GHC/Hs/Binds.hs index 1f895c20ec..c345cbe5e9 100644 --- a/compiler/GHC/Hs/Binds.hs +++ b/compiler/GHC/Hs/Binds.hs @@ -7,9 +7,10 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] - -- in module GHC.Hs.Extension + -- in module Language.Haskell.Syntax.Extension {-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -Wno-orphans #-} -- Outputable {- (c) The University of Glasgow 2006 @@ -20,26 +21,26 @@ Datatype for: @BindGroup@, @Bind@, @Sig@, @Bind@. -} -module GHC.Hs.Binds where +module GHC.Hs.Binds + ( module Language.Haskell.Syntax.Binds + , module GHC.Hs.Binds + ) where import GHC.Prelude -import {-# SOURCE #-} GHC.Hs.Expr ( pprExpr, LHsExpr, - MatchGroup, pprFunBind, - GRHSs, pprPatBind ) -import {-# SOURCE #-} GHC.Hs.Pat ( LPat ) +import Language.Haskell.Syntax.Binds +import {-# SOURCE #-} GHC.Hs.Expr ( pprExpr, pprFunBind, pprPatBind ) + +import Language.Haskell.Syntax.Extension import GHC.Hs.Extension import GHC.Hs.Type -import GHC.Core import GHC.Tc.Types.Evidence import GHC.Core.Type import GHC.Types.Name.Set 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.FastString import GHC.Data.BooleanFormula (LBooleanFormula) @@ -47,10 +48,8 @@ import GHC.Data.BooleanFormula (LBooleanFormula) import GHC.Utils.Outputable import GHC.Utils.Panic -import Data.Data hiding ( Fixity ) import Data.List hiding ( foldr ) import Data.Function -import Data.Void {- ************************************************************************ @@ -62,76 +61,14 @@ import Data.Void Global bindings (where clauses) -} --- During renaming, we need bindings where the left-hand sides --- have been renamed but the right-hand sides have not. -- the ...LR datatypes are parametrized by two id types, -- one for the left and one for the right. --- 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 instance XHsValBinds (GhcPass pL) (GhcPass pR) = NoExtField type instance XHsIPBinds (GhcPass pL) (GhcPass pR) = NoExtField type instance XEmptyLocalBinds (GhcPass pL) (GhcPass pR) = NoExtField type instance XXHsLocalBindsLR (GhcPass pL) (GhcPass pR) = NoExtCon -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) - -- --------------------------------------------------------------------- -- Deal with ValBindsOut @@ -147,177 +84,6 @@ type instance XXValBindsLR (GhcPass pL) (GhcPass pR) -- --------------------------------------------------------------------- --- | 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) - type instance XFunBind (GhcPass pL) GhcPs = NoExtField type instance XFunBind (GhcPass pL) GhcRn = NameSet -- Free variables type instance XFunBind (GhcPass pL) GhcTc = HsWrapper -- See comments on FunBind.fun_ext @@ -331,52 +97,9 @@ type instance XAbsBinds (GhcPass pL) (GhcPass pR) = NoExtField type instance XPatSynBind (GhcPass pL) (GhcPass pR) = NoExtField type instance XXHsBindsLR (GhcPass pL) (GhcPass pR) = NoExtCon - - -- 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) - type instance XABE (GhcPass p) = NoExtField type instance XXABExport (GhcPass p) = NoExtCon - --- | - '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) - type instance XPSB (GhcPass idL) GhcPs = NoExtField type instance XPSB (GhcPass idL) GhcRn = NameSet type instance XPSB (GhcPass idL) GhcTc = NameSet @@ -796,15 +519,6 @@ pprTicks pp_no_debug pp_when_debug ************************************************************************ -} --- | 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) - type instance XIPBinds GhcPs = NoExtField type instance XIPBinds GhcRn = NoExtField type instance XIPBinds GhcTc = TcEvBinds -- binds uses of the @@ -819,30 +533,6 @@ isEmptyIPBindsPR (IPBinds _ is) = null is isEmptyIPBindsTc :: HsIPBinds GhcTc -> Bool isEmptyIPBindsTc (IPBinds ds is) = null is && isEmptyTcEvBinds ds --- | 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) - type instance XCIPBind (GhcPass p) = NoExtField type instance XXIPBind (GhcPass p) = NoExtCon @@ -863,167 +553,8 @@ instance OutputableBndrId p => Outputable (IPBind (GhcPass p)) where \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) - type instance XTypeSig (GhcPass p) = NoExtField type instance XPatSynSig (GhcPass p) = NoExtField type instance XClassOpSig (GhcPass p) = NoExtField @@ -1037,116 +568,9 @@ type instance XSCCFunSig (GhcPass p) = NoExtField type instance XCompleteMatchSig (GhcPass p) = NoExtField type instance XXSig (GhcPass p) = NoExtCon --- | 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 instance XFixitySig (GhcPass p) = NoExtField type instance XXFixitySig (GhcPass p) = NoExtCon --- | 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" - -{- -Check if signatures overlap; this is used when checking for duplicate -signatures. Since some of the signatures contain a list of names, testing for -equality is not enough -- we have to check if they overlap. --} - instance OutputableBndrId p => Outputable (Sig (GhcPass p)) where ppr sig = ppr_sig sig @@ -1219,62 +643,3 @@ instance Outputable TcSpecPrag where pprMinimalSig :: (OutputableBndr name) => LBooleanFormula (Located name) -> SDoc pprMinimalSig (L _ bf) = ppr (fmap unLoc bf) - -{- -************************************************************************ -* * -\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/GHC/Hs/Decls.hs b/compiler/GHC/Hs/Decls.hs index 882303373f..f896d0aeba 100644 --- a/compiler/GHC/Hs/Decls.hs +++ b/compiler/GHC/Hs/Decls.hs @@ -9,7 +9,9 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] - -- in module GHC.Hs.Extension + -- in module Language.Haskell.Syntax.Extension + +{-# OPTIONS_GHC -Wno-orphans #-} {- (c) The University of Glasgow 2006 @@ -99,17 +101,17 @@ module GHC.Hs.Decls ( -- friends: import GHC.Prelude -import {-# SOURCE #-} GHC.Hs.Expr( HsExpr, HsSplice, pprExpr, - pprSpliceDecl ) +import Language.Haskell.Syntax.Decls + +import {-# SOURCE #-} GHC.Hs.Expr ( pprExpr, pprSpliceDecl ) -- Because Expr imports Decls via HsBracket import GHC.Hs.Binds import GHC.Hs.Type import GHC.Hs.Doc -import GHC.Core.TyCon import GHC.Types.Basic import GHC.Core.Coercion -import GHC.Types.ForeignCall +import Language.Haskell.Syntax.Extension import GHC.Hs.Extension import GHC.Types.Name import GHC.Types.Name.Set @@ -118,17 +120,13 @@ import GHC.Types.Fixity -- others: import GHC.Core.Class import GHC.Utils.Outputable -import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Types.SrcLoc import GHC.Types.SourceText import GHC.Core.Type -import GHC.Unit.Module.Warnings import GHC.Data.Bag import GHC.Data.Maybe -import Data.Data hiding (TyCon,Fixity, Infix) -import Data.Void {- ************************************************************************ @@ -138,33 +136,6 @@ import Data.Void ************************************************************************ -} -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) - type instance XTyClD (GhcPass _) = NoExtField type instance XInstD (GhcPass _) = NoExtField type instance XDerivD (GhcPass _) = NoExtField @@ -181,50 +152,6 @@ type instance XDocD (GhcPass _) = NoExtField type instance XRoleAnnotD (GhcPass _) = NoExtField type instance XXHsDecl (GhcPass _) = NoExtCon -{- -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). --} - -- | Partition a list of HsDecls into function/pattern bindings, signatures, -- type family declarations, type family instances, and documentation comments. -- @@ -257,40 +184,6 @@ partitionBindsAndSigs = go -> (bs, ss, ts, tfis, dfis, L l d : docs) _ -> pprPanic "partitionBindsAndSigs" (ppr decl) --- | 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) - type instance XCHsGroup (GhcPass _) = NoExtField type instance XXHsGroup (GhcPass _) = NoExtCon @@ -299,9 +192,6 @@ emptyGroup, emptyRdrGroup, emptyRnGroup :: HsGroup (GhcPass p) emptyRdrGroup = emptyGroup { hs_valds = emptyValBindsIn } emptyRnGroup = emptyGroup { hs_valds = emptyValBindsOut } -hsGroupInstDecls :: HsGroup id -> [LInstDecl id] -hsGroupInstDecls = (=<<) group_instds . hs_tyclds - emptyGroup = HsGroup { hs_ext = noExtField, hs_tyclds = [], hs_derivds = [], @@ -415,17 +305,6 @@ instance (OutputableBndrId p) => Outputable (HsGroup (GhcPass p)) where vcat_mb gap (Nothing : ds) = vcat_mb gap ds vcat_mb gap (Just d : ds) = gap $$ d $$ vcat_mb blankLine ds --- | 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 instance XSpliceDecl (GhcPass _) = NoExtField type instance XXSpliceDecl (GhcPass _) = NoExtCon @@ -439,236 +318,6 @@ instance OutputableBndrId 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] -} type instance XFamDecl (GhcPass _) = NoExtField @@ -685,74 +334,8 @@ type instance XClassDecl GhcPs = LayoutInfo -- See Note [Class LayoutInfo] type instance XClassDecl GhcRn = NameSet -- FVs type instance XClassDecl GhcTc = NameSet -- FVs -{- 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 --} - type instance XXTyClDecl (GhcPass _) = NoExtCon --- 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 tyFamInstDeclName :: TyFamInstDecl (GhcPass p) -> IdP (GhcPass p) @@ -773,25 +356,6 @@ tyClDeclLName (ClassDecl { tcdLName = ln }) = ln tcdName :: TyClDecl (GhcPass p) -> IdP (GhcPass p) tcdName = unLoc . tyClDeclLName -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 - -- | Does this declaration have a complete, user-supplied kind signature? -- See Note [CUSKs: complete user-supplied kind signatures] hsDeclHasCusk :: TyClDecl GhcRn -> Bool @@ -885,95 +449,6 @@ pprTyClDeclFlavour (FamDecl { tcdFam = FamilyDecl { fdInfo = info }}) pprTyClDeclFlavour (DataDecl { tcdDataDefn = HsDataDefn { dd_ND = nd } }) = ppr nd - -{- 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 @@ -982,210 +457,26 @@ NOTE THAT * * ********************************************************************* -} -{- 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) - type instance XCTyClGroup (GhcPass _) = NoExtField type instance XXTyClGroup (GhcPass _) = NoExtCon -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 - type instance XNoSig (GhcPass _) = NoExtField type instance XCKindSig (GhcPass _) = NoExtField type instance XTyVarSig (GhcPass _) = NoExtField type instance XXFamilyResultSig (GhcPass _) = NoExtCon - --- | 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 - type instance XCFamilyDecl (GhcPass _) = NoExtField type instance XXFamilyDecl (GhcPass _) = NoExtCon --- | 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]) - - ------------- Functions over FamilyDecls ----------- familyDeclLName :: FamilyDecl (GhcPass p) -> Located (IdP (GhcPass p)) @@ -1245,14 +536,6 @@ pprFamilyDecl top_level (FamilyDecl { fdInfo = info, fdLName = ltycon Just eqns -> vcat $ map (ppr_fam_inst_eqn . unLoc) eqns ) _ -> (empty, empty) -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" - {- ********************************************************************* @@ -1261,75 +544,10 @@ instance Outputable (FamilyInfo pass) where * * ********************************************************************* -} --- | 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) - type instance XCHsDataDefn (GhcPass _) = NoExtField type instance XXHsDataDefn (GhcPass _) = NoExtCon --- | 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 instance XCHsDerivingClause (GhcPass _) = NoExtField type instance XXHsDerivingClause (GhcPass _) = NoExtCon @@ -1349,35 +567,6 @@ instance OutputableBndrId p Just (L _ via@ViaStrategy{}) -> (empty, ppr via) _ -> (ppDerivStrategy dcs, empty) -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) - type instance XDctSingle (GhcPass _) = NoExtField type instance XDctMulti (GhcPass _) = NoExtField type instance XXDerivClauseTys (GhcPass _) = NoExtCon @@ -1386,252 +575,17 @@ instance OutputableBndrId p => Outputable (DerivClauseTys (GhcPass p)) where ppr (DctSingle _ ty) = ppr ty ppr (DctMulti _ tys) = parens (interpp'SP tys) --- | 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) - type instance XStandaloneKindSig (GhcPass p) = NoExtField type instance XXStandaloneKindSig (GhcPass p) = NoExtCon standaloneKindSigName :: StandaloneKindSig (GhcPass p) -> IdP (GhcPass p) standaloneKindSigName (StandaloneKindSig _ lname _) = unLoc lname -{- 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) - type instance XConDeclGADT (GhcPass _) = NoExtField type instance XConDeclH98 (GhcPass _) = NoExtField type instance XXConDecl (GhcPass _) = NoExtCon -{- 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]) - getConNames :: ConDecl GhcRn -> [Located Name] getConNames ConDeclH98 {con_name = name} = [name] getConNames ConDeclGADT {con_names = names} = names @@ -1685,10 +639,6 @@ instance OutputableBndrId p ppr (StandaloneKindSig _ v ki) = text "type" <+> pprPrefixOcc (unLoc v) <+> text "::" <+> ppr ki -instance Outputable NewOrData where - ppr NewType = text "newtype" - ppr DataType = text "data" - pp_condecls :: forall p. OutputableBndrId p => [LConDecl (GhcPass p)] -> SDoc pp_condecls cs | gadt_syntax -- In GADT syntax @@ -1749,190 +699,18 @@ ppr_con_names = pprWithCommas (pprPrefixOcc . unLoc) 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 - type instance XCFamEqn (GhcPass _) r = NoExtField type instance XXFamEqn (GhcPass _) r = NoExtCon ----------------- 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) - type instance XCClsInstDecl (GhcPass _) = NoExtField type instance XXClsInstDecl (GhcPass _) = NoExtCon ----------------- 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) - type instance XClsInstD (GhcPass _) = NoExtField type instance XDataFamInstD (GhcPass _) = NoExtField type instance XTyFamInstD (GhcPass _) = NoExtField @@ -2074,35 +852,6 @@ instDeclDataFamInsts inst_decls ************************************************************************ -} --- | 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) - type instance XCDerivDecl (GhcPass _) = NoExtField type instance XXDerivDecl (GhcPass _) = NoExtCon @@ -2125,22 +874,6 @@ instance OutputableBndrId p ************************************************************************ -} --- | 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@ - type instance XViaStrategy GhcPs = LHsSigType GhcPs type instance XViaStrategy GhcRn = LHsSigType GhcRn type instance XViaStrategy GhcTc = Type @@ -2155,15 +888,6 @@ instance OutputableBndrId p GhcRn -> ppr ty GhcTc -> ppr ty --- | 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" - -- | Eliminate a 'DerivStrategy'. foldDerivStrategy :: (p ~ GhcPass pass) => r -> (XViaStrategy p -> r) -> DerivStrategy p -> r @@ -2185,24 +909,8 @@ mapDerivStrategy f ds = foldDerivStrategy ds (ViaStrategy . f) ds \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) - type instance XCDefaultDecl (GhcPass _) = NoExtField type instance XXDefaultDecl (GhcPass _) = NoExtCon @@ -2219,45 +927,6 @@ instance OutputableBndrId p ************************************************************************ -} --- 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. --} - type instance XForeignImport GhcPs = NoExtField type instance XForeignImport GhcRn = NoExtField type instance XForeignImport GhcTc = Coercion @@ -2268,51 +937,6 @@ type instance XForeignExport GhcTc = Coercion type instance XXForeignDecl (GhcPass _) = NoExtCon --- 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 OutputableBndrId p => Outputable (ForeignDecl (GhcPass p)) where ppr (ForeignImport { fd_name = n, fd_sig_ty = ty, fd_fi = fimport }) @@ -2322,38 +946,6 @@ instance OutputableBndrId p hang (text "foreign export" <+> ppr fexport <+> ppr n) 2 (dcolon <+> ppr ty) -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 '"' - {- ************************************************************************ * * @@ -2362,50 +954,9 @@ instance Outputable ForeignExport where ************************************************************************ -} --- | 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) - type instance XCRuleDecls (GhcPass _) = NoExtField type instance XXRuleDecls (GhcPass _) = NoExtCon --- | 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 - type instance XHsRule GhcPs = NoExtField type instance XHsRule GhcRn = HsRuleRn type instance XHsRule GhcTc = HsRuleRn @@ -2415,30 +966,10 @@ type instance XXRuleDecl (GhcPass _) = NoExtCon flattenRuleDecls :: [LRuleDecls (GhcPass p)] -> [LRuleDecl (GhcPass p)] flattenRuleDecls decls = concatMap (rds_rules . unLoc) decls --- | 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 - type instance XCRuleBndr (GhcPass _) = NoExtField type instance XRuleBndrSig (GhcPass _) = NoExtField type instance XXRuleBndr (GhcPass _) = NoExtCon -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) - instance (OutputableBndrId p) => Outputable (RuleDecls (GhcPass p)) where ppr (HsRules { rds_src = st , rds_rules = rules }) @@ -2469,63 +1000,14 @@ instance (OutputableBndrId p) => Outputable (RuleBndr (GhcPass p)) where {- ************************************************************************ * * -\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) - type instance XWarnings (GhcPass _) = NoExtField type instance XXWarnDecls (GhcPass _) = NoExtCon --- | 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) - type instance XWarning (GhcPass _) = NoExtField type instance XXWarnDecl (GhcPass _) = NoExtCon @@ -2550,22 +1032,6 @@ instance OutputableBndr (IdP (GhcPass p)) ************************************************************************ -} --- | 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) - type instance XHsAnnotation (GhcPass _) = NoExtField type instance XXAnnDecl (GhcPass _) = NoExtCon @@ -2573,20 +1039,6 @@ instance (OutputableBndrId p) => Outputable (AnnDecl (GhcPass p)) where ppr (HsAnnotation _ _ provenance expr) = hsep [text "{-#", pprAnnProvenance provenance, pprExpr (unLoc expr), text "#-}"] --- | 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 - pprAnnProvenance :: OutputableBndr name => AnnProvenance name -> SDoc pprAnnProvenance ModuleAnnProvenance = text "ANN module" pprAnnProvenance (ValueAnnProvenance (L _ name)) @@ -2602,22 +1054,6 @@ pprAnnProvenance (TypeAnnProvenance (L _ name)) ************************************************************************ -} --- | 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) - type instance XCRoleAnnotDecl (GhcPass _) = NoExtField type instance XXRoleAnnotDecl (GhcPass _) = NoExtCon diff --git a/compiler/GHC/Hs/Expr.hs b/compiler/GHC/Hs/Expr.hs index 78b07e54a3..ac3a58a592 100644 --- a/compiler/GHC/Hs/Expr.hs +++ b/compiler/GHC/Hs/Expr.hs @@ -11,9 +11,10 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] - -- in module GHC.Hs.Extension + -- in module Language.Haskell.Syntax.Extension {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} +{-# OPTIONS_GHC -Wno-orphans #-} -- Outputable {- (c) The University of Glasgow 2006 @@ -21,23 +22,28 @@ -} -- | Abstract Haskell syntax for expressions. -module GHC.Hs.Expr where +module GHC.Hs.Expr + ( module Language.Haskell.Syntax.Expr + , module GHC.Hs.Expr + ) where #include "HsVersions.h" +import Language.Haskell.Syntax.Expr + -- friends: import GHC.Prelude import GHC.Hs.Decls import GHC.Hs.Pat import GHC.Hs.Lit +import Language.Haskell.Syntax.Extension import GHC.Hs.Extension import GHC.Hs.Type import GHC.Hs.Binds -- others: import GHC.Tc.Types.Evidence -import GHC.Core import GHC.Types.Name import GHC.Types.Name.Set import GHC.Types.Basic @@ -61,9 +67,6 @@ import qualified Data.Data as Data (Fixity(..)) import qualified Data.Kind import Data.Maybe (isJust) -import GHCi.RemoteTypes ( ForeignRef ) -import qualified Language.Haskell.TH as TH (Q) - {- ************************************************************************ * * @@ -72,16 +75,6 @@ import qualified Language.Haskell.TH as TH (Q) ************************************************************************ -} --- * 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 - -------------------------- -- | Post-Type checking Expression -- -- PostTcExpr is an evidence expression attached to the syntax tree by the @@ -95,39 +88,6 @@ type PostTcExpr = HsExpr GhcTc type PostTcTable = [(Name, PostTcExpr)] ------------------------- -{- 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 -- Defining SyntaxExpr in two stages allows for better type inference, because -- we can declare SyntaxExprGhc to be injective (and closed). Without injectivity, @@ -199,370 +159,6 @@ instance Outputable SyntaxExprTc where ppr NoSyntaxExprTc = text "<no syntax expr>" --- | 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 GhcRn) -- The parameterisation 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 GhcRn) -- Output of the renamer is the *original* renamed - -- expression, plus - [PendingRnSplice] -- _renamed_ splices to be type checked - - | HsTcBracketOut - (XTcBracketOut p) - (Maybe QuoteWrapper) -- The wrapper to apply type and dictionary argument - -- to the quote. - (HsBracket GhcRn) -- Output of the type checker is the *original* - -- renamed expression, plus - [PendingTcSplice] -- _typechecked_ splices to be - -- 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. - -- | Extra data fields for a 'RecordCon', added by the type checker data RecordConTc = RecordConTc { rcon_con_like :: ConLike -- The data constructor or pattern synonym @@ -594,6 +190,11 @@ data HsWrap hs_syn = HsWrap HsWrapper -- the wrapper deriving instance (Data (hs_syn GhcTc), Typeable hs_syn) => Data (HsWrap hs_syn) +type instance HsDoRn (GhcPass _) = GhcRn +type instance HsBracketRn (GhcPass _) = GhcRn +type instance PendingRnSplice' (GhcPass _) = PendingRnSplice +type instance PendingTcSplice' (GhcPass _) = PendingTcSplice + -- --------------------------------------------------------------------- type instance XVar (GhcPass _) = NoExtField @@ -694,184 +295,12 @@ data XXExprGhcTc | ExpansionExpr {-# UNPACK #-} !(HsExpansion (HsExpr GhcRn) (HsExpr GhcTc)) -{- -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) - type instance XSCC (GhcPass _) = NoExtField type instance XXPragE (GhcPass _) = NoExtCon --- | 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 - type instance XPresent (GhcPass _) = NoExtField type instance XMissing GhcPs = NoExtField @@ -884,148 +313,6 @@ tupArgPresent :: LHsTupArg (GhcPass p) -> Bool tupArgPresent (L _ (Present {})) = True tupArgPresent (L _ (Missing {})) = False -{- -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. --} - instance (OutputableBndrId p) => Outputable (HsExpr (GhcPass p)) where ppr expr = pprExpr expr @@ -1266,21 +553,6 @@ ppr_apps fun args = hang (ppr_expr fun) 2 (fsep (map pp args)) pp (Right arg) = text "@" <> ppr arg -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. --} pprDebugParendExpr :: (OutputableBndrId p) => PprPrec -> LHsExpr (GhcPass p) -> SDoc @@ -1410,111 +682,8 @@ instance Outputable (HsPragE (GhcPass p)) where \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 - type instance XCmdArrApp GhcPs = NoExtField type instance XCmdArrApp GhcRn = NoExtField type instance XCmdArrApp GhcTc = Type @@ -1541,25 +710,6 @@ type instance XXCmd GhcTc = HsWrap HsCmd -- wrap :: arg1 "->" arg2 -- Then (XCmd (HsWrap wrap cmd)) :: arg2 --> res --- | 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 - data CmdTopTc = CmdTopTc Type -- Nested tuple of inputs on the command's stack Type -- return type of the command @@ -1676,73 +826,17 @@ instance (OutputableBndrId p) => Outputable (HsCmdTop (GhcPass p)) where {- ************************************************************************ * * -\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 - type instance XMG GhcPs b = NoExtField type instance XMG GhcRn b = NoExtField type instance XMG GhcTc b = MatchGroupTc type instance XXMatchGroup (GhcPass _) b = NoExtCon --- | 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) - type instance XCMatch (GhcPass _) b = NoExtField type instance XXMatch (GhcPass _) b = NoExtCon @@ -1750,48 +844,6 @@ instance (OutputableBndrId pr, Outputable body) => Outputable (Match (GhcPass pr) body) where ppr = pprMatch -{- -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 - isEmptyMatchGroup :: MatchGroup (GhcPass p) body -> Bool isEmptyMatchGroup (MG { mg_alts = ms }) = null $ unLoc ms @@ -1814,41 +866,12 @@ matchGroupArity (MG { mg_alts = alts }) hsLMatchPats :: LMatch (GhcPass id) body -> [LPat (GhcPass id)] hsLMatchPats (L _ (Match { m_pats = pats })) = pats --- | 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) - type instance XCGRHSs (GhcPass _) b = NoExtField type instance XXGRHSs (GhcPass _) b = NoExtCon --- | 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) - type instance XCGRHS (GhcPass _) b = NoExtField type instance XXGRHS (GhcPass _) b = NoExtCon --- We know the list must have at least one @Match@ in it. - pprMatches :: (OutputableBndrId idR, Outputable body) => MatchGroup (GhcPass idR) body -> SDoc pprMatches MG { mg_alts = matches } @@ -1932,162 +955,6 @@ pp_rhs ctxt rhs = matchSeparator ctxt <+> pprDeeper (ppr rhs) ************************************************************************ -} --- | 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) - -- Extra fields available post typechecking for RecStmt. data RecStmtTc = RecStmtTc @@ -2151,70 +1018,9 @@ type instance XRecStmt (GhcPass _) GhcTc b = RecStmtTc type instance XXStmtLR (GhcPass _) (GhcPass _) b = NoExtCon -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) - type instance XParStmtBlock (GhcPass pL) (GhcPass pR) = NoExtField type instance XXParStmtBlock (GhcPass pL) (GhcPass pR) = NoExtCon --- | 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 GhcRn -- context of the do expression - -- used in pprArg - } - | XApplicativeArg !(XXApplicativeArg idL) - type instance XApplicativeArgOne GhcPs = NoExtField type instance XApplicativeArgOne GhcRn = FailOperator GhcRn type instance XApplicativeArgOne GhcTc = FailOperator GhcTc @@ -2222,170 +1028,7 @@ type instance XApplicativeArgOne GhcTc = FailOperator GhcTc type instance XApplicativeArgMany (GhcPass _) = NoExtField type instance XXApplicativeArg (GhcPass _) = NoExtCon -{- -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. --} +type instance ApplicativeArgStmCtxPass _ = GhcRn instance (Outputable (StmtLR (GhcPass idL) (GhcPass idL) (LHsExpr (GhcPass idL))), Outputable (XXParStmtBlock (GhcPass idL) (GhcPass idR))) @@ -2545,38 +1188,6 @@ pprQuals quals = interpp'SP quals ************************************************************************ -} --- | 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 - newtype HsSplicedT = HsSplicedT DelayedSplice deriving (Data) type instance XTypedSplice (GhcPass _) = NoExtField @@ -2587,36 +1198,6 @@ type instance XXSplice GhcPs = NoExtCon type instance XXSplice GhcRn = NoExtCon type instance XXSplice GhcTc = HsSplicedT --- | 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] - -- See Note [Running typed splices in the zonker] -- These are the arguments that are passed to `GHC.Tc.Gen.Splice.runTopSplice` data DelayedSplice = @@ -2632,29 +1213,10 @@ instance Data DelayedSplice where toConstr a = mkConstr (dataTypeOf a) "DelayedSplice" [] Data.Prefix dataTypeOf a = mkDataType "HsExpr.DelayedSplice" [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 - -- | Pending Renamer Splice data PendingRnSplice = PendingRnSplice UntypedSpliceFlavour SplicePointName (LHsExpr GhcRn) -data UntypedSpliceFlavour - = UntypedExpSplice - | UntypedPatSplice - | UntypedTypeSplice - | UntypedDeclSplice - deriving Data - -- | Pending Type-checker Splice data PendingTcSplice = PendingTcSplice SplicePointName (LHsExpr GhcTc) @@ -2776,18 +1338,6 @@ ppr_splice :: (OutputableBndrId p) ppr_splice herald n e trail = herald <> whenPprDebug (brackets (ppr n)) <> ppr e <> trail --- | 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 - type instance XExpBr (GhcPass _) = NoExtField type instance XPatBr (GhcPass _) = NoExtField type instance XDecBrL (GhcPass _) = NoExtField @@ -2797,10 +1347,6 @@ type instance XVarBr (GhcPass _) = NoExtField type instance XTExpBr (GhcPass _) = NoExtField type instance XXBracket (GhcPass _) = NoExtCon -isTypedBracket :: HsBracket id -> Bool -isTypedBracket (TExpBr {}) = True -isTypedBracket _ = False - instance OutputableBndrId p => Outputable (HsBracket (GhcPass p)) where ppr = pprHsBracket @@ -2839,18 +1385,6 @@ instance Outputable PendingTcSplice where ************************************************************************ -} --- | 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? - instance OutputableBndrId p => Outputable (ArithSeqInfo (GhcPass p)) where ppr (From e1) = hcat [ppr e1, pp_dotdot] @@ -2870,38 +1404,6 @@ pp_dotdot = text " .. " ************************************************************************ -} --- | 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 - instance OutputableBndrId p => Outputable (HsMatchContext (GhcPass p)) where ppr m@(FunRhs{}) = text "FunRhs" <+> ppr (mc_fun m) <+> ppr (mc_fixity m) ppr LambdaExpr = text "LambdaExpr" @@ -2916,134 +1418,7 @@ instance OutputableBndrId p => Outputable (HsMatchContext (GhcPass p)) where ppr ThPatQuote = text "ThPatQuote" ppr PatSyn = text "PatSyn" -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 instance OutputableBndrId p => Outputable (HsStmtContext (GhcPass p)) where diff --git a/compiler/GHC/Hs/Expr.hs-boot b/compiler/GHC/Hs/Expr.hs-boot index 7bd7753c56..3eb1894e70 100644 --- a/compiler/GHC/Hs/Expr.hs-boot +++ b/compiler/GHC/Hs/Expr.hs-boot @@ -1,38 +1,28 @@ -{-# LANGUAGE CPP, KindSignatures #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] - -- in module GHC.Hs.Extension -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE RoleAnnotations #-} -{-# LANGUAGE ExistentialQuantification #-} -{-# LANGUAGE TypeFamilies #-} + -- in module Language.Haskell.Syntax.Extension + +{-# OPTIONS_GHC -Wno-orphans #-} module GHC.Hs.Expr where import GHC.Utils.Outputable ( SDoc, Outputable ) -import {-# SOURCE #-} GHC.Hs.Pat ( LPat ) -import GHC.Types.Basic ( SpliceExplicitFlag(..)) -import GHC.Hs.Extension ( OutputableBndrId, GhcPass, XRec ) -import Data.Kind ( Type ) - -type role HsExpr nominal -type role HsCmd nominal -type role MatchGroup nominal nominal -type role GRHSs nominal nominal -type role HsSplice nominal -data HsExpr (i :: Type) -data HsCmd (i :: Type) -data HsSplice (i :: Type) -data MatchGroup (a :: Type) (body :: Type) -data GRHSs (a :: Type) (body :: Type) -type family SyntaxExpr (i :: Type) +import Language.Haskell.Syntax.Pat ( LPat ) +import {-# SOURCE #-} GHC.Hs.Pat () -- for Outputable +import GHC.Types.Basic ( SpliceExplicitFlag(..)) +import Language.Haskell.Syntax.Expr + ( HsExpr, LHsExpr + , HsCmd + , MatchGroup + , GRHSs + , HsSplice + ) +import GHC.Hs.Extension ( OutputableBndrId, GhcPass ) instance OutputableBndrId p => Outputable (HsExpr (GhcPass p)) instance OutputableBndrId p => Outputable (HsCmd (GhcPass p)) -type LHsExpr a = XRec a (HsExpr a) - pprLExpr :: (OutputableBndrId p) => LHsExpr (GhcPass p) -> SDoc pprExpr :: (OutputableBndrId p) => HsExpr (GhcPass p) -> SDoc diff --git a/compiler/GHC/Hs/Extension.hs b/compiler/GHC/Hs/Extension.hs index 3e9bac5442..ac79d83d0b 100644 --- a/compiler/GHC/Hs/Extension.hs +++ b/compiler/GHC/Hs/Extension.hs @@ -14,7 +14,7 @@ {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE UndecidableSuperClasses #-} -- for IsPass; see Note [NoGhcTc] {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] - -- in module GHC.Hs.Extension + -- in module Language.Haskell.Syntax.Extension module GHC.Hs.Extension where @@ -24,6 +24,7 @@ module GHC.Hs.Extension where import GHC.Prelude import Data.Data hiding ( Fixity ) +import Language.Haskell.Syntax.Extension import GHC.Types.Name import GHC.Types.Name.Reader import GHC.Types.Var @@ -31,40 +32,7 @@ import GHC.Utils.Outputable import GHC.Types.SrcLoc (Located, unLoc, noLoc) import GHC.Utils.Panic -import Data.Kind - {- -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]. - Note [IsPass] ~~~~~~~~~~~~~ One challenge with the Trees That Grow approach @@ -126,91 +94,8 @@ saying that NoGhcTcPass is idempotent. -} --- | 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 - type instance XRec (GhcPass p) a = Located 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 --- @noLoc@ for @GhcPass p@ --- See Note [XRec and SrcSpans in the AST] -class WrapXRec p where - wrapXRec :: a -> XRec p a - instance UnXRec (GhcPass p) where unXRec = unLoc instance MapXRec (GhcPass p) where @@ -293,8 +178,6 @@ instance IsPass 'Renamed where instance IsPass 'Typechecked where ghcPass = GhcTc --- | Maps the "normal" id type for a given pass -type family IdP p type instance IdP (GhcPass p) = IdGhcP p -- | Maps the "normal" id type for a given GHC pass @@ -303,530 +186,18 @@ type family IdGhcP pass where IdGhcP 'Renamed = Name IdGhcP 'Typechecked = Id -type LIdP p = XRec p (IdP p) - -- | Marks that a field uses the GhcRn variant even when the pass -- parameter is GhcTc. Useful for storing HsTypes in GHC.Hs.Exprs, say, because -- HsType GhcTc should never occur. -- See Note [NoGhcTc] -type family NoGhcTc (p :: Type) where - -- this way, GHC can figure out that the result is a GhcPass - NoGhcTc (GhcPass pass) = GhcPass (NoGhcTcPass pass) - NoGhcTc other = other + +-- Breaking it up this way, GHC can figure out that the result is a GhcPass +type instance NoGhcTc (GhcPass pass) = GhcPass (NoGhcTcPass pass) type family NoGhcTcPass (p :: Pass) :: Pass where NoGhcTcPass 'Typechecked = 'Renamed NoGhcTcPass other = other --- ===================================================================== --- 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 - --- ------------------------------------- - - --- ===================================================================== --- End of Type family definitions --- ===================================================================== - -- |Constraint type to bundle up the requirement for 'OutputableBndr' on both -- the @id@ and the 'NoGhcTc' of it. See Note [NoGhcTc]. type OutputableBndrId pass = diff --git a/compiler/GHC/Hs/ImpExp.hs b/compiler/GHC/Hs/ImpExp.hs index 33c32aa7f7..f290c458b2 100644 --- a/compiler/GHC/Hs/ImpExp.hs +++ b/compiler/GHC/Hs/ImpExp.hs @@ -5,7 +5,7 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] - -- in module GHC.Hs.Extension + -- in module Language.Haskell.Syntax.Extension {- (c) The University of Glasgow 2006 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 @@ -28,6 +28,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Data.FastString import GHC.Types.SrcLoc +import Language.Haskell.Syntax.Extension import GHC.Hs.Extension import Data.Data diff --git a/compiler/GHC/Hs/Lit.hs b/compiler/GHC/Hs/Lit.hs index 75ea3ef469..9aaadba24f 100644 --- a/compiler/GHC/Hs/Lit.hs +++ b/compiler/GHC/Hs/Lit.hs @@ -5,7 +5,9 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] - -- in module GHC.Hs.Extension + -- in module Language.Haskell.Syntax.Extension + +{-# OPTIONS_GHC -Wno-orphans #-} -- Outputable, OutputableBndrId {- (c) The University of Glasgow 2006 @@ -14,22 +16,25 @@ -} -- | Source-language literals -module GHC.Hs.Lit where +module GHC.Hs.Lit + ( module Language.Haskell.Syntax.Lit + , module GHC.Hs.Lit + ) where #include "HsVersions.h" import GHC.Prelude -import {-# SOURCE #-} GHC.Hs.Expr( HsExpr, pprExpr ) -import GHC.Types.Basic (PprPrec(..), topPrec ) +import {-# SOURCE #-} GHC.Hs.Expr( pprExpr ) + +import Language.Haskell.Syntax.Lit + 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 GHC.Hs.Extension -import Data.ByteString (ByteString) import Data.Data hiding ( Fixity ) {- @@ -40,45 +45,6 @@ import Data.Data hiding ( Fixity ) ************************************************************************ -} --- Note [Literal source text] in GHC.Types.Basic for SourceText fields in --- the following --- Note [Trees that grow] in GHC.Hs.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) - type instance XHsChar (GhcPass _) = SourceText type instance XHsCharPrim (GhcPass _) = SourceText type instance XHsString (GhcPass _) = SourceText @@ -94,32 +60,6 @@ type instance XHsFloatPrim (GhcPass _) = NoExtField type instance XHsDoublePrim (GhcPass _) = NoExtField type instance XXLit (GhcPass _) = NoExtCon -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) - data OverLitTc = OverLitTc { ol_rebindable :: Bool, -- Note [ol_rebindable] @@ -132,20 +72,6 @@ type instance XOverLit GhcTc = OverLitTc type instance XXOverLit (GhcPass _) = NoExtCon --- 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" - overLitType :: HsOverLit GhcTc -> Type overLitType (OverLit (OverLitTc _ ty) _ _) = ty @@ -178,52 +104,8 @@ Equivalently it's True if a) RebindableSyntax is on b) the witness for fromInteger/fromRational/fromString that happens to be in scope isn't the standard one - -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 specific to GhcPs, need the SourceText instance Outputable (HsLit (GhcPass p)) where ppr (HsChar st c) = pprWithSourceText st (pprHsChar c) @@ -251,11 +133,6 @@ instance OutputableBndrId p ppr (OverLit {ol_val=val, ol_witness=witness}) = ppr val <+> (whenPprDebug (parens (pprExpr witness))) -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) - -- | pmPprHsLit pretty prints literals and is used when pretty printing pattern -- match warnings. All are printed the same (i.e., without hashes if they are -- primitive and not wrapped in constructors if they are boxed). This happens @@ -276,34 +153,3 @@ pmPprHsLit (HsInteger _ i _) = integer i pmPprHsLit (HsRat _ f _) = ppr f pmPprHsLit (HsFloatPrim _ f) = ppr f pmPprHsLit (HsDoublePrim _ d) = ppr d - --- | @'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/GHC/Hs/Pat.hs b/compiler/GHC/Hs/Pat.hs index cf23cb4a1c..7f9cecda1b 100644 --- a/compiler/GHC/Hs/Pat.hs +++ b/compiler/GHC/Hs/Pat.hs @@ -10,8 +10,11 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] - -- in module GHC.Hs.Extension + -- in module Language.Haskell.Syntax.Extension {-# LANGUAGE ViewPatterns #-} + +{-# OPTIONS_GHC -Wno-orphans #-} -- Outputable + {- (c) The University of Glasgow 2006 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 @@ -48,11 +51,15 @@ module GHC.Hs.Pat ( import GHC.Prelude -import {-# SOURCE #-} GHC.Hs.Expr (SyntaxExpr, LHsExpr, HsSplice, pprLExpr, pprSplice) +import Language.Haskell.Syntax.Pat +import Language.Haskell.Syntax.Expr (SyntaxExpr) + +import {-# SOURCE #-} GHC.Hs.Expr (pprLExpr, pprSplice) -- friends: import GHC.Hs.Binds import GHC.Hs.Lit +import Language.Haskell.Syntax.Extension import GHC.Hs.Extension import GHC.Hs.Type import GHC.Tc.Types.Evidence @@ -72,182 +79,7 @@ import GHC.Types.SrcLoc import GHC.Data.Bag -- collect ev vars from pats import GHC.Data.Maybe import GHC.Types.Name (Name) --- 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) - --- --------------------------------------------------------------------- data ListPatTc = ListPatTc @@ -307,23 +139,12 @@ type instance XXPat GhcRn = NoExtCon type instance XXPat GhcTc = CoPat -- After typechecking, we add one extra constructor: CoPat -type family ConLikeP x - type instance ConLikeP GhcPs = RdrName -- IdP GhcPs type instance ConLikeP GhcRn = Name -- IdP GhcRn type instance ConLikeP GhcTc = ConLike -- --------------------------------------------------------------------- - --- | 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] - -- | This is the extension field for ConPat, added after typechecking -- It adds quite a few extra fields, to support elaboration of pattern matching. data ConPatTc @@ -370,123 +191,6 @@ data CoPat co_pat_ty :: Type } --- | 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 - hsRecFieldId :: HsRecField GhcTc arg -> Located Id hsRecFieldId = hsRecFieldSel @@ -623,22 +327,6 @@ pprConArgs (InfixCon p1 p2) = sep [ pprParendLPat appPrec p1 , pprParendLPat appPrec p2 ] pprConArgs (RecCon rpats) = ppr rpats -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/GHC/Hs/Pat.hs-boot b/compiler/GHC/Hs/Pat.hs-boot index e0849375b9..be8bcdf72f 100644 --- a/compiler/GHC/Hs/Pat.hs-boot +++ b/compiler/GHC/Hs/Pat.hs-boot @@ -1,20 +1,15 @@ -{-# LANGUAGE CPP, KindSignatures #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] - -- in module GHC.Hs.Extension -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE RoleAnnotations #-} -{-# LANGUAGE TypeFamilies #-} + -- in module Language.Haskell.Syntax.Extension + +{-# OPTIONS_GHC -Wno-orphans #-} -- Outputable module GHC.Hs.Pat where import GHC.Utils.Outputable -import GHC.Hs.Extension ( OutputableBndrId, GhcPass, XRec ) -import Data.Kind +import GHC.Hs.Extension ( OutputableBndrId, GhcPass ) -type role Pat nominal -data Pat (i :: Type) -type LPat i = XRec i (Pat i) +import Language.Haskell.Syntax.Pat instance OutputableBndrId p => Outputable (Pat (GhcPass p)) diff --git a/compiler/GHC/Hs/Type.hs b/compiler/GHC/Hs/Type.hs index eafe4daa70..d5560411e4 100644 --- a/compiler/GHC/Hs/Type.hs +++ b/compiler/GHC/Hs/Type.hs @@ -9,7 +9,10 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] - -- in module GHC.Hs.Extension + -- in module Language.Haskell.Syntax.Extension + +{-# OPTIONS_GHC -Wno-orphans #-} -- NamedThing, Outputable, OutputableBndrId + {- (c) The University of Glasgow 2006 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 @@ -87,8 +90,11 @@ module GHC.Hs.Type ( import GHC.Prelude -import {-# SOURCE #-} GHC.Hs.Expr ( HsSplice, pprSplice ) +import Language.Haskell.Syntax.Type +import {-# SOURCE #-} GHC.Hs.Expr ( pprSplice ) + +import Language.Haskell.Syntax.Extension import GHC.Hs.Extension import GHC.Types.Id ( Id ) @@ -96,8 +102,6 @@ import GHC.Types.SourceText import GHC.Types.Name( Name, NamedThing(getName) ) import GHC.Types.Name.Reader ( RdrName ) import GHC.Types.Var ( VarBndr ) -import GHC.Core.DataCon( HsSrcBang(..), HsImplBang(..), - SrcStrictness(..), SrcUnpackedness(..) ) import GHC.Core.TyCo.Rep ( Type(..) ) import GHC.Builtin.Types( manyDataConName, oneDataConName, mkTupleStr ) import GHC.Core.Type @@ -105,13 +109,9 @@ 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.Maybe -import Data.Void {- ************************************************************************ @@ -121,17 +121,6 @@ import Data.Void ************************************************************************ -} --- | 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 - getBangType :: LHsType (GhcPass p) -> LHsType (GhcPass p) getBangType (L _ (HsBangTy _ _ lty)) = lty getBangType (L _ (HsDocTy x (L _ (HsBangTy _ _ lty)) lds)) = @@ -149,181 +138,8 @@ getBangStrictness _ = (HsSrcBang NoSourceText NoSrcUnpack NoSrcStrict) \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 - noLHsContext :: LHsContext (GhcPass p) -- Use this when there is no context in the original program -- It would really be more kosher to use a Maybe, to distinguish @@ -332,64 +148,11 @@ noLHsContext :: LHsContext (GhcPass p) -- class C a where ... noLHsContext = noLoc [] --- | 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) - type instance XHsForAllVis (GhcPass _) = NoExtField type instance XHsForAllInvis (GhcPass _) = NoExtField type instance XXHsForAllTelescope (GhcPass _) = NoExtCon --- | 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) - type HsQTvsRn = [Name] -- Implicit variables -- For example, in data T (a :: k1 -> k2) = ... -- the 'a' is explicit while 'k1', 'k2' are implicit @@ -413,68 +176,11 @@ mkHsForAllInvisTele invis_bndrs = mkHsQTvs :: [LHsTyVarBndr () GhcPs] -> LHsQTyVars GhcPs mkHsQTvs tvs = HsQTvs { hsq_ext = noExtField, hsq_explicit = tvs } -hsQTvExplicit :: LHsQTyVars pass -> [LHsTyVarBndr () pass] -hsQTvExplicit = hsq_explicit - emptyLHsQTvs :: LHsQTyVars GhcRn emptyLHsQTvs = HsQTvs { hsq_ext = [], 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 () type instance XHsOuterImplicit GhcPs = NoExtField type instance XHsOuterImplicit GhcRn = [Name] @@ -486,297 +192,28 @@ type instance XHsOuterExplicit GhcTc flag = [VarBndr TyVar flag] type instance XXHsOuterTyVarBndrs (GhcPass _) = NoExtCon --- | 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) - type instance XHsWC GhcPs b = NoExtField type instance XHsWC GhcRn b = [Name] type instance XHsWC GhcTc b = [Name] type instance XXHsWildCardBndrs (GhcPass _) _ = NoExtCon --- | 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 - type instance XHsPS GhcPs = NoExtField type instance XHsPS GhcRn = HsPSRn type instance XHsPS GhcTc = HsPSRn type instance XXHsPatSigType (GhcPass _) = NoExtCon --- | 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) - type instance XHsSig (GhcPass _) = NoExtField type instance XXHsSigType (GhcPass _) = NoExtCon hsSigWcType :: LHsSigWcType pass -> LHsType pass hsSigWcType = sig_body . unLoc . hswc_body -hsPatSigType :: HsPatSigType pass -> LHsType pass -hsPatSigType = hsps_body - dropWildCards :: LHsSigWcType pass -> LHsSigType pass -- Drop the wildcard part of a LHsSigWcType dropWildCards sig_ty = hswc_body sig_ty -{- -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. --} - hsOuterTyVarNames :: HsOuterTyVarBndrs flag GhcRn -> [Name] hsOuterTyVarNames (HsOuterImplicit{hso_ximplicit = imp_tvs}) = imp_tvs hsOuterTyVarNames (HsOuterExplicit{hso_bndrs = bndrs}) = hsLTyVarNames bndrs @@ -786,14 +223,6 @@ hsOuterExplicitBndrs :: HsOuterTyVarBndrs flag (GhcPass p) hsOuterExplicitBndrs (HsOuterExplicit{hso_bndrs = bndrs}) = bndrs hsOuterExplicitBndrs (HsOuterImplicit{}) = [] -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 - mkHsOuterImplicit :: HsOuterTyVarBndrs flag GhcPs mkHsOuterImplicit = HsOuterImplicit{hso_ximplicit = noExtField} @@ -824,51 +253,8 @@ mkEmptyWildCardBndrs :: thing -> HsWildCardBndrs GhcRn thing mkEmptyWildCardBndrs x = HsWC { hswc_body = x , hswc_ext = [] } - --------------------------------------------------- --- | 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) - type instance XUserTyVar (GhcPass _) = NoExtField type instance XKindedTyVar (GhcPass _) = NoExtField @@ -885,12 +271,6 @@ setHsTyVarBndrFlag :: flag -> HsTyVarBndr flag' (GhcPass pass) setHsTyVarBndrFlag f (UserTyVar x _ l) = UserTyVar x f l setHsTyVarBndrFlag f (KindedTyVar x _ l k) = KindedTyVar x f l k --- | Does this 'HsTyVarBndr' come with an explicit kind annotation? -isHsKindedTyVar :: HsTyVarBndr flag pass -> Bool -isHsKindedTyVar (UserTyVar {}) = False -isHsKindedTyVar (KindedTyVar {}) = True -isHsKindedTyVar (XTyVarBndr {}) = False - -- | Do all type variables in this 'LHsQTyVars' come with kind annotations? hsTvbAllKinded :: LHsQTyVars (GhcPass p) -> Bool hsTvbAllKinded = all (isHsKindedTyVar . unLoc) . hsQTvExplicit @@ -899,187 +279,6 @@ instance NamedThing (HsTyVarBndr flag GhcRn) where getName (UserTyVar _ _ v) = unLoc v getName (KindedTyVar _ _ v _) = unLoc v --- | 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 - type instance XForAllTy (GhcPass _) = NoExtField type instance XQualTy (GhcPass _) = NoExtField type instance XTyVar (GhcPass _) = NoExtField @@ -1119,14 +318,6 @@ type instance XWildCardTy (GhcPass _) = NoExtField type instance XXType (GhcPass _) = HsCoreTy --- 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 - oneDataConHsTy :: HsType GhcRn oneDataConHsTy = HsTyVar noExtField NotPromoted (noLoc oneDataConName) @@ -1137,18 +328,6 @@ isUnrestricted :: HsArrow GhcRn -> Bool isUnrestricted (arrowToHsType -> L _ (HsTyVar _ _ (L _ n))) = n == manyDataConName isUnrestricted _ = False --- | 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. - -- | Convert an arrow into its corresponding multiplicity. In essence this -- erases the information of whether the programmer wrote an explicit -- multiplicity or a shorthand. @@ -1157,26 +336,6 @@ arrowToHsType (HsUnrestrictedArrow _) = noLoc manyDataConHsTy arrowToHsType (HsLinearArrow _) = noLoc oneDataConHsTy arrowToHsType (HsExplicitMult _ p) = p --- | 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 - instance (OutputableBndrId pass) => Outputable (HsArrow (GhcPass pass)) where @@ -1188,120 +347,6 @@ pprHsArrow (HsUnrestrictedArrow _) = arrow pprHsArrow (HsLinearArrow _) = lollipop pprHsArrow (HsExplicitMult _ p) = (mulArrow (ppr p)) -{- -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) - type instance XConDeclField (GhcPass _) = NoExtField type instance XXConDeclField (GhcPass _) = NoExtCon @@ -1309,63 +354,6 @@ instance OutputableBndrId p => Outputable (ConDeclField (GhcPass p)) where ppr (ConDeclField _ fld_n fld_ty _) = ppr fld_n <+> dcolon <+> ppr fld_ty --- | 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 - --------------------- hsWcScopedTvs :: LHsSigWcType GhcRn -> [Name] -- Get the lexically-scoped type variables of an LHsSigWcType: @@ -1385,81 +373,6 @@ hsScopedTvs (L _ (HsSig{sig_bndrs = outer_bndrs})) = hsLTyVarNames (hsOuterExplicitBndrs outer_bndrs) -- See Note [hsScopedTvs and visible foralls] -{- 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'. --} - --------------------- hsTyVarName :: HsTyVarBndr flag (GhcPass p) -> IdP (GhcPass p) hsTyVarName (UserTyVar _ _ (L _ n)) = n @@ -1582,20 +495,6 @@ hsTyGetAppHead_maybe = go go _ = Nothing ------------------------------------------------------------ --- 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) -- | Compute the 'SrcSpan' associated with an 'LHsTypeArg'. lhsTypeArgSrcSpan :: LHsTypeArg (GhcPass pass) -> SrcSpan @@ -1604,24 +503,6 @@ lhsTypeArgSrcSpan arg = case arg of HsTypeArg at ty -> at `combineSrcSpans` getLoc ty HsArgPar sp -> sp -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] - --} - -------------------------------- -- | Decompose a pattern synonym type signature into its constituent parts. @@ -1893,57 +774,16 @@ also forbids them in types involved with `deriving`: ************************************************************************ -} --- | 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 (GhcPass p)) => Eq (FieldOcc (GhcPass p)) - type instance XCFieldOcc GhcPs = NoExtField type instance XCFieldOcc GhcRn = Name type instance XCFieldOcc GhcTc = Id type instance XXFieldOcc (GhcPass _) = NoExtCon -instance Outputable (FieldOcc pass) where - ppr = ppr . rdrNameFieldOcc - mkFieldOcc :: Located RdrName -> FieldOcc GhcPs mkFieldOcc rdr = FieldOcc noExtField rdr --- | 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) - type instance XUnambiguous GhcPs = NoExtField type instance XUnambiguous GhcRn = Name type instance XUnambiguous GhcTc = Id @@ -2007,9 +847,6 @@ instance OutputableBndrId p => Outputable (HsSigType (GhcPass p)) where instance OutputableBndrId p => Outputable (HsType (GhcPass p)) where ppr ty = pprHsType ty -instance Outputable HsTyLit where - ppr = ppr_tylit - instance OutputableBndrId p => Outputable (LHsQTyVars (GhcPass p)) where ppr (HsQTvs { hsq_explicit = tvs }) = interppSP tvs @@ -2169,7 +1006,7 @@ ppr_mono_ty (HsExplicitTupleTy _ tys) = quote $ sep [text (mkTupleStr Boxed 1), ppr_mono_lty ty] | otherwise = quote $ parens (maybeAddSpace tys $ interpp'SP tys) -ppr_mono_ty (HsTyLit _ t) = ppr_tylit t +ppr_mono_ty (HsTyLit _ t) = ppr t ppr_mono_ty (HsWildCardTy {}) = char '_' ppr_mono_ty (HsStarTy _ isUni) = char (if isUni then '★' else '*') @@ -2207,11 +1044,6 @@ ppr_fun_ty mult ty1 ty2 sep [p1, arr <+> p2] -------------------------- -ppr_tylit :: HsTyLit -> SDoc -ppr_tylit (HsNumTy source i) = pprWithSourceText source (integer i) -ppr_tylit (HsStrTy source s) = pprWithSourceText source (text (show s)) - - -- | @'hsTypeNeedsParens' p t@ returns 'True' if the type @t@ needs parentheses -- under precedence @p@. hsTypeNeedsParens :: PprPrec -> HsType (GhcPass p) -> Bool diff --git a/compiler/GHC/Hs/Utils.hs b/compiler/GHC/Hs/Utils.hs index e538549265..39ce2c19bd 100644 --- a/compiler/GHC/Hs/Utils.hs +++ b/compiler/GHC/Hs/Utils.hs @@ -116,6 +116,7 @@ import GHC.Hs.Expr import GHC.Hs.Pat import GHC.Hs.Type import GHC.Hs.Lit +import Language.Haskell.Syntax.Extension import GHC.Hs.Extension import GHC.Tc.Types.Evidence |