{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow]
                                      -- in module Language.Haskell.Syntax.Extension
{-
(c) The University of Glasgow 2006
(c) The GRASP/AQUA Project, Glasgow University, 1992-1998

\section[PatSyntax]{Abstract Haskell syntax---patterns}
-}

-- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.*
module Language.Haskell.Syntax.Pat (
        Pat(..), LPat,
        ConLikeP,
        isInvisArgPat, isInvisArgLPat,
        isVisArgPat, isVisArgLPat,

        HsConPatDetails, hsConPatArgs,
        takeHsConPatTyArgs, dropHsConPatTyArgs,
        HsRecFields(..), XHsRecFields, HsFieldBind(..), LHsFieldBind,
        HsRecField, LHsRecField,
        HsRecUpdField, LHsRecUpdField,
        RecFieldsDotDot(..)
    ) where

import {-# SOURCE #-} Language.Haskell.Syntax.Expr (SyntaxExpr, LHsExpr, HsUntypedSplice)

-- friends:
import Language.Haskell.Syntax.Basic
import Language.Haskell.Syntax.Lit
import Language.Haskell.Syntax.Extension
import Language.Haskell.Syntax.Type

-- libraries:
import Data.Maybe
import Data.Functor
import Data.Foldable
import Data.Traversable
import Data.Bool
import Data.Data
import Data.Eq
import Data.Ord
import Data.Int
import Data.Function
import qualified Data.List
import Data.List.NonEmpty (NonEmpty)

type LPat p = XRec p (Pat p)

-- | Pattern
data Pat p
  =     ------------ Simple patterns ---------------
    WildPat     (XWildPat p)
    -- ^ Wildcard Pattern, i.e. @_@

  | VarPat      (XVarPat p)
                (LIdP p)
    -- ^ Variable Pattern, e.g. @x@

    -- See Note [Located RdrNames] in GHC.Hs.Expr
  | LazyPat     (XLazyPat p)
                (LPat p)
    -- ^ Lazy Pattern, e.g. @~x@
  | AsPat       (XAsPat p)
                (LIdP p)
                (LPat p)
    -- ^ As pattern, e.g. @x\@pat@
  | ParPat      (XParPat p)
                (LPat p)
    -- ^ Parenthesised pattern, e.g. @(x)@

    -- See Note [Parens in HsSyn] in GHC.Hs.Expr
  | BangPat     (XBangPat p)
                (LPat p)
    -- ^ Bang pattern, e.g. @!x@

        ------------ Lists, tuples, arrays ---------------
  | ListPat     (XListPat p)
                [LPat p]
    -- ^ Syntactic List, e.g. @[x]@ or @[x,y]@.
    -- Note that @[]@ and @(x:xs)@ patterns are both represented using 'ConPat'.

  | -- | Tuple pattern, e.g. @(x, y)@ (boxed tuples) or @(# x, y #)@ (requires @-XUnboxedTuples@)
    TuplePat    (XTuplePat p)    -- ^ After typechecking, holds the types of the tuple components
                [LPat p]         -- ^ Tuple sub-patterns
                Boxity

        -- You might think that the post typechecking Type was redundant,
        -- because we can get the pattern type by getting the types of the
        -- sub-patterns.
        -- But it's essential
        --      data T a where
        --        T1 :: Int -> T Int
        --      f :: (T a, a) -> Int
        --      f (T1 x, z) = z
        -- When desugaring, we must generate
        --      f = /\a. \v::a.  case v of (t::T a, w::a) ->
        --                       case t of (T1 (x::Int)) ->
        -- Note the (w::a), NOT (w::Int), because we have not yet
        -- refined 'a' to Int.  So we must know that the second component
        -- of the tuple is of type 'a' not Int.  See selectMatchVar
        -- (June 14: I'm not sure this comment is right; the sub-patterns
        --           will be wrapped in CoPats, no?)

  | OrPat       (XOrPat p)
                (NonEmpty (LPat p))
    -- ^ Or Pattern, e.g. @(pat_1; ...; pat_n)@. Used by @-XOrPatterns@
    --
    -- @since 9.12.1

  | SumPat      (XSumPat p)        -- after typechecker, types of the alternative
                (LPat p)           -- Sum sub-pattern
                ConTag             -- Alternative (one-based)
                SumWidth           -- Arity (INVARIANT: ≥ 2)

    -- ^ Anonymous sum pattern, e.g. @(# x | #)@. Used by @-XUnboxedSums@

        ------------ Constructor patterns ---------------
  | ConPat {
        forall p. Pat p -> XConPat p
pat_con_ext :: XConPat p,
        forall p. Pat p -> XRec p (ConLikeP p)
pat_con     :: XRec p (ConLikeP p),
        forall p. Pat p -> HsConPatDetails p
pat_args    :: HsConPatDetails p
    }
    -- ^ Constructor Pattern, e.g. @()@, @[]@ or @Nothing@

        ------------ View patterns ---------------

  | ViewPat       (XViewPat p)
                  (LHsExpr p)
                  (LPat p)
    -- ^ View Pattern, e.g. @someFun -> pat@. Used by @-XViewPatterns@

        ------------ Pattern splices ---------------

  | SplicePat       (XSplicePat p)
                    (HsUntypedSplice p)
  -- ^  Splice Pattern, e.g. @$(pat)@

        ------------ Literal and n+k patterns ---------------
  | LitPat          (XLitPat p)
                    (HsLit p)
    -- ^ Literal Pattern
    --
    -- Used for __non-overloaded__ literal patterns:
    -- Int#, Char#, Int, Char, String, etc.

  | QualLitPat      (XQualLitPat p)
                    (HsQualLit p)
    -- ^ Qualified Literal Pattern

  | NPat            (XNPat p)            -- Overall type of pattern. Might be
                                         -- different than the literal's type
                                         -- if (==) or negate changes the type
                    (XRec p (HsOverLit p))     -- ALWAYS positive
                    (Maybe (SyntaxExpr p)) -- Just (Name of 'negate') for
                                           -- negative patterns, Nothing
                                           -- otherwise
                    (SyntaxExpr p)       -- Equality checker, of type t->t->Bool

  -- ^ Natural Pattern, used for all overloaded literals, including overloaded Strings
  -- with @-XOverloadedStrings@

  | -- | n+k pattern, e.g. @n+1@, used by @-XNPlusKPatterns@
   NPlusKPat       (XNPlusKPat p)           -- Type of overall pattern
                    (LIdP p)                 -- n+k pattern
                    (XRec p (HsOverLit p))   -- It'll always be an HsIntegral
                    (HsOverLit p)            -- See Note [NPlusK patterns] in GHC.Tc.Gen.Pat
                     -- NB: This could be (PostTc ...), but that induced a
                     -- a new hs-boot file. Not worth it.

                    (SyntaxExpr p)   -- (>=) function, of type t1->t2->Bool
                    (SyntaxExpr p)   -- Name of '-' (see GHC.Rename.Env.lookupSyntax)

        ------------ Pattern type signatures ---------------

  | SigPat          (XSigPat p)             -- After typechecker: Type
                    (LPat p)                -- Pattern with a type signature
                    (HsPatSigType (NoGhcTc p)) --  Signature can bind both
                                               --  kind and type vars

   -- ^ Pattern with a type signature, e.g. @x :: Int@

  | -- | Embed the syntax of types into patterns, e.g. @fn (type t) = rhs@.
    -- Enabled by @-XExplicitNamespaces@ in conjunction with @-XRequiredTypeArguments@.
    EmbTyPat        (XEmbTyPat p)
                    (HsTyPat (NoGhcTc p))

  | InvisPat (XInvisPat p) (HsTyPat (NoGhcTc p))
  -- ^ Type abstraction which brings into scope type variables associated with invisible forall.
  -- E.g. @fn \@t ... = rhs@. Used by @-XTypeAbstractions@.

  | ModifiedPat (XModifiedPat p) [LHsModifier p] (LPat p)
  -- ^ Pattern with attached modifiers. See Note [Overview of Modifiers] and
  -- Note [Modifiers on patterns vs bindings].
  -- E.g. @(%X x) = ...@

  -- See Note [Invisible binders in functions] in GHC.Hs.Pat

  | -- | TTG Extension point; see Note [Trees That Grow] in Language.Haskell.Syntax.Extension
    XPat !(XXPat p)

type family ConLikeP x

{-
Note [Modifiers on patterns vs bindings]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modifiers can be attached both to patterns and to bindings. Modifiers on
bindings are used with @-XLinearTypes@ (see Note [Modifiers on bindings] in
Language.Haskell.Syntax.Binds). Modifiers on patterns are currently unused.

The modifiers proposal
(https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0370-modifiers.rst)
specifies that modifiers can be attached to patterns. These modifiers are
currently unused. The proposal also takes as a given that they can be attached
to bindings. (That syntax already existed when the proposal was written.) These
modifiers are used with @-XLinearTypes@, see Note [Modifiers on bindings] in
Language.Haskell.Syntax.Binds.

But the proposal isn't explicit about how to parse @let %m p = ...@. Naively it
could be either of

- @PatBind [%m] p@
- @PatBind [] (ModifiedPat [%m] p)@

But we need it to work with linear types, so we need to pick the first. We pick
it by parsing @%m p@ as a pattern (actually a 'PatBuilder'), and moving
modifiers at the root of the pattern to the binding, so that a 'PatBind' never
directly contains a 'ModifiedPat'. This logic is implemented in
'extract_pat_builder_modifiers' in GHC.Parser.PostProcess. In source code:

- @let %m p = ...@ attaches the modifier to the binding: @PatBind [%m] p@.
- @let (%m p) = ...@ attaches it to the pattern:
  @PatBind [] (ParPat (ModifiedPat [%m] p))@.
- @let %m x:xs = ...@ attaches it to the subpattern @x@:
  @PatBind [] (ConPat : [ModifiedPat [%m] x, xs])@.

This last is a breaking change: before modifiers were implemented, it would
instead have attached the %m to the binding. (And @let %m Just x = ...@ would
have done the same, where now it fails to parse.) So some programs that used to
be accepted with @-XLinearTypes@ are no longer accepted; but since linear
bindings must be strict, such programs would be rare.

Another possible solution (untried) might have been to specifically recognize
modifiers at the start of the binding, and not parse them as part of a pattern,
such that:

- @let %m p = ...@ and @let (%m p) = ...@ would be as above.
- @let %m x:xs = ...@ would be @PatBind [%m] (ConPat : [x, xs])@.
- @let %m Just x = ...@ would be @PatBind [%m] (ConPat Just [x])@.

This would make modifier parsing significantly different from how strict
bindings are parsed:

- @let !x = ...@ is a 'FunBind' with a 'SrcStrict' annotation.
- @let (!p) x = ...@ is a PatBind' holding a 'BangPat'.
- @let !x:y = ...@ parses like @let (!x):y = ...@.
- @let !Just x = ...@ fails to parse.

See Note [FunBind vs PatBind] in Language.Haskell.Syntax.Binds.
-}

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

isInvisArgPat :: Pat p -> Bool
isInvisArgPat :: forall p. Pat p -> Bool
isInvisArgPat InvisPat{} = Bool
True
isInvisArgPat Pat p
_   = Bool
False

isInvisArgLPat :: forall p. (UnXRec p) => LPat p -> Bool
isInvisArgLPat :: forall p. UnXRec p => LPat p -> Bool
isInvisArgLPat = Pat p -> Bool
forall p. Pat p -> Bool
isInvisArgPat (Pat p -> Bool)
-> (XRec p (Pat p) -> Pat p) -> XRec p (Pat p) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall p a. UnXRec p => XRec p a -> a
unXRec @p

isVisArgPat :: Pat p -> Bool
isVisArgPat :: forall p. Pat p -> Bool
isVisArgPat = Bool -> Bool
not (Bool -> Bool) -> (Pat p -> Bool) -> Pat p -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pat p -> Bool
forall p. Pat p -> Bool
isInvisArgPat

isVisArgLPat :: forall p. (UnXRec p) => LPat p -> Bool
isVisArgLPat :: forall p. UnXRec p => LPat p -> Bool
isVisArgLPat = Pat p -> Bool
forall p. Pat p -> Bool
isVisArgPat (Pat p -> Bool)
-> (XRec p (Pat p) -> Pat p) -> XRec p (Pat p) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall p a. UnXRec p => XRec p a -> a
unXRec @p

-- | Haskell Constructor Pattern Details
type HsConPatDetails p = HsConDetails (LPat p) (HsRecFields p (LPat p))

hsConPatArgs :: forall p . (UnXRec p) => HsConPatDetails p -> [LPat p]
hsConPatArgs :: forall p. UnXRec p => HsConPatDetails p -> [LPat p]
hsConPatArgs (PrefixCon [LPat p]
ps)   = [LPat p]
ps
hsConPatArgs (RecCon HsRecFields p (LPat p)
fs)      = (XRec p (HsFieldBind (XRec p (FieldOcc p)) (LPat p)) -> LPat p)
-> [XRec p (HsFieldBind (XRec p (FieldOcc p)) (LPat p))]
-> [LPat p]
forall a b. (a -> b) -> [a] -> [b]
Data.List.map (HsFieldBind (XRec p (FieldOcc p)) (LPat p) -> LPat p
forall lhs rhs. HsFieldBind lhs rhs -> rhs
hfbRHS (HsFieldBind (XRec p (FieldOcc p)) (LPat p) -> LPat p)
-> (XRec p (HsFieldBind (XRec p (FieldOcc p)) (LPat p))
    -> HsFieldBind (XRec p (FieldOcc p)) (LPat p))
-> XRec p (HsFieldBind (XRec p (FieldOcc p)) (LPat p))
-> LPat p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall p a. UnXRec p => XRec p a -> a
unXRec @p) (HsRecFields p (LPat p)
-> [XRec p (HsFieldBind (XRec p (FieldOcc p)) (LPat p))]
forall p arg. HsRecFields p arg -> [LHsRecField p arg]
rec_flds HsRecFields p (LPat p)
fs)
hsConPatArgs (InfixCon LPat p
p1 LPat p
p2) = [LPat p
p1,LPat p
p2]

takeHsConPatTyArgs :: forall p. (UnXRec p) => [LPat p] -> [HsTyPat (NoGhcTc p)]
takeHsConPatTyArgs :: forall p. UnXRec p => [LPat p] -> [HsTyPat (NoGhcTc p)]
takeHsConPatTyArgs (LPat p
p : [LPat p]
ps)
  | InvisPat XInvisPat p
_ HsTyPat (NoGhcTc p)
tp <- forall p a. UnXRec p => XRec p a -> a
unXRec @p LPat p
p
  = HsTyPat (NoGhcTc p)
tp HsTyPat (NoGhcTc p)
-> [HsTyPat (NoGhcTc p)] -> [HsTyPat (NoGhcTc p)]
forall a. a -> [a] -> [a]
: [LPat p] -> [HsTyPat (NoGhcTc p)]
forall p. UnXRec p => [LPat p] -> [HsTyPat (NoGhcTc p)]
takeHsConPatTyArgs [LPat p]
ps
takeHsConPatTyArgs [LPat p]
_ = []

dropHsConPatTyArgs :: forall p. (UnXRec p) => [LPat p] -> [LPat p]
dropHsConPatTyArgs :: forall p. UnXRec p => [LPat p] -> [LPat p]
dropHsConPatTyArgs = (XRec p (Pat p) -> Bool) -> [XRec p (Pat p)] -> [XRec p (Pat p)]
forall a. (a -> Bool) -> [a] -> [a]
Data.List.dropWhile (Pat p -> Bool
forall p. Pat p -> Bool
isInvisArgPat (Pat p -> Bool)
-> (XRec p (Pat p) -> Pat p) -> XRec p (Pat p) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall p a. UnXRec p => XRec p a -> a
unXRec @p)

-- | Haskell Record Fields
--
-- HsRecFields is used only for patterns and expressions (not data type
-- declarations)
data HsRecFields p arg         -- A bunch of record fields
                                --      { x = 3, y = True }
        -- Used for both expressions and patterns
  = HsRecFields { forall p arg. HsRecFields p arg -> XHsRecFields p
rec_ext    :: !(XHsRecFields p),
                  forall p arg. HsRecFields p arg -> [LHsRecField p arg]
rec_flds   :: [LHsRecField p arg],
                  forall p arg. HsRecFields p arg -> Maybe (XRec p RecFieldsDotDot)
rec_dotdot :: Maybe (XRec p RecFieldsDotDot) }  -- Note [DotDot fields]
  -- AZ:The XRec for LHsRecField makes the derivings fail.
  -- deriving (Functor, Foldable, Traversable)

type family XHsRecFields p

-- | Newtype to be able to have a specific XRec instance for the Int in `rec_dotdot`
newtype RecFieldsDotDot = RecFieldsDotDot { RecFieldsDotDot -> Int
unRecFieldsDotDot :: Int }
    deriving (Typeable RecFieldsDotDot
Typeable RecFieldsDotDot =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> RecFieldsDotDot -> c RecFieldsDotDot)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c RecFieldsDotDot)
-> (RecFieldsDotDot -> Constr)
-> (RecFieldsDotDot -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c RecFieldsDotDot))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c RecFieldsDotDot))
-> ((forall b. Data b => b -> b)
    -> RecFieldsDotDot -> RecFieldsDotDot)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> RecFieldsDotDot -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> RecFieldsDotDot -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> RecFieldsDotDot -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> RecFieldsDotDot -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> RecFieldsDotDot -> m RecFieldsDotDot)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> RecFieldsDotDot -> m RecFieldsDotDot)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> RecFieldsDotDot -> m RecFieldsDotDot)
