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