Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : master

http://hackage.haskell.org/trac/ghc/changeset/48cab6d497b3e1dafb3ddbfadc64417ca655051f

>---------------------------------------------------------------

commit 48cab6d497b3e1dafb3ddbfadc64417ca655051f
Author: Simon Peyton Jones <[email protected]>
Date:   Sun Mar 4 09:05:34 2012 +0000

    Make type trimming more conservative with -XDataKinds (fixes Trac #5912)
    
    See Note [When we can't trim types] in TidyPgm.  The real solution
    is to do a full dependency analysis, but that seems rather overkill.

>---------------------------------------------------------------

 compiler/main/TidyPgm.lhs |   66 ++++++++++++++++++++++++++++++++++-----------
 1 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/compiler/main/TidyPgm.lhs b/compiler/main/TidyPgm.lhs
index 34afd5c..01de9af 100644
--- a/compiler/main/TidyPgm.lhs
+++ b/compiler/main/TidyPgm.lhs
@@ -309,6 +309,9 @@ tidyProgram hsc_env  (ModGuts { mg_module    = mod
               ; omit_prags = dopt Opt_OmitInterfacePragmas dflags
               ; expose_all = dopt Opt_ExposeAllUnfoldings  dflags
               ; th         = xopt Opt_TemplateHaskell      dflags
+              ; data_kinds = xopt Opt_DataKinds            dflags
+              ; no_trim_types = th || data_kinds  
+                                -- See Note [When we can't trim types]
               }
         ; showPass dflags CoreTidy
 
@@ -334,7 +337,7 @@ tidyProgram hsc_env  (ModGuts { mg_module    = mod
              ; final_ids  = [ id | id <- bindersOfBinds tidy_binds, 
                                    isExternalName (idName id)]
 
-              ; tidy_type_env = tidyTypeEnv omit_prags th export_set
+              ; tidy_type_env = tidyTypeEnv omit_prags no_trim_types export_set
                                       (extendTypeEnvWithIds type_env final_ids)
 
               ; tidy_insts    = tidyInstances (lookup_dfun tidy_type_env) insts
@@ -410,7 +413,7 @@ lookup_dfun type_env dfun_id
 
 --------------------------
 tidyTypeEnv :: Bool       -- Compiling without -O, so omit prags
-            -> Bool       -- Template Haskell is on
+            -> Bool       -- Type-trimming flag
             -> NameSet -> TypeEnv -> TypeEnv
 
 -- The competed type environment is gotten from
@@ -423,11 +426,11 @@ tidyTypeEnv :: Bool       -- Compiling without -O, so 
omit prags
 -- This truncates the type environment to include only the 
 -- exported Ids and things needed from them, which saves space
 
-tidyTypeEnv omit_prags th exports type_env
+tidyTypeEnv omit_prags no_trim_types exports type_env
  = let
         type_env1 = filterNameEnv (not . isWiredInName . getName) type_env
           -- (1) remove wired-in things
-        type_env2 | omit_prags = mapNameEnv (trimThing th exports) type_env1
+        type_env2 | omit_prags = mapNameEnv (trimThing no_trim_types exports) 
type_env1
                   | otherwise  = type_env1
           -- (2) trimmed if necessary
     in
@@ -436,9 +439,9 @@ tidyTypeEnv omit_prags th exports type_env
 --------------------------
 trimThing :: Bool -> NameSet -> TyThing -> TyThing
 -- Trim off inessentials, for boot files and no -O
-trimThing th exports (ATyCon tc)
-   | not th && not (mustExposeTyCon exports tc)
-   = ATyCon (makeTyConAbstract tc)     -- Note [Trimming and Template Haskell]
+trimThing no_trim_types exports (ATyCon tc)
+   | not (mustExposeTyCon no_trim_types exports tc)
+   = ATyCon (makeTyConAbstract tc)     -- Note [When we can't trim types]
 
 trimThing _th _exports (AnId id)
    | not (isImplicitId id) 
@@ -448,30 +451,61 @@ trimThing _th _exports other_thing
   = other_thing
 
 
-{- Note [Trimming and Template Haskell]
-   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider (Trac #2386) this
+{- Note [When we can't trim types]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The basic idea of type trimming is to export algebraic data types
+abstractly (without their data constructors) when compiling without
+-O, unless of course they are explicitly exported by the user.  
+
+We always export synonyms, because they can be mentioned in the type
+of an exported Id.  We could do a full dependency analysis starting
+from the explicit exports, but that's quite painful, and not done for
+now.
+
+But there are some times we can't do that, indicated by the 'no_trim_types' 
flag.
+
+First, Template Haskell.  Consider (Trac #2386) this
        module M(T, makeOne) where
          data T = Yay String
          makeOne = [| Yay "Yep" |]
 Notice that T is exported abstractly, but makeOne effectively exports it too!
 A module that splices in $(makeOne) will then look for a declartion of Yay,
 so it'd better be there.  Hence, brutally but simply, we switch off type
-constructor trimming if TH is enabled in this module. -}
-
-
-mustExposeTyCon :: NameSet     -- Exports
+constructor trimming if TH is enabled in this module.
+
+Second, data kinds.  Consider (Trac #5912) 
+     {-# LANGUAGE DataKinds #-}
+     module M() where
+     data UnaryTypeC a = UnaryDataC a
+     type Bug = 'UnaryDataC
+We always export synonyms, so Bug is exposed, and that means that
+UnaryTypeC must be too, even though it's not explicitly exported.  In
+effect, DataKinds means that we'd need to do a full dependency analysis
+to see what data constructors are mentioned.  But we don't do that yet.
+
+In these two cases we just switch off type trimming altogether.
+ -}
+
+mustExposeTyCon :: Bool         -- Type-trimming flag 
+                -> NameSet     -- Exports
                -> TyCon        -- The tycon
                -> Bool         -- Can its rep be hidden?
 -- We are compiling without -O, and thus trying to write as little as 
 -- possible into the interface file.  But we must expose the details of
 -- any data types whose constructors or fields are exported
-mustExposeTyCon exports tc
-  | not (isAlgTyCon tc)        -- Synonyms
+mustExposeTyCon no_trim_types exports tc
+  | no_trim_types               -- See Note [When we can't trim types]
+  = True
+
+  | not (isAlgTyCon tc)        -- Always expose synonyms (otherwise we'd have 
to
+                                -- figure out whether it was mentioned in the 
type
+                                -- of any other exported thing)
   = True
+
   | isEnumerationTyCon tc      -- For an enumeration, exposing the constructors
   = True                       -- won't lead to the need for further exposure
                                -- (This includes data types with no 
constructors.)
+
   | isFamilyTyCon tc           -- Open type family
   = True
 



_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to