Module header tidyup, phase 1
[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                 -- sort to get into canonical order
146
147              mod_guts = ModGuts {       
148                 mg_module    = mod,
149                 mg_boot      = isHsBoot hsc_src,
150                 mg_exports   = exports,
151                 mg_deps      = deps,
152                 mg_usages    = usages,
153                 mg_dir_imps  = [m | (m,_,_) <- moduleEnvElts dir_imp_mods],
154                 mg_rdr_env   = rdr_env,
155                 mg_fix_env   = fix_env,
156                 mg_deprecs   = deprecs,
157                 mg_types     = type_env,
158                 mg_insts     = insts,
159                 mg_fam_insts = fam_insts,
160                 mg_rules     = ds_rules,
161                 mg_binds     = ds_binds,
162                 mg_foreign   = ds_fords }
163         
164         ; return (Just mod_guts)
165         }}}
166
167   where
168     dflags    = hsc_dflags hsc_env
169     ghci_mode = ghcMode (hsc_dflags hsc_env)
170
171 mkAutoScc :: Module -> NameSet -> AutoScc
172 mkAutoScc mod exports
173   | not opt_SccProfilingOn      -- No profiling
174   = NoSccs              
175   | opt_AutoSccsOnAllToplevs    -- Add auto-scc on all top-level things
176   = AddSccs mod (\id -> True)
177   | opt_AutoSccsOnExportedToplevs       -- Only on exported things
178   = AddSccs mod (\id -> idName id `elemNameSet` exports)
179   | otherwise
180   = NoSccs
181
182
183 deSugarExpr :: HscEnv
184             -> Module -> GlobalRdrEnv -> TypeEnv 
185             -> LHsExpr Id
186             -> IO (Maybe CoreExpr)
187 -- Prints its own errors; returns Nothing if error occurred
188
189 deSugarExpr hsc_env this_mod rdr_env type_env tc_expr
190   = do  { let dflags = hsc_dflags hsc_env
191         ; showPass dflags "Desugar"
192
193         -- Do desugaring
194         ; mb_core_expr <- initDs hsc_env this_mod rdr_env type_env $
195                           dsLExpr tc_expr
196
197         ; case mb_core_expr of {
198             Nothing   -> return Nothing ;
199             Just expr -> do {
200
201                 -- Dump output
202           dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr)
203
204         ; return (Just expr) } } }
205
206 --              addExportFlags
207 -- Set the no-discard flag if either 
208 --      a) the Id is exported
209 --      b) it's mentioned in the RHS of an orphan rule
210 --      c) it's in the keep-alive set
211 --
212 -- It means that the binding won't be discarded EVEN if the binding
213 -- ends up being trivial (v = w) -- the simplifier would usually just 
214 -- substitute w for v throughout, but we don't apply the substitution to
215 -- the rules (maybe we should?), so this substitution would make the rule
216 -- bogus.
217
218 -- You might wonder why exported Ids aren't already marked as such;
219 -- it's just because the type checker is rather busy already and
220 -- I didn't want to pass in yet another mapping.
221
222 addExportFlags ghci_mode exports keep_alive prs rules
223   = [(add_export bndr, rhs) | (bndr,rhs) <- prs]
224   where
225     add_export bndr
226         | dont_discard bndr = setIdExported bndr
227         | otherwise         = bndr
228
229     orph_rhs_fvs = unionVarSets [ ruleRhsFreeVars rule
230                                 | rule <- rules, 
231                                   not (isLocalRule rule) ]
232         -- A non-local rule keeps alive the free vars of its right-hand side. 
233         -- (A "non-local" is one whose head function is not locally defined.)
234         -- Local rules are (later, after gentle simplification) 
235         -- attached to the Id, and that keeps the rhs free vars alive.
236
237     dont_discard bndr = is_exported name
238                      || name `elemNameSet` keep_alive
239                      || bndr `elemVarSet` orph_rhs_fvs 
240                      where
241                         name = idName bndr
242
243         -- In interactive mode, we don't want to discard any top-level
244         -- entities at all (eg. do not inline them away during
245         -- simplification), and retain them all in the TypeEnv so they are
246         -- available from the command line.
247         --
248         -- isExternalName separates the user-defined top-level names from those
249         -- introduced by the type checker.
250     is_exported :: Name -> Bool
251     is_exported | ghci_mode == Interactive = isExternalName
252                 | otherwise                = (`elemNameSet` exports)
253
254 ppr_ds_rules [] = empty
255 ppr_ds_rules rules
256   = text "" $$ text "-------------- DESUGARED RULES -----------------" $$
257     pprRules rules
258 \end{code}
259
260
261
262 %************************************************************************
263 %*                                                                      *
264 %*              Desugaring transformation rules
265 %*                                                                      *
266 %************************************************************************
267
268 \begin{code}
269 dsRule :: Module -> IdSet -> LRuleDecl Id -> DsM (Maybe CoreRule)
270 dsRule mod in_scope (L loc (HsRule name act vars lhs tv_lhs rhs fv_rhs))
271   = putSrcSpanDs loc $ 
272     do  { let bndrs     = [var | RuleBndr (L _ var) <- vars]
273         ; lhs'  <- dsLExpr lhs
274         ; rhs'  <- dsLExpr rhs
275
276         ; case decomposeRuleLhs bndrs lhs' of {
277                 Nothing -> do { warnDs msg; return Nothing } ;
278                 Just (bndrs', fn_id, args) -> do
279         
280         -- Substitute the dict bindings eagerly,
281         -- and take the body apart into a (f args) form
282         { let local_rule = nameIsLocalOrFrom mod fn_name
283                 -- NB we can't use isLocalId in the orphan test, 
284                 -- because isLocalId isn't true of class methods
285               fn_name   = idName fn_id
286               lhs_names = fn_name : nameSetToList (exprsFreeNames args)
287                 -- No need to delete bndrs, because
288                 -- exprsFreeNames finds only External names
289
290                 -- A rule is an orphan only if none of the variables
291                 -- mentioned on its left-hand side are locally defined
292               orph = case filter (nameIsLocalOrFrom mod) lhs_names of
293                         (n:ns) -> Just (nameOccName n)
294                         []     -> Nothing
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, ru_orph = orph }
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}