id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	os	architecture	failure	difficulty	testcase	blockedby	blocking	related
3027	Specialisation rules fail because dictionary projections do not match	malcolm.wallace@…		"Here is an apparent bug in ghc's specialisation rules.  The rewrite rule
generated by a SPECIALISE pragma seems to want to pattern-match on exact
dictionaries (as well as types).  But the compiler is not necessarily
able to fully resolve dictionaries before the rules are supposed to
fire.

First, the source code we want to specialise:
{{{
    {-# SPECIALISE
        hedgehog :: Float -> Vector3 Float
                          -> [Cell_8 (Coord3 Float)]
                          -> [Cell_8 (Vector3 Float)]
                          -> [(Coord3 Float, Coord3 Float)]
      #-}
    hedgehog  :: ( Fractional a, Cell cell vert, Eq vert
                 , Geom coord, Geom vector, Embed vector coord ) =>
                 a -> vector a
                   -> [cell (coord a)]
                   -> [cell (vector a)]
                   -> [(coord a, coord a)]
}}}

The core + interface generated for this module contains the rule:
{{{
 ""SPEC Hedgehog.hedgehog"" ALWAYS forall
  Hedgehog.hedgehog @ GHC.Float.Float
                    @ RectGrid.Cell_8
                    @ RectGrid.MyVertex
                    @ Geometries.Coord3
                    @ Geometries.Vector3
                    GHC.Float.$f16
                    RectGrid.$f2
                    RectGrid.$f10
                    Geometries.$f5
                    Geometries.$f3
                    Geometries.$f1
}}}

But in a different module (Viewer.hs), here is what the usage site looks like just
before the specialisation rules are supposed to fire:
{{{
hedgehog_aWr =
  Hedgehog.hedgehog
    @ GHC.Float.Float
    @ RectGrid.Cell_8
    @ RectGrid.MyVertex
    @ Geometries.Coord3
    @ Geometries.Vector3
    GHC.Float.$f16
    RectGrid.$f2
    RectGrid.$f10
    (Dataset.$p2Embed @ Geometries.Vector3 @ Geometries.Coord3 Geometries.$f1)
    (Dataset.$p1Embed @ Geometries.Vector3 @ Geometries.Coord3 Geometries.$f1)
    Geometries.$f1
}}}

Notice how there are a couple of dictionary projection functions still sitting
there, so although some of the dictionaries match, not all do, and the
rule does not fire.  However, later the worker-wrapper transformation
is able to resolve those outstanding dictionaries, giving eventually:
{{{
hedgehog_r2at =
  Hedgehog.$whedgehog
    @ GHC.Float.Float
    @ RectGrid.Cell_8
    @ RectGrid.MyVertex
    @ Geometries.Coord3
    @ Geometries.Vector3
    GHC.Float.$f16
    RectGrid.$f2
    Geometries.$f5
    Geometries.$f3
    Geometries.$f1
}}}

So I'm left calling the worker for the polymorphic version of the
function, rather than the specialised monomorphic code I wanted.  Given
how many dictionaries are involved, and that this is the inner loop of
the program, I'm hoping there is a big performance win waiting for me,
if only I can get that specialised code to run!

A code archive is attached, to help you reproduce the behaviour.
I have cut down the code considerably already, but it is still spread
over 5 modules: I was unable to cut it down much further without
the bug disappearing (probably through inlining or something).

Classes are defined in Dataset.hs, instances in Geometries.hs.
The code I want to specialise is in Hedgehog.hs, and the usage site
is in Viewer.hs (the main program)."	bug	closed	normal	_|_	Compiler	6.8.2	fixed			Unknown/Multiple	Unknown/Multiple		Unknown				
