Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
269c4087
by Simon Peyton Jones at 2026-02-01T19:38:10-05:00
7 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/Types/InlinePragma.hs
- + testsuite/tests/simplCore/should_compile/T26826.hs
- testsuite/tests/simplCore/should_compile/all.T
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.
|
| ... | ... | @@ -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@.
|
| 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']) |