Fix hs-boot knot-tying with record wild cards.
authorEdward Z. Yang <ezyang@cs.stanford.edu>
Fri, 28 Jul 2017 22:25:12 +0000 (18:25 -0400)
committerBen Gamari <ben@smart-cactus.org>
Fri, 28 Jul 2017 22:25:13 +0000 (18:25 -0400)
Fixes #13710.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
Test Plan: validate

Reviewers: bgamari, austin, simonpj

Reviewed By: simonpj

Subscribers: simonpj, rwbarton, thomie

GHC Trac Issues: #13710

Differential Revision: https://phabricator.haskell.org/D3743

compiler/iface/TcIface.hs
testsuite/tests/driver/T13710/A.hs [new file with mode: 0644]
testsuite/tests/driver/T13710/A.hs-boot [new file with mode: 0644]
testsuite/tests/driver/T13710/B.hs [new file with mode: 0644]
testsuite/tests/driver/T13710/Makefile [new file with mode: 0644]
testsuite/tests/driver/T13710/T13710.stdout [new file with mode: 0644]
testsuite/tests/driver/T13710/all.T [new file with mode: 0644]

index b3119b2..9e06165 100644 (file)
@@ -915,7 +915,14 @@ tcIfaceDataCons tycon_name tycon tc_tybinders if_cons
         ; ~(eq_spec, theta, arg_tys, stricts) <- forkM (mk_doc dc_name) $
              do { eq_spec <- tcIfaceEqSpec spec
                 ; theta   <- tcIfaceCtxt ctxt
         ; ~(eq_spec, theta, arg_tys, stricts) <- forkM (mk_doc dc_name) $
              do { eq_spec <- tcIfaceEqSpec spec
                 ; theta   <- tcIfaceCtxt ctxt
-                ; arg_tys <- mapM tcIfaceType args
+                -- This fixes #13710.  The enclosing lazy thunk gets
+                -- forced when typechecking record wildcard pattern
+                -- matching (it's not completely clear why this
+                -- tuple is needed), which causes trouble if one of
+                -- the argument types was recursively defined.
+                -- See also Note [Tying the knot]
+                ; arg_tys <- forkM (mk_doc dc_name <+> text "arg_tys")
+                           $ mapM tcIfaceType args
                 ; stricts <- mapM tc_strict if_stricts
                         -- The IfBang field can mention
                         -- the type itself; hence inside forkM
                 ; stricts <- mapM tc_strict if_stricts
                         -- The IfBang field can mention
                         -- the type itself; hence inside forkM
diff --git a/testsuite/tests/driver/T13710/A.hs b/testsuite/tests/driver/T13710/A.hs
new file mode 100644 (file)
index 0000000..5181945
--- /dev/null
@@ -0,0 +1,5 @@
+{-# LANGUAGE RecordWildCards #-}
+module A where
+import B
+data E = MkE
+p (H{..}) = ()
diff --git a/testsuite/tests/driver/T13710/A.hs-boot b/testsuite/tests/driver/T13710/A.hs-boot
new file mode 100644 (file)
index 0000000..94a2f5e
--- /dev/null
@@ -0,0 +1,2 @@
+module A ( E ) where
+data E
diff --git a/testsuite/tests/driver/T13710/B.hs b/testsuite/tests/driver/T13710/B.hs
new file mode 100644 (file)
index 0000000..87c93a9
--- /dev/null
@@ -0,0 +1,3 @@
+module B where
+import {-# SOURCE #-} A
+data H = H { h :: E }
diff --git a/testsuite/tests/driver/T13710/Makefile b/testsuite/tests/driver/T13710/Makefile
new file mode 100644 (file)
index 0000000..d582f94
--- /dev/null
@@ -0,0 +1,6 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+T13710:
+       '$(TEST_HC)' $(TEST_HC_OPTS) --make B.hs
diff --git a/testsuite/tests/driver/T13710/T13710.stdout b/testsuite/tests/driver/T13710/T13710.stdout
new file mode 100644 (file)
index 0000000..2d72928
--- /dev/null
@@ -0,0 +1,3 @@
+[1 of 3] Compiling A[boot]          ( A.hs-boot, A.o-boot )
+[2 of 3] Compiling B                ( B.hs, B.o )
+[3 of 3] Compiling A                ( A.hs, A.o )
diff --git a/testsuite/tests/driver/T13710/all.T b/testsuite/tests/driver/T13710/all.T
new file mode 100644 (file)
index 0000000..64daacc
--- /dev/null
@@ -0,0 +1,4 @@
+test('T13710',
+     [extra_files(['A.hs', 'A.hs-boot', 'B.hs'])],
+     run_command,
+     ['$MAKE -s --no-print-directory T13710'])