-> Data RecFieldsDotDot
RecFieldsDotDot -> Constr
RecFieldsDotDot -> DataType
(forall b. Data b => b -> b) -> RecFieldsDotDot -> RecFieldsDotDot
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> RecFieldsDotDot -> u
forall u. (forall d. Data d => d -> u) -> RecFieldsDotDot -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> RecFieldsDotDot -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> RecFieldsDotDot -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> RecFieldsDotDot -> m RecFieldsDotDot
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> RecFieldsDotDot -> m RecFieldsDotDot
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c RecFieldsDotDot
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> RecFieldsDotDot -> c RecFieldsDotDot
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c RecFieldsDotDot)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c RecFieldsDotDot)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> RecFieldsDotDot -> c RecFieldsDotDot
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> RecFieldsDotDot -> c RecFieldsDotDot
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c RecFieldsDotDot
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c RecFieldsDotDot
$ctoConstr :: RecFieldsDotDot -> Constr
toConstr :: RecFieldsDotDot -> Constr
$cdataTypeOf :: RecFieldsDotDot -> DataType
dataTypeOf :: RecFieldsDotDot -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c RecFieldsDotDot)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c RecFieldsDotDot)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c RecFieldsDotDot)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c RecFieldsDotDot)
$cgmapT :: (forall b. Data b => b -> b) -> RecFieldsDotDot -> RecFieldsDotDot
gmapT :: (forall b. Data b => b -> b) -> RecFieldsDotDot -> RecFieldsDotDot
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> RecFieldsDotDot -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> RecFieldsDotDot -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> RecFieldsDotDot -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> RecFieldsDotDot -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> RecFieldsDotDot -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> RecFieldsDotDot -> [u]
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> RecFieldsDotDot -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> RecFieldsDotDot -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> RecFieldsDotDot -> m RecFieldsDotDot
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> RecFieldsDotDot -> m RecFieldsDotDot
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> RecFieldsDotDot -> m RecFieldsDotDot
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> RecFieldsDotDot -> m RecFieldsDotDot
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> RecFieldsDotDot -> m RecFieldsDotDot
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> RecFieldsDotDot -> m RecFieldsDotDot
Data, RecFieldsDotDot -> RecFieldsDotDot -> Bool
(RecFieldsDotDot -> RecFieldsDotDot -> Bool)
-> (RecFieldsDotDot -> RecFieldsDotDot -> Bool)
-> Eq RecFieldsDotDot
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
== :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
$c/= :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
/= :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
Eq, Eq RecFieldsDotDot
Eq RecFieldsDotDot =>
(RecFieldsDotDot -> RecFieldsDotDot -> Ordering)
-> (RecFieldsDotDot -> RecFieldsDotDot -> Bool)
-> (RecFieldsDotDot -> RecFieldsDotDot -> Bool)
-> (RecFieldsDotDot -> RecFieldsDotDot -> Bool)
-> (RecFieldsDotDot -> RecFieldsDotDot -> Bool)
-> (RecFieldsDotDot -> RecFieldsDotDot -> RecFieldsDotDot)
-> (RecFieldsDotDot -> RecFieldsDotDot -> RecFieldsDotDot)
-> Ord RecFieldsDotDot
RecFieldsDotDot -> RecFieldsDotDot -> Bool
RecFieldsDotDot -> RecFieldsDotDot -> Ordering
RecFieldsDotDot -> RecFieldsDotDot -> RecFieldsDotDot
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: RecFieldsDotDot -> RecFieldsDotDot -> Ordering
compare :: RecFieldsDotDot -> RecFieldsDotDot -> Ordering
$c< :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
< :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
$c<= :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
<= :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
$c> :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
> :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
$c>= :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
>= :: RecFieldsDotDot -> RecFieldsDotDot -> Bool
$cmax :: RecFieldsDotDot -> RecFieldsDotDot -> RecFieldsDotDot
max :: RecFieldsDotDot -> RecFieldsDotDot -> RecFieldsDotDot
$cmin :: RecFieldsDotDot -> RecFieldsDotDot -> RecFieldsDotDot
min :: RecFieldsDotDot -> RecFieldsDotDot -> RecFieldsDotDot
Ord)

