Commit 8168b42a authored by Vladislav Zavialov's avatar Vladislav Zavialov

Whitespace-sensitive bang patterns (#1087, #17162)

This patch implements a part of GHC Proposal #229 that covers five
operators:

* the bang operator (!)
* the tilde operator (~)
* the at operator (@)
* the dollar operator ($)
* the double dollar operator ($$)

Based on surrounding whitespace, these operators are disambiguated into
bang patterns, lazy patterns, strictness annotations, type
applications, splices, and typed splices.

This patch doesn't cover the (-) operator or the -Woperator-whitespace
warning, which are left as future work.
parent 5a08f7d4
......@@ -2308,9 +2308,8 @@ type instance XXSplice (GhcPass _) = NoExtCon
-- type captures explicitly how it was originally written, for use in the pretty
-- printer.
data SpliceDecoration
= HasParens -- ^ $( splice ) or $$( splice )
| HasDollar -- ^ $splice or $$splice
| NoParens -- ^ bare splice
= DollarSplice -- ^ $splice or $$splice
| BareSplice -- ^ bare splice
deriving (Data, Eq, Show)
instance Outputable SpliceDecoration where
......@@ -2452,12 +2451,12 @@ instance (OutputableBndrId p) => Outputable (HsSplice (GhcPass p)) where
pprPendingSplice :: (OutputableBndrId p)
=> SplicePointName -> LHsExpr (GhcPass p) -> SDoc
pprPendingSplice n e = angleBrackets (ppr n <> comma <+> ppr e)
pprPendingSplice n e = angleBrackets (ppr n <> comma <+> ppr (stripParensHsExpr e))
pprSpliceDecl :: (OutputableBndrId p)
=> HsSplice (GhcPass p) -> SpliceExplicitFlag -> SDoc
pprSpliceDecl e@HsQuasiQuote{} _ = pprSplice e
pprSpliceDecl e ExplicitSplice = text "$(" <> ppr_splice_decl e <> text ")"
pprSpliceDecl e ExplicitSplice = text "$" <> ppr_splice_decl e
pprSpliceDecl e ImplicitSplice = ppr_splice_decl e
ppr_splice_decl :: (OutputableBndrId p)
......@@ -2466,17 +2465,13 @@ ppr_splice_decl (HsUntypedSplice _ _ n e) = ppr_splice empty n e empty
ppr_splice_decl e = pprSplice e
pprSplice :: (OutputableBndrId p) => HsSplice (GhcPass p) -> SDoc
pprSplice (HsTypedSplice _ HasParens n e)
= ppr_splice (text "$$(") n e (text ")")
pprSplice (HsTypedSplice _ HasDollar n e)
pprSplice (HsTypedSplice _ DollarSplice n e)
= ppr_splice (text "$$") n e empty
pprSplice (HsTypedSplice _ NoParens n e)
= ppr_splice empty n e empty
pprSplice (HsUntypedSplice _ HasParens n e)
= ppr_splice (text "$(") n e (text ")")
pprSplice (HsUntypedSplice _ HasDollar n e)
pprSplice (HsTypedSplice _ BareSplice _ _ )
= panic "Bare typed splice" -- impossible
pprSplice (HsUntypedSplice _ DollarSplice n e)
= ppr_splice (text "$") n e empty
pprSplice (HsUntypedSplice _ NoParens n e)
pprSplice (HsUntypedSplice _ BareSplice n e)
= ppr_splice empty n e empty
pprSplice (HsQuasiQuote _ n q _ s) = ppr_quasi n q s
pprSplice (HsSpliced _ _ thing) = ppr thing
......
......@@ -4137,7 +4137,8 @@ wWarningFlagsDeps = [
flagSpec "unrecognised-warning-flags" Opt_WarnUnrecognisedWarningFlags,
flagSpec "star-binder" Opt_WarnStarBinder,
flagSpec "star-is-type" Opt_WarnStarIsType,
flagSpec "missing-space-after-bang" Opt_WarnSpaceAfterBang,
depFlagSpec "missing-space-after-bang" Opt_WarnSpaceAfterBang
"bang patterns can no longer be written with a space",
flagSpec "partial-fields" Opt_WarnPartialFields,
flagSpec "prepositive-qualified-module"
Opt_WarnPrepositiveQualifiedModule,
......
......@@ -258,9 +258,9 @@ data AnnKeywordId
| AnnOpenEQ -- ^ '[|'
| AnnOpenEQU -- ^ '[|', unicode variant
| AnnOpenP -- ^ '('
| AnnOpenPE -- ^ '$('
| AnnOpenPTE -- ^ '$$('
| AnnOpenS -- ^ '['
| AnnDollar -- ^ prefix '$' -- TemplateHaskell
| AnnDollarDollar -- ^ prefix '$$' -- TemplateHaskell
| AnnPackageName
| AnnPattern
| AnnProc
......
......@@ -44,6 +44,7 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
{-# OPTIONS_GHC -funbox-strict-fields #-}
......@@ -376,10 +377,6 @@ $tab { warnTab }
"[t|" / { ifExtension ThQuotesBit } { token ITopenTypQuote }
"|]" / { ifExtension ThQuotesBit } { token (ITcloseQuote NormalSyntax) }
"||]" / { ifExtension ThQuotesBit } { token ITcloseTExpQuote }
\$ @varid / { ifExtension ThBit } { skip_one_varid ITidEscape }
"$$" @varid / { ifExtension ThBit } { skip_two_varid ITidTyEscape }
"$(" / { ifExtension ThBit } { token ITparenEscape }
"$$(" / { ifExtension ThBit } { token ITparenTyEscape }
"[" @varid "|" / { ifExtension QqBit } { lex_quasiquote_tok }
......@@ -398,14 +395,6 @@ $tab { warnTab }
{ token (ITcloseQuote UnicodeSyntax) }
}
-- See Note [Lexing type applications]
<0> {
[^ $idchar \) ] ^
"@"
/ { ifExtension TypeApplicationsBit `alexAndPred` notFollowedBySymbol }
{ token ITtypeApp }
}
<0> {
"(|"
/ { ifExtension ArrowsBit `alexAndPred`
......@@ -471,12 +460,20 @@ $tab { warnTab }
@conid "#"+ / { ifExtension MagicHashBit } { idtoken conid }
}
-- Operators classified into prefix, suffix, tight infix, and loose infix.
-- See Note [Whitespace-sensitive operator parsing]
<0> {
@varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix }
@varsym / { followedByOpeningToken } { varsym_prefix }
@varsym / { precededByClosingToken } { varsym_suffix }
@varsym { varsym_loose_infix }
}
-- ToDo: - move `var` and (sym) into lexical syntax?
-- - remove backquote from $special?
<0> {
@qvarsym { idtoken qvarsym }
@qconsym { idtoken qconsym }
@varsym { varsym }
@consym { consym }
}
......@@ -550,32 +547,114 @@ $tab { warnTab }
\" { lex_string_tok }
}
-- Note [Lexing type applications]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- The desired syntax for type applications is to prefix the type application
-- with '@', like this:
-- Note [Whitespace-sensitive operator parsing]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- In accord with GHC Proposal #229 https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst
-- we classify operator occurrences into four categories:
--
-- a ! b -- a loose infix occurrence
-- a!b -- a tight infix occurrence
-- a !b -- a prefix occurrence
-- a! b -- a suffix occurrence
--
-- The rules are a bit more elaborate than simply checking for whitespace, in
-- order to accomodate the following use cases:
--
-- f (!a) = ... -- prefix occurrence
-- g (a !) -- loose infix occurrence
-- g (! a) -- loose infix occurrence
--
-- The precise rules are as follows:
--
-- * Identifiers, literals, and opening brackets (, (#, [, [|, [||, [p|, [e|,
-- [t|, {, are considered "opening tokens". The function followedByOpeningToken
-- tests whether the next token is an opening token.
--
-- * Identifiers, literals, and closing brackets ), #), ], |], },
-- are considered "closing tokens". The function precededByClosingToken tests
-- whether the previous token is a closing token.
--
-- foo @Int @Bool baz bum
-- * Whitespace, comments, separators, and other tokens, are considered
-- neither opening nor closing.
--
-- This, of course, conflicts with as-patterns. The conflict arises because
-- expressions and patterns use the same parser, and also because we want
-- to allow type patterns within expression patterns.
-- * Any unqualified operator occurrence is classified as prefix, suffix, or
-- tight/loose infix, based on preceding and following tokens:
--
-- Disambiguation is accomplished by requiring *something* to appear between
-- type application and the preceding token. This something must end with
-- a character that cannot be the end of the variable bound in an as-pattern.
-- Currently (June 2015), this means that the something cannot end with a
-- $idchar or a close-paren. (The close-paren is necessary if the as-bound
-- identifier is symbolic.)
-- precededByClosingToken | followedByOpeningToken | Occurrence
-- ------------------------+------------------------+------------
-- False | True | prefix
-- True | False | suffix
-- True | True | tight infix
-- False | False | loose infix
-- ------------------------+------------------------+------------
--
-- Note that looking for whitespace before the '@' is insufficient, because
-- of this pathological case:
-- A loose infix occurrence is always considered an operator. Other types of
-- occurrences may be assigned a special per-operator meaning override:
--
-- foo {- hi -}@Int
-- Operator | Occurrence | Token returned
-- ----------+---------------+------------------------------------------
-- ! | prefix | ITbang
-- | | strictness annotation or bang pattern,
-- | | e.g. f !x = rhs, data T = MkT !a
-- | not prefix | ITvarsym "!"
-- | | ordinary operator or type operator,
-- | | e.g. xs ! 3, (! x), Int ! Bool
-- ----------+---------------+------------------------------------------
-- ~ | prefix | ITtilde
-- | | laziness annotation or lazy pattern,
-- | | e.g. f ~x = rhs, data T = MkT ~a
-- | not prefix | ITvarsym "~"
-- | | ordinary operator or type operator,
-- | | e.g. xs ~ 3, (~ x), Int ~ Bool
-- ----------+---------------+------------------------------------------
-- $ $$ | prefix | ITdollar, ITdollardollar
-- | | untyped or typed Template Haskell splice,
-- | | e.g. $(f x), $$(f x), $$"str"
-- | not prefix | ITvarsym "$", ITvarsym "$$"
-- | | ordinary operator or type operator,
-- | | e.g. f $ g x, a $$ b
-- ----------+---------------+------------------------------------------
-- @ | prefix | ITtypeApp
-- | | type application, e.g. fmap @Maybe
-- | tight infix | ITat
-- | | as-pattern, e.g. f p@(a,b) = rhs
-- | suffix | parse error
-- | | e.g. f p@ x = rhs
-- | loose infix | ITvarsym "@"
-- | | ordinary operator or type operator,
-- | | e.g. f @ g, (f @)
-- ----------+---------------+------------------------------------------
--
-- This design is predicated on the fact that as-patterns are generally
-- whitespace-free, and also that this whole thing is opt-in, with the
-- TypeApplications extension.
-- Also, some of these overrides are guarded behind language extensions.
-- According to the specification, we must determine the occurrence based on
-- surrounding *tokens* (see the proposal for the exact rules). However, in
-- the implementation we cheat a little and do the classification based on
-- characters, for reasons of both simplicity and efficiency (see
-- 'followedByOpeningToken' and 'precededByClosingToken')
--
-- When an operator is subject to a meaning override, it is mapped to special
-- token: ITbang, ITtilde, ITat, ITdollar, ITdollardollar. Otherwise, it is
-- returned as ITvarsym.
--
-- For example, this is how we process the (!):
--
-- precededByClosingToken | followedByOpeningToken | Token
-- ------------------------+------------------------+-------------
-- False | True | ITbang
-- True | False | ITvarsym "!"
-- True | True | ITvarsym "!"
-- False | False | ITvarsym "!"
-- ------------------------+------------------------+-------------
--
-- And this is how we process the (@):
--
-- precededByClosingToken | followedByOpeningToken | Token
-- ------------------------+------------------------+-------------
-- False | True | ITtypeApp
-- True | False | parse error
-- True | True | ITat
-- False | False | ITvarsym "@"
-- ------------------------+------------------------+-------------
-- -----------------------------------------------------------------------------
-- Alex "Haskell code fragment bottom"
......@@ -680,11 +759,12 @@ data Token
| ITvbar
| ITlarrow IsUnicodeSyntax
| ITrarrow IsUnicodeSyntax
| ITat
| ITtilde
| ITdarrow IsUnicodeSyntax
| ITminus
| ITbang
| ITbang -- Prefix (!) only, e.g. f !x = rhs
| ITtilde -- Prefix (~) only, e.g. f ~x = rhs
| ITat -- Tight infix (@) only, e.g. f x@pat = rhs
| ITtypeApp -- Prefix (@) only, e.g. f @t
| ITstar IsUnicodeSyntax
| ITdot
......@@ -740,10 +820,8 @@ data Token
| ITcloseQuote IsUnicodeSyntax -- |]
| ITopenTExpQuote HasE -- [|| or [e||
| ITcloseTExpQuote -- ||]
| ITidEscape FastString -- $x
| ITparenEscape -- $(
| ITidTyEscape FastString -- $$x
| ITparenTyEscape -- $$(
| ITdollar -- prefix $
| ITdollardollar -- prefix $$
| ITtyQuote -- ''
| ITquasiQuote (FastString,FastString,RealSrcSpan)
-- ITquasiQuote(quoter, quote, loc)
......@@ -764,11 +842,6 @@ data Token
| ITLarrowtail IsUnicodeSyntax -- ^ @-<<@
| ITRarrowtail IsUnicodeSyntax -- ^ @>>-@
-- | Type application '@' (lexed differently than as-pattern '@',
-- due to checking for preceding whitespace)
| ITtypeApp
| ITunknown String -- ^ Used when the lexer can't make sense of it
| ITeof -- ^ end of file token
......@@ -889,11 +962,8 @@ reservedSymsFM = listToUFM $
,("|", ITvbar, NormalSyntax, 0 )
,("<-", ITlarrow NormalSyntax, NormalSyntax, 0 )
,("->", ITrarrow NormalSyntax, NormalSyntax, 0 )
,("@", ITat, NormalSyntax, 0 )
,("~", ITtilde, NormalSyntax, 0 )
,("=>", ITdarrow NormalSyntax, NormalSyntax, 0 )
,("-", ITminus, NormalSyntax, 0 )
,("!", ITbang, NormalSyntax, 0 )
,("*", ITstar NormalSyntax, NormalSyntax, xbit StarIsTypeBit)
......@@ -988,6 +1058,32 @@ pop_and :: Action -> Action
pop_and act span buf len = do _ <- popLexState
act span buf len
-- See Note [Whitespace-sensitive operator parsing]
followedByOpeningToken :: AlexAccPred ExtsBitmap
followedByOpeningToken _ _ _ (AI _ buf)
| atEnd buf = False
| otherwise =
case nextChar buf of
('{', buf') -> nextCharIsNot buf' (== '-')
('(', _) -> True
('[', _) -> True
('\"', _) -> True
('\'', _) -> True
('_', _) -> True
(c, _) -> isAlphaNum c
-- See Note [Whitespace-sensitive operator parsing]
precededByClosingToken :: AlexAccPred ExtsBitmap
precededByClosingToken _ (AI _ buf) _ _ =
case prevChar buf '\n' of
'}' -> decodePrevNChars 1 buf /= "-"
')' -> True
']' -> True
'\"' -> True
'\'' -> True
'_' -> True
c -> isAlphaNum c
{-# INLINE nextCharIs #-}
nextCharIs :: StringBuffer -> (Char -> Bool) -> Bool
nextCharIs buf p = not (atEnd buf) && p (currentChar buf)
......@@ -1348,11 +1444,40 @@ qvarsym, qconsym :: StringBuffer -> Int -> Token
qvarsym buf len = ITqvarsym $! splitQualName buf len False
qconsym buf len = ITqconsym $! splitQualName buf len False
varsym, consym :: Action
varsym = sym ITvarsym
consym = sym ITconsym
sym :: (FastString -> Token) -> Action
-- See Note [Whitespace-sensitive operator parsing]
varsym_prefix :: Action
varsym_prefix = sym $ \exts s ->
if | TypeApplicationsBit `xtest` exts, s == fsLit "@"
-> return ITtypeApp
| ThBit `xtest` exts, s == fsLit "$"
-> return ITdollar
| ThBit `xtest` exts, s == fsLit "$$"
-> return ITdollardollar
| s == fsLit "!" -> return ITbang
| s == fsLit "~" -> return ITtilde
| otherwise -> return (ITvarsym s)
-- See Note [Whitespace-sensitive operator parsing]
varsym_suffix :: Action
varsym_suffix = sym $ \_ s ->
if | s == fsLit "@"
-> failMsgP "Suffix occurrence of @. For an as-pattern, remove the leading whitespace."
| otherwise -> return (ITvarsym s)
-- See Note [Whitespace-sensitive operator parsing]
varsym_tight_infix :: Action
varsym_tight_infix = sym $ \_ s ->
if | s == fsLit "@" -> return ITat
| otherwise -> return (ITvarsym s)
-- See Note [Whitespace-sensitive operator parsing]
varsym_loose_infix :: Action
varsym_loose_infix = sym (\_ s -> return $ ITvarsym s)
consym :: Action
consym = sym (\_exts s -> return $ ITconsym s)
sym :: (ExtsBitmap -> FastString -> P Token) -> Action
sym con span buf len =
case lookupUFM reservedSymsFM fs of
Just (keyword, NormalSyntax, 0) ->
......@@ -1361,19 +1486,20 @@ sym con span buf len =
exts <- getExts
if exts .&. i /= 0
then return $ L span keyword
else return $ L span (con fs)
else L span <$!> con exts fs
Just (keyword, UnicodeSyntax, 0) -> do
exts <- getExts
if xtest UnicodeSyntaxBit exts
then return $ L span keyword
else return $ L span (con fs)
else L span <$!> con exts fs
Just (keyword, UnicodeSyntax, i) -> do
exts <- getExts
if exts .&. i /= 0 && xtest UnicodeSyntaxBit exts
then return $ L span keyword
else return $ L span (con fs)
Nothing ->
return $ L span $! con fs
else L span <$!> con exts fs
Nothing -> do
exts <- getExts
L span <$!> con exts fs
where
!fs = lexemeToFastString buf len
......@@ -2889,8 +3015,6 @@ isALRopen ITobrack = True
isALRopen ITocurly = True
-- GHC Extensions:
isALRopen IToubxparen = True
isALRopen ITparenEscape = True
isALRopen ITparenTyEscape = True
isALRopen _ = False
isALRclose :: Token -> Bool
......@@ -2945,12 +3069,9 @@ lexToken = do
let bytes = byteDiff buf buf2
span `seq` setLastToken span bytes
lt <- t span buf bytes
case unRealSrcSpan lt of
ITlineComment _ -> return lt
ITblockComment _ -> return lt
lt' -> do
setLastTk lt'
return lt
let lt' = unRealSrcSpan lt
unless (isComment lt') (setLastTk lt')
return lt
reportLexError :: RealSrcLoc -> RealSrcLoc -> StringBuffer -> [Char] -> P a
reportLexError loc1 loc2 buf str
......
......@@ -93,7 +93,7 @@ import Util ( looksLikePackageName, fstOf3, sndOf3, thdOf3 )
import GhcPrelude
}
%expect 236 -- shift/reduce conflicts
%expect 232 -- shift/reduce conflicts
{- Last updated: 04 June 2018
......@@ -541,18 +541,18 @@ are the most common patterns, rewritten as regular expressions for clarity:
'|' { L _ ITvbar }
'<-' { L _ (ITlarrow _) }
'->' { L _ (ITrarrow _) }
'@' { L _ ITat }
'~' { L _ ITtilde }
TIGHT_INFIX_AT { L _ ITat }
'=>' { L _ (ITdarrow _) }
'-' { L _ ITminus }
'!' { L _ ITbang }
PREFIX_TILDE { L _ ITtilde }
PREFIX_BANG { L _ ITbang }
'*' { L _ (ITstar _) }
'-<' { L _ (ITlarrowtail _) } -- for arrow notation
'>-' { L _ (ITrarrowtail _) } -- for arrow notation
'-<<' { L _ (ITLarrowtail _) } -- for arrow notation
'>>-' { L _ (ITRarrowtail _) } -- for arrow notation
'.' { L _ ITdot }
TYPEAPP { L _ ITtypeApp }
PREFIX_AT { L _ ITtypeApp }
'{' { L _ ITocurly } -- special symbols
'}' { L _ ITccurly }
......@@ -610,10 +610,8 @@ are the most common patterns, rewritten as regular expressions for clarity:
'|]' { L _ (ITcloseQuote _) }
'[||' { L _ (ITopenTExpQuote _) }
'||]' { L _ ITcloseTExpQuote }
TH_ID_SPLICE { L _ (ITidEscape _) } -- $x
'$(' { L _ ITparenEscape } -- $( exp )
TH_ID_TY_SPLICE { L _ (ITidTyEscape _) } -- $$x
'$$(' { L _ ITparenTyEscape } -- $$( exp )
PREFIX_DOLLAR { L _ ITdollar }
PREFIX_DOLLAR_DOLLAR { L _ ITdollardollar }
TH_TY_QUOTE { L _ ITtyQuote } -- ''T
TH_QUASIQUOTE { L _ (ITquasiQuote _) }
TH_QQUASIQUOTE { L _ (ITqQuasiQuote _) }
......@@ -647,8 +645,6 @@ identifier :: { Located RdrName }
| qconop { $1 }
| '(' '->' ')' {% ams (sLL $1 $> $ getRdrName funTyCon)
[mop $1,mu AnnRarrow $2,mcp $3] }
| '(' '~' ')' {% ams (sLL $1 $> $ eqTyCon_RDR)
[mop $1,mj AnnTilde $2,mcp $3] }
-----------------------------------------------------------------------------
-- Backpack stuff
......@@ -1681,13 +1677,30 @@ rule_activation :: { ([AddAnn],Maybe Activation) }
: {- empty -} { ([],Nothing) }
| rule_explicit_activation { (fst $1,Just (snd $1)) }
-- This production is used to parse the tilde syntax in pragmas such as
-- * {-# INLINE[~2] ... #-}
-- * {-# SPECIALISE [~ 001] ... #-}
-- * {-# RULES ... [~0] ... g #-}
-- Note that it can be written either
-- without a space [~1] (the PREFIX_TILDE case), or
-- with a space [~ 1] (the VARSYM case).
-- See Note [Whitespace-sensitive operator parsing] in Lexer.x
rule_activation_marker :: { [AddAnn] }
: PREFIX_TILDE { [mj AnnTilde $1] }
| VARSYM {% if (getVARSYM $1 == fsLit "~")
then return [mj AnnTilde $1]
else do { addError (getLoc $1) $ text "Invalid rule activation marker"
; return [] } }
rule_explicit_activation :: { ([AddAnn]
,Activation) } -- In brackets
: '[' INTEGER ']' { ([mos $1,mj AnnVal $2,mcs $3]
,ActiveAfter (getINTEGERs $2) (fromInteger (il_value (getINTEGER $2)))) }
| '[' '~' INTEGER ']' { ([mos $1,mj AnnTilde $2,mj AnnVal $3,mcs $4]
| '[' rule_activation_marker INTEGER ']'
{ ($2++[mos $1,mj AnnVal $3,mcs $4]
,ActiveBefore (getINTEGERs $3) (fromInteger (il_value (getINTEGER $3)))) }
| '[' '~' ']' { ([mos $1,mj AnnTilde $2,mcs $3]
| '[' rule_activation_marker ']'
{ ($2++[mos $1,mcs $3]
,NeverActive) }
rule_foralls :: { ([AddAnn], Maybe [LHsTyVarBndr GhcPs], [LRuleBndr GhcPs]) }
......@@ -2026,10 +2039,11 @@ tyapps :: { [Located TyEl] } -- NB: This list is reversed
tyapp :: { Located TyEl }
: atype { sL1 $1 $ TyElOpd (unLoc $1) }
| TYPEAPP atype { sLL $1 $> $ (TyElKindApp (comb2 $1 $2) $2) }
| qtyconop { sL1 $1 $ if isBangRdr (unLoc $1) then TyElBang else
if isTildeRdr (unLoc $1) then TyElTilde else
TyElOpr (unLoc $1) }
-- See Note [Whitespace-sensitive operator parsing] in Lexer.x
| PREFIX_AT atype { sLL $1 $> $ (TyElKindApp (comb2 $1 $2) $2) }
| qtyconop { sL1 $1 $ TyElOpr (unLoc $1) }
| tyvarop { sL1 $1 $ TyElOpr (unLoc $1) }
| SIMPLEQUOTE qconop {% ams (sLL $1 $> $ TyElOpr (unLoc $2))
[mj AnnSimpleQuote $1,mj AnnVal $2] }
......@@ -2042,6 +2056,11 @@ atype :: { LHsType GhcPs }
| tyvar { sL1 $1 (HsTyVar noExtField NotPromoted $1) } -- (See Note [Unit tuples])
| '*' {% do { warnStarIsType (getLoc $1)
; return $ sL1 $1 (HsStarTy noExtField (isUnicode $1)) } }
-- See Note [Whitespace-sensitive operator parsing] in Lexer.x
| PREFIX_TILDE atype {% ams (sLL $1 $> (mkBangTy SrcLazy $2)) [mj AnnTilde $1] }
| PREFIX_BANG atype {% ams (sLL $1 $> (mkBangTy SrcStrict $2)) [mj AnnBang $1] }
| '{' fielddecls '}' {% amms (checkRecordSyntax
(sLL $1 $> $ HsRecTy noExtField $2))
-- Constructor sigs only
......@@ -2411,25 +2430,8 @@ docdecld :: { LDocDecl }
decl_no_th :: { LHsDecl GhcPs }
: sigdecl { $1 }
| '!' aexp rhs {% runECP_P $2 >>= \ $2 ->
do { let { e = patBuilderBang (getLoc $1) $2
; l = comb2 $1 $> };
(ann, r) <- checkValDef SrcStrict e Nothing $3 ;
runPV $ hintBangPat (comb2 $1 $2) (unLoc e) ;
-- Depending upon what the pattern looks like we might get either
-- a FunBind or PatBind back from checkValDef. See Note
-- [FunBind vs PatBind]
case r of {
(FunBind _ n _ _ _) ->
amsL l [mj AnnFunId n] >> return () ;
(PatBind _ (dL->L l _) _rhs _) ->
amsL l [] >> return () } ;
_ <- amsL l (ann ++ fst (unLoc $3) ++ [mj AnnBang $1]) ;
return $! (sL l $ ValD noExtField r) } }
| infixexp_top opt_sig rhs {% runECP_P $1 >>= \ $1 ->
do { (ann,r) <- checkValDef NoSrcStrict $1 (snd $2) $3;
do { (ann,r) <- checkValDef $1 (snd $2) $3;
let { l = comb2 $1 $> };
-- Depending upon what the pattern looks like we might get either
-- a FunBind or PatBind back from checkValDef. See Note
......@@ -2551,8 +2553,8 @@ activation :: { ([AddAnn],Maybe Activation) }
explicit_activation :: { ([AddAnn],Activation) } -- In brackets
: '[' INTEGER ']' { ([mj AnnOpenS $1,mj AnnVal $2,mj AnnCloseS $3]
,ActiveAfter (getINTEGERs $2) (fromInteger (il_value (getINTEGER $2)))) }
| '[' '~' INTEGER ']' { ([mj AnnOpenS $1,mj AnnTilde $2,mj AnnVal $3
,mj AnnCloseS $4]
| '[' rule_activation_marker INTEGER ']'
{ ($2++[mj AnnOpenS $1,mj AnnVal $3,mj AnnCloseS $4]
,ActiveBefore (getINTEGERs $3) (fromInteger (il_value (getINTEGER $3)))) }
-----------------------------------------------------------------------------
......@@ -2694,11 +2696,14 @@ fexp :: { ECP }
runECP_PV $1 >>= \ $1 ->
runECP_PV $2 >>= \ $2 ->