Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
9769cc03
by Simon Hengel at 2026-02-01T04:21:03-05:00
-
5fc9442a
by Peter Trommler at 2026-02-01T04:21:44-05:00
-
74dbb224
by Simon Peyton Jones at 2026-02-01T15:07:49-05:00
-
f856b07b
by Vladislav Zavialov at 2026-02-01T15:07:50-05:00
26 changed files:
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/String.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Types/InlinePragma.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- docs/users_guide/exts/multiway_if.rst
- hadrian/src/Builder.hs
- hadrian/src/Rules/Compile.hs
- hadrian/src/Settings/Builders/Cc.hs
- hadrian/src/Settings/Packages.hs
- + testsuite/tests/parser/should_fail/T26860ppr.hs
- + testsuite/tests/parser/should_fail/T26860ppr.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/simplCore/should_compile/T26826.hs
- testsuite/tests/simplCore/should_compile/all.T
- utils/check-exact/ExactPrint.hs
Changes:
| ... | ... | @@ -1417,16 +1417,17 @@ then we *must* choose f to be a loop breaker. Example: see Note |
| 1417 | 1417 | That is the whole reason for computing rule_fv_env in mkLoopBreakerNodes.
|
| 1418 | 1418 | Wrinkles:
|
| 1419 | 1419 | |
| 1420 | -* We only consider /active/ rules. See Note [Finding rule RHS free vars]
|
|
| 1420 | +(RLB1) We only consider /active/ rules.
|
|
| 1421 | + This is important: see Note [Finding rule RHS free vars]
|
|
| 1421 | 1422 | |
| 1422 | -* We need only consider free vars that are also binders in this Rec
|
|
| 1423 | +(RLB2) We need only consider free vars that are also binders in this Rec
|
|
| 1423 | 1424 | group. See also Note [Finding rule RHS free vars]
|
| 1424 | 1425 | |
| 1425 | -* We only consider variables free in the *RHS* of the rule, in
|
|
| 1426 | +(RLB3) We only consider variables free in the *RHS* of the rule, in
|
|
| 1426 | 1427 | contrast to the way we build the Rec group in the first place (Note
|
| 1427 | 1428 | [Rule dependency info])
|
| 1428 | 1429 | |
| 1429 | -* Why "transitive sequence of rules"? Because active rules apply
|
|
| 1430 | +(RLB4) Why "transitive sequence of rules"? Because active rules apply
|
|
| 1430 | 1431 | unconditionally, without checking loop-breaker-ness.
|
| 1431 | 1432 | See Note [Loop breaker dependencies].
|
| 1432 | 1433 | |
| ... | ... | @@ -1854,10 +1855,13 @@ makeNode !env imp_rule_edges bndr_set (bndr, rhs) |
| 1854 | 1855 | add_rule_uds (_, l, r) uds = l `andUDs` r `andUDs` uds
|
| 1855 | 1856 | |
| 1856 | 1857 | -------- active_rule_fvs ------------
|
| 1858 | + -- See Note [Rules and loop breakers]
|
|
| 1857 | 1859 | active_rule_fvs = foldr add_active_rule imp_rule_fvs rules_w_uds
|
| 1858 | 1860 | add_active_rule (rule, _, rhs_uds) fvs
|
| 1859 | - | is_active (ruleActivation rule)
|
|
| 1861 | + | is_active (ruleActivation rule) -- See (RLB1)
|
|
| 1860 | 1862 | = udFreeVars bndr_set rhs_uds `unionVarSet` fvs
|
| 1863 | + -- Only consider the `rhs_uss`, not the LHS ones; see (RLB3)
|
|
| 1864 | + -- udFreeVars restricts to bndr_set; see (RLB2)
|
|
| 1861 | 1865 | | otherwise
|
| 1862 | 1866 | = fvs
|
| 1863 | 1867 |
| ... | ... | @@ -12,7 +12,7 @@ module GHC.Core.Opt.Simplify.Env ( |
| 12 | 12 | |
| 13 | 13 | -- * Environments
|
| 14 | 14 | SimplEnv(..), pprSimplEnv, -- Temp not abstract
|
| 15 | - SimplPhase(..), isActive,
|
|
| 15 | + SimplPhase(..), isActive, simplStartPhase, simplEndPhase,
|
|
| 16 | 16 | seArityOpts, seCaseCase, seCaseFolding, seCaseMerge, seCastSwizzle,
|
| 17 | 17 | seDoEtaReduction, seEtaExpand, seFloatEnable, seInline, seNames,
|
| 18 | 18 | seOptCoercionOpts, sePhase, sePlatform, sePreInline,
|
| ... | ... | @@ -293,7 +293,9 @@ data SimplMode = SimplMode -- See comments in GHC.Core.Opt.Simplify.Monad |
| 293 | 293 | -- | See Note [SimplPhase]
|
| 294 | 294 | data SimplPhase
|
| 295 | 295 | -- | A simplifier phase: InitialPhase, Phase 2, Phase 1, Phase 0, FinalPhase
|
| 296 | + -- NB: (SimplPhase p) is equivalent to (SimplPhaseRange p p)
|
|
| 296 | 297 | = SimplPhase CompilerPhase
|
| 298 | + |
|
| 297 | 299 | -- | Simplifying the RHS of a rule or of a stable unfolding: the range of
|
| 298 | 300 | -- phases of the activation of the rule/stable unfolding.
|
| 299 | 301 | --
|
| ... | ... | @@ -302,13 +304,18 @@ data SimplPhase |
| 302 | 304 | --
|
| 303 | 305 | -- See Note [What is active in the RHS of a RULE or unfolding?]
|
| 304 | 306 | -- in GHC.Core.Opt.Simplify.Utils.
|
| 305 | - | SimplPhaseRange
|
|
| 306 | - { simplStartPhase :: CompilerPhase
|
|
| 307 | - , simplEndPhase :: CompilerPhase
|
|
| 308 | - }
|
|
| 307 | + | SimplPhaseRange CompilerPhase CompilerPhase
|
|
| 309 | 308 | |
| 310 | 309 | deriving Eq
|
| 311 | 310 | |
| 311 | +simplStartPhase :: SimplPhase -> CompilerPhase
|
|
| 312 | +simplStartPhase (SimplPhase p) = p
|
|
| 313 | +simplStartPhase (SimplPhaseRange p _) = p
|
|
| 314 | + |
|
| 315 | +simplEndPhase :: SimplPhase -> CompilerPhase
|
|
| 316 | +simplEndPhase (SimplPhase p) = p
|
|
| 317 | +simplEndPhase (SimplPhaseRange _ p) = p
|
|
| 318 | + |
|
| 312 | 319 | instance Outputable SimplPhase where
|
| 313 | 320 | ppr (SimplPhase p) = ppr p
|
| 314 | 321 | ppr (SimplPhaseRange s e) = brackets $ ppr s <> ellipsis <> ppr e
|
| ... | ... | @@ -322,12 +329,13 @@ instance Outputable SimplPhase where |
| 322 | 329 | --
|
| 323 | 330 | -- See Note [SimplPhase].
|
| 324 | 331 | isActive :: SimplPhase -> ActivationGhc -> Bool
|
| 325 | -isActive (SimplPhase p) act = isActiveInPhase p act
|
|
| 326 | -isActive (SimplPhaseRange start end) act =
|
|
| 327 | - -- To check whether the activation is active throughout the whole phase range,
|
|
| 328 | - -- it's sufficient to check the endpoints of the phase range, because an
|
|
| 329 | - -- activation can never have gaps (all activations are phase intervals).
|
|
| 330 | - isActiveInPhase start act && isActiveInPhase end act
|
|
| 332 | +isActive (SimplPhase p) act
|
|
| 333 | + = isActiveInPhase p act
|
|
| 334 | +isActive (SimplPhaseRange start end) act
|
|
| 335 | + = -- To check whether the activation is active throughout the whole phase range,
|
|
| 336 | + -- it's sufficient to check the endpoints of the phase range, because an
|
|
| 337 | + -- activation can never have gaps (all activations are phase intervals).
|
|
| 338 | + isActiveInPhase start act && isActiveInPhase end act
|
|
| 331 | 339 | |
| 332 | 340 | {- Note [SimplPhase]
|
| 333 | 341 | ~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1099,7 +1099,7 @@ updModeForStableUnfoldings :: ActivationGhc -> SimplMode -> SimplMode |
| 1099 | 1099 | -- See Note [Simplifying inside stable unfoldings]
|
| 1100 | 1100 | updModeForStableUnfoldings unf_act current_mode
|
| 1101 | 1101 | = current_mode
|
| 1102 | - { sm_phase = phaseFromActivation (sm_phase current_mode) unf_act
|
|
| 1102 | + { sm_phase = phaseForRuleOrUnf (sm_phase current_mode) unf_act
|
|
| 1103 | 1103 | -- See Note [What is active in the RHS of a RULE or unfolding?]
|
| 1104 | 1104 | , sm_eta_expand = False
|
| 1105 | 1105 | -- See Note [Eta expansion in stable unfoldings and rules]
|
| ... | ... | @@ -1123,27 +1123,32 @@ updModeForRuleRHS :: ActivationGhc -> SimplMode -> SimplMode |
| 1123 | 1123 | updModeForRuleRHS rule_act current_mode =
|
| 1124 | 1124 | current_mode
|
| 1125 | 1125 | -- See Note [What is active in the RHS of a RULE or unfolding?]
|
| 1126 | - { sm_phase = phaseFromActivation (sm_phase current_mode) rule_act
|
|
| 1126 | + { sm_phase = phaseForRuleOrUnf (sm_phase current_mode) rule_act
|
|
| 1127 | 1127 | , sm_eta_expand = False
|
| 1128 | 1128 | -- See Note [Eta expansion in stable unfoldings and rules]
|
| 1129 | 1129 | }
|
| 1130 | 1130 | |
| 1131 | --- | Compute the phase range to set the 'SimplMode' to
|
|
| 1132 | --- when simplifying the RHS of a rule or of a stable unfolding.
|
|
| 1131 | +-- | `phaseForRuleOrUnf` computes the phase range to use when
|
|
| 1132 | +-- simplifying the RHS of a rule or of a stable unfolding.
|
|
| 1133 | 1133 | --
|
| 1134 | +-- This subtle function implements the careful plan described in
|
|
| 1134 | 1135 | -- See Note [What is active in the RHS of a RULE or unfolding?]
|
| 1135 | -phaseFromActivation
|
|
| 1136 | - :: SimplPhase -- ^ the current simplifier phase
|
|
| 1136 | +phaseForRuleOrUnf
|
|
| 1137 | + :: SimplPhase -- ^ the current simplifier phase
|
|
| 1137 | 1138 | -> ActivationGhc -- ^ the activation of the RULE or stable unfolding
|
| 1138 | 1139 | -> SimplPhase
|
| 1139 | -phaseFromActivation p act
|
|
| 1140 | - | isNeverActive act
|
|
| 1141 | - = p
|
|
| 1140 | +phaseForRuleOrUnf current_phase act
|
|
| 1141 | + | start == end
|
|
| 1142 | + = SimplPhase start
|
|
| 1142 | 1143 | | otherwise
|
| 1143 | - = SimplPhaseRange act_start act_end
|
|
| 1144 | + = SimplPhaseRange start end
|
|
| 1144 | 1145 | where
|
| 1145 | - act_start = beginPhase act
|
|
| 1146 | - act_end = endPhase act
|
|
| 1146 | + start, end :: CompilerPhase
|
|
| 1147 | + start = beginPhase act `earliestPhase` simplStartPhase current_phase
|
|
| 1148 | + end = endPhase act `latestPhase` simplEndPhase current_phase
|
|
| 1149 | + -- The beginPhase/endPhase implements (WAR1)
|
|
| 1150 | + -- The simplStartPhase/simplEndPhase implements (WAR2)
|
|
| 1151 | + -- of Note [What is active in the RHS of a RULE or unfolding?]
|
|
| 1147 | 1152 | |
| 1148 | 1153 | {- Note [Simplifying rules]
|
| 1149 | 1154 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1275,26 +1280,47 @@ Our carefully crafted plan is as follows: |
| 1275 | 1280 | |
| 1276 | 1281 | -------------------------------------------------------------
|
| 1277 | 1282 | When simplifying the RHS of a RULE R with activation range A,
|
| 1278 | - fire only other rules R' that are active throughout all of A.
|
|
| 1283 | + fire only other rules R' that are active
|
|
| 1284 | + (WAR1) throughout all of A
|
|
| 1285 | + (WAR2) in the current phase
|
|
| 1286 | + See `phaseForRuleOrUnf`.
|
|
| 1279 | 1287 | -------------------------------------------------------------
|
| 1280 | 1288 | |
| 1281 | -Reason: R might fire in any phase in A. Then R' can fire only if R' is active
|
|
| 1282 | -in that phase. If not, it's not safe to unconditionally fire R' in the RHS of R.
|
|
| 1289 | +Reasons for (WAR1):
|
|
| 1290 | + * R might fire in any phase in A. Then R' can fire only if R' is active in that
|
|
| 1291 | + phase. If not, it's not safe to unconditionally fire R' in the RHS of R.
|
|
| 1292 | + |
|
| 1293 | +Reasons for (WAR2):
|
|
| 1294 | + * If A is empty (e.g. a NOINLINE pragma, so the unfolding is never active)
|
|
| 1295 | + we don't want to vacuously satisfy (WAR1) and thereby fire /all/ RULES in
|
|
| 1296 | + the unfolding. Two RULES may be crafted so that they are never simultaneously
|
|
| 1297 | + active, and will loop if they are.
|
|
| 1298 | + |
|
| 1299 | + * Suppose we are in Phase 2, looking at a stable unfolding for INLINE [1].
|
|
| 1300 | + If we just do (WAR1) we will fire RULES active in phase 1; but the
|
|
| 1301 | + occurrence analyser ignores any rules not active in the current phase.
|
|
| 1302 | + So occ-anal may fail to detect a loop breaker; see #26826 for details.
|
|
| 1303 | + See Note [Rules and loop breakers] in GHC.Core.Opt.OccurAnal.
|
|
| 1304 | + |
|
| 1305 | + * Aesthetically, this means that when the simplifer is in phase N, it
|
|
| 1306 | + won't switch to a phase-range that doesn't include N (e.g. might be later
|
|
| 1307 | + than N). This is what caused #26826.
|
|
| 1308 | + |
|
| 1309 | + * Also note that as the current phase advances, it'll eventually be inside
|
|
| 1310 | + the range specified by (WAR1), and hence will not widen the range.
|
|
| 1311 | + Unless the latter is empty, of course.
|
|
| 1283 | 1312 | |
| 1284 | 1313 | This plan is implemented by:
|
| 1285 | 1314 | |
| 1286 | - 1. Setting the simplifier phase to the range of phases
|
|
| 1287 | - corresponding to the start/end phases of the rule's activation.
|
|
| 1315 | + 1. Setting the simplifier phase to the /range/ of phases
|
|
| 1316 | + corresponding to the start/end phases of the rule's activation, implementing
|
|
| 1317 | + (WAR1) and (WAR2). This happens in `phaseForRuleOrUnf`.
|
|
| 1318 | + |
|
| 1288 | 1319 | 2. When checking whether another rule is active, we use the function
|
| 1289 | 1320 | isActive :: SimplPhase -> Activation -> Bool
|
| 1290 | 1321 | from GHC.Core.Opt.Simplify.Env, which checks whether the other rule is
|
| 1291 | 1322 | active throughout the whole range of phases.
|
| 1292 | 1323 | |
| 1293 | -However, if the rule whose RHS we are simplifying is never active, instead of
|
|
| 1294 | -setting the phase range to an empty interval, we keep the current simplifier
|
|
| 1295 | -phase. This special case avoids firing ALL rules in the RHS of a never-active
|
|
| 1296 | -rule.
|
|
| 1297 | - |
|
| 1298 | 1324 | You might wonder about a situation such as the following:
|
| 1299 | 1325 | |
| 1300 | 1326 | module M1 where
|
| ... | ... | @@ -1307,6 +1333,7 @@ It looks tempting to use "r1" when simplifying the RHS of "r2", yet we |
| 1307 | 1333 | **must not** do so: for any module M that imports M1, we are going to start
|
| 1308 | 1334 | simplification in M starting at InitialPhase, and we will see the
|
| 1309 | 1335 | fully simplified rules RHSs imported from M1.
|
| 1336 | + |
|
| 1310 | 1337 | Conclusion: stick to the plan.
|
| 1311 | 1338 | |
| 1312 | 1339 | Note [Simplifying inside stable unfoldings]
|
| ... | ... | @@ -914,9 +914,9 @@ mkStrWrapperInlinePrag (InlinePragma { inl_inline = fn_inl |
| 914 | 914 | where
|
| 915 | 915 | srcTxt = SourceText $ fsLit "{-# INLINE"
|
| 916 | 916 | -- See Note [Wrapper activation]
|
| 917 | - wrapper_phase = foldr (laterPhase . get_rule_phase) earliest_inline_phase rules
|
|
| 918 | - earliest_inline_phase = beginPhase fn_act `laterPhase` nextPhase InitialPhase
|
|
| 919 | - -- laterPhase (nextPhase InitialPhase) is a temporary hack
|
|
| 917 | + wrapper_phase = foldr (latestPhase . get_rule_phase) earliest_inline_phase rules
|
|
| 918 | + earliest_inline_phase = beginPhase fn_act `latestPhase` nextPhase InitialPhase
|
|
| 919 | + -- latestPhase (nextPhase InitialPhase) is a temporary hack
|
|
| 920 | 920 | -- to inline no earlier than phase 2. I got regressions in
|
| 921 | 921 | -- 'mate', due to changes in full laziness due to Note [Case
|
| 922 | 922 | -- MFEs], when I did earlier inlining.
|
| ... | ... | @@ -45,7 +45,6 @@ import Language.Haskell.Syntax.Lit |
| 45 | 45 | type instance XHsChar (GhcPass _) = SourceText
|
| 46 | 46 | type instance XHsCharPrim (GhcPass _) = SourceText
|
| 47 | 47 | type instance XHsString (GhcPass _) = SourceText
|
| 48 | -type instance XHsMultilineString (GhcPass _) = SourceText
|
|
| 49 | 48 | type instance XHsStringPrim (GhcPass _) = SourceText
|
| 50 | 49 | type instance XHsInt (GhcPass _) = NoExtField
|
| 51 | 50 | type instance XHsIntPrim (GhcPass _) = SourceText
|
| ... | ... | @@ -147,7 +146,6 @@ hsLitNeedsParens p = go |
| 147 | 146 | go (HsChar {}) = False
|
| 148 | 147 | go (HsCharPrim {}) = False
|
| 149 | 148 | go (HsString {}) = False
|
| 150 | - go (HsMultilineString {}) = False
|
|
| 151 | 149 | go (HsStringPrim {}) = False
|
| 152 | 150 | go (HsInt _ x) = p > topPrec && il_neg x
|
| 153 | 151 | go (HsFloatPrim {}) = False
|
| ... | ... | @@ -177,7 +175,6 @@ convertLit :: XXLit (GhcPass p)~DataConCantHappen => HsLit (GhcPass p) -> HsLit |
| 177 | 175 | convertLit (HsChar a x) = HsChar a x
|
| 178 | 176 | convertLit (HsCharPrim a x) = HsCharPrim a x
|
| 179 | 177 | convertLit (HsString a x) = HsString a x
|
| 180 | -convertLit (HsMultilineString a x) = HsMultilineString a x
|
|
| 181 | 178 | convertLit (HsStringPrim a x) = HsStringPrim a x
|
| 182 | 179 | convertLit (HsInt a x) = HsInt a x
|
| 183 | 180 | convertLit (HsIntPrim a x) = HsIntPrim a x
|
| ... | ... | @@ -212,8 +209,7 @@ Equivalently it's True if |
| 212 | 209 | instance IsPass p => Outputable (HsLit (GhcPass p)) where
|
| 213 | 210 | ppr (HsChar st c) = pprWithSourceText st (pprHsChar c)
|
| 214 | 211 | ppr (HsCharPrim st c) = pprWithSourceText st (pprPrimChar c)
|
| 215 | - ppr (HsString st s) = pprWithSourceText st (pprHsString s)
|
|
| 216 | - ppr (HsMultilineString st s) =
|
|
| 212 | + ppr (HsString st s) =
|
|
| 217 | 213 | case st of
|
| 218 | 214 | NoSourceText -> pprHsString s
|
| 219 | 215 | SourceText src -> vcat $ map text $ split '\n' (unpackFS src)
|
| ... | ... | @@ -248,36 +244,6 @@ instance Outputable OverLitVal where |
| 248 | 244 | ppr (HsFractional f) = ppr f
|
| 249 | 245 | ppr (HsIsString st s) = pprWithSourceText st (pprHsString s)
|
| 250 | 246 | |
| 251 | --- | pmPprHsLit pretty prints literals and is used when pretty printing pattern
|
|
| 252 | --- match warnings. All are printed the same (i.e., without hashes if they are
|
|
| 253 | --- primitive and not wrapped in constructors if they are boxed). This happens
|
|
| 254 | --- mainly for too reasons:
|
|
| 255 | --- * We do not want to expose their internal representation
|
|
| 256 | --- * The warnings become too messy
|
|
| 257 | -pmPprHsLit :: forall p. IsPass p => HsLit (GhcPass p) -> SDoc
|
|
| 258 | -pmPprHsLit (HsChar _ c) = pprHsChar c
|
|
| 259 | -pmPprHsLit (HsCharPrim _ c) = pprHsChar c
|
|
| 260 | -pmPprHsLit (HsString st s) = pprWithSourceText st (pprHsString s)
|
|
| 261 | -pmPprHsLit (HsMultilineString st s) = pprWithSourceText st (pprHsString s)
|
|
| 262 | -pmPprHsLit (HsStringPrim _ s) = pprHsBytes s
|
|
| 263 | -pmPprHsLit (HsInt _ i) = integer (il_value i)
|
|
| 264 | -pmPprHsLit (HsIntPrim _ i) = integer i
|
|
| 265 | -pmPprHsLit (HsWordPrim _ w) = integer w
|
|
| 266 | -pmPprHsLit (HsInt8Prim _ i) = integer i
|
|
| 267 | -pmPprHsLit (HsInt16Prim _ i) = integer i
|
|
| 268 | -pmPprHsLit (HsInt32Prim _ i) = integer i
|
|
| 269 | -pmPprHsLit (HsInt64Prim _ i) = integer i
|
|
| 270 | -pmPprHsLit (HsWord8Prim _ w) = integer w
|
|
| 271 | -pmPprHsLit (HsWord16Prim _ w) = integer w
|
|
| 272 | -pmPprHsLit (HsWord32Prim _ w) = integer w
|
|
| 273 | -pmPprHsLit (HsWord64Prim _ w) = integer w
|
|
| 274 | -pmPprHsLit (HsFloatPrim _ f) = ppr f
|
|
| 275 | -pmPprHsLit (HsDoublePrim _ d) = ppr d
|
|
| 276 | -pmPprHsLit (XLit x) = case ghcPass @p of
|
|
| 277 | - GhcTc -> case x of
|
|
| 278 | - (HsInteger _ i _) -> integer i
|
|
| 279 | - (HsRat f _) -> ppr f
|
|
| 280 | - |
|
| 281 | 247 | negateOverLitVal :: OverLitVal -> OverLitVal
|
| 282 | 248 | negateOverLitVal (HsIntegral i) = HsIntegral (negateIntegralLit i)
|
| 283 | 249 | negateOverLitVal (HsFractional f) = HsFractional (negateFractionalLit f)
|
| ... | ... | @@ -75,7 +75,6 @@ hsLitType :: forall p. IsPass p => HsLit (GhcPass p) -> Type |
| 75 | 75 | hsLitType (HsChar _ _) = charTy
|
| 76 | 76 | hsLitType (HsCharPrim _ _) = charPrimTy
|
| 77 | 77 | hsLitType (HsString _ _) = stringTy
|
| 78 | -hsLitType (HsMultilineString _ _) = stringTy
|
|
| 79 | 78 | hsLitType (HsStringPrim _ _) = addrPrimTy
|
| 80 | 79 | hsLitType (HsInt _ _) = intTy
|
| 81 | 80 | hsLitType (HsIntPrim _ _) = intPrimTy
|
| ... | ... | @@ -117,7 +117,6 @@ dsLit l = do |
| 117 | 117 | HsDoublePrim _ fl -> return (Lit (LitDouble (rationalFromFractionalLit fl)))
|
| 118 | 118 | HsChar _ c -> return (mkCharExpr c)
|
| 119 | 119 | HsString _ str -> mkStringExprFS str
|
| 120 | - HsMultilineString _ str -> mkStringExprFS str
|
|
| 121 | 120 | HsInt _ i -> return (mkIntExpr platform (il_value i))
|
| 122 | 121 | XLit x -> case ghcPass @p of
|
| 123 | 122 | GhcTc -> case x of
|
| ... | ... | @@ -463,7 +462,6 @@ getSimpleIntegralLit (XLit (HsInteger _ i ty)) = Just (i, ty) |
| 463 | 462 | getSimpleIntegralLit HsChar{} = Nothing
|
| 464 | 463 | getSimpleIntegralLit HsCharPrim{} = Nothing
|
| 465 | 464 | getSimpleIntegralLit HsString{} = Nothing
|
| 466 | -getSimpleIntegralLit HsMultilineString{} = Nothing
|
|
| 467 | 465 | getSimpleIntegralLit HsStringPrim{} = Nothing
|
| 468 | 466 | getSimpleIntegralLit (XLit (HsRat{})) = Nothing
|
| 469 | 467 | getSimpleIntegralLit HsFloatPrim{} = Nothing
|
| ... | ... | @@ -3077,7 +3077,6 @@ repLiteral lit |
| 3077 | 3077 | HsChar _ _ -> Just charLName
|
| 3078 | 3078 | HsCharPrim _ _ -> Just charPrimLName
|
| 3079 | 3079 | HsString _ _ -> Just stringLName
|
| 3080 | - HsMultilineString _ _ -> Just stringLName
|
|
| 3081 | 3080 | _ -> Nothing
|
| 3082 | 3081 | |
| 3083 | 3082 | mk_integer :: Integer -> MetaM (HsLit GhcTc)
|
| ... | ... | @@ -4131,7 +4131,7 @@ literal :: { Located (HsLit GhcPs) } |
| 4131 | 4131 | : CHAR { sL1 $1 $ HsChar (getCHARs $1) $ getCHAR $1 }
|
| 4132 | 4132 | | STRING { sL1 $1 $ HsString (getSTRINGs $1)
|
| 4133 | 4133 | $ getSTRING $1 }
|
| 4134 | - | STRING_MULTI { sL1 $1 $ HsMultilineString (getSTRINGMULTIs $1)
|
|
| 4134 | + | STRING_MULTI { sL1 $1 $ HsString (getSTRINGMULTIs $1)
|
|
| 4135 | 4135 | $ getSTRINGMULTI $1 }
|
| 4136 | 4136 | | PRIMINTEGER { sL1 $1 $ HsIntPrim (getPRIMINTEGERs $1)
|
| 4137 | 4137 | $ getPRIMINTEGER $1 }
|
| ... | ... | @@ -392,9 +392,9 @@ proposal: https://github.com/ghc-proposals/ghc-proposals/pull/569 |
| 392 | 392 | |
| 393 | 393 | Multiline string literals are syntax sugar for normal string literals,
|
| 394 | 394 | with an extra post processing step. This all happens in the Lexer; that
|
| 395 | -is, HsMultilineString will contain the post-processed string. This matches
|
|
| 396 | -the same behavior as HsString, which contains the normalized string
|
|
| 397 | -(see Note [Literal source text]).
|
|
| 395 | +is, the multi-line HsString will contain the post-processed string.
|
|
| 396 | +This matches the behavior of the single-line HsString, which contains
|
|
| 397 | +the normalized string too (see Note [Literal source text]).
|
|
| 398 | 398 | |
| 399 | 399 | The canonical steps for post processing a multiline string are:
|
| 400 | 400 | 1. Collapse string gaps
|
| ... | ... | @@ -352,18 +352,13 @@ rnExpr (HsOverLabel src v) |
| 352 | 352 | hs_ty_arg = mkEmptyWildCardBndrs $ wrapGenSpan $
|
| 353 | 353 | HsTyLit noExtField (HsStrTy NoSourceText v)
|
| 354 | 354 | |
| 355 | -rnExpr (HsLit x lit) | Just (src, s) <- stringLike lit
|
|
| 355 | +rnExpr (HsLit x lit) | HsString src s <- lit
|
|
| 356 | 356 | = do { opt_OverloadedStrings <- xoptM LangExt.OverloadedStrings
|
| 357 | 357 | ; if opt_OverloadedStrings then
|
| 358 | 358 | rnExpr (HsOverLit x (mkHsIsString src s))
|
| 359 | 359 | else do {
|
| 360 | 360 | ; rnLit lit
|
| 361 | 361 | ; return (HsLit x (convertLit lit), emptyFVs) } }
|
| 362 | - where
|
|
| 363 | - stringLike = \case
|
|
| 364 | - HsString src s -> Just (src, s)
|
|
| 365 | - HsMultilineString src s -> Just (src, s)
|
|
| 366 | - _ -> Nothing
|
|
| 367 | 362 | |
| 368 | 363 | rnExpr (HsLit x lit)
|
| 369 | 364 | = do { rnLit lit
|
| ... | ... | @@ -4786,7 +4786,6 @@ promotionErr name err |
| 4786 | 4786 | |
| 4787 | 4787 | tyLitFromLit :: HsLit GhcRn -> Maybe (HsTyLit GhcRn)
|
| 4788 | 4788 | tyLitFromLit (HsString x str) = Just (HsStrTy x str)
|
| 4789 | -tyLitFromLit (HsMultilineString x str) = Just (HsStrTy x str)
|
|
| 4790 | 4789 | tyLitFromLit (HsChar x char) = Just (HsCharTy x char)
|
| 4791 | 4790 | tyLitFromLit _ = Nothing
|
| 4792 | 4791 |
| ... | ... | @@ -104,9 +104,8 @@ module GHC.Types.InlinePragma |
| 104 | 104 | , endPhase
|
| 105 | 105 | -- *** Queries
|
| 106 | 106 | , isActiveInPhase
|
| 107 | - , laterPhase
|
|
| 108 | - , laterThanPhase
|
|
| 109 | - , nextPhase
|
|
| 107 | + , latestPhase, earliestPhase
|
|
| 108 | + , laterThanPhase, nextPhase
|
|
| 110 | 109 | ) where
|
| 111 | 110 | |
| 112 | 111 | import GHC.Prelude
|
| ... | ... | @@ -422,13 +421,21 @@ nextPhase (Phase 0) = FinalPhase |
| 422 | 421 | nextPhase (Phase n) = Phase (n-1)
|
| 423 | 422 | nextPhase FinalPhase = FinalPhase
|
| 424 | 423 | |
| 425 | -laterPhase :: CompilerPhase -> CompilerPhase -> CompilerPhase
|
|
| 426 | --- ^ Returns the later of two phases
|
|
| 427 | -laterPhase (Phase n1) (Phase n2) = Phase (n1 `min` n2)
|
|
| 428 | -laterPhase InitialPhase p2 = p2
|
|
| 429 | -laterPhase FinalPhase _ = FinalPhase
|
|
| 430 | -laterPhase p1 InitialPhase = p1
|
|
| 431 | -laterPhase _ FinalPhase = FinalPhase
|
|
| 424 | +earliestPhase :: CompilerPhase -> CompilerPhase -> CompilerPhase
|
|
| 425 | +-- ^ Returns the earliest of two phases
|
|
| 426 | +earliestPhase (Phase n1) (Phase n2) = Phase (n1 `max` n2)
|
|
| 427 | +earliestPhase InitialPhase _ = InitialPhase
|
|
| 428 | +earliestPhase FinalPhase p2 = p2
|
|
| 429 | +earliestPhase _ InitialPhase = InitialPhase
|
|
| 430 | +earliestPhase p1 FinalPhase = p1
|
|
| 431 | + |
|
| 432 | +latestPhase :: CompilerPhase -> CompilerPhase -> CompilerPhase
|
|
| 433 | +-- ^ Returns the latest of two phases
|
|
| 434 | +latestPhase (Phase n1) (Phase n2) = Phase (n1 `min` n2)
|
|
| 435 | +latestPhase InitialPhase p2 = p2
|
|
| 436 | +latestPhase FinalPhase _ = FinalPhase
|
|
| 437 | +latestPhase p1 InitialPhase = p1
|
|
| 438 | +latestPhase _ FinalPhase = FinalPhase
|
|
| 432 | 439 | |
| 433 | 440 | -- | @p1 `laterThanOrEqualPhase` p2@ computes whether @p1@ happens (strictly)
|
| 434 | 441 | -- after @p2@.
|
| ... | ... | @@ -609,7 +609,6 @@ type family XXParStmtBlock x x' |
| 609 | 609 | type family XHsChar x
|
| 610 | 610 | type family XHsCharPrim x
|
| 611 | 611 | type family XHsString x
|
| 612 | -type family XHsMultilineString x
|
|
| 613 | 612 | type family XHsStringPrim x
|
| 614 | 613 | type family XHsInt x
|
| 615 | 614 | type family XHsIntPrim x
|
| ... | ... | @@ -47,8 +47,6 @@ data HsLit x |
| 47 | 47 | -- ^ Unboxed character
|
| 48 | 48 | | HsString (XHsString x) {- SourceText -} FastString
|
| 49 | 49 | -- ^ String
|
| 50 | - | HsMultilineString (XHsMultilineString x) {- SourceText -} FastString
|
|
| 51 | - -- ^ String
|
|
| 52 | 50 | | HsStringPrim (XHsStringPrim x) {- SourceText -} !ByteString
|
| 53 | 51 | -- ^ Packed bytes
|
| 54 | 52 | | HsInt (XHsInt x) IntegralLit
|
| ... | ... | @@ -10,7 +10,7 @@ Multi-way if-expressions |
| 10 | 10 | |
| 11 | 11 | Allow the use of multi-way-``if`` syntax.
|
| 12 | 12 | |
| 13 | -With :extension:`MultiWayIf` extension GHC accepts conditional expressions with
|
|
| 13 | +With the :extension:`MultiWayIf` extension GHC accepts conditional expressions with
|
|
| 14 | 14 | multiple branches: ::
|
| 15 | 15 | |
| 16 | 16 | if | guard1 -> expr1
|
| ... | ... | @@ -24,12 +24,12 @@ which is roughly equivalent to :: |
| 24 | 24 | ...
|
| 25 | 25 | _ | guardN -> exprN
|
| 26 | 26 | |
| 27 | -Multi-way if expressions introduce a new layout context. So the example
|
|
| 27 | +Multi-way if expressions introduce a new kind of layout context that does not generate semicolons. The example
|
|
| 28 | 28 | above is equivalent to: ::
|
| 29 | 29 | |
| 30 | 30 | if { | guard1 -> expr1
|
| 31 | - ; | ...
|
|
| 32 | - ; | guardN -> exprN
|
|
| 31 | + | ...
|
|
| 32 | + | guardN -> exprN
|
|
| 33 | 33 | }
|
| 34 | 34 | |
| 35 | 35 | The following behaves as expected: ::
|
| ... | ... | @@ -41,14 +41,14 @@ The following behaves as expected: :: |
| 41 | 41 | because layout translates it as ::
|
| 42 | 42 | |
| 43 | 43 | if { | guard1 -> if { | guard2 -> expr2
|
| 44 | - ; | guard3 -> expr3
|
|
| 44 | + | guard3 -> expr3
|
|
| 45 | 45 | }
|
| 46 | - ; | guard4 -> expr4
|
|
| 46 | + | guard4 -> expr4
|
|
| 47 | 47 | }
|
| 48 | 48 | |
| 49 | 49 | Layout with multi-way if works in the same way as other layout contexts,
|
| 50 | -except that the semi-colons between guards in a multi-way if are
|
|
| 51 | -optional. So it is not necessary to line up all the guards at the same
|
|
| 50 | +except that desugaring does not insert semicolons.
|
|
| 51 | +So it is not necessary to line up all the guards at the same
|
|
| 52 | 52 | column; this is consistent with the way guards work in function
|
| 53 | 53 | definitions and case expressions.
|
| 54 | 54 |
| ... | ... | @@ -49,7 +49,7 @@ import GHC.Toolchain.Program |
| 49 | 49 | -- * Compile or preprocess a source file.
|
| 50 | 50 | -- * Extract source dependencies by passing @-MM@ command line argument.
|
| 51 | 51 | data CcMode = CompileC | FindCDependencies DependencyType deriving (Eq, Generic, Show)
|
| 52 | -data DependencyType = CDep | CxxDep deriving (Eq, Generic, Show)
|
|
| 52 | +data DependencyType = CDep | CxxDep | AsmDep deriving (Eq, Generic, Show)
|
|
| 53 | 53 | |
| 54 | 54 | instance Binary CcMode
|
| 55 | 55 | instance Hashable CcMode
|
| ... | ... | @@ -282,8 +282,11 @@ needDependencies lang context@Context {..} src depFile = do |
| 282 | 282 | discover -- Continue the discovery process
|
| 283 | 283 | |
| 284 | 284 | -- We need to pass different flags to cc depending on whether the
|
| 285 | - -- file to compile is a .c or a .cpp file
|
|
| 286 | - depType = if lang == Cxx then CxxDep else CDep
|
|
| 285 | + -- file to compile is a .c or a .cpp or a .S file
|
|
| 286 | + depType = case lang of
|
|
| 287 | + Cxx -> CxxDep
|
|
| 288 | + Asm -> AsmDep
|
|
| 289 | + _ -> CDep
|
|
| 287 | 290 | |
| 288 | 291 | parseFile :: FilePath -> Action [String]
|
| 289 | 292 | parseFile file = do
|
| ... | ... | @@ -18,6 +18,7 @@ ccBuilderArgs = do |
| 18 | 18 | , arg "-o", arg =<< getOutput ]
|
| 19 | 19 | , builder (Cc (FindCDependencies CDep)) ? findCDepExpr CDep
|
| 20 | 20 | , builder (Cc (FindCDependencies CxxDep)) ? findCDepExpr CxxDep
|
| 21 | + , builder (Cc (FindCDependencies AsmDep)) ? findCDepExpr AsmDep
|
|
| 21 | 22 | ]
|
| 22 | 23 | where
|
| 23 | 24 | findCDepExpr depType = do
|
| ... | ... | @@ -26,10 +27,10 @@ ccBuilderArgs = do |
| 26 | 27 | , arg "-MM", arg "-MG"
|
| 27 | 28 | , arg "-MF", arg output
|
| 28 | 29 | , arg "-MT", arg $ dropExtension output -<.> "o"
|
| 29 | - , case depType of CDep -> mempty; CxxDep -> arg "-std=c++11"
|
|
| 30 | + , case depType of CDep -> mempty; CxxDep -> arg "-std=c++11"; AsmDep -> mempty
|
|
| 30 | 31 | , cIncludeArgs
|
| 31 | - , arg "-x", arg (case depType of CDep -> "c"; CxxDep -> "c++")
|
|
| 32 | - , case depType of CDep -> mempty; CxxDep -> getContextData cxxOpts
|
|
| 32 | + , arg "-x", arg (case depType of CDep -> "c"; CxxDep -> "c++"; AsmDep -> "assembler-with-cpp")
|
|
| 33 | + , case depType of CDep -> mempty; CxxDep -> getContextData cxxOpts; AsmDep -> mempty
|
|
| 33 | 34 | -- Pass 'ghcversion.h' to give sources access to the
|
| 34 | 35 | -- `MIN_VERSION_GLASGOW_HASKELL` macro.
|
| 35 | 36 | , notStage0 ? arg "-include" <> arg "rts/include/ghcversion.h"
|
| ... | ... | @@ -428,6 +428,7 @@ rtsPackageArgs = package rts ? do |
| 428 | 428 | ]
|
| 429 | 429 | , builder (Cc (FindCDependencies CDep)) ? cArgs
|
| 430 | 430 | , builder (Cc (FindCDependencies CxxDep)) ? cArgs
|
| 431 | + , builder (Cc (FindCDependencies AsmDep)) ? cArgs
|
|
| 431 | 432 | , builder (Ghc CompileCWithGhc) ? map ("-optc" ++) <$> cArgs
|
| 432 | 433 | , builder (Ghc CompileCppWithGhc) ? map ("-optcxx" ++) <$> cArgs
|
| 433 | 434 | , builder Ghc ? ghcArgs
|
| 1 | +{-# LANGUAGE NoOverloadedStrings #-}
|
|
| 2 | + |
|
| 3 | +module T26860ppr where
|
|
| 4 | + |
|
| 5 | +-- Test that the error message containing the string literal is well-formatted.
|
|
| 6 | +-- See also: parser/should_fail/MultilineStringsError
|
|
| 7 | +x :: Int
|
|
| 8 | +x = "first line \
|
|
| 9 | + \asdf\n\
|
|
| 10 | + \second line"
|
|
| 11 | + |
| 1 | +T26860ppr.hs:8:5: error: [GHC-83865]
|
|
| 2 | + • Couldn't match type ‘[Char]’ with ‘Int’
|
|
| 3 | + Expected: Int
|
|
| 4 | + Actual: String
|
|
| 5 | + • In the expression:
|
|
| 6 | + "first line \
|
|
| 7 | + \asdf\n\
|
|
| 8 | + \second line"
|
|
| 9 | + In an equation for ‘x’:
|
|
| 10 | + x = "first line \
|
|
| 11 | + \asdf\n\
|
|
| 12 | + \second line"
|
|
| 13 | + |
| ... | ... | @@ -244,3 +244,4 @@ test('T25530', normal, compile_fail, ['']) |
| 244 | 244 | test('T26418', normal, compile_fail, [''])
|
| 245 | 245 | test('T12488c', normal, compile_fail, [''])
|
| 246 | 246 | test('T12488d', normal, compile_fail, [''])
|
| 247 | +test('T26860ppr', normal, compile_fail, ['']) |
| 1 | +{-# LANGUAGE BangPatterns #-}
|
|
| 2 | +{-# LANGUAGE CPP #-}
|
|
| 3 | +{-# LANGUAGE GADTs #-}
|
|
| 4 | +{-# LANGUAGE KindSignatures #-}
|
|
| 5 | +{-# LANGUAGE LambdaCase #-}
|
|
| 6 | +{-# LANGUAGE ScopedTypeVariables #-}
|
|
| 7 | +{-# LANGUAGE TypeAbstractions #-}
|
|
| 8 | +{-# LANGUAGE TypeApplications #-}
|
|
| 9 | +{-# LANGUAGE TypeData #-}
|
|
| 10 | + |
|
| 11 | +module T26826 where
|
|
| 12 | + |
|
| 13 | +import Data.Kind (Type)
|
|
| 14 | + |
|
| 15 | +type data AstSpan =
|
|
| 16 | + FullSpan | PrimalStepSpan AstSpan | PlainSpan
|
|
| 17 | + |
|
| 18 | +data SAstSpan (s :: AstSpan) where
|
|
| 19 | + SFullSpan :: SAstSpan FullSpan
|
|
| 20 | + SPrimalStepSpan :: SAstSpan s -> SAstSpan (PrimalStepSpan s)
|
|
| 21 | + SPlainSpan :: SAstSpan PlainSpan
|
|
| 22 | + |
|
| 23 | +class KnownSpan (s :: AstSpan) where
|
|
| 24 | + knownSpan :: SAstSpan s
|
|
| 25 | + |
|
| 26 | +instance KnownSpan FullSpan where
|
|
| 27 | + knownSpan = SFullSpan
|
|
| 28 | + |
|
| 29 | +instance KnownSpan s => KnownSpan (PrimalStepSpan s) where
|
|
| 30 | + knownSpan = SPrimalStepSpan (knownSpan @s)
|
|
| 31 | + |
|
| 32 | +instance KnownSpan PlainSpan where
|
|
| 33 | + knownSpan = SPlainSpan
|
|
| 34 | + |
|
| 35 | +class ADReady target where
|
|
| 36 | + ttlet :: target a -> (target a -> target b) -> target b
|
|
| 37 | + ttletPrimal :: target a -> (target a -> target b) -> target b
|
|
| 38 | + ttletPlain :: target a -> (target a -> target b) -> target b
|
|
| 39 | + tplainPart :: target a -> target a
|
|
| 40 | + tfromPlain :: target a -> target a
|
|
| 41 | + tprimalPart :: target a -> target a
|
|
| 42 | + tfromPrimal :: target a -> target a
|
|
| 43 | + |
|
| 44 | +type SpanTargetFam target (s :: AstSpan) (y :: Type) = target y
|
|
| 45 | + |
|
| 46 | +type AstEnv target = ()
|
|
| 47 | + |
|
| 48 | +data AstTensor (s :: AstSpan) (y :: Type) where
|
|
| 49 | + AstLet
|
|
| 50 | + :: forall a b s1 s2.
|
|
| 51 | + KnownSpan s1
|
|
| 52 | + => AstTensor s1 a
|
|
| 53 | + -> AstTensor s2 b
|
|
| 54 | + -> AstTensor s2 b
|
|
| 55 | + |
|
| 56 | + AstPrimalPart :: KnownSpan s' => AstTensor s' a -> AstTensor (PrimalStepSpan s') a
|
|
| 57 | + AstFromPrimal :: AstTensor (PrimalStepSpan s') a -> AstTensor s' a
|
|
| 58 | + AstPlainPart :: KnownSpan s' => AstTensor s' a -> AstTensor PlainSpan a
|
|
| 59 | + AstFromPlain :: AstTensor PlainSpan a -> AstTensor s' a
|
|
| 60 | + |
|
| 61 | +interpretAst
|
|
| 62 | + :: forall target s y. (ADReady target, KnownSpan s)
|
|
| 63 | + => AstEnv target -> AstTensor s y
|
|
| 64 | + -> SpanTargetFam target s y
|
|
| 65 | +{-# INLINE [1] interpretAst #-}
|
|
| 66 | +interpretAst !env
|
|
| 67 | + = \case
|
|
| 68 | + AstLet @_ @_ @s1 @s2 u v ->
|
|
| 69 | + case knownSpan @s1 of
|
|
| 70 | + SFullSpan ->
|
|
| 71 | + ttlet (interpretAst env u)
|
|
| 72 | + (\_w -> interpretAst env v)
|
|
| 73 | + SPrimalStepSpan _ ->
|
|
| 74 | + ttletPrimal (interpretAst env u)
|
|
| 75 | + (\_w -> interpretAst env v)
|
|
| 76 | + SPlainSpan ->
|
|
| 77 | + ttletPlain (interpretAst env u)
|
|
| 78 | + (\_w -> interpretAst env v)
|
|
| 79 | + AstPrimalPart a ->
|
|
| 80 | + tprimalPart (interpretAst env a)
|
|
| 81 | + AstFromPrimal a ->
|
|
| 82 | + tfromPrimal (interpretAst env a)
|
|
| 83 | + AstPlainPart a ->
|
|
| 84 | + tplainPart (interpretAst env a)
|
|
| 85 | + AstFromPlain a ->
|
|
| 86 | + tfromPlain (interpretAst env a) |
| ... | ... | @@ -578,4 +578,6 @@ test('T26615', [grep_errmsg(r'fEqList')], multimod_compile, ['T26615', '-O -fsp |
| 578 | 578 | |
| 579 | 579 | # T26722: there should be no reboxing in $wg
|
| 580 | 580 | test('T26722', [grep_errmsg(r'SPEC')], compile, ['-O -dno-typeable-binds'])
|
| 581 | + |
|
| 581 | 582 | test('T26805', [grep_errmsg(r'fromInteger')], compile, ['-O -dno-typeable-binds -ddump-simpl -dsuppress-uniques'])
|
| 583 | +test('T26826', normal, compile, ['-O']) |
| ... | ... | @@ -4794,7 +4794,6 @@ hsLit2String lit = |
| 4794 | 4794 | HsChar src v -> toSourceTextWithSuffix src v ""
|
| 4795 | 4795 | HsCharPrim src p -> toSourceTextWithSuffix src p ""
|
| 4796 | 4796 | HsString src v -> toSourceTextWithSuffix src v ""
|
| 4797 | - HsMultilineString src v -> toSourceTextWithSuffix src v ""
|
|
| 4798 | 4797 | HsStringPrim src v -> toSourceTextWithSuffix src v ""
|
| 4799 | 4798 | HsInt _ (IL src _ v) -> toSourceTextWithSuffix src v ""
|
| 4800 | 4799 | HsIntPrim src v -> toSourceTextWithSuffix src v ""
|