{-
    %
(c) The University of Glasgow 2006
(c) The GRASP/AQUA Project, Glasgow University, 1992-1998

-}

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}

{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}

-- | Generating derived instance declarations
--
-- This module is nominally ``subordinate'' to "GHC.Tc.Deriv", which is the
-- ``official'' interface to deriving-related things.
--
-- This is where we do all the grimy bindings' generation.
module GHC.Tc.Deriv.Generate (
        AuxBindSpec(..),

        gen_Eq_binds,
        gen_Ord_binds,
        gen_Enum_binds,
        gen_Bounded_binds,
        gen_Ix_binds,
        gen_Show_binds,
        gen_Read_binds,
        gen_Data_binds,
        gen_Lift_binds,
        gen_Newtype_binds,
        gen_Newtype_fam_insts,
        mkCoerceClassMethEqn,
        genAuxBinds,
        ordOpTbl, boxConTbl,
        mkRdrFunBind, mkRdrFunBindEC, mkRdrFunBindSE, error_Expr,

        getPossibleDataCons,
        DerivInstTys(..), buildDataConInstArgEnv,
        derivDataConInstArgTys, substDerivInstTys, zonkDerivInstTys
    ) where

import GHC.Prelude

import GHC.Hs

import GHC.Tc.TyCl.Class ( substATBndrs )
import GHC.Tc.Utils.Monad
import GHC.Tc.Utils.Instantiate( newFamInst )
import GHC.Tc.Utils.Env
import GHC.Tc.Utils.TcType
import GHC.Tc.Zonk.Type
import GHC.Tc.Validity

import GHC.Core.DataCon
import GHC.Core.FamInstEnv
import GHC.Core.TyCon
import GHC.Core.Coercion.Axiom ( coAxiomSingleBranch )
import GHC.Core.Type
import GHC.Core.Class

import GHC.Types.Name.Reader
import GHC.Types.Basic
import GHC.Types.Fixity
import GHC.Types.Name
import GHC.Types.SourceText
import GHC.Types.Id.Make ( coerceId )
import GHC.Types.SrcLoc
import GHC.Types.Unique.FM ( lookupUFM, listToUFM )
import GHC.Types.Var.Env
import GHC.Types.Var
import GHC.Types.Var.Set

import GHC.Builtin.Names
import GHC.Builtin.Names.TH
import GHC.Builtin.PrimOps
import GHC.Builtin.PrimOps.Ids (primOpId)
import GHC.Builtin.Types.Prim
import GHC.Builtin.Types

import GHC.Utils.Misc
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Utils.Lexeme

import GHC.Data.FastString
import GHC.Data.Pair
import GHC.Data.Bag
import GHC.Data.Maybe ( expectJust )
import GHC.Unit.Module

import Language.Haskell.Syntax.Basic (FieldLabelString(..))

import Data.List  ( find, partition, intersperse )

-- | A declarative description of an auxiliary binding that should be
-- generated. See @Note [Auxiliary binders]@ for a more detailed description
-- of how these are used.
data AuxBindSpec
  -- DerivTag2Con, and DerivMaxTag are used in derived Eq, Ord,
  -- Enum, and Ix instances.
  -- All these generate ZERO-BASED tag operations
  -- I.e first constructor has tag 0

    -- | @$tag2con@: Given a tag, computes the corresponding data constructor
  = DerivTag2Con
      TyCon   -- The type constructor of the data type to which the
              -- constructors belong
      RdrName -- The to-be-generated $tag2con binding's RdrName

    -- | @$maxtag@: The maximum possible tag value among a data type's
    -- constructors
  | DerivMaxTag
      TyCon   -- The type constructor of the data type to which the
              -- constructors belong
      RdrName -- The to-be-generated $maxtag binding's RdrName

  -- DerivDataDataType and DerivDataConstr are only used in derived Data
  -- instances

    -- | @$t@: The @DataType@ representation for a @Data@ instance
  | DerivDataDataType
      TyCon     -- The type constructor of the data type to be represented
      RdrName   -- The to-be-generated $t binding's RdrName
      [RdrName] -- The RdrNames of the to-be-generated $c bindings for each
                -- data constructor. These are only used on the RHS of the
                -- to-be-generated $t binding.

    -- | @$c@: The @Constr@ representation for a @Data@ instance
  | DerivDataConstr
      DataCon -- The data constructor to be represented
      RdrName -- The to-be-generated $c binding's RdrName
      RdrName -- The RdrName of the to-be-generated $t binding for the parent
              -- data type. This is only used on the RHS of the
              -- to-be-generated $c binding.

-- | Retrieve the 'RdrName' of the binding that the supplied 'AuxBindSpec'
-- describes.
auxBindSpecRdrName :: AuxBindSpec -> RdrName
auxBindSpecRdrName :: AuxBindSpec -> RdrName
auxBindSpecRdrName (DerivTag2Con      TyCon
_ RdrName
tag2con_RDR) = RdrName
tag2con_RDR
auxBindSpecRdrName (DerivMaxTag       TyCon
_ RdrName
maxtag_RDR)  = RdrName
maxtag_RDR
auxBindSpecRdrName (DerivDataDataType TyCon
_ RdrName
dataT_RDR [RdrName]
_) = RdrName
dataT_RDR
auxBindSpecRdrName (DerivDataConstr   DataCon
_ RdrName
dataC_RDR RdrName
_) = RdrName
dataC_RDR

{-
************************************************************************
*                                                                      *
                Eq instances
*                                                                      *
************************************************************************

Here are the heuristics for the code we generate for @Eq@. Let's
assume we have a data type with some (possibly zero) nullary data
constructors and some ordinary, non-nullary ones (the rest, also
possibly zero of them).  Here's an example, with both \tr{N}ullary and
\tr{O}rdinary data cons.

  data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...

* We first attempt to compare the constructor tags. If tags don't
  match - we immediately bail out. Otherwise, we then generate one
  branch per constructor comparing only the fields as we already
  know that the tags match. Note that it only makes sense to check
  the tag if there is more than one data constructor.

* For the ordinary constructors (if any), we emit clauses to do The
  Usual Thing, e.g.,:

    (==) (O1 a1 b1)    (O1 a2 b2)    = a1 == a2 && b1 == b2
    (==) (O2 a1)       (O2 a2)       = a1 == a2
    (==) (O3 a1 b1 c1) (O3 a2 b2 c2) = a1 == a2 && b1 == b2 && c1 == c2

  Note: if we're comparing unlifted things, e.g., if 'a1' and
  'a2' are Float#s, then we have to generate
       case (a1 `eqFloat#` a2) of r -> r
  for that particular test.

* For nullary constructors, we emit a catch-all clause that always
  returns True since we already know that the tags match.

* So, given this data type:

    data T = A | B Int | C Char

  We roughly get:

    (==) a b =
      case dataToTag# a /= dataToTag# b of
        True -> False
        False -> case a of       -- Here we already know that tags match
            B a1 -> case b of
                B b1 -> a1 == b1 -- Only one branch
            C a1 -> case b of
                C b1 -> a1 == b1 -- Only one branch
            _ -> True            -- catch-all to match all nullary ctors

  An older approach preferred regular pattern matches in some cases
  but with dataToTag# forcing it's argument, and work on improving
  join points, this seems no longer necessary.

* For the @(/=)@ method, we normally just use the default method.
  If the type is an enumeration type, we could/may/should? generate
  special code that calls @dataToTag#@, much like for @(==)@ shown
  above.

We thought about doing this: If we're also deriving 'Ord' for this
tycon, we generate:
  instance ... Eq (Foo ...) where
    (==) a b  = case (compare a b) of { _LT -> False; _EQ -> True ; _GT -> False}
    (/=) a b  = case (compare a b) of { _LT -> True ; _EQ -> False; _GT -> True }
However, that requires that (Ord <whatever>) was put in the context
for the instance decl, which it probably wasn't, so the decls
produced don't get through the typechecker.
-}

gen_Eq_binds :: SrcSpan -> DerivInstTys -> TcM (LHsBinds GhcPs, Bag AuxBindSpec)
gen_Eq_binds :: SrcSpan
-> DerivInstTys
-> TcM (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
gen_Eq_binds SrcSpan
loc dit :: DerivInstTys
dit@(DerivInstTys{ dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
tycon
                                  , dit_rep_tc_args :: DerivInstTys -> [Type]
dit_rep_tc_args = [Type]
tycon_args }) = do
    ([GenLocated
    SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))],
 Bag AuxBindSpec)
