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
22 import CoqPass ( coqPassCoreToString, coqPassCoreToCore )
28 import DsExpr () -- Forces DsExpr to be compiled; DsBinds only
29 -- depends on DsExpr.hi-boot.
35 import CoreMonad ( endPass, CoreToDo(..) )
53 %************************************************************************
55 %* The main function: deSugar
57 %************************************************************************
61 -- | Main entry point to the desugarer.
62 deSugar :: HscEnv -> ModLocation -> TcGblEnv -> IO (Messages, Maybe ModGuts)
63 -- Can modify PCS by faulting in more declarations
67 tcg_env@(TcGblEnv { tcg_mod = mod,
69 tcg_type_env = type_env,
70 tcg_imports = imports,
71 tcg_exports = exports,
73 tcg_rdr_env = rdr_env,
74 tcg_fix_env = fix_env,
75 tcg_inst_env = inst_env,
76 tcg_fam_inst_env = fam_inst_env,
80 tcg_imp_specs = imp_specs,
81 tcg_ev_binds = ev_binds,
86 tcg_fam_insts = fam_insts,
87 tcg_hpc = other_hpc_info })
89 = do { let dflags = hsc_dflags hsc_env
90 ; showPass dflags "Desugar"
92 -- Desugar the program
93 ; let export_set = availsToNameSet exports
94 ; let auto_scc = mkAutoScc dflags mod export_set
95 ; let target = hscTarget dflags
96 ; let hpcInfo = emptyHpcInfo other_hpc_info
100 return (emptyMessages,
101 Just ([], nilOL, [], [], NoStubs, hpcInfo, emptyModBreaks, undefined, undefined
128 (binds_cvr,ds_hpc_info, modBreaks)
130 || target == HscInterpreted)
131 && (not (isHsBoot hsc_src))
132 then addCoverageTicksToBinds dflags mod mod_loc
133 (typeEnvTyCons type_env) binds
134 else return (binds, hpcInfo, emptyModBreaks)
135 initDs hsc_env mod rdr_env type_env $ do
136 do { ds_ev_binds <- dsEvBinds ev_binds
137 ; core_prs <- dsTopLHsBinds auto_scc binds_cvr
138 ; (spec_prs, spec_rules) <- dsImpSpecs imp_specs
139 ; (ds_fords, foreign_prs) <- dsForeigns fords
140 ; ds_rules <- mapMaybeM dsRule rules
141 ; ds_vects <- mapM dsVect vects
142 ; hetmet_brak <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_brak_name else return undefined
143 ; hetmet_esc <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_esc_name else return undefined
144 ; hetmet_flatten <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_flatten_name else return undefined
145 ; hetmet_unflatten <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_unflatten_name else return undefined
146 ; hetmet_flattened_id <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_flattened_id_name else return undefined
147 ; hetmet_PGArrow <- if dopt Opt_F_coqpass dflags then dsLookupTyCon hetmet_PGArrow_name else return undefined
148 ; hetmet_PGArrow_unit <- if dopt Opt_F_coqpass dflags then dsLookupTyCon hetmet_PGArrow_unit_name else return undefined
149 ; hetmet_PGArrow_tensor <- if dopt Opt_F_coqpass dflags then dsLookupTyCon hetmet_PGArrow_tensor_name else return undefined
150 ; hetmet_PGArrow_exponent <- if dopt Opt_F_coqpass dflags then dsLookupTyCon hetmet_PGArrow_exponent_name else return undefined
151 ; hetmet_pga_id <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_id_name else return undefined
152 ; hetmet_pga_comp <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_comp_name else return undefined
153 ; hetmet_pga_first <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_first_name else return undefined
154 ; hetmet_pga_second <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_second_name else return undefined
155 ; hetmet_pga_cancell <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_cancell_name else return undefined
156 ; hetmet_pga_cancelr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_cancelr_name else return undefined
157 ; hetmet_pga_uncancell <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_uncancell_name else return undefined
158 ; hetmet_pga_uncancelr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_uncancelr_name else return undefined
159 ; hetmet_pga_assoc <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_assoc_name else return undefined
160 ; hetmet_pga_unassoc <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_unassoc_name else return undefined
161 ; hetmet_pga_copy <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_copy_name else return undefined
162 ; hetmet_pga_drop <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_drop_name else return undefined
163 ; hetmet_pga_swap <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_swap_name else return undefined
164 ; hetmet_pga_applyl <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_applyl_name else return undefined
165 ; hetmet_pga_applyr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_applyr_name else return undefined
166 ; hetmet_pga_curryl <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_curryl_name else return undefined
167 ; hetmet_pga_curryr <- if dopt Opt_F_coqpass dflags then dsLookupGlobalId hetmet_pga_curryr_name else return undefined
169 | opt_Hpc = hpcInitCode mod ds_hpc_info
171 ; return ( ds_ev_binds
172 , foreign_prs `appOL` core_prs `appOL` spec_prs
173 , spec_rules ++ ds_rules, ds_vects
174 , ds_fords `appendStubC` hpc_init
175 , ds_hpc_info, modBreaks, hetmet_brak, hetmet_esc
178 , hetmet_flattened_id
180 , hetmet_PGArrow_unit
181 , hetmet_PGArrow_tensor
182 , hetmet_PGArrow_exponent
189 , hetmet_pga_uncancell
190 , hetmet_pga_uncancelr
203 Nothing -> return (msgs, Nothing) ;
204 Just (ds_ev_binds, all_prs, all_rules, ds_vects, ds_fords,ds_hpc_info, modBreaks
205 , hetmet_brak, hetmet_esc
208 , hetmet_flattened_id
210 , hetmet_PGArrow_unit
211 , hetmet_PGArrow_tensor
212 , hetmet_PGArrow_exponent
219 , hetmet_pga_uncancell
220 , hetmet_pga_uncancelr
229 , hetmet_pga_curryr) -> do
231 { -- Add export flags to bindings
232 keep_alive <- readIORef keep_var
233 ; let (rules_for_locals, rules_for_imps)
234 = partition isLocalRule all_rules
235 final_prs = addExportFlagsAndRules target
236 export_set keep_alive rules_for_locals (fromOL all_prs)
238 final_pgm = simplifyBinds $ combineEvBinds ds_ev_binds final_prs
239 -- Notice that we put the whole lot in a big Rec, even the foreign binds
240 -- When compiling PrelFloat, which defines data Float = F# Float#
241 -- we want F# to be in scope in the foreign marshalling code!
242 -- You might think it doesn't matter, but the simplifier brings all top-level
243 -- things into the in-scope set before simplifying; so we get no unfolding for F#!
245 -- Lint result if necessary, and print
246 ; dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared, before opt" $
247 (vcat [ pprCoreBindings final_pgm
248 , pprRules rules_for_imps ])
250 ; (final_pgm', rules_for_imps') <- if dopt Opt_F_simpleopt_before_flatten dflags
251 then simpleOptPgm dflags final_pgm rules_for_imps
252 else return (final_pgm, rules_for_imps)
254 ; ds_binds <- if dopt Opt_F_coqpass dflags
255 then do { us <- mkSplitUniqSupply '~'
256 ; let do_flatten = dopt Opt_F_flatten dflags
257 ; let do_skolemize = dopt Opt_F_skolemize dflags
258 ; return (coqPassCoreToCore
270 hetmet_PGArrow_tensor
271 hetmet_PGArrow_exponent
290 else return final_pgm
292 ; (ds_binds', ds_rules_for_imps) <- if dopt Opt_F_simpleopt_before_flatten dflags
293 then return (ds_binds, rules_for_imps')
294 else simpleOptPgm dflags ds_binds rules_for_imps'
295 -- The simpleOptPgm gets rid of type
296 -- bindings plus any stupid dead code
298 ; dumpIfSet_dyn dflags Opt_D_dump_proofs "Coq Pass Output" $ text $ coqPassCoreToString ds_binds'
300 ; dumpIfSet_dyn dflags Opt_D_coqpass "After Coq Pass" (text $ showSDoc $ pprCoreBindings ds_binds')
302 ; endPass dflags CoreDesugar ds_binds' ds_rules_for_imps
304 ; let used_names = mkUsedNames tcg_env
305 ; deps <- mkDependencies tcg_env
307 ; let mod_guts = ModGuts {
309 mg_boot = isHsBoot hsc_src,
310 mg_exports = exports,
312 mg_used_names = used_names,
313 mg_dir_imps = imp_mods imports,
314 mg_rdr_env = rdr_env,
315 mg_fix_env = fix_env,
320 mg_fam_insts = fam_insts,
321 mg_inst_env = inst_env,
322 mg_fam_inst_env = fam_inst_env,
323 mg_rules = ds_rules_for_imps,
324 mg_binds = ds_binds',
325 mg_foreign = ds_fords,
326 mg_hpc_info = ds_hpc_info,
327 mg_modBreaks = modBreaks,
328 mg_vect_decls = ds_vects,
329 mg_vect_info = noVectInfo
331 ; return (msgs, Just mod_guts)
334 dsImpSpecs :: [LTcSpecPrag] -> DsM (OrdList (Id,CoreExpr), [CoreRule])
336 = do { spec_prs <- mapMaybeM (dsSpec Nothing) imp_specs
337 ; let (spec_binds, spec_rules) = unzip spec_prs
338 ; return (concatOL spec_binds, spec_rules) }
340 combineEvBinds :: [DsEvBind] -> [(Id,CoreExpr)] -> [CoreBind]
341 -- Top-level bindings can include coercion bindings, but not via superclasses
342 -- See Note [Top-level evidence]
343 combineEvBinds [] val_prs
345 combineEvBinds (LetEvBind (NonRec b r) : bs) val_prs
346 | isId b = combineEvBinds bs ((b,r):val_prs)
347 | otherwise = NonRec b r : combineEvBinds bs val_prs
348 combineEvBinds (LetEvBind (Rec prs) : bs) val_prs
349 = combineEvBinds bs (prs ++ val_prs)
350 combineEvBinds (CaseEvBind x _ _ : _) _
351 = pprPanic "topEvBindPairs" (ppr x)
354 Note [Top-level evidence]
355 ~~~~~~~~~~~~~~~~~~~~~~~~~
356 Top-level evidence bindings may be mutually recursive with the top-level value
357 bindings, so we must put those in a Rec. But we can't put them *all* in a Rec
358 because the occurrence analyser doesn't teke account of type/coercion variables
359 when computing dependencies.
361 So we pull out the type/coercion variables (which are in dependency order),
366 mkAutoScc :: DynFlags -> Module -> NameSet -> AutoScc
367 mkAutoScc dflags mod exports
368 | not opt_SccProfilingOn -- No profiling
370 -- Add auto-scc on all top-level things
371 | dopt Opt_AutoSccsOnAllToplevs dflags
372 = AddSccs mod (\id -> not $ isDerivedOccName $ getOccName id)
373 -- See #1641. This is pretty yucky, but I can't see a better way
374 -- to identify compiler-generated Ids, and at least this should
376 -- Only on exported things
377 | dopt Opt_AutoSccsOnExportedToplevs dflags
378 = AddSccs mod (\id -> idName id `elemNameSet` exports)
382 deSugarExpr :: HscEnv
383 -> Module -> GlobalRdrEnv -> TypeEnv
385 -> IO (Messages, Maybe CoreExpr)
386 -- Prints its own errors; returns Nothing if error occurred
388 deSugarExpr hsc_env this_mod rdr_env type_env tc_expr = do
389 let dflags = hsc_dflags hsc_env
390 showPass dflags "Desugar"
393 (msgs, mb_core_expr) <- initDs hsc_env this_mod rdr_env type_env $
397 Nothing -> return (msgs, Nothing)
401 dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr)
403 return (msgs, Just expr)
406 %************************************************************************
408 %* Add rules and export flags to binders
410 %************************************************************************
413 addExportFlagsAndRules
414 :: HscTarget -> NameSet -> NameSet -> [CoreRule]
415 -> [(Id, t)] -> [(Id, t)]
416 addExportFlagsAndRules target exports keep_alive rules prs
419 add_one bndr = add_rules name (add_export name bndr)
423 ---------- Rules --------
424 -- See Note [Attach rules to local ids]
425 -- NB: the binder might have some existing rules,
426 -- arising from specialisation pragmas
428 | Just rules <- lookupNameEnv rule_base name
429 = bndr `addIdSpecialisations` rules
432 rule_base = extendRuleBaseList emptyRuleBase rules
434 ---------- Export flag --------
435 -- See Note [Adding export flags]
437 | dont_discard name = setIdExported bndr
440 dont_discard :: Name -> Bool
441 dont_discard name = is_exported name
442 || name `elemNameSet` keep_alive
444 -- In interactive mode, we don't want to discard any top-level
445 -- entities at all (eg. do not inline them away during
446 -- simplification), and retain them all in the TypeEnv so they are
447 -- available from the command line.
449 -- isExternalName separates the user-defined top-level names from those
450 -- introduced by the type checker.
451 is_exported :: Name -> Bool
452 is_exported | target == HscInterpreted = isExternalName
453 | otherwise = (`elemNameSet` exports)
457 Note [Adding export flags]
458 ~~~~~~~~~~~~~~~~~~~~~~~~~~
459 Set the no-discard flag if either
460 a) the Id is exported
461 b) it's mentioned in the RHS of an orphan rule
462 c) it's in the keep-alive set
464 It means that the binding won't be discarded EVEN if the binding
465 ends up being trivial (v = w) -- the simplifier would usually just
466 substitute w for v throughout, but we don't apply the substitution to
467 the rules (maybe we should?), so this substitution would make the rule
470 You might wonder why exported Ids aren't already marked as such;
471 it's just because the type checker is rather busy already and
472 I didn't want to pass in yet another mapping.
474 Note [Attach rules to local ids]
475 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
476 Find the rules for locally-defined Ids; then we can attach them
477 to the binders in the top-level bindings
480 - It makes the rules easier to look up
481 - It means that transformation rules and specialisations for
482 locally defined Ids are handled uniformly
483 - It keeps alive things that are referred to only from a rule
484 (the occurrence analyser knows about rules attached to Ids)
485 - It makes sure that, when we apply a rule, the free vars
486 of the RHS are more likely to be in scope
487 - The imported rules are carried in the in-scope set
488 which is extended on each iteration by the new wave of
489 local binders; any rules which aren't on the binding will
493 %************************************************************************
495 %* Desugaring transformation rules
497 %************************************************************************
500 dsRule :: LRuleDecl Id -> DsM (Maybe CoreRule)
501 dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
503 do { let bndrs' = [var | RuleBndr (L _ var) <- vars]
505 ; lhs' <- unsetOptM Opt_EnableRewriteRules $
506 unsetOptM Opt_WarnIdentities $
507 dsLExpr lhs -- Note [Desugaring RULE left hand sides]
509 ; rhs' <- dsLExpr rhs
511 -- Substitute the dict bindings eagerly,
512 -- and take the body apart into a (f args) form
513 ; case decomposeRuleLhs bndrs' lhs' of {
514 Left msg -> do { warnDs msg; return Nothing } ;
515 Right (final_bndrs, fn_id, args) -> do
517 { let is_local = isLocalId fn_id
518 -- NB: isLocalId is False of implicit Ids. This is good becuase
519 -- we don't want to attach rules to the bindings of implicit Ids,
520 -- because they don't show up in the bindings until just before code gen
521 fn_name = idName fn_id
522 final_rhs = simpleOptExpr rhs' -- De-crap it
523 rule = mkRule False {- Not auto -} is_local
524 name act fn_name final_bndrs args final_rhs
529 Note [Desugaring RULE left hand sides]
530 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
531 For the LHS of a RULE we do *not* want to desugar
532 [x] to build (\cn. x `c` n)
533 We want to leave explicit lists simply as chains
534 of cons's. We can achieve that slightly indirectly by
535 switching off EnableRewriteRules. See DsExpr.dsExplicitList.
537 That keeps the desugaring of list comprehensions simple too.
541 Nor do we want to warn of conversion identities on the LHS;
542 the rule is precisly to optimise them:
543 {-# RULES "fromRational/id" fromRational = id :: Rational -> Rational #-}
546 %************************************************************************
548 %* Desugaring vectorisation declarations
550 %************************************************************************
553 dsVect :: LVectDecl Id -> DsM CoreVect
554 dsVect (L loc (HsVect v rhs))
556 do { rhs' <- fmapMaybeM dsLExpr rhs
557 ; return $ Vect (unLoc v) rhs'
559 -- dsVect (L loc (HsVect v Nothing))
560 -- = return $ Vect v Nothing
561 -- dsVect (L loc (HsVect v (Just rhs)))
562 -- = putSrcSpanDs loc $
563 -- do { rhs' <- dsLExpr rhs
564 -- ; return $ Vect v (Just rhs')
572 -- Simplification routines run before the flattener. We can't use
573 -- simpleOptPgm -- it doesn't preserve the order of subexpressions or
574 -- let-binding groups.
576 simplify :: Expr CoreBndr -> Expr CoreBndr
577 simplify (Var v) = Var v
578 simplify (App e1 e2) = App (simplify e1) (simplify e2)
579 simplify (Lit lit) = Lit lit
580 simplify (Note note e) = Note note (simplify e)
581 simplify (Cast e co) = if eqType (fst $ unPair $ coercionKind co) (snd $ unPair $ coercionKind co)
583 else Cast (simplify e) co
584 simplify (Lam v e) = Lam v (simplify e)
585 simplify (Case e b ty as) = Case (simplify e) b ty (map (\(a,b,e) -> (a,b,simplify e)) as)
586 simplify (Let bind body) = foldr Let (simplify body) (simplifyBind bind)
587 simplify (Type t) = Type t
588 simplify (Coercion co) = Coercion co
590 simplifyBind :: Bind CoreBndr -> [Bind CoreBndr]
591 simplifyBind (NonRec b e) = [NonRec b (simplify e)]
592 simplifyBind (Rec []) = []
593 simplifyBind (Rec (rbs@((b,e):rbs'))) =
594 if or $ map (\x -> elemUFM x (exprFreeIds e)) (map fst rbs)
595 then [Rec (map (\(v,e) -> (v,simplify e)) rbs)]
596 else (NonRec b (simplify e)):(simplifyBind $ Rec rbs')
598 simplifyBinds = concatMap simplifyBind