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