root/compiler/deSugar/Desugar.lhs

Revision 5a0b82706ba93969716addf0a179f8452f19247b, 16.0 KB (checked in by David Terei <davidterei@…>, 8 weeks ago)

Fix GHC API with respect to safe haskell. (#5989)

This fixes haddock so it correctly reports
the safe haskell mode of a module.

  • Property mode set to 100644
Line 
1%
2% (c) The University of Glasgow 2006
3% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4%
5
6The Desugarer: turning HsSyn into Core.
7
8\begin{code}
9{-# OPTIONS -fno-warn-tabs #-}
10-- The above warning supression flag is a temporary kludge.
11-- While working on this module you are encouraged to remove it and
12-- detab the module (please do the detabbing in a separate patch). See
13--     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
14-- for details
15
16module Desugar ( deSugar, deSugarExpr ) where
17
18import DynFlags
19import StaticFlags
20import HscTypes
21import HsSyn
22import TcRnTypes
23import TcRnMonad ( finalSafeMode )
24import MkIface
25import Id
26import Name
27import Type
28import InstEnv
29import Class
30import Avail
31import CoreSyn
32import CoreSubst
33import PprCore
34import DsMonad
35import DsExpr
36import DsBinds
37import DsForeign
38import DsExpr           ()      -- Forces DsExpr to be compiled; DsBinds only
39                                -- depends on DsExpr.hi-boot.
40import Module
41import RdrName
42import NameSet
43import NameEnv
44import Rules
45import CoreMonad        ( endPass, CoreToDo(..) )
46import ErrUtils
47import Outputable
48import SrcLoc
49import Coverage
50import Util
51import MonadUtils
52import OrdList
53import Data.List
54import Data.IORef
55\end{code}
56
57%************************************************************************
58%*                                                                      *
59%*              The main function: deSugar
60%*                                                                      *
61%************************************************************************
62
63\begin{code}
64-- | Main entry point to the desugarer.
65deSugar :: HscEnv -> ModLocation -> TcGblEnv -> IO (Messages, Maybe ModGuts)
66-- Can modify PCS by faulting in more declarations
67
68deSugar hsc_env
69        mod_loc
70        tcg_env@(TcGblEnv { tcg_mod          = mod,
71                            tcg_src          = hsc_src,
72                            tcg_type_env     = type_env,
73                            tcg_imports      = imports,
74                            tcg_exports      = exports,
75                            tcg_keep         = keep_var,
76                            tcg_th_splice_used = tc_splice_used,
77                            tcg_rdr_env      = rdr_env,
78                            tcg_fix_env      = fix_env,
79                            tcg_inst_env     = inst_env,
80                            tcg_fam_inst_env = fam_inst_env,
81                            tcg_warns        = warns,
82                            tcg_anns         = anns,
83                            tcg_binds        = binds,
84                            tcg_imp_specs    = imp_specs,
85                            tcg_dependent_files = dependent_files,
86                            tcg_ev_binds     = ev_binds,
87                            tcg_fords        = fords,
88                            tcg_rules        = rules,
89                            tcg_vects        = vects,
90                            tcg_tcs          = tcs,
91                            tcg_insts        = insts,
92                            tcg_fam_insts    = fam_insts,
93                            tcg_hpc          = other_hpc_info })
94
95  = do { let dflags = hsc_dflags hsc_env
96             platform = targetPlatform dflags
97        ; showPass dflags "Desugar"
98
99        -- Desugar the program
100        ; let export_set = availsToNameSet exports
101        ; let target = hscTarget dflags
102        ; let hpcInfo = emptyHpcInfo other_hpc_info
103        ; (msgs, mb_res)
104              <- case target of
105                   HscNothing ->
106                       return (emptyMessages,
107                               Just ([], nilOL, [], [], NoStubs, hpcInfo, emptyModBreaks))
108                   _        -> do
109
110                     let want_ticks = opt_Hpc
111                                   || target == HscInterpreted
112                                   || (opt_SccProfilingOn
113                                       && case profAuto dflags of
114                                            NoProfAuto -> False
115                                            _          -> True)
116
117                     (binds_cvr,ds_hpc_info, modBreaks)
118                         <- if want_ticks && not (isHsBoot hsc_src)
119                              then addTicksToBinds dflags mod mod_loc export_set
120                                          (typeEnvTyCons type_env) binds
121                              else return (binds, hpcInfo, emptyModBreaks)
122
123                     initDs hsc_env mod rdr_env type_env $ do
124                       do { ds_ev_binds <- dsEvBinds ev_binds
125                          ; core_prs <- dsTopLHsBinds 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                          ; let hpc_init
131                                  | opt_Hpc   = hpcInitCode platform mod ds_hpc_info
132                                  | otherwise = empty
133                          ; return ( ds_ev_binds
134                                   , foreign_prs `appOL` core_prs `appOL` spec_prs
135                                   , spec_rules ++ ds_rules, ds_vects
136                                   , ds_fords `appendStubC` hpc_init
137                                   , ds_hpc_info, modBreaks) }
138
139        ; case mb_res of {
140           Nothing -> return (msgs, Nothing) ;
141           Just (ds_ev_binds, all_prs, all_rules, vects0, ds_fords, ds_hpc_info, modBreaks) -> do
142
143        {       -- Add export flags to bindings
144          keep_alive <- readIORef keep_var
145        ; let (rules_for_locals, rules_for_imps) 
146                   = partition isLocalRule all_rules
147              final_prs = addExportFlagsAndRules target
148                              export_set keep_alive rules_for_locals (fromOL all_prs)
149
150              final_pgm = combineEvBinds ds_ev_binds final_prs
151        -- Notice that we put the whole lot in a big Rec, even the foreign binds
152        -- When compiling PrelFloat, which defines data Float = F# Float#
153        -- we want F# to be in scope in the foreign marshalling code!
154        -- You might think it doesn't matter, but the simplifier brings all top-level
155        -- things into the in-scope set before simplifying; so we get no unfolding for F#!
156
157#ifdef DEBUG
158          -- Debug only as pre-simple-optimisation program may be really big
159        ; endPass dflags CoreDesugar final_pgm rules_for_imps
160#endif
161        ; (ds_binds, ds_rules_for_imps, ds_vects) 
162            <- simpleOptPgm dflags mod final_pgm rules_for_imps vects0
163                         -- The simpleOptPgm gets rid of type
164                         -- bindings plus any stupid dead code
165
166        ; endPass dflags CoreDesugarOpt ds_binds ds_rules_for_imps
167
168        ; let used_names = mkUsedNames tcg_env
169        ; deps <- mkDependencies tcg_env
170
171        ; used_th <- readIORef tc_splice_used
172        ; dep_files <- readIORef dependent_files
173        ; safe_mode <- finalSafeMode dflags tcg_env
174
175        ; let mod_guts = ModGuts {
176                mg_module       = mod,
177                mg_boot         = isHsBoot hsc_src,
178                mg_exports      = exports,
179                mg_deps         = deps,
180                mg_used_names   = used_names,
181                mg_used_th      = used_th,
182                mg_dir_imps     = imp_mods imports,
183                mg_rdr_env      = rdr_env,
184                mg_fix_env      = fix_env,
185                mg_warns        = warns,
186                mg_anns         = anns,
187                mg_tcs          = tcs,
188                mg_insts        = insts,
189                mg_fam_insts    = fam_insts,
190                mg_inst_env     = inst_env,
191                mg_fam_inst_env = fam_inst_env,
192                mg_rules        = ds_rules_for_imps,
193                mg_binds        = ds_binds,
194                mg_foreign      = ds_fords,
195                mg_hpc_info     = ds_hpc_info,
196                mg_modBreaks    = modBreaks,
197                mg_vect_decls   = ds_vects,
198                mg_vect_info    = noVectInfo,
199                mg_safe_haskell = safe_mode,
200                mg_trust_pkg    = imp_trust_own_pkg imports,
201                mg_dependent_files = dep_files
202              }
203        ; return (msgs, Just mod_guts)
204        }}}
205
206dsImpSpecs :: [LTcSpecPrag] -> DsM (OrdList (Id,CoreExpr), [CoreRule])
207dsImpSpecs imp_specs
208 = do { spec_prs <- mapMaybeM (dsSpec Nothing) imp_specs
209      ; let (spec_binds, spec_rules) = unzip spec_prs
210      ; return (concatOL spec_binds, spec_rules) }
211
212combineEvBinds :: [CoreBind] -> [(Id,CoreExpr)] -> [CoreBind]
213-- Top-level bindings can include coercion bindings, but not via superclasses
214-- See Note [Top-level evidence]
215combineEvBinds [] val_prs
216  = [Rec val_prs]
217combineEvBinds (NonRec b r : bs) val_prs
218  | isId b    = combineEvBinds bs ((b,r):val_prs)
219  | otherwise = NonRec b r : combineEvBinds bs val_prs
220combineEvBinds (Rec prs : bs) val_prs
221  = combineEvBinds bs (prs ++ val_prs)
222\end{code}
223
224Note [Top-level evidence]
225~~~~~~~~~~~~~~~~~~~~~~~~~
226Top-level evidence bindings may be mutually recursive with the top-level value
227bindings, so we must put those in a Rec.  But we can't put them *all* in a Rec
228because the occurrence analyser doesn't teke account of type/coercion variables
229when computing dependencies. 
230
231So we pull out the type/coercion variables (which are in dependency order),
232and Rec the rest.
233
234
235\begin{code}
236deSugarExpr :: HscEnv
237            -> Module -> GlobalRdrEnv -> TypeEnv 
238            -> LHsExpr Id
239            -> IO (Messages, Maybe CoreExpr)
240-- Prints its own errors; returns Nothing if error occurred
241
242deSugarExpr hsc_env this_mod rdr_env type_env tc_expr = do
243    let dflags = hsc_dflags hsc_env
244    showPass dflags "Desugar"
245
246    -- Do desugaring
247    (msgs, mb_core_expr) <- initDs hsc_env this_mod rdr_env type_env $
248                                   dsLExpr tc_expr
249
250    case mb_core_expr of
251      Nothing   -> return (msgs, Nothing)
252      Just expr -> do
253
254        -- Dump output
255        dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr)
256
257        return (msgs, Just expr)
258\end{code}
259
260%************************************************************************
261%*                                                                      *
262%*              Add rules and export flags to binders
263%*                                                                      *
264%************************************************************************
265
266\begin{code}
267addExportFlagsAndRules 
268    :: HscTarget -> NameSet -> NameSet -> [CoreRule]
269    -> [(Id, t)] -> [(Id, t)]
270addExportFlagsAndRules target exports keep_alive rules prs
271  = mapFst add_one prs
272  where
273    add_one bndr = add_rules name (add_export name bndr)
274       where
275         name = idName bndr
276
277    ---------- Rules --------
278        -- See Note [Attach rules to local ids]
279        -- NB: the binder might have some existing rules,
280        -- arising from specialisation pragmas
281    add_rules name bndr
282        | Just rules <- lookupNameEnv rule_base name
283        = bndr `addIdSpecialisations` rules
284        | otherwise
285        = bndr
286    rule_base = extendRuleBaseList emptyRuleBase rules
287
288    ---------- Export flag --------
289    -- See Note [Adding export flags]
290    add_export name bndr
291        | dont_discard name = setIdExported bndr
292        | otherwise         = bndr
293
294    dont_discard :: Name -> Bool
295    dont_discard name = is_exported name
296                     || name `elemNameSet` keep_alive
297
298        -- In interactive mode, we don't want to discard any top-level
299        -- entities at all (eg. do not inline them away during
300        -- simplification), and retain them all in the TypeEnv so they are
301        -- available from the command line.
302        --
303        -- isExternalName separates the user-defined top-level names from those
304        -- introduced by the type checker.
305    is_exported :: Name -> Bool
306    is_exported | targetRetainsAllBindings target = isExternalName
307                | otherwise                       = (`elemNameSet` exports)
308\end{code}
309
310
311Note [Adding export flags]
312~~~~~~~~~~~~~~~~~~~~~~~~~~
313Set the no-discard flag if either
314        a) the Id is exported
315        b) it's mentioned in the RHS of an orphan rule
316        c) it's in the keep-alive set
317
318It means that the binding won't be discarded EVEN if the binding
319ends up being trivial (v = w) -- the simplifier would usually just
320substitute w for v throughout, but we don't apply the substitution to
321the rules (maybe we should?), so this substitution would make the rule
322bogus.
323
324You might wonder why exported Ids aren't already marked as such;
325it's just because the type checker is rather busy already and
326I didn't want to pass in yet another mapping.
327
328Note [Attach rules to local ids]
329~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
330Find the rules for locally-defined Ids; then we can attach them
331to the binders in the top-level bindings
332
333Reason
334  - It makes the rules easier to look up
335  - It means that transformation rules and specialisations for
336    locally defined Ids are handled uniformly
337  - It keeps alive things that are referred to only from a rule
338    (the occurrence analyser knows about rules attached to Ids)
339  - It makes sure that, when we apply a rule, the free vars
340    of the RHS are more likely to be in scope
341  - The imported rules are carried in the in-scope set
342    which is extended on each iteration by the new wave of
343    local binders; any rules which aren't on the binding will
344    thereby get dropped
345
346
347%************************************************************************
348%*                                                                      *
349%*              Desugaring transformation rules
350%*                                                                      *
351%************************************************************************
352
353\begin{code}
354dsRule :: LRuleDecl Id -> DsM (Maybe CoreRule)
355dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
356  = putSrcSpanDs loc $ 
357    do  { let bndrs' = [var | RuleBndr (L _ var) <- vars]
358
359        ; lhs' <- unsetDOptM Opt_EnableRewriteRules $
360                  unsetWOptM Opt_WarnIdentities $
361                  dsLExpr lhs   -- Note [Desugaring RULE left hand sides]
362
363        ; rhs' <- dsLExpr rhs
364
365        -- Substitute the dict bindings eagerly,
366        -- and take the body apart into a (f args) form
367        ; case decomposeRuleLhs bndrs' lhs' of {
368                Left msg -> do { warnDs msg; return Nothing } ;
369                Right (final_bndrs, fn_id, args) -> do
370       
371        { let is_local = isLocalId fn_id
372                -- NB: isLocalId is False of implicit Ids.  This is good becuase
373                -- we don't want to attach rules to the bindings of implicit Ids,
374                -- because they don't show up in the bindings until just before code gen
375              fn_name   = idName fn_id
376              final_rhs = simpleOptExpr rhs'    -- De-crap it
377              rule      = mkRule False {- Not auto -} is_local
378                                 name act fn_name final_bndrs args final_rhs
379        ; return (Just rule)
380        } } }
381\end{code}
382
383Note [Desugaring RULE left hand sides]
384~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
385For the LHS of a RULE we do *not* want to desugar
386    [x]   to    build (\cn. x `c` n)
387We want to leave explicit lists simply as chains
388of cons's. We can achieve that slightly indirectly by
389switching off EnableRewriteRules.  See DsExpr.dsExplicitList.
390
391That keeps the desugaring of list comprehensions simple too.
392
393
394
395Nor do we want to warn of conversion identities on the LHS;
396the rule is precisly to optimise them:
397  {-# RULES "fromRational/id" fromRational = id :: Rational -> Rational #-}
398
399
400%************************************************************************
401%*                                                                      *
402%*              Desugaring vectorisation declarations
403%*                                                                      *
404%************************************************************************
405
406\begin{code}
407dsVect :: LVectDecl Id -> DsM CoreVect
408dsVect (L loc (HsVect (L _ v) rhs))
409  = putSrcSpanDs loc $ 
410    do { rhs' <- fmapMaybeM dsLExpr rhs
411       ; return $ Vect v rhs'
412       }
413dsVect (L _loc (HsNoVect (L _ v)))
414  = return $ NoVect v
415dsVect (L _loc (HsVectTypeOut isScalar tycon rhs_tycon))
416  = return $ VectType isScalar tycon' rhs_tycon
417  where
418    tycon' | Just ty <- coreView $ mkTyConTy tycon
419           , (tycon', []) <- splitTyConApp ty      = tycon'
420           | otherwise                             = tycon
421dsVect vd@(L _ (HsVectTypeIn _ _ _))
422  = pprPanic "Desugar.dsVect: unexpected 'HsVectTypeIn'" (ppr vd)
423dsVect (L _loc (HsVectClassOut cls))
424  = return $ VectClass (classTyCon cls)
425dsVect vc@(L _ (HsVectClassIn _))
426  = pprPanic "Desugar.dsVect: unexpected 'HsVectClassIn'" (ppr vc)
427dsVect (L _loc (HsVectInstOut inst))
428  = return $ VectInst (instanceDFunId inst)
429dsVect vi@(L _ (HsVectInstIn _))
430  = pprPanic "Desugar.dsVect: unexpected 'HsVectInstIn'" (ppr vi)
431\end{code}
Note: See TracBrowser for help on using the browser.