-> IOEnv
     (Env TcGblEnv TcLclEnv)
     ([GenLocated
         SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))],
      Bag AuxBindSpec)
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([GenLocated
   SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
method_binds, Bag AuxBindSpec
forall a. Bag a
emptyBag)
  where
    all_cons :: [DataCon]
all_cons = TyCon -> [Type] -> [DataCon]
getPossibleDataCons TyCon
tycon [Type]
tycon_args
    non_nullary_cons :: [DataCon]
non_nullary_cons = (DataCon -> Bool) -> [DataCon] -> [DataCon]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (DataCon -> Bool) -> DataCon -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DataCon -> Bool
isNullarySrcDataCon) [DataCon]
all_cons

    -- Generate tag check. See #17240
    eq_expr_with_tag_check :: LHsExpr (GhcPass 'Parsed)
eq_expr_with_tag_check = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase
      (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar ([(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR,RdrName
ah_RDR), (RdrName
b_RDR,RdrName
bh_RDR)]
                    (LHsExpr (GhcPass 'Parsed)
-> IdP (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsOpApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
ah_RDR) IdP (GhcPass 'Parsed)
RdrName
neInt_RDR (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
bh_RDR))))
      [ LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (HsLit (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
nlLitPat (XHsIntPrim (GhcPass 'Parsed) -> Integer -> HsLit (GhcPass 'Parsed)
forall x. XHsIntPrim x -> Integer -> HsLit x
HsIntPrim XHsIntPrim (GhcPass 'Parsed)
SourceText
NoSourceText Integer
1)) LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
false_Expr
      , LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
nlWildPat (
          LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase
            (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
a_RDR)
            -- Only one branch to match all nullary constructors
            -- as we already know the tags match but do not emit
            -- the branch if there are no nullary constructors
            (let non_nullary_pats :: [GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
non_nullary_pats = (DataCon
 -> GenLocated
      SrcSpanAnnA
      (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> [DataCon]
-> [GenLocated
      SrcSpanAnnA
      (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a b. (a -> b) -> [a] -> [b]
map DataCon
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
DataCon
-> GenLocated
     SrcSpanAnnA
     (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))
pats_etc [DataCon]
non_nullary_cons
             in if [DataCon] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [DataCon]
non_nullary_cons
                then [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
[GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
non_nullary_pats
                else [GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
non_nullary_pats [GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ [LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
nlWildPat LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
true_Expr]))
      ]

    method_binds :: [GenLocated
   SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
method_binds = [LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
eq_bind]
    eq_bind :: LHsBind (GhcPass 'Parsed)
eq_bind = Int
-> SrcSpan
-> RdrName
-> (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkFunBindEC Int
2 SrcSpan
loc RdrName
eq_RDR (LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a b. a -> b -> a
const LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
true_Expr) [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
[([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
  LocatedA (HsExpr (GhcPass 'Parsed)))]
binds
      where
        binds :: [([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
  LocatedA (HsExpr (GhcPass 'Parsed)))]
binds
          | [DataCon] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [DataCon]
all_cons = []
          -- Tag checking is redundant when there is only one data constructor
          | [DataCon
data_con] <- [DataCon]
all_cons
          , ([RdrName]
as_needed, [RdrName]
bs_needed, [Type]
tys_needed) <- DataCon -> ([RdrName], [RdrName], [Type])
gen_con_fields_and_tys DataCon
data_con
          , RdrName
data_con_RDR <- DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
data_con
          , LPat (GhcPass 'Parsed)
con1_pat <- LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LPat (GhcPass p) -> LPat (GhcPass p)
nlParPat (LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed))
-> LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
data_con_RDR [RdrName]
as_needed
          , LPat (GhcPass 'Parsed)
con2_pat <- LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LPat (GhcPass p) -> LPat (GhcPass p)
nlParPat (LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed))
-> LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
data_con_RDR [RdrName]
bs_needed
          , LocatedA (HsExpr (GhcPass 'Parsed))
eq_expr <- [Type]
-> [RdrName] -> [RdrName] -> LocatedA (HsExpr (GhcPass 'Parsed))
nested_eq_expr [Type]
tys_needed [RdrName]
as_needed [RdrName]
bs_needed
          = [([LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
con1_pat, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
con2_pat], LocatedA (HsExpr (GhcPass 'Parsed))
eq_expr)]
          -- This is an enum (all constructors are nullary) - just do a simple tag check
          | (DataCon -> Bool) -> [DataCon] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all DataCon -> Bool
isNullarySrcDataCon [DataCon]
all_cons
          = [([LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
b_Pat], [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR,RdrName
ah_RDR), (RdrName
b_RDR,RdrName
bh_RDR)]
                    (LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genPrimOpApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
ah_RDR) RdrName
eqInt_RDR (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
bh_RDR)))]
          | Bool
otherwise
          = [([LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
b_Pat], LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
eq_expr_with_tag_check)]

    ------------------------------------------------------------------
    nested_eq_expr :: [Type] -> [RdrName] -> [RdrName] -> LHsExpr (GhcPass 'Parsed)
nested_eq_expr []  [] [] = LHsExpr (GhcPass 'Parsed)
true_Expr
    nested_eq_expr [Type]
tys [RdrName]
as [RdrName]
bs
      = (LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
and_Expr (String
-> (Type
    -> RdrName -> RdrName -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [Type]
-> [RdrName]
-> [RdrName]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a b c d.
HasDebugCallStack =>
String -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3Equal String
"nested_eq" Type -> RdrName -> RdrName -> LocatedA (HsExpr (GhcPass 'Parsed))
nested_eq [Type]
tys [RdrName]
as [RdrName]
bs)
      -- Using 'foldr1' here ensures that the derived code is correctly
      -- associated. See #10859.
      where
        nested_eq :: Type -> RdrName -> RdrName -> LHsExpr (GhcPass 'Parsed)
nested_eq Type
ty RdrName
a RdrName
b = LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar (Type
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
eq_Expr Type
ty (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
a) (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b))

    gen_con_fields_and_tys :: DataCon -> ([RdrName], [RdrName], [Type])
gen_con_fields_and_tys DataCon
data_con
      | [Type]
tys_needed <- DataCon -> DerivInstTys -> [Type]
derivDataConInstArgTys DataCon
data_con DerivInstTys
dit
      , Int
con_arity <- [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys_needed
      , [RdrName]
as_needed <- Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take Int
con_arity [RdrName]
as_RDRs
      , [RdrName]
bs_needed <- Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take Int
con_arity [RdrName]
bs_RDRs
      = ([RdrName]
as_needed, [RdrName]
bs_needed, [Type]
tys_needed)

    pats_etc :: DataCon
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
pats_etc DataCon
data_con
      | ([RdrName]
as_needed, [RdrName]
bs_needed, [Type]
tys_needed) <- DataCon -> ([RdrName], [RdrName], [Type])
gen_con_fields_and_tys DataCon
data_con
      , RdrName
data_con_RDR <- DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
data_con
      , LPat (GhcPass 'Parsed)
con1_pat <- LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LPat (GhcPass p) -> LPat (GhcPass p)
nlParPat (LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed))
-> LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
data_con_RDR [RdrName]
as_needed
      , LPat (GhcPass 'Parsed)
con2_pat <- LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LPat (GhcPass p) -> LPat (GhcPass p)
nlParPat (LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed))
-> LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
data_con_RDR [RdrName]
bs_needed
      , LocatedA (HsExpr (GhcPass 'Parsed))
fields_eq_expr <- [Type]
-> [RdrName] -> [RdrName] -> LocatedA (HsExpr (GhcPass 'Parsed))
nested_eq_expr [Type]
tys_needed [RdrName]
as_needed [RdrName]
bs_needed
      = LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
con1_pat (LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b_RDR) [LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
con2_pat LocatedA (HsExpr (GhcPass 'Parsed))
fields_eq_expr])

{-
************************************************************************
*                                                                      *
        Ord instances
*                                                                      *
************************************************************************

Note [Generating Ord instances]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppose constructors are K1..Kn, and some are nullary.
The general form we generate is:

* Do case on first argument
        case a of
          K1 ... -> rhs_1
          K2 ... -> rhs_2
          ...
          Kn ... -> rhs_n
          _ -> nullary_rhs

* To make rhs_i
     If i = 1, 2, n-1, n, generate a single case.
        rhs_2    case b of
                   K1 {}  -> LT
                   K2 ... -> ...eq_rhs(K2)...
                   _      -> GT

     Otherwise do a tag compare against the bigger range
     (because this is the one most likely to succeed)
        rhs_3    case tag b of tb ->
                 if 3 <# tg then GT
                 else case b of
                         K3 ... -> ...eq_rhs(K3)....
                         _      -> LT

* To make eq_rhs(K), which knows that
    a = K a1 .. av
    b = K b1 .. bv
  we just want to compare (a1,b1) then (a2,b2) etc.
  Take care on the last field to tail-call into comparing av,bv

* To make nullary_rhs generate this
     case dataToTag# a of a# ->
     case dataToTag# b of ->
     a# `compare` b#

Several special cases:

* Two or fewer nullary constructors: don't generate nullary_rhs

* Be careful about unlifted comparisons.  When comparing unboxed
  values we can't call the overloaded functions.
  See function unliftedOrdOp

Note [Game plan for deriving Ord]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It's a bad idea to define only 'compare', and build the other binary
comparisons on top of it; see #2130, #4019.  Reason: we don't
want to laboriously make a three-way comparison, only to extract a
binary result, something like this:
     (>) (I# x) (I# y) = case <# x y of
                            True -> False
                            False -> case ==# x y of
                                       True  -> False
                                       False -> True

This being said, we can get away with generating full code only for
'compare' and '<' thus saving us generation of other three operators.
Other operators can be cheaply expressed through '<':
a <= b = not $ b < a
a > b = b < a
a >= b = not $ a < b

So for sufficiently small types (few constructors, or all nullary)
we generate all methods; for large ones we just use 'compare'.

-}

data OrdOp = OrdCompare | OrdLT | OrdLE | OrdGE | OrdGT

------------
ordMethRdr :: OrdOp -> RdrName
ordMethRdr :: OrdOp -> RdrName
ordMethRdr OrdOp
op
  = case OrdOp
op of
       OrdOp
OrdCompare -> RdrName
compare_RDR
       OrdOp
OrdLT      -> RdrName
lt_RDR
       OrdOp
OrdLE      -> RdrName
le_RDR
       OrdOp
OrdGE      -> RdrName
ge_RDR
       OrdOp
OrdGT      -> RdrName
gt_RDR

------------
ltResult :: OrdOp -> LHsExpr GhcPs
-- Knowing a<b, what is the result for a `op` b?
ltResult :: OrdOp -> LHsExpr (GhcPass 'Parsed)
ltResult OrdOp
OrdCompare = LHsExpr (GhcPass 'Parsed)
ltTag_Expr
ltResult OrdOp
OrdLT      = LHsExpr (GhcPass 'Parsed)
true_Expr
ltResult OrdOp
OrdLE      = LHsExpr (GhcPass 'Parsed)
true_Expr
ltResult OrdOp
OrdGE      = LHsExpr (GhcPass 'Parsed)
false_Expr
ltResult OrdOp
OrdGT      = LHsExpr (GhcPass 'Parsed)
false_Expr

------------
eqResult :: OrdOp -> LHsExpr GhcPs
-- Knowing a=b, what is the result for a `op` b?
eqResult :: OrdOp -> LHsExpr (GhcPass 'Parsed)
eqResult OrdOp
OrdCompare = LHsExpr (GhcPass 'Parsed)
eqTag_Expr
eqResult OrdOp
OrdLT      = LHsExpr (GhcPass 'Parsed)
false_Expr
eqResult OrdOp
OrdLE      = LHsExpr (GhcPass 'Parsed)
true_Expr
eqResult OrdOp
OrdGE      = LHsExpr (GhcPass 'Parsed)
true_Expr
eqResult OrdOp
OrdGT      = LHsExpr (GhcPass 'Parsed)
false_Expr

------------
gtResult :: OrdOp -> LHsExpr GhcPs
-- Knowing a>b, what is the result for a `op` b?
gtResult :: OrdOp -> LHsExpr (GhcPass 'Parsed)
gtResult OrdOp
OrdCompare = LHsExpr (GhcPass 'Parsed)
gtTag_Expr
gtResult OrdOp
OrdLT      = LHsExpr (GhcPass 'Parsed)
false_Expr
gtResult OrdOp
OrdLE      = LHsExpr (GhcPass 'Parsed)
false_Expr
gtResult OrdOp
OrdGE      = LHsExpr (GhcPass 'Parsed)
true_Expr
gtResult OrdOp
OrdGT      = LHsExpr (GhcPass 'Parsed)
true_Expr

------------
gen_Ord_binds :: SrcSpan -> DerivInstTys -> TcM (LHsBinds GhcPs, Bag AuxBindSpec)
gen_Ord_binds :: SrcSpan
-> DerivInstTys
-> TcM (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
gen_Ord_binds SrcSpan
loc dit :: DerivInstTys
dit@(DerivInstTys{ dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
tycon
                                   , dit_rep_tc_args :: DerivInstTys -> [Type]
dit_rep_tc_args = [Type]
tycon_args }) = do
    (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
-> TcM (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
 -> TcM (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec))
-> (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
-> TcM (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
forall a b. (a -> b) -> a -> b
$ if [DataCon] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [DataCon]
tycon_data_cons -- No data-cons => invoke bale-out case
      then ( [Int
-> SrcSpan
-> RdrName
-> (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkFunBindEC Int
2 SrcSpan
loc RdrName
compare_RDR (LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a b. a -> b -> a
const LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
eqTag_Expr) []]
           , Bag AuxBindSpec
forall a. Bag a
emptyBag)
      else ( [OrdOp -> LHsBind (GhcPass 'Parsed)
mkOrdOp OrdOp
OrdCompare] [GenLocated
   SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
-> [GenLocated
      SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
-> [GenLocated
      SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
forall a. [a] -> [a] -> [a]
++ [GenLocated
   SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
other_ops
           , Bag AuxBindSpec
forall a. Bag a
aux_binds)
  where
    aux_binds :: Bag a
aux_binds = Bag a
forall a. Bag a
emptyBag

        -- Note [Game plan for deriving Ord]
    other_ops :: [GenLocated
   SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
other_ops
      | (Int
last_tag Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
first_tag) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
2     -- 1-3 constructors
        Bool -> Bool -> Bool
|| [DataCon] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [DataCon]
non_nullary_cons        -- Or it's an enumeration
      = [OrdOp -> LHsBind (GhcPass 'Parsed)
mkOrdOp OrdOp
OrdLT, LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
lE, LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
gT, LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
gE]
      | Bool
otherwise
      = []

    negate_expr :: LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
negate_expr = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
not_RDR)
    pats :: GenLocated
  EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
pats = [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
b_Pat]
    lE :: LHsBind (GhcPass 'Parsed)
lE = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
le_RDR LocatedE [LPat (GhcPass 'Parsed)]
GenLocated
  EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
pats (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
negate_expr (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
lt_RDR) LHsExpr (GhcPass 'Parsed)
b_Expr) LHsExpr (GhcPass 'Parsed)
a_Expr)
    gT :: LHsBind (GhcPass 'Parsed)
gT = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
gt_RDR LocatedE [LPat (GhcPass 'Parsed)]
GenLocated
  EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
pats (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
lt_RDR) LHsExpr (GhcPass 'Parsed)
b_Expr) LHsExpr (GhcPass 'Parsed)
a_Expr
    gE :: LHsBind (GhcPass 'Parsed)
gE = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
ge_RDR LocatedE [LPat (GhcPass 'Parsed)]
GenLocated
  EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
pats (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
negate_expr (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
lt_RDR) LHsExpr (GhcPass 'Parsed)
a_Expr) LHsExpr (GhcPass 'Parsed)
b_Expr)

    get_tag :: DataCon -> Int
get_tag DataCon
con = DataCon -> Int
dataConTag DataCon
con Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
fIRST_TAG
        -- We want *zero-based* tags, because that's what
        -- con2Tag returns (generated by untag_Expr)!

    tycon_data_cons :: [DataCon]
tycon_data_cons = TyCon -> [Type] -> [DataCon]
getPossibleDataCons TyCon
tycon [Type]
tycon_args
    single_con_type :: Bool
single_con_type = [DataCon] -> Bool
forall a. [a] -> Bool
isSingleton [DataCon]
tycon_data_cons
    (DataCon
first_con : [DataCon]
_) = [DataCon]
tycon_data_cons
    (DataCon
last_con : [DataCon]
_)  = [DataCon] -> [DataCon]
forall a. [a] -> [a]
reverse [DataCon]
tycon_data_cons
    first_tag :: Int
first_tag       = DataCon -> Int
get_tag DataCon
first_con
    last_tag :: Int
last_tag        = DataCon -> Int
get_tag DataCon
last_con

    ([DataCon]
nullary_cons, [DataCon]
non_nullary_cons) = (DataCon -> Bool) -> [DataCon] -> ([DataCon], [DataCon])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition DataCon -> Bool
isNullarySrcDataCon [DataCon]
tycon_data_cons


    mkOrdOp :: OrdOp -> LHsBind GhcPs
    -- Returns a binding   op a b = ... compares a and b according to op ....
    mkOrdOp :: OrdOp -> LHsBind (GhcPass 'Parsed)
mkOrdOp OrdOp
op
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc (OrdOp -> RdrName
ordMethRdr OrdOp
op) ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
b_Pat])
                        (OrdOp -> LHsExpr (GhcPass 'Parsed)
mkOrdOpRhs OrdOp
op)

    mkOrdOpRhs :: OrdOp -> LHsExpr GhcPs
    mkOrdOpRhs :: OrdOp -> LHsExpr (GhcPass 'Parsed)
mkOrdOpRhs OrdOp
op -- RHS for comparing 'a' and 'b' according to op
      | [DataCon]
nullary_cons [DataCon] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthAtMost` Int
2 -- Two nullary or fewer, so use cases
      = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
a_RDR) ([LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
 -> LHsExpr (GhcPass 'Parsed))
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        (DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed)))
-> [DataCon]
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
forall a b. (a -> b) -> [a] -> [b]
map (OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkOrdOpAlt OrdOp
op) [DataCon]
tycon_data_cons
        -- i.e.  case a of { C1 x y -> case b of C1 x y -> ....compare x,y...
        --                   C2 x   -> case b of C2 x -> ....compare x.... }

      | [DataCon] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [DataCon]
non_nullary_cons    -- All nullary, so go straight to comparing tags
      = OrdOp -> LHsExpr (GhcPass 'Parsed)
mkTagCmp OrdOp
op

      | Bool
otherwise                -- Mixed nullary and non-nullary
      = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
a_RDR) ([LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
 -> LHsExpr (GhcPass 'Parsed))
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        ((DataCon
 -> GenLocated
      SrcSpanAnnA
      (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> [DataCon]
-> [GenLocated
      SrcSpanAnnA
      (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a b. (a -> b) -> [a] -> [b]
map (OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkOrdOpAlt OrdOp
op) [DataCon]
non_nullary_cons
         [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
forall a. [a] -> [a] -> [a]
++ [LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
nlWildPat (OrdOp -> LHsExpr (GhcPass 'Parsed)
mkTagCmp OrdOp
op)])


    mkOrdOpAlt :: OrdOp -> DataCon
               -> LMatch GhcPs (LHsExpr GhcPs)
    -- Make the alternative  (Ki a1 a2 .. av ->
    mkOrdOpAlt :: OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkOrdOpAlt OrdOp
op DataCon
data_con
      = LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
data_con_RDR [RdrName]
as_needed)
                    (OrdOp -> DataCon -> LHsExpr (GhcPass 'Parsed)
mkInnerRhs OrdOp
op DataCon
data_con)
      where
        as_needed :: [RdrName]
as_needed    = Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take (DataCon -> Int
dataConSourceArity DataCon
data_con) [RdrName]
as_RDRs
        data_con_RDR :: RdrName
data_con_RDR = DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
data_con

    mkInnerRhs :: OrdOp -> DataCon -> LHsExpr (GhcPass 'Parsed)
mkInnerRhs OrdOp
op DataCon
data_con
      | Bool
single_con_type
      = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b_RDR) [ OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkInnerEqAlt OrdOp
op DataCon
data_con ]

      | Int
tag Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
first_tag
      = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b_RDR) [ OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkInnerEqAlt OrdOp
op DataCon
data_con
                                 , LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
nlWildPat (OrdOp -> LHsExpr (GhcPass 'Parsed)
ltResult OrdOp
op) ]
      | Int
tag Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
last_tag
      = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b_RDR) [ OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkInnerEqAlt OrdOp
op DataCon
data_con
                                 , LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
nlWildPat (OrdOp -> LHsExpr (GhcPass 'Parsed)
gtResult OrdOp
op) ]

      | Int
tag Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
first_tag Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
      = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b_RDR) [ LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (DataCon -> LPat (GhcPass 'Parsed)
nlConWildPat DataCon
first_con)
                                             (OrdOp -> LHsExpr (GhcPass 'Parsed)
gtResult OrdOp
op)
                                 , OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkInnerEqAlt OrdOp
op DataCon
data_con
                                 , LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
nlWildPat (OrdOp -> LHsExpr (GhcPass 'Parsed)
ltResult OrdOp
op) ]
      | Int
tag Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
last_tag Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
      = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b_RDR) [ LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (DataCon -> LPat (GhcPass 'Parsed)
nlConWildPat DataCon
last_con)
                                             (OrdOp -> LHsExpr (GhcPass 'Parsed)
ltResult OrdOp
op)
                                 , OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkInnerEqAlt OrdOp
op DataCon
data_con
                                 , LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
nlWildPat (OrdOp -> LHsExpr (GhcPass 'Parsed)
gtResult OrdOp
op) ]

      | Int
tag Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
last_tag Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2  -- lower range is larger
      = [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
b_RDR, RdrName
bh_RDR)] (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsIf (LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genPrimOpApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
bh_RDR) RdrName
ltInt_RDR LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
tag_lit)
               (OrdOp -> LHsExpr (GhcPass 'Parsed)
gtResult OrdOp
op) (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$  -- Definitely GT
        LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b_RDR) [ OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkInnerEqAlt OrdOp
op DataCon
data_con
                                 , LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
nlWildPat (OrdOp -> LHsExpr (GhcPass 'Parsed)
ltResult OrdOp
op) ]

      | Bool
otherwise               -- upper range is larger
      = [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
b_RDR, RdrName
bh_RDR)] (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsIf (LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genPrimOpApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
bh_RDR) RdrName
gtInt_RDR LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
tag_lit)
               (OrdOp -> LHsExpr (GhcPass 'Parsed)
ltResult OrdOp
op) (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$  -- Definitely LT
        LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b_RDR) [ OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkInnerEqAlt OrdOp
op DataCon
data_con
                                 , LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt LPat (GhcPass 'Parsed)
nlWildPat (OrdOp -> LHsExpr (GhcPass 'Parsed)
gtResult OrdOp
op) ]
      where
        tag :: Int
tag     = DataCon -> Int
get_tag DataCon
data_con
        tag_lit :: LocatedA (HsExpr (GhcPass 'Parsed))
tag_lit
             = HsExpr (GhcPass 'Parsed) -> LocatedA (HsExpr (GhcPass 'Parsed))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (XLitE (GhcPass 'Parsed)
-> HsLit (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
forall p. XLitE p -> HsLit p -> HsExpr p
HsLit XLitE (GhcPass 'Parsed)
NoExtField
noExtField (XHsIntPrim (GhcPass 'Parsed) -> Integer -> HsLit (GhcPass 'Parsed)
forall x. XHsIntPrim x -> Integer -> HsLit x
HsIntPrim XHsIntPrim (GhcPass 'Parsed)
SourceText
NoSourceText (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
tag)))

    mkInnerEqAlt :: OrdOp -> DataCon -> LMatch GhcPs (LHsExpr GhcPs)
    -- First argument 'a' known to be built with K
    -- Returns a case alternative  Ki b1 b2 ... bv -> compare (a1,a2,...) with (b1,b2,...)
    mkInnerEqAlt :: OrdOp
-> DataCon -> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
mkInnerEqAlt OrdOp
op DataCon
data_con
      = LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
data_con_RDR [RdrName]
bs_needed) (LocatedA (HsExpr (GhcPass 'Parsed))
 -> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall a b. (a -> b) -> a -> b
$
        OrdOp -> [Type] -> LHsExpr (GhcPass 'Parsed)
mkCompareFields OrdOp
op (DataCon -> DerivInstTys -> [Type]
derivDataConInstArgTys DataCon
data_con DerivInstTys
dit)
      where
        data_con_RDR :: RdrName
data_con_RDR = DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
data_con
        bs_needed :: [RdrName]
bs_needed    = Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take (DataCon -> Int
dataConSourceArity DataCon
data_con) [RdrName]
bs_RDRs

    mkTagCmp :: OrdOp -> LHsExpr GhcPs
    -- Both constructors known to be nullary
    -- generates (case data2Tag a of a# -> case data2Tag b of b# -> a# `op` b#
    mkTagCmp :: OrdOp -> LHsExpr (GhcPass 'Parsed)
mkTagCmp OrdOp
op =
      [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR, RdrName
ah_RDR),(RdrName
b_RDR, RdrName
bh_RDR)] (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        Type -> OrdOp -> RdrName -> RdrName -> LHsExpr (GhcPass 'Parsed)
unliftedOrdOp Type
intPrimTy OrdOp
op RdrName
ah_RDR RdrName
bh_RDR

mkCompareFields :: OrdOp -> [Type] -> LHsExpr GhcPs
-- Generates nested comparisons for (a1,a2...) against (b1,b2,...)
-- where the ai,bi have the given types
mkCompareFields :: OrdOp -> [Type] -> LHsExpr (GhcPass 'Parsed)
mkCompareFields OrdOp
op [Type]
tys
  = [Type]
-> [RdrName] -> [RdrName] -> LocatedA (HsExpr (GhcPass 'Parsed))
go [Type]
tys [RdrName]
as_RDRs [RdrName]
bs_RDRs
  where
    go :: [Type]
-> [RdrName] -> [RdrName] -> LocatedA (HsExpr (GhcPass 'Parsed))
go []   [RdrName]
_      [RdrName]
_          = OrdOp -> LHsExpr (GhcPass 'Parsed)
eqResult OrdOp
op
    go [Type
ty] (RdrName
a:[RdrName]
_)  (RdrName
b:[RdrName]
_)
      | HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType Type
ty     = Type -> OrdOp -> RdrName -> RdrName -> LHsExpr (GhcPass 'Parsed)
unliftedOrdOp Type
ty OrdOp
op RdrName
a RdrName
b
      | Bool
otherwise             = LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genOpApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
a) (OrdOp -> RdrName
ordMethRdr OrdOp
op) (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b)
    go (Type
ty:[Type]
tys) (RdrName
a:[RdrName]
as) (RdrName
b:[RdrName]
bs) = Type
-> RdrName
-> RdrName
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
mk_compare Type
ty RdrName
a RdrName
b
                                  (OrdOp -> LHsExpr (GhcPass 'Parsed)
ltResult OrdOp
op)
                                  ([Type]
-> [RdrName] -> [RdrName] -> LocatedA (HsExpr (GhcPass 'Parsed))
go [Type]
tys [RdrName]
as [RdrName]
bs)
                                  (OrdOp -> LHsExpr (GhcPass 'Parsed)
gtResult OrdOp
op)
    go [Type]
_ [RdrName]
_ [RdrName]
_ = String -> LocatedA (HsExpr (GhcPass 'Parsed))
forall a. HasCallStack => String -> a
panic String
"mkCompareFields"

    -- (mk_compare ty a b) generates
    --    (case (compare a b) of { LT -> <lt>; EQ -> <eq>; GT -> <bt> })
    -- but with suitable special cases for
    mk_compare :: Type
-> IdGhcP 'Parsed
-> IdGhcP 'Parsed
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed)
mk_compare Type
ty IdGhcP 'Parsed
a IdGhcP 'Parsed
b LocatedA (HsExpr (GhcPass 'Parsed))
lt LocatedA (HsExpr (GhcPass 'Parsed))
eq LocatedA (HsExpr (GhcPass 'Parsed))
gt
      | HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType Type
ty
      = RdrName
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
unliftedCompare RdrName
lt_op RdrName
eq_op LHsExpr (GhcPass 'Parsed)
a_expr LHsExpr (GhcPass 'Parsed)
b_expr LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
lt LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
eq LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
gt
      | Bool
otherwise
      = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
compare_RDR) LHsExpr (GhcPass 'Parsed)
a_expr) LHsExpr (GhcPass 'Parsed)
b_expr))
          [LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (RdrName -> LPat (GhcPass 'Parsed)
nlNullaryConPat RdrName
ltTag_RDR) LocatedA (HsExpr (GhcPass 'Parsed))
lt,
           LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (RdrName -> LPat (GhcPass 'Parsed)
nlNullaryConPat RdrName
eqTag_RDR) LocatedA (HsExpr (GhcPass 'Parsed))
eq,
           LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (RdrName -> LPat (GhcPass 'Parsed)
nlNullaryConPat RdrName
gtTag_RDR) LocatedA (HsExpr (GhcPass 'Parsed))
gt]
      where
        a_expr :: LHsExpr (GhcPass 'Parsed)
a_expr = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
IdGhcP 'Parsed
a
        b_expr :: LHsExpr (GhcPass 'Parsed)
b_expr = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
IdGhcP 'Parsed
b
        (RdrName
lt_op, RdrName
_, RdrName
eq_op, RdrName
_, RdrName
_) = String -> Type -> (RdrName, RdrName, RdrName, RdrName, RdrName)
primOrdOps String
"Ord" Type
ty

unliftedOrdOp :: Type -> OrdOp -> RdrName -> RdrName -> LHsExpr GhcPs
unliftedOrdOp :: Type -> OrdOp -> RdrName -> RdrName -> LHsExpr (GhcPass 'Parsed)
unliftedOrdOp Type
ty OrdOp
op RdrName
a RdrName
b
  = case OrdOp
op of
       OrdOp
OrdCompare -> RdrName
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
unliftedCompare RdrName
lt_op RdrName
eq_op LHsExpr (GhcPass 'Parsed)
a_expr LHsExpr (GhcPass 'Parsed)
b_expr
                                     LHsExpr (GhcPass 'Parsed)
ltTag_Expr LHsExpr (GhcPass 'Parsed)
eqTag_Expr LHsExpr (GhcPass 'Parsed)
gtTag_Expr
       OrdOp
OrdLT      -> RdrName -> LHsExpr (GhcPass 'Parsed)
wrap RdrName
lt_op
       OrdOp
OrdLE      -> RdrName -> LHsExpr (GhcPass 'Parsed)
wrap RdrName
le_op
       OrdOp
OrdGE      -> RdrName -> LHsExpr (GhcPass 'Parsed)
wrap RdrName
ge_op
       OrdOp
OrdGT      -> RdrName -> LHsExpr (GhcPass 'Parsed)
wrap RdrName
gt_op
  where
   (RdrName
lt_op, RdrName
le_op, RdrName
eq_op, RdrName
ge_op, RdrName
gt_op) = String -> Type -> (RdrName, RdrName, RdrName, RdrName, RdrName)
primOrdOps String
"Ord" Type
ty
   wrap :: RdrName -> LHsExpr (GhcPass 'Parsed)
wrap RdrName
prim_op = LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genPrimOpApp LHsExpr (GhcPass 'Parsed)
a_expr RdrName
prim_op LHsExpr (GhcPass 'Parsed)
b_expr
   a_expr :: LHsExpr (GhcPass 'Parsed)
a_expr = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
a
   b_expr :: LHsExpr (GhcPass 'Parsed)
b_expr = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b

unliftedCompare :: RdrName -> RdrName
                -> LHsExpr GhcPs -> LHsExpr GhcPs   -- What to compare
                -> LHsExpr GhcPs -> LHsExpr GhcPs -> LHsExpr GhcPs
                                                    -- Three results
                -> LHsExpr GhcPs
-- Return (if a < b then lt else if a == b then eq else gt)
unliftedCompare :: RdrName
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
unliftedCompare RdrName
lt_op RdrName
eq_op LHsExpr (GhcPass 'Parsed)
a_expr LHsExpr (GhcPass 'Parsed)
b_expr LHsExpr (GhcPass 'Parsed)
lt LHsExpr (GhcPass 'Parsed)
eq LHsExpr (GhcPass 'Parsed)
gt
  = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsIf (LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
ascribeBool (LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a b. (a -> b) -> a -> b
$ LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genPrimOpApp LHsExpr (GhcPass 'Parsed)
a_expr RdrName
lt_op LHsExpr (GhcPass 'Parsed)
b_expr) LHsExpr (GhcPass 'Parsed)
lt (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
                        -- Test (<) first, not (==), because the latter
                        -- is true less often, so putting it first would
                        -- mean more tests (dynamically)
        LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsIf (LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
ascribeBool (LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a b. (a -> b) -> a -> b
$ LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genPrimOpApp LHsExpr (GhcPass 'Parsed)
a_expr RdrName
eq_op LHsExpr (GhcPass 'Parsed)
b_expr) LHsExpr (GhcPass 'Parsed)
eq LHsExpr (GhcPass 'Parsed)
gt
  where
    ascribeBool :: LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
ascribeBool = RdrName -> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
nlAscribe RdrName
boolTyCon_RDR

nlConWildPat :: DataCon -> LPat GhcPs
-- The pattern (K {})
nlConWildPat :: DataCon -> LPat (GhcPass 'Parsed)
nlConWildPat DataCon
con = Pat (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (Pat (GhcPass 'Parsed)
 -> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed)))
-> Pat (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
forall a b. (a -> b) -> a -> b
$ ConPat
  { pat_con_ext :: XConPat (GhcPass 'Parsed)
pat_con_ext = XConPat (GhcPass 'Parsed)
forall a. NoAnn a => a
noAnn
  , pat_con :: XRec (GhcPass 'Parsed) (ConLikeP (GhcPass 'Parsed))
pat_con = RdrName -> GenLocated SrcSpanAnnN RdrName
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (RdrName -> GenLocated SrcSpanAnnN RdrName)
-> RdrName -> GenLocated SrcSpanAnnN RdrName
forall a b. (a -> b) -> a -> b
$ DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
con
  , pat_args :: HsConPatDetails (GhcPass 'Parsed)
pat_args = HsRecFields (GhcPass 'Parsed) (LPat (GhcPass 'Parsed))
-> HsConPatDetails (GhcPass 'Parsed)
forall tyarg arg rec. rec -> HsConDetails tyarg arg rec
RecCon (HsRecFields (GhcPass 'Parsed) (LPat (GhcPass 'Parsed))
 -> HsConPatDetails (GhcPass 'Parsed))
-> HsRecFields (GhcPass 'Parsed) (LPat (GhcPass 'Parsed))
-> HsConPatDetails (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ HsRecFields
      { rec_ext :: XHsRecFields (GhcPass 'Parsed)
rec_ext = NoExtField
XHsRecFields (GhcPass 'Parsed)
noExtField
      , rec_flds :: [LHsRecField (GhcPass 'Parsed) (LPat (GhcPass 'Parsed))]
rec_flds = []
      , rec_dotdot :: Maybe (XRec (GhcPass 'Parsed) RecFieldsDotDot)
rec_dotdot = Maybe (XRec (GhcPass 'Parsed) RecFieldsDotDot)
forall a. Maybe a
Nothing }
  }

{-
************************************************************************
*                                                                      *
        Enum instances
*                                                                      *
************************************************************************

@Enum@ can only be derived for enumeration types.  For a type
\begin{verbatim}
data Foo ... = N1 | N2 | ... | Nn
\end{verbatim}

we use both dataToTag# and @tag2con_Foo@ functions, as well as a
@maxtag_Foo@ variable, the later generated by @gen_tag_n_con_binds.

\begin{verbatim}
instance ... Enum (Foo ...) where
    succ x   = toEnum (1 + fromEnum x)
    pred x   = toEnum (fromEnum x - 1)

    toEnum i = tag2con_Foo i

    enumFrom a = map tag2con_Foo [dataToTag# a .. maxtag_Foo]

    -- or, really...
    enumFrom a
      = case dataToTag# a of
          a# -> map tag2con_Foo (enumFromTo (I# a#) maxtag_Foo)

   enumFromThen a b
     = map tag2con_Foo [dataToTag# a, dataToTag# b .. maxtag_Foo]

    -- or, really...
    enumFromThen a b
      = case dataToTag# a of { a# ->
        case dataToTag# b of { b# ->
        map tag2con_Foo (enumFromThenTo (I# a#) (I# b#) maxtag_Foo)
        }}
\end{verbatim}

For @enumFromTo@ and @enumFromThenTo@, we use the default methods.
-}

gen_Enum_binds :: SrcSpan -> DerivInstTys -> TcM (LHsBinds GhcPs, Bag AuxBindSpec)
gen_Enum_binds :: SrcSpan
-> DerivInstTys
-> TcM (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
gen_Enum_binds SrcSpan
loc (DerivInstTys{dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
tycon}) = do
    -- See Note [Auxiliary binders]
    tag2con_RDR <- SrcSpan -> TyCon -> TcM RdrName
new_tag2con_rdr_name SrcSpan
loc TyCon
tycon
    maxtag_RDR  <- new_maxtag_rdr_name  loc tycon

    return ( method_binds tag2con_RDR maxtag_RDR
           , aux_binds    tag2con_RDR maxtag_RDR )
  where
    method_binds :: RdrName
-> RdrName
-> [GenLocated
      SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
method_binds RdrName
tag2con_RDR RdrName
maxtag_RDR =
      [ RdrName -> RdrName -> LHsBind (GhcPass 'Parsed)
succ_enum      RdrName
tag2con_RDR RdrName
maxtag_RDR
      , RdrName -> LHsBind (GhcPass 'Parsed)
pred_enum      RdrName
tag2con_RDR
      , RdrName -> RdrName -> LHsBind (GhcPass 'Parsed)
to_enum        RdrName
tag2con_RDR RdrName
maxtag_RDR
      , RdrName -> RdrName -> LHsBind (GhcPass 'Parsed)
enum_from      RdrName
tag2con_RDR RdrName
maxtag_RDR -- [0 ..]
      , RdrName -> RdrName -> LHsBind (GhcPass 'Parsed)
enum_from_then RdrName
tag2con_RDR RdrName
maxtag_RDR -- [0, 1 ..]
      , LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
from_enum
      ]
    aux_binds :: RdrName -> RdrName -> Bag AuxBindSpec
aux_binds RdrName
tag2con_RDR RdrName
maxtag_RDR = [AuxBindSpec] -> Bag AuxBindSpec
forall a. [a] -> Bag a
listToBag
      [ TyCon -> RdrName -> AuxBindSpec
DerivTag2Con TyCon
tycon RdrName
tag2con_RDR
      , TyCon -> RdrName -> AuxBindSpec
DerivMaxTag  TyCon
tycon RdrName
maxtag_RDR
      ]

    occ_nm :: String
occ_nm = TyCon -> String
forall a. NamedThing a => a -> String
getOccString TyCon
tycon

    succ_enum :: RdrName -> RdrName -> LHsBind (GhcPass 'Parsed)
succ_enum RdrName
tag2con_RDR RdrName
maxtag_RDR
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
succ_RDR ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat]) (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR, RdrName
ah_RDR)] (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsIf (IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
eq_RDR [IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
maxtag_RDR,
                               IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
ah_RDR]])
             (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
succError_RDR) (HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (String -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). String -> HsLit (GhcPass p)
mkHsString String
occ_nm)))
             (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
tag2con_RDR)
                    (IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
plus_RDR [IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
ah_RDR],
                                        Integer -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). Integer -> LHsExpr (GhcPass p)
nlHsIntLit Integer
1]))

    pred_enum :: RdrName -> LHsBind (GhcPass 'Parsed)
pred_enum RdrName
tag2con_RDR
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
pred_RDR ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat]) (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR, RdrName
ah_RDR)] (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsIf (IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
eq_RDR [Integer -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). Integer -> LHsExpr (GhcPass p)
nlHsIntLit Integer
0,
                               IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
ah_RDR]])
             (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
predError_RDR) (HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (String -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). String -> HsLit (GhcPass p)
mkHsString String
occ_nm)))
             (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
tag2con_RDR)
                      (IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
plus_RDR
                            [ IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
ah_RDR]
                            , HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (XHsInt (GhcPass 'Parsed) -> IntegralLit -> HsLit (GhcPass 'Parsed)
forall x. XHsInt x -> IntegralLit -> HsLit x
HsInt XHsInt (GhcPass 'Parsed)
NoExtField
noExtField
                                                (Int -> IntegralLit
forall a. Integral a => a -> IntegralLit
mkIntegralLit (-Int
1 :: Int)))]))

    to_enum :: RdrName -> RdrName -> LHsBind (GhcPass 'Parsed)
to_enum RdrName
tag2con_RDR RdrName
maxtag_RDR
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
toEnum_RDR ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat]) (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        let to_word :: LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
to_word = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
enumIntToWord_RDR)
            -- cast to Word to check both bounds (0,maxtag) with one comparison
        in LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsIf (IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
le_RDR [ LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
to_word (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
a_RDR), LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
to_word (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
maxtag_RDR)])
             (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
tag2con_RDR [IdP (GhcPass 'Parsed)
RdrName
a_RDR])
             (IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
toEnumError_RDR
                       [ HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (String -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). String -> HsLit (GhcPass p)
mkHsString String
occ_nm)
                       , IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
a_RDR
                       , [LHsExpr (GhcPass 'Parsed)]
-> XExplicitTuple (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
[LHsExpr (GhcPass p)]
-> XExplicitTuple (GhcPass p) -> LHsExpr (GhcPass p)
mkLHsTupleExpr [Integer -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). Integer -> LHsExpr (GhcPass p)
nlHsIntLit Integer
0, IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
maxtag_RDR] (EpaLocation, EpaLocation)
XExplicitTuple (GhcPass 'Parsed)
forall a. NoAnn a => a
noAnn
                       ])


    enum_from :: RdrName -> RdrName -> LHsBind (GhcPass 'Parsed)
enum_from RdrName
tag2con_RDR RdrName
maxtag_RDR
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
enumFrom_RDR ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat]) (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR, RdrName
ah_RDR)] (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
map_RDR
                [IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
tag2con_RDR,
                 LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
enum_from_to_Expr
                            (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
ah_RDR])
                            (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
maxtag_RDR))]

    enum_from_then :: RdrName -> RdrName -> LHsBind (GhcPass 'Parsed)
enum_from_then RdrName
tag2con_RDR RdrName
maxtag_RDR
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
enumFromThen_RDR ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
b_Pat]) (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR, RdrName
ah_RDR), (RdrName
b_RDR, RdrName
bh_RDR)] (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
map_RDR [IdP (GhcPass 'Parsed)
RdrName
tag2con_RDR]) (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
            LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
enum_from_then_to_Expr
                    (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
ah_RDR])
                    (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
bh_RDR])
                    (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsIf  (IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
gt_RDR [IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
ah_RDR],
                                               IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
bh_RDR]])
                           (Integer -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). Integer -> LHsExpr (GhcPass p)
nlHsIntLit Integer
0)
                           (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
maxtag_RDR)
                           ))

    from_enum :: LHsBind (GhcPass 'Parsed)
from_enum
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
fromEnum_RDR ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat]) (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR, RdrName
ah_RDR)] (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
ah_RDR])

{-
************************************************************************
*                                                                      *
        Bounded instances
*                                                                      *
************************************************************************
-}

gen_Bounded_binds :: SrcSpan -> DerivInstTys -> (LHsBinds GhcPs, Bag AuxBindSpec)
gen_Bounded_binds :: SrcSpan
-> DerivInstTys -> (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
gen_Bounded_binds SrcSpan
loc (DerivInstTys{dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
tycon})
  | TyCon -> Bool
isEnumerationTyCon TyCon
tycon
  = ([ LHsBind (GhcPass 'Parsed)
min_bound_enum, LHsBind (GhcPass 'Parsed)
max_bound_enum ], Bag AuxBindSpec
forall a. Bag a
emptyBag)
  | Bool
otherwise
  = Bool
-> ([GenLocated
       SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))],
    Bag AuxBindSpec)
-> ([GenLocated
       SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))],
    Bag AuxBindSpec)
forall a. HasCallStack => Bool -> a -> a
assert ([DataCon] -> Bool
forall a. [a] -> Bool
isSingleton [DataCon]
data_cons)
    ([ LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
min_bound_1con, LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
max_bound_1con ], Bag AuxBindSpec
forall a. Bag a
emptyBag)
  where
    data_cons :: [DataCon]
data_cons = TyCon -> [DataCon]
tyConDataCons TyCon
tycon

    ----- enum-flavored: ---------------------------
    min_bound_enum :: LHsBind (GhcPass 'Parsed)
min_bound_enum = SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
minBound_RDR (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
data_con_1_RDR)
    max_bound_enum :: LHsBind (GhcPass 'Parsed)
max_bound_enum = SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
maxBound_RDR (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
data_con_N_RDR)

    data_con_1 :: DataCon
data_con_1     = [DataCon] -> DataCon
forall a. HasCallStack => [a] -> a
head [DataCon]
data_cons
    data_con_N :: DataCon
data_con_N     = [DataCon] -> DataCon
forall a. HasCallStack => [a] -> a
last [DataCon]
data_cons
    data_con_1_RDR :: RdrName
data_con_1_RDR = DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
data_con_1
    data_con_N_RDR :: RdrName
data_con_N_RDR = DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
data_con_N

    ----- single-constructor-flavored: -------------
    arity :: Int
arity          = DataCon -> Int
dataConSourceArity DataCon
data_con_1

    min_bound_1con :: LHsBind (GhcPass 'Parsed)
min_bound_1con = SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
minBound_RDR (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
                     IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
data_con_1_RDR (Int -> RdrName -> [RdrName]
forall a. Int -> a -> [a]
replicate Int
arity RdrName
minBound_RDR)
    max_bound_1con :: LHsBind (GhcPass 'Parsed)
max_bound_1con = SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
maxBound_RDR (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
                     IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
data_con_1_RDR (Int -> RdrName -> [RdrName]
forall a. Int -> a -> [a]
replicate Int
arity RdrName
maxBound_RDR)

{-
************************************************************************
*                                                                      *
        Ix instances
*                                                                      *
************************************************************************

Deriving @Ix@ is only possible for enumeration types and
single-constructor types.  We deal with them in turn.

For an enumeration type, e.g.,
\begin{verbatim}
    data Foo ... = N1 | N2 | ... | Nn
\end{verbatim}
things go not too differently from @Enum@:
\begin{verbatim}
instance ... Ix (Foo ...) where
    range (a, b)
      = map tag2con_Foo [dataToTag# a .. dataToTag# b]

    -- or, really...
    range (a, b)
      = case (dataToTag# a) of { a# ->
        case (dataToTag# b) of { b# ->
        map tag2con_Foo (enumFromTo (I# a#) (I# b#))
        }}

    -- Generate code for unsafeIndex, because using index leads
    -- to lots of redundant range tests
    unsafeIndex c@(a, b) d
      = case (dataToTag# d -# dataToTag# a) of
               r# -> I# r#

    inRange (a, b) c
      = let
            p_tag = dataToTag# c
        in
        p_tag >= dataToTag# a && p_tag <= dataToTag# b

    -- or, really...
    inRange (a, b) c
      = case (dataToTag# a)   of { a_tag ->
        case (dataToTag# b)   of { b_tag ->
        case (dataToTag# c)   of { c_tag ->
        if (c_tag >=# a_tag) then
          c_tag <=# b_tag
        else
          False
        }}}
\end{verbatim}
(modulo suitable case-ification to handle the unlifted tags)

For a single-constructor type (NB: this includes all tuples), e.g.,
\begin{verbatim}
    data Foo ... = MkFoo a b Int Double c c
\end{verbatim}
we follow the scheme given in Figure~19 of the Haskell~1.2 report
(p.~147).
-}

gen_Ix_binds :: SrcSpan -> DerivInstTys -> TcM (LHsBinds GhcPs, Bag AuxBindSpec)

gen_Ix_binds :: SrcSpan
-> DerivInstTys
-> TcM (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
gen_Ix_binds SrcSpan
loc (DerivInstTys{dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
tycon}) = do
    -- See Note [Auxiliary binders]
    tag2con_RDR <- SrcSpan -> TyCon -> TcM RdrName
new_tag2con_rdr_name SrcSpan
loc TyCon
tycon

    return $ if isEnumerationTyCon tycon
      then (enum_ixes tag2con_RDR, listToBag
                   [ DerivTag2Con tycon tag2con_RDR
                   ])
      else (single_con_ixes, emptyBag)
  where
    --------------------------------------------------------------
    enum_ixes :: RdrName
-> [GenLocated
      SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
enum_ixes RdrName
tag2con_RDR =
      [ RdrName -> LHsBind (GhcPass 'Parsed)
enum_range   RdrName
tag2con_RDR
      , LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
enum_index
      , LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
enum_inRange
      ]

    enum_range :: RdrName -> LHsBind (GhcPass 'Parsed)
enum_range RdrName
tag2con_RDR
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
range_RDR ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [[LPat (GhcPass 'Parsed)] -> Boxity -> LPat (GhcPass 'Parsed)
nlTuplePat [LPat (GhcPass 'Parsed)
a_Pat, LPat (GhcPass 'Parsed)
b_Pat] Boxity
Boxed]) (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR, RdrName
ah_RDR)] (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
b_RDR, RdrName
bh_RDR)] (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
map_RDR [IdP (GhcPass 'Parsed)
RdrName
tag2con_RDR]) (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
              LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
enum_from_to_Expr
                        (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
ah_RDR])
                        (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
bh_RDR]))

    enum_index :: LHsBind (GhcPass 'Parsed)
enum_index
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
unsafeIndex_RDR
                ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [Pat (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (XAsPat (GhcPass 'Parsed)
-> LIdP (GhcPass 'Parsed)
-> LPat (GhcPass 'Parsed)
-> Pat (GhcPass 'Parsed)
forall p. XAsPat p -> LIdP p -> LPat p -> Pat p
AsPat XAsPat (GhcPass 'Parsed)
EpToken "@"
forall a. NoAnn a => a
noAnn (RdrName -> GenLocated SrcSpanAnnN RdrName
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA RdrName
c_RDR)
                                  ([LPat (GhcPass 'Parsed)] -> Boxity -> LPat (GhcPass 'Parsed)
nlTuplePat [LPat (GhcPass 'Parsed)
a_Pat, LPat (GhcPass 'Parsed)
nlWildPat] Boxity
Boxed)),
                                       LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
d_Pat]) (
           [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR, RdrName
ah_RDR)] (
           [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
d_RDR, RdrName
dh_RDR)] (
           let
                rhs :: LHsExpr (GhcPass 'Parsed)
rhs = IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR [IdP (GhcPass 'Parsed)
RdrName
c_RDR]
           in
           LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase
             (LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genOpApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
dh_RDR) RdrName
minusInt_RDR (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
ah_RDR))
             [LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
c_RDR) LocatedA (HsExpr (GhcPass 'Parsed))
rhs]
           ))
        )

    -- This produces something like `(ch >= ah) && (ch <= bh)`
    enum_inRange :: LHsBind (GhcPass 'Parsed)
enum_inRange
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
inRange_RDR ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [[LPat (GhcPass 'Parsed)] -> Boxity -> LPat (GhcPass 'Parsed)
nlTuplePat [LPat (GhcPass 'Parsed)
a_Pat, LPat (GhcPass 'Parsed)
b_Pat] Boxity
Boxed, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
c_Pat]) (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
a_RDR, RdrName
ah_RDR)] (
          [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
b_RDR, RdrName
bh_RDR)] (
          [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName
c_RDR, RdrName
ch_RDR)] (
          -- This used to use `if`, which interacts badly with RebindableSyntax.
          -- See #11396.
          IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
and_RDR
              [ LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genPrimOpApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
ch_RDR) RdrName
geInt_RDR (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
ah_RDR)
              , LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genPrimOpApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
ch_RDR) RdrName
leInt_RDR (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
bh_RDR)
              ]
          )))

    --------------------------------------------------------------
    single_con_ixes :: [GenLocated
   SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
single_con_ixes
      = [LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
single_con_range, LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
single_con_index, LHsBind (GhcPass 'Parsed)
GenLocated
  SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
single_con_inRange]

    data_con :: DataCon
data_con
      = case TyCon -> Maybe DataCon
tyConSingleDataCon_maybe TyCon
tycon of -- just checking...
          Maybe DataCon
Nothing -> String -> DataCon
forall a. HasCallStack => String -> a
panic String
"get_Ix_binds"
          Just DataCon
dc -> DataCon
dc

    con_arity :: Int
con_arity    = DataCon -> Int
dataConSourceArity DataCon
data_con
    data_con_RDR :: RdrName
data_con_RDR = DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
data_con

    as_needed :: [RdrName]
as_needed = Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take Int
con_arity [RdrName]
as_RDRs
    bs_needed :: [RdrName]
bs_needed = Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take Int
con_arity [RdrName]
bs_RDRs
    cs_needed :: [RdrName]
cs_needed = Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take Int
con_arity [RdrName]
cs_RDRs

    con_pat :: [RdrName] -> LPat (GhcPass 'Parsed)
con_pat  [RdrName]
xs  = RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
data_con_RDR [RdrName]
xs
    con_expr :: LHsExpr (GhcPass 'Parsed)
con_expr     = IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
data_con_RDR [IdP (GhcPass 'Parsed)]
[RdrName]
cs_needed

    --------------------------------------------------------------
    single_con_range :: LHsBind (GhcPass 'Parsed)
single_con_range
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
range_RDR
          ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [[LPat (GhcPass 'Parsed)] -> Boxity -> LPat (GhcPass 'Parsed)
nlTuplePat [[RdrName] -> LPat (GhcPass 'Parsed)
con_pat [RdrName]
as_needed, [RdrName] -> LPat (GhcPass 'Parsed)
con_pat [RdrName]
bs_needed] Boxity
Boxed]) (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
        HsExpr (GhcPass 'Parsed) -> LocatedA (HsExpr (GhcPass 'Parsed))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (HsDoFlavour
-> [ExprLStmt (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> HsExpr (GhcPass 'Parsed)
mkHsComp HsDoFlavour
ListComp [ExprLStmt (GhcPass 'Parsed)]
[GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
stmts LHsExpr (GhcPass 'Parsed)
con_expr)
      where
        stmts :: [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
stmts = String
-> (RdrName
    -> RdrName
    -> RdrName
    -> GenLocated
         SrcSpanAnnA
         (StmtLR
            (GhcPass 'Parsed)
            (GhcPass 'Parsed)
            (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> [RdrName]
-> [RdrName]
-> [RdrName]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a b c d.
HasDebugCallStack =>
String -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3Equal String
"single_con_range" RdrName
-> RdrName
-> RdrName
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e}.
HasAnnotation e =>
RdrName
-> RdrName
-> RdrName
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
mk_qual [RdrName]
as_needed [RdrName]
bs_needed [RdrName]
cs_needed

        mk_qual :: RdrName
-> RdrName
-> RdrName
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
mk_qual RdrName
a RdrName
b RdrName
c = StmtLR
  (GhcPass 'Parsed)
  (GhcPass 'Parsed)
  (LocatedA (HsExpr (GhcPass 'Parsed)))
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (StmtLR
   (GhcPass 'Parsed)
   (GhcPass 'Parsed)
   (LocatedA (HsExpr (GhcPass 'Parsed)))
 -> GenLocated
      e
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed)))
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall a b. (a -> b) -> a -> b
$ EpUniToken "<-" "\8592"
-> LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (bodyR :: * -> *).
EpUniToken "<-" "\8592"
-> LPat (GhcPass 'Parsed)
-> LocatedA (bodyR (GhcPass 'Parsed))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (bodyR (GhcPass 'Parsed)))
mkPsBindStmt EpUniToken "<-" "\8592"
forall a. NoAnn a => a
noAnn (IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
c)
                                 (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
range_RDR)
                                          ([IdP (GhcPass 'Parsed)]
-> XExplicitTuple (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
[IdP (GhcPass p)]
-> XExplicitTuple (GhcPass p) -> LHsExpr (GhcPass p)
mkLHsVarTuple [IdP (GhcPass 'Parsed)
RdrName
a,IdP (GhcPass 'Parsed)
RdrName
b] (EpaLocation, EpaLocation)
XExplicitTuple (GhcPass 'Parsed)
forall a. NoAnn a => a
noAnn))

    ----------------
    single_con_index :: LHsBind (GhcPass 'Parsed)
single_con_index
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
unsafeIndex_RDR
                ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [[LPat (GhcPass 'Parsed)] -> Boxity -> LPat (GhcPass 'Parsed)
nlTuplePat [[RdrName] -> LPat (GhcPass 'Parsed)
con_pat [RdrName]
as_needed, [RdrName] -> LPat (GhcPass 'Parsed)
con_pat [RdrName]
bs_needed] Boxity
Boxed,
                        [RdrName] -> LPat (GhcPass 'Parsed)
con_pat [RdrName]
cs_needed])
        -- We need to reverse the order we consider the components in
        -- so that
        --     range (l,u) !! index (l,u) i == i   -- when i is in range
        -- (from http://haskell.org/onlinereport/ix.html) holds.
                ([(RdrName, RdrName, RdrName)]
-> LocatedA (HsExpr (GhcPass 'Parsed))
mk_index ([(RdrName, RdrName, RdrName)] -> [(RdrName, RdrName, RdrName)]
forall a. [a] -> [a]
reverse ([(RdrName, RdrName, RdrName)] -> [(RdrName, RdrName, RdrName)])
-> [(RdrName, RdrName, RdrName)] -> [(RdrName, RdrName, RdrName)]
forall a b. (a -> b) -> a -> b
$ [RdrName]
-> [RdrName] -> [RdrName] -> [(RdrName, RdrName, RdrName)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [RdrName]
as_needed [RdrName]
bs_needed [RdrName]
cs_needed))
      where
        -- index (l1,u1) i1 + rangeSize (l1,u1) * (index (l2,u2) i2 + ...)
        mk_index :: [(RdrName, RdrName, RdrName)]
-> LocatedA (HsExpr (GhcPass 'Parsed))
mk_index []        = Integer -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). Integer -> LHsExpr (GhcPass p)
nlHsIntLit Integer
0
        mk_index [(RdrName
l,RdrName
u,RdrName
i)] = RdrName
-> RdrName -> RdrName -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {p :: Pass}.
(IdGhcP p ~ RdrName, NoAnn (XExplicitTuple (GhcPass p)),
 IsPass p) =>
RdrName
-> RdrName
-> RdrName
-> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
mk_one RdrName
l RdrName
u RdrName
i
        mk_index ((RdrName
l,RdrName
u,RdrName
i) : [(RdrName, RdrName, RdrName)]
rest)
          = LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genOpApp (
                RdrName
-> RdrName -> RdrName -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {p :: Pass}.
(IdGhcP p ~ RdrName, NoAnn (XExplicitTuple (GhcPass p)),
 IsPass p) =>
RdrName
-> RdrName
-> RdrName
-> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
mk_one RdrName
l RdrName
u RdrName
i
            ) RdrName
plus_RDR (
                LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genOpApp (
                    (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
unsafeRangeSize_RDR)
                             ([IdP (GhcPass 'Parsed)]
-> XExplicitTuple (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
[IdP (GhcPass p)]
-> XExplicitTuple (GhcPass p) -> LHsExpr (GhcPass p)
mkLHsVarTuple [IdP (GhcPass 'Parsed)
RdrName
l,IdP (GhcPass 'Parsed)
RdrName
u] (EpaLocation, EpaLocation)
XExplicitTuple (GhcPass 'Parsed)
forall a. NoAnn a => a
noAnn))
                ) RdrName
times_RDR ([(RdrName, RdrName, RdrName)]
-> LocatedA (HsExpr (GhcPass 'Parsed))
mk_index [(RdrName, RdrName, RdrName)]
rest)
           )
        mk_one :: RdrName -> RdrName -> RdrName -> LHsExpr (GhcPass p)
mk_one RdrName
l RdrName
u RdrName
i
          = IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass p)
RdrName
unsafeIndex_RDR [[IdP (GhcPass p)]
-> XExplicitTuple (GhcPass p) -> LHsExpr (GhcPass p)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
[IdP (GhcPass p)]
-> XExplicitTuple (GhcPass p) -> LHsExpr (GhcPass p)
mkLHsVarTuple [IdP (GhcPass p)
RdrName
l,IdP (GhcPass p)
RdrName
u] XExplicitTuple (GhcPass p)
forall a. NoAnn a => a
noAnn, IdP (GhcPass p) -> LHsExpr (GhcPass p)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass p)
RdrName
i]

    ------------------
    single_con_inRange :: LHsBind (GhcPass 'Parsed)
single_con_inRange
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
inRange_RDR
                ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [[LPat (GhcPass 'Parsed)] -> Boxity -> LPat (GhcPass 'Parsed)
nlTuplePat [[RdrName] -> LPat (GhcPass 'Parsed)
con_pat [RdrName]
as_needed, [RdrName] -> LPat (GhcPass 'Parsed)
con_pat [RdrName]
bs_needed] Boxity
Boxed,
                         [RdrName] -> LPat (GhcPass 'Parsed)
con_pat [RdrName]
cs_needed]) (LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsBind (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          if Int
con_arity Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
             -- If the product type has no fields, inRange is trivially true
             -- (see #12853).
             then LHsExpr (GhcPass 'Parsed)
true_Expr
             else (LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
and_Expr (String
-> (RdrName
    -> RdrName -> RdrName -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [RdrName]
-> [RdrName]
-> [RdrName]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a b c d.
HasDebugCallStack =>
String -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3Equal String
"single_con_inRange" RdrName
-> RdrName -> RdrName -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {p :: Pass}.
(IdGhcP p ~ RdrName, NoAnn (XExplicitTuple (GhcPass p)),
 IsPass p) =>
RdrName
-> RdrName
-> RdrName
-> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
in_range
                    [RdrName]
as_needed [RdrName]
bs_needed [RdrName]
cs_needed)
      where
        in_range :: RdrName -> RdrName -> RdrName -> LHsExpr (GhcPass p)
in_range RdrName
a RdrName
b RdrName
c
          = IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass p)
RdrName
inRange_RDR [[IdP (GhcPass p)]
-> XExplicitTuple (GhcPass p) -> LHsExpr (GhcPass p)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
[IdP (GhcPass p)]
-> XExplicitTuple (GhcPass p) -> LHsExpr (GhcPass p)
mkLHsVarTuple [IdP (GhcPass p)
RdrName
a,IdP (GhcPass p)
RdrName
b] XExplicitTuple (GhcPass p)
forall a. NoAnn a => a
noAnn, IdP (GhcPass p) -> LHsExpr (GhcPass p)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass p)
RdrName
c]

{-
************************************************************************
*                                                                      *
        Read instances
*                                                                      *
************************************************************************

Example

  infix 4 %%
  data T = Int %% Int
         | T1 { f1 :: Int }
         | T2 T

instance Read T where
  readPrec =
    parens
    ( prec 4 (
        do x <- ReadP.step Read.readPrec
           expectP (Symbol "%%")
           y <- ReadP.step Read.readPrec
           return (x %% y))
      +++
      prec (appPrec+1) (
        -- Note the "+1" part; "T2 T1 {f1=3}" should parse ok
        -- Record construction binds even more tightly than application
        do expectP (Ident "T1")
           expectP (Punc '{')
           x          <- Read.readField "f1" (ReadP.reset readPrec)
           expectP (Punc '}')
           return (T1 { f1 = x }))
      +++
      prec appPrec (
        do expectP (Ident "T2")
           x <- ReadP.step Read.readPrec
           return (T2 x))
    )

  readListPrec = readListPrecDefault
  readList     = readListDefault


Note [Use expectP]
~~~~~~~~~~~~~~~~~~
Note that we use
   expectP (Ident "T1")
rather than
   Ident "T1" <- lexP
The latter desugares to inline code for matching the Ident and the
string, and this can be very voluminous. The former is much more
compact.  Cf #7258, although that also concerned non-linearity in
the occurrence analyser, a separate issue.

Note [Read for empty data types]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
What should we get for this?  (#7931)
   data Emp deriving( Read )   -- No data constructors

Here we want
  read "[]" :: [Emp]   to succeed, returning []
So we do NOT want
   instance Read Emp where
     readPrec = error "urk"
Rather we want
   instance Read Emp where
     readPred = pfail   -- Same as choose []

Because 'pfail' allows the parser to backtrack, but 'error' doesn't.
These instances are also useful for Read (Either Int Emp), where
we want to be able to parse (Left 3) just fine.
-}

gen_Read_binds :: (Name -> Fixity) -> SrcSpan -> DerivInstTys
               -> (LHsBinds GhcPs, Bag AuxBindSpec)

gen_Read_binds :: (Name -> Fixity)
-> SrcSpan
-> DerivInstTys
-> (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
gen_Read_binds Name -> Fixity
get_fixity SrcSpan
loc dit :: DerivInstTys
dit@(DerivInstTys{dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
tycon})
  = ([LHsBind (GhcPass 'Parsed)
read_prec, LHsBind (GhcPass 'Parsed)
default_readlist, LHsBind (GhcPass 'Parsed)
default_readlistprec], Bag AuxBindSpec
forall a. Bag a
emptyBag)
  where
    -----------------------------------------------------------------------
    default_readlist :: LHsBind (GhcPass 'Parsed)
default_readlist
        = SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
readList_RDR     (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
readListDefault_RDR)

    default_readlistprec :: LHsBind (GhcPass 'Parsed)
default_readlistprec
        = SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
readListPrec_RDR (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
readListPrecDefault_RDR)
    -----------------------------------------------------------------------

    data_cons :: [DataCon]
data_cons = TyCon -> [DataCon]
tyConDataCons TyCon
tycon
    ([DataCon]
nullary_cons, [DataCon]
non_nullary_cons) = (DataCon -> Bool) -> [DataCon] -> ([DataCon], [DataCon])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition DataCon -> Bool
isNullarySrcDataCon [DataCon]
data_cons

    read_prec :: LHsBind (GhcPass 'Parsed)
read_prec = SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
readPrec_RDR LHsExpr (GhcPass 'Parsed)
rhs
      where
        rhs :: LHsExpr (GhcPass 'Parsed)
rhs | [DataCon] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [DataCon]
data_cons -- See Note [Read for empty data types]
            = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
pfail_RDR
            | Bool
otherwise
            = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
parens_RDR)
                      ((LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
mk_alt ([LocatedA (HsExpr (GhcPass 'Parsed))]
read_nullary_cons [LocatedA (HsExpr (GhcPass 'Parsed))]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a. [a] -> [a] -> [a]
++
                                      [LocatedA (HsExpr (GhcPass 'Parsed))]
read_non_nullary_cons))

    read_non_nullary_cons :: [LocatedA (HsExpr (GhcPass 'Parsed))]
read_non_nullary_cons = (DataCon -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [DataCon] -> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a b. (a -> b) -> [a] -> [b]
map DataCon -> LocatedA (HsExpr (GhcPass 'Parsed))
read_non_nullary_con [DataCon]
non_nullary_cons

    read_nullary_cons :: [LocatedA (HsExpr (GhcPass 'Parsed))]
read_nullary_cons
      = case [DataCon]
nullary_cons of
            []    -> []
            [DataCon
con] -> [HsDoFlavour
-> [ExprLStmt (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
nlHsDo (Maybe ModuleName -> HsDoFlavour
DoExpr Maybe ModuleName
forall a. Maybe a
Nothing) (DataCon
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall {a} {e} {idL :: Pass}.
(NamedThing a, HasAnnotation e) =>
a
-> [GenLocated
      e
      (StmtLR
         (GhcPass idL)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
match_con DataCon
con [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ [StmtLR
  (GhcPass 'Parsed)
  (GhcPass 'Parsed)
  (LocatedA (HsExpr (GhcPass 'Parsed)))
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (StmtLR
   (GhcPass 'Parsed)
   (GhcPass 'Parsed)
   (LocatedA (HsExpr (GhcPass 'Parsed)))
 -> GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed)))
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall a b. (a -> b) -> a -> b
$ LocatedA (HsExpr (GhcPass 'Parsed))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (idR :: Pass) (bodyR :: * -> *) (idL :: Pass).
IsPass idR =>
LocatedA (bodyR (GhcPass idR))
-> StmtLR
     (GhcPass idL) (GhcPass idR) (LocatedA (bodyR (GhcPass idR)))
mkLastStmt (DataCon -> [RdrName] -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {id :: Pass} {thing}.
(IdGhcP id ~ RdrName, NamedThing thing, IsPass id) =>
thing -> [RdrName] -> GenLocated SrcSpanAnnA (HsExpr (GhcPass id))
result_expr DataCon
con [])])]
            [DataCon]
_     -> [LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
choose_RDR)
                              ([LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
nlList ((DataCon -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [DataCon] -> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a b. (a -> b) -> [a] -> [b]
map DataCon -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {p :: Pass} {thing}.
(IdGhcP p ~ RdrName, NamedThing thing,
 NoAnn (XExplicitTuple (GhcPass p)), IsPass p) =>
thing -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
mk_pair [DataCon]
nullary_cons))]
        -- NB For operators the parens around (:=:) are matched by the
        -- enclosing "parens" call, so here we must match the naked
        -- data_con_str con

    match_con :: a
-> [GenLocated
      e
      (StmtLR
         (GhcPass idL)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
match_con a
con | String -> Bool
isSym String
con_str = [String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
symbol_pat String
con_str]
                  | Bool
otherwise     = String
-> [GenLocated
      e
      (StmtLR
         (GhcPass idL)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> [GenLocated
      e
      (StmtLR
         (GhcPass idL)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
ident_h_pat  String
con_str
                  where
                    con_str :: String
con_str = a -> String
forall a. NamedThing a => a -> String
data_con_str a
con
        -- For nullary constructors we must match Ident s for normal constrs
        -- and   Symbol s   for operators

    mk_pair :: thing -> LHsExpr (GhcPass p)
mk_pair thing
con = [LHsExpr (GhcPass p)]
-> XExplicitTuple (GhcPass p) -> LHsExpr (GhcPass p)
forall (p :: Pass).
[LHsExpr (GhcPass p)]
-> XExplicitTuple (GhcPass p) -> LHsExpr (GhcPass p)
mkLHsTupleExpr [HsLit (GhcPass p) -> LHsExpr (GhcPass p)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (String -> HsLit (GhcPass p)
forall (p :: Pass). String -> HsLit (GhcPass p)
mkHsString (thing -> String
forall a. NamedThing a => a -> String
data_con_str thing
con)),
                                  thing -> [RdrName] -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
forall {id :: Pass} {thing}.
(IdGhcP id ~ RdrName, NamedThing thing, IsPass id) =>
thing -> [RdrName] -> GenLocated SrcSpanAnnA (HsExpr (GhcPass id))
result_expr thing
con []] XExplicitTuple (GhcPass p)
forall a. NoAnn a => a
noAnn

    read_non_nullary_con :: DataCon -> LocatedA (HsExpr (GhcPass 'Parsed))
read_non_nullary_con DataCon
data_con
      | Bool
is_infix  = Integer
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
mk_parser Integer
infix_prec  [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
infix_stmts  LocatedA (HsExpr (GhcPass 'Parsed))
body
      | Bool
is_record = Integer
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
mk_parser Integer
record_prec [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
record_stmts LocatedA (HsExpr (GhcPass 'Parsed))
body
--              Using these two lines instead allows the derived
--              read for infix and record bindings to read the prefix form
--      | is_infix  = mk_alt prefix_parser (mk_parser infix_prec  infix_stmts  body)
--      | is_record = mk_alt prefix_parser (mk_parser record_prec record_stmts body)
      | Bool
otherwise = LocatedA (HsExpr (GhcPass 'Parsed))
prefix_parser
      where
        body :: LocatedA (HsExpr (GhcPass 'Parsed))
body = DataCon -> [RdrName] -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {id :: Pass} {thing}.
(IdGhcP id ~ RdrName, NamedThing thing, IsPass id) =>
thing -> [RdrName] -> GenLocated SrcSpanAnnA (HsExpr (GhcPass id))
result_expr DataCon
data_con [RdrName]
as_needed
        con_str :: String
con_str = DataCon -> String
forall a. NamedThing a => a -> String
data_con_str DataCon
data_con

        prefix_parser :: LocatedA (HsExpr (GhcPass 'Parsed))
prefix_parser = Integer
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
mk_parser Integer
prefix_prec [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
prefix_stmts LocatedA (HsExpr (GhcPass 'Parsed))
body

        read_prefix_con :: [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
read_prefix_con
            | String -> Bool
isSym String
con_str = [String
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
read_punc String
"(", String
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
symbol_pat String
con_str, String
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
read_punc String
")"]
            | Bool
otherwise     = String
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> [GenLocated
      e
      (StmtLR
         (GhcPass idL)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
ident_h_pat String
con_str

        read_infix_con :: [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
read_infix_con
            | String -> Bool
isSym String
con_str = [String
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
symbol_pat String
con_str]
            | Bool
otherwise     = [String
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
read_punc String
"`"] [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ String
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> [GenLocated
      e
      (StmtLR
         (GhcPass idL)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
ident_h_pat String
con_str [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ [String
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
read_punc String
"`"]

        prefix_stmts :: [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
prefix_stmts            -- T a b c
          = [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
read_prefix_con [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
read_args

        infix_stmts :: [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
infix_stmts             -- a %% b, or  a `T` b
          = [GenLocated
  SrcSpanAnnA
  (StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed))))
read_a1]
            [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
read_infix_con
            [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ [GenLocated
  SrcSpanAnnA
  (StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed))))
read_a2]

        record_stmts :: [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
record_stmts            -- T { f1 = a, f2 = b }
          = [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
read_prefix_con
            [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ [String
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
read_punc String
"{"]
            [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ [[GenLocated
    SrcSpanAnnA
    (StmtLR
       (GhcPass 'Parsed)
       (GhcPass 'Parsed)
       (LocatedA (HsExpr (GhcPass 'Parsed))))]]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [[GenLocated
       SrcSpanAnnA
       (StmtLR
          (GhcPass 'Parsed)
          (GhcPass 'Parsed)
          (LocatedA (HsExpr (GhcPass 'Parsed))))]]
-> [[GenLocated
       SrcSpanAnnA
       (StmtLR
          (GhcPass 'Parsed)
          (GhcPass 'Parsed)
          (LocatedA (HsExpr (GhcPass 'Parsed))))]]
forall a. a -> [a] -> [a]
intersperse [String
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
read_punc String
","] [[GenLocated
    SrcSpanAnnA
    (StmtLR
       (GhcPass 'Parsed)
       (GhcPass 'Parsed)
       (LocatedA (HsExpr (GhcPass 'Parsed))))]]
field_stmts)
            [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ [String
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
read_punc String
"}"]

        field_stmts :: [[GenLocated
    SrcSpanAnnA
    (StmtLR
       (GhcPass 'Parsed)
       (GhcPass 'Parsed)
       (LocatedA (HsExpr (GhcPass 'Parsed))))]]
field_stmts  = String
-> (FastString
    -> RdrName
    -> [GenLocated
          SrcSpanAnnA
          (StmtLR
             (GhcPass 'Parsed)
             (GhcPass 'Parsed)
             (LocatedA (HsExpr (GhcPass 'Parsed))))])
-> [FastString]
-> [RdrName]
-> [[GenLocated
       SrcSpanAnnA
       (StmtLR
          (GhcPass 'Parsed)
          (GhcPass 'Parsed)
          (LocatedA (HsExpr (GhcPass 'Parsed))))]]
forall a b c.
HasDebugCallStack =>
String -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithEqual String
"lbl_stmts" FastString
-> RdrName
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall {e}.
HasAnnotation e =>
FastString
-> RdrName
-> [GenLocated
      e
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
read_field [FastString]
labels [RdrName]
as_needed

        con_arity :: Int
con_arity    = DataCon -> Int
dataConSourceArity DataCon
data_con
        labels :: [FastString]
labels       = (FieldLabel -> FastString) -> [FieldLabel] -> [FastString]
forall a b. (a -> b) -> [a] -> [b]
map (FieldLabelString -> FastString
field_label (FieldLabelString -> FastString)
-> (FieldLabel -> FieldLabelString) -> FieldLabel -> FastString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldLabel -> FieldLabelString
flLabel) ([FieldLabel] -> [FastString]) -> [FieldLabel] -> [FastString]
forall a b. (a -> b) -> a -> b
$ DataCon -> [FieldLabel]
dataConFieldLabels DataCon
data_con
        dc_nm :: Name
dc_nm        = DataCon -> Name
forall a. NamedThing a => a -> Name
getName DataCon
data_con
        is_infix :: Bool
is_infix     = DataCon -> Bool
dataConIsInfix DataCon
data_con
        is_record :: Bool
is_record    = [FastString]
labels [FastString] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthExceeds` Int
0
        as_needed :: [RdrName]
as_needed    = Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take Int
con_arity [RdrName]
as_RDRs
        read_args :: [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
read_args    = String
-> (RdrName
    -> Type
    -> GenLocated
         SrcSpanAnnA
         (StmtLR
            (GhcPass 'Parsed)
            (GhcPass 'Parsed)
            (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> [RdrName]
-> [Type]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a b c.
HasDebugCallStack =>
String -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithEqual String
"gen_Read_binds" RdrName
-> Type
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e}.
HasAnnotation e =>
RdrName
-> Type
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
read_arg [RdrName]
as_needed (DataCon -> DerivInstTys -> [Type]
derivDataConInstArgTys DataCon
data_con DerivInstTys
dit)
        (GenLocated
  SrcSpanAnnA
  (StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed))))
read_a1:GenLocated
  SrcSpanAnnA
  (StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed))))
read_a2:[GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
_) = [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
read_args

        prefix_prec :: Integer
prefix_prec = Integer
appPrecedence
        infix_prec :: Integer
infix_prec  = (Name -> Fixity) -> Name -> Integer
getPrecedence Name -> Fixity
get_fixity Name
dc_nm
        record_prec :: Integer
record_prec = Integer
appPrecedence Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1 -- Record construction binds even more tightly
                                        -- than application; e.g. T2 T1 {x=2} means T2 (T1 {x=2})

    ------------------------------------------------------------------------
    --          Helpers
    ------------------------------------------------------------------------
    mk_alt :: LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed)) -> LHsExpr (GhcPass 'Parsed)
mk_alt LocatedA (HsExpr (GhcPass 'Parsed))
e1 LocatedA (HsExpr (GhcPass 'Parsed))
e2       = LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genOpApp LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
e1 RdrName
alt_RDR LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
e2                         -- e1 +++ e2
    mk_parser :: Integer
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed)
mk_parser Integer
p [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
ss LocatedA (HsExpr (GhcPass 'Parsed))
b   = IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
prec_RDR [Integer -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). Integer -> LHsExpr (GhcPass p)
nlHsIntLit Integer
p                -- prec p (do { ss ; b })
                                           , HsDoFlavour
-> [ExprLStmt (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
nlHsDo (Maybe ModuleName -> HsDoFlavour
DoExpr Maybe ModuleName
forall a. Maybe a
Nothing) ([GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
ss [GenLocated
   SrcSpanAnnA
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> [GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a. [a] -> [a] -> [a]
++ [StmtLR
  (GhcPass 'Parsed)
  (GhcPass 'Parsed)
  (LocatedA (HsExpr (GhcPass 'Parsed)))
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (StmtLR
   (GhcPass 'Parsed)
   (GhcPass 'Parsed)
   (LocatedA (HsExpr (GhcPass 'Parsed)))
 -> GenLocated
      SrcSpanAnnA
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed)))
-> GenLocated
     SrcSpanAnnA
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall a b. (a -> b) -> a -> b
$ LocatedA (HsExpr (GhcPass 'Parsed))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (idR :: Pass) (bodyR :: * -> *) (idL :: Pass).
IsPass idR =>
LocatedA (bodyR (GhcPass idR))
-> StmtLR
     (GhcPass idL) (GhcPass idR) (LocatedA (bodyR (GhcPass idR)))
mkLastStmt LocatedA (HsExpr (GhcPass 'Parsed))
b])]
    con_app :: thing -> [RdrName] -> LHsExpr (GhcPass p)
con_app thing
con [RdrName]
as     = IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps (thing -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName thing
con) [IdP (GhcPass p)]
[RdrName]
as                -- con as
    result_expr :: thing -> [RdrName] -> LHsExpr (GhcPass id)
result_expr thing
con [RdrName]
as = LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass id) -> LHsExpr (GhcPass id)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass id)
RdrName
returnM_RDR) (thing -> [RdrName] -> GenLocated SrcSpanAnnA (HsExpr (GhcPass id))
forall {id :: Pass} {thing}.
(IdGhcP id ~ RdrName, NamedThing thing, IsPass id) =>
thing -> [RdrName] -> GenLocated SrcSpanAnnA (HsExpr (GhcPass id))
con_app thing
con [RdrName]
as) -- return (con as)

    -- For constructors and field labels ending in '#', we hackily
    -- let the lexer generate two tokens, and look for both in sequence
    -- Thus [Ident "I"; Symbol "#"].  See #5041
    ident_h_pat :: String
-> [GenLocated
      e
      (StmtLR
         (GhcPass idL)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
ident_h_pat String
s | Just (String
ss, Char
'#') <- String -> Maybe (String, Char)
forall a. [a] -> Maybe ([a], a)
snocView String
s = [ String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
ident_pat String
ss, String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
symbol_pat String
"#" ]
                  | Bool
otherwise                    = [ String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
ident_pat String
s ]

    bindLex :: LocatedA (HsExpr (GhcPass 'Parsed))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
bindLex LocatedA (HsExpr (GhcPass 'Parsed))
pat  = StmtLR
  (GhcPass idL)
  (GhcPass 'Parsed)
  (LocatedA (HsExpr (GhcPass 'Parsed)))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (LocatedA (HsExpr (GhcPass 'Parsed))
-> StmtLR
     (GhcPass idL)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (bodyR :: * -> *) (idL :: Pass).
LocatedA (bodyR (GhcPass 'Parsed))
-> StmtLR
     (GhcPass idL)
     (GhcPass 'Parsed)
     (LocatedA (bodyR (GhcPass 'Parsed)))
mkBodyStmt (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
expectP_RDR) LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
pat)) -- expectP p
                   -- See Note [Use expectP]
    ident_pat :: String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
ident_pat  String
s = LocatedA (HsExpr (GhcPass 'Parsed))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
LocatedA (HsExpr (GhcPass 'Parsed))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
bindLex (LocatedA (HsExpr (GhcPass 'Parsed))
 -> GenLocated
      e
      (StmtLR
         (GhcPass idL)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall a b. (a -> b) -> a -> b
$ IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
ident_RDR  [HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (String -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). String -> HsLit (GhcPass p)
mkHsString String
s)]  -- expectP (Ident "foo")
    symbol_pat :: String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
symbol_pat String
s = LocatedA (HsExpr (GhcPass 'Parsed))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
LocatedA (HsExpr (GhcPass 'Parsed))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
bindLex (LocatedA (HsExpr (GhcPass 'Parsed))
 -> GenLocated
      e
      (StmtLR
         (GhcPass idL)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall a b. (a -> b) -> a -> b
$ IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
symbol_RDR [HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (String -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). String -> HsLit (GhcPass p)
mkHsString String
s)]  -- expectP (Symbol ">>")
    read_punc :: String
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
read_punc String
c  = LocatedA (HsExpr (GhcPass 'Parsed))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall {e} {idL :: Pass}.
HasAnnotation e =>
LocatedA (HsExpr (GhcPass 'Parsed))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
bindLex (LocatedA (HsExpr (GhcPass 'Parsed))
 -> GenLocated
      e
      (StmtLR
         (GhcPass idL)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> GenLocated
     e
     (StmtLR
        (GhcPass idL)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall a b. (a -> b) -> a -> b
$ IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
punc_RDR   [HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (String -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). String -> HsLit (GhcPass p)
mkHsString String
c)]  -- expectP (Punc "<")

    data_con_str :: a -> String
data_con_str a
con = OccName -> String
occNameString (a -> OccName
forall a. NamedThing a => a -> OccName
getOccName a
con)

    read_arg :: RdrName
-> Type
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
read_arg RdrName
a Type
ty = Bool
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall a. HasCallStack => Bool -> a -> a
assert (Bool -> Bool
not (HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType Type
ty)) (GenLocated
   e
   (StmtLR
      (GhcPass 'Parsed)
      (GhcPass 'Parsed)
      (LocatedA (HsExpr (GhcPass 'Parsed))))
 -> GenLocated
      e
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall a b. (a -> b) -> a -> b
$
                    StmtLR
  (GhcPass 'Parsed)
  (GhcPass 'Parsed)
  (LocatedA (HsExpr (GhcPass 'Parsed)))
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (EpUniToken "<-" "\8592"
-> LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (bodyR :: * -> *).
EpUniToken "<-" "\8592"
-> LPat (GhcPass 'Parsed)
-> LocatedA (bodyR (GhcPass 'Parsed))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (bodyR (GhcPass 'Parsed)))
mkPsBindStmt EpUniToken "<-" "\8592"
forall a. NoAnn a => a
noAnn (IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
a) (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
step_RDR [IdP (GhcPass 'Parsed)
RdrName
readPrec_RDR]))

    -- When reading field labels we might encounter
    --      a  = 3
    --      _a = 3
    -- or   (#) = 4
    -- Note the parens!
    read_field :: FastString
-> RdrName
-> [GenLocated
      e
      (StmtLR
         (GhcPass 'Parsed)
         (GhcPass 'Parsed)
         (LocatedA (HsExpr (GhcPass 'Parsed))))]
read_field FastString
lbl RdrName
a =
        [StmtLR
  (GhcPass 'Parsed)
  (GhcPass 'Parsed)
  (LocatedA (HsExpr (GhcPass 'Parsed)))
-> GenLocated
     e
     (StmtLR
        (GhcPass 'Parsed)
        (GhcPass 'Parsed)
        (LocatedA (HsExpr (GhcPass 'Parsed))))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA
          (EpUniToken "<-" "\8592"
-> LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (bodyR :: * -> *).
EpUniToken "<-" "\8592"
-> LPat (GhcPass 'Parsed)
-> LocatedA (bodyR (GhcPass 'Parsed))
-> StmtLR
     (GhcPass 'Parsed)
     (GhcPass 'Parsed)
     (LocatedA (bodyR (GhcPass 'Parsed)))
mkPsBindStmt EpUniToken "<-" "\8592"
forall a. NoAnn a => a
noAnn
            (IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
a)
            (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp
              LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
read_field
              (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
reset_RDR [IdP (GhcPass 'Parsed)
RdrName
readPrec_RDR])
            )
          )
        ]
        where
          lbl_str :: String
lbl_str = FastString -> String
unpackFS FastString
lbl
          mk_read_field :: IdGhcP p -> FastString -> LHsExpr (GhcPass p)
mk_read_field IdGhcP p
read_field_rdr FastString
lbl
              = IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass p)
IdGhcP p
read_field_rdr [HsLit (GhcPass p) -> LHsExpr (GhcPass p)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (FastString -> HsLit (GhcPass p)
forall (p :: Pass). FastString -> HsLit (GhcPass p)
mkHsStringFS FastString
lbl)]
          read_field :: LocatedA (HsExpr (GhcPass 'Parsed))
read_field
              | String -> Bool
isSym String
lbl_str
              = IdGhcP 'Parsed -> FastString -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {p :: Pass} {a}.
(Anno (IdGhcP p) ~ EpAnn a, NoAnn a, IsPass p) =>
IdGhcP p
-> FastString -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
mk_read_field RdrName
IdGhcP 'Parsed
readSymField_RDR FastString
lbl
              | Just (String
ss, Char
'#') <- String -> Maybe (String, Char)
forall a. [a] -> Maybe ([a], a)
snocView String
lbl_str -- #14918
              = IdGhcP 'Parsed -> FastString -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {p :: Pass} {a}.
(Anno (IdGhcP p) ~ EpAnn a, NoAnn a, IsPass p) =>
IdGhcP p
-> FastString -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
mk_read_field RdrName
IdGhcP 'Parsed
readFieldHash_RDR (String -> FastString
mkFastString String
ss)
              | Bool
otherwise
              = IdGhcP 'Parsed -> FastString -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {p :: Pass} {a}.
(Anno (IdGhcP p) ~ EpAnn a, NoAnn a, IsPass p) =>
IdGhcP p
-> FastString -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
mk_read_field RdrName
IdGhcP 'Parsed
readField_RDR FastString
lbl

{-
************************************************************************
*                                                                      *
        Show instances
*                                                                      *
************************************************************************

Example

    infixr 5 :^:

    data Tree a =  Leaf a  |  Tree a :^: Tree a

    instance (Show a) => Show (Tree a) where

        showsPrec d (Leaf m) = showParen (d > app_prec) showStr
          where
             showStr = showString "Leaf " . showsPrec (app_prec+1) m

        showsPrec d (u :^: v) = showParen (d > up_prec) showStr
          where
             showStr = showsPrec (up_prec+1) u .
                       showString " :^: "      .
                       showsPrec (up_prec+1) v
                -- Note: right-associativity of :^: ignored

    up_prec  = 5    -- Precedence of :^:
    app_prec = 10   -- Application has precedence one more than
                    -- the most tightly-binding operator
-}

gen_Show_binds :: (Name -> Fixity) -> SrcSpan -> DerivInstTys
               -> (LHsBinds GhcPs, Bag AuxBindSpec)

gen_Show_binds :: (Name -> Fixity)
-> SrcSpan
-> DerivInstTys
-> (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
gen_Show_binds Name -> Fixity
get_fixity SrcSpan
loc dit :: DerivInstTys
dit@(DerivInstTys{ dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
tycon
                                               , dit_rep_tc_args :: DerivInstTys -> [Type]
dit_rep_tc_args = [Type]
tycon_args })
  = ([LHsBind (GhcPass 'Parsed)
shows_prec], Bag AuxBindSpec
forall a. Bag a
emptyBag)
  where
    data_cons :: [DataCon]
data_cons = TyCon -> [Type] -> [DataCon]
getPossibleDataCons TyCon
tycon [Type]
tycon_args
    shows_prec :: LHsBind (GhcPass 'Parsed)
shows_prec = Int
-> SrcSpan
-> RdrName
-> (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkFunBindEC Int
2 SrcSpan
loc RdrName
showsPrec_RDR LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a. a -> a
id ((DataCon
 -> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
     LocatedA (HsExpr (GhcPass 'Parsed))))
-> [DataCon]
-> [([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
     LocatedA (HsExpr (GhcPass 'Parsed)))]
forall a b. (a -> b) -> [a] -> [b]
map DataCon
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    LocatedA (HsExpr (GhcPass 'Parsed)))
pats_etc [DataCon]
data_cons)
    comma_space :: LHsExpr (GhcPass 'Parsed)
comma_space = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
showCommaSpace_RDR

    pats_etc :: DataCon
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    LocatedA (HsExpr (GhcPass 'Parsed)))
pats_etc DataCon
data_con
      | Bool
nullary_con =  -- skip the showParen junk...
         Bool
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    LocatedA (HsExpr (GhcPass 'Parsed)))
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    LocatedA (HsExpr (GhcPass 'Parsed)))
forall a. HasCallStack => Bool -> a -> a
assert ([RdrName] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [RdrName]
bs_needed)
         ([LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
nlWildPat, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
con_pat], String -> LHsExpr (GhcPass 'Parsed)
mk_showString_app String
op_con_str)
      | Bool
otherwise   =
         ([LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
a_Pat, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
con_pat],
          LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
showParen_Expr (LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genOpApp LHsExpr (GhcPass 'Parsed)
a_Expr RdrName
ge_RDR (HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit
                         (XHsInt (GhcPass 'Parsed) -> IntegralLit -> HsLit (GhcPass 'Parsed)
forall x. XHsInt x -> IntegralLit -> HsLit x
HsInt XHsInt (GhcPass 'Parsed)
NoExtField
noExtField (Integer -> IntegralLit
forall a. Integral a => a -> IntegralLit
mkIntegralLit Integer
con_prec_plus_one))))
                         (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar ([LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
nested_compose_Expr [LHsExpr (GhcPass 'Parsed)]
[LocatedA (HsExpr (GhcPass 'Parsed))]
show_thingies)))
        where
             data_con_RDR :: RdrName
data_con_RDR  = DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
data_con
             con_arity :: Int
con_arity     = DataCon -> Int
dataConSourceArity DataCon
data_con
             bs_needed :: [RdrName]
bs_needed     = Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take Int
con_arity [RdrName]
bs_RDRs
             arg_tys :: [Type]
arg_tys       = DataCon -> DerivInstTys -> [Type]
derivDataConInstArgTys DataCon
data_con DerivInstTys
dit -- Correspond 1-1 with bs_needed
             con_pat :: LPat (GhcPass 'Parsed)
con_pat       = RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
data_con_RDR [RdrName]
bs_needed
             nullary_con :: Bool
nullary_con   = Int
con_arity Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
             labels :: [FastString]
labels        = (FieldLabel -> FastString) -> [FieldLabel] -> [FastString]
forall a b. (a -> b) -> [a] -> [b]
map (FieldLabelString -> FastString
field_label (FieldLabelString -> FastString)
-> (FieldLabel -> FieldLabelString) -> FieldLabel -> FastString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldLabel -> FieldLabelString
flLabel) ([FieldLabel] -> [FastString]) -> [FieldLabel] -> [FastString]
forall a b. (a -> b) -> a -> b
$ DataCon -> [FieldLabel]
dataConFieldLabels DataCon
data_con
             lab_fields :: Int
lab_fields    = [FastString] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [FastString]
labels
             record_syntax :: Bool
record_syntax = Int
lab_fields Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0

             dc_nm :: Name
dc_nm          = DataCon -> Name
forall a. NamedThing a => a -> Name
getName DataCon
data_con
             dc_occ_nm :: OccName
dc_occ_nm      = DataCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName DataCon
data_con
             con_str :: String
con_str        = OccName -> String
occNameString OccName
dc_occ_nm
             op_con_str :: String
op_con_str     = String -> String
wrapOpParens String
con_str
             backquote_str :: String
backquote_str  = String -> String
wrapOpBackquotes String
con_str

             show_thingies :: [LocatedA (HsExpr (GhcPass 'Parsed))]
show_thingies
                | Bool
is_infix      = [LocatedA (HsExpr (GhcPass 'Parsed))
show_arg1, String -> LHsExpr (GhcPass 'Parsed)
mk_showString_app (String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
backquote_str String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" "), LocatedA (HsExpr (GhcPass 'Parsed))
show_arg2]
                | Bool
record_syntax = String -> LHsExpr (GhcPass 'Parsed)
mk_showString_app (String
op_con_str String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" {") LocatedA (HsExpr (GhcPass 'Parsed))
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a. a -> [a] -> [a]
:
                                  [LocatedA (HsExpr (GhcPass 'Parsed))]
show_record_args [LocatedA (HsExpr (GhcPass 'Parsed))]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a. [a] -> [a] -> [a]
++ [String -> LHsExpr (GhcPass 'Parsed)
mk_showString_app String
"}"]
                | Bool
otherwise     = String -> LHsExpr (GhcPass 'Parsed)
mk_showString_app (String
op_con_str String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ") LocatedA (HsExpr (GhcPass 'Parsed))
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a. a -> [a] -> [a]
: [LocatedA (HsExpr (GhcPass 'Parsed))]
show_prefix_args

             show_label :: FastString -> LHsExpr (GhcPass 'Parsed)
show_label FastString
l = String -> LHsExpr (GhcPass 'Parsed)
mk_showString_app (String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" = ")
                        -- Note the spaces around the "=" sign.  If we
                        -- don't have them then we get Foo { x=-1 } and
                        -- the "=-" parses as a single lexeme.  Only the
                        -- space after the '=' is necessary, but it
                        -- seems tidier to have them both sides.
                 where
                   nm :: String
nm       = String -> String
wrapOpParens (FastString -> String
unpackFS FastString
l)

             show_args :: [LocatedA (HsExpr (GhcPass 'Parsed))]
show_args               = String
-> (RdrName -> Type -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [RdrName]
-> [Type]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a b c.
HasDebugCallStack =>
String -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithEqual String
"gen_Show_binds" RdrName -> Type -> LHsExpr (GhcPass 'Parsed)
RdrName -> Type -> LocatedA (HsExpr (GhcPass 'Parsed))
show_arg [RdrName]
bs_needed [Type]
arg_tys
             (LocatedA (HsExpr (GhcPass 'Parsed))
show_arg1:LocatedA (HsExpr (GhcPass 'Parsed))
show_arg2:[LocatedA (HsExpr (GhcPass 'Parsed))]
_) = [LocatedA (HsExpr (GhcPass 'Parsed))]
show_args
             show_prefix_args :: [LocatedA (HsExpr (GhcPass 'Parsed))]
show_prefix_args        = LocatedA (HsExpr (GhcPass 'Parsed))
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a. a -> [a] -> [a]
intersperse (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
showSpace_RDR) [LocatedA (HsExpr (GhcPass 'Parsed))]
show_args

                -- Assumption for record syntax: no of fields == no of
                -- labelled fields (and in same order)
             show_record_args :: [LocatedA (HsExpr (GhcPass 'Parsed))]
show_record_args = [[LocatedA (HsExpr (GhcPass 'Parsed))]]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[LocatedA (HsExpr (GhcPass 'Parsed))]]
 -> [LocatedA (HsExpr (GhcPass 'Parsed))])
-> [[LocatedA (HsExpr (GhcPass 'Parsed))]]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a b. (a -> b) -> a -> b
$
                                [LocatedA (HsExpr (GhcPass 'Parsed))]
-> [[LocatedA (HsExpr (GhcPass 'Parsed))]]
-> [[LocatedA (HsExpr (GhcPass 'Parsed))]]
forall a. a -> [a] -> [a]
intersperse [LocatedA (HsExpr (GhcPass 'Parsed))
comma_space] ([[LocatedA (HsExpr (GhcPass 'Parsed))]]
 -> [[LocatedA (HsExpr (GhcPass 'Parsed))]])
-> [[LocatedA (HsExpr (GhcPass 'Parsed))]]
-> [[LocatedA (HsExpr (GhcPass 'Parsed))]]
forall a b. (a -> b) -> a -> b
$
                                [ [FastString -> LocatedA (HsExpr (GhcPass 'Parsed))
show_label FastString
lbl, LocatedA (HsExpr (GhcPass 'Parsed))
arg]
                                | (FastString
lbl,LocatedA (HsExpr (GhcPass 'Parsed))
arg) <- String
-> [FastString]
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
-> [(FastString, LocatedA (HsExpr (GhcPass 'Parsed)))]
forall a b. HasDebugCallStack => String -> [a] -> [b] -> [(a, b)]
zipEqual String
"gen_Show_binds"
                                                        [FastString]
labels [LocatedA (HsExpr (GhcPass 'Parsed))]
show_args ]

             show_arg :: RdrName -> Type -> LHsExpr GhcPs
             show_arg :: RdrName -> Type -> LHsExpr (GhcPass 'Parsed)
show_arg RdrName
b Type
arg_ty
                 | HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType Type
arg_ty
                 -- See Note [Deriving and unboxed types] in GHC.Tc.Deriv.Infer
                 = IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
compose_RDR
                        [LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
mk_shows_app LHsExpr (GhcPass 'Parsed)
boxed_arg, String -> LHsExpr (GhcPass 'Parsed)
mk_showString_app String
postfixMod]
                 | Bool
otherwise
                 = Integer -> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
mk_showsPrec_app Integer
arg_prec LHsExpr (GhcPass 'Parsed)
arg
               where
                 arg :: LHsExpr (GhcPass 'Parsed)
arg        = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b
                 boxed_arg :: LHsExpr (GhcPass 'Parsed)
boxed_arg  = String
-> LHsExpr (GhcPass 'Parsed) -> Type -> LHsExpr (GhcPass 'Parsed)
box String
"Show" LHsExpr (GhcPass 'Parsed)
arg Type
arg_ty
                 postfixMod :: String
postfixMod = String -> [(Type, String)] -> Type -> String
forall a. HasDebugCallStack => String -> [(Type, a)] -> Type -> a
assoc_ty_id String
"Show" [(Type, String)]
postfixModTbl Type
arg_ty

                -- Fixity stuff
             is_infix :: Bool
is_infix = DataCon -> Bool
dataConIsInfix DataCon
data_con
             con_prec_plus_one :: Integer
con_prec_plus_one = Integer
1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Bool -> (Name -> Fixity) -> Name -> Integer
getPrec Bool
is_infix Name -> Fixity
get_fixity Name
dc_nm
             arg_prec :: Integer
arg_prec | Bool
record_syntax = Integer
0  -- Record fields don't need parens
                      | Bool
otherwise     = Integer
con_prec_plus_one

wrapOpParens :: String -> String
wrapOpParens :: String -> String
wrapOpParens String
s | String -> Bool
isSym String
s   = Char
'(' Char -> String -> String
forall a. a -> [a] -> [a]
: String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
               | Bool
otherwise = String
s

wrapOpBackquotes :: String -> String
wrapOpBackquotes :: String -> String
wrapOpBackquotes String
s | String -> Bool
isSym String
s   = String
s
                   | Bool
otherwise = Char
'`' Char -> String -> String
forall a. a -> [a] -> [a]
: String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"`"

isSym :: String -> Bool
isSym :: String -> Bool
isSym String
""      = Bool
False
isSym (Char
c : String
_) = Char -> Bool
startsVarSym Char
c Bool -> Bool -> Bool
|| Char -> Bool
startsConSym Char
c

-- | showString :: String -> ShowS
mk_showString_app :: String -> LHsExpr GhcPs
mk_showString_app :: String -> LHsExpr (GhcPass 'Parsed)
mk_showString_app String
str = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
showString_RDR) (HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (String -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). String -> HsLit (GhcPass p)
mkHsString String
str))

-- | showsPrec :: Show a => Int -> a -> ShowS
mk_showsPrec_app :: Integer -> LHsExpr GhcPs -> LHsExpr GhcPs
mk_showsPrec_app :: Integer -> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
mk_showsPrec_app Integer
p LHsExpr (GhcPass 'Parsed)
x
  = IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
showsPrec_RDR [HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (XHsInt (GhcPass 'Parsed) -> IntegralLit -> HsLit (GhcPass 'Parsed)
forall x. XHsInt x -> IntegralLit -> HsLit x
HsInt XHsInt (GhcPass 'Parsed)
NoExtField
noExtField (Integer -> IntegralLit
forall a. Integral a => a -> IntegralLit
mkIntegralLit Integer
p)), LHsExpr (GhcPass 'Parsed)
x]

-- | shows :: Show a => a -> ShowS
mk_shows_app :: LHsExpr GhcPs -> LHsExpr GhcPs
mk_shows_app :: LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
mk_shows_app LHsExpr (GhcPass 'Parsed)
x = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
shows_RDR) LHsExpr (GhcPass 'Parsed)
x

getPrec :: Bool -> (Name -> Fixity) -> Name -> Integer
getPrec :: Bool -> (Name -> Fixity) -> Name -> Integer
getPrec Bool
is_infix Name -> Fixity
get_fixity Name
nm
  | Bool -> Bool
not Bool
is_infix   = Integer
appPrecedence
  | Bool
otherwise      = (Name -> Fixity) -> Name -> Integer
getPrecedence Name -> Fixity
get_fixity Name
nm

appPrecedence :: Integer
appPrecedence :: Integer
appPrecedence = Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
maxPrecedence Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1
  -- One more than the precedence of the most
  -- tightly-binding operator

getPrecedence :: (Name -> Fixity) -> Name -> Integer
getPrecedence :: (Name -> Fixity) -> Name -> Integer
getPrecedence Name -> Fixity
get_fixity Name
nm
   = case Name -> Fixity
get_fixity Name
nm of
        Fixity Int
x FixityDirection
_assoc -> Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x
          -- NB: the Report says that associativity is not taken
          --     into account for either Read or Show; hence we
          --     ignore associativity here

{-
************************************************************************
*                                                                      *
        Data instances
*                                                                      *
************************************************************************

From the data type

  data T a b = T1 a b | T2

we generate

  $cT1 = mkDataCon $dT "T1" Prefix
  $cT2 = mkDataCon $dT "T2" Prefix
  $dT  = mkDataType "Module.T" [] [$con_T1, $con_T2]
  -- the [] is for field labels.

  instance (Data a, Data b) => Data (T a b) where
    gfoldl k z (T1 a b) = z T `k` a `k` b
    gfoldl k z T2           = z T2
    -- ToDo: add gmapT,Q,M, gfoldr

    gunfold k z c = case conIndex c of
                        I# 1# -> k (k (z T1))
                        I# 2# -> z T2

    toConstr (T1 _ _) = $cT1
    toConstr T2       = $cT2

    dataTypeOf _ = $dT

    dataCast1 = gcast1   -- If T :: * -> *
    dataCast2 = gcast2   -- if T :: * -> * -> *
-}

gen_Data_binds :: SrcSpan
               -> DerivInstTys
               -> TcM (LHsBinds GhcPs,  -- The method bindings
                       Bag AuxBindSpec) -- Auxiliary bindings
gen_Data_binds :: SrcSpan
-> DerivInstTys
-> TcM (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
gen_Data_binds SrcSpan
loc (DerivInstTys{dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
rep_tc})
  = do { -- See Note [Auxiliary binders]
         dataT_RDR  <- SrcSpan -> TyCon -> TcM RdrName
new_dataT_rdr_name SrcSpan
loc TyCon
rep_tc
       ; dataC_RDRs <- traverse (new_dataC_rdr_name loc) data_cons

       ; pure ( [ gfoldl_bind, gunfold_bind
                , toCon_bind dataC_RDRs, dataTypeOf_bind dataT_RDR ]
                ++ gcast_binds
                          -- Auxiliary definitions: the data type and constructors
              , listToBag
                  ( DerivDataDataType rep_tc dataT_RDR dataC_RDRs
                  : zipWith (\DataCon
data_con RdrName
dataC_RDR ->
                               DataCon -> RdrName -> RdrName -> AuxBindSpec
DerivDataConstr DataCon
data_con RdrName
dataC_RDR RdrName
dataT_RDR)
                            data_cons dataC_RDRs )
              ) }
  where
    data_cons :: [DataCon]
data_cons  = TyCon -> [DataCon]
tyConDataCons TyCon
rep_tc
    n_cons :: Int
n_cons     = [DataCon] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [DataCon]
data_cons

        ------------ gfoldl
    gfoldl_bind :: LHsBind (GhcPass 'Parsed)
gfoldl_bind = Int
-> SrcSpan
-> RdrName
-> (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkFunBindEC Int
3 SrcSpan
loc RdrName
gfoldl_RDR LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a. a -> a
id ((DataCon
 -> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
     LocatedA (HsExpr (GhcPass 'Parsed))))
-> [DataCon]
-> [([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
     LocatedA (HsExpr (GhcPass 'Parsed)))]
forall a b. (a -> b) -> [a] -> [b]
map DataCon
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    LocatedA (HsExpr (GhcPass 'Parsed)))
gfoldl_eqn [DataCon]
data_cons)

    gfoldl_eqn :: DataCon
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    LocatedA (HsExpr (GhcPass 'Parsed)))
gfoldl_eqn DataCon
con
      = ([IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
k_RDR, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
z_Pat, RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
con_name [RdrName]
as_needed],
                   (LocatedA (HsExpr (GhcPass 'Parsed))
 -> RdrName -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> [RdrName]
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' LocatedA (HsExpr (GhcPass 'Parsed))
-> RdrName -> LocatedA (HsExpr (GhcPass 'Parsed))
mk_k_app (LHsExpr (GhcPass 'Parsed)
z_Expr LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
`nlHsApp` (DataCon -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {p :: Pass}.
(XMG (GhcPass p) (GenLocated SrcSpanAnnA (HsExpr (GhcPass p)))
 ~ Origin,
 IdGhcP p ~ RdrName, IsPass p) =>
DataCon -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
eta_expand_data_con DataCon
con)) [RdrName]
as_needed)
                   where
                     con_name ::  RdrName
                     con_name :: RdrName
con_name = DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
con
                     as_needed :: [RdrName]
as_needed = Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take (DataCon -> Int
dataConSourceArity DataCon
con) [RdrName]
as_RDRs
                     mk_k_app :: LocatedA (HsExpr (GhcPass 'Parsed))
-> RdrName -> LHsExpr (GhcPass 'Parsed)
mk_k_app LocatedA (HsExpr (GhcPass 'Parsed))
e RdrName
v = LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar (LHsExpr (GhcPass 'Parsed)
-> IdP (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsOpApp LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
e IdP (GhcPass 'Parsed)
RdrName
k_RDR (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
v))

        ------------ gunfold
    gunfold_bind :: LHsBind (GhcPass 'Parsed)
gunfold_bind = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc
                     RdrName
gunfold_RDR
                     ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
k_Pat, LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
z_Pat, if Int
n_cons Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
nlWildPat else LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
c_Pat])
                     LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
gunfold_rhs

    gunfold_rhs :: LocatedA (HsExpr (GhcPass 'Parsed))
gunfold_rhs
        | [DataCon
con] <- [DataCon]
data_cons = DataCon -> LocatedA (HsExpr (GhcPass 'Parsed))
mk_unfold_rhs DataCon
con   -- No need for case
        | Bool
otherwise  = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
conIndex_RDR LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
`nlHsApp` LHsExpr (GhcPass 'Parsed)
c_Expr)
                                ((DataCon
 -> GenLocated
      SrcSpanAnnA
      (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))))
-> [DataCon]
-> [GenLocated
      SrcSpanAnnA
      (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
forall a b. (a -> b) -> [a] -> [b]
map DataCon
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
DataCon
-> GenLocated
     SrcSpanAnnA
     (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))
gunfold_alt [DataCon]
data_cons)

    gunfold_alt :: DataCon
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
gunfold_alt DataCon
dc = LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (DataCon -> LPat (GhcPass 'Parsed)
mk_unfold_pat DataCon
dc) (DataCon -> LocatedA (HsExpr (GhcPass 'Parsed))
mk_unfold_rhs DataCon
dc)
    mk_unfold_rhs :: DataCon -> LocatedA (HsExpr (GhcPass 'Parsed))
mk_unfold_rhs DataCon
dc = (LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp
                           (LHsExpr (GhcPass 'Parsed)
z_Expr LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
`nlHsApp` (DataCon -> LocatedA (HsExpr (GhcPass 'Parsed))
forall {p :: Pass}.
(XMG (GhcPass p) (GenLocated SrcSpanAnnA (HsExpr (GhcPass p)))
 ~ Origin,
 IdGhcP p ~ RdrName, IsPass p) =>
DataCon -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
eta_expand_data_con DataCon
dc))
                           (Int
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a. Int -> a -> [a]
replicate (DataCon -> Int
dataConSourceArity DataCon
dc) (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
k_RDR))

    eta_expand_data_con :: DataCon -> LHsExpr (GhcPass p)
eta_expand_data_con DataCon
dc =
        LocatedE [LPat (GhcPass p)]
-> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
forall (p :: Pass).
(IsPass p, XMG (GhcPass p) (LHsExpr (GhcPass p)) ~ Origin) =>
LocatedE [LPat (GhcPass p)]
-> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
mkHsLam ([GenLocated SrcSpanAnnA (Pat (GhcPass p))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass p))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [GenLocated SrcSpanAnnA (Pat (GhcPass p))]
eta_expand_pats)
          ((GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
 -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
 -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p)))
-> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
-> [GenLocated SrcSpanAnnA (HsExpr (GhcPass p))]
-> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl LHsExpr (GhcPass p) -> LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
-> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
-> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass p) -> LHsExpr (GhcPass p)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar (DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
dc)) [GenLocated SrcSpanAnnA (HsExpr (GhcPass p))]
eta_expand_hsvars)
      where
        eta_expand_pats :: [GenLocated SrcSpanAnnA (Pat (GhcPass p))]
eta_expand_pats = (RdrName -> GenLocated SrcSpanAnnA (Pat (GhcPass p)))
-> [RdrName] -> [GenLocated SrcSpanAnnA (Pat (GhcPass p))]
forall a b. (a -> b) -> [a] -> [b]
map IdP (GhcPass p) -> LPat (GhcPass p)
RdrName -> GenLocated SrcSpanAnnA (Pat (GhcPass p))
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat [RdrName]
eta_expand_vars
        eta_expand_hsvars :: [GenLocated SrcSpanAnnA (HsExpr (GhcPass p))]
eta_expand_hsvars = (RdrName -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p)))
-> [RdrName] -> [GenLocated SrcSpanAnnA (HsExpr (GhcPass p))]
forall a b. (a -> b) -> [a] -> [b]
map IdP (GhcPass p) -> LHsExpr (GhcPass p)
RdrName -> GenLocated SrcSpanAnnA (HsExpr (GhcPass p))
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar [RdrName]
eta_expand_vars
        eta_expand_vars :: [RdrName]
eta_expand_vars = Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take (DataCon -> Int
dataConSourceArity DataCon
dc) [RdrName]
as_RDRs


    mk_unfold_pat :: DataCon -> LPat (GhcPass 'Parsed)
mk_unfold_pat DataCon
dc    -- Last one is a wild-pat, to avoid
                        -- redundant test, and annoying warning
      | Int
tagInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
fIRST_TAG Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n_consInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1 = LPat (GhcPass 'Parsed)
nlWildPat   -- Last constructor
      | Bool
otherwise = RdrName -> [LPat (GhcPass 'Parsed)] -> LPat (GhcPass 'Parsed)
nlConPat RdrName
intDataCon_RDR
                             [HsLit (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
nlLitPat (XHsIntPrim (GhcPass 'Parsed) -> Integer -> HsLit (GhcPass 'Parsed)
forall x. XHsIntPrim x -> Integer -> HsLit x
HsIntPrim XHsIntPrim (GhcPass 'Parsed)
SourceText
NoSourceText (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
tag))]
      where
        tag :: Int
tag = DataCon -> Int
dataConTag DataCon
dc

        ------------ toConstr
    toCon_bind :: [RdrName] -> LHsBind (GhcPass 'Parsed)
toCon_bind [RdrName]
dataC_RDRs
      = Int
-> SrcSpan
-> RdrName
-> (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkFunBindEC Int
1 SrcSpan
loc RdrName
toConstr_RDR LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a. a -> a
id
            ((DataCon
 -> RdrName
 -> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
     LocatedA (HsExpr (GhcPass 'Parsed))))
-> [DataCon]
-> [RdrName]
-> [([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
     LocatedA (HsExpr (GhcPass 'Parsed)))]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith DataCon
-> RdrName
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    LocatedA (HsExpr (GhcPass 'Parsed)))
DataCon
-> IdGhcP 'Parsed
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    LocatedA (HsExpr (GhcPass 'Parsed)))
forall {p :: Pass} {a}.
(Anno (IdGhcP p) ~ EpAnn a, NoAnn a, IsPass p) =>
DataCon
-> IdGhcP p
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    GenLocated SrcSpanAnnA (HsExpr (GhcPass p)))
to_con_eqn [DataCon]
data_cons [RdrName]
dataC_RDRs)
    to_con_eqn :: DataCon
-> IdGhcP p
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    GenLocated SrcSpanAnnA (HsExpr (GhcPass p)))
to_con_eqn DataCon
dc IdGhcP p
con_name = ([DataCon -> LPat (GhcPass 'Parsed)
nlWildConPat DataCon
dc], IdP (GhcPass p) -> LHsExpr (GhcPass p)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass p)
IdGhcP p
con_name)

        ------------ dataTypeOf
    dataTypeOf_bind :: RdrName -> LHsBind (GhcPass 'Parsed)
dataTypeOf_bind RdrName
dataT_RDR
      = SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind
          SrcSpan
loc
          RdrName
dataTypeOf_RDR
          ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
nlWildPat])
          (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
dataT_RDR)

        ------------ gcast1/2
        -- Make the binding    dataCast1 x = gcast1 x  -- if T :: * -> *
        --               or    dataCast2 x = gcast2 s  -- if T :: * -> * -> *
        -- (or nothing if T has neither of these two types)

        -- But care is needed for data families:
        -- If we have   data family D a
        --              data instance D (a,b,c) = A | B deriving( Data )
        -- and we want  instance ... => Data (D [(a,b,c)]) where ...
        -- then we need     dataCast1 x = gcast1 x
        -- because D :: * -> *
        -- even though rep_tc has kind * -> * -> * -> *
        -- Hence looking for the kind of fam_tc not rep_tc
        -- See #4896
    tycon_kind :: Type
tycon_kind = case TyCon -> Maybe (TyCon, [Type])
tyConFamInst_maybe TyCon
rep_tc of
                    Just (TyCon
fam_tc, [Type]
_) -> TyCon -> Type
tyConKind TyCon
fam_tc
                    Maybe (TyCon, [Type])
Nothing          -> TyCon -> Type
tyConKind TyCon
rep_tc
    gcast_binds :: [GenLocated
   SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
gcast_binds | Type
tycon_kind HasDebugCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`tcEqKind` Type
kind1 = RdrName
-> RdrName
-> [GenLocated
      SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
mk_gcast RdrName
dataCast1_RDR RdrName
gcast1_RDR
                | Type
tycon_kind HasDebugCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`tcEqKind` Type
kind2 = RdrName
-> RdrName
-> [GenLocated
      SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
mk_gcast RdrName
dataCast2_RDR RdrName
gcast2_RDR
                | Bool
otherwise                 = []
    mk_gcast :: RdrName
-> RdrName
-> [GenLocated
      SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
mk_gcast RdrName
dataCast_RDR RdrName
gcast_RDR
      = [SrcSpan
-> RdrName
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkSimpleGeneratedFunBind SrcSpan
loc RdrName
dataCast_RDR ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA [IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
f_RDR])
                                 (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
gcast_RDR LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
`nlHsApp` IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
f_RDR)]


kind1, kind2 :: Kind
kind1 :: Type
kind1 = Type
typeToTypeKind
kind2 :: Type
kind2 = Type
liftedTypeKind HasDebugCallStack => Type -> Type -> Type
Type -> Type -> Type
`mkVisFunTyMany` Type
kind1

gfoldl_RDR, gunfold_RDR, toConstr_RDR, dataTypeOf_RDR, mkConstrTag_RDR,
    mkDataType_RDR, conIndex_RDR, prefix_RDR, infix_RDR,
    dataCast1_RDR, dataCast2_RDR, gcast1_RDR, gcast2_RDR,
    constr_RDR, dataType_RDR,
    eqChar_RDR  , ltChar_RDR  , geChar_RDR  , gtChar_RDR  , leChar_RDR  ,
    eqInt_RDR   , ltInt_RDR   , geInt_RDR   , gtInt_RDR   , leInt_RDR   , neInt_RDR ,
    eqInt8_RDR  , ltInt8_RDR  , geInt8_RDR  , gtInt8_RDR  , leInt8_RDR  ,
    eqInt16_RDR , ltInt16_RDR , geInt16_RDR , gtInt16_RDR , leInt16_RDR ,
    eqInt32_RDR , ltInt32_RDR , geInt32_RDR , gtInt32_RDR , leInt32_RDR ,
    eqInt64_RDR , ltInt64_RDR , geInt64_RDR , gtInt64_RDR , leInt64_RDR ,
    eqWord_RDR  , ltWord_RDR  , geWord_RDR  , gtWord_RDR  , leWord_RDR  ,
    eqWord8_RDR , ltWord8_RDR , geWord8_RDR , gtWord8_RDR , leWord8_RDR ,
    eqWord16_RDR, ltWord16_RDR, geWord16_RDR, gtWord16_RDR, leWord16_RDR,
    eqWord32_RDR, ltWord32_RDR, geWord32_RDR, gtWord32_RDR, leWord32_RDR,
    eqWord64_RDR, ltWord64_RDR, geWord64_RDR, gtWord64_RDR, leWord64_RDR,
    eqAddr_RDR  , ltAddr_RDR  , geAddr_RDR  , gtAddr_RDR  , leAddr_RDR  ,
    eqFloat_RDR , ltFloat_RDR , geFloat_RDR , gtFloat_RDR , leFloat_RDR ,
    eqDouble_RDR, ltDouble_RDR, geDouble_RDR, gtDouble_RDR, leDouble_RDR,
    int8DataCon_RDR, int16DataCon_RDR, int32DataCon_RDR, int64DataCon_RDR,
    word8DataCon_RDR, word16DataCon_RDR, word32DataCon_RDR, word64DataCon_RDR
    :: RdrName
gfoldl_RDR :: RdrName
gfoldl_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"gfoldl")
gunfold_RDR :: RdrName
gunfold_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"gunfold")
toConstr_RDR :: RdrName
toConstr_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"toConstr")
dataTypeOf_RDR :: RdrName
dataTypeOf_RDR = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"dataTypeOf")
dataCast1_RDR :: RdrName
dataCast1_RDR  = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"dataCast1")
dataCast2_RDR :: RdrName
dataCast2_RDR  = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"dataCast2")
gcast1_RDR :: RdrName
gcast1_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_INTERNAL_TYPEABLE (String -> FastString
fsLit String
"gcast1")
gcast2_RDR :: RdrName
gcast2_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_INTERNAL_TYPEABLE (String -> FastString
fsLit String
"gcast2")
mkConstrTag_RDR :: RdrName
mkConstrTag_RDR = Module -> FastString -> RdrName
varQual_RDR Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"mkConstrTag")
constr_RDR :: RdrName
constr_RDR     = Module -> FastString -> RdrName
tcQual_RDR   Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"Constr")
mkDataType_RDR :: RdrName
mkDataType_RDR = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"mkDataType")
dataType_RDR :: RdrName
dataType_RDR   = Module -> FastString -> RdrName
tcQual_RDR   Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"DataType")
conIndex_RDR :: RdrName
conIndex_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"constrIndex")
prefix_RDR :: RdrName
prefix_RDR     = Module -> FastString -> RdrName
dataQual_RDR Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"Prefix")
infix_RDR :: RdrName
infix_RDR      = Module -> FastString -> RdrName
dataQual_RDR Module
gHC_INTERNAL_DATA_DATA (String -> FastString
fsLit String
"Infix")

eqChar_RDR :: RdrName
eqChar_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqChar#")
ltChar_RDR :: RdrName
ltChar_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltChar#")
leChar_RDR :: RdrName
leChar_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leChar#")
gtChar_RDR :: RdrName
gtChar_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtChar#")
geChar_RDR :: RdrName
geChar_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geChar#")

eqInt_RDR :: RdrName
eqInt_RDR      = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"==#")
neInt_RDR :: RdrName
neInt_RDR      = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"/=#")
ltInt_RDR :: RdrName
ltInt_RDR      = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"<#" )
leInt_RDR :: RdrName
leInt_RDR      = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"<=#")
gtInt_RDR :: RdrName
gtInt_RDR      = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
">#" )
geInt_RDR :: RdrName
geInt_RDR      = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
">=#")

eqInt8_RDR :: RdrName
eqInt8_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqInt8#")
ltInt8_RDR :: RdrName
ltInt8_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltInt8#" )
leInt8_RDR :: RdrName
leInt8_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leInt8#")
gtInt8_RDR :: RdrName
gtInt8_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtInt8#" )
geInt8_RDR :: RdrName
geInt8_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geInt8#")

eqInt16_RDR :: RdrName
eqInt16_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqInt16#")
ltInt16_RDR :: RdrName
ltInt16_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltInt16#" )
leInt16_RDR :: RdrName
leInt16_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leInt16#")
gtInt16_RDR :: RdrName
gtInt16_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtInt16#" )
geInt16_RDR :: RdrName
geInt16_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geInt16#")

eqInt32_RDR :: RdrName
eqInt32_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqInt32#")
ltInt32_RDR :: RdrName
ltInt32_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltInt32#" )
leInt32_RDR :: RdrName
leInt32_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leInt32#")
gtInt32_RDR :: RdrName
gtInt32_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtInt32#" )
geInt32_RDR :: RdrName
geInt32_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geInt32#")

eqInt64_RDR :: RdrName
eqInt64_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqInt64#")
ltInt64_RDR :: RdrName
ltInt64_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltInt64#" )
leInt64_RDR :: RdrName
leInt64_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leInt64#")
gtInt64_RDR :: RdrName
gtInt64_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtInt64#" )
geInt64_RDR :: RdrName
geInt64_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geInt64#")

eqWord_RDR :: RdrName
eqWord_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqWord#")
ltWord_RDR :: RdrName
ltWord_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltWord#")
leWord_RDR :: RdrName
leWord_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leWord#")
gtWord_RDR :: RdrName
gtWord_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtWord#")
geWord_RDR :: RdrName
geWord_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geWord#")

eqWord8_RDR :: RdrName
eqWord8_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqWord8#")
ltWord8_RDR :: RdrName
ltWord8_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltWord8#" )
leWord8_RDR :: RdrName
leWord8_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leWord8#")
gtWord8_RDR :: RdrName
gtWord8_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtWord8#" )
geWord8_RDR :: RdrName
geWord8_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geWord8#")

eqWord16_RDR :: RdrName
eqWord16_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqWord16#")
ltWord16_RDR :: RdrName
ltWord16_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltWord16#" )
leWord16_RDR :: RdrName
leWord16_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leWord16#")
gtWord16_RDR :: RdrName
gtWord16_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtWord16#" )
geWord16_RDR :: RdrName
geWord16_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geWord16#")

eqWord32_RDR :: RdrName
eqWord32_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqWord32#")
ltWord32_RDR :: RdrName
ltWord32_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltWord32#" )
leWord32_RDR :: RdrName
leWord32_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leWord32#")
gtWord32_RDR :: RdrName
gtWord32_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtWord32#" )
geWord32_RDR :: RdrName
geWord32_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geWord32#")

eqWord64_RDR :: RdrName
eqWord64_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqWord64#")
ltWord64_RDR :: RdrName
ltWord64_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltWord64#" )
leWord64_RDR :: RdrName
leWord64_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leWord64#")
gtWord64_RDR :: RdrName
gtWord64_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtWord64#" )
geWord64_RDR :: RdrName
geWord64_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geWord64#")

eqAddr_RDR :: RdrName
eqAddr_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqAddr#")
ltAddr_RDR :: RdrName
ltAddr_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltAddr#")
leAddr_RDR :: RdrName
leAddr_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leAddr#")
gtAddr_RDR :: RdrName
gtAddr_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtAddr#")
geAddr_RDR :: RdrName
geAddr_RDR     = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geAddr#")

eqFloat_RDR :: RdrName
eqFloat_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"eqFloat#")
ltFloat_RDR :: RdrName
ltFloat_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"ltFloat#")
leFloat_RDR :: RdrName
leFloat_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"leFloat#")
gtFloat_RDR :: RdrName
gtFloat_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"gtFloat#")
geFloat_RDR :: RdrName
geFloat_RDR    = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"geFloat#")

eqDouble_RDR :: RdrName
eqDouble_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"==##")
ltDouble_RDR :: RdrName
ltDouble_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"<##" )
leDouble_RDR :: RdrName
leDouble_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
"<=##")
gtDouble_RDR :: RdrName
gtDouble_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
">##" )
geDouble_RDR :: RdrName
geDouble_RDR   = Module -> FastString -> RdrName
varQual_RDR  Module
gHC_PRIM (String -> FastString
fsLit String
">=##")

int8DataCon_RDR :: RdrName
int8DataCon_RDR   = Module -> FastString -> RdrName
dataQual_RDR Module
gHC_INTERNAL_INT (String -> FastString
fsLit String
"I8#")
int16DataCon_RDR :: RdrName
int16DataCon_RDR  = Module -> FastString -> RdrName
dataQual_RDR Module
gHC_INTERNAL_INT (String -> FastString
fsLit String
"I16#")
int32DataCon_RDR :: RdrName
int32DataCon_RDR  = Module -> FastString -> RdrName
dataQual_RDR Module
gHC_INTERNAL_INT (String -> FastString
fsLit String
"I32#")
int64DataCon_RDR :: RdrName
int64DataCon_RDR  = Module -> FastString -> RdrName
dataQual_RDR Module
gHC_INTERNAL_INT (String -> FastString
fsLit String
"I64#")
word8DataCon_RDR :: RdrName
word8DataCon_RDR  = Module -> FastString -> RdrName
dataQual_RDR Module
gHC_INTERNAL_WORD (String -> FastString
fsLit String
"W8#")
word16DataCon_RDR :: RdrName
word16DataCon_RDR = Module -> FastString -> RdrName
dataQual_RDR Module
gHC_INTERNAL_WORD (String -> FastString
fsLit String
"W16#")
word32DataCon_RDR :: RdrName
word32DataCon_RDR = Module -> FastString -> RdrName
dataQual_RDR Module
gHC_INTERNAL_WORD (String -> FastString
fsLit String
"W32#")
word64DataCon_RDR :: RdrName
word64DataCon_RDR = Module -> FastString -> RdrName
dataQual_RDR Module
gHC_INTERNAL_WORD (String -> FastString
fsLit String
"W64#")
{-
************************************************************************
*                                                                      *
                        Lift instances
*                                                                      *
************************************************************************

Example:

    data Foo a = Foo a | a :^: a deriving Lift

    ==>

    instance (Lift a) => Lift (Foo a) where
        lift (Foo a) = [| Foo $(lift a) |]
        lift ((:^:) u v) = [| (:^:) $(lift u) $(lift v) |]

        liftTyped (Foo a) = [|| Foo $$(liftTyped a) ||]
        liftTyped ((:^:) u v) = [|| (:^:) $$(liftTyped u) $$(liftTyped v) ||]

Note that we use explicit splices here in order to not trigger the implicit
lifting warning in derived code. (See #20688)
-}


gen_Lift_binds :: SrcSpan -> DerivInstTys -> (LHsBinds GhcPs, Bag AuxBindSpec)
gen_Lift_binds :: SrcSpan
-> DerivInstTys -> (LHsBinds (GhcPass 'Parsed), Bag AuxBindSpec)
gen_Lift_binds SrcSpan
loc (DerivInstTys{ dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
tycon
                                , dit_rep_tc_args :: DerivInstTys -> [Type]
dit_rep_tc_args = [Type]
tycon_args }) =
  ([LHsBind (GhcPass 'Parsed)
lift_bind, LHsBind (GhcPass 'Parsed)
liftTyped_bind], Bag AuxBindSpec
forall a. Bag a
emptyBag)
  where
    lift_bind :: LHsBind (GhcPass 'Parsed)
lift_bind      = Int
-> SrcSpan
-> RdrName
-> (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkFunBindEC Int
1 SrcSpan
loc RdrName
lift_RDR (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp LHsExpr (GhcPass 'Parsed)
pure_Expr)
                                 ((DataCon
 -> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
     LocatedA (HsExpr (GhcPass 'Parsed))))
-> [DataCon]
-> [([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
     LocatedA (HsExpr (GhcPass 'Parsed)))]
forall a b. (a -> b) -> [a] -> [b]
map ((LocatedA (HsExpr (GhcPass 'Parsed)) -> HsExpr (GhcPass 'Parsed))
-> (LocatedA (HsExpr (GhcPass 'Parsed))
    -> HsExpr (GhcPass 'Parsed))
-> Name
-> DataCon
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    LocatedA (HsExpr (GhcPass 'Parsed)))
forall {e} {a}.
HasAnnotation e =>
(LocatedA (HsExpr (GhcPass 'Parsed)) -> a)
-> (LocatedA (HsExpr (GhcPass 'Parsed))
    -> HsExpr (GhcPass 'Parsed))
-> Name
-> DataCon
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    GenLocated e a)
pats_etc LHsExpr (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed)) -> HsExpr (GhcPass 'Parsed)
mk_untyped_bracket LHsExpr (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed)) -> HsExpr (GhcPass 'Parsed)
mk_usplice Name
liftName) [DataCon]
data_cons)
    liftTyped_bind :: LHsBind (GhcPass 'Parsed)
liftTyped_bind = Int
-> SrcSpan
-> RdrName
-> (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkFunBindEC Int
1 SrcSpan
loc RdrName
liftTyped_RDR (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp LHsExpr (GhcPass 'Parsed)
unsafeCodeCoerce_Expr (LocatedA (HsExpr (GhcPass 'Parsed))
 -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> (LocatedA (HsExpr (GhcPass 'Parsed))
    -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp LHsExpr (GhcPass 'Parsed)
pure_Expr)
                                 ((DataCon
 -> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
     LocatedA (HsExpr (GhcPass 'Parsed))))
-> [DataCon]
-> [([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
     LocatedA (HsExpr (GhcPass 'Parsed)))]
forall a b. (a -> b) -> [a] -> [b]
map ((LocatedA (HsExpr (GhcPass 'Parsed)) -> HsExpr (GhcPass 'Parsed))
-> (LocatedA (HsExpr (GhcPass 'Parsed))
    -> HsExpr (GhcPass 'Parsed))
-> Name
-> DataCon
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    LocatedA (HsExpr (GhcPass 'Parsed)))
forall {e} {a}.
HasAnnotation e =>
(LocatedA (HsExpr (GhcPass 'Parsed)) -> a)
-> (LocatedA (HsExpr (GhcPass 'Parsed))
    -> HsExpr (GhcPass 'Parsed))
-> Name
-> DataCon
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    GenLocated e a)
pats_etc LHsExpr (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed)) -> HsExpr (GhcPass 'Parsed)
mk_typed_bracket LHsExpr (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed)) -> HsExpr (GhcPass 'Parsed)
mk_tsplice Name
liftTypedName) [DataCon]
data_cons)

    mk_untyped_bracket :: LHsExpr (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
mk_untyped_bracket = XUntypedBracket (GhcPass 'Parsed)
-> HsQuote (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
forall p. XUntypedBracket p -> HsQuote p -> HsExpr p
HsUntypedBracket XUntypedBracket (GhcPass 'Parsed)
forall a. NoAnn a => a
noAnn (HsQuote (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed))
-> (LHsExpr (GhcPass 'Parsed) -> HsQuote (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed)
-> HsExpr (GhcPass 'Parsed)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XExpBr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> HsQuote (GhcPass 'Parsed)
forall p. XExpBr p -> LHsExpr p -> HsQuote p
ExpBr XExpBr (GhcPass 'Parsed)
NoExtField
noExtField
    mk_typed_bracket :: LHsExpr (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
mk_typed_bracket = XTypedBracket (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
forall p. XTypedBracket p -> LHsExpr p -> HsExpr p
HsTypedBracket XTypedBracket (GhcPass 'Parsed)
forall a. NoAnn a => a
noAnn

    mk_tsplice :: LHsExpr (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
mk_tsplice = XTypedSplice (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
forall p. XTypedSplice p -> LHsExpr p -> HsExpr p
HsTypedSplice XTypedSplice (GhcPass 'Parsed)
forall a. NoAnn a => a
noAnn
    mk_usplice :: LHsExpr (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
mk_usplice = XUntypedSplice (GhcPass 'Parsed)
-> HsUntypedSplice (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed)
forall p. XUntypedSplice p -> HsUntypedSplice p -> HsExpr p
HsUntypedSplice XUntypedSplice (GhcPass 'Parsed)
NoExtField
noExtField (HsUntypedSplice (GhcPass 'Parsed) -> HsExpr (GhcPass 'Parsed))
-> (LHsExpr (GhcPass 'Parsed) -> HsUntypedSplice (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed)
-> HsExpr (GhcPass 'Parsed)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XUntypedSpliceExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> HsUntypedSplice (GhcPass 'Parsed)
forall id.
XUntypedSpliceExpr id -> LHsExpr id -> HsUntypedSplice id
HsUntypedSpliceExpr XUntypedSpliceExpr (GhcPass 'Parsed)
forall a. NoAnn a => a
noAnn
    data_cons :: [DataCon]
data_cons = TyCon -> [Type] -> [DataCon]
getPossibleDataCons TyCon
tycon [Type]
tycon_args

    pats_etc :: (LocatedA (HsExpr (GhcPass 'Parsed)) -> a)
-> (LocatedA (HsExpr (GhcPass 'Parsed))
    -> HsExpr (GhcPass 'Parsed))
-> Name
-> DataCon
-> ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
    GenLocated e a)
pats_etc LocatedA (HsExpr (GhcPass 'Parsed)) -> a
mk_bracket LocatedA (HsExpr (GhcPass 'Parsed)) -> HsExpr (GhcPass 'Parsed)
mk_splice Name
lift_name DataCon
data_con
      = ([LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
con_pat], GenLocated e a
lift_Expr)
       where
            con_pat :: LPat (GhcPass 'Parsed)
con_pat      = RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
data_con_RDR [RdrName]
as_needed
            data_con_RDR :: RdrName
data_con_RDR = DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
data_con
            con_arity :: Int
con_arity    = DataCon -> Int
dataConSourceArity DataCon
data_con
            as_needed :: [RdrName]
as_needed    = Int -> [RdrName] -> [RdrName]
forall a. Int -> [a] -> [a]
take Int
con_arity [RdrName]
as_RDRs
            lift_Expr :: GenLocated e a
lift_Expr    = a -> GenLocated e a
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (LocatedA (HsExpr (GhcPass 'Parsed)) -> a
mk_bracket LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
br_body)
            br_body :: LHsExpr (GhcPass 'Parsed)
br_body      = IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps (Name -> RdrName
Exact (DataCon -> Name
dataConName DataCon
data_con))
                                    ((RdrName -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [RdrName] -> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a b. (a -> b) -> [a] -> [b]
map RdrName -> LHsExpr (GhcPass 'Parsed)
RdrName -> LocatedA (HsExpr (GhcPass 'Parsed))
lift_var [RdrName]
as_needed)

            lift_var :: RdrName -> LHsExpr (GhcPass 'Parsed)
            lift_var :: RdrName -> LHsExpr (GhcPass 'Parsed)
lift_var RdrName
x   = HsExpr (GhcPass 'Parsed) -> LocatedA (HsExpr (GhcPass 'Parsed))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (LocatedA (HsExpr (GhcPass 'Parsed)) -> HsExpr (GhcPass 'Parsed)
mk_splice (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar (RdrName -> LHsExpr (GhcPass 'Parsed)
mk_lift_expr RdrName
x)))

            mk_lift_expr :: RdrName -> LHsExpr (GhcPass 'Parsed)
            mk_lift_expr :: RdrName -> LHsExpr (GhcPass 'Parsed)
mk_lift_expr RdrName
x = IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps (Name -> RdrName
Exact Name
lift_name) [IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
x]

{-
************************************************************************
*                                                                      *
                     Newtype-deriving instances
*                                                                      *
************************************************************************

Note [Newtype-deriving instances]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We take every method in the original instance and `coerce` it to fit
into the derived instance. We need type applications on the argument
to `coerce` to make it obvious what instantiation of the method we're
coercing from.  So from, say,

  class C a b where
    op :: forall c. a -> [b] -> c -> Int

  newtype T x = MkT <rep-ty>

  instance C a <rep-ty> => C a (T x) where
    op @c = coerce @(a -> [<rep-ty>] -> c -> Int)
                   @(a -> [T x]      -> c -> Int)
                   (op @c)

In addition to the type applications, we also use a type abstraction to bring
the method-bound variable `c` into scope. We do this for two reasons:

* We need to bring `c` into scope over the two type applications to `coerce`.
  See Note [GND and QuantifiedConstraints] for more information on why this
  is important.
* We need to bring `c` into scope over the type application to `op`. See
  Note [GND and ambiguity] for more information on why this is important.

(In the surface syntax, only specified type variables can be used in type
abstractions. Since a method signature could contain both specified and
inferred type variables, we need an internal-only way to represent the inferred
case. We handle this by smuggling a Specificity field in XInvisPat. See
Note [Inferred invisible patterns].)

Giving 'coerce' two explicitly-visible type arguments grants us finer control
over how it should be instantiated. Recall

  coerce :: Coercible a b => a -> b

By giving it explicit type arguments we deal with the case where
'op' has a higher rank type, and so we must instantiate 'coerce' with
a polytype.  E.g.

   class C a where op :: a -> forall b. b -> b
   newtype T x = MkT <rep-ty>
   instance C <rep-ty> => C (T x) where
     op = coerce @(<rep-ty> -> forall b. b -> b)
                 @(T x      -> forall b. b -> b)
                op

The use of type applications is crucial here. We have to instantiate
both type args of (coerce :: Coercible a b => a -> b) to polytypes,
and we can only do that with VTA or Quick Look. Here VTA seems more
appropriate for machine generated code: it's simple and robust.

However, to allow VTA with polytypes we must switch on
-XImpredicativeTypes locally in GHC.Tc.Deriv.genInst.
See #8503 for more discussion.

The following Notes describe further nuances of GeneralizedNewtypeDeriving:

-----
-- In GHC.Tc.Deriv
-----

* Note [Newtype deriving]
* Note [Newtype representation]
* Note [Recursive newtypes]
* Note [Determining whether newtype-deriving is appropriate]
* Note [GND and associated type families]
* Note [Bindings for Generalised Newtype Deriving]

-----
-- In GHC.Tc.Deriv.Generate
-----

* Note [Newtype-deriving trickiness]
* Note [GND and QuantifiedConstraints]
* Note [GND and ambiguity]

Note [Inferred invisible patterns]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider the following:

  class R a where
    r :: forall b. Proxy b -> a

When newtype-deriving an instance of `R`, following
Note [GND and QuantifiedConstraints], we might generate the following code:

  instance R <rep-ty> => R <new-ty> where
    r = \ @b -> coerce @(Proxy b -> <rep-ty>)
                      @(Proxy b -> <new-ty>)
                      r

The code being generated is an HsSyn AST, except for the arguments to coerce,
which are XHsTypes carrying Core types. As Core types, they must be fully
elaborated, so we actually want something more like the following:

  instance R <rep-ty> => R <new-ty> where
    r = \ @b -> coerce @(Proxy @{k} b -> <rep-ty>)
                      @(Proxy @{k} b -> <new-ty>)
                      r

where the `k` corresponds to the `k` in the elaborated type of `r`:

  class R (a :: Type) where
    r :: forall {k :: Type} (b :: k). Proxy @{k} b -> a

However, `k` is not bound in the definition of `r` in the derived instance, and
binding it requires a way to create an inferred (because `k` is inferred in the
signature of `r`) invisible pattern.

So we actually generate the following for `R`:

  instance R <rep-ty> => R <new-ty> where
    r = \ @{k :: Type} -> \ @(b :: k) ->
            coerce @(Proxy @{k} b -> <rep-ty>)
                   @(Proxy @{k} b -> <new-ty>)
                   r

The `\ @{k :: Type} ->` (note the braces!) is the big lambda that binds `k`, and
represents an inferred invisible pattern. Inferred invisible patterns aren't
allowed in the surface syntax of Haskell, for the reason that the order in
which inferred foralls are added to a signature is not specified, so it is
ambiguous which pattern would bind to which forall. But when deriving an
instance, the patterns are being created after the type of the method has been
elaborated, so an order for the inferred foralls has already been determined.
This makes inferred invisible patterns safe for internal use.

(You might wonder if you could bring `k` into scope via the pattern signature
in `\ @(b :: k)`, but that does not work in general; e.g. if
`r :: Proxy Any -> a`; see `C5` in test `deriving-inferred-ty-arg`.)

The implementation is straightforward: we have a Specificity field in
XInvisPat, which is always SpecifiedSpec when coming from the parser or
Template Haskell, but takes the specificity of the corresponding forall from
the method type during instance deriving. When type checking an invisible
pattern, we allow inferred patterns to bind inferred foralls just like we allow
specified patterns to bind specified foralls.

More discussion of this scenario and some rejected alternatives at
https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13190

See also https://github.com/ghc-proposals/ghc-proposals/pull/675, which
was triggered by this ticket, and explores source-language syntax in this
space.

Note [Newtype-deriving trickiness]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider (#12768):
  class C a where { op :: D a => a -> a }

  instance C a  => C [a] where { op = opList }

  opList :: (C a, D [a]) => [a] -> [a]
  opList = ...

Now suppose we try GND on this:
  newtype N a = MkN [a] deriving( C )

The GND is expecting to get an implementation of op for N by
coercing opList, thus:

  instance C a => C (N a) where { op = opN }

  opN :: (C a, D (N a)) => N a -> N a
  opN = coerce @([a]   -> [a])
               @([N a] -> [N a]
               opList :: D (N a) => [N a] -> [N a]

But there is no reason to suppose that (D [a]) and (D (N a))
are inter-coercible; these instances might completely different.
So GHC rightly rejects this code.

Note [GND and QuantifiedConstraints]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider the following example from #15290:

  class C m where
    join :: m (m a) -> m a

  newtype T m a = MkT (m a)

  deriving instance
    (C m, forall p q. Coercible p q => Coercible (m p) (m q)) =>
    C (T m)

The code that GHC used to generate for this was:

  instance (C m, forall p q. Coercible p q => Coercible (m p) (m q)) =>
      C (T m) where
    join = coerce @(forall a.   m   (m a) ->   m a)
                  @(forall a. T m (T m a) -> T m a)
                  join

This instantiates `coerce` at a polymorphic type, a form of impredicative
polymorphism, so we're already on thin ice. And in fact the ice breaks,
as we'll explain:

The call to `coerce` gives rise to:

  Coercible (forall a.   m   (m a) ->   m a)
            (forall a. T m (T m a) -> T m a)

And that simplified to the following implication constraint:

  forall a <no-ev>. m (T m a) ~R# m (m a)

But because this constraint is under a `forall`, inside a type, we have to
prove it *without computing any term evidence* (hence the <no-ev>). Alas, we
*must* generate a term-level evidence binding in order to instantiate the
quantified constraint! In response, GHC currently chooses not to use such
a quantified constraint.
See Note [Instances in no-evidence implications] in GHC.Tc.Solver.Equality.

But this isn't the death knell for combining QuantifiedConstraints with GND.
On the contrary, if we generate GND bindings in a slightly different way, then
we can avoid this situation altogether. Instead of applying `coerce` to two
polymorphic types, we instead use a type abstraction to bind the type
variables, and omit the `forall`s in the type applications. More concretely, we
generate the following code instead:

  instance (C m, forall p q. Coercible p q => Coercible (m p) (m q)) =>
      C (T m) where
    join @a = coerce @(  m   (m a) ->   m a)
                     @(T m (T m a) -> T m a)
                     join

Now the visible type arguments are both monotypes, so we don't need any of this
funny quantified constraint instantiation business. While this particular
example no longer uses impredicative instantiation, we still need to enable
ImpredicativeTypes to typecheck GND-generated code for class methods with
higher-rank types. See Note [Newtype-deriving instances].

You might think that that second @(T m (T m a) -> T m a) argument is redundant
with the type information provided by the class, but in fact leaving it off
will break the following example (from the T12616 test case):

  type m ~> n = forall a. m a -> n a
  data StateT s m a = ...
  newtype OtherStateT s m a = OtherStateT (StateT s m a)

  class MonadTrans t where
    lift :: (Monad m) => m ~> t m

  instance MonadTrans (StateT s)

  instance MonadTrans (OtherStateT s) where
    lift @m = coerce @(m ~> StateT s m)
                     lift

That is because we still need to instantiate the second argument of
coerce with a polytype, and we can only do that with VTA or QuickLook.

Note [GND and ambiguity]
~~~~~~~~~~~~~~~~~~~~~~~~
We make an effort to make the code generated through GND be robust w.r.t.
ambiguous type variables. Here are a couple of examples to illustrate this:

* In this example (from #15637), the class-bound type variable `a` is ambiguous
  in the type of `f`:

    class C a where
      f :: String    -- f :: forall a. C a => String
    instance C ()
      where f = "foo"
    newtype T = T ()
      deriving C

  A naïve attempt and generating a C T instance would be:

    instance C T where
      f = coerce @String @String f

  This isn't going to typecheck, however, since GHC doesn't know what to
  instantiate the type variable `a` with in the call to `f` in the method body.
  (Note that `f :: forall a. String`!) To compensate for the possibility of
  ambiguity here, we explicitly instantiate `a` like so:

    instance C T where
      f = coerce @String @String (f @())

  All better now.

* In this example (adapted from #25148), the ambiguity arises from the `n`
  type variable bound by the type signature for `fact1`:

    class Facts a where
      fact1 :: forall n. Proxy a -> Dict (0 <= n)
    newtype T a = MkT a
      deriving newtype Facts

  When generating code for the derived `Facts` instance, we must use a type
  abstraction to bring `n` into scope over the type applications to `coerce`
  (see Note [Newtype-deriving instances] for more why this is needed). A first
  attempt at generating the instance would be:

    instance Facts a => Facts (T a) where
      fact1 @n = coerce @(Proxy    a  -> Dict (0 <= n))
                        @(Proxy (T a) -> Dict (0 <= n))
                        (fact1 @a)

  This still won't typecheck, however, as GHC doesn't know how to instantiate
  `n` in the call to `fact1 @a`. To compensate for the possibility of ambiguity
  here, we also visibly apply `n` in the call to `fact1` on the RHS:

    instance Facts a => Facts (T a) where
      fact1 @n = coerce @(Proxy    a  -> Dict (0 <= n))
                        @(Proxy (T a) -> Dict (0 <= n))
                        (fact1 @a @n) -- Note the @n here!

  This takes advantage of the fact that we *already* need to bring `n` into
  scope using a type abstraction, and so we are able to use it both for
  instantiating the call to `coerce` and instantiating the call to `fact1`.

  Note that we use this same type abstractions-based approach for resolving
  ambiguity in default methods, as described in Note [Default methods in
  instances] (Wrinkle: Ambiguous types from vanilla method type signatures) in
  GHC.Tc.TyCl.Instance.
-}

gen_Newtype_binds :: SrcSpan
                  -> Class   -- the class being derived
                  -> [TyVar] -- the tvs in the instance head (this includes
                             -- the tvs from both the class types and the
                             -- newtype itself)
                  -> [Type]  -- instance head parameters (incl. newtype)
                  -> Type    -- the representation type
                  -> LHsBinds GhcPs
-- See Note [Newtype-deriving instances]
gen_Newtype_binds :: SrcSpan
-> Class -> [Id] -> [Type] -> Type -> LHsBinds (GhcPass 'Parsed)
gen_Newtype_binds SrcSpan
loc' Class
cls [Id]
inst_tvs [Type]
inst_tys Type
rhs_ty
  = (Id
 -> GenLocated
      SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)))
-> [Id]
-> [GenLocated
      SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))]
forall a b. (a -> b) -> [a] -> [b]
map Id -> LHsBind (GhcPass 'Parsed)
Id
-> GenLocated
     SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
mk_bind (Class -> [Id]
classMethods Class
cls)
  where
    -- Same as inst_tys, but with the last argument type replaced by the
    -- representation type.
    underlying_inst_tys :: [Type]
    underlying_inst_tys :: [Type]
underlying_inst_tys = [Type] -> Type -> [Type]
forall a. [a] -> a -> [a]
changeLast [Type]
inst_tys Type
rhs_ty

    locn :: SrcSpanAnnN
locn = SrcSpan -> SrcSpanAnnN
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc'
    -- For each class method, generate its derived binding. Using the first
    -- example from
    -- Note [Newtype-deriving instances]:
    --
    --   class C a b where
    --     op :: forall c. a -> [b] -> c -> Int
    --
    --   newtype T x = MkT <rep-ty>
    --
    -- Then we would generate <derived-op-impl> below:
    --
    --   instance C a <rep-ty> => C a (T x) where
    --     <derived-op-impl>
    mk_bind :: Id -> LHsBind GhcPs
    mk_bind :: Id -> LHsBind (GhcPass 'Parsed)
mk_bind Id
meth_id
      = -- The derived binding, e.g.,
        --
        --   op @c = coerce @(a -> [<rep-ty>] -> c -> Int)
        --                  @(a -> [T x]      -> c -> Int)
        --                  op
        GenLocated SrcSpanAnnN RdrName
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkRdrFunBind GenLocated SrcSpanAnnN RdrName
loc_meth_RDR [HsMatchContext (LIdP (NoGhcTc (GhcPass 'Parsed)))
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA,
 Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns) =>
HsMatchContext (LIdP (NoGhcTc (GhcPass p)))
-> LocatedE [LPat (GhcPass p)]
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkSimpleMatch
                                      (GenLocated SrcSpanAnnN RdrName
-> AnnFunRhs -> HsMatchContext (GenLocated SrcSpanAnnN RdrName)
forall fn. fn -> AnnFunRhs -> HsMatchContext fn
mkPrefixFunRhs GenLocated SrcSpanAnnN RdrName
loc_meth_RDR AnnFunRhs
forall a. NoAnn a => a
noAnn)
                                      ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA ((VarBndr Id Specificity
 -> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed)))
-> [VarBndr Id Specificity]
-> [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall a b. (a -> b) -> [a] -> [b]
map VarBndr Id Specificity -> LPat (GhcPass 'Parsed)
VarBndr Id Specificity
-> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
mk_ty_pat [VarBndr Id Specificity]
to_tvbs)) LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
rhs_expr]

      where
        Pair Type
from_ty Type
to_ty = Class -> [Id] -> [Type] -> Type -> Id -> Pair Type
mkCoerceClassMethEqn Class
cls [Id]
inst_tvs [Type]
inst_tys Type
rhs_ty Id
meth_id
        ([Id]
_, [Type]
_, Type
from_tau)  = Type -> ([Id], [Type], Type)
tcSplitSigmaTy Type
from_ty
        ([VarBndr Id Specificity]
to_tvbs, Type
to_rho) = Type -> ([VarBndr Id Specificity], Type)
tcSplitForAllInvisTVBinders Type
to_ty
        ([Type]
_, Type
to_tau)       = Type -> ([Type], Type)
tcSplitPhiTy Type
to_rho
        -- The `to_tvbs` bind variables that are mentioned in `to_rho` and
        -- hence in `to_tau`. So we bring `to_tvbs` into scope via the
        -- `mkSimpleMatch` above, so that their use in `to_tau` in `rhs_expr`
        -- is well-scoped.

        mk_ty_pat :: VarBndr TyVar Specificity -> LPat GhcPs
        mk_ty_pat :: VarBndr Id Specificity -> LPat (GhcPass 'Parsed)
mk_ty_pat (Bndr Id
tv Specificity
spec) = Pat (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (Pat (GhcPass 'Parsed)
 -> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed)))
-> Pat (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
forall a b. (a -> b) -> a -> b
$ XInvisPat (GhcPass 'Parsed)
-> HsTyPat (NoGhcTc (GhcPass 'Parsed)) -> Pat (GhcPass 'Parsed)
forall p. XInvisPat p -> HsTyPat (NoGhcTc p) -> Pat p
InvisPat (EpToken "@"
forall a. NoAnn a => a
noAnn, Specificity
spec) (HsTyPat (NoGhcTc (GhcPass 'Parsed)) -> Pat (GhcPass 'Parsed))
-> HsTyPat (NoGhcTc (GhcPass 'Parsed)) -> Pat (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ LHsType (GhcPass 'Parsed) -> HsTyPat (GhcPass 'Parsed)
mkHsTyPat (LHsType (GhcPass 'Parsed) -> HsTyPat (GhcPass 'Parsed))
-> LHsType (GhcPass 'Parsed) -> HsTyPat (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$
          PromotionFlag -> IdP (GhcPass 'Parsed) -> LHsType (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
PromotionFlag -> IdP (GhcPass p) -> LHsType (GhcPass p)
nlHsTyVar PromotionFlag
NotPromoted (IdP (GhcPass 'Parsed) -> LHsType (GhcPass 'Parsed))
-> IdP (GhcPass 'Parsed) -> LHsType (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ Id -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName Id
tv

        meth_RDR :: RdrName
meth_RDR = Id -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName Id
meth_id
        loc_meth_RDR :: GenLocated SrcSpanAnnN RdrName
loc_meth_RDR = SrcSpanAnnN -> RdrName -> GenLocated SrcSpanAnnN RdrName
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnN
locn RdrName
meth_RDR

        rhs_expr :: LHsExpr (GhcPass 'Parsed)
rhs_expr = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar (Id -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName Id
coerceId)
                                      LHsExpr (GhcPass 'Parsed) -> Type -> LHsExpr (GhcPass 'Parsed)
`nlHsAppType`     Type
from_tau
                                      LHsExpr (GhcPass 'Parsed) -> Type -> LHsExpr (GhcPass 'Parsed)
`nlHsAppType`     Type
to_tau
                                      LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
`nlHsApp`         LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
meth_app

        -- The class method, applied to the following types to avoid potential
        -- ambiguity:
        --
        -- 1. All of the class instance types (including the representation type)
        -- 2. All of `to_tvbs`
        --
        -- See Note [GND and ambiguity].
        meth_app :: LocatedA (HsExpr (GhcPass 'Parsed))
meth_app = (LocatedA (HsExpr (GhcPass 'Parsed))
 -> Type -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> [Type]
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' LHsExpr (GhcPass 'Parsed) -> Type -> LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
-> Type -> LocatedA (HsExpr (GhcPass 'Parsed))
nlHsAppType (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
meth_RDR) ([Type] -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [Type] -> LocatedA (HsExpr (GhcPass 'Parsed))
forall a b. (a -> b) -> a -> b
$
                   TyCon -> [Type] -> [Type]
filterOutInferredTypes (Class -> TyCon
classTyCon Class
cls) [Type]
underlying_inst_tys [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ -- (1)
                   [Id -> Type
mkTyVarTy Id
tv | Bndr Id
tv Specificity
spec <- [VarBndr Id Specificity]
to_tvbs, Specificity
spec Specificity -> Specificity -> Bool
forall a. Eq a => a -> a -> Bool
/= Specificity
InferredSpec] -- (2)
                     -- Filter out any inferred arguments, since they can't be
                     -- applied with visible type application.

gen_Newtype_fam_insts :: SrcSpan
                      -> Class   -- the class being derived
                      -> [TyVar] -- the tvs in the instance head (this includes
                                 -- the tvs from both the class types and the
                                 -- newtype itself)
                      -> [Type]  -- instance head parameters (incl. newtype)
                      -> Type    -- the representation type
                      -> TcM [FamInst]
-- See Note [GND and associated type families] in GHC.Tc.Deriv
gen_Newtype_fam_insts :: SrcSpan -> Class -> [Id] -> [Type] -> Type -> TcM [FamInst]
gen_Newtype_fam_insts SrcSpan
loc' Class
cls [Id]
inst_tvs [Type]
inst_tys Type
rhs_ty
  = Bool -> TcM [FamInst] -> TcM [FamInst]
forall a. HasCallStack => Bool -> a -> a
assert ((TyCon -> Bool) -> [TyCon] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Bool -> Bool
not (Bool -> Bool) -> (TyCon -> Bool) -> TyCon -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyCon -> Bool
isDataFamilyTyCon) [TyCon]
ats) (TcM [FamInst] -> TcM [FamInst]) -> TcM [FamInst] -> TcM [FamInst]
forall a b. (a -> b) -> a -> b
$
    (TyCon -> IOEnv (Env TcGblEnv TcLclEnv) FamInst)
-> [TyCon] -> TcM [FamInst]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM TyCon -> IOEnv (Env TcGblEnv TcLclEnv) FamInst
mk_atf_inst [TyCon]
ats
  where
    -- Same as inst_tys, but with the last argument type replaced by the
    -- representation type.
    underlying_inst_tys :: [Type]
    underlying_inst_tys :: [Type]
underlying_inst_tys = [Type] -> Type -> [Type]
forall a. [a] -> a -> [a]
changeLast [Type]
inst_tys Type
rhs_ty

    ats :: [TyCon]
ats       = Class -> [TyCon]
classATs Class
cls
    locn :: SrcSpanAnnN
locn      = SrcSpan -> SrcSpanAnnN
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc'
    cls_tvs :: [Id]
cls_tvs   = Class -> [Id]
classTyVars Class
cls
    in_scope :: InScopeSet
in_scope  = [Id] -> InScopeSet
mkInScopeSetList [Id]
inst_tvs
    lhs_env :: TvSubstEnv
lhs_env   = [Id] -> [Type] -> TvSubstEnv
HasDebugCallStack => [Id] -> [Type] -> TvSubstEnv
zipTyEnv [Id]
cls_tvs [Type]
inst_tys
    lhs_subst :: Subst
lhs_subst = InScopeSet -> TvSubstEnv -> Subst
mkTvSubst InScopeSet
in_scope TvSubstEnv
lhs_env
    rhs_env :: TvSubstEnv
rhs_env   = [Id] -> [Type] -> TvSubstEnv
HasDebugCallStack => [Id] -> [Type] -> TvSubstEnv
zipTyEnv [Id]
cls_tvs [Type]
underlying_inst_tys
    rhs_subst :: Subst
rhs_subst = InScopeSet -> TvSubstEnv -> Subst
mkTvSubst InScopeSet
in_scope TvSubstEnv
rhs_env

    mk_atf_inst :: TyCon -> TcM FamInst
    mk_atf_inst :: TyCon -> IOEnv (Env TcGblEnv TcLclEnv) FamInst
mk_atf_inst TyCon
fam_tc = do
        rep_tc_name <- LocatedN Name -> [Type] -> TcM Name
newFamInstTyConName (SrcSpanAnnN -> Name -> LocatedN Name
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnN
locn (TyCon -> Name
tyConName TyCon
fam_tc))
                                           [Type]
rep_lhs_tys
        let axiom = Role
-> Name
-> [Id]
-> [Id]
-> [Id]
-> TyCon
-> [Type]
-> Type
-> CoAxiom Unbranched
mkSingleCoAxiom Role
Nominal Name
rep_tc_name [Id]
rep_tvs' [] [Id]
rep_cvs'
                                    TyCon
fam_tc [Type]
rep_lhs_tys Type
rep_rhs_ty
        checkFamPatBinders fam_tc (rep_tvs' ++ rep_cvs') emptyVarSet rep_lhs_tys rep_rhs_ty
        -- Check (c) from Note [GND and associated type families] in GHC.Tc.Deriv
        checkValidCoAxBranch fam_tc (coAxiomSingleBranch axiom)
        newFamInst SynFamilyInst axiom
      where
        fam_tvs :: [Id]
fam_tvs     = TyCon -> [Id]
tyConTyVars TyCon
fam_tc
        (Subst
_, [Type]
rep_lhs_tys) = Subst -> [Id] -> (Subst, [Type])
substATBndrs Subst
lhs_subst [Id]
fam_tvs
        (Subst
_, [Type]
rep_rhs_tys) = Subst -> [Id] -> (Subst, [Type])
substATBndrs Subst
rhs_subst [Id]
fam_tvs
        rep_rhs_ty :: Type
rep_rhs_ty  = TyCon -> [Type] -> Type
mkTyConApp TyCon
fam_tc [Type]
rep_rhs_tys
        rep_tcvs :: [Id]
rep_tcvs    = [Type] -> [Id]
tyCoVarsOfTypesList [Type]
rep_lhs_tys
        ([Id]
rep_tvs, [Id]
rep_cvs) = (Id -> Bool) -> [Id] -> ([Id], [Id])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Id -> Bool
isTyVar [Id]
rep_tcvs
        rep_tvs' :: [Id]
rep_tvs'    = [Id] -> [Id]
scopedSort [Id]
rep_tvs
        rep_cvs' :: [Id]
rep_cvs'    = [Id] -> [Id]
scopedSort [Id]
rep_cvs

nlHsAppType :: LHsExpr GhcPs -> Type -> LHsExpr GhcPs
nlHsAppType :: LHsExpr (GhcPass 'Parsed) -> Type -> LHsExpr (GhcPass 'Parsed)
nlHsAppType LHsExpr (GhcPass 'Parsed)
e Type
s = HsExpr (GhcPass 'Parsed) -> LocatedA (HsExpr (GhcPass 'Parsed))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (XAppTypeE (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsWcType (NoGhcTc (GhcPass 'Parsed))
-> HsExpr (GhcPass 'Parsed)
forall p.
XAppTypeE p -> LHsExpr p -> LHsWcType (NoGhcTc p) -> HsExpr p
HsAppType XAppTypeE (GhcPass 'Parsed)
EpToken "@"
forall a. NoAnn a => a
noAnn LHsExpr (GhcPass 'Parsed)
e LHsWcType (NoGhcTc (GhcPass 'Parsed))
HsWildCardBndrs
  (GhcPass 'Parsed)
  (GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed)))
hs_ty)
  where
    hs_ty :: HsWildCardBndrs
  (GhcPass 'Parsed)
  (GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed)))
hs_ty = GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> HsWildCardBndrs
     (GhcPass 'Parsed)
     (GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed)))
forall thing. thing -> HsWildCardBndrs (GhcPass 'Parsed) thing
mkHsWildCardBndrs (GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
 -> HsWildCardBndrs
      (GhcPass 'Parsed)
      (GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))))
-> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> HsWildCardBndrs
     (GhcPass 'Parsed)
     (GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed)))
forall a b. (a -> b) -> a -> b
$ PprPrec -> LHsType (GhcPass 'Parsed) -> LHsType (GhcPass 'Parsed)
forall (p :: Pass).
PprPrec -> LHsType (GhcPass p) -> LHsType (GhcPass p)
parenthesizeHsType PprPrec
appPrec (LHsType (GhcPass 'Parsed) -> LHsType (GhcPass 'Parsed))
-> LHsType (GhcPass 'Parsed) -> LHsType (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ Type -> LHsType (GhcPass 'Parsed)
nlHsCoreTy Type
s

nlHsCoreTy :: HsCoreTy -> LHsType GhcPs
nlHsCoreTy :: Type -> LHsType (GhcPass 'Parsed)
nlHsCoreTy = HsType (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (HsType (GhcPass 'Parsed)
 -> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed)))
-> (Type -> HsType (GhcPass 'Parsed))
-> Type
-> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XXType (GhcPass 'Parsed) -> HsType (GhcPass 'Parsed)
Type -> HsType (GhcPass 'Parsed)
forall pass. XXType pass -> HsType pass
XHsType

mkCoerceClassMethEqn :: Class   -- the class being derived
                     -> [TyVar] -- the tvs in the instance head (this includes
                                -- the tvs from both the class types and the
                                -- newtype itself)
                     -> [Type]  -- instance head parameters (incl. newtype)
                     -> Type    -- the representation type
                     -> Id      -- the method to look at
                     -> Pair Type
-- See Note [Newtype-deriving instances]
-- See also Note [Newtype-deriving trickiness]
-- The pair is the (from_type, to_type), where to_type is
-- the type of the method we are trying to get
mkCoerceClassMethEqn :: Class -> [Id] -> [Type] -> Type -> Id -> Pair Type
mkCoerceClassMethEqn Class
cls [Id]
inst_tvs [Type]
inst_tys Type
rhs_ty Id
id
  = Type -> Type -> Pair Type
forall a. a -> a -> Pair a
Pair (HasDebugCallStack => Subst -> Type -> Type
Subst -> Type -> Type
substTy Subst
rhs_subst Type
user_meth_ty)
         (HasDebugCallStack => Subst -> Type -> Type
Subst -> Type -> Type
substTy Subst
lhs_subst Type
user_meth_ty)
  where
    cls_tvs :: [Id]
cls_tvs = Class -> [Id]
classTyVars Class
cls
    in_scope :: InScopeSet
in_scope = [Id] -> InScopeSet
mkInScopeSetList [Id]
inst_tvs
    lhs_subst :: Subst
lhs_subst = InScopeSet -> TvSubstEnv -> Subst
mkTvSubst InScopeSet
in_scope ([Id] -> [Type] -> TvSubstEnv
HasDebugCallStack => [Id] -> [Type] -> TvSubstEnv
zipTyEnv [Id]
cls_tvs [Type]
inst_tys)
    rhs_subst :: Subst
rhs_subst = InScopeSet -> TvSubstEnv -> Subst
mkTvSubst InScopeSet
in_scope ([Id] -> [Type] -> TvSubstEnv
HasDebugCallStack => [Id] -> [Type] -> TvSubstEnv
zipTyEnv [Id]
cls_tvs ([Type] -> Type -> [Type]
forall a. [a] -> a -> [a]
changeLast [Type]
inst_tys Type
rhs_ty))
    ([Id]
_class_tvs, Type
_class_constraint, Type
user_meth_ty)
      = Type -> ([Id], Type, Type)
tcSplitMethodTy (Id -> Type
varType Id
id)

{-
************************************************************************
*                                                                      *
\subsection{Generating extra binds (@tag2con@, etc.)}
*                                                                      *
************************************************************************

\begin{verbatim}
data Foo ... = ...

tag2con_Foo :: Int -> Foo ...   -- easier if Int, not Int#
maxtag_Foo  :: Int              -- ditto (NB: not unlifted)
\end{verbatim}

The `tags' here start at zero, hence the @fIRST_TAG@ (currently one)
fiddling around.
-}

-- | Generate the full code for an auxiliary binding.
-- See @Note [Auxiliary binders] (Wrinkle: Reducing code duplication)@.
genAuxBindSpecOriginal :: SrcSpan -> AuxBindSpec
                       -> (LHsBind GhcPs, LSig GhcPs)
genAuxBindSpecOriginal :: SrcSpan
-> AuxBindSpec
-> (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed))
genAuxBindSpecOriginal SrcSpan
loc AuxBindSpec
spec
  = (AuxBindSpec -> LHsBind (GhcPass 'Parsed)
gen_bind AuxBindSpec
spec,
     SrcSpanAnnA
-> Sig (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed))
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnA
loca (XTypeSig (GhcPass 'Parsed)
-> [LIdP (GhcPass 'Parsed)]
-> LHsSigWcType (GhcPass 'Parsed)
-> Sig (GhcPass 'Parsed)
forall pass.
XTypeSig pass -> [LIdP pass] -> LHsSigWcType pass -> Sig pass
TypeSig XTypeSig (GhcPass 'Parsed)
AnnSig
forall a. NoAnn a => a
noAnn [SrcSpanAnnN -> RdrName -> GenLocated SrcSpanAnnN RdrName
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnN
locn (AuxBindSpec -> RdrName
auxBindSpecRdrName AuxBindSpec
spec)]
           (SrcSpan -> AuxBindSpec -> LHsSigWcType (GhcPass 'Parsed)
genAuxBindSpecSig SrcSpan
loc AuxBindSpec
spec)))
  where
    loca :: SrcSpanAnnA
loca = SrcSpan -> SrcSpanAnnA
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc
    locn :: SrcSpanAnnN
locn = SrcSpan -> SrcSpanAnnN
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc
    gen_bind :: AuxBindSpec -> LHsBind GhcPs
    gen_bind :: AuxBindSpec -> LHsBind (GhcPass 'Parsed)
gen_bind (DerivTag2Con TyCon
_ RdrName
tag2con_RDR)
      = Int
-> SrcSpan
-> RdrName
-> [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkFunBindSE Int
0 SrcSpan
loc RdrName
tag2con_RDR
           [([RdrName -> [RdrName] -> LPat (GhcPass 'Parsed)
nlConVarPat RdrName
intDataCon_RDR [RdrName
a_RDR]],
              LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
tagToEnum_RDR) LHsExpr (GhcPass 'Parsed)
a_Expr)]

    gen_bind (DerivMaxTag TyCon
tycon RdrName
maxtag_RDR)
      = SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
maxtag_RDR LHsExpr (GhcPass 'Parsed)
rhs
      where
        rhs :: LHsExpr (GhcPass 'Parsed)
rhs = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
intDataCon_RDR)
                      (HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (XHsIntPrim (GhcPass 'Parsed) -> Integer -> HsLit (GhcPass 'Parsed)
forall x. XHsIntPrim x -> Integer -> HsLit x
HsIntPrim XHsIntPrim (GhcPass 'Parsed)
SourceText
NoSourceText Integer
max_tag))
        max_tag :: Integer
max_tag =  case (TyCon -> [DataCon]
tyConDataCons TyCon
tycon) of
                     [DataCon]
data_cons -> Int -> Integer
forall a. Integral a => a -> Integer
toInteger (([DataCon] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [DataCon]
data_cons) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
fIRST_TAG)

    gen_bind (DerivDataDataType TyCon
tycon RdrName
dataT_RDR [RdrName]
dataC_RDRs)
      = SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
dataT_RDR LHsExpr (GhcPass 'Parsed)
rhs
      where
        tc_name :: Name
tc_name = TyCon -> Name
tyConName TyCon
tycon
        tc_name_string :: FastString
tc_name_string = OccName -> FastString
occNameFS (Name -> OccName
forall a. NamedThing a => a -> OccName
getOccName Name
tc_name)
        definition_mod_name :: FastString
definition_mod_name = ModuleName -> FastString
moduleNameFS (Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName (String -> Maybe Module -> Module
forall a. HasDebugCallStack => String -> Maybe a -> a
expectJust String
"gen_bind DerivDataDataType" (Maybe Module -> Module) -> Maybe Module -> Module
forall a b. (a -> b) -> a -> b
$ Name -> Maybe Module
nameModule_maybe Name
tc_name))
        rhs :: LHsExpr (GhcPass 'Parsed)
rhs = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
mkDataType_RDR
              LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
`nlHsApp` HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (FastString -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). FastString -> HsLit (GhcPass p)
mkHsStringFS ([FastString] -> FastString
concatFS [FastString
definition_mod_name, String -> FastString
fsLit String
".", FastString
tc_name_string]))
              LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
`nlHsApp` [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
nlList ((RdrName -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [RdrName] -> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a b. (a -> b) -> [a] -> [b]
map IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
RdrName -> LocatedA (HsExpr (GhcPass 'Parsed))
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar [RdrName]
dataC_RDRs)

    gen_bind (DerivDataConstr DataCon
dc RdrName
dataC_RDR RdrName
dataT_RDR)
      = SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
dataC_RDR LHsExpr (GhcPass 'Parsed)
rhs
      where
        rhs :: LHsExpr (GhcPass 'Parsed)
rhs = IdP (GhcPass 'Parsed)
-> [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [LHsExpr (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsApps IdP (GhcPass 'Parsed)
RdrName
mkConstrTag_RDR [LHsExpr (GhcPass 'Parsed)]
[LocatedA (HsExpr (GhcPass 'Parsed))]
constr_args

        constr_args :: [LocatedA (HsExpr (GhcPass 'Parsed))]
constr_args
           = [ IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
dataT_RDR                            -- DataType
             , HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (FastString -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). FastString -> HsLit (GhcPass p)
mkHsStringFS (OccName -> FastString
occNameFS OccName
dc_occ))    -- Constructor name
             , Integer -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). Integer -> LHsExpr (GhcPass p)
nlHsIntLit (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (DataCon -> Int
dataConTag DataCon
dc))       -- Constructor tag
             , [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
nlList  [LHsExpr (GhcPass 'Parsed)]
[LocatedA (HsExpr (GhcPass 'Parsed))]
labels                               -- Field labels
             , IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
fixity ]                             -- Fixity

        labels :: [LocatedA (HsExpr (GhcPass 'Parsed))]
labels   = (FieldLabel -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> [FieldLabel] -> [LocatedA (HsExpr (GhcPass 'Parsed))]
forall a b. (a -> b) -> [a] -> [b]
map (HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
HsLit (GhcPass 'Parsed) -> LocatedA (HsExpr (GhcPass 'Parsed))
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (HsLit (GhcPass 'Parsed) -> LocatedA (HsExpr (GhcPass 'Parsed)))
-> (FieldLabel -> HsLit (GhcPass 'Parsed))
-> FieldLabel
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FastString -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). FastString -> HsLit (GhcPass p)
mkHsStringFS (FastString -> HsLit (GhcPass 'Parsed))
-> (FieldLabel -> FastString)
-> FieldLabel
-> HsLit (GhcPass 'Parsed)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldLabelString -> FastString
field_label (FieldLabelString -> FastString)
-> (FieldLabel -> FieldLabelString) -> FieldLabel -> FastString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldLabel -> FieldLabelString
flLabel)
                       (DataCon -> [FieldLabel]
dataConFieldLabels DataCon
dc)
        dc_occ :: OccName
dc_occ   = DataCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName DataCon
dc
        is_infix :: Bool
is_infix = OccName -> Bool
isDataSymOcc OccName
dc_occ
        fixity :: RdrName
fixity | Bool
is_infix  = RdrName
infix_RDR
               | Bool
otherwise = RdrName
prefix_RDR

-- | Generate the code for an auxiliary binding that is a duplicate of another
-- auxiliary binding.
-- See @Note [Auxiliary binders] (Wrinkle: Reducing code duplication)@.
genAuxBindSpecDup :: SrcSpan -> RdrName -> AuxBindSpec
                  -> (LHsBind GhcPs, LSig GhcPs)
genAuxBindSpecDup :: SrcSpan
-> RdrName
-> AuxBindSpec
-> (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed))
genAuxBindSpecDup SrcSpan
loc RdrName
original_rdr_name AuxBindSpec
dup_spec
  = (SrcSpan
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsBind (GhcPass 'Parsed)
mkHsVarBind SrcSpan
loc RdrName
dup_rdr_name (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
original_rdr_name),
     SrcSpanAnnA
-> Sig (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed))
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnA
loca (XTypeSig (GhcPass 'Parsed)
-> [LIdP (GhcPass 'Parsed)]
-> LHsSigWcType (GhcPass 'Parsed)
-> Sig (GhcPass 'Parsed)
forall pass.
XTypeSig pass -> [LIdP pass] -> LHsSigWcType pass -> Sig pass
TypeSig XTypeSig (GhcPass 'Parsed)
AnnSig
forall a. NoAnn a => a
noAnn [SrcSpanAnnN -> RdrName -> GenLocated SrcSpanAnnN RdrName
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnN
locn RdrName
dup_rdr_name]
           (SrcSpan -> AuxBindSpec -> LHsSigWcType (GhcPass 'Parsed)
genAuxBindSpecSig SrcSpan
loc AuxBindSpec
dup_spec)))
  where
    loca :: SrcSpanAnnA
loca = SrcSpan -> SrcSpanAnnA
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc
    locn :: SrcSpanAnnN
locn = SrcSpan -> SrcSpanAnnN
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc
    dup_rdr_name :: RdrName
dup_rdr_name = AuxBindSpec -> RdrName
auxBindSpecRdrName AuxBindSpec
dup_spec

-- | Generate the type signature of an auxiliary binding.
-- See @Note [Auxiliary binders]@.
genAuxBindSpecSig :: SrcSpan -> AuxBindSpec -> LHsSigWcType GhcPs
genAuxBindSpecSig :: SrcSpan -> AuxBindSpec -> LHsSigWcType (GhcPass 'Parsed)
genAuxBindSpecSig SrcSpan
loc AuxBindSpec
spec = case AuxBindSpec
spec of
  DerivTag2Con TyCon
tycon RdrName
_
    -> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> HsWildCardBndrs
     (GhcPass 'Parsed)
     (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed)))
mk_sig (GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
 -> HsWildCardBndrs
      (GhcPass 'Parsed)
      (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed))))
-> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> HsWildCardBndrs
     (GhcPass 'Parsed)
     (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed)))
forall a b. (a -> b) -> a -> b
$ SrcSpanAnnA
-> HsType (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
forall l e. l -> e -> GenLocated l e
L (SrcSpan -> SrcSpanAnnA
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc) (HsType (GhcPass 'Parsed)
 -> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed)))
-> HsType (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
forall a b. (a -> b) -> a -> b
$
       XXType (GhcPass 'Parsed) -> HsType (GhcPass 'Parsed)
forall pass. XXType pass -> HsType pass
XHsType (XXType (GhcPass 'Parsed) -> HsType (GhcPass 'Parsed))
-> XXType (GhcPass 'Parsed) -> HsType (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ [Id] -> Type -> Type
mkSpecForAllTys (TyCon -> [Id]
tyConTyVars TyCon
tycon) (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$
       Type
intTy HasDebugCallStack => Type -> Type -> Type
Type -> Type -> Type
`mkVisFunTyMany` TyCon -> Type
mkParentType TyCon
tycon
  DerivMaxTag TyCon
_ RdrName
_
    -> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> HsWildCardBndrs
     (GhcPass 'Parsed)
     (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed)))
mk_sig (SrcSpanAnnA
-> HsType (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
forall l e. l -> e -> GenLocated l e
L (SrcSpan -> SrcSpanAnnA
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc) (XXType (GhcPass 'Parsed) -> HsType (GhcPass 'Parsed)
forall pass. XXType pass -> HsType pass
XHsType XXType (GhcPass 'Parsed)
Type
intTy))
  DerivDataDataType TyCon
_ RdrName
_ [RdrName]
_
    -> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> HsWildCardBndrs
     (GhcPass 'Parsed)
     (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed)))
mk_sig (PromotionFlag -> IdP (GhcPass 'Parsed) -> LHsType (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
PromotionFlag -> IdP (GhcPass p) -> LHsType (GhcPass p)
nlHsTyVar PromotionFlag
NotPromoted IdP (GhcPass 'Parsed)
RdrName
dataType_RDR)
  DerivDataConstr DataCon
_ RdrName
_ RdrName
_
    -> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> HsWildCardBndrs
     (GhcPass 'Parsed)
     (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed)))
mk_sig (PromotionFlag -> IdP (GhcPass 'Parsed) -> LHsType (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
PromotionFlag -> IdP (GhcPass p) -> LHsType (GhcPass p)
nlHsTyVar PromotionFlag
NotPromoted IdP (GhcPass 'Parsed)
RdrName
constr_RDR)
  where
    mk_sig :: GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> HsWildCardBndrs
     (GhcPass 'Parsed)
     (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed)))
mk_sig = GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed))
-> HsWildCardBndrs
     (GhcPass 'Parsed)
     (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed)))
forall thing. thing -> HsWildCardBndrs (GhcPass 'Parsed) thing
mkHsWildCardBndrs (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed))
 -> HsWildCardBndrs
      (GhcPass 'Parsed)
      (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed))))
-> (GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
    -> GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed)))
-> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> HsWildCardBndrs
     (GhcPass 'Parsed)
     (GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcSpanAnnA
-> HsSigType (GhcPass 'Parsed)
-> GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed))
forall l e. l -> e -> GenLocated l e
L (SrcSpan -> SrcSpanAnnA
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc) (HsSigType (GhcPass 'Parsed)
 -> GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed)))
-> (GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
    -> HsSigType (GhcPass 'Parsed))
-> GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> GenLocated SrcSpanAnnA (HsSigType (GhcPass 'Parsed))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LHsType (GhcPass 'Parsed) -> HsSigType (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (HsType (GhcPass 'Parsed))
-> HsSigType (GhcPass 'Parsed)
mkHsImplicitSigType

-- | Take a 'Bag' of 'AuxBindSpec's and generate the code for auxiliary
-- bindings based on the declarative descriptions in the supplied
-- 'AuxBindSpec's. See @Note [Auxiliary binders]@.
genAuxBinds :: SrcSpan -> Bag AuxBindSpec
            -> Bag (LHsBind GhcPs, LSig GhcPs)
genAuxBinds :: SrcSpan
-> Bag AuxBindSpec
-> Bag (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed))
genAuxBinds SrcSpan
loc = (OccEnv RdrName,
 Bag
   (GenLocated
      SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
    GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed))))
-> Bag
     (GenLocated
        SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
      GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
forall a b. (a, b) -> b
snd ((OccEnv RdrName,
  Bag
    (GenLocated
       SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
     GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed))))
 -> Bag
      (GenLocated
         SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
       GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed))))
-> (Bag AuxBindSpec
    -> (OccEnv RdrName,
        Bag
          (GenLocated
             SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
           GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))))
-> Bag AuxBindSpec
-> Bag
     (GenLocated
        SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
      GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AuxBindSpec
 -> (OccEnv RdrName,
     Bag
       (GenLocated
          SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
        GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed))))
 -> (OccEnv RdrName,
     Bag
       (GenLocated
          SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
        GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))))
-> (OccEnv RdrName,
    Bag
      (GenLocated
         SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
       GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed))))
-> Bag AuxBindSpec
-> (OccEnv RdrName,
    Bag
      (GenLocated
         SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
       GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed))))
forall a b. (a -> b -> b) -> b -> Bag a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr AuxBindSpec
-> (OccEnv RdrName,
    Bag (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed)))
-> (OccEnv RdrName,
    Bag (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed)))
AuxBindSpec
-> (OccEnv RdrName,
    Bag
      (GenLocated
         SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
       GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed))))
-> (OccEnv RdrName,
    Bag
      (GenLocated
         SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
       GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed))))
gen_aux_bind_spec (OccEnv RdrName
forall a. OccEnv a
emptyOccEnv, Bag
  (GenLocated
     SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
   GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
forall a. Bag a
emptyBag)
 where
  -- Perform a CSE-like pass over the generated auxiliary bindings to avoid
  -- code duplication, as described in
  -- Note [Auxiliary binders] (Wrinkle: Reducing code duplication).
  -- The OccEnv remembers the first occurrence of each sort of auxiliary
  -- binding and maps it to the unique RdrName for that binding.
  gen_aux_bind_spec :: AuxBindSpec
                    -> (OccEnv RdrName, Bag (LHsBind GhcPs, LSig GhcPs))
                    -> (OccEnv RdrName, Bag (LHsBind GhcPs, LSig GhcPs))
  gen_aux_bind_spec :: AuxBindSpec
-> (OccEnv RdrName,
    Bag (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed)))
-> (OccEnv RdrName,
    Bag (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed)))
gen_aux_bind_spec AuxBindSpec
spec (OccEnv RdrName
original_rdr_name_env, Bag (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed))
spec_bag) =
    case OccEnv RdrName -> OccName -> Maybe RdrName
forall a. OccEnv a -> OccName -> Maybe a
lookupOccEnv OccEnv RdrName
original_rdr_name_env OccName
spec_occ of
      Maybe RdrName
Nothing
        -> ( OccEnv RdrName -> OccName -> RdrName -> OccEnv RdrName
forall a. OccEnv a -> OccName -> a -> OccEnv a
extendOccEnv OccEnv RdrName
original_rdr_name_env OccName
spec_occ RdrName
spec_rdr_name
           , SrcSpan
-> AuxBindSpec
-> (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed))
genAuxBindSpecOriginal SrcSpan
loc AuxBindSpec
spec (GenLocated
   SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
 GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
-> Bag
     (GenLocated
        SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
      GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
-> Bag
     (GenLocated
        SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
      GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
forall a. a -> Bag a -> Bag a
`consBag` Bag (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed))
Bag
  (GenLocated
     SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
   GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
spec_bag )
      Just RdrName
original_rdr_name
        -> ( OccEnv RdrName
original_rdr_name_env
           , SrcSpan
-> RdrName
-> AuxBindSpec
-> (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed))
genAuxBindSpecDup SrcSpan
loc RdrName
original_rdr_name AuxBindSpec
spec (GenLocated
   SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
 GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
-> Bag
     (GenLocated
        SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
      GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
-> Bag
     (GenLocated
        SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
      GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
forall a. a -> Bag a -> Bag a
`consBag` Bag (LHsBind (GhcPass 'Parsed), LSig (GhcPass 'Parsed))
Bag
  (GenLocated
     SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)),
   GenLocated SrcSpanAnnA (Sig (GhcPass 'Parsed)))
spec_bag )
    where
      spec_rdr_name :: RdrName
spec_rdr_name = AuxBindSpec -> RdrName
auxBindSpecRdrName AuxBindSpec
spec
      spec_occ :: OccName
spec_occ      = RdrName -> OccName
rdrNameOcc RdrName
spec_rdr_name

mkParentType :: TyCon -> Type
-- Turn the representation tycon of a family into
-- a use of its family constructor
mkParentType :: TyCon -> Type
mkParentType TyCon
tc
  = case TyCon -> Maybe (TyCon, [Type])
tyConFamInst_maybe TyCon
tc of
       Maybe (TyCon, [Type])
Nothing  -> TyCon -> [Type] -> Type
mkTyConApp TyCon
tc ([Id] -> [Type]
mkTyVarTys (TyCon -> [Id]
tyConTyVars TyCon
tc))
       Just (TyCon
fam_tc,[Type]
tys) -> TyCon -> [Type] -> Type
mkTyConApp TyCon
fam_tc [Type]
tys

{-
************************************************************************
*                                                                      *
\subsection{Utility bits for generating bindings}
*                                                                      *
************************************************************************
-}

-- | Make a function binding. If no equations are given, produce a function
-- with the given arity that produces a stock error.
mkFunBindSE :: Arity -> SrcSpan -> RdrName
             -> [([LPat GhcPs], LHsExpr GhcPs)]
             -> LHsBind GhcPs
mkFunBindSE :: Int
-> SrcSpan
-> RdrName
-> [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkFunBindSE Int
arity SrcSpan
loc RdrName
fun [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
pats_and_exprs
  = Int
-> GenLocated SrcSpanAnnN RdrName
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkRdrFunBindSE Int
arity (SrcSpanAnnN -> RdrName -> GenLocated SrcSpanAnnN RdrName
forall l e. l -> e -> GenLocated l e
L (SrcSpan -> SrcSpanAnnN
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc) RdrName
fun) [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
[GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches
  where
    matches :: [GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches = [HsMatchContext (LIdP (NoGhcTc (GhcPass 'Parsed)))
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> HsLocalBinds (GhcPass 'Parsed)
-> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
forall (p :: Pass).
IsPass p =>
HsMatchContext (LIdP (NoGhcTc (GhcPass p)))
-> LocatedE [LPat (GhcPass p)]
-> LHsExpr (GhcPass p)
-> HsLocalBinds (GhcPass p)
-> LMatch (GhcPass p) (LHsExpr (GhcPass p))
mkMatch (GenLocated (Anno (IdGhcP (NoGhcTcPass 'Parsed))) RdrName
-> AnnFunRhs
-> HsMatchContext
     (GenLocated (Anno (IdGhcP (NoGhcTcPass 'Parsed))) RdrName)
forall fn. fn -> AnnFunRhs -> HsMatchContext fn
mkPrefixFunRhs (Anno (IdGhcP (NoGhcTcPass 'Parsed))
-> RdrName
-> GenLocated (Anno (IdGhcP (NoGhcTcPass 'Parsed))) RdrName
forall l e. l -> e -> GenLocated l e
L (SrcSpan -> Anno (IdGhcP (NoGhcTcPass 'Parsed))
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc) RdrName
fun) AnnFunRhs
forall a. NoAnn a => a
noAnn)
                              ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA ((GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
 -> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed)))
-> [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall a b. (a -> b) -> [a] -> [b]
map (PprPrec -> LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p)
parenthesizePat PprPrec
appPrec) [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
p)) LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
e
                               HsLocalBinds (GhcPass 'Parsed)
forall (a :: Pass) (b :: Pass).
HsLocalBindsLR (GhcPass a) (GhcPass b)
emptyLocalBinds
              | ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
p,LocatedA (HsExpr (GhcPass 'Parsed))
e) <-[([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
[([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
  LocatedA (HsExpr (GhcPass 'Parsed)))]
pats_and_exprs]

mkRdrFunBind :: LocatedN RdrName -> [LMatch GhcPs (LHsExpr GhcPs)]
             -> LHsBind GhcPs
mkRdrFunBind :: GenLocated SrcSpanAnnN RdrName
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkRdrFunBind fun :: GenLocated SrcSpanAnnN RdrName
fun@(L SrcSpanAnnN
loc RdrName
_fun_rdr) [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
matches
  = SrcSpanAnnA
-> HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)
-> GenLocated
     SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
forall l e. l -> e -> GenLocated l e
L (SrcSpanAnnN -> SrcSpanAnnA
forall a b. (HasLoc a, HasAnnotation b) => a -> b
l2l SrcSpanAnnN
loc) (Origin
-> GenLocated SrcSpanAnnN RdrName
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)
mkFunBind (GenReason -> DoPmc -> Origin
Generated GenReason
OtherExpansion DoPmc
SkipPmc) GenLocated SrcSpanAnnN RdrName
fun [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
matches)

-- | Make a function binding. If no equations are given, produce a function
-- with the given arity that uses an empty case expression for the last
-- argument that is passes to the given function to produce the right-hand
-- side.
mkFunBindEC :: Arity -> SrcSpan -> RdrName
            -> (LHsExpr GhcPs -> LHsExpr GhcPs)
            -> [([LPat GhcPs], LHsExpr GhcPs)]
            -> LHsBind GhcPs
mkFunBindEC :: Int
-> SrcSpan
-> RdrName
-> (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkFunBindEC Int
arity SrcSpan
loc RdrName
fun LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
catch_all [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
pats_and_exprs
  = Int
-> (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> GenLocated SrcSpanAnnN RdrName
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkRdrFunBindEC Int
arity LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
catch_all (SrcSpanAnnN -> RdrName -> GenLocated SrcSpanAnnN RdrName
forall l e. l -> e -> GenLocated l e
L (SrcSpan -> SrcSpanAnnN
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc) RdrName
fun) [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
[GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches
  where
    matches :: [GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches = [ HsMatchContext (LIdP (NoGhcTc (GhcPass 'Parsed)))
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> HsLocalBinds (GhcPass 'Parsed)
-> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
forall (p :: Pass).
IsPass p =>
HsMatchContext (LIdP (NoGhcTc (GhcPass p)))
-> LocatedE [LPat (GhcPass p)]
-> LHsExpr (GhcPass p)
-> HsLocalBinds (GhcPass p)
-> LMatch (GhcPass p) (LHsExpr (GhcPass p))
mkMatch (GenLocated (Anno (IdGhcP (NoGhcTcPass 'Parsed))) RdrName
-> AnnFunRhs
-> HsMatchContext
     (GenLocated (Anno (IdGhcP (NoGhcTcPass 'Parsed))) RdrName)
forall fn. fn -> AnnFunRhs -> HsMatchContext fn
mkPrefixFunRhs (Anno (IdGhcP (NoGhcTcPass 'Parsed))
-> RdrName
-> GenLocated (Anno (IdGhcP (NoGhcTcPass 'Parsed))) RdrName
forall l e. l -> e -> GenLocated l e
L (SrcSpan -> Anno (IdGhcP (NoGhcTcPass 'Parsed))
forall e. HasAnnotation e => SrcSpan -> e
noAnnSrcSpan SrcSpan
loc) RdrName
fun) AnnFunRhs
forall a. NoAnn a => a
noAnn)
                                ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA ((GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
 -> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed)))
-> [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall a b. (a -> b) -> [a] -> [b]
map (PprPrec -> LPat (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
PprPrec -> LPat (GhcPass p) -> LPat (GhcPass p)
parenthesizePat PprPrec
appPrec) [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
p)) LHsExpr (GhcPass 'Parsed)
LocatedA (HsExpr (GhcPass 'Parsed))
e
                                HsLocalBinds (GhcPass 'Parsed)
forall (a :: Pass) (b :: Pass).
HsLocalBindsLR (GhcPass a) (GhcPass b)
emptyLocalBinds
              | ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
p,LocatedA (HsExpr (GhcPass 'Parsed))
e) <- [([LPat (GhcPass 'Parsed)], LHsExpr (GhcPass 'Parsed))]
[([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))],
  LocatedA (HsExpr (GhcPass 'Parsed)))]
pats_and_exprs ]

-- | Produces a function binding. When no equations are given, it generates
-- a binding of the given arity and an empty case expression
-- for the last argument that it passes to the given function to produce
-- the right-hand side.
mkRdrFunBindEC :: Arity
               -> (LHsExpr GhcPs -> LHsExpr GhcPs)
               -> LocatedN RdrName
               -> [LMatch GhcPs (LHsExpr GhcPs)]
               -> LHsBind GhcPs
mkRdrFunBindEC :: Int
-> (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> GenLocated SrcSpanAnnN RdrName
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkRdrFunBindEC Int
arity LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
catch_all fun :: GenLocated SrcSpanAnnN RdrName
fun@(L SrcSpanAnnN
loc RdrName
_fun_rdr) [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
matches
  = SrcSpanAnnA
-> HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)
-> GenLocated
     SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
forall l e. l -> e -> GenLocated l e
L (SrcSpanAnnN -> SrcSpanAnnA
forall a b. (HasLoc a, HasAnnotation b) => a -> b
l2l SrcSpanAnnN
loc) (Origin
-> GenLocated SrcSpanAnnN RdrName
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)
mkFunBind (GenReason -> DoPmc -> Origin
Generated GenReason
OtherExpansion DoPmc
SkipPmc) GenLocated SrcSpanAnnN RdrName
fun [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
[GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches')
 where
   -- Catch-all eqn looks like
   --     fmap _ z = case z of {}
   -- or
   --     traverse _ z = pure (case z of)
   -- or
   --     foldMap _ z = mempty
   -- It's needed if there no data cons at all,
   -- which can happen with -XEmptyDataDecls
   -- See #4302
   matches' :: [GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches' = if [GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
[GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches
              then [HsMatchContext (LIdP (NoGhcTc (GhcPass 'Parsed)))
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> HsLocalBinds (GhcPass 'Parsed)
-> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
forall (p :: Pass).
IsPass p =>
HsMatchContext (LIdP (NoGhcTc (GhcPass p)))
-> LocatedE [LPat (GhcPass p)]
-> LHsExpr (GhcPass p)
-> HsLocalBinds (GhcPass p)
-> LMatch (GhcPass p) (LHsExpr (GhcPass p))
mkMatch (GenLocated SrcSpanAnnN RdrName
-> AnnFunRhs -> HsMatchContext (GenLocated SrcSpanAnnN RdrName)
forall fn. fn -> AnnFunRhs -> HsMatchContext fn
mkPrefixFunRhs GenLocated SrcSpanAnnN RdrName
fun AnnFunRhs
forall a. NoAnn a => a
noAnn)
                            ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (Int
-> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
-> [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall a. Int -> a -> [a]
replicate (Int
arity Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
nlWildPat) [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall a. [a] -> [a] -> [a]
++ [LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
z_Pat]))
                            (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
catch_all (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase LHsExpr (GhcPass 'Parsed)
z_Expr [])
                            HsLocalBinds (GhcPass 'Parsed)
forall (a :: Pass) (b :: Pass).
HsLocalBindsLR (GhcPass a) (GhcPass b)
emptyLocalBinds]
              else [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
[GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches

-- | Produces a function binding. When there are no equations, it generates
-- a binding with the given arity that produces an error based on the name of
-- the type of the last argument.
mkRdrFunBindSE :: Arity -> LocatedN RdrName ->
                    [LMatch GhcPs (LHsExpr GhcPs)] -> LHsBind GhcPs
mkRdrFunBindSE :: Int
-> GenLocated SrcSpanAnnN RdrName
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsBind (GhcPass 'Parsed)
mkRdrFunBindSE Int
arity fun :: GenLocated SrcSpanAnnN RdrName
fun@(L SrcSpanAnnN
loc RdrName
fun_rdr) [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
matches
  = SrcSpanAnnA
-> HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)
-> GenLocated
     SrcSpanAnnA (HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed))
forall l e. l -> e -> GenLocated l e
L (SrcSpanAnnN -> SrcSpanAnnA
forall a b. (HasLoc a, HasAnnotation b) => a -> b
l2l SrcSpanAnnN
loc) (Origin
-> GenLocated SrcSpanAnnN RdrName
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> HsBindLR (GhcPass 'Parsed) (GhcPass 'Parsed)
mkFunBind (GenReason -> DoPmc -> Origin
Generated GenReason
OtherExpansion DoPmc
SkipPmc) GenLocated SrcSpanAnnN RdrName
fun [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
[GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches')
 where
   -- Catch-all eqn looks like
   --     compare _ _ = error "Void compare"
   -- It's needed if there no data cons at all,
   -- which can happen with -XEmptyDataDecls
   -- See #4302
   matches' :: [GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches' = if [GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
-> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
[GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches
              then [HsMatchContext (LIdP (NoGhcTc (GhcPass 'Parsed)))
-> LocatedE [LPat (GhcPass 'Parsed)]
-> LHsExpr (GhcPass 'Parsed)
-> HsLocalBinds (GhcPass 'Parsed)
-> LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))
forall (p :: Pass).
IsPass p =>
HsMatchContext (LIdP (NoGhcTc (GhcPass p)))
-> LocatedE [LPat (GhcPass p)]
-> LHsExpr (GhcPass p)
-> HsLocalBinds (GhcPass p)
-> LMatch (GhcPass p) (LHsExpr (GhcPass p))
mkMatch (GenLocated SrcSpanAnnN RdrName
-> AnnFunRhs -> HsMatchContext (GenLocated SrcSpanAnnN RdrName)
forall fn. fn -> AnnFunRhs -> HsMatchContext fn
mkPrefixFunRhs GenLocated SrcSpanAnnN RdrName
fun AnnFunRhs
forall a. NoAnn a => a
noAnn)
                            ([GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
-> GenLocated
     EpaLocation [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall e a. HasAnnotation e => a -> GenLocated e a
noLocA (Int
-> GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
-> [GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))]
forall a. Int -> a -> [a]
replicate Int
arity LPat (GhcPass 'Parsed)
GenLocated SrcSpanAnnA (Pat (GhcPass 'Parsed))
nlWildPat))
                            (FastString -> LHsExpr (GhcPass 'Parsed)
error_Expr FastString
str) HsLocalBinds (GhcPass 'Parsed)
forall (a :: Pass) (b :: Pass).
HsLocalBindsLR (GhcPass a) (GhcPass b)
emptyLocalBinds]
              else [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
[GenLocated
   SrcSpanAnnA
   (Match (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed))))]
matches
   str :: FastString
str = String -> FastString
fsLit String
"Void " FastString -> FastString -> FastString
`appendFS` OccName -> FastString
occNameFS (RdrName -> OccName
rdrNameOcc RdrName
fun_rdr)


box ::         String           -- The class involved
            -> LHsExpr GhcPs    -- The argument
            -> Type             -- The argument type
            -> LHsExpr GhcPs    -- Boxed version of the arg
-- See Note [Deriving and unboxed types] in GHC.Tc.Deriv.Infer
box :: String
-> LHsExpr (GhcPass 'Parsed) -> Type -> LHsExpr (GhcPass 'Parsed)
box String
cls_str LHsExpr (GhcPass 'Parsed)
arg Type
arg_ty = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (String
-> [(Type, LocatedA (HsExpr (GhcPass 'Parsed)))]
-> Type
-> LocatedA (HsExpr (GhcPass 'Parsed))
forall a. HasDebugCallStack => String -> [(Type, a)] -> Type -> a
assoc_ty_id String
cls_str [(Type, LHsExpr (GhcPass 'Parsed))]
[(Type, LocatedA (HsExpr (GhcPass 'Parsed)))]
boxConTbl Type
arg_ty) LHsExpr (GhcPass 'Parsed)
arg

---------------------
primOrdOps :: String    -- The class involved
           -> Type      -- The type
           -> (RdrName, RdrName, RdrName, RdrName, RdrName)  -- (lt,le,eq,ge,gt)
-- See Note [Deriving and unboxed types] in GHC.Tc.Deriv.Infer
primOrdOps :: String -> Type -> (RdrName, RdrName, RdrName, RdrName, RdrName)
primOrdOps String
str Type
ty = String
-> [(Type, (RdrName, RdrName, RdrName, RdrName, RdrName))]
-> Type
-> (RdrName, RdrName, RdrName, RdrName, RdrName)
forall a. HasDebugCallStack => String -> [(Type, a)] -> Type -> a
assoc_ty_id String
str [(Type, (RdrName, RdrName, RdrName, RdrName, RdrName))]
ordOpTbl Type
ty

ordOpTbl :: [(Type, (RdrName, RdrName, RdrName, RdrName, RdrName))]
ordOpTbl :: [(Type, (RdrName, RdrName, RdrName, RdrName, RdrName))]
ordOpTbl
 =  [(Type
charPrimTy  , (RdrName
ltChar_RDR  , RdrName
leChar_RDR
     , RdrName
eqChar_RDR  , RdrName
geChar_RDR  , RdrName
gtChar_RDR  ))
    ,(Type
intPrimTy   , (RdrName
ltInt_RDR   , RdrName
leInt_RDR
     , RdrName
eqInt_RDR   , RdrName
geInt_RDR   , RdrName
gtInt_RDR   ))
    ,(Type
int8PrimTy  , (RdrName
ltInt8_RDR  , RdrName
leInt8_RDR
     , RdrName
eqInt8_RDR  , RdrName
geInt8_RDR  , RdrName
gtInt8_RDR   ))
    ,(Type
int16PrimTy , (RdrName
ltInt16_RDR , RdrName
leInt16_RDR
     , RdrName
eqInt16_RDR , RdrName
geInt16_RDR , RdrName
gtInt16_RDR   ))
    ,(Type
int32PrimTy , (RdrName
ltInt32_RDR , RdrName
leInt32_RDR
     , RdrName
eqInt32_RDR , RdrName
geInt32_RDR , RdrName
gtInt32_RDR   ))
    ,(Type
int64PrimTy , (RdrName
ltInt64_RDR , RdrName
leInt64_RDR
     , RdrName
eqInt64_RDR , RdrName
geInt64_RDR , RdrName
gtInt64_RDR   ))
    ,(Type
wordPrimTy  , (RdrName
ltWord_RDR  , RdrName
leWord_RDR
     , RdrName
eqWord_RDR  , RdrName
geWord_RDR  , RdrName
gtWord_RDR  ))
    ,(Type
word8PrimTy , (RdrName
ltWord8_RDR , RdrName
leWord8_RDR
     , RdrName
eqWord8_RDR , RdrName
geWord8_RDR , RdrName
gtWord8_RDR   ))
    ,(Type
word16PrimTy, (RdrName
ltWord16_RDR, RdrName
leWord16_RDR
     , RdrName
eqWord16_RDR, RdrName
geWord16_RDR, RdrName
gtWord16_RDR  ))
    ,(Type
word32PrimTy, (RdrName
ltWord32_RDR, RdrName
leWord32_RDR
     , RdrName
eqWord32_RDR, RdrName
geWord32_RDR, RdrName
gtWord32_RDR  ))
    ,(Type
word64PrimTy, (RdrName
ltWord64_RDR, RdrName
leWord64_RDR
     , RdrName
eqWord64_RDR, RdrName
geWord64_RDR, RdrName
gtWord64_RDR  ))
    ,(Type
addrPrimTy  , (RdrName
ltAddr_RDR  , RdrName
leAddr_RDR
     , RdrName
eqAddr_RDR  , RdrName
geAddr_RDR  , RdrName
gtAddr_RDR  ))
    ,(Type
floatPrimTy , (RdrName
ltFloat_RDR , RdrName
leFloat_RDR
     , RdrName
eqFloat_RDR , RdrName
geFloat_RDR , RdrName
gtFloat_RDR ))
    ,(Type
doublePrimTy, (RdrName
ltDouble_RDR, RdrName
leDouble_RDR
     , RdrName
eqDouble_RDR, RdrName
geDouble_RDR, RdrName
gtDouble_RDR)) ]

-- A mapping from a primitive type to a DataCon of its boxed version.
boxConTbl :: [(Type, LHsExpr GhcPs)]
boxConTbl :: [(Type, LHsExpr (GhcPass 'Parsed))]
boxConTbl =
    [ (Type
charPrimTy  , IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
charDataCon)
    , (Type
intPrimTy   , IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
intDataCon)
    , (Type
wordPrimTy  , IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
wordDataCon)
    , (Type
floatPrimTy , IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
floatDataCon)
    , (Type
doublePrimTy, IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed))
-> IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall a b. (a -> b) -> a -> b
$ DataCon -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName DataCon
doubleDataCon)
    , (Type
int8PrimTy,   IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
int8DataCon_RDR)
    , (Type
word8PrimTy,  IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
word8DataCon_RDR)
    , (Type
int16PrimTy,  IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
int16DataCon_RDR)
    , (Type
word16PrimTy, IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
word16DataCon_RDR)
    , (Type
int32PrimTy,  IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
int32DataCon_RDR)
    , (Type
word32PrimTy, IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
word32DataCon_RDR)
    , (Type
int64PrimTy,  IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
int64DataCon_RDR)
    , (Type
word64PrimTy, IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
word64DataCon_RDR)
    ]


-- | A table of postfix modifiers for unboxed values.
-- Following https://github.com/ghc-proposals/ghc-proposals/pull/596,
-- we use the ExtendedLiterals syntax for sized literals.
postfixModTbl :: [(Type, String)]
postfixModTbl :: [(Type, String)]
postfixModTbl
  = [(Type
charPrimTy  , String
"#" )
    ,(Type
intPrimTy   , String
"#" )
    ,(Type
wordPrimTy  , String
"##")
    ,(Type
floatPrimTy , String
"#" )
    ,(Type
doublePrimTy, String
"##")
    ,(Type
int8PrimTy  , String
"#Int8")
    ,(Type
word8PrimTy , String
"#Word8")
    ,(Type
int16PrimTy , String
"#Int16")
    ,(Type
word16PrimTy, String
"#Word16")
    ,(Type
int32PrimTy , String
"#Int32")
    ,(Type
word32PrimTy, String
"#Word32")
    ,(Type
int64PrimTy , String
"#Int64")
    ,(Type
word64PrimTy, String
"#Word64")
    ]

-- | Lookup `Type` in an association list.
assoc_ty_id :: HasDebugCallStack => String           -- The class involved
            -> [(Type,a)]       -- The table
            -> Type             -- The type
            -> a                -- The result of the lookup
assoc_ty_id :: forall a. HasDebugCallStack => String -> [(Type, a)] -> Type -> a
assoc_ty_id String
cls_str [(Type, a)]
tbl Type
ty
  | Just a
a <- [(Type, a)] -> Type -> Maybe a
forall a. [(Type, a)] -> Type -> Maybe a
assoc_ty_id_maybe [(Type, a)]
tbl Type
ty = a
a
  | Bool
otherwise =
      String -> SDoc -> a
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"Error in deriving:"
          (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Can't derive" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
cls_str SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
           String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"for primitive type" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)

-- | Lookup `Type` in an association list.
assoc_ty_id_maybe :: [(Type, a)] -> Type -> Maybe a
assoc_ty_id_maybe :: forall a. [(Type, a)] -> Type -> Maybe a
assoc_ty_id_maybe [(Type, a)]
tbl Type
ty = (Type, a) -> a
forall a b. (a, b) -> b
snd ((Type, a) -> a) -> Maybe (Type, a) -> Maybe a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Type, a) -> Bool) -> [(Type, a)] -> Maybe (Type, a)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\(Type
t, a
_) -> Type
t HasCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`eqType` Type
ty) [(Type, a)]
tbl

-----------------------------------------------------------------------

and_Expr :: LHsExpr GhcPs -> LHsExpr GhcPs -> LHsExpr GhcPs
and_Expr :: LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
and_Expr LHsExpr (GhcPass 'Parsed)
a LHsExpr (GhcPass 'Parsed)
b = LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genOpApp LHsExpr (GhcPass 'Parsed)
a RdrName
and_RDR    LHsExpr (GhcPass 'Parsed)
b

-----------------------------------------------------------------------

eq_Expr :: Type -> LHsExpr GhcPs -> LHsExpr GhcPs -> LHsExpr GhcPs
eq_Expr :: Type
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
eq_Expr Type
ty LHsExpr (GhcPass 'Parsed)
a LHsExpr (GhcPass 'Parsed)
b
    | Bool -> Bool
not (HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType Type
ty) = LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genOpApp LHsExpr (GhcPass 'Parsed)
a RdrName
eq_RDR LHsExpr (GhcPass 'Parsed)
b
    | Bool
otherwise               = LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genPrimOpApp LHsExpr (GhcPass 'Parsed)
a RdrName
prim_eq LHsExpr (GhcPass 'Parsed)
b
 where
   (RdrName
_, RdrName
_, RdrName
prim_eq, RdrName
_, RdrName
_) = String -> Type -> (RdrName, RdrName, RdrName, RdrName, RdrName)
primOrdOps String
"Eq" Type
ty

untag_Expr :: [(RdrName, RdrName)]
           -> LHsExpr GhcPs -> LHsExpr GhcPs
untag_Expr :: [(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [] LHsExpr (GhcPass 'Parsed)
expr = LHsExpr (GhcPass 'Parsed)
expr
untag_Expr ((RdrName
untag_this, RdrName
put_tag_here) : [(RdrName, RdrName)]
more) LHsExpr (GhcPass 'Parsed)
expr
  = LHsExpr (GhcPass 'Parsed)
-> [LMatch (GhcPass 'Parsed) (LHsExpr (GhcPass 'Parsed))]
-> LHsExpr (GhcPass 'Parsed)
nlHsCase (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar (IdP (GhcPass 'Parsed)
-> [IdP (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> [IdP (GhcPass p)] -> LHsExpr (GhcPass p)
nlHsVarApps IdP (GhcPass 'Parsed)
RdrName
dataToTag_RDR [IdP (GhcPass 'Parsed)
RdrName
untag_this])) {-of-}
      [LPat (GhcPass 'Parsed)
-> LocatedA (HsExpr (GhcPass 'Parsed))
-> LMatch (GhcPass 'Parsed) (LocatedA (HsExpr (GhcPass 'Parsed)))
forall (p :: Pass) (body :: * -> *).
(Anno (GRHS (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ EpAnn NoEpAnns,
 Anno (Match (GhcPass p) (LocatedA (body (GhcPass p))))
 ~ SrcSpanAnnA) =>
LPat (GhcPass p)
-> LocatedA (body (GhcPass p))
-> LMatch (GhcPass p) (LocatedA (body (GhcPass p)))
mkHsCaseAlt (IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
put_tag_here) ([(RdrName, RdrName)]
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
untag_Expr [(RdrName, RdrName)]
more LHsExpr (GhcPass 'Parsed)
expr)]

enum_from_to_Expr
        :: LHsExpr GhcPs -> LHsExpr GhcPs
        -> LHsExpr GhcPs
enum_from_then_to_Expr
        :: LHsExpr GhcPs -> LHsExpr GhcPs -> LHsExpr GhcPs
        -> LHsExpr GhcPs

enum_from_to_Expr :: LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
enum_from_to_Expr      LHsExpr (GhcPass 'Parsed)
f   LHsExpr (GhcPass 'Parsed)
t2 = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
enumFromTo_RDR) LHsExpr (GhcPass 'Parsed)
f) LHsExpr (GhcPass 'Parsed)
t2
enum_from_then_to_Expr :: LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
enum_from_then_to_Expr LHsExpr (GhcPass 'Parsed)
f LHsExpr (GhcPass 'Parsed)
t LHsExpr (GhcPass 'Parsed)
t2 = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
enumFromThenTo_RDR) LHsExpr (GhcPass 'Parsed)
f) LHsExpr (GhcPass 'Parsed)
t) LHsExpr (GhcPass 'Parsed)
t2

showParen_Expr
        :: LHsExpr GhcPs -> LHsExpr GhcPs
        -> LHsExpr GhcPs

showParen_Expr :: LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
showParen_Expr LHsExpr (GhcPass 'Parsed)
e1 LHsExpr (GhcPass 'Parsed)
e2 = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
showParen_RDR) LHsExpr (GhcPass 'Parsed)
e1) LHsExpr (GhcPass 'Parsed)
e2

nested_compose_Expr :: [LHsExpr GhcPs] -> LHsExpr GhcPs

nested_compose_Expr :: [LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
nested_compose_Expr []  = String -> LocatedA (HsExpr (GhcPass 'Parsed))
forall a. HasCallStack => String -> a
panic String
"nested_compose_expr"   -- Arg is always non-empty
nested_compose_Expr [LHsExpr (GhcPass 'Parsed)
e] = LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
parenify LHsExpr (GhcPass 'Parsed)
e
nested_compose_Expr (LHsExpr (GhcPass 'Parsed)
e:[LHsExpr (GhcPass 'Parsed)]
es)
  = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
compose_RDR) (LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
parenify LHsExpr (GhcPass 'Parsed)
e)) ([LHsExpr (GhcPass 'Parsed)] -> LHsExpr (GhcPass 'Parsed)
nested_compose_Expr [LHsExpr (GhcPass 'Parsed)]
es)

-- impossible_Expr is used in case RHSs that should never happen.
-- We generate these to keep the desugarer from complaining that they *might* happen!
error_Expr :: FastString -> LHsExpr GhcPs
error_Expr :: FastString -> LHsExpr (GhcPass 'Parsed)
error_Expr FastString
string = LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
error_RDR) (HsLit (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass). HsLit (GhcPass p) -> LHsExpr (GhcPass p)
nlHsLit (FastString -> HsLit (GhcPass 'Parsed)
forall (p :: Pass). FastString -> HsLit (GhcPass p)
mkHsStringFS FastString
string))

parenify :: LHsExpr GhcPs -> LHsExpr GhcPs
parenify :: LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
parenify e :: LHsExpr (GhcPass 'Parsed)
e@(L SrcSpanAnnA
_ (HsVar XVar (GhcPass 'Parsed)
_ LIdP (GhcPass 'Parsed)
_)) = LHsExpr (GhcPass 'Parsed)
e
parenify LHsExpr (GhcPass 'Parsed)
e                   = LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
mkHsPar LHsExpr (GhcPass 'Parsed)
e

-- genOpApp wraps brackets round the operator application, so that the
-- renamer won't subsequently try to re-associate it.
genOpApp :: LHsExpr GhcPs -> RdrName -> LHsExpr GhcPs -> LHsExpr GhcPs
genOpApp :: LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genOpApp LHsExpr (GhcPass 'Parsed)
e1 RdrName
op LHsExpr (GhcPass 'Parsed)
e2 = LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar (LHsExpr (GhcPass 'Parsed)
-> IdP (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsOpApp LHsExpr (GhcPass 'Parsed)
e1 IdP (GhcPass 'Parsed)
RdrName
op LHsExpr (GhcPass 'Parsed)
e2)

genPrimOpApp :: LHsExpr GhcPs -> RdrName -> LHsExpr GhcPs -> LHsExpr GhcPs
genPrimOpApp :: LHsExpr (GhcPass 'Parsed)
-> RdrName
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
genPrimOpApp LHsExpr (GhcPass 'Parsed)
e1 RdrName
op LHsExpr (GhcPass 'Parsed)
e2 = LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass).
IsPass p =>
LHsExpr (GhcPass p) -> LHsExpr (GhcPass p)
nlHsPar (LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (id :: Pass).
IsPass id =>
LHsExpr (GhcPass id)
-> LHsExpr (GhcPass id) -> LHsExpr (GhcPass id)
nlHsApp (IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
tagToEnum_RDR) (LHsExpr (GhcPass 'Parsed)
-> IdP (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
-> LHsExpr (GhcPass 'Parsed)
nlHsOpApp LHsExpr (GhcPass 'Parsed)
e1 IdP (GhcPass 'Parsed)
RdrName
op LHsExpr (GhcPass 'Parsed)
e2))

a_RDR, b_RDR, c_RDR, d_RDR, f_RDR, k_RDR, z_RDR, ah_RDR, bh_RDR, ch_RDR, dh_RDR
    :: RdrName
a_RDR :: RdrName
a_RDR           = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"a")
b_RDR :: RdrName
b_RDR           = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"b")
c_RDR :: RdrName
c_RDR           = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"c")
d_RDR :: RdrName
d_RDR           = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"d")
f_RDR :: RdrName
f_RDR           = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"f")
k_RDR :: RdrName
k_RDR           = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"k")
z_RDR :: RdrName
z_RDR           = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"z")
ah_RDR :: RdrName
ah_RDR          = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"a#")
bh_RDR :: RdrName
bh_RDR          = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"b#")
ch_RDR :: RdrName
ch_RDR          = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"c#")
dh_RDR :: RdrName
dh_RDR          = FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
"d#")

as_RDRs, bs_RDRs, cs_RDRs :: [RdrName]
as_RDRs :: [RdrName]
as_RDRs         = [ FastString -> RdrName
mkVarUnqual (String -> FastString
mkFastString (String
"a"String -> String -> String
forall a. [a] -> [a] -> [a]
++Int -> String
forall a. Show a => a -> String
show Int
i)) | Int
i <- [(Int
1::Int) .. ] ]
bs_RDRs :: [RdrName]
bs_RDRs         = [ FastString -> RdrName
mkVarUnqual (String -> FastString
mkFastString (String
"b"String -> String -> String
forall a. [a] -> [a] -> [a]
++Int -> String
forall a. Show a => a -> String
show Int
i)) | Int
i <- [(Int
1::Int) .. ] ]
cs_RDRs :: [RdrName]
cs_RDRs         = [ FastString -> RdrName
mkVarUnqual (String -> FastString
mkFastString (String
"c"String -> String -> String
forall a. [a] -> [a] -> [a]
++Int -> String
forall a. Show a => a -> String
show Int
i)) | Int
i <- [(Int
1::Int) .. ] ]

a_Expr, b_Expr, c_Expr, z_Expr, ltTag_Expr, eqTag_Expr, gtTag_Expr, false_Expr,
    true_Expr, pure_Expr, unsafeCodeCoerce_Expr :: LHsExpr GhcPs
a_Expr :: LHsExpr (GhcPass 'Parsed)
a_Expr                = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
a_RDR
b_Expr :: LHsExpr (GhcPass 'Parsed)
b_Expr                = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
b_RDR
c_Expr :: LHsExpr (GhcPass 'Parsed)
c_Expr                = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
c_RDR
z_Expr :: LHsExpr (GhcPass 'Parsed)
z_Expr                = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
z_RDR
ltTag_Expr :: LHsExpr (GhcPass 'Parsed)
ltTag_Expr            = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
ltTag_RDR
eqTag_Expr :: LHsExpr (GhcPass 'Parsed)
eqTag_Expr            = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
eqTag_RDR
gtTag_Expr :: LHsExpr (GhcPass 'Parsed)
gtTag_Expr            = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
gtTag_RDR
false_Expr :: LHsExpr (GhcPass 'Parsed)
false_Expr            = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
false_RDR
true_Expr :: LHsExpr (GhcPass 'Parsed)
true_Expr             = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
true_RDR
pure_Expr :: LHsExpr (GhcPass 'Parsed)
pure_Expr             = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
pure_RDR
unsafeCodeCoerce_Expr :: LHsExpr (GhcPass 'Parsed)
unsafeCodeCoerce_Expr = IdP (GhcPass 'Parsed) -> LHsExpr (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LHsExpr (GhcPass p)
nlHsVar IdP (GhcPass 'Parsed)
RdrName
unsafeCodeCoerce_RDR

a_Pat, b_Pat, c_Pat, d_Pat, k_Pat, z_Pat :: LPat GhcPs
a_Pat :: LPat (GhcPass 'Parsed)
a_Pat           = IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
a_RDR
b_Pat :: LPat (GhcPass 'Parsed)
b_Pat           = IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
b_RDR
c_Pat :: LPat (GhcPass 'Parsed)
c_Pat           = IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
c_RDR
d_Pat :: LPat (GhcPass 'Parsed)
d_Pat           = IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
d_RDR
k_Pat :: LPat (GhcPass 'Parsed)
k_Pat           = IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
k_RDR
z_Pat :: LPat (GhcPass 'Parsed)
z_Pat           = IdP (GhcPass 'Parsed) -> LPat (GhcPass 'Parsed)
forall (p :: Pass) a.
IsSrcSpanAnn p a =>
IdP (GhcPass p) -> LPat (GhcPass p)
nlVarPat IdP (GhcPass 'Parsed)
RdrName
z_RDR

minusInt_RDR, tagToEnum_RDR :: RdrName
minusInt_RDR :: RdrName
minusInt_RDR  = Id -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName (PrimOp -> Id
primOpId PrimOp
IntSubOp   )
tagToEnum_RDR :: RdrName
tagToEnum_RDR = Id -> RdrName
forall thing. NamedThing thing => thing -> RdrName
getRdrName (PrimOp -> Id
primOpId PrimOp
TagToEnumOp)

new_tag2con_rdr_name, new_maxtag_rdr_name
  :: SrcSpan -> TyCon -> TcM RdrName
-- Generates Exact RdrNames, for the binding positions
new_tag2con_rdr_name :: SrcSpan -> TyCon -> TcM RdrName
new_tag2con_rdr_name SrcSpan
dflags TyCon
tycon = SrcSpan -> TyCon -> (OccName -> OccName) -> TcM RdrName
new_tc_deriv_rdr_name SrcSpan
dflags TyCon
tycon OccName -> OccName
mkTag2ConOcc
new_maxtag_rdr_name :: SrcSpan -> TyCon -> TcM RdrName
new_maxtag_rdr_name  SrcSpan
dflags TyCon
tycon = SrcSpan -> TyCon -> (OccName -> OccName) -> TcM RdrName
new_tc_deriv_rdr_name SrcSpan
dflags TyCon
tycon OccName -> OccName
mkMaxTagOcc

new_dataT_rdr_name :: SrcSpan -> TyCon -> TcM RdrName
new_dataT_rdr_name :: SrcSpan -> TyCon -> TcM RdrName
new_dataT_rdr_name SrcSpan
dflags TyCon
tycon = SrcSpan -> TyCon -> (OccName -> OccName) -> TcM RdrName
new_tc_deriv_rdr_name SrcSpan
dflags TyCon
tycon OccName -> OccName
mkDataTOcc

new_dataC_rdr_name :: SrcSpan -> DataCon -> TcM RdrName
new_dataC_rdr_name :: SrcSpan -> DataCon -> TcM RdrName
new_dataC_rdr_name SrcSpan
dflags DataCon
dc = SrcSpan -> DataCon -> (OccName -> OccName) -> TcM RdrName
new_dc_deriv_rdr_name SrcSpan
dflags DataCon
dc OccName -> OccName
mkDataCOcc

new_tc_deriv_rdr_name :: SrcSpan -> TyCon -> (OccName -> OccName) -> TcM RdrName
new_tc_deriv_rdr_name :: SrcSpan -> TyCon -> (OccName -> OccName) -> TcM RdrName
new_tc_deriv_rdr_name SrcSpan
loc TyCon
tycon OccName -> OccName
occ_fun
  = SrcSpan -> Name -> (OccName -> OccName) -> TcM RdrName
newAuxBinderRdrName SrcSpan
loc (TyCon -> Name
tyConName TyCon
tycon) OccName -> OccName
occ_fun

new_dc_deriv_rdr_name :: SrcSpan -> DataCon -> (OccName -> OccName) -> TcM RdrName
new_dc_deriv_rdr_name :: SrcSpan -> DataCon -> (OccName -> OccName) -> TcM RdrName
new_dc_deriv_rdr_name SrcSpan
loc DataCon
dc OccName -> OccName
occ_fun
  = SrcSpan -> Name -> (OccName -> OccName) -> TcM RdrName
newAuxBinderRdrName SrcSpan
loc (DataCon -> Name
dataConName DataCon
dc) OccName -> OccName
occ_fun

-- | Generate the name for an auxiliary binding, giving it a fresh 'Unique'.
-- Returns an 'Exact' 'RdrName' with an underlying 'System' 'Name'.
-- See @Note [Auxiliary binders]@.
newAuxBinderRdrName :: SrcSpan -> Name -> (OccName -> OccName) -> TcM RdrName
newAuxBinderRdrName :: SrcSpan -> Name -> (OccName -> OccName) -> TcM RdrName
newAuxBinderRdrName SrcSpan
loc Name
parent OccName -> OccName
occ_fun = do
  uniq <- TcRnIf TcGblEnv TcLclEnv Unique
forall gbl lcl. TcRnIf gbl lcl Unique
newUnique
  pure $ Exact $ mkSystemNameAt uniq (occ_fun (nameOccName parent)) loc

-- | @getPossibleDataCons tycon tycon_args@ returns the constructors of @tycon@
-- whose return types match when checked against @tycon_args@.
--
-- See Note [Filter out impossible GADT data constructors]
getPossibleDataCons :: TyCon -> [Type] -> [DataCon]
getPossibleDataCons :: TyCon -> [Type] -> [DataCon]
getPossibleDataCons TyCon
tycon [Type]
tycon_args = (DataCon -> Bool) -> [DataCon] -> [DataCon]
forall a. (a -> Bool) -> [a] -> [a]
filter DataCon -> Bool
isPossible ([DataCon] -> [DataCon]) -> [DataCon] -> [DataCon]
forall a b. (a -> b) -> a -> b
$ TyCon -> [DataCon]
tyConDataCons TyCon
tycon
  where
    isPossible :: DataCon -> Bool
isPossible DataCon
dc = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Type] -> DataCon -> Bool
dataConCannotMatch (DataCon -> [Type] -> [Type]
dataConInstUnivs DataCon
dc [Type]
tycon_args) DataCon
dc

-- | Information about the arguments to the class in a stock- or
-- newtype-derived instance. For a @deriving@-generated instance declaration
-- such as this one:
--
-- @
-- instance Ctx => Cls cls_ty_1 ... cls_ty_m (TC tc_arg_1 ... tc_arg_n) where ...
-- @
--
-- * 'dit_cls_tys' corresponds to @cls_ty_1 ... cls_ty_m@.
--
-- * 'dit_tc' corresponds to @TC@.
--
-- * 'dit_tc_args' corresponds to @tc_arg_1 ... tc_arg_n@.
--
-- See @Note [DerivEnv and DerivSpecMechanism]@ in "GHC.Tc.Deriv.Utils" for a
-- more in-depth explanation, including the relationship between
-- 'dit_tc'/'dit_rep_tc' and 'dit_tc_args'/'dit_rep_tc_args'.
--
-- A 'DerivInstTys' value can be seen as a more structured representation of
-- the 'denv_inst_tys' in a 'DerivEnv', as the 'denv_inst_tys' is equal to
-- @dit_cls_tys ++ ['mkTyConApp' dit_tc dit_tc_args]@. Other parts of the
-- instance declaration can be found in the 'DerivEnv'. For example, the @Cls@
-- in the example above corresponds to the 'denv_cls' field of 'DerivEnv'.
--
-- Similarly, the type variables that appear in a 'DerivInstTys' value are the
-- same type variables as the 'denv_tvs' in the parent 'DerivEnv'. Accordingly,
-- if we are inferring an instance context, the type variables will be 'TcTyVar'
-- skolems. Otherwise, they will be ordinary 'TyVar's.
-- See @Note [Overlap and deriving]@ in "GHC.Tc.Deriv.Infer".
data DerivInstTys = DerivInstTys
  { DerivInstTys -> [Type]
dit_cls_tys     :: [Type]
    -- ^ Other arguments to the class except the last
  , DerivInstTys -> TyCon
dit_tc          :: TyCon
    -- ^ Type constructor for which the instance is requested
    --   (last arguments to the type class)
  , DerivInstTys -> [Type]
dit_tc_args     :: [Type]
    -- ^ Arguments to the type constructor
  , DerivInstTys -> TyCon
dit_rep_tc      :: TyCon
    -- ^ The representation tycon for 'dit_tc'
    --   (for data family instances). Otherwise the same as 'dit_tc'.
  , DerivInstTys -> [Type]
dit_rep_tc_args :: [Type]
    -- ^ The representation types for 'dit_tc_args'
    --   (for data family instances). Otherwise the same as 'dit_tc_args'.
  , DerivInstTys -> DataConEnv [Type]
dit_dc_inst_arg_env :: DataConEnv [Type]
    -- ^ The cached results of instantiating each data constructor's field
    --   types using @'dataConInstUnivs' data_con 'dit_rep_tc_args'@.
    --   See @Note [Instantiating field types in stock deriving]@.
    --
    --   This field is only used for stock-derived instances and goes unused
    --   for newtype-derived instances. It is put here mainly for the sake of
    --   convenience.
  }

instance Outputable DerivInstTys where
  ppr :: DerivInstTys -> SDoc
ppr (DerivInstTys { dit_cls_tys :: DerivInstTys -> [Type]
dit_cls_tys = [Type]
cls_tys, dit_tc :: DerivInstTys -> TyCon
dit_tc = TyCon
tc, dit_tc_args :: DerivInstTys -> [Type]
dit_tc_args = [Type]
tc_args
                    , dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
rep_tc, dit_rep_tc_args :: DerivInstTys -> [Type]
dit_rep_tc_args = [Type]
rep_tc_args
                    , dit_dc_inst_arg_env :: DerivInstTys -> DataConEnv [Type]
dit_dc_inst_arg_env = DataConEnv [Type]
dc_inst_arg_env })
    = SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"DerivInstTys")
         Int
2 ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat [ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"dit_cls_tys"         SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
cls_tys
                 , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"dit_tc"              SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tc
                 , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"dit_tc_args"         SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
tc_args
                 , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"dit_rep_tc"          SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
rep_tc
                 , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"dit_rep_tc_args"     SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
rep_tc_args
                 , String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"dit_dc_inst_arg_env" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> DataConEnv [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataConEnv [Type]
dc_inst_arg_env ])

-- | Look up a data constructor's instantiated field types in a 'DerivInstTys'.
-- See @Note [Instantiating field types in stock deriving]@.
derivDataConInstArgTys :: DataCon -> DerivInstTys -> [Type]
derivDataConInstArgTys :: DataCon -> DerivInstTys -> [Type]
derivDataConInstArgTys DataCon
dc DerivInstTys
dit =
  case DataConEnv [Type] -> DataCon -> Maybe [Type]
forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
lookupUFM (DerivInstTys -> DataConEnv [Type]
dit_dc_inst_arg_env DerivInstTys
dit) DataCon
dc of
    Just [Type]
inst_arg_tys -> [Type]
inst_arg_tys
    Maybe [Type]
Nothing           -> String -> SDoc -> [Type]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"derivDataConInstArgTys" (DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
dc)

-- | @'buildDataConInstArgEnv' tycon arg_tys@ constructs a cache that maps
-- each of @tycon@'s data constructors to their field types, with are to be
-- instantiated with @arg_tys@.
-- See @Note [Instantiating field types in stock deriving]@.
buildDataConInstArgEnv :: TyCon -> [Type] -> DataConEnv [Type]
buildDataConInstArgEnv :: TyCon -> [Type] -> DataConEnv [Type]
buildDataConInstArgEnv TyCon
rep_tc [Type]
rep_tc_args =
  [(DataCon, [Type])] -> DataConEnv [Type]
forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
listToUFM [ (DataCon
dc, [Type]
inst_arg_tys)
            | DataCon
dc <- TyCon -> [DataCon]
tyConDataCons TyCon
rep_tc
            , let ([Id]
_, [Type]
_, [Type]
inst_arg_tys) =
                    DataCon -> [Type] -> ([Id], [Type], [Type])
dataConInstSig DataCon
dc ([Type] -> ([Id], [Type], [Type]))
-> [Type] -> ([Id], [Type], [Type])
forall a b. (a -> b) -> a -> b
$ DataCon -> [Type] -> [Type]
dataConInstUnivs DataCon
dc [Type]
rep_tc_args
            ]

-- | Apply a substitution to all of the 'Type's contained in a 'DerivInstTys'.
-- See @Note [Instantiating field types in stock deriving]@ for why we need to
-- substitute into a 'DerivInstTys' in the first place.
substDerivInstTys :: Subst -> DerivInstTys -> DerivInstTys
substDerivInstTys :: Subst -> DerivInstTys -> DerivInstTys
substDerivInstTys Subst
subst
  dit :: DerivInstTys
dit@(DerivInstTys { dit_cls_tys :: DerivInstTys -> [Type]
dit_cls_tys = [Type]
cls_tys, dit_tc_args :: DerivInstTys -> [Type]
dit_tc_args = [Type]
tc_args
                    , dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
rep_tc, dit_rep_tc_args :: DerivInstTys -> [Type]
dit_rep_tc_args = [Type]
rep_tc_args })

  | Subst -> Bool
isEmptyTCvSubst Subst
subst
  = DerivInstTys
dit
  | Bool
otherwise
  = DerivInstTys
dit{ dit_cls_tys         = cls_tys'
       , dit_tc_args         = tc_args'
       , dit_rep_tc_args     = rep_tc_args'
       , dit_dc_inst_arg_env = buildDataConInstArgEnv rep_tc rep_tc_args'
       }
  where
    cls_tys' :: [Type]
cls_tys'     = HasDebugCallStack => Subst -> [Type] -> [Type]
Subst -> [Type] -> [Type]
substTys Subst
subst [Type]
cls_tys
    tc_args' :: [Type]
tc_args'     = HasDebugCallStack => Subst -> [Type] -> [Type]
Subst -> [Type] -> [Type]
substTys Subst
subst [Type]
tc_args
    rep_tc_args' :: [Type]
rep_tc_args' = HasDebugCallStack => Subst -> [Type] -> [Type]
Subst -> [Type] -> [Type]
substTys Subst
subst [Type]
rep_tc_args

-- | Zonk the 'TcTyVar's in a 'DerivInstTys' value to 'TyVar's.
-- See @Note [What is zonking?]@ in "GHC.Tc.Zonk.Type".
--
-- This is only used in the final zonking step when inferring
-- the context for a derived instance.
-- See @Note [Overlap and deriving]@ in "GHC.Tc.Deriv.Infer".
zonkDerivInstTys :: DerivInstTys -> ZonkT TcM DerivInstTys
zonkDerivInstTys :: DerivInstTys -> ZonkT TcM DerivInstTys
zonkDerivInstTys dit :: DerivInstTys
dit@(DerivInstTys { dit_cls_tys :: DerivInstTys -> [Type]
dit_cls_tys = [Type]
cls_tys
                                   , dit_tc_args :: DerivInstTys -> [Type]
dit_tc_args = [Type]
tc_args
                                   , dit_rep_tc :: DerivInstTys -> TyCon
dit_rep_tc = TyCon
rep_tc
                                   , dit_rep_tc_args :: DerivInstTys -> [Type]
dit_rep_tc_args = [Type]
rep_tc_args }) = do
  cls_tys'     <- [Type] -> ZonkTcM [Type]
zonkTcTypesToTypesX [Type]
cls_tys
  tc_args'     <- zonkTcTypesToTypesX tc_args
  rep_tc_args' <- zonkTcTypesToTypesX rep_tc_args
  pure dit{ dit_cls_tys         = cls_tys'
          , dit_tc_args         = tc_args'
          , dit_rep_tc_args     = rep_tc_args'
          , dit_dc_inst_arg_env = buildDataConInstArgEnv rep_tc rep_tc_args'
          }

{-
Note [Auxiliary binders]
~~~~~~~~~~~~~~~~~~~~~~~~
We often want to make top-level auxiliary bindings in derived instances.
For example, derived Ix instances sometimes generate code like this:

  data T = ...
  deriving instance Ix T

  ==>

  instance Ix T where
    range (a, b) = map tag2con_T [dataToTag# a .. dataToTag# b]

  $tag2con_T :: Int -> T
  $tag2con_T = ...code....

Note that multiple instances of the same type might need to use the same sort
of auxiliary binding. For example, $tag2con is used not only in derived Ix
instances, but also in derived Enum instances:

  deriving instance Enum T

  ==>

  instance Enum T where
    toEnum i = tag2con_T i

  $tag2con_T :: Int -> T
  $tag2con_T = ...code....

How do we ensure that the two usages of $tag2con_T do not conflict with each
other? We do so by generating a separate $tag2con_T definition for each
instance, giving each definition an Exact RdrName with a separate Unique to
avoid name clashes:

  instance Ix T where
    range (a, b) = map tag2con_T{Uniq2} [dataToTag# a .. dataToTag# b]

  instance Enum T where
    toEnum a = $tag2con_T{Uniq2} a

   -- $tag2con_T{Uniq1} and $tag2con_T{Uniq2} are Exact RdrNames with
   -- underlying System Names

   $tag2con_T{Uniq1} :: Int -> T
   $tag2con_T{Uniq1} = ...code....

   $tag2con_T{Uniq2} :: Int -> T
   $tag2con_T{Uniq2} = ...code....

Note that:

* This is /precisely/ the same mechanism that we use for
  Template Haskell–generated code.
  See Note [Binders in Template Haskell] in GHC.ThToHs.
  There we explain why we use a 'System' flavour of the Name we generate.

* See "Wrinkle: Reducing code duplication" for how we can avoid generating
  lots of duplicated code in common situations.

* See "Wrinkle: Why we sometimes do generated duplicate code" for why this
  de-duplication mechanism isn't perfect, so we fall back to CSE
  (which is very effective within a single module).

* Note that the "_T" part of "$tag2con_T" is just for debug-printing
  purposes. We could call them all "$tag2con", or even just "aux".
  The Unique is enough to keep them separate.

  This is important: we might be generating an Eq instance for two
  completely-distinct imported type constructors T.

At first glance, it might appear that this plan is infeasible, as it would
require generating multiple top-level declarations with the same OccName. But
what if auxiliary bindings /weren't/ top-level? Conceptually, we could imagine
that auxiliary bindings are /local/ to the instance declarations in which they
are used. Using some hypothetical Haskell syntax, it might look like this:

  let {
    $tag2con_T{Uniq1} :: Int -> T
    $tag2con_T{Uniq1} = ...code....

    $tag2con_T{Uniq2} :: Int -> T
    $tag2con_T{Uniq2} = ...code....
  } in {
    instance Ix T where
      range (a, b) = map tag2con_T{Uniq2} [dataToTag# a .. dataToTag# b]

    instance Enum T where
      toEnum a = $tag2con_T{Uniq2} a
  }

Making auxiliary bindings local is key to making this work, since GHC will
not reject local bindings with duplicate names provided that:

* Each binding has a distinct unique, and
* Each binding has an Exact RdrName with a System Name.

Even though the hypothetical Haskell syntax above does not exist, we can
accomplish the same end result through some sleight of hand in renameDeriv:
we rename auxiliary bindings with rnLocalValBindsLHS. (If we had used
rnTopBindsLHS instead, then GHC would spuriously reject auxiliary bindings
with the same OccName as duplicates.) Luckily, no special treatment is needed
to typecheck them; we can typecheck them as normal top-level bindings
(using tcTopBinds) without danger.

-----
-- Wrinkle: Reducing code duplication
-----

While the approach of generating copies of each sort of auxiliary binder per
derived instance is simpler, it can lead to code bloat if done naïvely.
Consider this example:

  data T = ...
  deriving instance Eq T
  deriving instance Ord T

  ==>

  instance Ix T where
    range (a, b) = map tag2con_T{Uniq2} [dataToTag# a .. dataToTag# b]

  instance Enum T where
    toEnum a = $tag2con_T{Uniq2} a

  $tag2con_T{Uniq1} :: Int -> T
  $tag2con_T{Uniq1} = ...code....

  $tag2con_T{Uniq2} :: Int -> T
  $tag2con_T{Uniq2} = ...code....

$tag2con_T{Uniq1} and $tag2con_T{Uniq2} are blatant duplicates of each other,
which is not ideal. Surely GHC can do better than that at the very least! And
indeed it does. Within the genAuxBinds function, GHC performs a small CSE-like
pass to define duplicate auxiliary binders in terms of the original one. On
the example above, that would look like this:

  $tag2con_T{Uniq1} :: Int -> T
  $tag2con_T{Uniq1} = ...code....

  $tag2con_T{Uniq2} :: Int -> T
  $tag2con_T{Uniq2} = $tag2con_T{Uniq1}

(Note that this pass does not cover all possible forms of code duplication.
See "Wrinkle: Why we sometimes do generate duplicate code" for situations
where genAuxBinds does not deduplicate code.)

To start, genAuxBinds is given a list of AuxBindSpecs, which describe the sort
of auxiliary bindings that must be generates along with their RdrNames. As
genAuxBinds processes this list, it marks the first occurrence of each sort of
auxiliary binding as the "original". For example, if genAuxBinds sees a
DerivCon2Tag for the first time (with the RdrName $tag2con_T{Uniq1}), then it
will generate the full code for a $tag2con binding:

  $tag2con_T{Uniq1} :: Int -> T
  $tag2con_T{Uniq1} = ...code....

Later, if genAuxBinds sees any additional DerivCon2Tag values, it will treat
them as duplicates. For example, if genAuxBinds later sees a DerivCon2Tag with
the RdrName $tag2con_T{Uniq2}, it will generate this code, which is much more
compact:

  $tag2con_T{Uniq2} :: Int -> T
  $tag2con_T{Uniq2} = $tag2con_T{Uniq1}

An alternative approach would be /not/ performing any kind of deduplication in
genAuxBinds at all and simply relying on GHC's simplifier to perform this kind
of CSE. But this is a more expensive analysis in general, while genAuxBinds can
accomplish the same result with a simple check.

-----
-- Wrinkle: Why we sometimes do generate duplicate code
-----

It is worth noting that deduplicating auxiliary binders is difficult in the
general case. Here are two particular examples where GHC cannot easily remove
duplicate copies of an auxiliary binding:

1. When derived instances are contained in different modules, as in the
   following example:

     module A where
       data T = ...
     module B where
       import A
       deriving instance Ix T
     module C where
       import B
       deriving instance Enum T

   The derived Eq and Enum instances for T make use of $tag2con_T, and since
   they are defined in separate modules, each module must produce its own copy
   of $tag2con_T.

2. When derived instances are separated by TH splices (#18321), as in the
   following example:

     module M where

     data T = ...
     deriving instance Ix T
     $(pure [])
     deriving instance Enum T

   Due to the way that GHC typechecks TyClGroups, genAuxBinds will run twice
   in this program: once for all the declarations before the TH splice, and
   once again for all the declarations after the TH splice. As a result,
   $tag2con_T will be generated twice, since genAuxBinds will be unable to
   recognize the presence of duplicates.

These situations are much rarer, so we do not spend any effort to deduplicate
auxiliary bindings there. Instead, we focus on the common case of multiple
derived instances within the same module, not separated by any TH splices.
(This is the case described in "Wrinkle: Reducing code duplication".) In
situation (1), we can at least fall back on GHC's simplifier to pick up
genAuxBinds' slack.

Note [Filter out impossible GADT data constructors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Some stock-derivable classes will filter out impossible GADT data constructors,
to rule out problematic constructors when deriving instances. e.g.

```
data Foo a where
  X :: Foo Int
  Y :: (Bool -> Bool) -> Foo Bool
```

when deriving an instance on `Foo Int`, `Y` should be treated as if it didn't
exist in the first place. For instance, if we write

```
deriving instance Eq (Foo Int)
```

it should generate:

```
instance Eq (Foo Int) where
  X == X = True
```

Classes that filter constructors:

* Eq
* Ord
* Show
* Lift
* Functor
* Foldable
* Traversable

Classes that do not filter constructors:

* Enum: doesn't make sense for GADTs in the first place
* Bounded: only makes sense for GADTs with a single constructor
* Ix: only makes sense for GADTs with a single constructor
* Read: `Read a` returns `a` instead of consumes `a`, so filtering data
  constructors would make this function _more_ partial instead of less
* Data: derived implementations of gunfold rely on a constructor-indexing
  scheme that wouldn't work if certain constructors were filtered out
* Generic/Generic1: doesn't make sense for GADTs

Classes that do not currently filter constructors may do so in the future, if
there is a valid use-case and we have requirements for how they should work.

See #16341 and the T16341.hs test case.

Note [Instantiating field types in stock deriving]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Figuring out what the types of data constructor fields are in `deriving` can
be surprisingly tricky. Here are some examples (adapted from #20375) to set
the scene:

  data Ta = MkTa Int#
  data Tb (x :: TYPE IntRep) = MkTb x

  deriving instance Eq Ta        -- 1.
  deriving instance Eq (Tb a)    -- 2.
  deriving instance Eq (Tb Int#) -- 3.

Example (1) is accepted, as `deriving Eq` has a special case for fields of type
Int#. Example (2) is rejected, however, as the special case for Int# does not
extend to all types of kind (TYPE IntRep).

Example (3) ought to typecheck. If you instantiate the field of type `x` in
MkTb to be Int#, then `deriving Eq` is capable of handling that. We must be
careful, however. If we naïvely use, say, `dataConOrigArgTys` to retrieve the
field types, then we would get `b`, which `deriving Eq` would reject. In
order to handle `deriving Eq` (and, more generally, any stock deriving
strategy) correctly, we /must/ instantiate the field types as needed.
Not doing so led to #20375 and #20387.

In fact, we end up needing to instantiate the field types in quite a few
places:

* When performing validity checks for stock deriving strategies (e.g., in
  GHC.Tc.Deriv.Utils.cond_stdOK)

* When inferring the instance context in
  GHC.Tc.Deriv.Infer.inferConstraintStock

* When generating code for stock-derived instances in
  GHC.Tc.Deriv.{Functor,Generate,Generics}

Repeatedly performing these instantiations in multiple places would be
wasteful, so we build a cache of data constructor field instantiations in
the `dit_dc_inst_arg_env` field of DerivInstTys. Specifically:

1. When beginning to generate code for a stock-derived instance
   `T arg_1 ... arg_n`, the `dit_dc_inst_arg_env` field is created by taking
   each data constructor `dc`, instantiating its field types with
   `dataConInstUnivs dc [arg_1, ..., arg_n]`, and mapping `dc` to the
   instantiated field types in the cache. The `buildDataConInstArgEnv` function
   is responsible for orchestrating this.

2. When a part of the code in GHC.Tc.Deriv.* needs to look up the field
   types, we deliberately avoid using `dataConOrigArgTys`. Instead, we use
   `derivDataConInstArgTys`, which looks up a DataCon's instantiated field
   types in the cache.

StandaloneDeriving is one way for the field types to become instantiated.
Another way is by deriving Functor and related classes, as chronicled in
Note [Inferring the instance context] in GHC.Tc.Deriv.Infer. Here is one such
example:

  newtype Compose (f :: k -> Type) (g :: j -> k) (a :: j) = Compose (f (g a))
    deriving Generic1

This ultimately generates the following instance:

  instance forall (f :: Type -> Type) (g :: j -> Type).
    Functor f => Generic1 (Compose f g) where ...

Note that because of the inferred `Functor f` constraint, `k` was instantiated
to be `Type`. GHC's deriving machinery doesn't realize this until it performs
constraint inference (in GHC.Tc.Deriv.Infer.inferConstraintsStock), however,
which is *after* the initial DerivInstTys has been created. As a result, the
`dit_dc_inst_arg_env` field might need to be updated after constraint inference,
as the inferred constraints might instantiate the field types further.

This is accomplished by way of `substDerivInstTys`, which substitutes all of
the fields in a `DerivInstTys`, including the `dit_dc_inst_arg_env`.
It is important to do this in inferConstraintsStock, as the
deriving/should_compile/T20387 test case will not compile otherwise.
-}