summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Z. Yang <ezyang@cs.stanford.edu>2017-01-18 16:17:04 -0800
committerEdward Z. Yang <ezyang@cs.stanford.edu>2017-01-22 12:05:15 -0800
commit294f95dcc2ae4cd9fdcdfca90173d92ef39a4bea (patch)
treea25489c297222f27668f1241c706798a62071e59
parent5d38fb69fd1e7a434ccc3147ae6a17fe0b5b0be3 (diff)
downloadhaskell-294f95dcc2ae4cd9fdcdfca90173d92ef39a4bea.tar.gz
Preserve coercion axioms when thinning.
Forgot to handle these! In they go, plus a test case. Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
-rw-r--r--compiler/typecheck/TcBackpack.hs40
-rw-r--r--testsuite/tests/backpack/should_compile/all.T1
-rw-r--r--testsuite/tests/backpack/should_compile/bkp50.bkp8
-rw-r--r--testsuite/tests/backpack/should_compile/bkp50.stderr4
4 files changed, 45 insertions, 8 deletions
diff --git a/compiler/typecheck/TcBackpack.hs b/compiler/typecheck/TcBackpack.hs
index 5c61871155..d74cf51d77 100644
--- a/compiler/typecheck/TcBackpack.hs
+++ b/compiler/typecheck/TcBackpack.hs
@@ -368,18 +368,42 @@ thinModIface avails iface =
-- perhaps there might be two IfaceTopBndr that are the same
-- OccName but different Name. Requires better understanding
-- of invariants here.
- mi_decls = filter (decl_pred . snd) (mi_decls iface)
+ mi_decls = exported_decls ++ non_exported_decls ++ dfun_decls
-- mi_insts = ...,
-- mi_fam_insts = ...,
}
where
- occs = mkOccSet [ occName n
- | a <- avails
- , n <- availNames a ]
- -- NB: Never drop DFuns
- decl_pred IfaceId{ ifIdDetails = IfDFunId } = True
- decl_pred decl =
- nameOccName (ifName decl) `elemOccSet` occs
+ decl_pred occs decl = nameOccName (ifName decl) `elemOccSet` occs
+ filter_decls occs = filter (decl_pred occs . snd) (mi_decls iface)
+
+ exported_occs = mkOccSet [ occName n
+ | a <- avails
+ , n <- availNames a ]
+ exported_decls = filter_decls exported_occs
+
+ non_exported_occs = mkOccSet [ occName n
+ | (_, d) <- exported_decls
+ , n <- ifaceDeclNonExportedRefs d ]
+ non_exported_decls = filter_decls non_exported_occs
+
+ dfun_pred IfaceId{ ifIdDetails = IfDFunId } = True
+ dfun_pred _ = False
+ dfun_decls = filter (dfun_pred . snd) (mi_decls iface)
+
+-- | The list of 'Name's of *non-exported* 'IfaceDecl's which this
+-- 'IfaceDecl' may refer to. A non-exported 'IfaceDecl' should be kept
+-- after thinning if an *exported* 'IfaceDecl' (or 'mi_insts', perhaps)
+-- refers to it; we can't decide to keep it by looking at the exports
+-- of a module after thinning. Keep this synchronized with
+-- 'rnIfaceDecl'.
+ifaceDeclNonExportedRefs :: IfaceDecl -> [Name]
+ifaceDeclNonExportedRefs d@IfaceFamily{} =
+ case ifFamFlav d of
+ IfaceClosedSynFamilyTyCon (Just (n, _))
+ -> [n]
+ _ -> []
+ifaceDeclNonExportedRefs _ = []
+
-- Note [Blank hsigs for all requirements]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/testsuite/tests/backpack/should_compile/all.T b/testsuite/tests/backpack/should_compile/all.T
index 33d0357988..9897c037a3 100644
--- a/testsuite/tests/backpack/should_compile/all.T
+++ b/testsuite/tests/backpack/should_compile/all.T
@@ -41,3 +41,4 @@ test('bkp46', normal, backpack_compile, [''])
test('bkp47', normal, backpack_compile, [''])
test('bkp48', normal, backpack_compile, [''])
test('bkp49', normal, backpack_compile, [''])
+test('bkp50', normal, backpack_compile, [''])
diff --git a/testsuite/tests/backpack/should_compile/bkp50.bkp b/testsuite/tests/backpack/should_compile/bkp50.bkp
new file mode 100644
index 0000000000..2dcee80863
--- /dev/null
+++ b/testsuite/tests/backpack/should_compile/bkp50.bkp
@@ -0,0 +1,8 @@
+{-# LANGUAGE TypeFamilies #-}
+unit p where
+ signature A where
+ type family F a where
+ F a = Int
+unit q where
+ dependency p[A=<A>]
+ signature A(F) where
diff --git a/testsuite/tests/backpack/should_compile/bkp50.stderr b/testsuite/tests/backpack/should_compile/bkp50.stderr
new file mode 100644
index 0000000000..d8f64f0657
--- /dev/null
+++ b/testsuite/tests/backpack/should_compile/bkp50.stderr
@@ -0,0 +1,4 @@
+[1 of 2] Processing p
+ [1 of 1] Compiling A[sig] ( p/A.hsig, nothing )
+[2 of 2] Processing q
+ [1 of 1] Compiling A[sig] ( q/A.hsig, nothing )