INLINEABLE function fails to specialize.
Summary
Staged INLINABLE
pragmas don't seem to actually allow specialization.
Steps to reproduce
{-# language LambdaCase, Strict, DeriveFunctor, DerivingStrategies #-}
module Altery where
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
foo :: Either Int Char -> Map (Either Int Char) v -> Maybe (v, (Map (Either Int Char) v))
foo x subst = case Map.alterF (\case {Nothing -> NotFound; Just t -> Found t Nothing}) x subst of
NotFound -> foo (fmap (toEnum . (+1) . fromEnum) x) subst
Found p q -> Just (p, q)
data CheckRes a m = NotFound | Found !a ~m
deriving stock Functor
Compile this with -O2 -ddump-simpl
. The interesting parts:
Altery.$wfoo [InlPrag=[2]]
:: forall {v}.
Either Int Char
-> Map (Either Int Char) v -> (# v, Map (Either Int Char) v #)
[GblId[StrictWorker([!, !])],
Arity=2,
Str=<SL><SL>,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [60 0] 222 10}]
Altery.$wfoo
= \ (@v_s1kj)
(x_s1kk :: Either Int Char)
(subst_s1kl :: Map (Either Int Char) v_s1kj) ->
case Map.alterF
@(CheckRes v_s1kj)
@(Either Int Char)
@v_s1kj
(Altery.$fFunctorCheckRes @v_s1kj)
Altery.foo2
(Altery.foo1 @v_s1kj)
x_s1kk
subst_s1kl
of {
NotFound ->
case x_s1kk of {
Left x1_a1j5 -> Altery.foo_$s$wfoo1 @v_s1kj x1_a1j5 subst_s1kl;
Right y_a1j7 ->
Altery.foo_$s$wfoo
@v_s1kj
(case y_a1j7 of { GHC.Types.C# c#_a1jA ->
let {
i#_s1jT :: GHC.Prim.Int#
[LclId]
i#_s1jT = GHC.Prim.+# (GHC.Prim.ord# c#_a1jA) 1# } in
case GHC.Prim.leWord# (GHC.Prim.int2Word# i#_s1jT) 1114111## of {
__DEFAULT -> GHC.Char.$wlvl i#_s1jT;
1# -> GHC.Types.C# (GHC.Prim.chr# i#_s1jT)
}
})
subst_s1kl
};
Found p_aQ7 q_aQ8 -> (# p_aQ7, q_aQ8 #)
}
foo [InlPrag=[2]]
:: forall v.
Either Int Char
-> Map (Either Int Char) v -> Maybe (v, Map (Either Int Char) v)
[GblId,
Arity=2,
Str=<SL><SL>,
Cpr=2(1),
Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False)
Tmpl= \ (@v_s1kj)
(x_s1kk [Occ=Once1] :: Either Int Char)
(subst_s1kl [Occ=Once1] :: Map (Either Int Char) v_s1kj) ->
case Altery.$wfoo @v_s1kj x_s1kk subst_s1kl of
{ (# ww_s1ks [Occ=Once1], ww1_s1kt [Occ=Once1] #) ->
GHC.Maybe.Just
@(v_s1kj, Map (Either Int Char) v_s1kj) (ww_s1ks, ww1_s1kt)
}}]
foo
= \ (@v_s1kj)
(x_s1kk :: Either Int Char)
(subst_s1kl :: Map (Either Int Char) v_s1kj) ->
case Altery.$wfoo @v_s1kj x_s1kk subst_s1kl of
{ (# ww_s1ks, ww1_s1kt #) ->
GHC.Maybe.Just
@(v_s1kj, Map (Either Int Char) v_s1kj) (ww_s1ks, ww1_s1kt)
}
The compiled foo
(not just its unfolding) calls $wfoo
, which calls unspecialized alterF
. That's awful! alterF
is defined as INLINABLE [2]
because there are rewrite rules attached to it.
Environment
- GHC version used: 9.4.3
Optional:
- Operating System:
- System Architecture: