summaryrefslogtreecommitdiff
path: root/testsuite/tests/simplCore/should_compile/T7796.hs
blob: 6d6c82433252385e348f32203ecdb1a20a202764 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
{-# LANGUAGE MagicHash #-}

module T7796 where

import GHC.Exts

--
-- test for #7796
--
-- created by nicolas.frisby@gmail.com, feel free to email me!
--
-- a delicate interaction between specialisation and w/w creates a
-- binding that is dead but is allocated at run-time
--

--
-- we grep the -ddump-prep for $s$go, and the actual test expects a
-- particular number of hits
--
-- thus the test will fail in two scenarios:
--
--   * the actually interesting case where the zombie $s$go binding
--     survives, or
--
--   * the naming convention for specialised things changes, in which
--     case the Makefile rule for this test needs to be updated to
--     scrape the -ddump-prep output differently
--

--
-- the zombie binding is $sgo; here's how we reproduce it:
--
--   1. specialise go such that the RHS of $sgo uses both $sgo and go
--
--   2. worker-wrapper $sgo but *not* go
--
-- thus: $sgo uses $w$sgo uses go uses $sgo
--
-- the key point: the last "use" is only via a RULE; see the ticket
-- #7796 for more discussion and related tickets
--

data L = C Int# L | N Int# -- I'm using unboxed elements to avoid ww'd
                           -- unrelated to the bug

host :: Eq b => b -> L -> Bool
host b x =
  let go :: Eq a =>  -- must be used (to trigger specialise), but not
                     -- strict (else we ww the unspecialised version)

            a ->     -- must be strict, so that we ww the
                     -- specialisation

            L ->     -- not sure what this needs... but strict is
                     -- doing the trick

            Bool

      go d (N i) = d `seq` case i of
        0# -> True
        o  -> go b (N (i -# 1#)) -- NB must at (a ~ b)

      go d (C x xs) = (d == d) `seq` go d (C (x -# 1#) xs)
  in go (3 :: Int) x