-- Note [DotDot fields]
-- ~~~~~~~~~~~~~~~~~~~~
-- The rec_dotdot field means this:
--   Nothing => the normal case
--   Just n  => the group uses ".." notation,
--
-- In the latter case:
--
--   *before* renamer: rec_flds are exactly the n user-written fields
--
--   *after* renamer:  rec_flds includes *all* fields, with
--                     the first 'n' being the user-written ones
--                     and the remainder being 'filled in' implicitly

-- | Located Haskell Record Field
type LHsFieldBind p id arg = XRec p (HsFieldBind id arg)

-- | Located Haskell Record Field
type LHsRecField  p arg = XRec p (HsRecField  p arg)

-- | Haskell Record Field
type HsRecField p arg   = HsFieldBind (LFieldOcc p) arg

-- | Located Haskell Record Update Field
type LHsRecUpdField p q = XRec p (HsRecUpdField p q)

-- | Haskell Record Update Field
type HsRecUpdField p q  = HsFieldBind (LFieldOcc p) (LHsExpr q)

-- | Haskell Field Binding
data HsFieldBind lhs rhs = HsFieldBind {
        forall lhs rhs. HsFieldBind lhs rhs -> XHsFieldBind lhs
hfbAnn :: XHsFieldBind lhs,
        forall lhs rhs. HsFieldBind lhs rhs -> lhs
hfbLHS :: lhs,
        forall lhs rhs. HsFieldBind lhs rhs -> rhs
hfbRHS :: rhs,           -- ^ Filled in by renamer when punning
        forall lhs rhs. HsFieldBind lhs rhs -> Bool
hfbPun :: Bool           -- ^ Note [Punning]
  } deriving ((forall a b. (a -> b) -> HsFieldBind lhs a -> HsFieldBind lhs b)
-> (forall a b. a -> HsFieldBind lhs b -> HsFieldBind lhs a)
-> Functor (HsFieldBind lhs)
forall a b. a -> HsFieldBind lhs b -> HsFieldBind lhs a
forall a b. (a -> b) -> HsFieldBind lhs a -> HsFieldBind lhs b
forall lhs a b. a -> HsFieldBind lhs b -> HsFieldBind lhs a
forall lhs a b. (a -> b) -> HsFieldBind lhs a -> HsFieldBind lhs b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall lhs a b. (a -> b) -> HsFieldBind lhs a -> HsFieldBind lhs b
fmap :: forall a b. (a -> b) -> HsFieldBind lhs a -> HsFieldBind lhs b
$c<$ :: forall lhs a b. a -> HsFieldBind lhs b -> HsFieldBind lhs a
<$ :: forall a b. a -> HsFieldBind lhs b -> HsFieldBind lhs a
Functor, (forall m. Monoid m => HsFieldBind lhs m -> m)
-> (forall m a. Monoid m => (a -> m) -> HsFieldBind lhs a -> m)
-> (forall m a. Monoid m => (a -> m) -> HsFieldBind lhs a -> m)
-> (forall a b. (a -> b -> b) -> b -> HsFieldBind lhs a -> b)
-> (forall a b. (a -> b -> b) -> b -> HsFieldBind lhs a -> b)
-> (forall b a. (b -> a -> b) -> b -> HsFieldBind lhs a -> b)
-> (forall b a. (b -> a -> b) -> b -> HsFieldBind lhs a -> b)
-> (forall a. (a -> a -> a) -> HsFieldBind lhs a -> a)
-> (forall a. (a -> a -> a) -> HsFieldBind lhs a -> a)
-> (forall a. HsFieldBind lhs a -> [a])
-> (forall a. HsFieldBind lhs a -> Bool)
-> (forall a. HsFieldBind lhs a -> Int)
-> (forall a. Eq a => a -> HsFieldBind lhs a -> Bool)
-> (forall a. Ord a => HsFieldBind lhs a -> a)
-> (forall a. Ord a => HsFieldBind lhs a -> a)
-> (forall a. Num a => HsFieldBind lhs a -> a)
-> (forall a. Num a => HsFieldBind lhs a -> a)
-> Foldable (HsFieldBind lhs)
forall a. Eq a => a -> HsFieldBind lhs a -> Bool
forall a. Num a => HsFieldBind lhs a -> a
forall a. Ord a => HsFieldBind lhs a -> a
forall m. Monoid m => HsFieldBind lhs m -> m
forall a. HsFieldBind lhs a -> Bool
forall a. HsFieldBind lhs a -> Int
forall a. HsFieldBind lhs a -> [a]
forall a. (a -> a -> a) -> HsFieldBind lhs a -> a
forall lhs a. Eq a => a -> HsFieldBind lhs a -> Bool
forall lhs a. Num a => HsFieldBind lhs a -> a
forall lhs a. Ord a => HsFieldBind lhs a -> a
forall lhs m. Monoid m => HsFieldBind lhs m -> m
forall m a. Monoid m => (a -> m) -> HsFieldBind lhs a -> m
forall lhs rhs. HsFieldBind lhs rhs -> Bool
forall lhs a. HsFieldBind lhs a -> Int
forall lhs a. HsFieldBind lhs a -> [a]
forall b a. (b -> a -> b) -> b -> HsFieldBind lhs a -> b
forall a b. (a -> b -> b) -> b -> HsFieldBind lhs a -> b
forall lhs a. (a -> a -> a) -> HsFieldBind lhs a -> a
forall lhs m a. Monoid m => (a -> m) -> HsFieldBind lhs a -> m
forall lhs b a. (b -> a -> b) -> b -> HsFieldBind lhs a -> b
forall lhs a b. (a -> b -> b) -> b -> HsFieldBind lhs a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall lhs m. Monoid m => HsFieldBind lhs m -> m
fold :: forall m. Monoid m => HsFieldBind lhs m -> m
$cfoldMap :: forall lhs m a. Monoid m => (a -> m) -> HsFieldBind lhs a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> HsFieldBind lhs a -> m
$cfoldMap' :: forall lhs m a. Monoid m => (a -> m) -> HsFieldBind lhs a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> HsFieldBind lhs a -> m
$cfoldr :: forall lhs a b. (a -> b -> b) -> b -> HsFieldBind lhs a -> b
foldr :: forall a b. (a -> b -> b) -> b -> HsFieldBind lhs a -> b
$cfoldr' :: forall lhs a b. (a -> b -> b) -> b -> HsFieldBind lhs a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> HsFieldBind lhs a -> b
$cfoldl :: forall lhs b a. (b -> a -> b) -> b -> HsFieldBind lhs a -> b
foldl :: forall b a. (b -> a -> b) -> b -> HsFieldBind lhs a -> b
$cfoldl' :: forall lhs b a. (b -> a -> b) -> b -> HsFieldBind lhs a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> HsFieldBind lhs a -> b
$cfoldr1 :: forall lhs a. (a -> a -> a) -> HsFieldBind lhs a -> a
foldr1 :: forall a. (a -> a -> a) -> HsFieldBind lhs a -> a
$cfoldl1 :: forall lhs a. (a -> a -> a) -> HsFieldBind lhs a -> a
foldl1 :: forall a. (a -> a -> a) -> HsFieldBind lhs a -> a
$ctoList :: forall lhs a. HsFieldBind lhs a -> [a]
toList :: forall a. HsFieldBind lhs a -> [a]
$cnull :: forall lhs rhs. HsFieldBind lhs rhs -> Bool
null :: forall a. HsFieldBind lhs a -> Bool
$clength :: forall lhs a. HsFieldBind lhs a -> Int
length :: forall a. HsFieldBind lhs a -> Int
$celem :: forall lhs a. Eq a => a -> HsFieldBind lhs a -> Bool
elem :: forall a. Eq a => a -> HsFieldBind lhs a -> Bool
$cmaximum :: forall lhs a. Ord a => HsFieldBind lhs a -> a
maximum :: forall a. Ord a => HsFieldBind lhs a -> a
$cminimum :: forall lhs a. Ord a => HsFieldBind lhs a -> a
minimum :: forall a. Ord a => HsFieldBind lhs a -> a
$csum :: forall lhs a. Num a => HsFieldBind lhs a -> a
sum :: forall a. Num a => HsFieldBind lhs a -> a
$cproduct :: forall lhs a. Num a => HsFieldBind lhs a -> a
product :: forall a. Num a => HsFieldBind lhs a -> a
Foldable, Functor (HsFieldBind lhs)
Foldable (HsFieldBind lhs)
(Functor (HsFieldBind lhs), Foldable (HsFieldBind lhs)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> HsFieldBind lhs a -> f (HsFieldBind lhs b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    HsFieldBind lhs (f a) -> f (HsFieldBind lhs a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> HsFieldBind lhs a -> m (HsFieldBind lhs b))
-> (forall (m :: * -> *) a.
    Monad m =>
    HsFieldBind lhs (m a) -> m (HsFieldBind lhs a))
-> Traversable (HsFieldBind lhs)
forall lhs. Functor (HsFieldBind lhs)
forall lhs. Foldable (HsFieldBind lhs)
forall lhs (m :: * -> *) a.
Monad m =>
HsFieldBind lhs (m a) -> m (HsFieldBind lhs a)
forall lhs (f :: * -> *) a.
Applicative f =>
HsFieldBind lhs (f a) -> f (HsFieldBind lhs a)
forall lhs (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HsFieldBind lhs a -> m (HsFieldBind lhs b)
forall lhs (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HsFieldBind lhs a -> f (HsFieldBind lhs b)
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
HsFieldBind lhs (m a) -> m (HsFieldBind lhs a)
forall (f :: * -> *) a.
Applicative f =>
HsFieldBind lhs (f a) -> f (HsFieldBind lhs a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HsFieldBind lhs a -> m (HsFieldBind lhs b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HsFieldBind lhs a -> f (HsFieldBind lhs b)
$ctraverse :: forall lhs (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HsFieldBind lhs a -> f (HsFieldBind lhs b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HsFieldBind lhs a -> f (HsFieldBind lhs b)
$csequenceA :: forall lhs (f :: * -> *) a.
Applicative f =>
HsFieldBind lhs (f a) -> f (HsFieldBind lhs a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
HsFieldBind lhs (f a) -> f (HsFieldBind lhs a)
$cmapM :: forall lhs (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HsFieldBind lhs a -> m (HsFieldBind lhs b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HsFieldBind lhs a -> m (HsFieldBind lhs b)
$csequence :: forall lhs (m :: * -> *) a.
Monad m =>
HsFieldBind lhs (m a) -> m (HsFieldBind lhs a)
sequence :: forall (m :: * -> *) a.
Monad m =>
HsFieldBind lhs (m a) -> m (HsFieldBind lhs a)
Traversable)


-- Note [Punning]
-- ~~~~~~~~~~~~~~
-- If you write T { x, y = v+1 }, the HsRecFields will be
--      HsRecField x x True ...
--      HsRecField y (v+1) False ...
-- That is, for "punned" field x is expanded (in the renamer)
-- to x=x; but with a punning flag so we can detect it later
-- (e.g. when pretty printing)
--
-- If the original field was qualified, we un-qualify it, thus
--    T { A.x } means T { A.x = x }


-- Note [HsRecField and HsRecUpdField]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-- A HsRecField (used for record construction and pattern matching)
-- contains an unambiguous occurrence of a field (i.e. a FieldOcc).
-- We can't just store the Name, because thanks to
-- DuplicateRecordFields this may not correspond to the label the user
-- wrote.
--
-- A HsRecUpdField (used for record update) contains a potentially
-- ambiguous occurrence of a field (an AmbiguousFieldOcc).  The
-- renamer will fill in the selector function if it can, but if the
-- selector is ambiguous the renamer will defer to the typechecker.
-- After the typechecker, a unique selector will have been determined.
--
-- The renamer produces an Unambiguous result if it can, rather than
-- just doing the lookup in the typechecker, so that completely
-- unambiguous updates can be represented by 'GHC.HsToCore.Quote.repUpdFields'.
--
-- For example, suppose we have:
--
--     data S = MkS { x :: Int }
--     data T = MkT { x :: Int }
--
--     f z = (z { x = 3 }) :: S
--
-- The parsed HsRecUpdField corresponding to the record update will have:
--
--     hfbLHS = Unambiguous "x" noExtField :: AmbiguousFieldOcc RdrName
--
-- After the renamer, this will become:
--
--     hfbLHS = Ambiguous   "x" noExtField :: AmbiguousFieldOcc Name
--
-- (note that the Unambiguous constructor is not type-correct here).
-- The typechecker will determine the particular selector:
--
--     hfbLHS = Unambiguous "x" $sel:x:MkS  :: AmbiguousFieldOcc Id
--
-- See also Note [Disambiguating record updates] in GHC.Rename.Pat.