Keep track of family instance modules
[ghc-hetmet.git] / compiler / deSugar / Desugar.lhs
1 %
2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 %
5
6 The Desugarer: turning HsSyn into Core.
7
8 \begin{code}
9 module Desugar ( deSugar, deSugarExpr ) where
10
11 #include "HsVersions.h"
12
13 import DynFlags
14 import StaticFlags
15 import HscTypes
16 import HsSyn
17 import TcRnTypes
18 import MkIface
19 import Id
20 import Name
21 import CoreSyn
22 import PprCore
23 import DsMonad
24 import DsExpr
25 import DsBinds
26 import DsForeign
27 import DsExpr           ()      -- Forces DsExpr to be compiled; DsBinds only
28                                 -- depends on DsExpr.hi-boot.
29 import Module
30 import UniqFM
31 import PackageConfig
32 import RdrName
33 import NameSet
34 import VarSet
35 import Rules
36 import CoreLint
37 import CoreFVs
38 import ErrUtils
39 import ListSetOps
40 import Outputable
41 import SrcLoc
42 import Maybes
43 import FastString
44 import Util
45
46 import Data.IORef
47 \end{code}
48
49 %************************************************************************
50 %*                                                                      *
51 %*              The main function: deSugar
52 %*                                                                      *
53 %************************************************************************
54
55 \begin{code}
56 deSugar :: HscEnv -> TcGblEnv -> IO (Maybe ModGuts)
57 -- Can modify PCS by faulting in more declarations
58
59 deSugar hsc_env 
60         tcg_env@(TcGblEnv { tcg_mod       = mod,
61                             tcg_src       = hsc_src,
62                             tcg_type_env  = type_env,
63                             tcg_imports   = imports,
64                             tcg_exports   = exports,
65                             tcg_dus       = dus, 
66                             tcg_inst_uses = dfun_uses_var,
67                             tcg_th_used   = th_var,
68                             tcg_keep      = keep_var,
69                             tcg_rdr_env   = rdr_env,
70                             tcg_fix_env   = fix_env,
71                             tcg_deprecs   = deprecs,
72                             tcg_binds     = binds,
73                             tcg_fords     = fords,
74                             tcg_rules     = rules,
75                             tcg_insts     = insts,
76                             tcg_fam_insts = fam_insts })
77   = do  { showPass dflags "Desugar"
78
79         -- Desugar the program
80         ; let export_set = availsToNameSet exports
81         ; let auto_scc = mkAutoScc mod export_set
82
83         ; mb_res <- case ghcMode dflags of
84                      JustTypecheck -> return (Just ([], [], NoStubs))
85                      _             -> initDs hsc_env mod rdr_env type_env $ do
86                                         { core_prs <- dsTopLHsBinds auto_scc binds
87                                         ; (ds_fords, foreign_prs) <- dsForeigns fords
88                                         ; let all_prs = foreign_prs ++ core_prs
89                                               local_bndrs = mkVarSet (map fst all_prs)
90                                         ; ds_rules <- mappM (dsRule mod local_bndrs) rules
91                                         ; return (all_prs, catMaybes ds_rules, ds_fords)
92                                         }
93         ; case mb_res of {
94            Nothing -> return Nothing ;
95            Just (all_prs, ds_rules, ds_fords) -> do
96
97         {       -- Add export flags to bindings
98           keep_alive <- readIORef keep_var
99         ; let final_prs = addExportFlags ghci_mode export_set
100                                  keep_alive all_prs ds_rules
101               ds_binds  = [Rec final_prs]
102         -- Notice that we put the whole lot in a big Rec, even the foreign binds
103         -- When compiling PrelFloat, which defines data Float = F# Float#
104         -- we want F# to be in scope in the foreign marshalling code!
105         -- You might think it doesn't matter, but the simplifier brings all top-level
106         -- things into the in-scope set before simplifying; so we get no unfolding for F#!
107
108         -- Lint result if necessary
109         ; endPass dflags "Desugar" Opt_D_dump_ds ds_binds
110
111         -- Dump output
112         ; doIfSet (dopt Opt_D_dump_ds dflags) 
113                   (printDump (ppr_ds_rules ds_rules))
114
115         ; dfun_uses <- readIORef dfun_uses_var          -- What dfuns are used
116         ; th_used   <- readIORef th_var                 -- Whether TH is used
117         ; let used_names = allUses dus `unionNameSets` dfun_uses
118               pkgs | th_used   = insertList thPackageId (imp_dep_pkgs imports)
119                    | otherwise = imp_dep_pkgs imports
120
121               dep_mods = eltsUFM (delFromUFM (imp_dep_mods imports) (moduleName mod))
122                 -- M.hi-boot can be in the imp_dep_mods, but we must remove
123                 -- it before recording the modules on which this one depends!
124                 -- (We want to retain M.hi-boot in imp_dep_mods so that 
125                 --  loadHiBootInterface can see if M's direct imports depend 
126                 --  on M.hi-boot, and hence that we should do the hi-boot consistency 
127                 --  check.)
128
129               dir_imp_mods = imp_mods imports
130
131         ; usages <- mkUsageInfo hsc_env dir_imp_mods dep_mods used_names
132
133         ; let 
134                 -- Modules don't compare lexicographically usually, 
135                 -- but we want them to do so here.
136              le_mod :: Module -> Module -> Bool  
137              le_mod m1 m2 = moduleNameFS (moduleName m1) 
138                                 <= moduleNameFS (moduleName m2)
139              le_dep_mod :: (ModuleName, IsBootInterface) -> (ModuleName, IsBootInterface) -> Bool        
140              le_dep_mod (m1,_) (m2,_) = moduleNameFS m1 <= moduleNameFS m2
141
142              deps = Deps { dep_mods   = sortLe le_dep_mod dep_mods,
143                            dep_pkgs   = sortLe (<=)   pkgs,     
144                            dep_orphs  = sortLe le_mod (imp_orphs  imports),
145                            dep_finsts = sortLe le_mod (imp_finsts imports) }
146                 -- sort to get into canonical order
147
148              mod_guts = ModGuts {       
149                 mg_module    = mod,
150                 mg_boot      = isHsBoot hsc_src,
151                 mg_exports   = exports,
152                 mg_deps      = deps,
153                 mg_usages    = usages,
154                 mg_dir_imps  = [m | (m,_,_) <- moduleEnvElts dir_imp_mods],
155                 mg_rdr_env   = rdr_env,
156                 mg_fix_env   = fix_env,
157                 mg_deprecs   = deprecs,
158                 mg_types     = type_env,
159                 mg_insts     = insts,
160                 mg_fam_insts = fam_insts,
161                 mg_rules     = ds_rules,
162                 mg_binds     = ds_binds,
163                 mg_foreign   = ds_fords }
164         
165         ; return (Just mod_guts)
166         }}}
167
168   where
169     dflags    = hsc_dflags hsc_env
170     ghci_mode = ghcMode (hsc_dflags hsc_env)
171
172 mkAutoScc :: Module -> NameSet -> AutoScc
173 mkAutoScc mod exports
174   | not opt_SccProfilingOn      -- No profiling
175   = NoSccs              
176   | opt_AutoSccsOnAllToplevs    -- Add auto-scc on all top-level things
177   = AddSccs mod (\id -> True)
178   | opt_AutoSccsOnExportedToplevs       -- Only on exported things
179   = AddSccs mod (\id -> idName id `elemNameSet` exports)
180   | otherwise
181   = NoSccs
182
183
184 deSugarExpr :: HscEnv
185             -> Module -> GlobalRdrEnv -> TypeEnv 
186             -> LHsExpr Id
187             -> IO (Maybe CoreExpr)
188 -- Prints its own errors; returns Nothing if error occurred
189
190 deSugarExpr hsc_env this_mod rdr_env type_env tc_expr
191   = do  { let dflags = hsc_dflags hsc_env
192         ; showPass dflags "Desugar"
193
194         -- Do desugaring
195         ; mb_core_expr <- initDs hsc_env this_mod rdr_env type_env $
196                           dsLExpr tc_expr
197
198         ; case mb_core_expr of {
199             Nothing   -> return Nothing ;
200             Just expr -> do {
201
202                 -- Dump output
203           dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr)
204
205         ; return (Just expr) } } }
206
207 --              addExportFlags
208 -- Set the no-discard flag if either 
209 --      a) the Id is exported
210 --      b) it's mentioned in the RHS of an orphan rule
211 --      c) it's in the keep-alive set
212 --
213 -- It means that the binding won't be discarded EVEN if the binding
214 -- ends up being trivial (v = w) -- the simplifier would usually just 
215 -- substitute w for v throughout, but we don't apply the substitution to
216 -- the rules (maybe we should?), so this substitution would make the rule
217 -- bogus.
218
219 -- You might wonder why exported Ids aren't already marked as such;
220 -- it's just because the type checker is rather busy already and
221 -- I didn't want to pass in yet another mapping.
222
223 addExportFlags ghci_mode exports keep_alive prs rules
224   = [(add_export bndr, rhs) | (bndr,rhs) <- prs]
225   where
226     add_export bndr
227         | dont_discard bndr = setIdExported bndr
228         | otherwise         = bndr
229
230     orph_rhs_fvs = unionVarSets [ ruleRhsFreeVars rule
231                                 | rule <- rules, 
232                                   not (isLocalRule rule) ]
233         -- A non-local rule keeps alive the free vars of its right-hand side. 
234         -- (A "non-local" is one whose head function is not locally defined.)
235         -- Local rules are (later, after gentle simplification) 
236         -- attached to the Id, and that keeps the rhs free vars alive.
237
238     dont_discard bndr = is_exported name
239                      || name `elemNameSet` keep_alive
240                      || bndr `elemVarSet` orph_rhs_fvs 
241                      where
242                         name = idName bndr
243
244         -- In interactive mode, we don't want to discard any top-level
245         -- entities at all (eg. do not inline them away during
246         -- simplification), and retain them all in the TypeEnv so they are
247         -- available from the command line.
248         --
249         -- isExternalName separates the user-defined top-level names from those
250         -- introduced by the type checker.
251     is_exported :: Name -> Bool
252     is_exported | ghci_mode == Interactive = isExternalName
253                 | otherwise                = (`elemNameSet` exports)
254
255 ppr_ds_rules [] = empty
256 ppr_ds_rules rules
257   = text "" $$ text "-------------- DESUGARED RULES -----------------" $$
258     pprRules rules
259 \end{code}
260
261
262
263 %************************************************************************
264 %*                                                                      *
265 %*              Desugaring transformation rules
266 %*                                                                      *
267 %************************************************************************
268
269 \begin{code}
270 dsRule :: Module -> IdSet -> LRuleDecl Id -> DsM (Maybe CoreRule)
271 dsRule mod in_scope (L loc (HsRule name act vars lhs tv_lhs rhs fv_rhs))
272   = putSrcSpanDs loc $ 
273     do  { let bndrs     = [var | RuleBndr (L _ var) <- vars]
274         ; lhs'  <- dsLExpr lhs
275         ; rhs'  <- dsLExpr rhs
276
277         ; case decomposeRuleLhs bndrs lhs' of {
278                 Nothing -> do { warnDs msg; return Nothing } ;
279                 Just (bndrs', fn_id, args) -> do
280         
281         -- Substitute the dict bindings eagerly,
282         -- and take the body apart into a (f args) form
283         { let local_rule = nameIsLocalOrFrom mod fn_name
284                 -- NB we can't use isLocalId in the orphan test, 
285                 -- because isLocalId isn't true of class methods
286               fn_name   = idName fn_id
287               lhs_names = fn_name : nameSetToList (exprsFreeNames args)
288                 -- No need to delete bndrs, because
289                 -- exprsFreeNames finds only External names
290
291                 -- A rule is an orphan only if none of the variables
292                 -- mentioned on its left-hand side are locally defined
293               orph = case filter (nameIsLocalOrFrom mod) lhs_names of
294                         (n:ns) -> Just (nameOccName n)
295                         []     -> Nothing
296
297               rule = Rule { ru_name = name, ru_fn = fn_name, ru_act = act,
298                             ru_bndrs = bndrs', ru_args = args, ru_rhs = rhs', 
299                             ru_rough = roughTopNames args, 
300                             ru_local = local_rule, ru_orph = orph }
301         ; return (Just rule)
302         } } }
303   where
304     msg = hang (ptext SLIT("RULE left-hand side too complicated to desugar; ignored"))
305              2 (ppr lhs)
306 \end{code}