Skip to content
  • Sebastian Graf's avatar
    WorkWrap: Unbox constructors with existentials (#18982) · f0ec06c7
    Sebastian Graf authored and Marge Bot's avatar Marge Bot committed
    Consider
    
    ```hs
    data Ex where
      Ex :: e -> Int -> Ex
    
    f :: Ex -> Int
    f (Ex e n) = e `seq` n + 1
    ```
    
    Worker/wrapper should build the following worker for `f`:
    
    ```hs
    $wf :: forall e. e -> Int# -> Int#
    $wf e n = e `seq` n +# 1#
    ```
    
    But previously it didn't, because `Ex` binds an existential.
    This patch lifts that condition. That entailed having to instantiate
    existential binders in `GHC.Core.Opt.WorkWrap.Utils.mkWWstr` via
    `GHC.Core.Utils.dataConRepFSInstPat`, requiring a bit of a refactoring
    around what is now `DataConPatContext`.
    
    CPR W/W still won't unbox DataCons with existentials.
    See `Note [Which types are unboxed?]` for details.
    
    I also refactored the various `tyCon*DataCon(s)_maybe` functions in
    `GHC.Core.TyCon`, deleting some of them which are no longer needed
    (`isDataProductType_maybe` and `isDataSumType_maybe`).
    I cleaned up a couple of call sites, some of which weren't very explicit
    about whether they cared for existentials or not.
    
    The test output of `T18013` changed, because we now unbox the `Rule`
    data type. Its constructor carries existential state and will be
    w/w'd now. In the particular example, the worker functions inlines right
    back into the wrapper, which then unnecessarily has a (quite big) stable
    unfolding. I think this kind of fallout is inevitable;
    see also Note [Don't w/w inline small non-loop-breaker things].
    
    There's a new regression test case `T18982`.
    Fixes #18982.
    f0ec06c7