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