summaryrefslogtreecommitdiff
path: root/testsuite/tests/cpranal/sigs/RecDataConCPR.hs
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/tests/cpranal/sigs/RecDataConCPR.hs')
-rw-r--r--testsuite/tests/cpranal/sigs/RecDataConCPR.hs117
1 files changed, 117 insertions, 0 deletions
diff --git a/testsuite/tests/cpranal/sigs/RecDataConCPR.hs b/testsuite/tests/cpranal/sigs/RecDataConCPR.hs
new file mode 100644
index 0000000000..c26ae1264f
--- /dev/null
+++ b/testsuite/tests/cpranal/sigs/RecDataConCPR.hs
@@ -0,0 +1,117 @@
+{-# OPTIONS_GHC -O2 -fforce-recomp #-}
+{-# LANGUAGE TypeFamilies #-}
+
+-- | Serves as a unit test for isRecDataCon.
+-- See Note [CPR for recursive data constructors] for similar examples.
+module RecDataConCPR where
+
+import Control.Monad.Trans.State
+import Control.Monad.ST
+import Data.Char
+
+import {-# SOURCE #-} RecDataConCPRa
+
+replicateOne :: Int -> [Int]
+replicateOne 1 = [1]
+replicateOne n = 1 : replicateOne (n-1)
+
+data T = T (Int, (Bool, Char)) -- NonRec
+t :: Char -> Bool -> Int -> T
+t a b c = T (c, (b, a))
+
+data U = U [Int] -- NonRec
+
+u :: Int -> U
+u x = U (replicate x 1000)
+
+data U2 = U2 [U2] -- Rec
+
+u2 :: Int -> U2
+u2 x = U2 (replicate 1000 (u2 (x-1)))
+
+data R0 = R0 R1 | R0End Int -- Rec, but out of fuel (and thus considered NonRec)
+data R1 = R1 R2
+data R2 = R2 R3
+data R3 = R3 R4
+data R4 = R4 R5
+data R5 = R5 R6
+data R6 = R6 R7
+data R7 = R7 R8
+data R8 = R8 R9
+data R9 = R9 R0
+
+r :: Bool -> Int -> R0
+r False x = r True x
+r True x = R0 (R1 (R2 (R3 (R4 (R5 (R6 (R7 (R8 (R9 (R0End x))))))))))
+
+data R20 = R20 R21 | R20End Int -- Rec
+data R21 = R21 R20
+
+r2 :: Bool -> Int -> R20
+r2 False x = r2 True x
+r2 True x = R20 (R21 (R20End 4))
+
+newtype Fix f = Fix (f (Fix f)) -- Rec
+
+fixx :: Int -> Fix Maybe
+fixx 0 = Fix Nothing
+fixx n = Fix (Just (fixx (n-1)))
+
+data N = N (Fix (Either Int)) -- NonRec
+data M = M (Fix (Either M)) -- Rec
+
+n :: Int -> N
+n = N . go
+ where
+ go 0 = Fix (Left 42)
+ go n = Fix (Right (go (n-1)))
+
+m :: Int -> M
+m = M . go
+ where
+ go 0 = Fix (Left (m 42))
+ go n = Fix (Right (go (n-1)))
+
+data F = F (F -> Int) -- NonRec
+f :: Int -> F
+f n = F (const n)
+
+data G = G (Int -> G) -- NonRec
+g :: Int -> G
+g n = G (\m -> g (n+m))
+
+newtype MyM s a = MyM (StateT Int (ST s) a) -- NonRec
+myM :: Int -> MyM s Int
+myM 0 = MyM $ pure 42
+myM n = myM (n-1)
+
+type S = (Int, Bool) -- NonRec
+s :: Int -> S
+s n = (n, True)
+
+type family E a
+type instance E Int = Char
+type instance E (a,b) = (E a, E b)
+type instance E Char = Blub
+data Blah = Blah (E (Int, (Int, Int))) -- NonRec
+data Blub = Blub (E (Char, Int)) -- Rec
+data Blub2 = Blub2 (E (Bool, Int)) -- Rec, because stuck
+
+blah :: Int -> Blah
+blah n = Blah (chr n, (chr (n+1), chr (n+2)))
+
+blub :: Int -> Blub
+blub n = Blub (blub (n-1), chr n)
+
+blub2 :: Int -> Blub2
+blub2 n = Blub2 (undefined :: E Bool, chr n)
+
+-- Now for abstract TyCons, point (7) of the Note:
+data BootNonRec1 = BootNonRec1 BootNonRec2 -- in RecDataConCPRa.hs-boot
+data BootRec1 = BootRec1 BootRec2 -- in RecDataConCPRa.hs-boot, recurses back
+
+bootNonRec :: Int -> BootNonRec2 -> BootNonRec1 -- Nothing, thus like NonRec
+bootNonRec x b2 = BootNonRec1 b2
+
+bootRec :: Int -> BootRec2 -> BootRec1 -- Nothing, thus like NonRec
+bootRec x b2 = BootRec1 b2