Load orphan interfaces before checking if module implements signature
authorEdward Z. Yang <ezyang@cs.stanford.edu>
Wed, 14 Dec 2016 02:03:47 +0000 (18:03 -0800)
committerEdward Z. Yang <ezyang@cs.stanford.edu>
Wed, 14 Dec 2016 03:00:54 +0000 (19:00 -0800)
Summary:
If we didn't load the orphans, we might conclude an instance
is not implemented when it is.  See test bkp42.

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

Reviewers: simonpj, austin, bgamari

Subscribers: thomie

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

compiler/typecheck/TcBackpack.hs
testsuite/tests/backpack/should_compile/all.T
testsuite/tests/backpack/should_compile/bkp42.bkp [new file with mode: 0644]
testsuite/tests/backpack/should_compile/bkp42.stderr [new file with mode: 0644]

index b6623cd..1cf3393 100644 (file)
@@ -549,6 +549,11 @@ checkImplements impl_mod (IndefModule uid mod_name) = do
                     (gresFromAvails Nothing (mi_exports impl_iface))
         nsubst = mkNameShape (moduleName impl_mod) (mi_exports impl_iface)
 
+    -- Load all the orphans, so the subsequent 'checkHsigIface' sees
+    -- all the instances it needs to
+    loadModuleInterfaces (text "Loading orphan modules (from implementor of hsig)")
+                         (dep_orphs (mi_deps impl_iface))
+
     dflags <- getDynFlags
     let avails = calculateAvails dflags
                     impl_iface False{- safe -} False{- boot -}
index 1f0136f..bb77278 100644 (file)
@@ -33,3 +33,4 @@ test('bkp38', normal, backpack_compile, [''])
 test('bkp39', normal, backpack_compile, [''])
 test('bkp40', normal, backpack_compile, [''])
 test('bkp41', normal, backpack_compile, [''])
+test('bkp42', normal, backpack_compile, [''])
diff --git a/testsuite/tests/backpack/should_compile/bkp42.bkp b/testsuite/tests/backpack/should_compile/bkp42.bkp
new file mode 100644 (file)
index 0000000..59590f9
--- /dev/null
@@ -0,0 +1,21 @@
+unit impl where
+    module A where
+        data T = T
+    module B(module A, module B) where
+        import A
+        instance Show T where
+            show T = "T"
+    module C(module B) where
+        import B
+
+unit sig where
+    signature B where
+        data T
+        instance Show T
+    module App where
+        import B
+        app :: T -> IO ()
+        app t = print t
+
+unit main where
+    dependency sig[B=impl:C]
diff --git a/testsuite/tests/backpack/should_compile/bkp42.stderr b/testsuite/tests/backpack/should_compile/bkp42.stderr
new file mode 100644 (file)
index 0000000..69d8d7c
--- /dev/null
@@ -0,0 +1,14 @@
+[1 of 3] Processing impl
+  Instantiating impl
+  [1 of 3] Compiling A                ( impl/A.hs, bkp42.out/impl/A.o )
+  [2 of 3] Compiling B                ( impl/B.hs, bkp42.out/impl/B.o )
+  [3 of 3] Compiling C                ( impl/C.hs, bkp42.out/impl/C.o )
+[2 of 3] Processing sig
+  [1 of 2] Compiling B[sig]           ( sig/B.hsig, nothing )
+  [2 of 2] Compiling App              ( sig/App.hs, nothing )
+[3 of 3] Processing main
+  Instantiating main
+  [1 of 1] Including sig[B=impl:C]
+    Instantiating sig[B=impl:C]
+    [1 of 2] Compiling B[sig]           ( sig/B.hsig, bkp42.out/sig/sig-Ko6MwJiRFc509cOdDShPV5/B.o )
+    [2 of 2] Compiling App              ( sig/App.hs, bkp42.out/sig/sig-Ko6MwJiRFc509cOdDShPV5/App.o )