Here is a minimal example reproducing the real problem I'm working on:
One library module:
module Lib where class H h where hash :: (S s)=> s -> h -> s class S s where mix :: s -> Int -> s instance (H x, H y)=> H (x,y) where hash s = \(x,y) -> s `hash` x `hash` y -- make this look "big": `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y `hash` x `hash` y instance H Int where hash s = \n -> s `mix` n 
Another, possibly user defined:
 module S where import Lib newtype Foo = Foo Int deriving Show instance S Foo where mix (Foo x) y = Foo (x+y) 
And our Main :
 module Main where import Lib import S import Criterion.Main main = defaultMain [ bench "foo" $ whnf (hash (Foo 1)) (2::Int,3::Int) ] 
Compiling with ghc 8.0.1 with ghc --make -Wall -O2 -rtsopts -ddump-to-file -ddump-simpl -dsuppress-module-prefixes -dsuppress-uniques -ddump-core-stats -ddump-inlinings -fforce-recomp Main.hs
In this test, above 4 μs . If, however, we put INLINE pragmas on two hash declarations in Lib , we will see the required specializations and get a 66 ns runtime.
But I really do not want to embed everything (in the real user Main she can call hash the same type many times), I just need a function specialized for each combination of H and S in the user code.
Changing INLINE pragmas to INLINABLE caused a regression of the old behavior (as I believe, since the GHC inlining heuristic is still in the game). Then I tried to add
 {- 
for modules Main and S , but this generates
 Ignoring useless SPECIALISE pragma for class method selector 'hash' 
... warnings and the same bad code.
Some limitations:
- It would be acceptable, although not ideal, to require that every instance declaration of 
S include a finite number of pragmas (possibly related to H ) - similar for 
H - it is not acceptable to require users to do 
SPECIALIZE for each combination of S and H 
Is it possible to do this without INLINE?
This is probably the same as the Restricted Specialization and the associated truck ticket https://ghc.haskell.org/trac/ghc/ticket/8668 , but I thought I would ask again and maybe post it as simpler example for GHC Trac.
EDIT : went ahead and opened a ghc ticket: https://ghc.haskell.org/trac/ghc/ticket/13376