From: simonpj@microsoft.com Date: Thu, 9 Aug 2007 16:47:46 +0000 (+0000) Subject: Fix grouping by module in the mi_exports, for indexed data type families X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=daccbd2600f8c5e88291a85fdf81289b2c1fc791 Fix grouping by module in the mi_exports, for indexed data type families This is a little tricky. See Note [Original module] in MkIface. --- diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs index 564d3a4..99854d4 100644 --- a/compiler/iface/MkIface.lhs +++ b/compiler/iface/MkIface.lhs @@ -806,23 +806,54 @@ mkIfaceExports exports | (mod, avails) <- fmToList groupFM ] where + -- Group by the module where the exported entities are defined + -- (which may not be the same for all Names in an Avail) -- Deliberately use FiniteMap rather than UniqFM so we -- get a canonical ordering groupFM :: ModuleEnv (FiniteMap FastString (GenAvailInfo OccName)) groupFM = foldl add emptyModuleEnv exports - add env avail - = extendModuleEnv_C add_avail env mod (unitFM avail_fs avail_occ) + add_one :: ModuleEnv (FiniteMap FastString (GenAvailInfo OccName)) + -> Module -> GenAvailInfo OccName + -> ModuleEnv (FiniteMap FastString (GenAvailInfo OccName)) + add_one env mod avail + = extendModuleEnv_C plusFM env mod + (unitFM (occNameFS (availName avail)) avail) + + -- NB: we should not get T(X) and T(Y) in the export list + -- else the plusFM will simply discard one! They + -- should have been combined by now. + add env (Avail n) + = add_one env (nameModule n) (Avail (nameOccName n)) + + add env (AvailTC tc ns) + = foldl add_for_mod env mods where - avail_occ = availToOccs avail - mod = nameModule (availName avail) - avail_fs = occNameFS (availName avail_occ) - add_avail avail_fm _ = addToFM avail_fm avail_fs avail_occ - - availToOccs (Avail n) = Avail (nameOccName n) - availToOccs (AvailTC tc ns) = AvailTC (nameOccName tc) (map nameOccName ns) + tc_occ = nameOccName tc + mods = nub (map nameModule ns) + -- Usually just one, but see Note [Original module] + + add_for_mod env mod + = add_one env mod (AvailTC tc_occ names_from_mod) + where + names_from_mod = [nameOccName n | n <- ns, nameModule n == mod] \end{code} +Note [Orignal module] +~~~~~~~~~~~~~~~~~~~~~ +Consider this: + module X where { data family T } + module Y( T(..) ) where { import X; data instance T Int = MkT Int } +The exported Avail from Y will look like + X.T{X.T, Y.MkT} +That is, in Y, + - only MkT is brought into scope by the data instance; + - but the parent (used for grouping and naming in T(..) exports) is X.T + - and in this case we export X.T too + +In the result of MkIfaceExports, the names are grouped by defining module, +so we may need to split up a single Avail into multiple ones. + %************************************************************************ %* *