Commit 8cef8af3 authored by kanetw's avatar kanetw Committed by Ben Gamari
Browse files

Re-export data family when exporting a data instance without an export list

Whenever a data instance is exported, the corresponding data family
is exported, too. This allows one to write

```
     -- Foo.hs
     module Foo where

     data family T a

     -- Bar.hs
     module Bar where

     import Foo

     data instance T Int = MkT

     -- Baz.hs
     module Baz where

     import Bar (T(MkT))
```

In previous versions of GHC, this required a workaround
explicit export list in `Bar`.

Reviewers: bgamari, goldfire, austin

Reviewed By: bgamari, goldfire

Subscribers: goldfire, thomie

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

GHC Trac Issues: #11164
parent 3d55e41e
......@@ -1200,14 +1200,24 @@ exports_from_avail :: Maybe (Located [LIE RdrName])
-> RnM (Maybe [LIE Name], [AvailInfo])
exports_from_avail Nothing rdr_env _imports _this_mod
= -- The same as (module M) where M is the current module name,
-- so that's how we handle it.
let
avails = [ availFromGRE gre
| gre <- globalRdrEnvElts rdr_env
, isLocalGRE gre ]
in
return (Nothing, avails)
-- The same as (module M) where M is the current module name,
-- so that's how we handle it, except we also export the data family
-- when a data instance is exported.
= let avails = [ fix_faminst $ availFromGRE gre
| gre <- globalRdrEnvElts rdr_env
, isLocalGRE gre ]
in return (Nothing, avails)
where
-- #11164: when we define a data instance
-- but not data family, re-export the family
-- Generally, whenever we export a part of a declaration,
-- export the declaration, too.
fix_faminst (AvailTC n ns flds)
| not (n `elem` ns)
= AvailTC n (n:ns) flds
fix_faminst avail = avail
exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
= do (ie_names, _, exports) <- foldlM do_litem emptyExportAccum rdr_items
......
......@@ -109,6 +109,29 @@ Language
-- P is imported
import Foo (T(..))
- Whenever a data instance is exported, the corresponding data family
is exported, too. This allows one to write ::
-- Foo.hs
module Foo where
data family T a
-- Bar.hs
module Bar where
import Foo
data instance T Int = MkT
-- Baz.hs
module Baz where
import Bar (T(MkT))
In previous versions of GHC, this required a workaround via an
explicit export list in Bar.
Compiler
......
......@@ -6702,10 +6702,10 @@ Two things to watch out for:
data instance D Int = D1 | D2
Module Y exports all the entities defined in Y, namely the data
constructors ``D1`` and ``D2``, *but not the data family* ``D``. That
(annoyingly) means that you cannot selectively import Y selectively,
thus "``import Y( D(D1,D2) )``", because Y does not export ``D``.
Instead you should list the exports explicitly, thus:
constructors ``D1`` and ``D2``, and *implicitly* the data family ``D``,
even though it's defined in X.
This means you can write "``import Y( D(D1,D2) )``" *without*
giving an explicit export list like this:
::
......
data B1 a = B1 a
data instance C.F (B1 a) = B2 a
data family D a
class C.C1 a where
data family C.F a
class C.C1 a where
data family C.F a
-- Defined at T5417a.hs:5:5
......
OverB.hs:7:15:
Conflicting family instance declarations:
OverA.C [Int] [a] = CListList2 -- Defined at OverB.hs:7:15
OverA.C [a] [Int] = C9ListList -- Defined at OverC.hs:7:15
OverB.hs:9:15:
Conflicting family instance declarations:
OverA.D [Int] [a] = Int -- Defined at OverB.hs:9:15
OverA.D [a] [Int] = Char -- Defined at OverC.hs:9:15
OverB.hs:7:15: error:
Conflicting family instance declarations:
C [Int] [a] = CListList2 -- Defined at OverB.hs:7:15
C [a] [Int] = C9ListList -- Defined at OverC.hs:7:15
OverB.hs:9:15: error:
Conflicting family instance declarations:
OverA.D [Int] [a] = Int -- Defined at OverB.hs:9:15
OverA.D [a] [Int] = Char -- Defined at OverC.hs:9:15
module T11164 where
import T11164b (T)
{-# LANGUAGE TypeFamilies #-}
module T11164a where
data family T a
{-# LANGUAGE TypeFamilies #-}
module T11164b where
import T11164a
data instance T Int = MkT
......@@ -226,3 +226,7 @@ test('T7969',
test('T9127', normal, compile, [''])
test('T4426', normal, compile_fail, [''])
test('T9778', normal, compile, ['-fwarn-unticked-promoted-constructors'])
test('T11164',
extra_clean(['T11164a.hi', 'T11164a.o',
'T11164b.hi', 'T11164b.o']),
multimod_compile, ['T11164', '-v0'])
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment