Initial checkin of HetMet / -XModalTypes modifications
[ghc-hetmet.git] / compiler / deSugar / Desugar.lhs
index 9616c62..7d0be3f 100644 (file)
@@ -8,6 +8,7 @@ The Desugarer: turning HsSyn into Core.
 \begin{code}
 module Desugar ( deSugar, deSugarExpr ) where
 
+import TysWiredIn (unitDataConId)
 import DynFlags
 import StaticFlags
 import HscTypes
@@ -34,13 +35,14 @@ import CoreMonad    ( endPass, CoreToDo(..) )
 import ErrUtils
 import Outputable
 import SrcLoc
-import Maybes
-import FastString
 import Coverage
 import Util
-
+import MonadUtils
+import OrdList
 import Data.List
 import Data.IORef
+import DsHetMet
+import Control.Exception ( catch, ErrorCall, Exception(..) )
 \end{code}
 
 %************************************************************************
@@ -69,6 +71,7 @@ deSugar hsc_env
                            tcg_warns        = warns,
                            tcg_anns         = anns,
                            tcg_binds        = binds,
+                           tcg_imp_specs    = imp_specs,
                            tcg_ev_binds     = ev_binds,
                            tcg_fords        = fords,
                            tcg_rules        = rules,
@@ -88,7 +91,7 @@ deSugar hsc_env
               <- case target of
                   HscNothing ->
                        return (emptyMessages,
-                               Just ([], [], [], NoStubs, hpcInfo, emptyModBreaks))
+                               Just ([], nilOL, [], NoStubs, hpcInfo, emptyModBreaks))
                    _        -> do
                      (binds_cvr,ds_hpc_info, modBreaks)
                         <- if (opt_Hpc
@@ -98,23 +101,26 @@ deSugar hsc_env
                                                            (typeEnvTyCons type_env) binds 
                               else return (binds, hpcInfo, emptyModBreaks)
                      initDs hsc_env mod rdr_env type_env $ do
-                        ds_ev_binds <- dsEvBinds ev_binds
-                        core_prs <- dsTopLHsBinds auto_scc binds_cvr
-                        (ds_fords, foreign_prs) <- dsForeigns fords
-                        let all_prs = foreign_prs ++ core_prs
-                        mb_rules <- mapM dsRule rules
-                        return (ds_ev_binds, all_prs, mb_rules, ds_fords, ds_hpc_info, modBreaks)
+                      do { ds_ev_binds <- dsEvBinds ev_binds
+                         ; core_prs <- dsTopLHsBinds auto_scc binds_cvr
+                          ; (spec_prs, spec_rules) <- dsImpSpecs imp_specs
+                         ; (ds_fords, foreign_prs) <- dsForeigns fords
+                         ; rules <- mapMaybeM dsRule rules
+                         ; return ( ds_ev_binds
+                                   , foreign_prs `appOL` core_prs `appOL` spec_prs
+                                   , spec_rules ++ rules
+                                   , ds_fords, ds_hpc_info, modBreaks) }
 
        ; case mb_res of {
           Nothing -> return (msgs, Nothing) ;
-          Just (ds_ev_binds, all_prs, mb_rules, ds_fords,ds_hpc_info, modBreaks) -> do
+          Just (ds_ev_binds, all_prs, all_rules, ds_fords,ds_hpc_info, modBreaks) -> do
 
        {       -- Add export flags to bindings
          keep_alive <- readIORef keep_var
        ; let (rules_for_locals, rules_for_imps) 
-                   = partition isLocalRule (catMaybes mb_rules)
+                   = partition isLocalRule all_rules
               final_prs = addExportFlagsAndRules target
-                             export_set keep_alive rules_for_locals all_prs 
+                             export_set keep_alive rules_for_locals (fromOL all_prs)
 
               final_pgm = combineEvBinds ds_ev_binds final_prs
        -- Notice that we put the whole lot in a big Rec, even the foreign binds
@@ -131,10 +137,28 @@ deSugar hsc_env
        ; (ds_binds, ds_rules_for_imps) <- simpleOptPgm dflags final_pgm rules_for_imps
                         -- The simpleOptPgm gets rid of type 
                         -- bindings plus any stupid dead code
-
+{-
+        ; dumpIfSet_dyn dflags Opt_D_dump_proof "input to flattener" (text $ showSDoc $ pprCoreBindings ds_binds)
+        ; let uhandler (err::ErrorCall)
+                      = dumpIfSet_dyn dflags Opt_D_dump_proof "System FC Proof"
+                                       (text $ "\\begin{verbatim}\n" ++
+                                               show err ++
+                                               "\\end{verbatim}\n\n")
+          in (dumpIfSet_dyn dflags Opt_D_dump_proof "System FC Proof" $
+               (vcat (map (\ bind -> let e = case bind of
+                                               NonRec b e -> e
+                                               Rec    lve -> Let (Rec lve) (Var unitDataConId)
+                                     in text $ "\\begin{verbatim}\n" ++
+                                               (showSDoc $ pprCoreBindings ds_binds) ++
+                                               "\\end{verbatim}\n\n" ++
+                                               "$$\n"++
+                                               (core2proofAndShow e) ++
+                                               "$$\n"
+                          ) ds_binds))) `Control.Exception.catch` uhandler
+-}
        ; endPass dflags CoreDesugar ds_binds ds_rules_for_imps
 
-        ; used_names <- mkUsedNames tcg_env
+        ; let used_names = mkUsedNames tcg_env
        ; deps <- mkDependencies tcg_env
 
         ; let mod_guts = ModGuts {     
@@ -163,6 +187,11 @@ deSugar hsc_env
         ; return (msgs, Just mod_guts)
        }}}
 
+dsImpSpecs :: [LTcSpecPrag] -> DsM (OrdList (Id,CoreExpr), [CoreRule])
+dsImpSpecs imp_specs
+ = do { spec_prs <- mapMaybeM (dsSpec Nothing) imp_specs
+      ; let (spec_binds, spec_rules) = unzip spec_prs
+      ; return (concatOL spec_binds, spec_rules) }
 
 combineEvBinds :: [DsEvBind] -> [(Id,CoreExpr)] -> [CoreBind]
 -- Top-level bindings can include coercion bindings, but not via superclasses
@@ -214,7 +243,7 @@ deSugarExpr :: HscEnv
 
 deSugarExpr hsc_env this_mod rdr_env type_env tc_expr = do
     let dflags = hsc_dflags hsc_env
-    showPass dflags "Desugar"
+    showPass dflags "Desugarz"
 
     -- Do desugaring
     (msgs, mb_core_expr) <- initDs hsc_env this_mod rdr_env type_env $
@@ -224,8 +253,10 @@ deSugarExpr hsc_env this_mod rdr_env type_env tc_expr = do
       Nothing   -> return (msgs, Nothing)
       Just expr -> do
 
+{-
         -- Dump output
-        dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr)
+        dumpIfSet_dyn dflags Opt_D_dump_ds    "Desugared"            (text $ "$$\n"++(core2proofAndShow expr)++"$$\n")
+-}
 
         return (msgs, Just expr)
 \end{code}
@@ -329,29 +360,28 @@ dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
   = putSrcSpanDs loc $ 
     do { let bndrs' = [var | RuleBndr (L _ var) <- vars]
 
-       ; lhs' <- unsetOptM Opt_EnableRewriteRules $
-                 dsLExpr lhs   -- Note [Desugaring RULE left hand sides]
+        ; lhs' <- unsetOptM Opt_EnableRewriteRules $
+                  unsetOptM Opt_WarnIdentities $
+                  dsLExpr lhs   -- Note [Desugaring RULE left hand sides]
 
        ; rhs' <- dsLExpr rhs
 
        -- Substitute the dict bindings eagerly,
        -- and take the body apart into a (f args) form
-       ; case decomposeRuleLhs lhs' of {
-               Nothing -> do { warnDs msg; return Nothing } ;
-               Just (fn_id, args) -> do
+       ; case decomposeRuleLhs bndrs' lhs' of {
+               Left msg -> do { warnDs msg; return Nothing } ;
+               Right (final_bndrs, fn_id, args) -> do
        
-       { let local_rule = isLocalId fn_id
+       { let is_local = isLocalId fn_id
                -- NB: isLocalId is False of implicit Ids.  This is good becuase
                -- we don't want to attach rules to the bindings of implicit Ids, 
                -- because they don't show up in the bindings until just before code gen
              fn_name   = idName fn_id
              final_rhs = simpleOptExpr rhs'    -- De-crap it
-             rule      = mkRule local_rule name act fn_name bndrs' args final_rhs
+             rule      = mkRule False {- Not auto -} is_local 
+                                 name act fn_name final_bndrs args final_rhs
        ; return (Just rule)
        } } }
-  where
-    msg = hang (ptext (sLit "RULE left-hand side too complicated to desugar; ignored"))
-            2 (ppr lhs)
 \end{code}
 
 Note [Desugaring RULE left hand sides]
@@ -364,4 +394,6 @@ switching off EnableRewriteRules.  See DsExpr.dsExplicitList.
 
 That keeps the desugaring of list comprehensions simple too.
 
-
+Nor do we want to warn of conversion identities on the LHS;
+the rule is precisly to optimise them:
+  {-# RULES "fromRational/id" fromRational = id :: Rational -> Rational #-}