summaryrefslogtreecommitdiff
path: root/compiler/hsSyn/HsBinds.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/hsSyn/HsBinds.hs')
-rw-r--r--compiler/hsSyn/HsBinds.hs518
1 files changed, 308 insertions, 210 deletions
diff --git a/compiler/hsSyn/HsBinds.hs b/compiler/hsSyn/HsBinds.hs
index f08a6af700..98f503b0d9 100644
--- a/compiler/hsSyn/HsBinds.hs
+++ b/compiler/hsSyn/HsBinds.hs
@@ -14,9 +14,12 @@ Datatype for: @BindGroup@, @Bind@, @Sig@, @Bind@.
-- in module PlaceHolder
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE TypeFamilies #-}
module HsBinds where
+import GhcPrelude
+
import {-# SOURCE #-} HsExpr ( pprExpr, LHsExpr,
MatchGroup, pprFunBind,
GRHSs, pprPatBind )
@@ -54,7 +57,7 @@ Global bindings (where clauses)
-}
-- During renaming, we need bindings where the left-hand sides
--- have been renamed but the the right-hand sides have not.
+-- 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.
@@ -70,23 +73,34 @@ type LHsLocalBinds id = Located (HsLocalBinds id)
-- Bindings in a 'let' expression
-- or a 'where' clause
data HsLocalBindsLR idL idR
- = HsValBinds (HsValBindsLR 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 the
+ -- The parser accepts them, however, leaving the
-- renamer to report them
- | HsIPBinds (HsIPBinds idR)
+ | HsIPBinds
+ (XHsIPBinds idL idR)
+ (HsIPBinds idR)
-- ^ Haskell Implicit Parameter Bindings
- | EmptyLocalBinds
+ | EmptyLocalBinds (XEmptyLocalBinds idL idR)
-- ^ Empty Local Bindings
+ | XHsLocalBindsLR
+ (XXHsLocalBindsLR idL idR)
+
+type instance XHsValBinds (GhcPass pL) (GhcPass pR) = NoExt
+type instance XHsIPBinds (GhcPass pL) (GhcPass pR) = NoExt
+type instance XEmptyLocalBinds (GhcPass pL) (GhcPass pR) = NoExt
+type instance XXHsLocalBindsLR (GhcPass pL) (GhcPass pR) = NoExt
+
type LHsLocalBindsLR idL idR = Located (HsLocalBindsLR idL idR)
-deriving instance (DataId idL, DataId idR) => Data (HsLocalBindsLR idL idR)
-- | Haskell Value Bindings
type HsValBinds id = HsValBindsLR id id
@@ -101,18 +115,31 @@ data HsValBindsLR idL idR
-- Before renaming RHS; idR is always RdrName
-- Not dependency analysed
-- Recursive by default
- ValBindsIn
+ 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.
- | ValBindsOut
- [(RecFlag, LHsBinds idL)]
- [LSig GhcRn] -- AZ: how to do this?
+ | XValBindsLR
+ (XXValBindsLR idL idR)
+
+-- ---------------------------------------------------------------------
+-- Deal with ValBindsOut
+
+-- TODO: make this the only type for ValBinds
+data NHsValBindsLR idL
+ = NValBinds
+ [(RecFlag, LHsBinds idL)]
+ [LSig GhcRn]
-deriving instance (DataId idL, DataId idR) => Data (HsValBindsLR idL idR)
+type instance XValBinds (GhcPass pL) (GhcPass pR) = NoExt
+type instance XXValBindsLR (GhcPass pL) (GhcPass pR)
+ = NHsValBindsLR (GhcPass pL)
+
+-- ---------------------------------------------------------------------
-- | Located Haskell Binding
type LHsBind id = LHsBindLR id id
@@ -129,9 +156,8 @@ type LHsBindsLR idL idR = Bag (LHsBindLR idL idR)
-- | Located Haskell Binding with separate Left and Right identifier types
type LHsBindLR idL idR = Located (HsBindLR idL idR)
-{- Note [Varieties of binding pattern matches]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+{- 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.
@@ -142,12 +168,17 @@ patterns which resemble function bindings and simple variable bindings.
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 Match will be FunRhs and carries two bits of information
-about the match,
+The m_ctxt field of each Match in fun_matches will be FunRhs and carries
+two bits of information about the match,
- * the mc_strictness field describes whether the match is decorated with a bang
- (e.g. `!x = e`)
- * the mc_fixity field describes the fixity of the function binder
+ * 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,
@@ -175,7 +206,7 @@ data HsBindLR idL idR
-- @(f :: a -> a) = ... @
--
-- Strict bindings have their strictness recorded in the 'SrcStrictness' of their
- -- 'MatchContext'. See Note [Varieties of binding pattern matches] for
+ -- 'MatchContext'. See Note [FunBind vs PatBind] for
-- details about the relationship between FunBind and PatBind.
--
-- 'ApiAnnotation.AnnKeywordId's
@@ -188,6 +219,11 @@ data HsBindLR idL idR
-- For details on above see note [Api annotations] in ApiAnnotation
FunBind {
+ fun_ext :: XFunBind idL idR, -- ^ After the renamer, this contains
+ -- the locally-bound
+ -- free variables of this defn.
+ -- See Note [Bind free vars]
+
fun_id :: Located (IdP idL), -- Note [fun_id in Match] in HsExpr
fun_matches :: MatchGroup idR (LHsExpr idR), -- ^ The payload
@@ -206,12 +242,6 @@ data HsBindLR idL idR
-- type Int -> forall a'. a' -> a'
-- Notice that the coercion captures the free a'.
- bind_fvs :: PostRn idL NameSet, -- ^ After the renamer, this contains
- -- the locally-bound
- -- free variables of this defn.
- -- See Note [Bind free vars]
-
-
fun_tick :: [Tickish Id] -- ^ Ticks to put on the rhs, if any
}
@@ -219,7 +249,7 @@ data HsBindLR idL idR
--
-- The pattern is never a simple variable;
-- That case is done by FunBind.
- -- See Note [Varieties of binding pattern matches] for details about the
+ -- See Note [FunBind vs PatBind] for details about the
-- relationship between FunBind and PatBind.
--
@@ -229,10 +259,9 @@ data HsBindLR idL idR
-- For details on above see note [Api annotations] in ApiAnnotation
| PatBind {
+ pat_ext :: XPatBind idL idR, -- ^ See Note [Bind free vars]
pat_lhs :: LPat idL,
pat_rhs :: GRHSs idR (LHsExpr idR),
- pat_rhs_ty :: PostTc idR Type, -- ^ Type of the GRHSs
- bind_fvs :: PostRn idL NameSet, -- ^ See Note [Bind free vars]
pat_ticks :: ([Tickish Id], [[Tickish Id]])
-- ^ Ticks to put on the rhs, if any, and ticks to put on
-- the bound variables.
@@ -243,6 +272,7 @@ data HsBindLR idL idR
-- 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
var_inline :: Bool -- ^ True <=> inline this binding regardless
@@ -251,6 +281,7 @@ data HsBindLR idL idR
-- | Abstraction Bindings
| AbsBinds { -- Binds abstraction; TRANSLATION
+ abs_ext :: XAbsBinds idL idR,
abs_tvs :: [TyVar],
abs_ev_vars :: [EvVar], -- ^ Includes equality constraints
@@ -265,26 +296,15 @@ data HsBindLR idL idR
abs_ev_binds :: [TcEvBinds],
-- | Typechecked user bindings
- abs_binds :: LHsBinds idL
- }
+ abs_binds :: LHsBinds idL,
- -- | Abstraction Bindings Signature
- | AbsBindsSig { -- Simpler form of AbsBinds, used with a type sig
- -- in tcPolyCheck. Produces simpler desugaring and
- -- is necessary to avoid #11405, comment:3.
- abs_tvs :: [TyVar],
- abs_ev_vars :: [EvVar],
-
- abs_sig_export :: IdP idL, -- like abe_poly
- abs_sig_prags :: TcSpecPrags,
-
- abs_sig_ev_bind :: TcEvBinds, -- no list needed here
- abs_sig_bind :: LHsBind idL -- always only one, and it's always a
- -- FunBind
+ abs_sig :: Bool -- See Note [The abs_sig field of AbsBinds]
}
-- | Patterns Synonym Binding
- | PatSynBind (PatSynBind idL idR)
+ | PatSynBind
+ (XPatSynBind idL idR)
+ (PatSynBind idL idR)
-- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnPattern',
-- 'ApiAnnotation.AnnLarrow','ApiAnnotation.AnnEqual',
-- 'ApiAnnotation.AnnWhere'
@@ -292,7 +312,26 @@ data HsBindLR idL idR
-- For details on above see note [Api annotations] in ApiAnnotation
-deriving instance (DataId idL, DataId idR) => Data (HsBindLR idL idR)
+ | XHsBindsLR (XXHsBindsLR idL idR)
+
+data NPatBindTc = NPatBindTc {
+ pat_fvs :: NameSet, -- ^ Free variables
+ pat_rhs_ty :: Type -- ^ Type of the GRHSs
+ } deriving Data
+
+type instance XFunBind (GhcPass pL) GhcPs = NoExt
+type instance XFunBind (GhcPass pL) GhcRn = NameSet -- Free variables
+type instance XFunBind (GhcPass pL) GhcTc = NameSet -- Free variables
+
+type instance XPatBind GhcPs (GhcPass pR) = NoExt
+type instance XPatBind GhcRn (GhcPass pR) = NameSet -- Free variables
+type instance XPatBind GhcTc (GhcPass pR) = NPatBindTc
+
+type instance XVarBind (GhcPass pL) (GhcPass pR) = NoExt
+type instance XAbsBinds (GhcPass pL) (GhcPass pR) = NoExt
+type instance XPatSynBind (GhcPass pL) (GhcPass pR) = NoExt
+type instance XXHsBindsLR (GhcPass pL) (GhcPass pR) = NoExt
+
-- Consider (AbsBinds tvs ds [(ftvs, poly_f, mono_f) binds]
--
@@ -308,13 +347,18 @@ deriving instance (DataId idL, DataId idR) => Data (HsBindLR idL idR)
-- | Abtraction Bindings Export
data ABExport p
- = ABE { abe_poly :: IdP p -- ^ Any INLINE pragmas is attached to this Id
+ = 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
- }
-deriving instance (DataId p) => Data (ABExport p)
+ }
+ | XABExport (XXABExport p)
+
+type instance XABE (GhcPass p) = NoExt
+type instance XXABExport (GhcPass p) = NoExt
+
-- | - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnPattern',
-- 'ApiAnnotation.AnnEqual','ApiAnnotation.AnnLarrow'
@@ -325,14 +369,21 @@ deriving instance (DataId p) => Data (ABExport p)
-- | Pattern Synonym binding
data PatSynBind idL idR
- = PSB { psb_id :: Located (IdP idL), -- ^ Name of the pattern synonym
- psb_fvs :: PostRn idR NameSet, -- ^ See Note [Bind free vars]
+ = PSB { psb_ext :: XPSB idL idR, -- ^ Post renaming, FVs.
+ -- See Note [Bind free vars]
+ psb_id :: Located (IdP idL), -- ^ Name of the pattern synonym
psb_args :: HsPatSynDetails (Located (IdP idR)),
-- ^ Formal parameter names
psb_def :: LPat idR, -- ^ Right-hand side
psb_dir :: HsPatSynDir idR -- ^ Directionality
- }
-deriving instance (DataId idL, DataId idR) => Data (PatSynBind idL idR)
+ }
+ | XPatSynBind (XXPatSynBind idL idR)
+
+type instance XPSB (GhcPass idL) GhcPs = NoExt
+type instance XPSB (GhcPass idL) GhcRn = NameSet
+type instance XPSB (GhcPass idL) GhcTc = NameSet
+
+type instance XXPatSynBind (GhcPass idL) (GhcPass idR) = NoExt
{-
Note [AbsBinds]
@@ -477,6 +528,53 @@ bindings only when
lacks a user type signature
* The group forms a strongly connected component
+
+Note [The abs_sig field of AbsBinds]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The abs_sig field supports a couple of special cases for bindings.
+Consider
+
+ x :: Num a => (# a, a #)
+ x = (# 3, 4 #)
+
+The general desugaring for AbsBinds would give
+
+ x = /\a. \ ($dNum :: Num a) ->
+ letrec xm = (# fromInteger $dNum 3, fromInteger $dNum 4 #) in
+ xm
+
+But that has an illegal let-binding for an unboxed tuple. In this
+case we'd prefer to generate the (more direct)
+
+ x = /\ a. \ ($dNum :: Num a) ->
+ (# fromInteger $dNum 3, fromInteger $dNum 4 #)
+
+A similar thing happens with representation-polymorphic defns
+(Trac #11405):
+
+ undef :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a
+ undef = error "undef"
+
+Again, the vanilla desugaring gives a local let-binding for a
+representation-polymorphic (undefm :: a), which is illegal. But
+again we can desugar without a let:
+
+ undef = /\ a. \ (d:HasCallStack) -> error a d "undef"
+
+The abs_sig field supports this direct desugaring, with no local
+let-bining. When abs_sig = True
+
+ * the abs_binds is single FunBind
+
+ * the abs_exports is a singleton
+
+ * we have a complete type sig for binder
+ and hence the abs_binds is non-recursive
+ (it binds the mono_id but refers to the poly_id
+
+These properties are exploited in DsBinds.dsAbsBinds to
+generate code without a let-binding.
+
Note [ABExport wrapper]
~~~~~~~~~~~~~~~~~~~~~~~
Consider
@@ -520,20 +618,21 @@ Specifically,
it's just an error thunk
-}
-instance (SourceTextX idL, SourceTextX idR,
+instance (idL ~ GhcPass pl, idR ~ GhcPass pr,
OutputableBndrId idL, OutputableBndrId idR)
=> Outputable (HsLocalBindsLR idL idR) where
- ppr (HsValBinds bs) = ppr bs
- ppr (HsIPBinds bs) = ppr bs
- ppr EmptyLocalBinds = empty
+ ppr (HsValBinds _ bs) = ppr bs
+ ppr (HsIPBinds _ bs) = ppr bs
+ ppr (EmptyLocalBinds _) = empty
+ ppr (XHsLocalBindsLR x) = ppr x
-instance (SourceTextX idL, SourceTextX idR,
+instance (idL ~ GhcPass pl, idR ~ GhcPass pr,
OutputableBndrId idL, OutputableBndrId idR)
=> Outputable (HsValBindsLR idL idR) where
- ppr (ValBindsIn binds sigs)
+ ppr (ValBinds _ binds sigs)
= pprDeclList (pprLHsBindsForUser binds sigs)
- ppr (ValBindsOut sccs sigs)
+ ppr (XValBindsLR (NValBinds sccs sigs))
= getPprStyle $ \ sty ->
if debugStyle sty then -- Print with sccs showing
vcat (map ppr sigs) $$ vcat (map ppr_scc sccs)
@@ -544,17 +643,16 @@ instance (SourceTextX idL, SourceTextX idR,
pp_rec Recursive = text "rec"
pp_rec NonRecursive = text "nonrec"
-pprLHsBinds :: (SourceTextX idL, SourceTextX idR,
- OutputableBndrId idL, OutputableBndrId idR)
- => LHsBindsLR idL idR -> SDoc
+pprLHsBinds :: (OutputableBndrId (GhcPass idL), OutputableBndrId (GhcPass idR))
+ => LHsBindsLR (GhcPass idL) (GhcPass idR) -> SDoc
pprLHsBinds binds
| isEmptyLHsBinds binds = empty
| otherwise = pprDeclList (map ppr (bagToList binds))
-pprLHsBindsForUser :: (SourceTextX idL, SourceTextX idR,
- OutputableBndrId idL, OutputableBndrId idR,
- SourceTextX id2, OutputableBndrId id2)
- => LHsBindsLR idL idR -> [LSig id2] -> [SDoc]
+pprLHsBindsForUser :: (OutputableBndrId (GhcPass idL),
+ OutputableBndrId (GhcPass idR),
+ OutputableBndrId (GhcPass id2))
+ => LHsBindsLR (GhcPass idL) (GhcPass idR) -> [LSig (GhcPass id2)] -> [SDoc]
-- pprLHsBindsForUser is different to pprLHsBinds because
-- a) No braces: 'let' and 'where' include a list of HsBindGroups
-- and we don't want several groups of bindings each
@@ -583,25 +681,33 @@ pprDeclList :: [SDoc] -> SDoc -- Braces with a space
pprDeclList ds = pprDeeperList vcat ds
------------
-emptyLocalBinds :: HsLocalBindsLR a b
-emptyLocalBinds = EmptyLocalBinds
-
-isEmptyLocalBinds :: HsLocalBindsLR a b -> Bool
-isEmptyLocalBinds (HsValBinds ds) = isEmptyValBinds ds
-isEmptyLocalBinds (HsIPBinds ds) = isEmptyIPBinds ds
-isEmptyLocalBinds EmptyLocalBinds = True
+emptyLocalBinds :: HsLocalBindsLR (GhcPass a) (GhcPass b)
+emptyLocalBinds = EmptyLocalBinds noExt
+
+-- AZ:These functions do not seem to be used at all?
+isEmptyLocalBindsTc :: HsLocalBindsLR (GhcPass a) GhcTc -> Bool
+isEmptyLocalBindsTc (HsValBinds _ ds) = isEmptyValBinds ds
+isEmptyLocalBindsTc (HsIPBinds _ ds) = isEmptyIPBindsTc ds
+isEmptyLocalBindsTc (EmptyLocalBinds _) = True
+isEmptyLocalBindsTc (XHsLocalBindsLR _) = True
+
+isEmptyLocalBindsPR :: HsLocalBindsLR (GhcPass a) (GhcPass b) -> Bool
+isEmptyLocalBindsPR (HsValBinds _ ds) = isEmptyValBinds ds
+isEmptyLocalBindsPR (HsIPBinds _ ds) = isEmptyIPBindsPR ds
+isEmptyLocalBindsPR (EmptyLocalBinds _) = True
+isEmptyLocalBindsPR (XHsLocalBindsLR _) = True
eqEmptyLocalBinds :: HsLocalBindsLR a b -> Bool
-eqEmptyLocalBinds EmptyLocalBinds = True
-eqEmptyLocalBinds _ = False
+eqEmptyLocalBinds (EmptyLocalBinds _) = True
+eqEmptyLocalBinds _ = False
-isEmptyValBinds :: HsValBindsLR a b -> Bool
-isEmptyValBinds (ValBindsIn ds sigs) = isEmptyLHsBinds ds && null sigs
-isEmptyValBinds (ValBindsOut ds sigs) = null ds && null sigs
+isEmptyValBinds :: HsValBindsLR (GhcPass a) (GhcPass b) -> Bool
+isEmptyValBinds (ValBinds _ ds sigs) = isEmptyLHsBinds ds && null sigs
+isEmptyValBinds (XValBindsLR (NValBinds ds sigs)) = null ds && null sigs
-emptyValBindsIn, emptyValBindsOut :: HsValBindsLR a b
-emptyValBindsIn = ValBindsIn emptyBag []
-emptyValBindsOut = ValBindsOut [] []
+emptyValBindsIn, emptyValBindsOut :: HsValBindsLR (GhcPass a) (GhcPass b)
+emptyValBindsIn = ValBinds noExt emptyBag []
+emptyValBindsOut = XValBindsLR (NValBinds [] [])
emptyLHsBinds :: LHsBindsLR idL idR
emptyLHsBinds = emptyBag
@@ -610,22 +716,23 @@ isEmptyLHsBinds :: LHsBindsLR idL idR -> Bool
isEmptyLHsBinds = isEmptyBag
------------
-plusHsValBinds :: HsValBinds a -> HsValBinds a -> HsValBinds a
-plusHsValBinds (ValBindsIn ds1 sigs1) (ValBindsIn ds2 sigs2)
- = ValBindsIn (ds1 `unionBags` ds2) (sigs1 ++ sigs2)
-plusHsValBinds (ValBindsOut ds1 sigs1) (ValBindsOut ds2 sigs2)
- = ValBindsOut (ds1 ++ ds2) (sigs1 ++ sigs2)
+plusHsValBinds :: HsValBinds (GhcPass a) -> HsValBinds (GhcPass a)
+ -> HsValBinds(GhcPass a)
+plusHsValBinds (ValBinds _ ds1 sigs1) (ValBinds _ ds2 sigs2)
+ = ValBinds noExt (ds1 `unionBags` ds2) (sigs1 ++ sigs2)
+plusHsValBinds (XValBindsLR (NValBinds ds1 sigs1))
+ (XValBindsLR (NValBinds ds2 sigs2))
+ = XValBindsLR (NValBinds (ds1 ++ ds2) (sigs1 ++ sigs2))
plusHsValBinds _ _
= panic "HsBinds.plusHsValBinds"
-instance (SourceTextX idL, SourceTextX idR,
+instance (idL ~ GhcPass pl, idR ~ GhcPass pr,
OutputableBndrId idL, OutputableBndrId idR)
=> Outputable (HsBindLR idL idR) where
ppr mbind = ppr_monobind mbind
-ppr_monobind :: (SourceTextX idL, SourceTextX idR,
- OutputableBndrId idL, OutputableBndrId idR)
- => HsBindLR idL idR -> SDoc
+ppr_monobind :: (OutputableBndrId (GhcPass idL), OutputableBndrId (GhcPass idR))
+ => HsBindLR (GhcPass idL) (GhcPass idR) -> SDoc
ppr_monobind (PatBind { pat_lhs = pat, pat_rhs = grhss })
= pprPatBind pat grhss
@@ -637,10 +744,10 @@ ppr_monobind (FunBind { fun_id = fun,
fun_tick = ticks })
= pprTicks empty (if null ticks then empty
else text "-- ticks = " <> ppr ticks)
- $$ ifPprDebug (pprBndr LetBind (unLoc fun))
+ $$ whenPprDebug (pprBndr LetBind (unLoc fun))
$$ pprFunBind matches
- $$ ifPprDebug (ppr wrap)
-ppr_monobind (PatSynBind psb) = ppr psb
+ $$ whenPprDebug (ppr wrap)
+ppr_monobind (PatSynBind _ psb) = ppr psb
ppr_monobind (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dictvars
, abs_exports = exports, abs_binds = val_binds
, abs_ev_binds = ev_binds })
@@ -658,30 +765,17 @@ ppr_monobind (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dictvars
, text "Evidence:" <+> ppr ev_binds ]
else
pprLHsBinds val_binds
-ppr_monobind (AbsBindsSig { abs_tvs = tyvars
- , abs_ev_vars = dictvars
- , abs_sig_export = poly_id
- , abs_sig_ev_bind = ev_bind
- , abs_sig_bind = bind })
- = sdocWithDynFlags $ \ dflags ->
- if gopt Opt_PrintTypecheckerElaboration dflags then
- hang (text "AbsBindsSig" <+> brackets (interpp'SP tyvars)
- <+> brackets (interpp'SP dictvars))
- 2 $ braces $ vcat
- [ text "Exported type:" <+> pprBndr LetBind poly_id
- , text "Bind:" <+> ppr bind
- , text "Evidence:" <+> ppr ev_bind ]
- else
- ppr bind
+ppr_monobind (XHsBindsLR x) = ppr x
-instance (OutputableBndrId p) => Outputable (ABExport p) where
+instance (p ~ GhcPass pass, OutputableBndrId p) => Outputable (ABExport p) where
ppr (ABE { abe_wrap = wrap, abe_poly = gbl, abe_mono = lcl, abe_prags = prags })
= vcat [ ppr gbl <+> text "<=" <+> ppr lcl
, nest 2 (pprTcSpecPrags prags)
, nest 2 (text "wrap:" <+> ppr wrap)]
+ ppr (XABExport x) = ppr x
-instance (SourceTextX idR,
- OutputableBndrId idL, OutputableBndrId idR)
+instance (idR ~ GhcPass pr,OutputableBndrId idL, OutputableBndrId idR,
+ Outputable (XXPatSynBind idL idR))
=> Outputable (PatSynBind idL idR) where
ppr (PSB{ psb_id = (L _ psyn), psb_args = details, psb_def = pat,
psb_dir = dir })
@@ -691,17 +785,17 @@ instance (SourceTextX idR,
ppr_simple syntax = syntax <+> ppr pat
ppr_details = case details of
- InfixPatSyn v1 v2 -> hsep [ppr v1, pprInfixOcc psyn, ppr v2]
- PrefixPatSyn vs -> hsep (pprPrefixOcc psyn : map ppr vs)
- RecordPatSyn vs ->
- pprPrefixOcc psyn
- <> braces (sep (punctuate comma (map ppr vs)))
+ InfixCon v1 v2 -> hsep [ppr v1, pprInfixOcc psyn, ppr v2]
+ PrefixCon vs -> hsep (pprPrefixOcc psyn : map ppr vs)
+ RecCon vs -> pprPrefixOcc psyn
+ <> braces (sep (punctuate comma (map ppr vs)))
ppr_rhs = case dir of
Unidirectional -> ppr_simple (text "<-")
ImplicitBidirectional -> ppr_simple equals
ExplicitBidirectional mg -> ppr_simple (text "<-") <+> ptext (sLit "where") $$
(nest 2 $ pprFunBind mg)
+ ppr (XPatSynBind x) = ppr x
pprTicks :: SDoc -> SDoc -> SDoc
-- Print stuff about ticks only when -dppr-debug is on, to avoid
@@ -724,13 +818,27 @@ 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
-deriving instance (DataId id) => Data (HsIPBinds id)
+ -- TcEvBinds -- Only in typechecker output; binds
+ -- -- uses of the implicit parameters
+ | XHsIPBinds (XXHsIPBinds id)
+
+type instance XIPBinds GhcPs = NoExt
+type instance XIPBinds GhcRn = NoExt
+type instance XIPBinds GhcTc = TcEvBinds -- binds uses of the
+ -- implicit parameters
-isEmptyIPBinds :: HsIPBinds id -> Bool
-isEmptyIPBinds (IPBinds is ds) = null is && isEmptyTcEvBinds ds
+
+type instance XXHsIPBinds (GhcPass p) = NoExt
+
+isEmptyIPBindsPR :: HsIPBinds (GhcPass p) -> Bool
+isEmptyIPBindsPR (IPBinds _ is) = null is
+isEmptyIPBindsPR (XHsIPBinds _) = True
+
+isEmptyIPBindsTc :: HsIPBinds GhcTc -> Bool
+isEmptyIPBindsTc (IPBinds ds is) = null is && isEmptyTcEvBinds ds
+isEmptyIPBindsTc (XHsIPBinds _) = True
-- | Located Implicit Parameter Binding
type LIPBind id = Located (IPBind id)
@@ -750,18 +858,27 @@ type LIPBind id = Located (IPBind id)
-- For details on above see note [Api annotations] in ApiAnnotation
data IPBind id
- = IPBind (Either (Located HsIPName) (IdP id)) (LHsExpr id)
-deriving instance (DataId name) => Data (IPBind name)
-
-instance (SourceTextX p, OutputableBndrId p) => Outputable (HsIPBinds p) where
- ppr (IPBinds bs ds) = pprDeeperList vcat (map ppr bs)
- $$ ifPprDebug (ppr ds)
-
-instance (SourceTextX p, OutputableBndrId p ) => Outputable (IPBind p) where
- ppr (IPBind lr rhs) = name <+> equals <+> pprExpr (unLoc rhs)
+ = IPBind
+ (XCIPBind id)
+ (Either (Located HsIPName) (IdP id))
+ (LHsExpr id)
+ | XIPBind (XXIPBind id)
+
+type instance XCIPBind (GhcPass p) = NoExt
+type instance XXIPBind (GhcPass p) = NoExt
+
+instance (p ~ GhcPass pass, OutputableBndrId p)
+ => Outputable (HsIPBinds p) where
+ ppr (IPBinds ds bs) = pprDeeperList vcat (map ppr bs)
+ $$ whenPprDebug (ppr ds)
+ ppr (XHsIPBinds x) = ppr x
+
+instance (p ~ GhcPass pass, OutputableBndrId p) => Outputable (IPBind p) where
+ ppr (IPBind _ lr rhs) = name <+> equals <+> pprExpr (unLoc rhs)
where name = case lr of
Left (L _ ip) -> pprBndr LetBind ip
Right id -> pprBndr LetBind id
+ ppr (XIPBind x) = ppr x
{-
************************************************************************
@@ -798,6 +915,7 @@ data Sig pass
-- For details on above see note [Api annotations] in ApiAnnotation
TypeSig
+ (XTypeSig pass)
[Located (IdP pass)] -- LHS of the signature; e.g. f,g,h :: blah
(LHsSigWcType pass) -- RHS of the signature; can have wildcards
@@ -810,7 +928,7 @@ data Sig pass
-- 'ApiAnnotation.AnnDot','ApiAnnotation.AnnDarrow'
-- For details on above see note [Api annotations] in ApiAnnotation
- | PatSynSig [Located (IdP pass)] (LHsSigType pass)
+ | PatSynSig (XPatSynSig pass) [Located (IdP pass)] (LHsSigType pass)
-- P :: forall a b. Req => Prov => ty
-- | A signature for a class method
@@ -823,14 +941,14 @@ data Sig pass
--
-- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnDefault',
-- 'ApiAnnotation.AnnDcolon'
- | ClassOpSig Bool [Located (IdP pass)] (LHsSigType pass)
+ | ClassOpSig (XClassOpSig pass) Bool [Located (IdP 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 Id
+ | IdSig (XIdSig pass) Id
-- | An ordinary fixity declaration
--
@@ -841,7 +959,7 @@ data Sig pass
-- 'ApiAnnotation.AnnVal'
-- For details on above see note [Api annotations] in ApiAnnotation
- | FixSig (FixitySig pass)
+ | FixSig (XFixSig pass) (FixitySig pass)
-- | An inline pragma
--
@@ -854,7 +972,8 @@ data Sig pass
-- 'ApiAnnotation.AnnClose'
-- For details on above see note [Api annotations] in ApiAnnotation
- | InlineSig (Located (IdP pass)) -- Function name
+ | InlineSig (XInlineSig pass)
+ (Located (IdP pass)) -- Function name
InlinePragma -- Never defaultInlinePragma
-- | A specialisation pragma
@@ -869,7 +988,8 @@ data Sig pass
-- 'ApiAnnotation.AnnDcolon'
-- For details on above see note [Api annotations] in ApiAnnotation
- | SpecSig (Located (IdP pass)) -- Specialise a function or datatype ...
+ | SpecSig (XSpecSig pass)
+ (Located (IdP 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
@@ -886,7 +1006,7 @@ data Sig pass
-- 'ApiAnnotation.AnnInstance','ApiAnnotation.AnnClose'
-- For details on above see note [Api annotations] in ApiAnnotation
- | SpecInstSig SourceText (LHsSigType pass)
+ | SpecInstSig (XSpecInstSig pass) SourceText (LHsSigType pass)
-- Note [Pragma source text] in BasicTypes
-- | A minimal complete definition pragma
@@ -898,7 +1018,8 @@ data Sig pass
-- 'ApiAnnotation.AnnClose'
-- For details on above see note [Api annotations] in ApiAnnotation
- | MinimalSig SourceText (LBooleanFormula (Located (IdP pass)))
+ | MinimalSig (XMinimalSig pass)
+ SourceText (LBooleanFormula (Located (IdP pass)))
-- Note [Pragma source text] in BasicTypes
-- | A "set cost centre" pragma for declarations
@@ -909,7 +1030,8 @@ data Sig pass
--
-- > {-# SCC funName "cost_centre_name" #-}
- | SCCFunSig SourceText -- Note [Pragma source text] in BasicTypes
+ | SCCFunSig (XSCCFunSig pass)
+ SourceText -- Note [Pragma source text] in BasicTypes
(Located (IdP pass)) -- Function name
(Maybe (Located StringLiteral))
-- | A complete match pragma
@@ -919,18 +1041,34 @@ data Sig pass
-- Used to inform the pattern match checker about additional
-- complete matchings which, for example, arise from pattern
-- synonym definitions.
- | CompleteMatchSig SourceText
+ | CompleteMatchSig (XCompleteMatchSig pass)
+ SourceText
(Located [Located (IdP pass)])
(Maybe (Located (IdP pass)))
-
-deriving instance (DataId pass) => Data (Sig pass)
+ | XSig (XXSig pass)
+
+type instance XTypeSig (GhcPass p) = NoExt
+type instance XPatSynSig (GhcPass p) = NoExt
+type instance XClassOpSig (GhcPass p) = NoExt
+type instance XIdSig (GhcPass p) = NoExt
+type instance XFixSig (GhcPass p) = NoExt
+type instance XInlineSig (GhcPass p) = NoExt
+type instance XSpecSig (GhcPass p) = NoExt
+type instance XSpecInstSig (GhcPass p) = NoExt
+type instance XMinimalSig (GhcPass p) = NoExt
+type instance XSCCFunSig (GhcPass p) = NoExt
+type instance XCompleteMatchSig (GhcPass p) = NoExt
+type instance XXSig (GhcPass p) = NoExt
-- | Located Fixity Signature
type LFixitySig pass = Located (FixitySig pass)
-- | Fixity Signature
-data FixitySig pass = FixitySig [Located (IdP pass)] Fixity
-deriving instance (DataId pass) => Data (FixitySig pass)
+data FixitySig pass = FixitySig (XFixitySig pass) [Located (IdP pass)] Fixity
+ | XFixitySig (XXFixitySig pass)
+
+type instance XFixitySig (GhcPass p) = NoExt
+type instance XXFixitySig (GhcPass p) = NoExt
-- | Type checker Specialisation Pragmas
--
@@ -950,7 +1088,7 @@ data TcSpecPrag
Id
HsWrapper
InlinePragma
- -- ^ The Id to be specialised, an wrapper that specialises the
+ -- ^ The Id to be specialised, a wrapper that specialises the
-- polymorphic function, and inlining spec for the specialised function
deriving Data
@@ -1012,17 +1150,18 @@ isCompleteMatchSig _ = False
hsSigDoc :: Sig name -> SDoc
hsSigDoc (TypeSig {}) = text "type signature"
hsSigDoc (PatSynSig {}) = text "pattern synonym signature"
-hsSigDoc (ClassOpSig is_deflt _ _)
+hsSigDoc (ClassOpSig _ is_deflt _ _)
| is_deflt = text "default type signature"
| otherwise = text "class method signature"
hsSigDoc (IdSig {}) = text "id signature"
hsSigDoc (SpecSig {}) = text "SPECIALISE pragma"
-hsSigDoc (InlineSig _ prag) = ppr (inlinePragmaSpec prag) <+> text "pragma"
+hsSigDoc (InlineSig _ _ prag) = ppr (inlinePragmaSpec prag) <+> text "pragma"
hsSigDoc (SpecInstSig {}) = text "SPECIALISE 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
@@ -1030,46 +1169,48 @@ 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 (SourceTextX pass, OutputableBndrId pass)
- => Outputable (Sig pass) where
+instance (p ~ GhcPass pass, OutputableBndrId p) => Outputable (Sig p) where
ppr sig = ppr_sig sig
-ppr_sig :: (SourceTextX pass, OutputableBndrId pass ) => Sig pass -> SDoc
-ppr_sig (TypeSig vars ty) = pprVarSig (map unLoc vars) (ppr ty)
-ppr_sig (ClassOpSig is_deflt vars ty)
+ppr_sig :: (OutputableBndrId (GhcPass p)) => Sig (GhcPass p) -> SDoc
+ppr_sig (TypeSig _ vars ty) = pprVarSig (map unLoc vars) (ppr ty)
+ppr_sig (ClassOpSig _ is_deflt vars ty)
| is_deflt = text "default" <+> pprVarSig (map unLoc vars) (ppr ty)
| otherwise = pprVarSig (map unLoc vars) (ppr ty)
-ppr_sig (IdSig id) = pprVarSig [id] (ppr (varType id))
-ppr_sig (FixSig fix_sig) = ppr fix_sig
-ppr_sig (SpecSig var ty inl@(InlinePragma { inl_inline = spec }))
+ppr_sig (IdSig _ id) = pprVarSig [id] (ppr (varType id))
+ppr_sig (FixSig _ fix_sig) = ppr fix_sig
+ppr_sig (SpecSig _ var ty inl@(InlinePragma { inl_inline = spec }))
= pragSrcBrackets (inl_src inl) pragmaSrc (pprSpec (unLoc var)
(interpp'SP ty) inl)
where
pragmaSrc = case spec of
- EmptyInlineSpec -> "{-# SPECIALISE"
- _ -> "{-# SPECIALISE_INLINE"
-ppr_sig (InlineSig var inl)
+ NoUserInline -> "{-# SPECIALISE"
+ _ -> "{-# SPECIALISE_INLINE"
+ppr_sig (InlineSig _ var inl)
= pragSrcBrackets (inl_src inl) "{-# INLINE" (pprInline inl
<+> pprPrefixOcc (unLoc var))
-ppr_sig (SpecInstSig src ty)
+ppr_sig (SpecInstSig _ src ty)
= pragSrcBrackets src "{-# SPECIALISE" (text "instance" <+> ppr ty)
-ppr_sig (MinimalSig src bf)
+ppr_sig (MinimalSig _ src bf)
= pragSrcBrackets src "{-# MINIMAL" (pprMinimalSig bf)
-ppr_sig (PatSynSig names sig_ty)
+ppr_sig (PatSynSig _ names sig_ty)
= text "pattern" <+> pprVarSig (map unLoc names) (ppr sig_ty)
-ppr_sig (SCCFunSig src fn mlabel)
+ppr_sig (SCCFunSig _ src fn mlabel)
= pragSrcBrackets src "{-# SCC" (ppr fn <+> maybe empty ppr mlabel )
-ppr_sig (CompleteMatchSig src cs mty)
+ppr_sig (CompleteMatchSig _ src cs mty)
= pragSrcBrackets src "{-# COMPLETE"
((hsep (punctuate comma (map ppr (unLoc cs))))
<+> opt_sig)
where
opt_sig = maybe empty ((\t -> dcolon <+> ppr t) . unLoc) mty
+ppr_sig (XSig x) = ppr x
-instance OutputableBndrId pass => Outputable (FixitySig pass) where
- ppr (FixitySig names fixity) = sep [ppr fixity, pprops]
+instance (p ~ GhcPass pass, OutputableBndrId p)
+ => Outputable (FixitySig p) where
+ ppr (FixitySig _ names fixity) = sep [ppr fixity, pprops]
where
pprops = hsep $ punctuate comma (map (pprInfixOcc . unLoc) names)
+ ppr (XFixitySig x) = ppr x
pragBrackets :: SDoc -> SDoc
pragBrackets doc = text "{-#" <+> doc <+> text "#-}"
@@ -1112,12 +1253,7 @@ pprMinimalSig (L _ bf) = ppr (fmap unLoc bf)
-}
-- | Haskell Pattern Synonym Details
-data HsPatSynDetails a
- = InfixPatSyn a a -- ^ Infix Pattern Synonym
- | PrefixPatSyn [a] -- ^ Prefix Pattern Synonym
- | RecordPatSyn [RecordPatSynField a] -- ^ Record Pattern Synonym
- deriving Data
-
+type HsPatSynDetails arg = HsConDetails arg [RecordPatSynField arg]
-- See Note [Record PatSyn Fields]
-- | Record Pattern Synonym Field
@@ -1174,46 +1310,8 @@ instance Traversable RecordPatSynField where
<$> f visible <*> f hidden
-instance Functor HsPatSynDetails where
- fmap f (InfixPatSyn left right) = InfixPatSyn (f left) (f right)
- fmap f (PrefixPatSyn args) = PrefixPatSyn (fmap f args)
- fmap f (RecordPatSyn args) = RecordPatSyn (map (fmap f) args)
-
-instance Foldable HsPatSynDetails where
- foldMap f (InfixPatSyn left right) = f left `mappend` f right
- foldMap f (PrefixPatSyn args) = foldMap f args
- foldMap f (RecordPatSyn args) = foldMap (foldMap f) args
-
- foldl1 f (InfixPatSyn left right) = left `f` right
- foldl1 f (PrefixPatSyn args) = Data.List.foldl1 f args
- foldl1 f (RecordPatSyn args) =
- Data.List.foldl1 f (map (Data.Foldable.foldl1 f) args)
-
- foldr1 f (InfixPatSyn left right) = left `f` right
- foldr1 f (PrefixPatSyn args) = Data.List.foldr1 f args
- foldr1 f (RecordPatSyn args) =
- Data.List.foldr1 f (map (Data.Foldable.foldr1 f) args)
-
- length (InfixPatSyn _ _) = 2
- length (PrefixPatSyn args) = Data.List.length args
- length (RecordPatSyn args) = Data.List.length args
-
- null (InfixPatSyn _ _) = False
- null (PrefixPatSyn args) = Data.List.null args
- null (RecordPatSyn args) = Data.List.null args
-
- toList (InfixPatSyn left right) = [left, right]
- toList (PrefixPatSyn args) = args
- toList (RecordPatSyn args) = foldMap toList args
-
-instance Traversable HsPatSynDetails where
- traverse f (InfixPatSyn left right) = InfixPatSyn <$> f left <*> f right
- traverse f (PrefixPatSyn args) = PrefixPatSyn <$> traverse f args
- traverse f (RecordPatSyn args) = RecordPatSyn <$> traverse (traverse f) args
-
-- | Haskell Pattern Synonym Direction
data HsPatSynDir id
= Unidirectional
| ImplicitBidirectional
| ExplicitBidirectional (MatchGroup id (LHsExpr id))
-deriving instance (DataId id) => Data (HsPatSynDir id)