[GHC] #10595: BuiltinRules override other rules in some cases.

GHC ghc-devs at haskell.org
Tue Jul 7 04:21:36 UTC 2015


#10595: BuiltinRules override other rules in some cases.
-------------------------------------+-------------------------------------
        Reporter:  gjsimms           |                   Owner:
            Type:  bug               |                  Status:  new
        Priority:  high              |               Milestone:
       Component:  Compiler          |                 Version:  7.11
      Resolution:                    |                Keywords:
Operating System:  Unknown/Multiple  |            Architecture:
 Type of failure:  None/Unknown      |  Unknown/Multiple
      Blocked By:                    |               Test Case:
 Related Tickets:                    |                Blocking:
                                     |  Differential Revisions:
-------------------------------------+-------------------------------------
Changes (by gjsimms):

 * version:  7.10.1 => 7.11


Comment:

 Tested this occurs in HEAD on my machine.

 I think I have determined why this occurs, I don't see an easy fix
 offhand. If this is an know issue or if it is not a priority feel free to
 change the priority/close.

 Evaluation of rewrite rules seems to work up the syntax tree (lower leafs
 will be rewritten before the final expressions).

 So given a BuiltinRule for exp (exp -> exp???)
 and the Rule (f . exp -> exp) for some fixed f.

 Processing
 1) f . exp
 2) (.) f exp
 Rewrite branches, f has no rule.
 3) (.) f exp???
 Done, no more rewrites possible.


 Some code which I believe demonstrates this correctly. (compile with
 rewrite rules active)
 {{{
 class A a where
     ida :: a -> a
     idb :: a -> a

 class B a where
     idB :: a -> a


 instance A Bool where
     ida _ = False
     idb _ = True

 instance B Bool where
     idB False = True
     idB True = False

 {-# NOINLINE ida' #-}
 ida' :: A a => a -> a
 ida' = ida

 {-# NOINLINE idb' #-}
 idb' :: A a => a -> a
 idb' = idb

 {-# RULES
 "SuccessB" forall f. idB (idB f) = idB f
 "Failure1" forall f. ida (ida f) = idb f
 "Failure2" forall f. ida' (ida f) = idb f
 "Success1" forall f. ida (ida' f) = idb f
 "Success2" forall f. ida' (ida' f) = idb' f #-}

 main = do
   print (ida (ida True))  -- FAIL should print True >> prints False
   print (ida' (ida True)) -- FAIL should print True >> prints False
   print (ida' (ida' True))  -- PASS should print True
   print (ida (ida' True)) -- PASS should print TRUE
   print (idB (idB False))  -- PASS should print True (INLINING may make
 this run specific it seems consistent on my machine though)
 }}}

 I would appreciate someone more knowledgeable than me checking this out...
 I have tried forcing BuiltinRules activation on the last step only --
 infinite loop in the rewriter during tests (fixes the issue for simple
 cases).

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10595#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list