X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Fparser%2FParser.y.pp;h=5fbbcad4549d65c296dfb1d9c489c58beb3286c2;hp=515c4744224e22b0215f97b9531137730b95c56d;hb=4bc25e8c30559b7a6a87b39afcc79340ae778788;hpb=bf1cff988c19adb2937294e41f6d0a0f41f1168d diff --git a/compiler/parser/Parser.y.pp b/compiler/parser/Parser.y.pp index 515c474..5fbbcad 100644 --- a/compiler/parser/Parser.y.pp +++ b/compiler/parser/Parser.y.pp @@ -15,15 +15,20 @@ -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings -- for details +{-# OPTIONS_GHC -O0 -fno-ignore-interface-pragmas #-} +{- +Careful optimisation of the parser: we don't want to throw everything +at it, because that takes too long and doesn't buy much, but we do want +to inline certain key external functions, so we instruct GHC not to +throw away inlinings as it would normally do in -O0 mode. +-} + module Parser ( parseModule, parseStmt, parseIdentifier, parseType, parseHeader ) where -#define INCLUDE #include -INCLUDE "HsVersions.h" - import HsSyn import RdrHsSyn -import HscTypes ( IsBootInterface, DeprecTxt ) +import HscTypes ( IsBootInterface, WarningTxt(..) ) import Lexer import RdrName import TysWiredIn ( unitTyCon, unitDataCon, tupleTyCon, tupleCon, nilDataCon, @@ -42,7 +47,7 @@ import Module import StaticFlags ( opt_SccProfilingOn, opt_Hpc ) import Type ( Kind, mkArrowKind, liftedTypeKind, unliftedTypeKind ) import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..), - Activation(..), defaultInlineSpec ) + Activation(..), RuleMatchInfo(..), defaultInlineSpec ) import DynFlags import OrdList import HaddockParse @@ -249,6 +254,7 @@ incorrect. 'using' { L _ ITusing } -- for list transform extension '{-# INLINE' { L _ (ITinline_prag _) } + '{-# INLINE_CONLIKE' { L _ (ITinline_conlike_prag _) } '{-# SPECIALISE' { L _ ITspec_prag } '{-# SPECIALISE_INLINE' { L _ (ITspec_inline_prag _) } '{-# SOURCE' { L _ ITsource_prag } @@ -257,7 +263,9 @@ incorrect. '{-# SCC' { L _ ITscc_prag } '{-# GENERATED' { L _ ITgenerated_prag } '{-# DEPRECATED' { L _ ITdeprecated_prag } + '{-# WARNING' { L _ ITwarning_prag } '{-# UNPACK' { L _ ITunpack_prag } + '{-# ANN' { L _ ITann_prag } '#-}' { L _ ITclose_prag } '..' { L _ ITdotdot } -- reserved symbols @@ -308,6 +316,8 @@ incorrect. QCONID { L _ (ITqconid _) } QVARSYM { L _ (ITqvarsym _) } QCONSYM { L _ (ITqconsym _) } + PREFIXQVARSYM { L _ (ITprefixqvarsym _) } + PREFIXQCONSYM { L _ (ITprefixqconsym _) } IPDUPVARID { L _ (ITdupipvarid _) } -- GHC extension @@ -319,6 +329,7 @@ incorrect. PRIMCHAR { L _ (ITprimchar _) } PRIMSTRING { L _ (ITprimstring _) } PRIMINTEGER { L _ (ITprimint _) } + PRIMWORD { L _ (ITprimword _) } PRIMFLOAT { L _ (ITprimfloat _) } PRIMDOUBLE { L _ (ITprimdouble _) } @@ -369,7 +380,7 @@ identifier :: { Located RdrName } -- know what they are doing. :-) module :: { Located (HsModule RdrName) } - : maybedocheader 'module' modid maybemoddeprec maybeexports 'where' body + : maybedocheader 'module' modid maybemodwarning maybeexports 'where' body {% fileSrcSpan >>= \ loc -> case $1 of { (info, doc) -> return (L loc (HsModule (Just $3) $5 (fst $7) (snd $7) $4 info doc) )}} @@ -380,15 +391,16 @@ module :: { Located (HsModule RdrName) } Nothing)) } maybedocheader :: { (HaddockModInfo RdrName, Maybe (HsDoc RdrName)) } - : moduleheader { (fst $1, snd $1) } + : moduleheader { $1 } | {- empty -} { (emptyHaddockModInfo, Nothing) } missing_module_keyword :: { () } : {- empty -} {% pushCurrentContext } -maybemoddeprec :: { Maybe DeprecTxt } - : '{-# DEPRECATED' STRING '#-}' { Just (getSTRING $2) } - | {- empty -} { Nothing } +maybemodwarning :: { Maybe WarningTxt } + : '{-# DEPRECATED' STRING '#-}' { Just (DeprecatedTxt (getSTRING $2)) } + | '{-# WARNING' STRING '#-}' { Just (WarningTxt (getSTRING $2)) } + | {- empty -} { Nothing } body :: { ([LImportDecl RdrName], [LHsDecl RdrName]) } : '{' top '}' { $2 } @@ -410,7 +422,7 @@ cvtopdecls :: { [LHsDecl RdrName] } -- Module declaration & imports only header :: { Located (HsModule RdrName) } - : maybedocheader 'module' modid maybemoddeprec maybeexports 'where' header_body + : maybedocheader 'module' modid maybemodwarning maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> case $1 of { (info, doc) -> return (L loc (HsModule (Just $3) $5 $7 [] $4 info doc))}} @@ -487,13 +499,17 @@ importdecls :: { [LImportDecl RdrName] } | {- empty -} { [] } importdecl :: { LImportDecl RdrName } - : 'import' maybe_src optqualified modid maybeas maybeimpspec - { L (comb4 $1 $4 $5 $6) (ImportDecl $4 $2 $3 (unLoc $5) (unLoc $6)) } + : 'import' maybe_src optqualified maybe_pkg modid maybeas maybeimpspec + { L (comb4 $1 $5 $6 $7) (ImportDecl $5 $4 $2 $3 (unLoc $6) (unLoc $7)) } maybe_src :: { IsBootInterface } : '{-# SOURCE' '#-}' { True } | {- empty -} { False } +maybe_pkg :: { Maybe FastString } + : STRING { Just (getSTRING $1) } + | {- empty -} { Nothing } + optqualified :: { Bool } : 'qualified' { True } | {- empty -} { False } @@ -544,8 +560,10 @@ topdecl :: { OrdList (LHsDecl RdrName) } | stand_alone_deriving { unitOL (LL (DerivD (unLoc $1))) } | 'default' '(' comma_types0 ')' { unitOL (LL $ DefD (DefaultDecl $3)) } | 'foreign' fdecl { unitOL (LL (unLoc $2)) } - | '{-# DEPRECATED' deprecations '#-}' { $2 } + | '{-# DEPRECATED' deprecations '#-}' { $2 } + | '{-# WARNING' warnings '#-}' { $2 } | '{-# RULES' rules '#-}' { $2 } + | annotation { unitOL $1 } | decl { unLoc $1 } -- Template Haskell Extension @@ -608,8 +626,8 @@ ty_decl :: { LTyClDecl RdrName } | data_or_newtype tycl_hdr constrs deriving {% do { let {(ctxt, tc, tvs, tparms) = unLoc $2} ; checkTyVars tparms -- no type pattern - ; return $ - L (comb4 $1 $2 $3 $4) + ; return $! + sL (comb4 $1 $2 $3 $4) -- We need the location on tycl_hdr in case -- constrs and deriving are both empty (mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing) @@ -621,8 +639,8 @@ ty_decl :: { LTyClDecl RdrName } deriving {% do { let {(ctxt, tc, tvs, tparms) = unLoc $2} ; checkTyVars tparms -- can have type pats - ; return $ - L (comb4 $1 $2 $4 $5) + ; return $! + sL (comb4 $1 $2 $4 $5) (mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing) (unLoc $3) (reverse (unLoc $5)) (unLoc $6)) } } @@ -822,7 +840,11 @@ where_inst :: { Located (OrdList (LHsDecl RdrName)) } -- Reversed -- Declarations in binding groups other than classes and instances -- decls :: { Located (OrdList (LHsDecl RdrName)) } - : decls ';' decl { LL (unLoc $1 `appOL` unLoc $3) } + : decls ';' decl { let { this = unLoc $3; + rest = unLoc $1; + these = rest `appOL` this } + in rest `seq` this `seq` these `seq` + LL these } | decls ';' { LL (unLoc $1) } | decl { $1 } | {- empty -} { noLoc nilOL } @@ -881,7 +903,19 @@ rule_var :: { RuleBndr RdrName } | '(' varid '::' ctype ')' { RuleBndrSig $2 $4 } ----------------------------------------------------------------------------- --- Deprecations (c.f. rules) +-- Warnings and deprecations (c.f. rules) + +warnings :: { OrdList (LHsDecl RdrName) } + : warnings ';' warning { $1 `appOL` $3 } + | warnings ';' { $1 } + | warning { $1 } + | {- empty -} { nilOL } + +-- SUP: TEMPORARY HACK, not checking for `module Foo' +warning :: { OrdList (LHsDecl RdrName) } + : namelist STRING + { toOL [ LL $ WarningD (Warning n (WarningTxt (getSTRING $2))) + | n <- unLoc $1 ] } deprecations :: { OrdList (LHsDecl RdrName) } : deprecations ';' deprecation { $1 `appOL` $3 } @@ -891,10 +925,17 @@ deprecations :: { OrdList (LHsDecl RdrName) } -- SUP: TEMPORARY HACK, not checking for `module Foo' deprecation :: { OrdList (LHsDecl RdrName) } - : depreclist STRING - { toOL [ LL $ DeprecD (Deprecation n (getSTRING $2)) + : namelist STRING + { toOL [ LL $ WarningD (Warning n (DeprecatedTxt (getSTRING $2))) | n <- unLoc $1 ] } +----------------------------------------------------------------------------- +-- Annotations +annotation :: { LHsDecl RdrName } + : '{-# ANN' name_var aexp '#-}' { LL (AnnD $ HsAnnotation (ValueAnnProvenance (unLoc $2)) $3) } + | '{-# ANN' 'type' tycon aexp '#-}' { LL (AnnD $ HsAnnotation (TypeAnnProvenance (unLoc $3)) $4) } + | '{-# ANN' 'module' aexp '#-}' { LL (AnnD $ HsAnnotation ModuleAnnProvenance $3) } + ----------------------------------------------------------------------------- -- Foreign import and export declarations @@ -1227,7 +1268,7 @@ decl :: { Located (OrdList (LHsDecl RdrName)) } | docdecl { LL $ unitOL $1 } rhs :: { Located (GRHSs RdrName) } - : '=' exp wherebinds { L (comb3 $1 $2 $3) $ GRHSs (unguardedRHS $2) (unLoc $3) } + : '=' exp wherebinds { sL (comb3 $1 $2 $3) $ GRHSs (unguardedRHS $2) (unLoc $3) } | gdrhs wherebinds { LL $ GRHSs (reverse (unLoc $1)) (unLoc $2) } gdrhs :: { Located [LGRHS RdrName] } @@ -1247,12 +1288,14 @@ sigdecl :: { Located (OrdList (LHsDecl RdrName)) } | infix prec ops { LL $ toOL [ LL $ SigD (FixSig (FixitySig n (Fixity $2 (unLoc $1)))) | n <- unLoc $3 ] } | '{-# INLINE' activation qvar '#-}' - { LL $ unitOL (LL $ SigD (InlineSig $3 (mkInlineSpec $2 (getINLINE $1)))) } + { LL $ unitOL (LL $ SigD (InlineSig $3 (mkInlineSpec $2 FunLike (getINLINE $1)))) } + | '{-# INLINE_CONLIKE' activation qvar '#-}' + { LL $ unitOL (LL $ SigD (InlineSig $3 (mkInlineSpec $2 ConLike (getINLINE_CONLIKE $1)))) } | '{-# SPECIALISE' qvar '::' sigtypes1 '#-}' { LL $ toOL [ LL $ SigD (SpecSig $2 t defaultInlineSpec) | t <- $4] } | '{-# SPECIALISE_INLINE' activation qvar '::' sigtypes1 '#-}' - { LL $ toOL [ LL $ SigD (SpecSig $3 t (mkInlineSpec $2 (getSPEC_INLINE $1))) + { LL $ toOL [ LL $ SigD (SpecSig $3 t (mkInlineSpec $2 FunLike (getSPEC_INLINE $1))) | t <- $5] } | '{-# SPECIALISE' 'instance' inst_type '#-}' { LL $ unitOL (LL $ SigD (SpecInstSig $3)) } @@ -1306,9 +1349,9 @@ exp10 :: { LHsExpr RdrName } | fexp { $1 } scc_annot :: { Located FastString } - : '_scc_' STRING {% (addWarning Opt_WarnDeprecations (getLoc $1) (text "_scc_ is deprecated; use an SCC pragma instead")) >>= \_ -> - (return $ LL $ getSTRING $2) } - | '{-# SCC' STRING '#-}' { LL $ getSTRING $2 } + : '_scc_' STRING {% (addWarning Opt_WarnWarningsDeprecations (getLoc $1) (text "_scc_ is deprecated; use an SCC pragma instead")) >>= \_ -> + ( do scc <- getSCC $2; return $ LL scc ) } + | '{-# SCC' STRING '#-}' {% do scc <- getSCC $2; return $ LL scc } hpc_annot :: { Located (FastString,(Int,Int),(Int,Int)) } : '{-# GENERATED' STRING INTEGER ':' INTEGER '-' INTEGER ':' INTEGER '#-}' @@ -1404,16 +1447,27 @@ cvtopdecls0 :: { [LHsDecl RdrName] } : {- empty -} { [] } | cvtopdecls { $1 } --- tuple expressions: things that can appear unparenthesized as long as they're +-- "texp" is short for tuple expressions: +-- things that can appear unparenthesized as long as they're -- inside parens or delimitted by commas texp :: { LHsExpr RdrName } : exp { $1 } - -- Technically, this should only be used for bang patterns, - -- but we can be a little more liberal here and avoid parens - -- inside tuples - | infixexp qop { LL $ SectionL $1 $2 } + + -- Note [Parsing sections] + -- ~~~~~~~~~~~~~~~~~~~~~~~ + -- We include left and right sections here, which isn't + -- technically right according to Haskell 98. For example + -- (3 +, True) isn't legal + -- However, we want to parse bang patterns like + -- (!x, !y) + -- and it's convenient to do so here as a section + -- Then when converting expr to pattern we unravel it again + -- Meanwhile, the renamer checks that real sections appear + -- inside parens. + | infixexp qop { LL $ SectionL $1 $2 } | qopm infixexp { LL $ SectionR $1 $2 } - -- view patterns get parenthesized above + + -- View patterns get parenthesized above | exp '->' exp { LL $ EViewPat $1 $3 } texps :: { [LHsExpr RdrName] } @@ -1437,7 +1491,7 @@ list :: { LHsExpr RdrName } | texp '|' flattenedpquals { sL (comb2 $1 $>) $ mkHsDo ListComp (unLoc $3) $1 } lexps :: { Located [LHsExpr RdrName] } - : lexps ',' texp { LL ($3 : unLoc $1) } + : lexps ',' texp { LL (((:) $! $3) $! unLoc $1) } | texp ',' texp { LL [$3,$1] } ----------------------------------------------------------------------------- @@ -1625,9 +1679,10 @@ fbind :: { HsRecField RdrName (LHsExpr RdrName) } -- Implicit Parameter Bindings dbinds :: { Located [LIPBind RdrName] } - : dbinds ';' dbind { LL ($3 : unLoc $1) } + : dbinds ';' dbind { let { this = $3; rest = unLoc $1 } + in rest `seq` this `seq` LL (this : rest) } | dbinds ';' { LL (unLoc $1) } - | dbind { L1 [$1] } + | dbind { let this = $1 in this `seq` L1 [this] } -- | {- empty -} { [] } dbind :: { LIPBind RdrName } @@ -1637,15 +1692,15 @@ ipvar :: { Located (IPName RdrName) } : IPDUPVARID { L1 (IPName (mkUnqual varName (getIPDUPVARID $1))) } ----------------------------------------------------------------------------- --- Deprecations +-- Warnings and deprecations -depreclist :: { Located [RdrName] } -depreclist : deprec_var { L1 [unLoc $1] } - | deprec_var ',' depreclist { LL (unLoc $1 : unLoc $3) } +namelist :: { Located [RdrName] } +namelist : name_var { L1 [unLoc $1] } + | name_var ',' namelist { LL (unLoc $1 : unLoc $3) } -deprec_var :: { Located RdrName } -deprec_var : var { $1 } - | con { $1 } +name_var :: { Located RdrName } +name_var : var { $1 } + | con { $1 } ----------------------------------------- -- Data constructors @@ -1698,6 +1753,7 @@ qtyconop :: { Located RdrName } -- Qualified or unqualified qtycon :: { Located RdrName } -- Qualified or unqualified : QCONID { L1 $! mkQual tcClsName (getQCONID $1) } + | PREFIXQCONSYM { L1 $! mkQual tcClsName (getPREFIXQCONSYM $1) } | tycon { $1 } tycon :: { Located RdrName } -- Unqualified @@ -1751,9 +1807,9 @@ tyvarop : '`' tyvarid '`' { LL (unLoc $2) } tyvarid :: { Located RdrName } : VARID { L1 $! mkUnqual tvName (getVARID $1) } | special_id { L1 $! mkUnqual tvName (unLoc $1) } - | 'unsafe' { L1 $! mkUnqual tvName FSLIT("unsafe") } - | 'safe' { L1 $! mkUnqual tvName FSLIT("safe") } - | 'threadsafe' { L1 $! mkUnqual tvName FSLIT("threadsafe") } + | 'unsafe' { L1 $! mkUnqual tvName (fsLit "unsafe") } + | 'safe' { L1 $! mkUnqual tvName (fsLit "safe") } + | 'threadsafe' { L1 $! mkUnqual tvName (fsLit "threadsafe") } tyvarsym :: { Located RdrName } -- Does not include "!", because that is used for strictness marks @@ -1778,19 +1834,17 @@ qvar :: { Located RdrName } qvarid :: { Located RdrName } : varid { $1 } - | QVARID { L1 $ mkQual varName (getQVARID $1) } + | QVARID { L1 $! mkQual varName (getQVARID $1) } + | PREFIXQVARSYM { L1 $! mkQual varName (getPREFIXQVARSYM $1) } varid :: { Located RdrName } - : varid_no_unsafe { $1 } - | 'unsafe' { L1 $! mkUnqual varName FSLIT("unsafe") } - | 'safe' { L1 $! mkUnqual varName FSLIT("safe") } - | 'threadsafe' { L1 $! mkUnqual varName FSLIT("threadsafe") } - -varid_no_unsafe :: { Located RdrName } : VARID { L1 $! mkUnqual varName (getVARID $1) } | special_id { L1 $! mkUnqual varName (unLoc $1) } - | 'forall' { L1 $! mkUnqual varName FSLIT("forall") } - | 'family' { L1 $! mkUnqual varName FSLIT("family") } + | 'unsafe' { L1 $! mkUnqual varName (fsLit "unsafe") } + | 'safe' { L1 $! mkUnqual varName (fsLit "safe") } + | 'threadsafe' { L1 $! mkUnqual varName (fsLit "threadsafe") } + | 'forall' { L1 $! mkUnqual varName (fsLit "forall") } + | 'family' { L1 $! mkUnqual varName (fsLit "family") } qvarsym :: { Located RdrName } : varsym { $1 } @@ -1805,7 +1859,7 @@ qvarsym1 : QVARSYM { L1 $ mkQual varName (getQVARSYM $1) } varsym :: { Located RdrName } : varsym_no_minus { $1 } - | '-' { L1 $ mkUnqual varName FSLIT("-") } + | '-' { L1 $ mkUnqual varName (fsLit "-") } varsym_no_minus :: { Located RdrName } -- varsym not including '-' : VARSYM { L1 $ mkUnqual varName (getVARSYM $1) } @@ -1818,26 +1872,27 @@ varsym_no_minus :: { Located RdrName } -- varsym not including '-' -- depending on context special_id :: { Located FastString } special_id - : 'as' { L1 FSLIT("as") } - | 'qualified' { L1 FSLIT("qualified") } - | 'hiding' { L1 FSLIT("hiding") } - | 'export' { L1 FSLIT("export") } - | 'label' { L1 FSLIT("label") } - | 'dynamic' { L1 FSLIT("dynamic") } - | 'stdcall' { L1 FSLIT("stdcall") } - | 'ccall' { L1 FSLIT("ccall") } + : 'as' { L1 (fsLit "as") } + | 'qualified' { L1 (fsLit "qualified") } + | 'hiding' { L1 (fsLit "hiding") } + | 'export' { L1 (fsLit "export") } + | 'label' { L1 (fsLit "label") } + | 'dynamic' { L1 (fsLit "dynamic") } + | 'stdcall' { L1 (fsLit "stdcall") } + | 'ccall' { L1 (fsLit "ccall") } special_sym :: { Located FastString } -special_sym : '!' { L1 FSLIT("!") } - | '.' { L1 FSLIT(".") } - | '*' { L1 FSLIT("*") } +special_sym : '!' { L1 (fsLit "!") } + | '.' { L1 (fsLit ".") } + | '*' { L1 (fsLit "*") } ----------------------------------------------------------------------------- -- Data constructors qconid :: { Located RdrName } -- Qualified or unqualified : conid { $1 } - | QCONID { L1 $ mkQual dataName (getQCONID $1) } + | QCONID { L1 $! mkQual dataName (getQCONID $1) } + | PREFIXQCONSYM { L1 $! mkQual dataName (getPREFIXQCONSYM $1) } conid :: { Located RdrName } : CONID { L1 $ mkUnqual dataName (getCONID $1) } @@ -1860,6 +1915,7 @@ literal :: { Located HsLit } : CHAR { L1 $ HsChar $ getCHAR $1 } | STRING { L1 $ HsString $ getSTRING $1 } | PRIMINTEGER { L1 $ HsIntPrim $ getPRIMINTEGER $1 } + | PRIMWORD { L1 $ HsWordPrim $ getPRIMWORD $1 } | PRIMCHAR { L1 $ HsCharPrim $ getPRIMCHAR $1 } | PRIMSTRING { L1 $ HsStringPrim $ getPRIMSTRING $1 } | PRIMFLOAT { L1 $ HsFloatPrim $ getPRIMFLOAT $1 } @@ -1945,6 +2001,8 @@ getQVARID (L _ (ITqvarid x)) = x getQCONID (L _ (ITqconid x)) = x getQVARSYM (L _ (ITqvarsym x)) = x getQCONSYM (L _ (ITqconsym x)) = x +getPREFIXQVARSYM (L _ (ITprefixqvarsym x)) = x +getPREFIXQCONSYM (L _ (ITprefixqconsym x)) = x getIPDUPVARID (L _ (ITdupipvarid x)) = x getCHAR (L _ (ITchar x)) = x getSTRING (L _ (ITstring x)) = x @@ -1953,10 +2011,12 @@ getRATIONAL (L _ (ITrational x)) = x getPRIMCHAR (L _ (ITprimchar x)) = x getPRIMSTRING (L _ (ITprimstring x)) = x getPRIMINTEGER (L _ (ITprimint x)) = x +getPRIMWORD (L _ (ITprimword x)) = x getPRIMFLOAT (L _ (ITprimfloat x)) = x getPRIMDOUBLE (L _ (ITprimdouble x)) = x getTH_ID_SPLICE (L _ (ITidEscape x)) = x getINLINE (L _ (ITinline_prag b)) = b +getINLINE_CONLIKE (L _ (ITinline_conlike_prag b)) = b getSPEC_INLINE (L _ (ITspec_inline_prag b)) = b getDOCNEXT (L _ (ITdocCommentNext x)) = x @@ -1964,16 +2024,26 @@ getDOCPREV (L _ (ITdocCommentPrev x)) = x getDOCNAMED (L _ (ITdocCommentNamed x)) = x getDOCSECTION (L _ (ITdocSection n x)) = (n, x) +getSCC :: Located Token -> P FastString +getSCC lt = do let s = getSTRING lt + err = "Spaces are not allowed in SCCs" + -- We probably actually want to be more restrictive than this + if ' ' `elem` unpackFS s + then failSpanMsgP (getLoc lt) (text err) + else return s + -- Utilities for combining source spans comb2 :: Located a -> Located b -> SrcSpan -comb2 = combineLocs +comb2 a b = a `seq` b `seq` combineLocs a b comb3 :: Located a -> Located b -> Located c -> SrcSpan -comb3 a b c = combineSrcSpans (getLoc a) (combineSrcSpans (getLoc b) (getLoc c)) +comb3 a b c = a `seq` b `seq` c `seq` + combineSrcSpans (getLoc a) (combineSrcSpans (getLoc b) (getLoc c)) comb4 :: Located a -> Located b -> Located c -> Located d -> SrcSpan -comb4 a b c d = combineSrcSpans (getLoc a) $ combineSrcSpans (getLoc b) $ - combineSrcSpans (getLoc c) (getLoc d) +comb4 a b c d = a `seq` b `seq` c `seq` d `seq` + (combineSrcSpans (getLoc a) $ combineSrcSpans (getLoc b) $ + combineSrcSpans (getLoc c) (getLoc d)) -- strict constructor version: {-# INLINE sL #-}