warning police
[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 OccurAnal
23 import PprCore
24 import DsMonad
25 import DsExpr
26 import DsBinds
27 import DsForeign
28 import DsExpr           ()      -- Forces DsExpr to be compiled; DsBinds only
29                                 -- depends on DsExpr.hi-boot.
30 import Module
31 import RdrName
32 import NameSet
33 import VarSet
34 import Rules
35 import CoreLint
36 import CoreFVs
37 import ErrUtils
38 import Outputable
39 import SrcLoc
40 import Maybes
41 import FastString
42 import Pretty      ( Doc )
43 import Coverage
44 import IOEnv
45 import Data.IORef
46 \end{code}
47
48 %************************************************************************
49 %*                                                                      *
50 %*              The main function: deSugar
51 %*                                                                      *
52 %************************************************************************
53
54 \begin{code}
55 deSugar :: HscEnv -> ModLocation -> TcGblEnv -> IO (Maybe ModGuts)
56 -- Can modify PCS by faulting in more declarations
57
58 deSugar hsc_env 
59         mod_loc
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_keep         = keep_var,
66                             tcg_rdr_env      = rdr_env,
67                             tcg_fix_env      = fix_env,
68                             tcg_inst_env     = inst_env,
69                             tcg_fam_inst_env = fam_inst_env,
70                             tcg_deprecs      = deprecs,
71                             tcg_binds        = binds,
72                             tcg_fords        = fords,
73                             tcg_rules        = rules,
74                             tcg_insts        = insts,
75                             tcg_fam_insts    = fam_insts,
76                             tcg_hpc          = other_hpc_info })
77
78   = do  { let dflags = hsc_dflags hsc_env
79         ; showPass dflags "Desugar"
80
81         -- Desugar the program
82         ; let export_set = availsToNameSet exports
83         ; let auto_scc = mkAutoScc mod export_set
84         ; let target = hscTarget dflags
85         ; let hpcInfo = emptyHpcInfo other_hpc_info
86         ; mb_res <- case target of
87                      HscNothing -> return (Just ([], [], NoStubs, hpcInfo, emptyModBreaks))
88                      _        -> do (binds_cvr,ds_hpc_info, modBreaks) 
89                                               <- if (opt_Hpc 
90                                                         || target == HscInterpreted)
91                                                      && (not (isHsBoot hsc_src))                                                        
92                                                  then addCoverageTicksToBinds dflags mod mod_loc (typeEnvTyCons type_env) binds 
93                                                  else return (binds, hpcInfo, 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                                         ; ds_rules <- mappM dsRule rules
99                                         ; return (all_prs, catMaybes ds_rules, ds_fords, ds_hpc_info, modBreaks)
100                                         }
101         ; case mb_res of {
102            Nothing -> return Nothing ;
103            Just (all_prs, ds_rules, ds_fords,ds_hpc_info, modBreaks) -> do
104
105         {       -- Add export flags to bindings
106           keep_alive <- readIORef keep_var
107         ; let final_prs = addExportFlags target export_set
108                                  keep_alive all_prs ds_rules
109               ds_binds  = [Rec final_prs]
110         -- Notice that we put the whole lot in a big Rec, even the foreign binds
111         -- When compiling PrelFloat, which defines data Float = F# Float#
112         -- we want F# to be in scope in the foreign marshalling code!
113         -- You might think it doesn't matter, but the simplifier brings all top-level
114         -- things into the in-scope set before simplifying; so we get no unfolding for F#!
115
116         -- Lint result if necessary
117         ; endPass dflags "Desugar" Opt_D_dump_ds ds_binds
118
119         -- Dump output
120         ; doIfSet (dopt Opt_D_dump_ds dflags) 
121                   (printDump (ppr_ds_rules ds_rules))
122
123         ; used_names <- mkUsedNames tcg_env
124         ; deps <- mkDependencies tcg_env
125
126         ; let mod_guts = ModGuts {      
127                 mg_module       = mod,
128                 mg_boot         = isHsBoot hsc_src,
129                 mg_exports      = exports,
130                 mg_deps         = deps,
131                 mg_used_names   = used_names,
132                 mg_dir_imps     = imp_mods imports,
133                 mg_rdr_env      = rdr_env,
134                 mg_fix_env      = fix_env,
135                 mg_deprecs      = deprecs,
136                 mg_types        = type_env,
137                 mg_insts        = insts,
138                 mg_fam_insts    = fam_insts,
139                 mg_inst_env     = inst_env,
140                 mg_fam_inst_env = fam_inst_env,
141                 mg_rules        = ds_rules,
142                 mg_binds        = ds_binds,
143                 mg_foreign      = ds_fords,
144                 mg_hpc_info     = ds_hpc_info,
145                 mg_modBreaks    = modBreaks,
146                 mg_vect_info    = noVectInfo
147               }
148         ; return (Just mod_guts)
149         }}}
150
151 mkAutoScc :: Module -> NameSet -> AutoScc
152 mkAutoScc mod exports
153   | not opt_SccProfilingOn      -- No profiling
154   = NoSccs              
155   | opt_AutoSccsOnAllToplevs    -- Add auto-scc on all top-level things
156   = AddSccs mod (\_ -> True)
157   | opt_AutoSccsOnExportedToplevs       -- Only on exported things
158   = AddSccs mod (\id -> idName id `elemNameSet` exports)
159   | otherwise
160   = NoSccs
161
162
163 deSugarExpr :: HscEnv
164             -> Module -> GlobalRdrEnv -> TypeEnv 
165             -> LHsExpr Id
166             -> IO (Maybe CoreExpr)
167 -- Prints its own errors; returns Nothing if error occurred
168
169 deSugarExpr hsc_env this_mod rdr_env type_env tc_expr
170   = do  { let dflags = hsc_dflags hsc_env
171         ; showPass dflags "Desugar"
172
173         -- Do desugaring
174         ; mb_core_expr <- initDs hsc_env this_mod rdr_env type_env $
175                           dsLExpr tc_expr
176
177         ; case mb_core_expr of {
178             Nothing   -> return Nothing ;
179             Just expr -> do {
180
181                 -- Dump output
182           dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr)
183
184         ; return (Just expr) } } }
185
186 --              addExportFlags
187 -- Set the no-discard flag if either 
188 --      a) the Id is exported
189 --      b) it's mentioned in the RHS of an orphan rule
190 --      c) it's in the keep-alive set
191 --
192 -- It means that the binding won't be discarded EVEN if the binding
193 -- ends up being trivial (v = w) -- the simplifier would usually just 
194 -- substitute w for v throughout, but we don't apply the substitution to
195 -- the rules (maybe we should?), so this substitution would make the rule
196 -- bogus.
197
198 -- You might wonder why exported Ids aren't already marked as such;
199 -- it's just because the type checker is rather busy already and
200 -- I didn't want to pass in yet another mapping.
201
202 addExportFlags :: HscTarget -> NameSet -> NameSet -> [(Id, t)] -> [CoreRule]
203                -> [(Id, t)]
204 addExportFlags target exports keep_alive prs rules
205   = [(add_export bndr, rhs) | (bndr,rhs) <- prs]
206   where
207     add_export bndr
208         | dont_discard bndr = setIdExported bndr
209         | otherwise         = bndr
210
211     orph_rhs_fvs = unionVarSets [ ruleRhsFreeVars rule
212                                 | rule <- rules, 
213                                   not (isLocalRule rule) ]
214         -- A non-local rule keeps alive the free vars of its right-hand side. 
215         -- (A "non-local" is one whose head function is not locally defined.)
216         -- Local rules are (later, after gentle simplification) 
217         -- attached to the Id, and that keeps the rhs free vars alive.
218
219     dont_discard bndr = is_exported name
220                      || name `elemNameSet` keep_alive
221                      || bndr `elemVarSet` orph_rhs_fvs 
222                      where
223                         name = idName bndr
224
225         -- In interactive mode, we don't want to discard any top-level
226         -- entities at all (eg. do not inline them away during
227         -- simplification), and retain them all in the TypeEnv so they are
228         -- available from the command line.
229         --
230         -- isExternalName separates the user-defined top-level names from those
231         -- introduced by the type checker.
232     is_exported :: Name -> Bool
233     is_exported | target == HscInterpreted = isExternalName
234                 | otherwise                = (`elemNameSet` exports)
235
236 ppr_ds_rules :: [CoreRule] -> PprStyle -> Doc
237 ppr_ds_rules [] = empty
238 ppr_ds_rules rules
239   = text "" $$ text "-------------- DESUGARED RULES -----------------" $$
240     pprRules rules
241 \end{code}
242
243
244
245 %************************************************************************
246 %*                                                                      *
247 %*              Desugaring transformation rules
248 %*                                                                      *
249 %************************************************************************
250
251 \begin{code}
252 dsRule :: LRuleDecl Id -> DsM (Maybe CoreRule)
253 dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
254   = putSrcSpanDs loc $ 
255     do  { let bndrs = [var | RuleBndr (L _ var) <- vars]
256         ; lhs'  <- dsLExpr lhs
257         ; rhs'  <- dsLExpr rhs
258
259         ; case decomposeRuleLhs (occurAnalyseExpr lhs') of {
260                 Nothing -> do { warnDs msg; return Nothing } ;
261                 Just (fn_id, args) -> do
262         
263         -- Substitute the dict bindings eagerly,
264         -- and take the body apart into a (f args) form
265         { let local_rule = isLocalId fn_id
266                 -- NB: isLocalId is False of implicit Ids.  This is good becuase
267                 -- we don't want to attach rules to the bindings of implicit Ids, 
268                 -- because they don't show up in the bindings until just before code gen
269               fn_name   = idName fn_id
270
271               rule = Rule { ru_name = name, ru_fn = fn_name, ru_act = act,
272                             ru_bndrs = bndrs, ru_args = args, ru_rhs = rhs', 
273                             ru_rough = roughTopNames args, 
274                             ru_local = local_rule }
275         ; return (Just rule)
276         } } }
277   where
278     msg = hang (ptext SLIT("RULE left-hand side too complicated to desugar; ignored"))
279              2 (ppr lhs)
280 \end{code}