Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

6 changed files:

Changes:

  • changelog.d/T27261
    1
    +section: compiler
    
    2
    +issues: #27261
    
    3
    +mrs: !16084
    
    4
    +synopsis:
    
    5
    +  Avoid a crash in ``mkDupableContWithDmds`` when given empty demands
    
    6
    +description:
    
    7
    +  The case of an empty list of remaining argument demands is now explicitly
    
    8
    +  handled by trimming the simplifier continuation, to avoid a compiler crash
    
    9
    +  of the form ``Non-exhaustive patterns in dmd : cont_dmds`` or ``expectNonEmpty``
    
    10
    +  in ``mkDupableContWithDmds``.

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -62,6 +62,7 @@ import GHC.Types.Var ( isTyCoVar )
    62 62
     import GHC.Builtin.Types.Prim( realWorldStatePrimTy )
    
    63 63
     import GHC.Builtin.Names( runRWKey, seqHashKey )
    
    64 64
     
    
    65
    +import qualified GHC.Data.List.Infinite as Inf
    
    65 66
     import GHC.Data.Maybe   ( isNothing, orElse, mapMaybe )
    
    66 67
     import GHC.Data.FastString
    
    67 68
     import GHC.Unit.Module ( moduleName )
    
    ... ... @@ -2444,24 +2445,9 @@ rebuildCall env arg_info _cont
    2444 2445
     
    
    2445 2446
     ---------- Bottoming applications --------------
    
    2446 2447
     rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont
    
    2447
    -  -- When we run out of strictness args, it means
    
    2448
    -  -- that the call is definitely bottom; see GHC.Core.Opt.Simplify.Utils.mkArgInfo
    
    2449
    -  -- Then we want to discard the entire strict continuation.  E.g.
    
    2450
    -  --    * case (error "hello") of { ... }
    
    2451
    -  --    * (error "Hello") arg
    
    2452
    -  --    * f (error "Hello") where f is strict
    
    2453
    -  --    etc
    
    2454
    -  -- Then, especially in the first of these cases, we'd like to discard
    
    2455
    -  -- the continuation, leaving just the bottoming expression.  But the
    
    2456
    -  -- type might not be right, so we may have to add a coerce.
    
    2457
    -  | not (contIsTrivial cont)     -- Only do this if there is a non-trivial
    
    2458
    -                                 -- continuation to discard, else we do it
    
    2459
    -                                 -- again and again!
    
    2460
    -  = seqType cont_ty `seq`        -- See Note [Avoiding space leaks in OutType]
    
    2461
    -    return (emptyFloats env, castBottomExpr res cont_ty)
    
    2462
    -  where
    
    2463
    -    res     = argInfoExpr fun rev_args
    
    2464
    -    cont_ty = contResultType cont
    
    2448
    +  -- When we run out of demands, it means that the call is definitely bottom.
    
    2449
    +  -- See (TC2) in Note [Trimming the continuation for bottoming functions]
    
    2450
    +  = rebuild env (argInfoExpr fun rev_args) (mkBottomCont cont)
    
    2465 2451
     
    
    2466 2452
     ---------- Simplify type applications --------------
    
    2467 2453
     rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont })
    
    ... ... @@ -4045,6 +4031,41 @@ When we have
    4045 4031
     then we can just duplicate those alts because the A and C cases
    
    4046 4032
     will disappear immediately.  This is more direct than creating
    
    4047 4033
     join points and inlining them away.  See #4930.
    
    4034
    +
    
    4035
    +Note [Trimming the continuation for bottoming functions]
    
    4036
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    4037
    +Suppose
    
    4038
    +   f :: Int -> Int -> Int
    
    4039
    +   f x = error "urk"
    
    4040
    +
    
    4041
    +   foo = f 3 4
    
    4042
    +
    
    4043
    +f's demand signature say "after one arg I return bottom".  We can drop
    
    4044
    +the remaining arguments, thus
    
    4045
    +
    
    4046
    +   foo = case f 3 of {}
    
    4047
    +
    
    4048
    +This trimming can also be done with other continuations:
    
    4049
    +   * case (error "hello") of { ... }
    
    4050
    +   * f (error "Hello") where f is strict
    
    4051
    +   etc
    
    4052
    +
    
    4053
    +We implement the trimming in three parts:
    
    4054
    +
    
    4055
    +(TC1) In `mkArgInfo`, for a bottoming function, we make a list of `RemainingArgDmds`
    
    4056
    +  with a finite list of elements (in the example above, just one).
    
    4057
    +
    
    4058
    +  For comparison, note that, for non-bottoming functions, the `RemainingArgDmds`
    
    4059
    +  always finishes with an infinite list of `topDmd`.
    
    4060
    +
    
    4061
    +(TC2) In `rebuildCall`, when we run out of `RemainingArgDmds` we discard the
    
    4062
    +  remaining continuation.
    
    4063
    +
    
    4064
    +  After discarding the continuation, the types might not match, in which case
    
    4065
    +  we leave behind a (case <hole> of {}) wrapper.  See the call to `mkBottomCont`.
    
    4066
    +
    
    4067
    +(TC3) In `mkDupableContWithDmds`, we similarly discard the continuation when
    
    4068
    +  we run out of `RemainingArgDmds`.
    
    4048 4069
     -}
    
    4049 4070
     
    
    4050 4071
     --------------------
    
    ... ... @@ -4079,10 +4100,10 @@ mkDupableCont env cont
    4079 4100
       = mkDupableContWithDmds (zapSubstEnv env) (repeat topDmd) cont
    
    4080 4101
     
    
    4081 4102
     mkDupableContWithDmds
    
    4082
    -   :: SimplEnvIS  -> [Demand]  -- Demands on arguments; always infinite
    
    4103
    +   :: SimplEnvIS -> RemainingArgDmds
    
    4083 4104
        -> SimplCont -> SimplM ( SimplFloats, SimplCont)
    
    4084 4105
     
    
    4085
    -mkDupableContWithDmds env _ cont
    
    4106
    +mkDupableContWithDmds env remaining_dmds cont
    
    4086 4107
       -- Check the invariant
    
    4087 4108
       | assertPpr (checkSimplEnvIS env) (pprBadSimplEnvIS env) False
    
    4088 4109
       = pprPanic "mkDupableContWithDmds" empty
    
    ... ... @@ -4090,6 +4111,13 @@ mkDupableContWithDmds env _ cont
    4090 4111
       | contIsDupable cont
    
    4091 4112
       = return (emptyFloats env, cont)
    
    4092 4113
     
    
    4114
    +  -- No more demands => function is definitely bottom
    
    4115
    +  --                 => simply trim the continuation
    
    4116
    +  -- c.f. the null-demands case in `rebuildCall`
    
    4117
    +  -- See (TC3) in Note [Trimming the continuation for bottoming functions]
    
    4118
    +  | null remaining_dmds
    
    4119
    +  = return (emptyFloats env, mkBottomCont cont)
    
    4120
    +
    
    4093 4121
     mkDupableContWithDmds _ _ (Stop {}) = panic "mkDupableCont"     -- Handled by previous eqn
    
    4094 4122
     
    
    4095 4123
     mkDupableContWithDmds env dmds (CastIt { sc_co = co, sc_opt = opt, sc_cont = cont })
    
    ... ... @@ -4134,7 +4162,8 @@ mkDupableContWithDmds env _
    4134 4162
       , thumbsUpPlanA cont
    
    4135 4163
       = -- Use Plan A of Note [Duplicating StrictArg]
    
    4136 4164
     --    pprTrace "Using plan A" (ppr (ai_fun fun) $$ text "args" <+> ppr (ai_args fun) $$ text "cont" <+> ppr cont) $
    
    4137
    -    do { let _ :| dmds = expectNonEmpty $ ai_dmds fun
    
    4165
    +    do { let _ :| dmds = expectNonEmpty (ai_dmds fun)   -- See Invariant of StrictArg;
    
    4166
    +                                                        -- ai_dmds is never empty
    
    4138 4167
            ; (floats1, cont')  <- mkDupableContWithDmds env dmds cont
    
    4139 4168
                                   -- Use the demands from the function to add the right
    
    4140 4169
                                   -- demand info on any bindings we make for further args
    
    ... ... @@ -4180,7 +4209,10 @@ mkDupableContWithDmds env dmds
    4180 4209
             --              let a = ...arg...
    
    4181 4210
             --              in [...hole...] a
    
    4182 4211
             -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable
    
    4183
    -    do  { let dmd:|cont_dmds = expectNonEmpty dmds
    
    4212
    +    do  { let dmd:|cont_dmds =
    
    4213
    +                -- We took care to handle an empty demand list at the start,
    
    4214
    +                -- ensuring this call to 'expectNonEmpty' does not panic (#27261).
    
    4215
    +                expectNonEmpty dmds
    
    4184 4216
             ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont
    
    4185 4217
             ; let env' = env `setInScopeFromF` floats1
    
    4186 4218
             ; arg' <- simplArg env' Nothing hole_ty se arg arg_mco
    
    ... ... @@ -4251,7 +4283,7 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty
    4251 4283
            ; let arg_info = ArgInfo { ai_fun   = join_bndr
    
    4252 4284
                                     , ai_rules = [], ai_args  = []
    
    4253 4285
                                     , ai_encl  = False, ai_dmds  = repeat topDmd
    
    4254
    -                                , ai_discs = repeat 0 }
    
    4286
    +                                , ai_discs = Inf.repeat 0 }
    
    4255 4287
            ; return ( addJoinFloats (emptyFloats env) $
    
    4256 4288
                       unitJoinFloat                   $
    
    4257 4289
                       NonRec join_bndr                $
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -25,13 +25,13 @@ module GHC.Core.Opt.Simplify.Utils (
    25 25
             StaticEnv(..),
    
    26 26
             isSimplified, contIsStop,
    
    27 27
             contIsDupable, contResultType, contHoleType, contHoleScaling,
    
    28
    -        contIsTrivial, contArgs, contIsRhs,
    
    28
    +        contIsTrivial, contArgs, contIsRhs, mkBottomCont,
    
    29 29
             hasArgs, countArgs, contOutArgs, dropContArgs,
    
    30 30
             mkBoringStop, mkRhsStop, mkLazyArgStop,
    
    31 31
             interestingCallContext,
    
    32 32
     
    
    33 33
             -- ArgInfo
    
    34
    -        ArgInfo(..), ArgSpec(..), mkArgInfo,
    
    34
    +        ArgInfo(..), ArgSpec(..), RemainingArgDmds, mkArgInfo,
    
    35 35
             addValArgTo, addTyArgTo,
    
    36 36
             argInfoExpr, argSpecArg,
    
    37 37
             pushOutArgs, pushArgSpecs,
    
    ... ... @@ -54,8 +54,10 @@ import GHC.Core.Opt.Stats ( Tick(..) )
    54 54
     import qualified GHC.Core.Subst
    
    55 55
     import GHC.Core.Ppr
    
    56 56
     import GHC.Core.TyCo.Ppr ( pprParendType )
    
    57
    +import GHC.Core.TyCo.Compare ( eqTypeIgnoringMultiplicity )
    
    57 58
     import GHC.Core.FVs
    
    58 59
     import GHC.Core.Utils
    
    60
    +import GHC.Core.Make( mkWildValBinder )
    
    59 61
     import GHC.Core.Opt.Arity
    
    60 62
     import GHC.Core.Unfold
    
    61 63
     import GHC.Core.Unfold.Make
    
    ... ... @@ -75,6 +77,8 @@ import GHC.Types.Var.Set
    75 77
     import GHC.Types.Basic
    
    76 78
     import GHC.Types.Name.Env
    
    77 79
     
    
    80
    +import GHC.Data.List.Infinite ( Infinite(..) )
    
    81
    +import qualified GHC.Data.List.Infinite as Inf
    
    78 82
     import GHC.Data.OrdList ( isNilOL )
    
    79 83
     import GHC.Data.FastString ( fsLit )
    
    80 84
     
    
    ... ... @@ -205,10 +209,10 @@ data SimplCont
    205 209
     
    
    206 210
       | StrictArg           -- (StrictArg (f e1 ..en) K)[e] = K[ f e1 .. en e ]
    
    207 211
           { sc_dup :: DupFlag
    
    208
    -      , sc_fun  :: ArgInfo     -- Specifies f, e1..en, Whether f has rules, etc
    
    212
    +      , sc_fun  :: ArgInfo     -- Specifies f, e1..en, whether f has rules, etc
    
    209 213
                                    --     plus demands and discount flags for *this* arg
    
    210 214
                                    --          and further args
    
    211
    -                               --     So ai_dmds and ai_discs are never empty
    
    215
    +                               --     Invariant: ai_dmds and ai_discs are never empty
    
    212 216
           , sc_fun_ty :: OutType   -- Type of the function (f e1 .. en),
    
    213 217
                                    -- presumably (arg_ty -> res_ty)
    
    214 218
                                    -- where res_ty is expected by sc_cont
    
    ... ... @@ -348,32 +352,41 @@ doesn't matter because we'll never compute them all.
    348 352
     
    
    349 353
     data ArgInfo
    
    350 354
       = ArgInfo {
    
    351
    -        ai_fun   :: OutId,      -- The function
    
    352
    -        ai_args  :: [ArgSpec],  -- ...applied to these args (which are in *reverse* order)
    
    355
    +        ai_fun   :: OutId,      -- ^ The function
    
    356
    +        ai_args  :: [ArgSpec],  -- ^ ...applied to these args (which are in *reverse* order)
    
    353 357
                                     -- NB: all these argumennts are already simplified
    
    354 358
     
    
    355
    -        ai_rules :: [CoreRule], -- Rules for this function
    
    356
    -        ai_encl  :: Bool,       -- Flag saying whether this function
    
    357
    -                                -- or an enclosing one has rules (recursively)
    
    358
    -                                --      True => be keener to inline in all args
    
    359
    +        ai_rules :: [CoreRule], -- ^ Rules for this function
    
    360
    +        ai_encl  :: Bool,
    
    361
    +          -- ^ Flag saying whether this function or an enclosing one has rules
    
    362
    +          -- (recursively)
    
    363
    +          --
    
    364
    +          -- @True@ means: be keener to inline in all args
    
    359 365
     
    
    360
    -        ai_dmds :: [Demand],    -- Demands on remaining value arguments (beyond ai_args)
    
    361
    -                                --   Usually infinite, but if it is finite it guarantees
    
    362
    -                                --   that the function diverges after being given
    
    363
    -                                --   that number of args
    
    366
    +        ai_dmds :: RemainingArgDmds,
    
    367
    +          -- ^ Demands on remaining value arguments (beyond 'ai_args')
    
    364 368
     
    
    365
    -        ai_discs :: [Int]       -- Discounts for remaining value arguments (beyond ai_args)
    
    366
    -                                --   non-zero => be keener to inline
    
    367
    -                                --   Always infinite
    
    369
    +        ai_discs :: Infinite Int
    
    370
    +          -- ^ Discounts for remaining value arguments (beyond 'ai_args')
    
    371
    +          --
    
    372
    +          -- A non-zero value means: be keener to inline
    
    368 373
         }
    
    369 374
     
    
    370
    -data ArgSpec
    
    371
    -  = ValArg { as_dmd  :: Demand        -- Demand placed on this argument
    
    372
    -           , as_arg  :: OutExpr       -- Apply to this (coercion or value); c.f. ApplyToVal
    
    373
    -           , as_hole_ty :: OutType }  -- Type of the function (presumably t1 -> t2)
    
    375
    +-- | 'RemainingArgDmds' gives the demands on any remaining value arguments.
    
    376
    +--
    
    377
    +-- It is usually infinite (with 'topDmd's in the tail), but if it is finite it
    
    378
    +-- guarantees that the function diverges after being applied to that number
    
    379
    +-- of arguments.
    
    380
    +type RemainingArgDmds = [Demand]
    
    374 381
     
    
    375
    -  | TyArg { as_arg_ty  :: OutType     -- Apply to this type; c.f. ApplyToTy
    
    376
    -          , as_hole_ty :: OutType }   -- Type of the function (presumably forall a. blah)
    
    382
    +data ArgSpec
    
    383
    +  -- | A value argument
    
    384
    +  = ValArg { as_dmd  :: Demand        -- ^ Demand placed on this argument
    
    385
    +           , as_arg  :: OutExpr       -- ^ Apply to this (coercion or value); c.f. 'ApplyToVal'
    
    386
    +           , as_hole_ty :: OutType }  -- ^ Type of the function (presumably @t1 -> t2@ for 'ValArg' or @forall a. blah@ for 'TyArg')
    
    387
    +  -- | A type argument
    
    388
    +  | TyArg { as_arg_ty  :: OutType     -- ^ Apply to this type; c.f. 'ApplyToTy'
    
    389
    +          , as_hole_ty :: OutType }   -- ^ Type of the function (presumably @t1 -> t2@ for 'ValArg' or @forall a. blah@ for 'TyArg')
    
    377 390
     
    
    378 391
     instance Outputable ArgInfo where
    
    379 392
       ppr (ArgInfo { ai_fun = fun, ai_args = args, ai_dmds = dmds, ai_rules = rules })
    
    ... ... @@ -389,7 +402,7 @@ instance Outputable ArgSpec where
    389 402
     
    
    390 403
     addValArgTo :: ArgInfo ->  OutExpr -> OutType -> ArgInfo
    
    391 404
     addValArgTo ai arg hole_ty
    
    392
    -  | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs } <- ai
    
    405
    +  | ArgInfo { ai_dmds = dmd:dmds, ai_discs = Inf _ discs } <- ai
    
    393 406
           -- Pop the top demand and and discounts off
    
    394 407
       , let arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty, as_dmd = dmd }
    
    395 408
       = ai { ai_args    = arg_spec : ai_args ai
    
    ... ... @@ -492,12 +505,23 @@ contIsDupable (TickIt _ k) = contIsDupable k
    492 505
     contIsTrivial :: SimplCont -> Bool
    
    493 506
     contIsTrivial (Stop {})                                         = True
    
    494 507
     contIsTrivial (ApplyToTy { sc_cont = k })                       = contIsTrivial k
    
    495
    --- This one doesn't look right.  A value application is not trivial
    
    496
    --- contIsTrivial (ApplyToVal { sc_arg = Coercion _, sc_cont = k }) = contIsTrivial k
    
    497 508
     contIsTrivial (CastIt { sc_cont = k })                          = contIsTrivial k
    
    498 509
     contIsTrivial _                                                 = False
    
    499 510
     
    
    500 511
     -------------------
    
    512
    +contStop :: SimplCont -> SimplCont
    
    513
    +-- ^ Get the 'Stop' at the tail of the continuation
    
    514
    +--
    
    515
    +-- Always returns a continuation of form @(Stop ...)@.
    
    516
    +contStop stop@(Stop {})               = stop
    
    517
    +contStop (CastIt { sc_cont = k })     = contStop k
    
    518
    +contStop (StrictBind { sc_cont = k }) = contStop k
    
    519
    +contStop (StrictArg { sc_cont = k })  = contStop k
    
    520
    +contStop (Select { sc_cont = k })     = contStop k
    
    521
    +contStop (ApplyToTy  { sc_cont = k }) = contStop k
    
    522
    +contStop (ApplyToVal { sc_cont = k }) = contStop k
    
    523
    +contStop (TickIt _ k)                 = contStop k
    
    524
    +
    
    501 525
     contResultType :: SimplCont -> OutType
    
    502 526
     contResultType (Stop ty _ _)                = ty
    
    503 527
     contResultType (CastIt { sc_cont = k })     = contResultType k
    
    ... ... @@ -651,6 +675,35 @@ contEvalContext bndrs cont = go cont
    651 675
         -- Perhaps reconstruct the demand on the scrutinee by looking at field
    
    652 676
         -- and case binder dmds, see addCaseBndrDmd. No priority right now.
    
    653 677
     
    
    678
    +-------------------
    
    679
    +mkBottomCont ::SimplCont -> SimplCont
    
    680
    +-- ^ Given a continuation `cont`, return a `cont` /of the same type/,
    
    681
    +-- looking like @(case \<hole\> of {})@.
    
    682
    +--
    
    683
    +-- This is used when we are going to fill in the @<hole>@ with bottom.
    
    684
    +-- See (TC2,3) in Note [Trimming the continuation for bottoming functions]
    
    685
    +--
    
    686
    +-- Don't bother to trim, making a @case <hole> of {}@, if we have only
    
    687
    +-- an essentially-trivial continuation; e.g. @(<hole> \@ty |> co)@.
    
    688
    +mkBottomCont cont = go cont
    
    689
    +  where
    
    690
    +    go k@(Stop {})                    = k
    
    691
    +    go (TickIt t k')                  = TickIt t (go k')
    
    692
    +    go k@(CastIt    { sc_cont = k' }) = k { sc_cont = go k' }
    
    693
    +    go k@(ApplyToTy { sc_cont = k' }) = k { sc_cont = go k' }
    
    694
    +    go k@(Select { sc_alts = [], sc_cont = Stop {} }) = k  -- Optimisation only
    
    695
    +    go k | Stop res_ty _ _ <- stop_cont
    
    696
    +         , hole_ty `eqTypeIgnoringMultiplicity` res_ty
    
    697
    +         = stop_cont
    
    698
    +         | otherwise
    
    699
    +         = Select { sc_alts = []
    
    700
    +                  , sc_bndr = mkWildValBinder OneTy hole_ty
    
    701
    +                  , sc_env  = Simplified OkDup
    
    702
    +                  , sc_cont = stop_cont }
    
    703
    +         where
    
    704
    +           hole_ty   = contHoleType k
    
    705
    +           stop_cont = contStop k
    
    706
    +
    
    654 707
     -------------------
    
    655 708
     mkArgInfo :: SimplEnv -> Id -> [CoreRule] -> SimplCont -> ArgInfo
    
    656 709
     mkArgInfo env fun rules_for_fun cont
    
    ... ... @@ -672,16 +725,17 @@ mkArgInfo env fun rules_for_fun cont
    672 725
     
    
    673 726
         fun_has_rules = not (null rules_for_fun)
    
    674 727
     
    
    675
    -    vanilla_discounts, arg_discounts :: [Int]
    
    676
    -    vanilla_discounts = repeat 0
    
    728
    +    vanilla_discounts, arg_discounts :: Infinite Int
    
    729
    +    vanilla_discounts = Inf.repeat 0
    
    677 730
         arg_discounts = case idUnfolding fun of
    
    678 731
                             CoreUnfolding {uf_guidance = UnfIfGoodArgs {ug_args = discounts}}
    
    679
    -                              -> discounts ++ vanilla_discounts
    
    732
    +                              -> discounts Inf.++ vanilla_discounts
    
    680 733
                             _     -> vanilla_discounts
    
    681 734
     
    
    682
    -    vanilla_dmds, arg_dmds :: [Demand]
    
    735
    +    vanilla_dmds :: RemainingArgDmds
    
    683 736
         vanilla_dmds  = repeat topDmd
    
    684 737
     
    
    738
    +    arg_dmds :: RemainingArgDmds
    
    685 739
         arg_dmds
    
    686 740
           | not (seInline env)
    
    687 741
           = vanilla_dmds -- See Note [Do not expose strictness if sm_inline=False]
    
    ... ... @@ -689,26 +743,22 @@ mkArgInfo env fun rules_for_fun cont
    689 743
           = -- add_type_str fun_ty $
    
    690 744
             case splitDmdSig (idDmdSig fun) of
    
    691 745
               (demands, result_info)
    
    692
    -                | not (demands `lengthExceeds` n_val_args)
    
    693
    -                ->      -- Enough args, use the strictness given.
    
    694
    -                        -- For bottoming functions we used to pretend that the arg
    
    695
    -                        -- is lazy, so that we don't treat the arg as an
    
    696
    -                        -- interesting context.  This avoids substituting
    
    697
    -                        -- top-level bindings for (say) strings into
    
    698
    -                        -- calls to error.  But now we are more careful about
    
    699
    -                        -- inlining lone variables, so its ok
    
    700
    -                        -- (see GHC.Core.Op.Simplify.Utils.analyseCont)
    
    701
    -                   if isDeadEndDiv result_info then
    
    702
    -                        demands  -- Finite => result is bottom
    
    703
    -                   else
    
    704
    -                        demands ++ vanilla_dmds
    
    746
    +               | not (demands `lengthExceeds` n_val_args)
    
    747
    +               -> remaining_dmds     -- Enough args, use the strictness given.
    
    705 748
                    | otherwise
    
    706 749
                    -> warnPprTrace True "More demands than arity" (ppr fun <+> ppr (idArity fun)
    
    707 750
                                     <+> ppr n_val_args <+> ppr demands) $
    
    708 751
                       vanilla_dmds      -- Not enough args, or no strictness
    
    709 752
     
    
    710
    -    add_type_strictness :: Type -> [Demand] -> [Demand]
    
    711
    -    -- If the function arg types are strict, record that in the 'strictness bits'
    
    753
    +                where
    
    754
    +                  remaining_dmds :: RemainingArgDmds
    
    755
    +                  -- isDeadEndDiv: if remaining_dmds is finite, result is bottom
    
    756
    +                  -- See (TC1) in Note [Trimming the continuation for bottoming functions]
    
    757
    +                  remaining_dmds | isDeadEndDiv result_info = demands
    
    758
    +                                 | otherwise                = demands ++ vanilla_dmds
    
    759
    +
    
    760
    +    add_type_strictness :: Type -> RemainingArgDmds -> RemainingArgDmds
    
    761
    +    -- If the function arg /types/ are strict, record that in the RemainingArgDmds
    
    712 762
         -- No need to instantiate because unboxed types (which dominate the strict
    
    713 763
         --   types) can't instantiate type variables.
    
    714 764
         -- add_type_strictness is done repeatedly (for each call);
    
    ... ... @@ -915,16 +965,16 @@ the incentive to disappear when we inline `f`!
    915 965
     lazyArgContext :: ArgInfo -> CallCtxt
    
    916 966
     -- Use this for lazy arguments
    
    917 967
     lazyArgContext (ArgInfo { ai_encl = encl_rules, ai_discs = discs })
    
    918
    -  | encl_rules                = RuleArgCtxt
    
    919
    -  | disc:_ <- discs, disc > 0 = DiscArgCtxt  -- Be keener here
    
    920
    -  | otherwise                 = BoringCtxt   -- Nothing interesting
    
    968
    +  | encl_rules                    = RuleArgCtxt
    
    969
    +  | Inf disc _ <- discs, disc > 0 = DiscArgCtxt  -- Be keener here
    
    970
    +  | otherwise                     = BoringCtxt   -- Nothing interesting
    
    921 971
     
    
    922 972
     strictArgContext :: ArgInfo -> CallCtxt
    
    923 973
     strictArgContext (ArgInfo { ai_encl = encl_rules, ai_discs = discs })
    
    924 974
     -- Use this for strict arguments
    
    925
    -  | encl_rules                = RuleArgCtxt
    
    926
    -  | disc:_ <- discs, disc > 0 = DiscArgCtxt  -- Be keener here
    
    927
    -  | otherwise                 = RhsCtxt NonRecursive
    
    975
    +  | encl_rules                    = RuleArgCtxt
    
    976
    +  | Inf disc _ <- discs, disc > 0 = DiscArgCtxt  -- Be keener here
    
    977
    +  | otherwise                     = RhsCtxt NonRecursive
    
    928 978
           -- Why RhsCtxt?  if we see f (g x), and f is strict, we
    
    929 979
           -- want to be a bit more eager to inline g, because it may
    
    930 980
           -- expose an eval (on x perhaps) that can be eliminated or
    

  • testsuite/tests/simplCore/should_compile/T27261.hs
    1
    +{-# OPTIONS_GHC -fno-full-laziness #-}
    
    2
    +
    
    3
    +module T27261 (foo) where
    
    4
    +
    
    5
    +import T27261_aux (myError)
    
    6
    +
    
    7
    +foo :: [String] -> (() -> Int) -> Int
    
    8
    +foo cs =
    
    9
    +  \ k -> ( case bar of
    
    10
    +             Just str -> let cs2 = case cs of { [] -> cs; _ -> "stack entry" : cs }
    
    11
    +                         in myError cs2 str
    
    12
    +             Nothing -> \ c -> c () )
    
    13
    +         ( \ _ -> k () )
    
    14
    +
    
    15
    +bar :: Maybe String
    
    16
    +bar = Nothing
    
    17
    +{-# NOINLINE bar #-}

  • testsuite/tests/simplCore/should_compile/T27261_aux.hs
    1
    +{-# LANGUAGE BangPatterns #-}
    
    2
    +
    
    3
    +module T27261_aux (myError) where
    
    4
    +
    
    5
    +myError :: [String] -> String -> a
    
    6
    +myError !_ _ = undefined
    
    7
    +{-# NOINLINE myError #-}

  • testsuite/tests/simplCore/should_compile/all.T
    ... ... @@ -601,3 +601,4 @@ test('T25718a', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress
    601 601
     test('T25718b', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all -dno-typeable-binds'])
    
    602 602
     test('T25718c', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all -dno-typeable-binds'])
    
    603 603
     test('T19166', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all -dno-typeable-binds'])
    
    604
    +test('T27261', [extra_files(['T27261_aux.hs'])], multimod_compile, ['T27261', '-v0 -O'])