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