Skip to content

Filter out nontrivial substituted expressions in substTickish

Torsten Schmits requested to merge wip/torsten.schmits/23272 into master

Fixes #23272 (closed)

As far as I can tell, the panic originates in lvlExpr. I can't tell what actually happens there.

f in the test case is specialized to the C () dict:

bug :: (forall a. C a => a -> a) -> ()
[LclIdX,
 Arity=1,
 Unf=Unf{Src=<vanilla>, TopLvl=True,
         Value=True, ConLike=True, WorkFree=True, Expandable=True,
         Guidance=IF_ARGS [180] 170 0}]
bug
  = \ (g_a5U :: forall a. C a => a -> a) ->
      let {
        $sf_scs :: forall {b}. () -> b
        [LclId,
         Arity=1,
         Unf=Unf{Src=<vanilla>, TopLvl=False,
                 Value=True, ConLike=True, WorkFree=True, Expandable=True,
                 Guidance=IF_ARGS [0] 40 0}]
        $sf_scs
          = \ (@b_a82) (x_a5W :: ()) ->
              break<1>(g_a5U,x_a5W)
              case break<0>(g_a5U,x_a5W) g_a5U @() T23272.$fCTYPEUnit x_a5W of
              { () ->
              lvl_scJ @b_a82
              } } in
      let {
        f_sco :: forall {a} {b}. C a => a -> b
        [LclId,
         Arity=2,
         Unf=Unf{Src=<vanilla>, TopLvl=False,
                 Value=True, ConLike=True, WorkFree=True, Expandable=True,
                 Guidance=IF_ARGS [0 0] 40 0},
         RULES: "SPEC f @() @_"
                    forall (@b_a82) ($dC_scp :: C ()).
                      f_sco @() @b_a82 $dC_scp
                      = $sf_scs @b_a82]
        f_sco
          = \ (@a_a81) (@b_a82) ($dC_aah :: C a_a81) (x_a5W :: a_a81) ->
              break<1>(g_a5U,x_a5W)
              case break<0>(g_a5U,x_a5W) g_a5U @a_a81 $dC_aah x_a5W of
              { __DEFAULT ->
              lvl_sd0 @b_a82
              } } in
      break<2>(f_sco)
      break<1>(g_a5U,GHC.Tuple.Prim.())
      case break<0>(g_a5U,GHC.Tuple.Prim.())
           g_a5U @() T23272.$fCTYPEUnit GHC.Tuple.Prim.()
      of
      { () ->
      lvl_scJ @()
      }

and $sf_scs becomes a poly binder, which appears to fail the isRuntimeArg test in getIdFromTrivialExpr_maybe. Unclear what this means.

If this specialization is valid, then my naive assumption would be that it should be acceptable that breakpoint FVs may be substituted with nontrivial Ids and filtering them out is fine.

In Specialise, the same thing is done with the justification:

  -- drop vars from the list if they have a non-variable substitution.
  -- should never happen, but it's harmless to drop them anyway.

So the question is whether "should never happen" is accurate here. Note [substTickish] is not very helpful, referring to NoOccInfo as a guard against this, which doesn't exist anymore.

Work sponsored by Tweag

Edited by Torsten Schmits

Merge request reports