4276414b17d75b8751aef1a083256e14ce00e511
[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 CoreSubst
21 import CoqPass ( coqPassCoreToString, coqPassCoreToCore )
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 RdrName
31 import NameSet
32 import NameEnv
33 import Rules
34 import CoreMonad        ( endPass, CoreToDo(..) )
35 import ErrUtils
36 import Outputable
37 import SrcLoc
38 import Coverage
39 import Util
40 import MonadUtils
41 import OrdList
42 import Data.List
43 import Data.IORef
44 import PrelNames
45 import UniqSupply
46 \end{code}
47
48 %************************************************************************
49 %*                                                                      *
50 %*              The main function: deSugar
51 %*                                                                      *
52 %************************************************************************
53
54 \begin{code}
55 -- | Main entry point to the desugarer.
56 deSugar :: HscEnv -> ModLocation -> TcGblEnv -> IO (Messages, Maybe ModGuts)
57 -- Can modify PCS by faulting in more declarations
58
59 deSugar hsc_env 
60         mod_loc
61         tcg_env@(TcGblEnv { tcg_mod          = mod,
62                             tcg_src          = hsc_src,
63                             tcg_type_env     = type_env,
64                             tcg_imports      = imports,
65                             tcg_exports      = exports,
66                             tcg_keep         = keep_var,
67                             tcg_rdr_env      = rdr_env,
68                             tcg_fix_env      = fix_env,
69                             tcg_inst_env     = inst_env,
70                             tcg_fam_inst_env = fam_inst_env,
71                             tcg_warns        = warns,
72                             tcg_anns         = anns,
73                             tcg_binds        = binds,
74                             tcg_imp_specs    = imp_specs,
75                             tcg_ev_binds     = ev_binds,
76                             tcg_fords        = fords,
77                             tcg_rules        = rules,
78                             tcg_vects        = vects,
79                             tcg_insts        = insts,
80                             tcg_fam_insts    = fam_insts,
81                             tcg_hpc          = other_hpc_info })
82
83   = do  { let dflags = hsc_dflags hsc_env
84         ; showPass dflags "Desugar"
85
86         -- Desugar the program
87         ; let export_set = availsToNameSet exports
88         ; let auto_scc = mkAutoScc dflags mod export_set
89         ; let target = hscTarget dflags
90         ; let hpcInfo = emptyHpcInfo other_hpc_info
91         ; (msgs, mb_res)
92               <- case target of
93                    HscNothing ->
94                        return (emptyMessages,
95                                Just ([], nilOL, [], [], NoStubs, hpcInfo, emptyModBreaks, undefined, undefined
96                                     , undefined
97                                     , undefined
98                                     , undefined
99                                     , undefined
100                                     , undefined
101                                     , undefined
102                                     , undefined
103                                     , undefined
104                                     , undefined
105                                     , undefined
106                                     , undefined
107                                     , undefined
108                                     , undefined
109                                     , undefined
110                                     , undefined
111                                     , undefined
112                                     , undefined
113                                     , undefined
114                                ))
115                    _        -> do
116                      (binds_cvr,ds_hpc_info, modBreaks)
117                          <- if (opt_Hpc
118                                   || target == HscInterpreted)
119                                && (not (isHsBoot hsc_src))
120                               then addCoverageTicksToBinds dflags mod mod_loc
121                                                            (typeEnvTyCons type_env) binds 
122                               else return (binds, hpcInfo, emptyModBreaks)
123                      initDs hsc_env mod rdr_env type_env $ do
124                        do { ds_ev_binds <- dsEvBinds ev_binds
125                           ; core_prs <- dsTopLHsBinds auto_scc binds_cvr
126                           ; (spec_prs, spec_rules) <- dsImpSpecs imp_specs
127                           ; (ds_fords, foreign_prs) <- dsForeigns fords
128                           ; ds_rules <- mapMaybeM dsRule rules
129                           ; ds_vects <- mapM dsVect vects
130                           ; hetmet_brak <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_brak_name else return undefined
131                           ; hetmet_esc  <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_esc_name  else return undefined
132                           ; hetmet_PGArrow <- if dopt Opt_F_coqpass dflags then dsLookupTyCon hetmet_PGArrow_name else return undefined
133                           ; hetmet_pga_id <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_id_name else return undefined
134                           ; hetmet_pga_comp <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_comp_name else return undefined
135                           ; hetmet_pga_first <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_first_name else return undefined
136                           ; hetmet_pga_second <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_second_name else return undefined
137                           ; hetmet_pga_cancell <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_cancell_name else return undefined
138                           ; hetmet_pga_cancelr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_cancelr_name else return undefined
139                           ; hetmet_pga_uncancell <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_uncancell_name else return undefined
140                           ; hetmet_pga_uncancelr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_uncancelr_name else return undefined
141                           ; hetmet_pga_assoc <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_assoc_name else return undefined
142                           ; hetmet_pga_unassoc <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_unassoc_name else return undefined
143                           ; hetmet_pga_copy <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_copy_name else return undefined
144                           ; hetmet_pga_drop <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_drop_name else return undefined
145                           ; hetmet_pga_swap <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_swap_name else return undefined
146                           ; hetmet_pga_applyl <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_applyl_name else return undefined
147                           ; hetmet_pga_applyr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_applyr_name else return undefined
148                           ; hetmet_pga_curryl <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_curryl_name else return undefined
149                           ; hetmet_pga_curryr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_curryr_name else return undefined
150                           ; let hpc_init
151                                   | opt_Hpc   = hpcInitCode mod ds_hpc_info
152                                   | otherwise = empty
153                           ; return ( ds_ev_binds
154                                    , foreign_prs `appOL` core_prs `appOL` spec_prs
155                                    , spec_rules ++ ds_rules, ds_vects
156                                    , ds_fords `appendStubC` hpc_init
157                                    , ds_hpc_info, modBreaks, hetmet_brak, hetmet_esc
158                                    , hetmet_PGArrow
159                                    , hetmet_pga_id
160                                    , hetmet_pga_comp
161                                    , hetmet_pga_first
162                                    , hetmet_pga_second
163                                    , hetmet_pga_cancell
164                                    , hetmet_pga_cancelr
165                                    , hetmet_pga_uncancell
166                                    , hetmet_pga_uncancelr
167                                    , hetmet_pga_assoc
168                                    , hetmet_pga_unassoc
169                                    , hetmet_pga_copy
170                                    , hetmet_pga_drop
171                                    , hetmet_pga_swap
172                                    , hetmet_pga_applyl
173                                    , hetmet_pga_applyr
174                                    , hetmet_pga_curryl
175                                    , hetmet_pga_curryr
176                                    ) }
177
178         ; case mb_res of {
179            Nothing -> return (msgs, Nothing) ;
180            Just (ds_ev_binds, all_prs, all_rules, ds_vects, ds_fords,ds_hpc_info, modBreaks, hetmet_brak, hetmet_esc
181                                    , hetmet_PGArrow
182                                    , hetmet_pga_id
183                                    , hetmet_pga_comp
184                                    , hetmet_pga_first
185                                    , hetmet_pga_second
186                                    , hetmet_pga_cancell
187                                    , hetmet_pga_cancelr
188                                    , hetmet_pga_uncancell
189                                    , hetmet_pga_uncancelr
190                                    , hetmet_pga_assoc
191                                    , hetmet_pga_unassoc
192                                    , hetmet_pga_copy
193                                    , hetmet_pga_drop
194                                    , hetmet_pga_swap
195                                    , hetmet_pga_applyl
196                                    , hetmet_pga_applyr
197                                    , hetmet_pga_curryl
198                                    , hetmet_pga_curryr) -> do
199
200         {       -- Add export flags to bindings
201           keep_alive <- readIORef keep_var
202         ; let (rules_for_locals, rules_for_imps) 
203                    = partition isLocalRule all_rules
204               final_prs = addExportFlagsAndRules target
205                               export_set keep_alive rules_for_locals (fromOL all_prs)
206
207               final_pgm = combineEvBinds ds_ev_binds final_prs
208         -- Notice that we put the whole lot in a big Rec, even the foreign binds
209         -- When compiling PrelFloat, which defines data Float = F# Float#
210         -- we want F# to be in scope in the foreign marshalling code!
211         -- You might think it doesn't matter, but the simplifier brings all top-level
212         -- things into the in-scope set before simplifying; so we get no unfolding for F#!
213
214         -- Lint result if necessary, and print
215         ; dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared, before opt" $
216                (vcat [ pprCoreBindings final_pgm
217                      , pprRules rules_for_imps ])
218
219         ; (ds_binds, ds_rules_for_imps) <- simpleOptPgm dflags final_pgm rules_for_imps
220                          -- The simpleOptPgm gets rid of type 
221                          -- bindings plus any stupid dead code
222
223         ; ds_binds' <- if dopt Opt_F_coqpass dflags
224                        then do { us <- mkSplitUniqSupply '~'
225                                ; return (coqPassCoreToCore
226                                              hetmet_brak
227                                              hetmet_esc
228                                              us
229                                              ds_binds
230                                              hetmet_PGArrow
231                                              hetmet_pga_id
232                                              hetmet_pga_comp
233                                              hetmet_pga_first
234                                              hetmet_pga_second
235                                              hetmet_pga_cancell
236                                              hetmet_pga_cancelr
237                                              hetmet_pga_uncancell
238                                              hetmet_pga_uncancelr
239                                              hetmet_pga_assoc
240                                              hetmet_pga_unassoc
241                                              hetmet_pga_copy
242                                              hetmet_pga_drop
243                                              hetmet_pga_swap
244                                              hetmet_pga_applyl
245                                              hetmet_pga_applyr
246                                              hetmet_pga_curryl
247                                              hetmet_pga_curryr)
248                                }
249                        else return ds_binds
250
251         ; dumpIfSet_dyn dflags Opt_D_coqpass "Coq Pass Output" $ text $ coqPassCoreToString ds_binds'
252
253         ; dumpIfSet_dyn dflags Opt_D_dump_coqpass "After Coq Pass" (text $ showSDoc $ pprCoreBindings ds_binds')
254
255         ; endPass dflags CoreDesugar ds_binds' ds_rules_for_imps
256
257         ; let used_names = mkUsedNames tcg_env
258         ; deps <- mkDependencies tcg_env
259
260         ; let mod_guts = ModGuts {      
261                 mg_module       = mod,
262                 mg_boot         = isHsBoot hsc_src,
263                 mg_exports      = exports,
264                 mg_deps         = deps,
265                 mg_used_names   = used_names,
266                 mg_dir_imps     = imp_mods imports,
267                 mg_rdr_env      = rdr_env,
268                 mg_fix_env      = fix_env,
269                 mg_warns        = warns,
270                 mg_anns         = anns,
271                 mg_types        = type_env,
272                 mg_insts        = insts,
273                 mg_fam_insts    = fam_insts,
274                 mg_inst_env     = inst_env,
275                 mg_fam_inst_env = fam_inst_env,
276                 mg_rules        = ds_rules_for_imps,
277                 mg_binds        = ds_binds',
278                 mg_foreign      = ds_fords,
279                 mg_hpc_info     = ds_hpc_info,
280                 mg_modBreaks    = modBreaks,
281                 mg_vect_decls   = ds_vects,
282                 mg_vect_info    = noVectInfo
283               }
284         ; return (msgs, Just mod_guts)
285         }}}
286
287 dsImpSpecs :: [LTcSpecPrag] -> DsM (OrdList (Id,CoreExpr), [CoreRule])
288 dsImpSpecs imp_specs
289  = do { spec_prs <- mapMaybeM (dsSpec Nothing) imp_specs
290       ; let (spec_binds, spec_rules) = unzip spec_prs
291       ; return (concatOL spec_binds, spec_rules) }
292
293 combineEvBinds :: [DsEvBind] -> [(Id,CoreExpr)] -> [CoreBind]
294 -- Top-level bindings can include coercion bindings, but not via superclasses
295 -- See Note [Top-level evidence]
296 combineEvBinds [] val_prs 
297   = [Rec val_prs]
298 combineEvBinds (LetEvBind (NonRec b r) : bs) val_prs
299   | isId b    = combineEvBinds bs ((b,r):val_prs)
300   | otherwise = NonRec b r : combineEvBinds bs val_prs
301 combineEvBinds (LetEvBind (Rec prs) : bs) val_prs 
302   = combineEvBinds bs (prs ++ val_prs)
303 combineEvBinds (CaseEvBind x _ _ : _) _
304   = pprPanic "topEvBindPairs" (ppr x)
305 \end{code}
306
307 Note [Top-level evidence]
308 ~~~~~~~~~~~~~~~~~~~~~~~~~
309 Top-level evidence bindings may be mutually recursive with the top-level value
310 bindings, so we must put those in a Rec.  But we can't put them *all* in a Rec
311 because the occurrence analyser doesn't teke account of type/coercion variables
312 when computing dependencies.  
313
314 So we pull out the type/coercion variables (which are in dependency order),
315 and Rec the rest.
316
317
318 \begin{code}
319 mkAutoScc :: DynFlags -> Module -> NameSet -> AutoScc
320 mkAutoScc dflags mod exports
321   | not opt_SccProfilingOn      -- No profiling
322   = NoSccs              
323     -- Add auto-scc on all top-level things
324   | dopt Opt_AutoSccsOnAllToplevs dflags
325   = AddSccs mod (\id -> not $ isDerivedOccName $ getOccName id)
326     -- See #1641.  This is pretty yucky, but I can't see a better way
327     -- to identify compiler-generated Ids, and at least this should
328     -- catch them all.
329     -- Only on exported things
330   | dopt Opt_AutoSccsOnExportedToplevs dflags
331   = AddSccs mod (\id -> idName id `elemNameSet` exports)
332   | otherwise
333   = NoSccs
334
335 deSugarExpr :: HscEnv
336             -> Module -> GlobalRdrEnv -> TypeEnv 
337             -> LHsExpr Id
338             -> IO (Messages, Maybe CoreExpr)
339 -- Prints its own errors; returns Nothing if error occurred
340
341 deSugarExpr hsc_env this_mod rdr_env type_env tc_expr = do
342     let dflags = hsc_dflags hsc_env
343     showPass dflags "Desugar"
344
345     -- Do desugaring
346     (msgs, mb_core_expr) <- initDs hsc_env this_mod rdr_env type_env $
347                                    dsLExpr tc_expr
348
349     case mb_core_expr of
350       Nothing   -> return (msgs, Nothing)
351       Just expr -> do
352
353         -- Dump output
354         dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr)
355
356         return (msgs, Just expr)
357 \end{code}
358
359 %************************************************************************
360 %*                                                                      *
361 %*              Add rules and export flags to binders
362 %*                                                                      *
363 %************************************************************************
364
365 \begin{code}
366 addExportFlagsAndRules 
367     :: HscTarget -> NameSet -> NameSet -> [CoreRule]
368     -> [(Id, t)] -> [(Id, t)]
369 addExportFlagsAndRules target exports keep_alive rules prs
370   = mapFst add_one prs
371   where
372     add_one bndr = add_rules name (add_export name bndr)
373        where
374          name = idName bndr
375
376     ---------- Rules --------
377         -- See Note [Attach rules to local ids]
378         -- NB: the binder might have some existing rules,
379         -- arising from specialisation pragmas
380     add_rules name bndr
381         | Just rules <- lookupNameEnv rule_base name
382         = bndr `addIdSpecialisations` rules
383         | otherwise
384         = bndr
385     rule_base = extendRuleBaseList emptyRuleBase rules
386
387     ---------- Export flag --------
388     -- See Note [Adding export flags]
389     add_export name bndr
390         | dont_discard name = setIdExported bndr
391         | otherwise         = bndr
392
393     dont_discard :: Name -> Bool
394     dont_discard name = is_exported name
395                      || name `elemNameSet` keep_alive
396
397         -- In interactive mode, we don't want to discard any top-level
398         -- entities at all (eg. do not inline them away during
399         -- simplification), and retain them all in the TypeEnv so they are
400         -- available from the command line.
401         --
402         -- isExternalName separates the user-defined top-level names from those
403         -- introduced by the type checker.
404     is_exported :: Name -> Bool
405     is_exported | target == HscInterpreted = isExternalName
406                 | otherwise                = (`elemNameSet` exports)
407 \end{code}
408
409
410 Note [Adding export flags]
411 ~~~~~~~~~~~~~~~~~~~~~~~~~~
412 Set the no-discard flag if either 
413         a) the Id is exported
414         b) it's mentioned in the RHS of an orphan rule
415         c) it's in the keep-alive set
416
417 It means that the binding won't be discarded EVEN if the binding
418 ends up being trivial (v = w) -- the simplifier would usually just 
419 substitute w for v throughout, but we don't apply the substitution to
420 the rules (maybe we should?), so this substitution would make the rule
421 bogus.
422
423 You might wonder why exported Ids aren't already marked as such;
424 it's just because the type checker is rather busy already and
425 I didn't want to pass in yet another mapping.
426
427 Note [Attach rules to local ids]
428 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
429 Find the rules for locally-defined Ids; then we can attach them
430 to the binders in the top-level bindings
431
432 Reason
433   - It makes the rules easier to look up
434   - It means that transformation rules and specialisations for
435     locally defined Ids are handled uniformly
436   - It keeps alive things that are referred to only from a rule
437     (the occurrence analyser knows about rules attached to Ids)
438   - It makes sure that, when we apply a rule, the free vars
439     of the RHS are more likely to be in scope
440   - The imported rules are carried in the in-scope set
441     which is extended on each iteration by the new wave of
442     local binders; any rules which aren't on the binding will
443     thereby get dropped
444
445
446 %************************************************************************
447 %*                                                                      *
448 %*              Desugaring transformation rules
449 %*                                                                      *
450 %************************************************************************
451
452 \begin{code}
453 dsRule :: LRuleDecl Id -> DsM (Maybe CoreRule)
454 dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
455   = putSrcSpanDs loc $ 
456     do  { let bndrs' = [var | RuleBndr (L _ var) <- vars]
457
458         ; lhs' <- unsetOptM Opt_EnableRewriteRules $
459                   unsetOptM Opt_WarnIdentities $
460                   dsLExpr lhs   -- Note [Desugaring RULE left hand sides]
461
462         ; rhs' <- dsLExpr rhs
463
464         -- Substitute the dict bindings eagerly,
465         -- and take the body apart into a (f args) form
466         ; case decomposeRuleLhs bndrs' lhs' of {
467                 Left msg -> do { warnDs msg; return Nothing } ;
468                 Right (final_bndrs, fn_id, args) -> do
469         
470         { let is_local = isLocalId fn_id
471                 -- NB: isLocalId is False of implicit Ids.  This is good becuase
472                 -- we don't want to attach rules to the bindings of implicit Ids, 
473                 -- because they don't show up in the bindings until just before code gen
474               fn_name   = idName fn_id
475               final_rhs = simpleOptExpr rhs'    -- De-crap it
476               rule      = mkRule False {- Not auto -} is_local 
477                                  name act fn_name final_bndrs args final_rhs
478         ; return (Just rule)
479         } } }
480 \end{code}
481
482 Note [Desugaring RULE left hand sides]
483 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
484 For the LHS of a RULE we do *not* want to desugar
485     [x]   to    build (\cn. x `c` n)
486 We want to leave explicit lists simply as chains
487 of cons's. We can achieve that slightly indirectly by
488 switching off EnableRewriteRules.  See DsExpr.dsExplicitList.
489
490 That keeps the desugaring of list comprehensions simple too.
491
492 Nor do we want to warn of conversion identities on the LHS;
493 the rule is precisly to optimise them:
494   {-# RULES "fromRational/id" fromRational = id :: Rational -> Rational #-}
495
496
497 %************************************************************************
498 %*                                                                      *
499 %*              Desugaring vectorisation declarations
500 %*                                                                      *
501 %************************************************************************
502
503 \begin{code}
504 dsVect :: LVectDecl Id -> DsM CoreVect
505 dsVect (L loc (HsVect v rhs))
506   = putSrcSpanDs loc $ 
507     do { rhs' <- fmapMaybeM dsLExpr rhs
508        ; return $ Vect (unLoc v) rhs'
509            }
510 -- dsVect (L loc (HsVect v Nothing))
511 --   = return $ Vect v Nothing
512 -- dsVect (L loc (HsVect v (Just rhs)))
513 --   = putSrcSpanDs loc $ 
514 --     do { rhs' <- dsLExpr rhs
515 --        ; return $ Vect v (Just rhs')
516 --       }
517 \end{code}