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

    Pattern-matching literal patterns
    -}

    {-# LANGUAGE CPP, ScopedTypeVariables #-}
    {-# LANGUAGE ViewPatterns #-}

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

    module GHC.HsToCore.Match.Literal
       ( dsLit, dsOverLit, hsLitKey
       , tidyLitPat, tidyNPat
       , matchLiterals, matchNPlusKPats, matchNPats
       , warnAboutIdentities
       , warnAboutOverflowedOverLit, warnAboutOverflowedLit
       , warnAboutEmptyEnumerations
       )
    where

    #include "HsVersions.h"

    import GHC.Prelude
    import GHC.Platform

    import {-# SOURCE #-} GHC.HsToCore.Match ( match )
    import {-# SOURCE #-} GHC.HsToCore.Expr  ( dsExpr, dsSyntaxExpr )

    import GHC.HsToCore.Monad
    import GHC.HsToCore.Utils

    import GHC.Hs

    import GHC.Types.Id
    import GHC.Core
    import GHC.Core.Make
    import GHC.Core.TyCon
    import GHC.Core.DataCon
    import GHC.Tc.Utils.Zonk ( shortCutLit )
    import GHC.Tc.Utils.TcType
    import GHC.Types.Name
    import GHC.Core.Type
    import GHC.Builtin.Names
    import GHC.Builtin.Types
    import GHC.Builtin.Types.Prim
    import GHC.Types.Literal
    import GHC.Types.SrcLoc
    import Data.Ratio
    import GHC.Utils.Outputable as Outputable
    import GHC.Types.Basic
    import GHC.Driver.Session
    import GHC.Utils.Misc
    import GHC.Data.FastString
    import qualified GHC.LanguageExtensions as LangExt
    import GHC.Core.FamInstEnv ( FamInstEnvs, normaliseType )

    import Control.Monad
    import Data.Int
    import Data.List.NonEmpty (NonEmpty(..))
    import qualified Data.List.NonEmpty as NEL
    import Data.Word
    import Data.Proxy

    {-
    ************************************************************************
    *                                                                      *
                    Desugaring literals
     [used to be in GHC.HsToCore.Expr, but GHC.HsToCore.Quote needs it,
      and it's nice to avoid a loop]
    *                                                                      *
    ************************************************************************

    We give int/float literals type @Integer@ and @Rational@, respectively.
    The typechecker will (presumably) have put \tr{from{Integer,Rational}s}
    around them.

    ToDo: put in range checks for when converting ``@i@''
    (or should that be in the typechecker?)

    For numeric literals, we try to detect there use at a standard type
    (@Int@, @Float@, etc.) are directly put in the right constructor.
    [NB: down with the @App@ conversion.]

    See also below where we look for @DictApps@ for \tr{plusInt}, etc.
    -}

    dsLit :: HsLit GhcRn -> DsM CoreExpr
    dsLit :: HsLit GhcRn -> DsM CoreExpr
    dsLit HsLit GhcRn
    l = do
      DynFlags
    dflags <- IOEnv (Env DsGblEnv DsLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
      let platform :: Platform
    platform = DynFlags -> Platform
    targetPlatform DynFlags
    dflags
      case HsLit GhcRn
    l of
        HsStringPrim XHsStringPrim GhcRn
    _ ByteString
    s -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Literal -> CoreExpr
    forall b. Literal -> Expr b
    Lit (ByteString -> Literal
    LitString ByteString
    s))
        HsCharPrim   XHsCharPrim GhcRn
    _ Char
    c -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Literal -> CoreExpr
    forall b. Literal -> Expr b
    Lit (Char -> Literal
    LitChar Char
    c))
        HsIntPrim    XHsIntPrim GhcRn
    _ Integer
    i -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Literal -> CoreExpr
    forall b. Literal -> Expr b
    Lit (Platform -> Integer -> Literal
    mkLitIntWrap Platform
    platform Integer
    i))
        HsWordPrim   XHsWordPrim GhcRn
    _ Integer
    w -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Literal -> CoreExpr
    forall b. Literal -> Expr b
    Lit (Platform -> Integer -> Literal
    mkLitWordWrap Platform
    platform Integer
    w))
        HsInt64Prim  XHsInt64Prim GhcRn
    _ Integer
    i -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Literal -> CoreExpr
    forall b. Literal -> Expr b
    Lit (Platform -> Integer -> Literal
    mkLitInt64Wrap Platform
    platform Integer
    i))
        HsWord64Prim XHsWord64Prim GhcRn
    _ Integer
    w -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Literal -> CoreExpr
    forall b. Literal -> Expr b
    Lit (Platform -> Integer -> Literal
    mkLitWord64Wrap Platform
    platform Integer
    w))
        HsFloatPrim  XHsFloatPrim GhcRn
    _ FractionalLit
    f -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Literal -> CoreExpr
    forall b. Literal -> Expr b
    Lit (Rational -> Literal
    LitFloat (FractionalLit -> Rational
    fl_value FractionalLit
    f)))
        HsDoublePrim XHsDoublePrim GhcRn
    _ FractionalLit
    d -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Literal -> CoreExpr
    forall b. Literal -> Expr b
    Lit (Rational -> Literal
    LitDouble (FractionalLit -> Rational
    fl_value FractionalLit
    d)))
        HsChar XHsChar GhcRn
    _ Char
    c       -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Char -> CoreExpr
    mkCharExpr Char
    c)
        HsString XHsString GhcRn
    _ FastString
    str   -> FastString -> DsM CoreExpr
    forall (m :: * -> *). MonadThings m => FastString -> m CoreExpr
    mkStringExprFS FastString
    str
        HsInteger XHsInteger GhcRn
    _ Integer
    i Type
    _  -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Integer -> CoreExpr
    mkIntegerExpr Integer
    i)
        HsInt XHsInt GhcRn
    _ IntegralLit
    i        -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Platform -> Integer -> CoreExpr
    mkIntExpr Platform
    platform (IntegralLit -> Integer
    il_value IntegralLit
    i))
        HsRat XHsRat GhcRn
    _ (FL SourceText
    _ Bool
    _ Rational
    val) Type
    ty -> do
          CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return (DataCon -> [CoreExpr] -> CoreExpr
    mkCoreConApps DataCon
    ratio_data_con [Type -> CoreExpr
    forall b. Type -> Expr b
    Type Type
    integer_ty, CoreExpr
    num, CoreExpr
    denom])
          where
            num :: CoreExpr
    num   = Integer -> CoreExpr
    mkIntegerExpr (Rational -> Integer
    forall a. Ratio a -> a
    numerator Rational
    val)
            denom :: CoreExpr
    denom = Integer -> CoreExpr
    mkIntegerExpr (Rational -> Integer
    forall a. Ratio a -> a
    denominator Rational
    val)
            (DataCon
    ratio_data_con, Type
    integer_ty)
                = case Type -> (TyCon, [Type])
    tcSplitTyConApp Type
    ty of
                        (TyCon
    tycon, [Type
    i_ty]) -> ASSERT(isIntegerTy i_ty && tycon `hasKey` ratioTyConKey)
                                           ([DataCon] -> DataCon
    forall a. [a] -> a
    head (TyCon -> [DataCon]
    tyConDataCons TyCon
    tycon), Type
    i_ty)
                        (TyCon, [Type])
    x -> String -> SDoc -> (DataCon, Type)
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "dsLit" ((TyCon, [Type]) -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (TyCon, [Type])
    x)

    dsOverLit :: HsOverLit GhcTc -> DsM CoreExpr
    -- ^ Post-typechecker, the 'HsExpr' field of an 'OverLit' contains
    -- (an expression for) the literal value itself.
    dsOverLit :: HsOverLit GhcTc -> DsM CoreExpr
    dsOverLit (OverLit { ol_val :: forall p. HsOverLit p -> OverLitVal
    ol_val = OverLitVal
    val, ol_ext :: forall p. HsOverLit p -> XOverLit p
    ol_ext = OverLitTc Bool
    rebindable Type
    ty
                       , ol_witness :: forall p. HsOverLit p -> HsExpr p
    ol_witness = HsExpr GhcTc
    witness }) = do
      DynFlags
    dflags <- IOEnv (Env DsGblEnv DsLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
      let platform :: Platform
    platform = DynFlags -> Platform
    targetPlatform DynFlags
    dflags
      case Platform -> OverLitVal -> Type -> Maybe (HsExpr GhcTc)
    shortCutLit Platform
    platform OverLitVal
    val Type
    ty of
        Just HsExpr GhcTc
    expr | Bool -> Bool
    not Bool
    rebindable -> HsExpr GhcTc -> DsM CoreExpr
    dsExpr HsExpr GhcTc
    expr        -- Note [Literal short cut]
        Maybe (HsExpr GhcTc)
    _                          -> HsExpr GhcTc -> DsM CoreExpr
    dsExpr HsExpr GhcTc
    witness
    {-
    Note [Literal short cut]
    ~~~~~~~~~~~~~~~~~~~~~~~~
    The type checker tries to do this short-cutting as early as possible, but
    because of unification etc, more information is available to the desugarer.
    And where it's possible to generate the correct literal right away, it's
    much better to do so.

    ************************************************************************
    *                                                                      *
                     Warnings about overflowed literals
    *                                                                      *
    ************************************************************************

    Warn about functions like toInteger, fromIntegral, that convert
    between one type and another when the to- and from- types are the
    same.  Then it's probably (albeit not definitely) the identity
    -}

    warnAboutIdentities :: DynFlags -> Id -> Type -> DsM ()
    warnAboutIdentities :: DynFlags -> Id -> Type -> DsM ()
    warnAboutIdentities DynFlags
    dflags Id
    conv_fn Type
    type_of_conv
      | WarningFlag -> DynFlags -> Bool
    wopt WarningFlag
    Opt_WarnIdentities DynFlags
    dflags
      , Id -> Name
    idName Id
    conv_fn Name -> [Name] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Name]
    conversionNames
      , Just (Type
    _, Type
    arg_ty, Type
    res_ty) <- Type -> Maybe (Type, Type, Type)
    splitFunTy_maybe Type
    type_of_conv
      , Type
    arg_ty Type -> Type -> Bool
    `eqType` Type
    res_ty  -- So we are converting  ty -> ty
      = WarnReason -> SDoc -> DsM ()
    warnDs (WarningFlag -> WarnReason
    Reason WarningFlag
    Opt_WarnIdentities)
               ([SDoc] -> SDoc
    vcat [ String -> SDoc
    text String
    "Call of" SDoc -> SDoc -> SDoc
    <+> Id -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Id
    conv_fn SDoc -> SDoc -> SDoc
    <+> SDoc
    dcolon SDoc -> SDoc -> SDoc
    <+> Type -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Type
    type_of_conv
                     , Int -> SDoc -> SDoc
    nest Int
    2 (SDoc -> SDoc) -> SDoc -> SDoc
    forall a b. (a -> b) -> a -> b
    $ String -> SDoc
    text String
    "can probably be omitted"
               ])
    warnAboutIdentities DynFlags
    _ Id
    _ Type
    _ = () -> DsM ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    conversionNames :: [Name]
    conversionNames :: [Name]
    conversionNames
      = [ Name
    toIntegerName, Name
    toRationalName
        , Name
    fromIntegralName, Name
    realToFracName ]
     -- We can't easily add fromIntegerName, fromRationalName,
     -- because they are generated by literals

    -- | Emit warnings on overloaded integral literals which overflow the bounds
    -- implied by their type.
    warnAboutOverflowedOverLit :: HsOverLit GhcTc -> DsM ()
    warnAboutOverflowedOverLit :: HsOverLit GhcTc -> DsM ()
    warnAboutOverflowedOverLit HsOverLit GhcTc
    hsOverLit = do
      DynFlags
    dflags <- IOEnv (Env DsGblEnv DsLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
      FamInstEnvs
    fam_envs <- DsM FamInstEnvs
    dsGetFamInstEnvs
      DynFlags -> Maybe (Integer, Name) -> DsM ()
    warnAboutOverflowedLiterals DynFlags
    dflags (Maybe (Integer, Name) -> DsM ())
    -> Maybe (Integer, Name) -> DsM ()
    forall a b. (a -> b) -> a -> b
    $
          HsOverLit GhcTc -> Maybe (Integer, Type)
    getIntegralLit HsOverLit GhcTc
    hsOverLit Maybe (Integer, Type)
    -> ((Integer, Type) -> Maybe (Integer, Name))
    -> Maybe (Integer, Name)
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= FamInstEnvs -> (Integer, Type) -> Maybe (Integer, Name)
    getNormalisedTyconName FamInstEnvs
    fam_envs

    -- | Emit warnings on integral literals which overflow the bounds implied by
    -- their type.
    warnAboutOverflowedLit :: HsLit GhcTc -> DsM ()
    warnAboutOverflowedLit :: HsLit GhcTc -> DsM ()
    warnAboutOverflowedLit HsLit GhcTc
    hsLit = do
      DynFlags
    dflags <- IOEnv (Env DsGblEnv DsLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
      DynFlags -> Maybe (Integer, Name) -> DsM ()
    warnAboutOverflowedLiterals DynFlags
    dflags (Maybe (Integer, Name) -> DsM ())
    -> Maybe (Integer, Name) -> DsM ()
    forall a b. (a -> b) -> a -> b
    $
          HsLit GhcTc -> Maybe (Integer, Type)
    getSimpleIntegralLit HsLit GhcTc
    hsLit Maybe (Integer, Type)
    -> ((Integer, Type) -> Maybe (Integer, Name))
    -> Maybe (Integer, Name)
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Integer, Type) -> Maybe (Integer, Name)
    getTyconName

    -- | Emit warnings on integral literals which overflow the bounds implied by
    -- their type.
    warnAboutOverflowedLiterals
      :: DynFlags
      -> Maybe (Integer, Name)  -- ^ the literal value and name of its tycon
      -> DsM ()
    warnAboutOverflowedLiterals :: DynFlags -> Maybe (Integer, Name) -> DsM ()
    warnAboutOverflowedLiterals DynFlags
    dflags Maybe (Integer, Name)
    lit
     | WarningFlag -> DynFlags -> Bool
    wopt WarningFlag
    Opt_WarnOverflowedLiterals DynFlags
    dflags
     , Just (Integer
    i, Name
    tc) <- Maybe (Integer, Name)
    lit
     =  if      Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    intTyConName     then Integer -> Name -> Proxy Int -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Int
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int)

        -- These only show up via the 'HsOverLit' route
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int8TyConName    then Integer -> Name -> Proxy Int8 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Int8
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int8)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int16TyConName   then Integer -> Name -> Proxy Int16 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Int16
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int16)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int32TyConName   then Integer -> Name -> Proxy Int32 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Int32
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int32)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int64TyConName   then Integer -> Name -> Proxy Int64 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Int64
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int64)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    wordTyConName    then Integer -> Name -> Proxy Word -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Word
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word8TyConName   then Integer -> Name -> Proxy Word8 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Word8
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word8)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word16TyConName  then Integer -> Name -> Proxy Word16 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Word16
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word16)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word32TyConName  then Integer -> Name -> Proxy Word32 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Word32
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word32)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word64TyConName  then Integer -> Name -> Proxy Word64 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Word64
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word64)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    naturalTyConName then Integer -> Name -> DsM ()
    checkPositive Integer
    i Name
    tc

        -- These only show up via the 'HsLit' route
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    intPrimTyConName    then Integer -> Name -> Proxy Int -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Int
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int8PrimTyConName   then Integer -> Name -> Proxy Int8 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Int8
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int8)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int32PrimTyConName  then Integer -> Name -> Proxy Int32 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Int32
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int32)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int64PrimTyConName  then Integer -> Name -> Proxy Int64 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Int64
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int64)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    wordPrimTyConName   then Integer -> Name -> Proxy Word -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Word
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word8PrimTyConName  then Integer -> Name -> Proxy Word8 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Word8
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word8)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word32PrimTyConName then Integer -> Name -> Proxy Word32 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Word32
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word32)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word64PrimTyConName then Integer -> Name -> Proxy Word64 -> DsM ()
    forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc (Proxy Word64
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word64)

        else () -> DsM ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

      | Bool
    otherwise = () -> DsM ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      where

        checkPositive :: Integer -> Name -> DsM ()
        checkPositive :: Integer -> Name -> DsM ()
    checkPositive Integer
    i Name
    tc
          = Bool -> DsM () -> DsM ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    0) (DsM () -> DsM ()) -> DsM () -> DsM ()
    forall a b. (a -> b) -> a -> b
    $ do
            WarnReason -> SDoc -> DsM ()
    warnDs (WarningFlag -> WarnReason
    Reason WarningFlag
    Opt_WarnOverflowedLiterals)
                   ([SDoc] -> SDoc
    vcat [ String -> SDoc
    text String
    "Literal" SDoc -> SDoc -> SDoc
    <+> Integer -> SDoc
    integer Integer
    i
                           SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "is negative but" SDoc -> SDoc -> SDoc
    <+> Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    tc
                           SDoc -> SDoc -> SDoc
    <+> PtrString -> SDoc
    ptext (String -> PtrString
    sLit String
    "only supports positive numbers")
                         ])

        check :: forall a. (Bounded a, Integral a) => Integer -> Name -> Proxy a -> DsM ()
        check :: forall a.
    (Bounded a, Integral a) =>
    Integer -> Name -> Proxy a -> DsM ()
    check Integer
    i Name
    tc Proxy a
    _proxy
          = Bool -> DsM () -> DsM ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    minB Bool -> Bool -> Bool
    || Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    maxB) (DsM () -> DsM ()) -> DsM () -> DsM ()
    forall a b. (a -> b) -> a -> b
    $ do
            WarnReason -> SDoc -> DsM ()
    warnDs (WarningFlag -> WarnReason
    Reason WarningFlag
    Opt_WarnOverflowedLiterals)
                   ([SDoc] -> SDoc
    vcat [ String -> SDoc
    text String
    "Literal" SDoc -> SDoc -> SDoc
    <+> Integer -> SDoc
    integer Integer
    i
                           SDoc -> SDoc -> SDoc
    <+> String -> SDoc
    text String
    "is out of the" SDoc -> SDoc -> SDoc
    <+> Name -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Name
    tc SDoc -> SDoc -> SDoc
    <+> PtrString -> SDoc
    ptext (String -> PtrString
    sLit String
    "range")
                           SDoc -> SDoc -> SDoc
    <+> Integer -> SDoc
    integer Integer
    minB SDoc -> SDoc -> SDoc
    <> String -> SDoc
    text String
    ".." SDoc -> SDoc -> SDoc
    <> Integer -> SDoc
    integer Integer
    maxB
                         , SDoc
    sug ])
          where
            minB :: Integer
    minB = a -> Integer
    forall a. Integral a => a -> Integer
    toInteger (a
    forall a. Bounded a => a
    minBound :: a)
            maxB :: Integer
    maxB = a -> Integer
    forall a. Integral a => a -> Integer
    toInteger (a
    forall a. Bounded a => a
    maxBound :: a)
            sug :: SDoc
    sug | Integer
    minB Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == -Integer
    i   -- Note [Suggest NegativeLiterals]
                , Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    0
                , Bool -> Bool
    not (Extension -> DynFlags -> Bool
    xopt Extension
    LangExt.NegativeLiterals DynFlags
    dflags)
                = String -> SDoc
    text String
    "If you are trying to write a large negative literal, use NegativeLiterals"
                | Bool
    otherwise = SDoc
    Outputable.empty

    {-
    Note [Suggest NegativeLiterals]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If you write
      x :: Int8
      x = -128
    it'll parse as (negate 128), and overflow.  In this case, suggest NegativeLiterals.
    We get an erroneous suggestion for
      x = 128
    but perhaps that does not matter too much.
    -}

    warnAboutEmptyEnumerations :: FamInstEnvs -> DynFlags -> LHsExpr GhcTc
                               -> Maybe (LHsExpr GhcTc)
                               -> LHsExpr GhcTc -> DsM ()
    -- ^ Warns about @[2,3 .. 1]@ or @['b' .. 'a']@ which return the empty list.
    -- For numeric literals, only works for integral types, not floating point.
    warnAboutEmptyEnumerations :: FamInstEnvs
    -> DynFlags
    -> LHsExpr GhcTc
    -> Maybe (LHsExpr GhcTc)
    -> LHsExpr GhcTc
    -> DsM ()
    warnAboutEmptyEnumerations FamInstEnvs
    fam_envs DynFlags
    dflags LHsExpr GhcTc
    fromExpr Maybe (LHsExpr GhcTc)
    mThnExpr LHsExpr GhcTc
    toExpr
      | Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ WarningFlag -> DynFlags -> Bool
    wopt WarningFlag
    Opt_WarnEmptyEnumerations DynFlags
    dflags
      = () -> DsM ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      -- Numeric Literals
      | Just from_ty :: (Integer, Type)
    from_ty@(Integer
    from,Type
    _) <- LHsExpr GhcTc -> Maybe (Integer, Type)
    getLHsIntegralLit LHsExpr GhcTc
    fromExpr
      , Just (Integer
    _, Name
    tc)          <- FamInstEnvs -> (Integer, Type) -> Maybe (Integer, Name)
    getNormalisedTyconName FamInstEnvs
    fam_envs (Integer, Type)
    from_ty
      , Just Maybe (Integer, Type)
    mThn             <- (LHsExpr GhcTc -> Maybe (Integer, Type))
    -> Maybe (LHsExpr GhcTc) -> Maybe (Maybe (Integer, Type))
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    traverse LHsExpr GhcTc -> Maybe (Integer, Type)
    getLHsIntegralLit Maybe (LHsExpr GhcTc)
    mThnExpr
      , Just (Integer
    to,Type
    _)           <- LHsExpr GhcTc -> Maybe (Integer, Type)
    getLHsIntegralLit LHsExpr GhcTc
    toExpr
      , let check :: forall a. (Enum a, Num a) => Proxy a -> DsM ()
            check :: forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check Proxy a
    _proxy
              = Bool -> DsM () -> DsM ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when ([a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [a]
    enumeration) DsM ()
    raiseWarning
              where
                enumeration :: [a]
                enumeration :: [a]
    enumeration = case Maybe (Integer, Type)
    mThn of
                                Maybe (Integer, Type)
    Nothing      -> [Integer -> a
    forall a. Num a => Integer -> a
    fromInteger Integer
    from                    .. Integer -> a
    forall a. Num a => Integer -> a
    fromInteger Integer
    to]
                                Just (Integer
    thn,Type
    _) -> [Integer -> a
    forall a. Num a => Integer -> a
    fromInteger Integer
    from, Integer -> a
    forall a. Num a => Integer -> a
    fromInteger Integer
    thn   .. Integer -> a
    forall a. Num a => Integer -> a
    fromInteger Integer
    to]

      = if      Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    intTyConName    then Proxy Int -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Int
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int8TyConName   then Proxy Int8 -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Int8
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int8)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int16TyConName  then Proxy Int16 -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Int16
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int16)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int32TyConName  then Proxy Int32 -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Int32
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int32)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    int64TyConName  then Proxy Int64 -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Int64
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Int64)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    wordTyConName   then Proxy Word -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Word
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word8TyConName  then Proxy Word8 -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Word8
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word8)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word16TyConName then Proxy Word16 -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Word16
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word16)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word32TyConName then Proxy Word32 -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Word32
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word32)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    word64TyConName then Proxy Word64 -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Word64
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Word64)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    integerTyConName then Proxy Integer -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Integer
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Integer)
        else if Name
    tc Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Name
    naturalTyConName then Proxy Integer -> DsM ()
    forall a. (Enum a, Num a) => Proxy a -> DsM ()
    check (Proxy Integer
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy Integer)
          -- We use 'Integer' because otherwise a negative 'Natural' literal
          -- could cause a compile time crash (instead of a runtime one).
          -- See the T10930b test case for an example of where this matters.
        else () -> DsM ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

      -- Char literals (#18402)
      | Just Char
    fromChar <- LHsExpr GhcTc -> Maybe Char
    getLHsCharLit LHsExpr GhcTc
    fromExpr
      , Just Maybe Char
    mThnChar <- (LHsExpr GhcTc -> Maybe Char)
    -> Maybe (LHsExpr GhcTc) -> Maybe (Maybe Char)
    forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    traverse LHsExpr GhcTc -> Maybe Char
    getLHsCharLit Maybe (LHsExpr GhcTc)
    mThnExpr
      , Just Char
    toChar   <- LHsExpr GhcTc -> Maybe Char
    getLHsCharLit LHsExpr GhcTc
    toExpr
      , let enumeration :: String
    enumeration = case Maybe Char
    mThnChar of
                            Maybe Char
    Nothing      -> [Char
    fromChar          .. Char
    toChar]
                            Just Char
    thnChar -> [Char
    fromChar, Char
    thnChar .. Char
    toChar]
      = Bool -> DsM () -> DsM ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (String -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    enumeration) DsM ()
    raiseWarning

      | Bool
    otherwise = () -> DsM ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
      where
        raiseWarning :: DsM ()
    raiseWarning = WarnReason -> SDoc -> DsM ()
    warnDs (WarningFlag -> WarnReason
    Reason WarningFlag
    Opt_WarnEmptyEnumerations) (String -> SDoc
    text String
    "Enumeration is empty")

    getLHsIntegralLit :: LHsExpr GhcTc -> Maybe (Integer, Type)
    -- ^ See if the expression is an 'Integral' literal.
    -- Remember to look through automatically-added tick-boxes! (#8384)
    getLHsIntegralLit :: LHsExpr GhcTc -> Maybe (Integer, Type)
    getLHsIntegralLit (L SrcSpan
    _ (HsPar XPar GhcTc
    _ LHsExpr GhcTc
    e))            = LHsExpr GhcTc -> Maybe (Integer, Type)
    getLHsIntegralLit LHsExpr GhcTc
    e
    getLHsIntegralLit (L SrcSpan
    _ (HsTick XTick GhcTc
    _ Tickish (IdP GhcTc)
    _ LHsExpr GhcTc
    e))         = LHsExpr GhcTc -> Maybe (Integer, Type)
    getLHsIntegralLit LHsExpr GhcTc
    e
    getLHsIntegralLit (L SrcSpan
    _ (HsBinTick XBinTick GhcTc
    _ Int
    _ Int
    _ LHsExpr GhcTc
    e))    = LHsExpr GhcTc -> Maybe (Integer, Type)
    getLHsIntegralLit LHsExpr GhcTc
    e
    getLHsIntegralLit (L SrcSpan
    _ (HsOverLit XOverLitE GhcTc
    _ HsOverLit GhcTc
    over_lit)) = HsOverLit GhcTc -> Maybe (Integer, Type)
    getIntegralLit HsOverLit GhcTc
    over_lit
    getLHsIntegralLit (L SrcSpan
    _ (HsLit XLitE GhcTc
    _ HsLit GhcTc
    lit))          = HsLit GhcTc -> Maybe (Integer, Type)
    getSimpleIntegralLit HsLit GhcTc
    lit
    getLHsIntegralLit LHsExpr GhcTc
    _ = Maybe (Integer, Type)
    forall a. Maybe a
    Nothing

    -- | If 'Integral', extract the value and type of the overloaded literal.
    -- See Note [Literals and the OverloadedLists extension]
    getIntegralLit :: HsOverLit GhcTc -> Maybe (Integer, Type)
    getIntegralLit :: HsOverLit GhcTc -> Maybe (Integer, Type)
    getIntegralLit (OverLit { ol_val :: forall p. HsOverLit p -> OverLitVal
    ol_val = HsIntegral IntegralLit
    i, ol_ext :: forall p. HsOverLit p -> XOverLit p
    ol_ext = OverLitTc Bool
    _ Type
    ty })
      = (Integer, Type) -> Maybe (Integer, Type)
    forall a. a -> Maybe a
    Just (IntegralLit -> Integer
    il_value IntegralLit
    i, Type
    ty)
    getIntegralLit HsOverLit GhcTc
    _ = Maybe (Integer, Type)
    forall a. Maybe a
    Nothing

    -- | If 'Integral', extract the value and type of the non-overloaded literal.
    getSimpleIntegralLit :: HsLit GhcTc -> Maybe (Integer, Type)
    getSimpleIntegralLit :: HsLit GhcTc -> Maybe (Integer, Type)
    getSimpleIntegralLit (HsInt XHsInt GhcTc
    _ IL{ il_value :: IntegralLit -> Integer
    il_value = Integer
    i }) = (Integer, Type) -> Maybe (Integer, Type)
    forall a. a -> Maybe a
    Just (Integer
    i, Type
    intTy)
    getSimpleIntegralLit (HsIntPrim XHsIntPrim GhcTc
    _ Integer
    i)    = (Integer, Type) -> Maybe (Integer, Type)
    forall a. a -> Maybe a
    Just (Integer
    i, Type
    intPrimTy)
    getSimpleIntegralLit (HsWordPrim XHsWordPrim GhcTc
    _ Integer
    i)   = (Integer, Type) -> Maybe (Integer, Type)
    forall a. a -> Maybe a
    Just (Integer
    i, Type
    wordPrimTy)
    getSimpleIntegralLit (HsInt64Prim XHsInt64Prim GhcTc
    _ Integer
    i)  = (Integer, Type) -> Maybe (Integer, Type)
    forall a. a -> Maybe a
    Just (Integer
    i, Type
    int64PrimTy)
    getSimpleIntegralLit (HsWord64Prim XHsWord64Prim GhcTc
    _ Integer
    i) = (Integer, Type) -> Maybe (Integer, Type)
    forall a. a -> Maybe a
    Just (Integer
    i, Type
    word64PrimTy)
    getSimpleIntegralLit (HsInteger XHsInteger GhcTc
    _ Integer
    i Type
    ty) = (Integer, Type) -> Maybe (Integer, Type)
    forall a. a -> Maybe a
    Just (Integer
    i, Type
    ty)
    getSimpleIntegralLit HsLit GhcTc
    _ = Maybe (Integer, Type)
    forall a. Maybe a
    Nothing

    -- | Extract the Char if the expression is a Char literal.
    getLHsCharLit :: LHsExpr GhcTc -> Maybe Char
    getLHsCharLit :: LHsExpr GhcTc -> Maybe Char
    getLHsCharLit (L SrcSpan
    _ (HsPar XPar GhcTc
    _ LHsExpr GhcTc
    e))            = LHsExpr GhcTc -> Maybe Char
    getLHsCharLit LHsExpr GhcTc
    e
    getLHsCharLit (L SrcSpan
    _ (HsTick XTick GhcTc
    _ Tickish (IdP GhcTc)
    _ LHsExpr GhcTc
    e))         = LHsExpr GhcTc -> Maybe Char
    getLHsCharLit LHsExpr GhcTc
    e
    getLHsCharLit (L SrcSpan
    _ (HsBinTick XBinTick GhcTc
    _ Int
    _ Int
    _ LHsExpr GhcTc
    e))    = LHsExpr GhcTc -> Maybe Char
    getLHsCharLit LHsExpr GhcTc
    e
    getLHsCharLit (L SrcSpan
    _ (HsLit XLitE GhcTc
    _ (HsChar XHsChar GhcTc
    _ Char
    c))) = Char -> Maybe Char
    forall a. a -> Maybe a
    Just Char
    c
    getLHsCharLit LHsExpr GhcTc
    _ = Maybe Char
    forall a. Maybe a
    Nothing

    -- | Convert a pair (Integer, Type) to (Integer, Name) after eventually
    -- normalising the type
    getNormalisedTyconName :: FamInstEnvs -> (Integer, Type) -> Maybe (Integer, Name)
    getNormalisedTyconName :: FamInstEnvs -> (Integer, Type) -> Maybe (Integer, Name)
    getNormalisedTyconName FamInstEnvs
    fam_envs (Integer
    i,Type
    ty)
        | Just TyCon
    tc <- Type -> Maybe TyCon
    tyConAppTyCon_maybe (FamInstEnvs -> Type -> Type
    normaliseNominal FamInstEnvs
    fam_envs Type
    ty)
        = (Integer, Name) -> Maybe (Integer, Name)
    forall a. a -> Maybe a
    Just (Integer
    i, TyCon -> Name
    tyConName TyCon
    tc)
        | Bool
    otherwise = Maybe (Integer, Name)
    forall a. Maybe a
    Nothing
      where
        normaliseNominal :: FamInstEnvs -> Type -> Type
        normaliseNominal :: FamInstEnvs -> Type -> Type
    normaliseNominal FamInstEnvs
    fam_envs Type
    ty = (Coercion, Type) -> Type
    forall a b. (a, b) -> b
    snd ((Coercion, Type) -> Type) -> (Coercion, Type) -> Type
    forall a b. (a -> b) -> a -> b
    $ FamInstEnvs -> Role -> Type -> (Coercion, Type)
    normaliseType FamInstEnvs
    fam_envs Role
    Nominal Type
    ty

    -- | Convert a pair (Integer, Type) to (Integer, Name) without normalising
    -- the type
    getTyconName :: (Integer, Type) -> Maybe (Integer, Name)
    getTyconName :: (Integer, Type) -> Maybe (Integer, Name)
    getTyconName (Integer
    i,Type
    ty)
      | Just TyCon
    tc <- Type -> Maybe TyCon
    tyConAppTyCon_maybe Type
    ty = (Integer, Name) -> Maybe (Integer, Name)
    forall a. a -> Maybe a
    Just (Integer
    i, TyCon -> Name
    tyConName TyCon
    tc)
      | Bool
    otherwise = Maybe (Integer, Name)
    forall a. Maybe a
    Nothing

    {-
    Note [Literals and the OverloadedLists extension]
    ~~~~
    Consider the Literal `[256] :: [Data.Word.Word8]`

    When the `OverloadedLists` extension is not active, then the `ol_ext` field
    in the `OverLitTc` record that is passed to the function `getIntegralLit`
    contains the type `Word8`. This is a simple type, and we can use its
    type constructor immediately for the `warnAboutOverflowedLiterals` function.

    When the `OverloadedLists` extension is active, then the `ol_ext` field
    contains the type family `Item [Word8]`. The function `nomaliseType` is used
    to convert it to the needed type `Word8`.
    -}

    {-
    ************************************************************************
    *                                                                      *
            Tidying lit pats
    *                                                                      *
    ************************************************************************
    -}

    tidyLitPat :: HsLit GhcTc -> Pat GhcTc
    -- Result has only the following HsLits:
    --      HsIntPrim, HsWordPrim, HsCharPrim, HsFloatPrim
    --      HsDoublePrim, HsStringPrim, HsString
    --  * HsInteger, HsRat, HsInt can't show up in LitPats
    --  * We get rid of HsChar right here
    tidyLitPat :: HsLit GhcTc -> Pat GhcTc
    tidyLitPat (HsChar XHsChar GhcTc
    src Char
    c) = GenLocated SrcSpan (Pat GhcTc) -> Pat GhcTc
    forall l e. GenLocated l e -> e
    unLoc (SourceText -> Char -> LPat GhcTc
    mkCharLitPat SourceText
    XHsChar GhcTc
    src Char
    c)
    tidyLitPat (HsString XHsString GhcTc
    src FastString
    s)
      | FastString -> Int
    lengthFS FastString
    s Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    1     -- Short string literals only
      = GenLocated SrcSpan (Pat GhcTc) -> Pat GhcTc
    forall l e. GenLocated l e -> e
    unLoc (GenLocated SrcSpan (Pat GhcTc) -> Pat GhcTc)
    -> GenLocated SrcSpan (Pat GhcTc) -> Pat GhcTc
    forall a b. (a -> b) -> a -> b
    $ (Char
     -> GenLocated SrcSpan (Pat GhcTc)
     -> GenLocated SrcSpan (Pat GhcTc))
    -> GenLocated SrcSpan (Pat GhcTc)
    -> String
    -> GenLocated SrcSpan (Pat GhcTc)
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\Char
    c GenLocated SrcSpan (Pat GhcTc)
    pat -> DataCon -> [LPat GhcTc] -> [Type] -> LPat GhcTc
    mkPrefixConPat DataCon
    consDataCon
                                                 [SourceText -> Char -> LPat GhcTc
    mkCharLitPat SourceText
    XHsString GhcTc
    src Char
    c, GenLocated SrcSpan (Pat GhcTc)
    LPat GhcTc
    pat] [Type
    charTy])
                      (Type -> LPat GhcTc
    mkNilPat Type
    charTy) (FastString -> String
    unpackFS FastString
    s)
            -- The stringTy is the type of the whole pattern, not
            -- the type to instantiate (:) or [] with!
    tidyLitPat HsLit GhcTc
    lit = XLitPat GhcTc -> HsLit GhcTc -> Pat GhcTc
    forall p. XLitPat p -> HsLit p -> Pat p
    LitPat NoExtField
    XLitPat GhcTc
    noExtField HsLit GhcTc
    lit

    ----------------
    tidyNPat :: HsOverLit GhcTc -> Maybe (SyntaxExpr GhcTc) -> SyntaxExpr GhcTc
             -> Type
             -> Pat GhcTc
    tidyNPat :: HsOverLit GhcTc
    -> Maybe (SyntaxExpr GhcTc)
    -> SyntaxExpr GhcTc
    -> Type
    -> Pat GhcTc
    tidyNPat (OverLit (OverLitTc Bool
    False Type
    ty) OverLitVal
    val HsExpr GhcTc
    _) Maybe (SyntaxExpr GhcTc)
    mb_neg SyntaxExpr GhcTc
    _eq Type
    outer_ty
            -- False: Take short cuts only if the literal is not using rebindable syntax
            --
            -- Once that is settled, look for cases where the type of the
            -- entire overloaded literal matches the type of the underlying literal,
            -- and in that case take the short cut
            -- NB: Watch out for weird cases like #3382
            --        f :: Int -> Int
            --        f "blah" = 4
            --     which might be ok if we have 'instance IsString Int'
            --
      | Bool -> Bool
    not Bool
    type_change, Type -> Bool
    isIntTy Type
    ty,    Just Integer
    int_lit <- Maybe Integer
    mb_int_lit
                     = DataCon -> HsLit GhcTc -> Pat GhcTc
    mk_con_pat DataCon
    intDataCon    (XHsIntPrim GhcTc -> Integer -> HsLit GhcTc
    forall x. XHsIntPrim x -> Integer -> HsLit x
    HsIntPrim    SourceText
    XHsIntPrim GhcTc
    NoSourceText Integer
    int_lit)
      | Bool -> Bool
    not Bool
    type_change, Type -> Bool
    isWordTy Type
    ty,   Just Integer
    int_lit <- Maybe Integer
    mb_int_lit
                     = DataCon -> HsLit GhcTc -> Pat GhcTc
    mk_con_pat DataCon
    wordDataCon   (XHsWordPrim GhcTc -> Integer -> HsLit GhcTc
    forall x. XHsWordPrim x -> Integer -> HsLit x
    HsWordPrim   SourceText
    XHsWordPrim GhcTc
    NoSourceText Integer
    int_lit)
      | Bool -> Bool
    not Bool
    type_change, Type -> Bool
    isStringTy Type
    ty, Just FastString
    str_lit <- Maybe FastString
    mb_str_lit
                     = HsLit GhcTc -> Pat GhcTc
    tidyLitPat (XHsString GhcTc -> FastString -> HsLit GhcTc
    forall x. XHsString x -> FastString -> HsLit x
    HsString SourceText
    XHsString GhcTc
    NoSourceText FastString
    str_lit)
         -- NB: do /not/ convert Float or Double literals to F# 3.8 or D# 5.3
         -- If we do convert to the constructor form, we'll generate a case
         -- expression on a Float# or Double# and that's not allowed in Core; see
         -- #9238 and Note [Rules for floating-point comparisons] in GHC.Core.Opt.ConstantFold
      where
        -- Sometimes (like in test case
        -- overloadedlists/should_run/overloadedlistsrun04), the SyntaxExprs include
        -- type-changing wrappers (for example, from Id Int to Int, for the identity
        -- type family Id). In these cases, we can't do the short-cut.
        type_change :: Bool
    type_change = Bool -> Bool
    not (Type
    outer_ty Type -> Type -> Bool
    `eqType` Type
    ty)

        mk_con_pat :: DataCon -> HsLit GhcTc -> Pat GhcTc
        mk_con_pat :: DataCon -> HsLit GhcTc -> Pat GhcTc
    mk_con_pat DataCon
    con HsLit GhcTc
    lit
          = GenLocated SrcSpan (Pat GhcTc) -> Pat GhcTc
    forall l e. GenLocated l e -> e
    unLoc (DataCon -> [LPat GhcTc] -> [Type] -> LPat GhcTc
    mkPrefixConPat DataCon
    con [Pat GhcTc -> GenLocated SrcSpan (Pat GhcTc)
    forall e. e -> Located e
    noLoc (Pat GhcTc -> GenLocated SrcSpan (Pat GhcTc))
    -> Pat GhcTc -> GenLocated SrcSpan (Pat GhcTc)
    forall a b. (a -> b) -> a -> b
    $ XLitPat GhcTc -> HsLit GhcTc -> Pat GhcTc
    forall p. XLitPat p -> HsLit p -> Pat p
    LitPat NoExtField
    XLitPat GhcTc
    noExtField HsLit GhcTc
    lit] [])

        mb_int_lit :: Maybe Integer
        mb_int_lit :: Maybe Integer
    mb_int_lit = case (Maybe (SyntaxExpr GhcTc)
    Maybe SyntaxExprTc
    mb_neg, OverLitVal
    val) of
                       (Maybe SyntaxExprTc
    Nothing, HsIntegral IntegralLit
    i) -> Integer -> Maybe Integer
    forall a. a -> Maybe a
    Just (IntegralLit -> Integer
    il_value IntegralLit
    i)
                       (Just SyntaxExprTc
    _,  HsIntegral IntegralLit
    i) -> Integer -> Maybe Integer
    forall a. a -> Maybe a
    Just (-(IntegralLit -> Integer
    il_value IntegralLit
    i))
                       (Maybe SyntaxExprTc, OverLitVal)
    _ -> Maybe Integer
    forall a. Maybe a
    Nothing

        mb_str_lit :: Maybe FastString
        mb_str_lit :: Maybe FastString
    mb_str_lit = case (Maybe (SyntaxExpr GhcTc)
    Maybe SyntaxExprTc
    mb_neg, OverLitVal
    val) of
                       (Maybe SyntaxExprTc
    Nothing, HsIsString SourceText
    _ FastString
    s) -> FastString -> Maybe FastString
    forall a. a -> Maybe a
    Just FastString
    s
                       (Maybe SyntaxExprTc, OverLitVal)
    _ -> Maybe FastString
    forall a. Maybe a
    Nothing

    tidyNPat HsOverLit GhcTc
    over_lit Maybe (SyntaxExpr GhcTc)
    mb_neg SyntaxExpr GhcTc
    eq Type
    outer_ty
      = XNPat GhcTc
    -> Located (HsOverLit GhcTc)
    -> Maybe (SyntaxExpr GhcTc)
    -> SyntaxExpr GhcTc
    -> Pat GhcTc
    forall p.
    XNPat p
    -> Located (HsOverLit p)
    -> Maybe (SyntaxExpr p)
    -> SyntaxExpr p
    -> Pat p
    NPat Type
    XNPat GhcTc
    outer_ty (HsOverLit GhcTc -> Located (HsOverLit GhcTc)
    forall e. e -> Located e
    noLoc HsOverLit GhcTc
    over_lit) Maybe (SyntaxExpr GhcTc)
    mb_neg SyntaxExpr GhcTc
    eq

    {-
    ************************************************************************
    *                                                                      *
                    Pattern matching on LitPat
    *                                                                      *
    ************************************************************************
    -}

    matchLiterals :: NonEmpty Id
                  -> Type -- ^ Type of the whole case expression
                  -> NonEmpty (NonEmpty EquationInfo) -- ^ All PgLits
                  -> DsM (MatchResult CoreExpr)

    matchLiterals :: NonEmpty Id
    -> Type
    -> NonEmpty (NonEmpty EquationInfo)
    -> DsM (MatchResult CoreExpr)
    matchLiterals (Id
    var :| [Id]
    vars) Type
    ty NonEmpty (NonEmpty EquationInfo)
    sub_groups
      = do  {       -- Deal with each group
            ; NonEmpty (Literal, MatchResult CoreExpr)
    alts <- (NonEmpty EquationInfo
     -> IOEnv (Env DsGblEnv DsLclEnv) (Literal, MatchResult CoreExpr))
    -> NonEmpty (NonEmpty EquationInfo)
    -> IOEnv
         (Env DsGblEnv DsLclEnv) (NonEmpty (Literal, MatchResult CoreExpr))
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM NonEmpty EquationInfo
    -> IOEnv (Env DsGblEnv DsLclEnv) (Literal, MatchResult CoreExpr)
    match_group NonEmpty (NonEmpty EquationInfo)
    sub_groups

                    -- Combine results.  For everything except String
                    -- we can use a case expression; for String we need
                    -- a chain of if-then-else
            ; if Type -> Bool
    isStringTy (Id -> Type
    idType Id
    var) then
                do  { Id
    eq_str <- Name -> DsM Id
    dsLookupGlobalId Name
    eqStringName
                    ; NonEmpty (MatchResult CoreExpr)
    mrs <- ((Literal, MatchResult CoreExpr) -> DsM (MatchResult CoreExpr))
    -> NonEmpty (Literal, MatchResult CoreExpr)
    -> IOEnv (Env DsGblEnv DsLclEnv) (NonEmpty (MatchResult CoreExpr))
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (Id -> (Literal, MatchResult CoreExpr) -> DsM (MatchResult CoreExpr)
    wrap_str_guard Id
    eq_str) NonEmpty (Literal, MatchResult CoreExpr)
    alts
                    ; MatchResult CoreExpr -> DsM (MatchResult CoreExpr)
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((MatchResult CoreExpr
     -> MatchResult CoreExpr -> MatchResult CoreExpr)
    -> NonEmpty (MatchResult CoreExpr) -> MatchResult CoreExpr
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
    foldr1 MatchResult CoreExpr
    -> MatchResult CoreExpr -> MatchResult CoreExpr
    combineMatchResults NonEmpty (MatchResult CoreExpr)
    mrs) }
              else
                MatchResult CoreExpr -> DsM (MatchResult CoreExpr)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Id
    -> Type
    -> [(Literal, MatchResult CoreExpr)]
    -> MatchResult CoreExpr
    mkCoPrimCaseMatchResult Id
    var Type
    ty ([(Literal, MatchResult CoreExpr)] -> MatchResult CoreExpr)
    -> [(Literal, MatchResult CoreExpr)] -> MatchResult CoreExpr
    forall a b. (a -> b) -> a -> b
    $ NonEmpty (Literal, MatchResult CoreExpr)
    -> [(Literal, MatchResult CoreExpr)]
    forall a. NonEmpty a -> [a]
    NEL.toList NonEmpty (Literal, MatchResult CoreExpr)
    alts)
            }
      where
        match_group :: NonEmpty EquationInfo -> DsM (Literal, MatchResult CoreExpr)
        match_group :: NonEmpty EquationInfo
    -> IOEnv (Env DsGblEnv DsLclEnv) (Literal, MatchResult CoreExpr)
    match_group eqns :: NonEmpty EquationInfo
    eqns@(EquationInfo
    firstEqn :| [EquationInfo]
    _)
            = do { DynFlags
    dflags <- IOEnv (Env DsGblEnv DsLclEnv) DynFlags
    forall (m :: * -> *). HasDynFlags m => m DynFlags
    getDynFlags
                 ; let platform :: Platform
    platform = DynFlags -> Platform
    targetPlatform DynFlags
    dflags
                 ; let LitPat XLitPat GhcTc
    _ HsLit GhcTc
    hs_lit = EquationInfo -> Pat GhcTc
    firstPat EquationInfo
    firstEqn
                 ; MatchResult CoreExpr
    match_result <- [Id] -> Type -> [EquationInfo] -> DsM (MatchResult CoreExpr)
    match [Id]
    vars Type
    ty (NonEmpty EquationInfo -> [EquationInfo]
    forall a. NonEmpty a -> [a]
    NEL.toList (NonEmpty EquationInfo -> [EquationInfo])
    -> NonEmpty EquationInfo -> [EquationInfo]
    forall a b. (a -> b) -> a -> b
    $ NonEmpty EquationInfo -> NonEmpty EquationInfo
    forall (f :: * -> *). Functor f => f EquationInfo -> f EquationInfo
    shiftEqns NonEmpty EquationInfo
    eqns)
                 ; (Literal, MatchResult CoreExpr)
    -> IOEnv (Env DsGblEnv DsLclEnv) (Literal, MatchResult CoreExpr)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Platform -> HsLit GhcTc -> Literal
    hsLitKey Platform
    platform HsLit GhcTc
    hs_lit, MatchResult CoreExpr
    match_result) }

        wrap_str_guard :: Id -> (Literal,MatchResult CoreExpr) -> DsM (MatchResult CoreExpr)
            -- Equality check for string literals
        wrap_str_guard :: Id -> (Literal, MatchResult CoreExpr) -> DsM (MatchResult CoreExpr)
    wrap_str_guard Id
    eq_str (LitString ByteString
    s, MatchResult CoreExpr
    mr)
            = do { -- We now have to convert back to FastString. Perhaps there
                   -- should be separate LitBytes and LitString constructors?
                   let s' :: FastString
    s'  = ByteString -> FastString
    mkFastStringByteString ByteString
    s
                 ; CoreExpr
    lit    <- FastString -> DsM CoreExpr
    forall (m :: * -> *). MonadThings m => FastString -> m CoreExpr
    mkStringExprFS FastString
    s'
                 ; let pred :: CoreExpr
    pred = CoreExpr -> [CoreExpr] -> CoreExpr
    forall b. Expr b -> [Expr b] -> Expr b
    mkApps (Id -> CoreExpr
    forall b. Id -> Expr b
    Var Id
    eq_str) [Id -> CoreExpr
    forall b. Id -> Expr b
    Var Id
    var, CoreExpr
    lit]
                 ; MatchResult CoreExpr -> DsM (MatchResult CoreExpr)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CoreExpr -> MatchResult CoreExpr -> MatchResult CoreExpr
    mkGuardedMatchResult CoreExpr
    pred MatchResult CoreExpr
    mr) }
        wrap_str_guard Id
    _ (Literal
    l, MatchResult CoreExpr
    _) = String -> SDoc -> DsM (MatchResult CoreExpr)
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "matchLiterals/wrap_str_guard" (Literal -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Literal
    l)

    ---------------------------
    hsLitKey :: Platform -> HsLit GhcTc -> Literal
    -- Get the Core literal corresponding to a HsLit.
    -- It only works for primitive types and strings;
    -- others have been removed by tidy
    -- For HsString, it produces a LitString, which really represents an _unboxed_
    -- string literal; and we deal with it in matchLiterals above. Otherwise, it
    -- produces a primitive Literal of type matching the original HsLit.
    -- In the case of the fixed-width numeric types, we need to wrap here
    -- because Literal has an invariant that the literal is in range, while
    -- HsLit does not.
    hsLitKey :: Platform -> HsLit GhcTc -> Literal
    hsLitKey Platform
    platform (HsIntPrim    XHsIntPrim GhcTc
    _ Integer
    i) = Platform -> Integer -> Literal
    mkLitIntWrap  Platform
    platform Integer
    i
    hsLitKey Platform
    platform (HsWordPrim   XHsWordPrim GhcTc
    _ Integer
    w) = Platform -> Integer -> Literal
    mkLitWordWrap Platform
    platform Integer
    w
    hsLitKey Platform
    platform (HsInt64Prim  XHsInt64Prim GhcTc
    _ Integer
    i) = Platform -> Integer -> Literal
    mkLitInt64Wrap  Platform
    platform Integer
    i
    hsLitKey Platform
    platform (HsWord64Prim XHsWord64Prim GhcTc
    _ Integer
    w) = Platform -> Integer -> Literal
    mkLitWord64Wrap Platform
    platform Integer
    w
    hsLitKey Platform
    _        (HsCharPrim   XHsCharPrim GhcTc
    _ Char
    c) = Char -> Literal
    mkLitChar            Char
    c
    hsLitKey Platform
    _        (HsFloatPrim  XHsFloatPrim GhcTc
    _ FractionalLit
    f) = Rational -> Literal
    mkLitFloat           (FractionalLit -> Rational
    fl_value FractionalLit
    f)
    hsLitKey Platform
    _        (HsDoublePrim XHsDoublePrim GhcTc
    _ FractionalLit
    d) = Rational -> Literal
    mkLitDouble          (FractionalLit -> Rational
    fl_value FractionalLit
    d)
    hsLitKey Platform
    _        (HsString XHsString GhcTc
    _ FastString
    s)     = ByteString -> Literal
    LitString (FastString -> ByteString
    bytesFS FastString
    s)
    hsLitKey Platform
    _        HsLit GhcTc
    l                  = String -> SDoc -> Literal
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "hsLitKey" (HsLit GhcTc -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr HsLit GhcTc
    l)

    {-
    ************************************************************************
    *                                                                      *
                    Pattern matching on NPat
    *                                                                      *
    ************************************************************************
    -}

    matchNPats :: NonEmpty Id -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr)
    matchNPats :: NonEmpty Id
    -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr)
    matchNPats (Id
    var :| [Id]
    vars) Type
    ty (EquationInfo
    eqn1 :| [EquationInfo]
    eqns)    -- All for the same literal
      = do  { let NPat XNPat GhcTc
    _ (L SrcSpan
    _ HsOverLit GhcTc
    lit) Maybe (SyntaxExpr GhcTc)
    mb_neg SyntaxExpr GhcTc
    eq_chk = EquationInfo -> Pat GhcTc
    firstPat EquationInfo
    eqn1
            ; CoreExpr
    lit_expr <- HsOverLit GhcTc -> DsM CoreExpr
    dsOverLit HsOverLit GhcTc
    lit
            ; CoreExpr
    neg_lit <- case Maybe SyntaxExprTc
    mb_neg of
                                Maybe SyntaxExprTc
    Nothing  -> CoreExpr -> DsM CoreExpr
    forall (m :: * -> *) a. Monad m => a -> m a
    return CoreExpr
    lit_expr
                                Just SyntaxExprTc
    neg -> SyntaxExpr GhcTc -> [CoreExpr] -> DsM CoreExpr
    dsSyntaxExpr SyntaxExpr GhcTc
    SyntaxExprTc
    neg [CoreExpr
    lit_expr]
            ; CoreExpr
    pred_expr <- SyntaxExpr GhcTc -> [CoreExpr] -> DsM CoreExpr
    dsSyntaxExpr SyntaxExpr GhcTc
    SyntaxExprTc
    eq_chk [Id -> CoreExpr
    forall b. Id -> Expr b
    Var Id
    var, CoreExpr
    neg_lit]
            ; MatchResult CoreExpr
    match_result <- [Id] -> Type -> [EquationInfo] -> DsM (MatchResult CoreExpr)
    match [Id]
    vars Type
    ty ([EquationInfo] -> [EquationInfo]
    forall (f :: * -> *). Functor f => f EquationInfo -> f EquationInfo
    shiftEqns (EquationInfo
    eqn1EquationInfo -> [EquationInfo] -> [EquationInfo]
    forall a. a -> [a] -> [a]
    :[EquationInfo]
    eqns))
            ; MatchResult CoreExpr -> DsM (MatchResult CoreExpr)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CoreExpr -> MatchResult CoreExpr -> MatchResult CoreExpr
    mkGuardedMatchResult CoreExpr
    pred_expr MatchResult CoreExpr
    match_result) }

    {-
    ************************************************************************
    *                                                                      *
                    Pattern matching on n+k patterns
    *                                                                      *
    ************************************************************************

    For an n+k pattern, we use the various magic expressions we've been given.
    We generate:
    \begin{verbatim}
        if ge var lit then
            let n = sub var lit
            in  <expr-for-a-successful-match>
        else
            <try-next-pattern-or-whatever>
    \end{verbatim}
    -}

    matchNPlusKPats :: NonEmpty Id -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr)
    -- All NPlusKPats, for the *same* literal k
    matchNPlusKPats :: NonEmpty Id
    -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr)
    matchNPlusKPats (Id
    var :| [Id]
    vars) Type
    ty (EquationInfo
    eqn1 :| [EquationInfo]
    eqns)
      = do  { let NPlusKPat XNPlusKPat GhcTc
    _ (L SrcSpan
    _ IdP GhcTc
    n1) (L SrcSpan
    _ HsOverLit GhcTc
    lit1) HsOverLit GhcTc
    lit2 SyntaxExpr GhcTc
    ge SyntaxExpr GhcTc
    minus
                    = EquationInfo -> Pat GhcTc
    firstPat EquationInfo
    eqn1
            ; CoreExpr
    lit1_expr   <- HsOverLit GhcTc -> DsM CoreExpr
    dsOverLit HsOverLit GhcTc
    lit1
            ; CoreExpr
    lit2_expr   <- HsOverLit GhcTc -> DsM CoreExpr
    dsOverLit HsOverLit GhcTc
    lit2
            ; CoreExpr
    pred_expr   <- SyntaxExpr GhcTc -> [CoreExpr] -> DsM CoreExpr
    dsSyntaxExpr SyntaxExpr GhcTc
    SyntaxExprTc
    ge    [Id -> CoreExpr
    forall b. Id -> Expr b
    Var Id
    var, CoreExpr
    lit1_expr]
            ; CoreExpr
    minusk_expr <- SyntaxExpr GhcTc -> [CoreExpr] -> DsM CoreExpr
    dsSyntaxExpr SyntaxExpr GhcTc
    SyntaxExprTc
    minus [Id -> CoreExpr
    forall b. Id -> Expr b
    Var Id
    var, CoreExpr
    lit2_expr]
            ; let ([CoreExpr -> CoreExpr]
    wraps, [EquationInfo]
    eqns') = (EquationInfo -> (CoreExpr -> CoreExpr, EquationInfo))
    -> [EquationInfo] -> ([CoreExpr -> CoreExpr], [EquationInfo])
    forall a b c. (a -> (b, c)) -> [a] -> ([b], [c])
    mapAndUnzip (Id -> EquationInfo -> (CoreExpr -> CoreExpr, EquationInfo)
    shift Id
    n1) (EquationInfo
    eqn1EquationInfo -> [EquationInfo] -> [EquationInfo]
    forall a. a -> [a] -> [a]
    :[EquationInfo]
    eqns)
            ; MatchResult CoreExpr
    match_result <- [Id] -> Type -> [EquationInfo] -> DsM (MatchResult CoreExpr)
    match [Id]
    vars Type
    ty [EquationInfo]
    eqns'
            ; MatchResult CoreExpr -> DsM (MatchResult CoreExpr)
    forall (m :: * -> *) a. Monad m => a -> m a
    return  (CoreExpr -> MatchResult CoreExpr -> MatchResult CoreExpr
    mkGuardedMatchResult CoreExpr
    pred_expr               (MatchResult CoreExpr -> MatchResult CoreExpr)
    -> MatchResult CoreExpr -> MatchResult CoreExpr
    forall a b. (a -> b) -> a -> b
    $
                       CoreBind -> MatchResult CoreExpr -> MatchResult CoreExpr
    mkCoLetMatchResult (Id -> CoreExpr -> CoreBind
    forall b. b -> Expr b -> Bind b
    NonRec Id
    n1 CoreExpr
    minusk_expr)   (MatchResult CoreExpr -> MatchResult CoreExpr)
    -> MatchResult CoreExpr -> MatchResult CoreExpr
    forall a b. (a -> b) -> a -> b
    $
                       (CoreExpr -> CoreExpr)
    -> MatchResult CoreExpr -> MatchResult CoreExpr
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (((CoreExpr -> CoreExpr)
     -> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr)
    -> [CoreExpr -> CoreExpr] -> CoreExpr -> CoreExpr
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
    foldr1 (CoreExpr -> CoreExpr)
    -> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.) [CoreExpr -> CoreExpr]
    wraps)                      (MatchResult CoreExpr -> MatchResult CoreExpr)
    -> MatchResult CoreExpr -> MatchResult CoreExpr
    forall a b. (a -> b) -> a -> b
    $
                       MatchResult CoreExpr
    match_result) }
      where
        shift :: Id -> EquationInfo -> (CoreExpr -> CoreExpr, EquationInfo)
    shift Id
    n1 eqn :: EquationInfo
    eqn@(EqnInfo { eqn_pats :: EquationInfo -> [Pat GhcTc]
    eqn_pats = NPlusKPat XNPlusKPat GhcTc
    _ (L SrcSpan
    _ IdP GhcTc
    n) Located (HsOverLit GhcTc)
    _ HsOverLit GhcTc
    _ SyntaxExpr GhcTc
    _ SyntaxExpr GhcTc
    _ : [Pat GhcTc]
    pats })
            = (Id -> Id -> CoreExpr -> CoreExpr
    wrapBind Id
    IdP GhcTc
    n Id
    n1, EquationInfo
    eqn { eqn_pats :: [Pat GhcTc]
    eqn_pats = [Pat GhcTc]
    pats })
            -- The wrapBind is a no-op for the first equation
        shift Id
    _ EquationInfo
    e = String -> SDoc -> (CoreExpr -> CoreExpr, EquationInfo)
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "matchNPlusKPats/shift" (EquationInfo -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr EquationInfo
    e)