2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
6 The Desugarer: turning HsSyn into Core.
9 module Desugar ( deSugar, deSugarExpr ) where
21 import CoqPass ( coqPassCoreToString, coqPassCoreToCore )
27 import DsExpr () -- Forces DsExpr to be compiled; DsBinds only
28 -- depends on DsExpr.hi-boot.
34 import CoreMonad ( endPass, CoreToDo(..) )
52 %************************************************************************
54 %* The main function: deSugar
56 %************************************************************************
60 -- | Main entry point to the desugarer.
61 deSugar :: HscEnv -> ModLocation -> TcGblEnv -> IO (Messages, Maybe ModGuts)
62 -- Can modify PCS by faulting in more declarations
66 tcg_env@(TcGblEnv { tcg_mod = mod,
68 tcg_type_env = type_env,
69 tcg_imports = imports,
70 tcg_exports = exports,
72 tcg_rdr_env = rdr_env,
73 tcg_fix_env = fix_env,
74 tcg_inst_env = inst_env,
75 tcg_fam_inst_env = fam_inst_env,
79 tcg_imp_specs = imp_specs,
80 tcg_ev_binds = ev_binds,
85 tcg_fam_insts = fam_insts,
86 tcg_hpc = other_hpc_info })
88 = do { let dflags = hsc_dflags hsc_env
89 ; showPass dflags "Desugar"
91 -- Desugar the program
92 ; let export_set = availsToNameSet exports
93 ; let auto_scc = mkAutoScc dflags mod export_set
94 ; let target = hscTarget dflags
95 ; let hpcInfo = emptyHpcInfo other_hpc_info
99 return (emptyMessages,
100 Just ([], nilOL, [], [], NoStubs, hpcInfo, emptyModBreaks, undefined, undefined
127 (binds_cvr,ds_hpc_info, modBreaks)
129 || target == HscInterpreted)
130 && (not (isHsBoot hsc_src))
131 then addCoverageTicksToBinds dflags mod mod_loc
132 (typeEnvTyCons type_env) binds
133 else return (binds, hpcInfo, emptyModBreaks)
134 initDs hsc_env mod rdr_env type_env $ do
135 do { ds_ev_binds <- dsEvBinds ev_binds
136 ; core_prs <- dsTopLHsBinds auto_scc binds_cvr
137 ; (spec_prs, spec_rules) <- dsImpSpecs imp_specs
138 ; (ds_fords, foreign_prs) <- dsForeigns fords
139 ; ds_rules <- mapMaybeM dsRule rules
140 ; ds_vects <- mapM dsVect vects
141 ; hetmet_brak <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_brak_name else return undefined
142 ; hetmet_esc <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_esc_name else return undefined
143 ; hetmet_flatten <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_flatten_name else return undefined
144 ; hetmet_unflatten <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_unflatten_name else return undefined
145 ; hetmet_flattened_id <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_flattened_id_name else return undefined
146 ; hetmet_PGArrow <- if dopt Opt_F_coqpass dflags then dsLookupTyCon hetmet_PGArrow_name else return undefined
147 ; hetmet_PGArrow_unit <- if dopt Opt_F_coqpass dflags then dsLookupTyCon hetmet_PGArrow_unit_name else return undefined
148 ; hetmet_PGArrow_tensor <- if dopt Opt_F_coqpass dflags then dsLookupTyCon hetmet_PGArrow_tensor_name else return undefined
149 ; hetmet_PGArrow_exponent <- if dopt Opt_F_coqpass dflags then dsLookupTyCon hetmet_PGArrow_exponent_name else return undefined
150 ; hetmet_pga_id <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_id_name else return undefined
151 ; hetmet_pga_comp <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_comp_name else return undefined
152 ; hetmet_pga_first <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_first_name else return undefined
153 ; hetmet_pga_second <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_second_name else return undefined
154 ; hetmet_pga_cancell <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_cancell_name else return undefined
155 ; hetmet_pga_cancelr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_cancelr_name else return undefined
156 ; hetmet_pga_uncancell <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_uncancell_name else return undefined
157 ; hetmet_pga_uncancelr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_uncancelr_name else return undefined
158 ; hetmet_pga_assoc <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_assoc_name else return undefined
159 ; hetmet_pga_unassoc <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_unassoc_name else return undefined
160 ; hetmet_pga_copy <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_copy_name else return undefined
161 ; hetmet_pga_drop <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_drop_name else return undefined
162 ; hetmet_pga_swap <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_swap_name else return undefined
163 ; hetmet_pga_applyl <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_applyl_name else return undefined
164 ; hetmet_pga_applyr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_applyr_name else return undefined
165 ; hetmet_pga_curryl <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_curryl_name else return undefined
166 ; hetmet_pga_curryr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_curryr_name else return undefined
168 | opt_Hpc = hpcInitCode mod ds_hpc_info
170 ; return ( ds_ev_binds
171 , foreign_prs `appOL` core_prs `appOL` spec_prs
172 , spec_rules ++ ds_rules, ds_vects
173 , ds_fords `appendStubC` hpc_init
174 , ds_hpc_info, modBreaks, hetmet_brak, hetmet_esc
177 , hetmet_flattened_id
179 , hetmet_PGArrow_unit
180 , hetmet_PGArrow_tensor
181 , hetmet_PGArrow_exponent
188 , hetmet_pga_uncancell
189 , hetmet_pga_uncancelr
202 Nothing -> return (msgs, Nothing) ;
203 Just (ds_ev_binds, all_prs, all_rules, ds_vects, ds_fords,ds_hpc_info, modBreaks
204 , hetmet_brak, hetmet_esc
207 , hetmet_flattened_id
209 , hetmet_PGArrow_unit
210 , hetmet_PGArrow_tensor
211 , hetmet_PGArrow_exponent
218 , hetmet_pga_uncancell
219 , hetmet_pga_uncancelr
228 , hetmet_pga_curryr) -> do
230 { -- Add export flags to bindings
231 keep_alive <- readIORef keep_var
232 ; let (rules_for_locals, rules_for_imps)
233 = partition isLocalRule all_rules
234 final_prs = addExportFlagsAndRules target
235 export_set keep_alive rules_for_locals (fromOL all_prs)
237 final_pgm = simplifyBinds $ combineEvBinds ds_ev_binds final_prs
238 -- Notice that we put the whole lot in a big Rec, even the foreign binds
239 -- When compiling PrelFloat, which defines data Float = F# Float#
240 -- we want F# to be in scope in the foreign marshalling code!
241 -- You might think it doesn't matter, but the simplifier brings all top-level
242 -- things into the in-scope set before simplifying; so we get no unfolding for F#!
244 -- Lint result if necessary, and print
245 ; dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared, before opt" $
246 (vcat [ pprCoreBindings final_pgm
247 , pprRules rules_for_imps ])
249 ; ds_binds <- if dopt Opt_F_coqpass dflags
250 then do { us <- mkSplitUniqSupply '~'
251 ; let do_flatten = dopt Opt_F_flatten dflags
252 ; let do_skolemize = dopt Opt_F_skolemize dflags
253 ; return (coqPassCoreToCore
265 hetmet_PGArrow_tensor
266 hetmet_PGArrow_exponent
285 else return final_pgm
287 ; (ds_binds', ds_rules_for_imps) <- simpleOptPgm dflags ds_binds rules_for_imps
288 -- The simpleOptPgm gets rid of type
289 -- bindings plus any stupid dead code
291 ; dumpIfSet_dyn dflags Opt_D_dump_proofs "Coq Pass Output" $ text $ coqPassCoreToString ds_binds'
293 ; dumpIfSet_dyn dflags Opt_D_coqpass "After Coq Pass" (text $ showSDoc $ pprCoreBindings ds_binds')
295 ; endPass dflags CoreDesugar ds_binds' ds_rules_for_imps
297 ; let used_names = mkUsedNames tcg_env
298 ; deps <- mkDependencies tcg_env
300 ; let mod_guts = ModGuts {
302 mg_boot = isHsBoot hsc_src,
303 mg_exports = exports,
305 mg_used_names = used_names,
306 mg_dir_imps = imp_mods imports,
307 mg_rdr_env = rdr_env,
308 mg_fix_env = fix_env,
313 mg_fam_insts = fam_insts,
314 mg_inst_env = inst_env,
315 mg_fam_inst_env = fam_inst_env,
316 mg_rules = ds_rules_for_imps,
317 mg_binds = ds_binds',
318 mg_foreign = ds_fords,
319 mg_hpc_info = ds_hpc_info,
320 mg_modBreaks = modBreaks,
321 mg_vect_decls = ds_vects,
322 mg_vect_info = noVectInfo
324 ; return (msgs, Just mod_guts)
327 dsImpSpecs :: [LTcSpecPrag] -> DsM (OrdList (Id,CoreExpr), [CoreRule])
329 = do { spec_prs <- mapMaybeM (dsSpec Nothing) imp_specs
330 ; let (spec_binds, spec_rules) = unzip spec_prs
331 ; return (concatOL spec_binds, spec_rules) }
333 combineEvBinds :: [DsEvBind] -> [(Id,CoreExpr)] -> [CoreBind]
334 -- Top-level bindings can include coercion bindings, but not via superclasses
335 -- See Note [Top-level evidence]
336 combineEvBinds [] val_prs
338 combineEvBinds (LetEvBind (NonRec b r) : bs) val_prs
339 | isId b = combineEvBinds bs ((b,r):val_prs)
340 | otherwise = NonRec b r : combineEvBinds bs val_prs
341 combineEvBinds (LetEvBind (Rec prs) : bs) val_prs
342 = combineEvBinds bs (prs ++ val_prs)
343 combineEvBinds (CaseEvBind x _ _ : _) _
344 = pprPanic "topEvBindPairs" (ppr x)
347 Note [Top-level evidence]
348 ~~~~~~~~~~~~~~~~~~~~~~~~~
349 Top-level evidence bindings may be mutually recursive with the top-level value
350 bindings, so we must put those in a Rec. But we can't put them *all* in a Rec
351 because the occurrence analyser doesn't teke account of type/coercion variables
352 when computing dependencies.
354 So we pull out the type/coercion variables (which are in dependency order),
359 mkAutoScc :: DynFlags -> Module -> NameSet -> AutoScc
360 mkAutoScc dflags mod exports
361 | not opt_SccProfilingOn -- No profiling
363 -- Add auto-scc on all top-level things
364 | dopt Opt_AutoSccsOnAllToplevs dflags
365 = AddSccs mod (\id -> not $ isDerivedOccName $ getOccName id)
366 -- See #1641. This is pretty yucky, but I can't see a better way
367 -- to identify compiler-generated Ids, and at least this should
369 -- Only on exported things
370 | dopt Opt_AutoSccsOnExportedToplevs dflags
371 = AddSccs mod (\id -> idName id `elemNameSet` exports)
375 deSugarExpr :: HscEnv
376 -> Module -> GlobalRdrEnv -> TypeEnv
378 -> IO (Messages, Maybe CoreExpr)
379 -- Prints its own errors; returns Nothing if error occurred
381 deSugarExpr hsc_env this_mod rdr_env type_env tc_expr = do
382 let dflags = hsc_dflags hsc_env
383 showPass dflags "Desugar"
386 (msgs, mb_core_expr) <- initDs hsc_env this_mod rdr_env type_env $
390 Nothing -> return (msgs, Nothing)
394 dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr)
396 return (msgs, Just expr)
399 %************************************************************************
401 %* Add rules and export flags to binders
403 %************************************************************************
406 addExportFlagsAndRules
407 :: HscTarget -> NameSet -> NameSet -> [CoreRule]
408 -> [(Id, t)] -> [(Id, t)]
409 addExportFlagsAndRules target exports keep_alive rules prs
412 add_one bndr = add_rules name (add_export name bndr)
416 ---------- Rules --------
417 -- See Note [Attach rules to local ids]
418 -- NB: the binder might have some existing rules,
419 -- arising from specialisation pragmas
421 | Just rules <- lookupNameEnv rule_base name
422 = bndr `addIdSpecialisations` rules
425 rule_base = extendRuleBaseList emptyRuleBase rules
427 ---------- Export flag --------
428 -- See Note [Adding export flags]
430 | dont_discard name = setIdExported bndr
433 dont_discard :: Name -> Bool
434 dont_discard name = is_exported name
435 || name `elemNameSet` keep_alive
437 -- In interactive mode, we don't want to discard any top-level
438 -- entities at all (eg. do not inline them away during
439 -- simplification), and retain them all in the TypeEnv so they are
440 -- available from the command line.
442 -- isExternalName separates the user-defined top-level names from those
443 -- introduced by the type checker.
444 is_exported :: Name -> Bool
445 is_exported | target == HscInterpreted = isExternalName
446 | otherwise = (`elemNameSet` exports)
450 Note [Adding export flags]
451 ~~~~~~~~~~~~~~~~~~~~~~~~~~
452 Set the no-discard flag if either
453 a) the Id is exported
454 b) it's mentioned in the RHS of an orphan rule
455 c) it's in the keep-alive set
457 It means that the binding won't be discarded EVEN if the binding
458 ends up being trivial (v = w) -- the simplifier would usually just
459 substitute w for v throughout, but we don't apply the substitution to
460 the rules (maybe we should?), so this substitution would make the rule
463 You might wonder why exported Ids aren't already marked as such;
464 it's just because the type checker is rather busy already and
465 I didn't want to pass in yet another mapping.
467 Note [Attach rules to local ids]
468 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
469 Find the rules for locally-defined Ids; then we can attach them
470 to the binders in the top-level bindings
473 - It makes the rules easier to look up
474 - It means that transformation rules and specialisations for
475 locally defined Ids are handled uniformly
476 - It keeps alive things that are referred to only from a rule
477 (the occurrence analyser knows about rules attached to Ids)
478 - It makes sure that, when we apply a rule, the free vars
479 of the RHS are more likely to be in scope
480 - The imported rules are carried in the in-scope set
481 which is extended on each iteration by the new wave of
482 local binders; any rules which aren't on the binding will
486 %************************************************************************
488 %* Desugaring transformation rules
490 %************************************************************************
493 dsRule :: LRuleDecl Id -> DsM (Maybe CoreRule)
494 dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
496 do { let bndrs' = [var | RuleBndr (L _ var) <- vars]
498 ; lhs' <- unsetOptM Opt_EnableRewriteRules $
499 unsetOptM Opt_WarnIdentities $
500 dsLExpr lhs -- Note [Desugaring RULE left hand sides]
502 ; rhs' <- dsLExpr rhs
504 -- Substitute the dict bindings eagerly,
505 -- and take the body apart into a (f args) form
506 ; case decomposeRuleLhs bndrs' lhs' of {
507 Left msg -> do { warnDs msg; return Nothing } ;
508 Right (final_bndrs, fn_id, args) -> do
510 { let is_local = isLocalId fn_id
511 -- NB: isLocalId is False of implicit Ids. This is good becuase
512 -- we don't want to attach rules to the bindings of implicit Ids,
513 -- because they don't show up in the bindings until just before code gen
514 fn_name = idName fn_id
515 final_rhs = simpleOptExpr rhs' -- De-crap it
516 rule = mkRule False {- Not auto -} is_local
517 name act fn_name final_bndrs args final_rhs
522 Note [Desugaring RULE left hand sides]
523 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
524 For the LHS of a RULE we do *not* want to desugar
525 [x] to build (\cn. x `c` n)
526 We want to leave explicit lists simply as chains
527 of cons's. We can achieve that slightly indirectly by
528 switching off EnableRewriteRules. See DsExpr.dsExplicitList.
530 That keeps the desugaring of list comprehensions simple too.
532 Nor do we want to warn of conversion identities on the LHS;
533 the rule is precisly to optimise them:
534 {-# RULES "fromRational/id" fromRational = id :: Rational -> Rational #-}
537 %************************************************************************
539 %* Desugaring vectorisation declarations
541 %************************************************************************
544 dsVect :: LVectDecl Id -> DsM CoreVect
545 dsVect (L loc (HsVect v rhs))
547 do { rhs' <- fmapMaybeM dsLExpr rhs
548 ; return $ Vect (unLoc v) rhs'
550 -- dsVect (L loc (HsVect v Nothing))
551 -- = return $ Vect v Nothing
552 -- dsVect (L loc (HsVect v (Just rhs)))
553 -- = putSrcSpanDs loc $
554 -- do { rhs' <- dsLExpr rhs
555 -- ; return $ Vect v (Just rhs')
563 -- Simplification routines run before the flattener. We can't use
564 -- simpleOptPgm -- it doesn't preserve the order of subexpressions or
565 -- let-binding groups.
567 simplify :: Expr CoreBndr -> Expr CoreBndr
568 simplify (Var v) = Var v
569 simplify (App e1 e2) = App (simplify e1) (simplify e2)
570 simplify (Lit lit) = Lit lit
571 simplify (Note note e) = Note note (simplify e)
572 simplify (Cast e co) = if tcEqType (fst $ coercionKind co) (snd $ coercionKind co)
574 else Cast (simplify e) co
575 simplify (Lam v e) = Lam v (simplify e)
576 simplify (Type t) = Type t
577 simplify (Case e b ty as) = Case (simplify e) b ty (map (\(a,b,e) -> (a,b,simplify e)) as)
578 simplify (Let bind body) = foldr Let (simplify body) (simplifyBind bind)
580 simplifyBind :: Bind CoreBndr -> [Bind CoreBndr]
581 simplifyBind (NonRec b e) = [NonRec b (simplify e)]
582 simplifyBind (Rec []) = []
583 simplifyBind (Rec (rbs@((b,e):rbs'))) =
584 if or $ map (\x -> elemUFM x (exprFreeIds e)) (map fst rbs)
585 then [Rec (map (\(v,e) -> (v,simplify e)) rbs)]
586 else (NonRec b (simplify e)):(simplifyBind $ Rec rbs')
588 simplifyBinds = concatMap simplifyBind