Merge master into the ghc-new-co branch
authorSimon Peyton Jones <simonpj@microsoft.com>
Fri, 6 May 2011 14:56:06 +0000 (15:56 +0100)
committerSimon Peyton Jones <simonpj@microsoft.com>
Fri, 6 May 2011 14:56:06 +0000 (15:56 +0100)
21 files changed:
1  2 
compiler/deSugar/Check.lhs
compiler/deSugar/DsExpr.lhs
compiler/deSugar/Match.lhs
compiler/ghc.cabal.in
compiler/hsSyn/HsPat.lhs
compiler/hsSyn/HsUtils.lhs
compiler/iface/IfaceSyn.lhs
compiler/main/DynFlags.hs
compiler/prelude/PrelNames.lhs
compiler/rename/RnBinds.lhs
compiler/typecheck/TcArrows.lhs
compiler/typecheck/TcExpr.lhs
compiler/typecheck/TcGenDeriv.lhs
compiler/typecheck/TcHsSyn.lhs
compiler/typecheck/TcMatches.lhs
compiler/typecheck/TcPat.lhs
compiler/typecheck/TcRnDriver.lhs
compiler/typecheck/TcRnMonad.lhs
compiler/typecheck/TcRnTypes.lhs
compiler/typecheck/TcSMonad.lhs
compiler/typecheck/TcUnify.lhs

@@@ -27,6 -27,7 +27,6 @@@ import TysWiredI
  import PrelNames
  import TyCon
  import Type
 -import Unify( dataConCannotMatch )
  import SrcLoc
  import UniqSet
  import Util
@@@ -111,7 -112,8 +111,8 @@@ check :: [EquationInfo] -> ([Exhaustive
    -- if there are view patterns, just give up - don't know what the function is
  check qs = (untidy_warns, shadowed_eqns)
        where
-       (warns, used_nos) = check' ([1..] `zip` map tidy_eqn qs)
+         tidy_qs = map tidy_eqn qs
+       (warns, used_nos) = check' ([1..] `zip` tidy_qs)
        untidy_warns = map untidy_exhaustive warns 
        shadowed_eqns = [eqn | (eqn,i) <- qs `zip` [1..], 
                                not (i `elementOfUniqSet` used_nos)]
@@@ -670,8 -672,6 +671,6 @@@ tidy_pat (CoPat _ pat _)  = tidy_pat pa
  tidy_pat (NPlusKPat id _ _ _) = WildPat (idType (unLoc id))
  tidy_pat (ViewPat _ _ ty)     = WildPat ty
  
- tidy_pat (NPat lit mb_neg eq) = tidyNPat lit mb_neg eq
  tidy_pat pat@(ConPatOut { pat_con = L _ id, pat_args = ps })
    = pat { pat_args = tidy_con id ps }
  
@@@ -695,16 -695,18 +694,18 @@@ tidy_pat (TuplePat ps boxity ty
    where
      arity = length ps
  
- -- Unpack string patterns fully, so we can see when they overlap with
- -- each other, or even explicit lists of Chars.
- tidy_pat (LitPat lit)
+ tidy_pat (NPat lit mb_neg eq) = tidyNPat tidy_lit_pat lit mb_neg eq
+ tidy_pat (LitPat lit)         = tidy_lit_pat lit
+ tidy_lit_pat :: HsLit -> Pat Id
+ -- Unpack string patterns fully, so we can see when they 
+ -- overlap with each other, or even explicit lists of Chars.
+ tidy_lit_pat lit
    | HsString s <- lit
-   = unLoc $ foldr (\c pat -> mkPrefixConPat consDataCon [mk_char_lit c, pat] stringTy)
+   = unLoc $ foldr (\c pat -> mkPrefixConPat consDataCon [mkCharLitPat c, pat] stringTy)
                  (mkPrefixConPat nilDataCon [] stringTy) (unpackFS s)
    | otherwise
    = tidyLitPat lit 
-   where
-     mk_char_lit c = mkPrefixConPat charDataCon [nlLitPat (HsCharPrim c)] charTy
  
  -----------------
  tidy_con :: DataCon -> HsConPatDetails Id -> HsConPatDetails Id
@@@ -49,8 -49,8 +49,8 @@@ import DynFlag
  import StaticFlags
  import CostCentre
  import Id
 -import Var
  import VarSet
 +import VarEnv
  import DataCon
  import TysWiredIn
  import BasicTypes
@@@ -325,26 -325,12 +325,12 @@@ dsExpr (HsLet binds body) = d
  -- We need the `ListComp' form to use `deListComp' (rather than the "do" form)
  -- because the interpretation of `stmts' depends on what sort of thing it is.
  --
- dsExpr (HsDo ListComp stmts body result_ty)
-   =   -- Special case for list comprehensions
-     dsListComp stmts body elt_ty
-   where
-     [elt_ty] = tcTyConAppArgs result_ty
- dsExpr (HsDo DoExpr stmts body result_ty)
-   = dsDo stmts body result_ty
- dsExpr (HsDo GhciStmt stmts body result_ty)
-   = dsDo stmts body result_ty
- dsExpr (HsDo MDoExpr stmts body result_ty)
-   = dsDo stmts body result_ty
- dsExpr (HsDo PArrComp stmts body result_ty)
-   =   -- Special case for array comprehensions
-     dsPArrComp (map unLoc stmts) body elt_ty
-   where
-     [elt_ty] = tcTyConAppArgs result_ty
+ dsExpr (HsDo ListComp  stmts res_ty) = dsListComp stmts res_ty
+ dsExpr (HsDo PArrComp  stmts _)      = dsPArrComp (map unLoc stmts)
+ dsExpr (HsDo DoExpr    stmts _)      = dsDo stmts 
+ dsExpr (HsDo GhciStmt  stmts _)      = dsDo stmts 
+ dsExpr (HsDo MDoExpr   stmts _)      = dsDo stmts 
+ dsExpr (HsDo MonadComp stmts _)      = dsMonadComp stmts
  
  dsExpr (HsIf mb_fun guard_expr then_expr else_expr)
    = do { pred <- dsLExpr guard_expr
@@@ -527,12 -513,12 +513,12 @@@ dsExpr expr@(RecordUpd record_expr (HsR
  
      mk_alt upd_fld_env con
        = do { let (univ_tvs, ex_tvs, eq_spec, 
 -                eq_theta, dict_theta, arg_tys, _) = dataConFullSig con
 +                theta, arg_tys, _) = dataConFullSig con
                 subst = mkTopTvSubst (univ_tvs `zip` in_inst_tys)
  
                -- I'm not bothering to clone the ex_tvs
           ; eqs_vars   <- mapM newPredVarDs (substTheta subst (eqSpecPreds eq_spec))
 -         ; theta_vars <- mapM newPredVarDs (substTheta subst (eq_theta ++ dict_theta))
 +         ; theta_vars <- mapM newPredVarDs (substTheta subst theta)
           ; arg_ids    <- newSysLocalsDs (substTys subst arg_tys)
           ; let val_args = zipWithEqual "dsExpr:RecordUpd" mk_val_arg
                                         (dataConFieldLabels con) arg_ids
                 wrap = mkWpEvVarApps theta_vars          `WpCompose` 
                        mkWpTyApps    (mkTyVarTys ex_tvs) `WpCompose`
                        mkWpTyApps [ty | (tv, ty) <- univ_tvs `zip` out_inst_tys
 -                                     , isNothing (lookupTyVar wrap_subst tv) ]
 +                                     , not (tv `elemVarEnv` wrap_subst) ]
                 rhs = foldl (\a b -> nlHsApp a b) inst_con val_args
  
                        -- Tediously wrap the application in a cast
                        -- Note [Update for GADTs]
                 wrapped_rhs | null eq_spec = rhs
                             | otherwise    = mkLHsWrap (WpCast wrap_co) rhs
 -               wrap_co = mkTyConApp tycon [ lookup tv ty 
 -                                          | (tv,ty) <- univ_tvs `zip` out_inst_tys]
 -               lookup univ_tv ty = case lookupTyVar wrap_subst univ_tv of
 -                                      Just ty' -> ty'
 -                                      Nothing  -> ty
 -               wrap_subst = mkTopTvSubst [ (tv,mkSymCoercion (mkTyVarTy co_var))
 -                                         | ((tv,_),co_var) <- eq_spec `zip` eqs_vars ]
 -               
 +               wrap_co = mkTyConAppCo tycon [ lookup tv ty
 +                                            | (tv,ty) <- univ_tvs `zip` out_inst_tys]
 +               lookup univ_tv ty = case lookupVarEnv wrap_subst univ_tv of
 +                                      Just co' -> co'
 +                                      Nothing  -> mkReflCo ty
 +               wrap_subst = mkVarEnv [ (tv, mkSymCo (mkCoVarCo co_var))
 +                                     | ((tv,_),co_var) <- eq_spec `zip` eqs_vars ]
 +
                 pat = noLoc $ ConPatOut { pat_con = noLoc con, pat_tvs = ex_tvs
                                         , pat_dicts = eqs_vars ++ theta_vars
                                         , pat_binds = emptyTcEvBinds
@@@ -597,7 -583,7 +583,7 @@@ dsExpr (HsTick ix vars e) = d
  
  dsExpr (HsBinTick ixT ixF e) = do
    e2 <- dsLExpr e
 -  do { ASSERT(exprType e2 `coreEqType` boolTy)
 +  do { ASSERT(exprType e2 `eqType` boolTy)
         mkBinaryTickBox ixT ixF e2
       }
  \end{code}
@@@ -708,25 -694,20 +694,20 @@@ handled in DsListComp).  Basically doe
  Haskell 98 report:
  
  \begin{code}
- dsDo  :: [LStmt Id]
-       -> LHsExpr Id
-       -> Type                 -- Type of the whole expression
-       -> DsM CoreExpr
- dsDo stmts body result_ty
+ dsDo :: [LStmt Id] -> DsM CoreExpr
+ dsDo stmts
    = goL stmts
    where
-     -- result_ty must be of the form (m b)
-     (m_ty, _b_ty) = tcSplitAppTy result_ty
-     goL [] = dsLExpr body
-     goL ((L loc stmt):lstmts) = putSrcSpanDs loc (go loc stmt lstmts)
+     goL [] = panic "dsDo"
+     goL (L loc stmt:lstmts) = putSrcSpanDs loc (go loc stmt lstmts)
    
-     go _ (ExprStmt rhs then_expr _) stmts
+     go _ (LastStmt body _) stmts
+       = ASSERT( null stmts ) dsLExpr body
+         -- The 'return' op isn't used for 'do' expressions
+     go _ (ExprStmt rhs then_expr _ _) stmts
        = do { rhs2 <- dsLExpr rhs
-            ; case tcSplitAppTy_maybe (exprType rhs2) of
-                 Just (container_ty, returning_ty) -> warnDiscardedDoBindings rhs container_ty returning_ty
-                 _                                 -> return ()
+            ; warnDiscardedDoBindings rhs (exprType rhs2) 
             ; then_expr2 <- dsExpr then_expr
           ; rest <- goL stmts
           ; return (mkApps then_expr2 [rhs2, rest]) }
      go loc (RecStmt { recS_stmts = rec_stmts, recS_later_ids = later_ids
                      , recS_rec_ids = rec_ids, recS_ret_fn = return_op
                      , recS_mfix_fn = mfix_op, recS_bind_fn = bind_op
-                     , recS_rec_rets = rec_rets }) stmts
+                     , recS_rec_rets = rec_rets, recS_ret_ty = body_ty }) stmts
        = ASSERT( length rec_ids > 0 )
          goL (new_bind_stmt : stmts)
        where
-         -- returnE <- dsExpr return_id
-         -- mfixE <- dsExpr mfix_id
-         new_bind_stmt = L loc $ BindStmt (mkLHsPatTup later_pats) mfix_app
-                                          bind_op 
+         new_bind_stmt = L loc $ BindStmt (mkLHsPatTup later_pats)
+                                          mfix_app bind_op 
                                           noSyntaxExpr  -- Tuple cannot fail
  
          tup_ids      = rec_ids ++ filterOut (`elem` rec_ids) later_ids
+         tup_ty       = mkBoxedTupleTy (map idType tup_ids) -- Deals with singleton case
          rec_tup_pats = map nlVarPat tup_ids
          later_pats   = rec_tup_pats
          rets         = map noLoc rec_rets
-         mfix_app   = nlHsApp (noLoc mfix_op) mfix_arg
-         mfix_arg   = noLoc $ HsLam (MatchGroup [mkSimpleMatch [mfix_pat] body]
-                                              (mkFunTy tup_ty body_ty))
-         mfix_pat   = noLoc $ LazyPat $ mkLHsPatTup rec_tup_pats
-         body       = noLoc $ HsDo DoExpr rec_stmts return_app body_ty
-         return_app = nlHsApp (noLoc return_op) (mkLHsTupleExpr rets)
-       body_ty    = mkAppTy m_ty tup_ty
-         tup_ty     = mkBoxedTupleTy (map idType tup_ids) -- Deals with singleton case
+         mfix_app     = nlHsApp (noLoc mfix_op) mfix_arg
+         mfix_arg     = noLoc $ HsLam (MatchGroup [mkSimpleMatch [mfix_pat] body]
+                                                  (mkFunTy tup_ty body_ty))
+         mfix_pat     = noLoc $ LazyPat $ mkLHsPatTup rec_tup_pats
+         body         = noLoc $ HsDo DoExpr (rec_stmts ++ [ret_stmt]) body_ty
+         ret_app      = nlHsApp (noLoc return_op) (mkLHsTupleExpr rets)
+         ret_stmt     = noLoc $ mkLastStmt ret_app
+                    -- This LastStmt will be desugared with dsDo, 
+                    -- which ignores the return_op in the LastStmt,
+                    -- so we must apply the return_op explicitly 
  
  handle_failure :: LPat Id -> MatchResult -> SyntaxExpr Id -> DsM CoreExpr
      -- In a do expression, pattern-match failure just calls
@@@ -790,104 -771,6 +771,6 @@@ mk_fail_msg pat = "Pattern match failur
                  showSDoc (ppr (getLoc pat))
  \end{code}
  
- Translation for RecStmt's: 
- -----------------------------
- We turn (RecStmt [v1,..vn] stmts) into:
-   
-   (v1,..,vn) <- mfix (\~(v1,..vn). do stmts
-                                     return (v1,..vn))
- \begin{code}
- {-
- dsMDo   :: HsStmtContext Name
-         -> [(Name,Id)]
-       -> [LStmt Id]
-       -> LHsExpr Id
-       -> Type                 -- Type of the whole expression
-       -> DsM CoreExpr
- dsMDo ctxt tbl stmts body result_ty
-   = goL stmts
-   where
-     goL [] = dsLExpr body
-     goL ((L loc stmt):lstmts) = putSrcSpanDs loc (go loc stmt lstmts)
-   
-     (m_ty, b_ty) = tcSplitAppTy result_ty     -- result_ty must be of the form (m b)
-     return_id = lookupEvidence tbl returnMName
-     bind_id   = lookupEvidence tbl bindMName
-     then_id   = lookupEvidence tbl thenMName
-     fail_id   = lookupEvidence tbl failMName
-     go _ (LetStmt binds) stmts
-       = do { rest <- goL stmts
-          ; dsLocalBinds binds rest }
-     go _ (ExprStmt rhs then_expr rhs_ty) stmts
-       = do { rhs2 <- dsLExpr rhs
-          ; warnDiscardedDoBindings rhs m_ty rhs_ty
-            ; then_expr2 <- dsExpr then_expr
-            ; rest <- goL stmts
-            ; return (mkApps then_expr2 [rhs2, rest]) }
-     
-     go _ (BindStmt pat rhs bind_op _) stmts
-       = do { body     <- goL stmts
-            ; rhs'     <- dsLExpr rhs
-            ; bind_op' <- dsExpr bind_op
-            ; var   <- selectSimpleMatchVarL pat
-          ; match <- matchSinglePat (Var var) (StmtCtxt ctxt) pat
-                                      result_ty (cantFailMatchResult body)
-            ; match_code <- handle_failure pat match fail_op
-            ; return (mkApps bind_op [rhs', Lam var match_code]) }
-     
-     go loc (RecStmt { recS_stmts = rec_stmts, recS_later_ids = later_ids
-                     , recS_rec_ids = rec_ids, recS_rec_rets = rec_rets
-                     , recS_mfix_fn = mfix_op, recS_bind_fn = bind_op }) stmts
-       = ASSERT( length rec_ids > 0 )
-         ASSERT( length rec_ids == length rec_rets )
-         ASSERT( isEmptyTcEvBinds _ev_binds )
-         pprTrace "dsMDo" (ppr later_ids) $
-        goL (new_bind_stmt : stmts)
-       where
-         new_bind_stmt = L loc $ BindStmt (mk_tup_pat later_pats) mfix_app
-                                          bind_op noSyntaxExpr
-       
-               -- Remove the later_ids that appear (without fancy coercions) 
-               -- in rec_rets, because there's no need to knot-tie them separately
-               -- See Note [RecStmt] in HsExpr
-       later_ids'   = filter (`notElem` mono_rec_ids) later_ids
-       mono_rec_ids = [ id | HsVar id <- rec_rets ]
-     
-         mfix_app = nlHsApp (noLoc mfix_op) mfix_arg
-       mfix_arg = noLoc $ HsLam (MatchGroup [mkSimpleMatch [mfix_pat] body]
-                                            (mkFunTy tup_ty body_ty))
-       -- The rec_tup_pat must bind the rec_ids only; remember that the 
-       --      trimmed_laters may share the same Names
-       -- Meanwhile, the later_pats must bind the later_vars
-       rec_tup_pats = map mk_wild_pat later_ids' ++ map nlVarPat rec_ids
-       later_pats   = map nlVarPat    later_ids' ++ map mk_later_pat rec_ids
-       rets         = map nlHsVar     later_ids' ++ map noLoc rec_rets
-       mfix_pat = noLoc $ LazyPat $ mk_tup_pat rec_tup_pats
-       body     = noLoc $ HsDo ctxt rec_stmts return_app body_ty
-       body_ty = mkAppTy m_ty tup_ty
-       tup_ty  = mkBoxedTupleTy (map idType (later_ids' ++ rec_ids))  -- Deals with singleton case
-         return_app  = nlHsApp (noLoc return_op) (mkLHsTupleExpr rets)
-       mk_wild_pat :: Id -> LPat Id 
-       mk_wild_pat v = noLoc $ WildPat $ idType v
-       mk_later_pat :: Id -> LPat Id
-       mk_later_pat v | v `elem` later_ids' = mk_wild_pat v
-                      | otherwise           = nlVarPat v
-       mk_tup_pat :: [LPat Id] -> LPat Id
-       mk_tup_pat [p] = p
-       mk_tup_pat ps  = noLoc $ mkVanillaTuplePat ps Boxed
- -}
- \end{code}
  
  %************************************************************************
  %*                                                                    *
@@@ -904,7 -787,7 +787,7 @@@ warnAboutIdentities (Var v) co_f
    | idName v `elem` conversionNames
    , let fun_ty = exprType (co_fn (Var v))
    , Just (arg_ty, res_ty) <- splitFunTy_maybe fun_ty
 -  , arg_ty `tcEqType` res_ty  -- So we are converting  ty -> ty
 +  , arg_ty `eqType` res_ty  -- So we are converting  ty -> ty
    = warnDs (vcat [ ptext (sLit "Call of") <+> ppr v <+> dcolon <+> ppr fun_ty
                   , nest 2 $ ptext (sLit "can probably be omitted")
                   , parens (ptext (sLit "Use -fno-warn-identities to suppress this messsage)"))
@@@ -927,30 -810,34 +810,34 @@@ conversionName
  
  \begin{code}
  -- Warn about certain types of values discarded in monadic bindings (#3263)
- warnDiscardedDoBindings :: LHsExpr Id -> Type -> Type -> DsM ()
- warnDiscardedDoBindings rhs container_ty returning_ty = do {
-           -- Warn about discarding non-() things in 'monadic' binding
-         ; warn_unused <- doptDs Opt_WarnUnusedDoBind
-         ; if warn_unused && not (returning_ty `eqType` unitTy)
-            then warnDs (unusedMonadBind rhs returning_ty)
-            else do {
-           -- Warn about discarding m a things in 'monadic' binding of the same type,
-           -- but only if we didn't already warn due to Opt_WarnUnusedDoBind
-         ; warn_wrong <- doptDs Opt_WarnWrongDoBind
-         ; case tcSplitAppTy_maybe returning_ty of
-                   Just (returning_container_ty, _) -> when (warn_wrong && container_ty `eqType` returning_container_ty) $
-                                                             warnDs (wrongMonadBind rhs returning_ty)
-                   _ -> return () } }
+ warnDiscardedDoBindings :: LHsExpr Id -> Type -> DsM ()
+ warnDiscardedDoBindings rhs rhs_ty
+   | Just (m_ty, elt_ty) <- tcSplitAppTy_maybe rhs_ty
+   = do {  -- Warn about discarding non-() things in 'monadic' binding
+        ; warn_unused <- doptDs Opt_WarnUnusedDoBind
+        ; if warn_unused && not (isUnitTy elt_ty)
+          then warnDs (unusedMonadBind rhs elt_ty)
+          else 
+          -- Warn about discarding m a things in 'monadic' binding of the same type,
+          -- but only if we didn't already warn due to Opt_WarnUnusedDoBind
+     do { warn_wrong <- doptDs Opt_WarnWrongDoBind
+        ; case tcSplitAppTy_maybe elt_ty of
 -           Just (elt_m_ty, _) | warn_wrong, m_ty `tcEqType` elt_m_ty
++           Just (elt_m_ty, _) | warn_wrong, m_ty `eqType` elt_m_ty
+                               -> warnDs (wrongMonadBind rhs elt_ty)
+            _ -> return () } }
+   | otherwise -- RHS does have type of form (m ty), which is wierd
+   = return ()   -- but at lesat this warning is irrelevant
  
  unusedMonadBind :: LHsExpr Id -> Type -> SDoc
- unusedMonadBind rhs returning_ty
-   = ptext (sLit "A do-notation statement discarded a result of type") <+> ppr returning_ty <> dot $$
+ unusedMonadBind rhs elt_ty
+   = ptext (sLit "A do-notation statement discarded a result of type") <+> ppr elt_ty <> dot $$
      ptext (sLit "Suppress this warning by saying \"_ <- ") <> ppr rhs <> ptext (sLit "\",") $$
      ptext (sLit "or by using the flag -fno-warn-unused-do-bind")
  
  wrongMonadBind :: LHsExpr Id -> Type -> SDoc
- wrongMonadBind rhs returning_ty
-   = ptext (sLit "A do-notation statement discarded a result of type") <+> ppr returning_ty <> dot $$
+ wrongMonadBind rhs elt_ty
+   = ptext (sLit "A do-notation statement discarded a result of type") <+> ppr elt_ty <> dot $$
      ptext (sLit "Suppress this warning by saying \"_ <- ") <> ppr rhs <> ptext (sLit "\",") $$
      ptext (sLit "or by using the flag -fno-warn-wrong-do-bind")
  \end{code}
@@@ -29,7 -29,6 +29,7 @@@ import DataCo
  import MatchCon
  import MatchLit
  import Type
 +import Coercion
  import TysWiredIn
  import ListSetOps
  import SrcLoc
@@@ -523,7 -522,7 +523,7 @@@ tidy1 _ (LitPat lit
  
  -- NPats: we *might* be able to replace these w/ a simpler form
  tidy1 _ (NPat lit mb_neg eq)
-   = return (idDsWrapper, tidyNPat lit mb_neg eq)
+   = return (idDsWrapper, tidyNPat tidyLitPat lit mb_neg eq)
  
  -- BangPatterns: Pattern matching is already strict in constructors,
  -- tuples etc, so the last case strips off the bang for thoses patterns.
@@@ -826,7 -825,7 +826,7 @@@ sameGroup (PgCon _)  (PgCon _)  = Tru
  sameGroup (PgLit _)  (PgLit _)  = True                -- One case expression
  sameGroup (PgN l1)   (PgN l2)   = l1==l2      -- Order is significant
  sameGroup (PgNpK l1) (PgNpK l2) = l1==l2      -- See Note [Grouping overloaded literal patterns]
 -sameGroup (PgCo       t1)  (PgCo t2)  = t1 `coreEqType` t2
 +sameGroup (PgCo       t1)  (PgCo t2)  = t1 `eqType` t2
        -- CoPats are in the same goup only if the type of the
        -- enclosed pattern is the same. The patterns outside the CoPat
        -- always have the same type, so this boils down to saying that
@@@ -874,7 -873,7 +874,7 @@@ viewLExprEq (e1,_) (e2,_) = lexp e1 e
          -- which resolve the overloading (e.g., fromInteger 1),
          -- because these expressions get written as a bunch of different variables
          -- (presumably to improve sharing)
 -        tcEqType (overLitType l) (overLitType l') && l == l'
 +        eqType (overLitType l) (overLitType l') && l == l'
      exp (HsApp e1 e2) (HsApp e1' e2') = lexp e1 e1' && lexp e2 e2'
      -- the fixities have been straightened out by now, so it's safe
      -- to ignore them?
  
      ---------
      tup_arg (Present e1) (Present e2) = lexp e1 e2
 -    tup_arg (Missing t1) (Missing t2) = tcEqType t1 t2
 +    tup_arg (Missing t1) (Missing t2) = eqType t1 t2
      tup_arg _ _ = False
  
      ---------
      --        equating different ways of writing a coercion)
      wrap WpHole WpHole = True
      wrap (WpCompose w1 w2) (WpCompose w1' w2') = wrap w1 w1' && wrap w2 w2'
 -    wrap (WpCast c)  (WpCast c')     = tcEqType c c'
 +    wrap (WpCast c)  (WpCast c')     = coreEqCoercion c c'
      wrap (WpEvApp et1) (WpEvApp et2) = ev_term et1 et2
 -    wrap (WpTyApp t) (WpTyApp t')    = tcEqType t t'
 +    wrap (WpTyApp t) (WpTyApp t')    = eqType t t'
      -- Enhancement: could implement equality for more wrappers
      --   if it seems useful (lams and lets)
      wrap _ _ = False
      ---------
      ev_term :: EvTerm -> EvTerm -> Bool
      ev_term (EvId a)       (EvId b)       = a==b
 -    ev_term (EvCoercion a) (EvCoercion b) = tcEqType a b
 +    ev_term (EvCoercion a) (EvCoercion b) = coreEqCoercion a b
      ev_term _ _ = False       
  
      ---------
@@@ -960,4 -959,3 +960,4 @@@ If the first arg matches '1' but the se
  cannot jump to the third equation!  Because the same argument might
  match '2'!
  Hence we don't regard 1 and 2, or (n+1) and (n+2), as part of the same group.
 +
diff --combined compiler/ghc.cabal.in
@@@ -36,11 -36,6 +36,6 @@@ Flag ghc
      Default: False
      Manual: True
  
- Flag ncg
-     Description: Build the NCG.
-     Default: False
-     Manual: True
  Flag stage1
      Description: Is this stage 1?
      Default: False
@@@ -88,9 -83,6 +83,6 @@@ Librar
          CPP-Options: -DGHCI
          Include-Dirs: ../libffi/build/include
  
-     if !flag(ncg)
-         CPP-Options: -DOMIT_NATIVE_CODEGEN
      Build-Depends: bin-package-db
      Build-Depends: hoopl
  
          Generics
          InstEnv
          TyCon
 +        Kind
          Type
          TypeRep
          Unify
          MonadUtils
          OrdList
          Outputable
 +        Pair
          Panic
          Pretty
          Serialized
          Vectorise.Exp
          Vectorise
  
-     -- We only need to expose more modules as some of the ncg code is used
-     -- by the LLVM backend so its always included
-     if flag(ncg)
-         Exposed-Modules:
+     Exposed-Modules:
              AsmCodeGen
              TargetReg
              NCGMonad
              RegClass
              PIC
              Platform
-             Alpha.Regs
-             Alpha.RegInfo
-             Alpha.Instr
-             Alpha.CodeGen
              X86.Regs
              X86.RegInfo
              X86.Instr
diff --combined compiler/hsSyn/HsPat.lhs
@@@ -24,7 -24,7 +24,7 @@@ module HsPat 
  
          isBangHsBind, isLiftedPatBind,
          isBangLPat, hsPatNeedsParens,
 -      isIrrefutableHsPat,
 +        isIrrefutableHsPat,
  
        pprParendLPat
      ) where
@@@ -65,7 -65,7 +65,7 @@@ data Pat i
        -- support hsPatType :: Pat Id -> Type
  
    | VarPat    id                      -- Variable
 -  | LazyPat   (LPat id)               -- Lazy pattern
 +  | LazyPat     (LPat id)               -- Lazy pattern
    | AsPat     (Located id) (LPat id)  -- As pattern
    | ParPat      (LPat id)             -- Parenthesised pattern
    | BangPat   (LPat id)               -- Bang pattern
    | LitPat        HsLit               -- Used for *non-overloaded* literal patterns:
                                        -- Int#, Char#, Int, Char, String, etc.
  
-   | NPat          (HsOverLit id)              -- ALWAYS positive
+   | NPat              -- Used for all overloaded literals, 
+                       -- including overloaded strings with -XOverloadedStrings
+                     (HsOverLit id)            -- ALWAYS positive
                    (Maybe (SyntaxExpr id))     -- Just (Name of 'negate') for negative
                                                -- patterns, Nothing otherwise
                    (SyntaxExpr id)             -- Equality checker, of type t->t->Bool
@@@ -19,9 -19,9 +19,9 @@@ module HsUtils
    mkHsPar, mkHsApp, mkHsConApp, mkSimpleHsAlt,
    mkSimpleMatch, unguardedGRHSs, unguardedRHS, 
    mkMatchGroup, mkMatch, mkHsLam, mkHsIf,
 -  mkHsWrap, mkLHsWrap, mkHsWrapCoI, mkLHsWrapCoI,
 -  coiToHsWrapper, mkHsLams, mkHsDictLet,
 -  mkHsOpApp, mkHsDo, mkHsComp, mkHsWrapPat, mkHsWrapPatCoI, 
 +  mkHsWrap, mkLHsWrap, mkHsWrapCo, mkLHsWrapCo,
 +  coToHsWrapper, mkHsDictLet, mkHsLams,
-   mkHsOpApp, mkHsDo, mkHsWrapPat, mkHsWrapPatCo,
++  mkHsOpApp, mkHsDo, mkHsComp, mkHsWrapPat, mkHsWrapPatCo,
  
    nlHsTyApp, nlHsVar, nlHsLit, nlHsApp, nlHsApps, nlHsIntLit, nlHsVarApps, 
    nlHsDo, nlHsOpApp, nlHsLam, nlHsPar, nlHsIf, nlHsCase, nlList,
@@@ -42,8 -42,8 +42,8 @@@
    nlHsAppTy, nlHsTyVar, nlHsFunTy, nlHsTyConApp, 
  
    -- Stmts
-   mkTransformStmt, mkTransformByStmt, mkExprStmt, mkBindStmt,
-   mkGroupUsingStmt, mkGroupByStmt, mkGroupByUsingStmt, 
+   mkTransformStmt, mkTransformByStmt, mkExprStmt, mkBindStmt, mkLastStmt,
+   emptyTransStmt, mkGroupUsingStmt, mkGroupByStmt, mkGroupByUsingStmt, 
    emptyRecStmt, mkRecStmt, 
  
    -- Template Haskell
@@@ -77,7 -77,7 +77,7 @@@ import HsLi
  import RdrName
  import Var
  import Coercion
 -import Type
 +import TypeRep
  import DataCon
  import Name
  import NameSet
@@@ -137,25 -137,25 +137,25 @@@ mkHsWrap :: HsWrapper -> HsExpr id -> H
  mkHsWrap co_fn e | isIdHsWrapper co_fn = e
                 | otherwise           = HsWrap co_fn e
  
 -mkHsWrapCoI :: CoercionI -> HsExpr id -> HsExpr id
 -mkHsWrapCoI (IdCo _) e = e
 -mkHsWrapCoI (ACo co) e = mkHsWrap (WpCast co) e
 +mkHsWrapCo :: Coercion -> HsExpr id -> HsExpr id
 +mkHsWrapCo (Refl _) e = e
 +mkHsWrapCo co       e = mkHsWrap (WpCast co) e
  
 -mkLHsWrapCoI :: CoercionI -> LHsExpr id -> LHsExpr id
 -mkLHsWrapCoI (IdCo _) e         = e
 -mkLHsWrapCoI (ACo co) (L loc e) = L loc (mkHsWrap (WpCast co) e)
 +mkLHsWrapCo :: Coercion -> LHsExpr id -> LHsExpr id
 +mkLHsWrapCo (Refl _) e         = e
 +mkLHsWrapCo co       (L loc e) = L loc (mkHsWrap (WpCast co) e)
  
 -coiToHsWrapper :: CoercionI -> HsWrapper
 -coiToHsWrapper (IdCo _) = idHsWrapper
 -coiToHsWrapper (ACo co) = WpCast co
 +coToHsWrapper :: Coercion -> HsWrapper
 +coToHsWrapper (Refl _) = idHsWrapper
 +coToHsWrapper co       = WpCast co
  
  mkHsWrapPat :: HsWrapper -> Pat id -> Type -> Pat id
  mkHsWrapPat co_fn p ty | isIdHsWrapper co_fn = p
                       | otherwise           = CoPat co_fn p ty
  
 -mkHsWrapPatCoI :: CoercionI -> Pat id -> Type -> Pat id
 -mkHsWrapPatCoI (IdCo _) pat _  = pat
 -mkHsWrapPatCoI (ACo co) pat ty = CoPat (WpCast co) pat ty
 +mkHsWrapPatCo :: Coercion -> Pat id -> Type -> Pat id
 +mkHsWrapPatCo (Refl _) pat _  = pat
 +mkHsWrapPatCo co       pat ty = CoPat (WpCast co) pat ty
  
  mkHsLam :: [LPat id] -> LHsExpr id -> LHsExpr id
  mkHsLam pats body = mkHsPar (L (getLoc body) (HsLam matches))
@@@ -190,14 -190,13 +190,13 @@@ mkSimpleHsAlt pat exp
  mkHsIntegral   :: Integer -> PostTcType -> HsOverLit id
  mkHsFractional :: Rational -> PostTcType -> HsOverLit id
  mkHsIsString   :: FastString -> PostTcType -> HsOverLit id
- mkHsDo         :: HsStmtContext Name -> [LStmt id] -> LHsExpr id -> HsExpr id
+ mkHsDo         :: HsStmtContext Name -> [LStmt id] -> HsExpr id
+ mkHsComp       :: HsStmtContext Name -> [LStmt id] -> LHsExpr id -> HsExpr id
  
  mkNPat      :: HsOverLit id -> Maybe (SyntaxExpr id) -> Pat id
  mkNPlusKPat :: Located id -> HsOverLit id -> Pat id
  
- mkTransformStmt   :: [LStmt idL] -> LHsExpr idR                -> StmtLR idL idR
- mkTransformByStmt :: [LStmt idL] -> LHsExpr idR -> LHsExpr idR -> StmtLR idL idR
+ mkLastStmt :: LHsExpr idR -> StmtLR idL idR
  mkExprStmt :: LHsExpr idR -> StmtLR idL idR
  mkBindStmt :: LPat idL -> LHsExpr idR -> StmtLR idL idR
  
@@@ -212,7 -211,10 +211,10 @@@ mkHsIsString   s       = OverLit (HsIsS
  noRebindableInfo :: Bool
  noRebindableInfo = error "noRebindableInfo"   -- Just another placeholder; 
  
- mkHsDo ctxt stmts body = HsDo ctxt stmts body placeHolderType
+ mkHsDo ctxt stmts = HsDo ctxt stmts placeHolderType
+ mkHsComp ctxt stmts expr = mkHsDo ctxt (stmts ++ [last_stmt])
+   where
+     last_stmt = L (getLoc expr) $ mkLastStmt expr
  
  mkHsIf :: LHsExpr id -> LHsExpr id -> LHsExpr id -> HsExpr id
  mkHsIf c a b = HsIf (Just noSyntaxExpr) c a b
  mkNPat lit neg     = NPat lit neg noSyntaxExpr
  mkNPlusKPat id lit = NPlusKPat id lit noSyntaxExpr noSyntaxExpr
  
- mkTransformStmt   stmts usingExpr        = TransformStmt stmts [] usingExpr Nothing
- mkTransformByStmt stmts usingExpr byExpr = TransformStmt stmts [] usingExpr (Just byExpr)
+ mkTransformStmt   :: [LStmt idL] -> LHsExpr idR                -> StmtLR idL idR
+ mkTransformByStmt :: [LStmt idL] -> LHsExpr idR -> LHsExpr idR -> StmtLR idL idR
  mkGroupUsingStmt   :: [LStmt idL]                -> LHsExpr idR -> StmtLR idL idR
  mkGroupByStmt      :: [LStmt idL] -> LHsExpr idR                -> StmtLR idL idR
  mkGroupByUsingStmt :: [LStmt idL] -> LHsExpr idR -> LHsExpr idR -> StmtLR idL idR
  
- mkGroupUsingStmt   stmts usingExpr        = GroupStmt stmts [] Nothing       (Left usingExpr)    
- mkGroupByStmt      stmts byExpr           = GroupStmt stmts [] (Just byExpr) (Right noSyntaxExpr)
- mkGroupByUsingStmt stmts byExpr usingExpr = GroupStmt stmts [] (Just byExpr) (Left usingExpr)    
- mkExprStmt expr           = ExprStmt expr noSyntaxExpr placeHolderType
+ emptyTransStmt :: StmtLR idL idR
+ emptyTransStmt = TransStmt { trS_form = undefined, trS_stmts = [], trS_bndrs = [] 
+                            , trS_by = Nothing, trS_using = noLoc noSyntaxExpr
+                            , trS_ret = noSyntaxExpr, trS_bind = noSyntaxExpr
+                            , trS_fmap = noSyntaxExpr }
+ mkTransformStmt   ss u    = emptyTransStmt { trS_form = ThenForm, trS_stmts = ss, trS_using = u }
+ mkTransformByStmt ss u b  = emptyTransStmt { trS_form = ThenForm, trS_stmts = ss, trS_using = u, trS_by = Just b }
+ mkGroupByStmt      ss b   = emptyTransStmt { trS_form = GroupFormB, trS_stmts = ss, trS_by = Just b }
+ mkGroupUsingStmt   ss u   = emptyTransStmt { trS_form = GroupFormU, trS_stmts = ss, trS_using = u }
+ mkGroupByUsingStmt ss b u = emptyTransStmt { trS_form = GroupFormU, trS_stmts = ss
+                                            , trS_by = Just b, trS_using = u }
+ mkLastStmt expr           = LastStmt expr noSyntaxExpr
+ mkExprStmt expr           = ExprStmt expr noSyntaxExpr noSyntaxExpr placeHolderType
  mkBindStmt pat expr = BindStmt pat expr noSyntaxExpr noSyntaxExpr
  
  emptyRecStmt = RecStmt { recS_stmts = [], recS_later_ids = [], recS_rec_ids = []
                         , recS_ret_fn = noSyntaxExpr, recS_mfix_fn = noSyntaxExpr
                       , recS_bind_fn = noSyntaxExpr
-                        , recS_rec_rets = [] }
+                        , recS_rec_rets = [], recS_ret_ty = placeHolderType }
  
  mkRecStmt stmts = emptyRecStmt { recS_stmts = stmts }
  
@@@ -327,8 -337,8 +337,8 @@@ nlWildConPat con = noLoc (ConPatIn (noL
  nlWildPat :: LPat id
  nlWildPat  = noLoc (WildPat placeHolderType)  -- Pre-typechecking
  
- nlHsDo :: HsStmtContext Name -> [LStmt id] -> LHsExpr id -> LHsExpr id
- nlHsDo ctxt stmts body = noLoc (mkHsDo ctxt stmts body)
+ nlHsDo :: HsStmtContext Name -> [LStmt id] -> LHsExpr id
+ nlHsDo ctxt stmts = noLoc (mkHsDo ctxt stmts)
  
  nlHsOpApp :: LHsExpr id -> id -> LHsExpr id -> LHsExpr id
  nlHsOpApp e1 op e2 = noLoc (mkHsOpApp e1 op e2)
@@@ -496,12 -506,12 +506,12 @@@ collectStmtBinders :: StmtLR idL idR -
    -- Id Binders for a Stmt... [but what about pattern-sig type vars]?
  collectStmtBinders (BindStmt pat _ _ _) = collectPatBinders pat
  collectStmtBinders (LetStmt binds)      = collectLocalBinders binds
- collectStmtBinders (ExprStmt _ _ _)     = []
- collectStmtBinders (ParStmt xs)         = collectLStmtsBinders
+ collectStmtBinders (ExprStmt {})        = []
+ collectStmtBinders (LastStmt {})        = []
+ collectStmtBinders (ParStmt xs _ _ _)   = collectLStmtsBinders
                                          $ concatMap fst xs
- collectStmtBinders (TransformStmt stmts _ _ _)   = collectLStmtsBinders stmts
- collectStmtBinders (GroupStmt     stmts _ _ _)   = collectLStmtsBinders stmts
- collectStmtBinders (RecStmt { recS_stmts = ss }) = collectLStmtsBinders ss
+ collectStmtBinders (TransStmt { trS_stmts = stmts }) = collectLStmtsBinders stmts
+ collectStmtBinders (RecStmt { recS_stmts = ss })     = collectLStmtsBinders ss
  
  
  ----------------- Patterns --------------------------
@@@ -642,12 -652,12 +652,12 @@@ lStmtsImplicits = hs_lstmt
      
      hs_stmt (BindStmt pat _ _ _) = lPatImplicits pat
      hs_stmt (LetStmt binds)      = hs_local_binds binds
-     hs_stmt (ExprStmt _ _ _)     = emptyNameSet
-     hs_stmt (ParStmt xs)         = hs_lstmts $ concatMap fst xs
+     hs_stmt (ExprStmt {})        = emptyNameSet
+     hs_stmt (LastStmt {})        = emptyNameSet
+     hs_stmt (ParStmt xs _ _ _)   = hs_lstmts $ concatMap fst xs
      
-     hs_stmt (TransformStmt stmts _ _ _)   = hs_lstmts stmts
-     hs_stmt (GroupStmt     stmts _ _ _)   = hs_lstmts stmts
-     hs_stmt (RecStmt { recS_stmts = ss }) = hs_lstmts ss
+     hs_stmt (TransStmt { trS_stmts = stmts }) = hs_lstmts stmts
+     hs_stmt (RecStmt { recS_stmts = ss })     = hs_lstmts ss
      
      hs_local_binds (HsValBinds val_binds) = hsValBindsImplicits val_binds
      hs_local_binds (HsIPBinds _)         = emptyNameSet
@@@ -5,34 -5,34 +5,34 @@@
  
  \begin{code}
  module IfaceSyn (
-       module IfaceType,               -- Re-export all this
+         module IfaceType,
  
-       IfaceDecl(..), IfaceClassOp(..), IfaceConDecl(..), IfaceConDecls(..),
-       IfaceExpr(..), IfaceAlt, IfaceNote(..), IfaceLetBndr(..),
-       IfaceBinding(..), IfaceConAlt(..), 
-       IfaceIdInfo(..), IfaceIdDetails(..), IfaceUnfolding(..),
-       IfaceInfoItem(..), IfaceRule(..), IfaceAnnotation(..), IfaceAnnTarget,
-       IfaceInst(..), IfaceFamInst(..),
+         IfaceDecl(..), IfaceClassOp(..), IfaceConDecl(..), IfaceConDecls(..),
+         IfaceExpr(..), IfaceAlt, IfaceNote(..), IfaceLetBndr(..),
+         IfaceBinding(..), IfaceConAlt(..),
+         IfaceIdInfo(..), IfaceIdDetails(..), IfaceUnfolding(..),
+         IfaceInfoItem(..), IfaceRule(..), IfaceAnnotation(..), IfaceAnnTarget,
+         IfaceInst(..), IfaceFamInst(..),
  
-       -- Misc
+         -- Misc
          ifaceDeclSubBndrs, visibleIfConDecls,
  
          -- Free Names
          freeNamesIfDecl, freeNamesIfRule,
  
-       -- Pretty printing
-       pprIfaceExpr, pprIfaceDeclHead 
+         -- Pretty printing
+         pprIfaceExpr, pprIfaceDeclHead
      ) where
  
  #include "HsVersions.h"
  
  import IfaceType
  import CoreSyn( DFunArg, dfunArgExprs )
- import PprCore()            -- Printing DFunArgs
+ import PprCore()     -- Printing DFunArgs
  import Demand
  import Annotations
  import Class
- import NameSet 
+ import NameSet
  import Name
  import CostCentre
  import Literal
@@@ -48,74 -48,75 +48,75 @@@ infixl 3 &&
  
  
  %************************************************************************
- %*                                                                    *
-               Data type declarations
- %*                                                                    *
+ %*                                                                      *
+     Data type declarations
+ %*                                                                      *
  %************************************************************************
  
  \begin{code}
- data IfaceDecl 
-   = IfaceId { ifName            :: OccName,
-             ifType      :: IfaceType, 
-             ifIdDetails :: IfaceIdDetails,
-             ifIdInfo    :: IfaceIdInfo }
-   | IfaceData { ifName       :: OccName,      -- Type constructor
-               ifTyVars     :: [IfaceTvBndr],  -- Type variables
-               ifCtxt       :: IfaceContext,   -- The "stupid theta"
-               ifCons       :: IfaceConDecls,  -- Includes new/data info
-               ifRec        :: RecFlag,        -- Recursive or not?
-               ifGadtSyntax :: Bool,           -- True <=> declared using
-                                               -- GADT syntax 
-               ifGeneric    :: Bool,           -- True <=> generic converter
-                                               --          functions available
-                                               -- We need this for imported
-                                               -- data decls, since the
-                                               -- imported modules may have
-                                               -- been compiled with
-                                               -- different flags to the
-                                               -- current compilation unit 
+ data IfaceDecl
+   = IfaceId { ifName      :: OccName,
+               ifType      :: IfaceType,
+               ifIdDetails :: IfaceIdDetails,
+               ifIdInfo    :: IfaceIdInfo }
+   | IfaceData { ifName       :: OccName,        -- Type constructor
+                 ifTyVars     :: [IfaceTvBndr],  -- Type variables
+                 ifCtxt       :: IfaceContext,   -- The "stupid theta"
+                 ifCons       :: IfaceConDecls,  -- Includes new/data info
+                 ifRec        :: RecFlag,        -- Recursive or not?
+                 ifGadtSyntax :: Bool,           -- True <=> declared using
+                                                 -- GADT syntax
+                 ifGeneric    :: Bool,           -- True <=> generic converter
+                                                 --          functions available
+                                                 -- We need this for imported
+                                                 -- data decls, since the
+                                                 -- imported modules may have
+                                                 -- been compiled with
+                                                 -- different flags to the
+                                                 -- current compilation unit
                  ifFamInst    :: Maybe (IfaceTyCon, [IfaceType])
                                                  -- Just <=> instance of family
-                                                 -- Invariant: 
+                                                 -- Invariant:
                                                  --   ifCons /= IfOpenDataTyCon
                                                  --   for family instances
      }
  
-   | IfaceSyn  {       ifName    :: OccName,           -- Type constructor
-               ifTyVars  :: [IfaceTvBndr],     -- Type variables
-               ifSynKind :: IfaceKind,         -- Kind of the *rhs* (not of the tycon)
-               ifSynRhs  :: Maybe IfaceType,   -- Just rhs for an ordinary synonyn
-                                               -- Nothing for an open family
+   | IfaceSyn  { ifName    :: OccName,           -- Type constructor
+                 ifTyVars  :: [IfaceTvBndr],     -- Type variables
+                 ifSynKind :: IfaceKind,         -- Kind of the *rhs* (not of the tycon)
+                 ifSynRhs  :: Maybe IfaceType,   -- Just rhs for an ordinary synonyn
+                                                 -- Nothing for an open family
                  ifFamInst :: Maybe (IfaceTyCon, [IfaceType])
                                                  -- Just <=> instance of family
                                                  -- Invariant: ifOpenSyn == False
                                                  --   for family instances
      }
  
-   | IfaceClass { ifCtxt    :: IfaceContext,   -- Context...
-                ifName    :: OccName,          -- Name of the class
-                ifTyVars  :: [IfaceTvBndr],    -- Type variables
-                ifFDs     :: [FunDep FastString], -- Functional dependencies
-                ifATs     :: [IfaceDecl],      -- Associated type families
-                ifSigs    :: [IfaceClassOp],   -- Method signatures
-                ifRec     :: RecFlag           -- Is newtype/datatype associated with the class recursive?
+   | IfaceClass { ifCtxt    :: IfaceContext,     -- Context...
+                  ifName    :: OccName,          -- Name of the class
+                  ifTyVars  :: [IfaceTvBndr],    -- Type variables
+                  ifFDs     :: [FunDep FastString], -- Functional dependencies
+                  ifATs     :: [IfaceDecl],      -- Associated type families
+                  ifSigs    :: [IfaceClassOp],   -- Method signatures
+                  ifRec     :: RecFlag           -- Is newtype/datatype associated
+                                                 --   with the class recursive?
      }
  
    | IfaceForeign { ifName :: OccName,           -- Needs expanding when we move
                                                  -- beyond .NET
-                  ifExtName :: Maybe FastString }
+                    ifExtName :: Maybe FastString }
  
  data IfaceClassOp = IfaceClassOp OccName DefMethSpec IfaceType
-       -- Nothing    => no default method
-       -- Just False => ordinary polymorphic default method
-       -- Just True  => generic default method
+         -- Nothing    => no default method
+         -- Just False => ordinary polymorphic default method
+         -- Just True  => generic default method
  
  data IfaceConDecls
-   = IfAbstractTyCon           -- No info
-   | IfOpenDataTyCon           -- Open data family
-   | IfDataTyCon [IfaceConDecl]        -- data type decls
-   | IfNewTyCon  IfaceConDecl  -- newtype decls
+   = IfAbstractTyCon             -- No info
+   | IfOpenDataTyCon             -- Open data family
+   | IfDataTyCon [IfaceConDecl]  -- data type decls
+   | IfNewTyCon  IfaceConDecl    -- newtype decls
  
  visibleIfConDecls :: IfaceConDecls -> [IfaceConDecl]
  visibleIfConDecls IfAbstractTyCon  = []
@@@ -123,49 -124,49 +124,49 @@@ visibleIfConDecls IfOpenDataTyCon  = [
  visibleIfConDecls (IfDataTyCon cs) = cs
  visibleIfConDecls (IfNewTyCon c)   = [c]
  
- data IfaceConDecl 
+ data IfaceConDecl
    = IfCon {
-       ifConOcc     :: OccName,                -- Constructor name
-       ifConWrapper :: Bool,                   -- True <=> has a wrapper
-       ifConInfix   :: Bool,                   -- True <=> declared infix
-       ifConUnivTvs :: [IfaceTvBndr],          -- Universal tyvars
-       ifConExTvs   :: [IfaceTvBndr],          -- Existential tyvars
-       ifConEqSpec  :: [(OccName,IfaceType)],  -- Equality contraints
-       ifConCtxt    :: IfaceContext,           -- Non-stupid context
-       ifConArgTys  :: [IfaceType],            -- Arg types
-       ifConFields  :: [OccName],              -- ...ditto... (field labels)
-       ifConStricts :: [HsBang]}               -- Empty (meaning all lazy),
-                                               -- or 1-1 corresp with arg tys
- data IfaceInst 
-   = IfaceInst { ifInstCls  :: IfExtName,              -- See comments with
-               ifInstTys  :: [Maybe IfaceTyCon],       -- the defn of Instance
-               ifDFun     :: IfExtName,                -- The dfun
-               ifOFlag    :: OverlapFlag,              -- Overlap flag
-               ifInstOrph :: Maybe OccName }           -- See Note [Orphans]
-       -- There's always a separate IfaceDecl for the DFun, which gives 
-       -- its IdInfo with its full type and version number.
-       -- The instance declarations taken together have a version number,
-       -- and we don't want that to wobble gratuitously
-       -- If this instance decl is *used*, we'll record a usage on the dfun;
-       -- and if the head does not change it won't be used if it wasn't before
+         ifConOcc     :: OccName,                -- Constructor name
+         ifConWrapper :: Bool,                   -- True <=> has a wrapper
+         ifConInfix   :: Bool,                   -- True <=> declared infix
+         ifConUnivTvs :: [IfaceTvBndr],          -- Universal tyvars
+         ifConExTvs   :: [IfaceTvBndr],          -- Existential tyvars
+         ifConEqSpec  :: [(OccName,IfaceType)],  -- Equality contraints
+         ifConCtxt    :: IfaceContext,           -- Non-stupid context
+         ifConArgTys  :: [IfaceType],            -- Arg types
+         ifConFields  :: [OccName],              -- ...ditto... (field labels)
+         ifConStricts :: [HsBang]}               -- Empty (meaning all lazy),
+                                                 -- or 1-1 corresp with arg tys
+ data IfaceInst
+   = IfaceInst { ifInstCls  :: IfExtName,                -- See comments with
+                 ifInstTys  :: [Maybe IfaceTyCon],       -- the defn of Instance
+                 ifDFun     :: IfExtName,                -- The dfun
+                 ifOFlag    :: OverlapFlag,              -- Overlap flag
+                 ifInstOrph :: Maybe OccName }           -- See Note [Orphans]
+         -- There's always a separate IfaceDecl for the DFun, which gives
+         -- its IdInfo with its full type and version number.
+         -- The instance declarations taken together have a version number,
+         -- and we don't want that to wobble gratuitously
+         -- If this instance decl is *used*, we'll record a usage on the dfun;
+         -- and if the head does not change it won't be used if it wasn't before
  
  data IfaceFamInst
    = IfaceFamInst { ifFamInstFam   :: IfExtName                -- Family tycon
-                , ifFamInstTys   :: [Maybe IfaceTyCon]  -- Rough match types
-                , ifFamInstTyCon :: IfaceTyCon          -- Instance decl
-                }
+                  , ifFamInstTys   :: [Maybe IfaceTyCon]  -- Rough match types
+                  , ifFamInstTyCon :: IfaceTyCon          -- Instance decl
+                  }
  
  data IfaceRule
-   = IfaceRule { 
-       ifRuleName   :: RuleName,
-       ifActivation :: Activation,
-       ifRuleBndrs  :: [IfaceBndr],    -- Tyvars and term vars
-       ifRuleHead   :: IfExtName,      -- Head of lhs
-       ifRuleArgs   :: [IfaceExpr],    -- Args of LHS
-       ifRuleRhs    :: IfaceExpr,
-       ifRuleAuto   :: Bool,
-       ifRuleOrph   :: Maybe OccName   -- Just like IfaceInst
+   = IfaceRule {
+         ifRuleName   :: RuleName,
+         ifActivation :: Activation,
+         ifRuleBndrs  :: [IfaceBndr],    -- Tyvars and term vars
+         ifRuleHead   :: IfExtName,      -- Head of lhs
+         ifRuleArgs   :: [IfaceExpr],    -- Args of LHS
+         ifRuleRhs    :: IfaceExpr,
+         ifRuleAuto   :: Bool,
+         ifRuleOrph   :: Maybe OccName   -- Just like IfaceInst
      }
  
  data IfaceAnnotation
@@@ -187,81 -188,80 +188,81 @@@ data IfaceIdDetail
    | IfDFunId Int          -- Number of silent args
  
  data IfaceIdInfo
-   = NoInfo                    -- When writing interface file without -O
-   | HasInfo [IfaceInfoItem]   -- Has info, and here it is
+   = NoInfo                      -- When writing interface file without -O
+   | HasInfo [IfaceInfoItem]     -- Has info, and here it is
  
  -- Here's a tricky case:
  --   * Compile with -O module A, and B which imports A.f
  --   * Change function f in A, and recompile without -O
  --   * When we read in old A.hi we read in its IdInfo (as a thunk)
- --    (In earlier GHCs we used to drop IdInfo immediately on reading,
- --     but we do not do that now.  Instead it's discarded when the
- --     ModIface is read into the various decl pools.)
+ --      (In earlier GHCs we used to drop IdInfo immediately on reading,
+ --       but we do not do that now.  Instead it's discarded when the
+ --       ModIface is read into the various decl pools.)
  --   * The version comparsion sees that new (=NoInfo) differs from old (=HasInfo *)
- --    and so gives a new version.
+ --      and so gives a new version.
  
  data IfaceInfoItem
-   = HsArity    Arity
+   = HsArity      Arity
    | HsStrictness StrictSig
    | HsInline     InlinePragma
-   | HsUnfold   Bool             -- True <=> isNonRuleLoopBreaker is true
-                IfaceUnfolding   -- See Note [Expose recursive functions] 
+   | HsUnfold     Bool             -- True <=> isNonRuleLoopBreaker is true
+                  IfaceUnfolding   -- See Note [Expose recursive functions]
    | HsNoCafRefs
  
  -- NB: Specialisations and rules come in separately and are
  -- only later attached to the Id.  Partial reason: some are orphans.
  
- data IfaceUnfolding 
+ data IfaceUnfolding
    = IfCoreUnfold Bool IfaceExpr -- True <=> INLINABLE, False <=> regular unfolding
                                  -- Possibly could eliminate the Bool here, the information
                                  -- is also in the InlinePragma.
  
-   | IfCompulsory IfaceExpr    -- Only used for default methods, in fact
+   | IfCompulsory IfaceExpr      -- Only used for default methods, in fact
  
    | IfInlineRule Arity          -- INLINE pragmas
-                  Bool         -- OK to inline even if *un*-saturated
-                Bool           -- OK to inline even if context is boring
-                  IfaceExpr 
+                  Bool           -- OK to inline even if *un*-saturated
+                  Bool           -- OK to inline even if context is boring
+                  IfaceExpr
  
-   | IfExtWrapper Arity IfExtName  -- NB: sometimes we need a IfExtName (not just IfLclName) 
-   | IfLclWrapper Arity IfLclName  --     because the worker can simplify to a function in 
-                                 --     another module.
+   | IfExtWrapper Arity IfExtName  -- NB: sometimes we need a IfExtName (not just IfLclName)
+   | IfLclWrapper Arity IfLclName  --     because the worker can simplify to a function in
+                                   --     another module.
  
    | IfDFunUnfold [DFunArg IfaceExpr]
  
  --------------------------------
  data IfaceExpr
-   = IfaceLcl  IfLclName
+   = IfaceLcl    IfLclName
    | IfaceExt    IfExtName
    | IfaceType   IfaceType
 -  | IfaceTuple  Boxity [IfaceExpr]              -- Saturated; type arguments omitted
 -  | IfaceLam    IfaceBndr IfaceExpr
 -  | IfaceApp    IfaceExpr IfaceExpr
 -  | IfaceCase   IfaceExpr IfLclName IfaceType [IfaceAlt]
 -  | IfaceLet    IfaceBinding  IfaceExpr
 -  | IfaceNote   IfaceNote IfaceExpr
 +  | IfaceCo     IfaceType             -- We re-use IfaceType for coercions
 +  | IfaceTuple        Boxity [IfaceExpr]      -- Saturated; type arguments omitted
 +  | IfaceLam  IfaceBndr IfaceExpr
 +  | IfaceApp  IfaceExpr IfaceExpr
 +  | IfaceCase IfaceExpr IfLclName [IfaceAlt]
 +  | IfaceLet  IfaceBinding  IfaceExpr
 +  | IfaceNote IfaceNote IfaceExpr
    | IfaceCast   IfaceExpr IfaceCoercion
-   | IfaceLit  Literal
-   | IfaceFCall        ForeignCall IfaceType
+   | IfaceLit    Literal
+   | IfaceFCall  ForeignCall IfaceType
    | IfaceTick   Module Int
  
  data IfaceNote = IfaceSCC CostCentre
                 | IfaceCoreNote String
  
  type IfaceAlt = (IfaceConAlt, [IfLclName], IfaceExpr)
-       -- Note: IfLclName, not IfaceBndr (and same with the case binder)
-       -- We reconstruct the kind/type of the thing from the context
-       -- thus saving bulk in interface files
+         -- Note: IfLclName, not IfaceBndr (and same with the case binder)
+         -- We reconstruct the kind/type of the thing from the context
+         -- thus saving bulk in interface files
  
  data IfaceConAlt = IfaceDefault
-                | IfaceDataAlt IfExtName
-                | IfaceTupleAlt Boxity
-                | IfaceLitAlt Literal
+                  | IfaceDataAlt IfExtName
+                  | IfaceTupleAlt Boxity
+                  | IfaceLitAlt Literal
  
  data IfaceBinding
-   = IfaceNonRec       IfaceLetBndr IfaceExpr
-   | IfaceRec  [(IfaceLetBndr, IfaceExpr)]
+   = IfaceNonRec IfaceLetBndr IfaceExpr
+   | IfaceRec    [(IfaceLetBndr, IfaceExpr)]
  
  -- IfaceLetBndr is like IfaceIdBndr, but has IdInfo too
  -- It's used for *non-top-level* let/rec binders
@@@ -300,9 -300,9 +301,9 @@@ complicate the situation though. Consid
  and suppose we are compiling module X:
  
    module X where
-       import M
-       data T = ...
-       instance C Int T where ...
+         import M
+         data T = ...
+         instance C Int T where ...
  
  This instance is an orphan, because when compiling a third module Y we
  might get a constraint (C Int v), and we'd want to improve v to T.  So
@@@ -316,7 -316,7 +317,7 @@@ More precisely, an instance is an orpha
  
    If there are fundeps, then for every fundep, at least one of the
    names free in a *non-determined* part of the instance head is
-   defined in this module.  
+   defined in this module.
  
  (Note that these conditions hold trivially if the class is locally
  defined.)
@@@ -343,10 -343,10 +344,10 @@@ a functionally-dependent part of the in
  and suppose we are compiling module X:
  
    module X where
-       import M
-       data S  = ...
-       data T = ...
-       instance C S T where ...
+         import M
+         data S  = ...
+         data T = ...
+         instance C S T where ...
  
  If we base the instance verion on T, I'm worried that changing S to S'
  would change T's version, but not S or S'.  But an importing module might
@@@ -357,8 -357,8 +358,8 @@@ and it seems deeply obscure, so I'm goi
  
  Note [Versioning of rules]
  ~~~~~~~~~~~~~~~~~~~~~~~~~~
- A rule that is not an orphan has an ifRuleOrph field of (Just n), where
- n appears on the LHS of the rule; any change in the rule changes the version of n.
+ A rule that is not an orphan has an ifRuleOrph field of (Just n), where n
+ appears on the LHS of the rule; any change in the rule changes the version of n.
  
  
  \begin{code}
@@@ -381,7 -381,7 +382,7 @@@ ifaceDeclSubBndrs IfaceData {ifCons = I
  ifaceDeclSubBndrs (IfaceData {ifName = tc_occ,
                                ifCons = IfNewTyCon (
                                          IfCon { ifConOcc = con_occ }),
-                               ifFamInst = famInst}) 
+                               ifFamInst = famInst})
    =   -- implicit coerion and (possibly) family instance coercion
      (mkNewTyCoOcc tc_occ) : (famInstCo famInst tc_occ) ++
        -- data constructor and worker (newtypes don't have a wrapper)
  
  
  ifaceDeclSubBndrs (IfaceData {ifName = tc_occ,
-                             ifCons = IfDataTyCon cons, 
-                             ifFamInst = famInst})
+                               ifCons = IfDataTyCon cons,
+                               ifFamInst = famInst})
    =   -- (possibly) family instance coercion;
        -- there is no implicit coercion for non-newtypes
      famInstCo famInst tc_occ
      ++ concatMap dc_occs cons
    where
      dc_occs con_decl
-       | has_wrapper = [con_occ, work_occ, wrap_occ]
-       | otherwise   = [con_occ, work_occ]
-       where
-         con_occ  = ifConOcc con_decl                  -- DataCon namespace
-         wrap_occ = mkDataConWrapperOcc con_occ        -- Id namespace
-         work_occ = mkDataConWorkerOcc con_occ         -- Id namespace
-         has_wrapper = ifConWrapper con_decl           -- This is the reason for
-                                                       -- having the ifConWrapper field!
- ifaceDeclSubBndrs (IfaceClass {ifCtxt = sc_ctxt, ifName = cls_occ, 
-                              ifSigs = sigs, ifATs = ats })
+         | has_wrapper = [con_occ, work_occ, wrap_occ]
+         | otherwise   = [con_occ, work_occ]
+         where
+           con_occ  = ifConOcc con_decl            -- DataCon namespace
+           wrap_occ = mkDataConWrapperOcc con_occ  -- Id namespace
+           work_occ = mkDataConWorkerOcc con_occ   -- Id namespace
+           has_wrapper = ifConWrapper con_decl     -- This is the reason for
+                                                   -- having the ifConWrapper field!
+ ifaceDeclSubBndrs (IfaceClass {ifCtxt = sc_ctxt, ifName = cls_occ,
+                                ifSigs = sigs, ifATs = ats })
    = -- dictionary datatype:
      --   type constructor
-     tc_occ : 
+     tc_occ :
      --   (possibly) newtype coercion
      co_occs ++
      --    data constructor (DataCon namespace)
      n_ctxt = length sc_ctxt
      n_sigs = length sigs
      tc_occ  = mkClassTyConOcc cls_occ
-     dc_occ  = mkClassDataConOcc cls_occ       
+     dc_occ  = mkClassDataConOcc cls_occ
      co_occs | is_newtype = [mkNewTyCoOcc tc_occ]
-           | otherwise  = []
+             | otherwise  = []
      dcww_occ = mkDataConWorkerOcc dc_occ
-     is_newtype = n_sigs + n_ctxt == 1                 -- Sigh 
+     is_newtype = n_sigs + n_ctxt == 1 -- Sigh
  
  ifaceDeclSubBndrs (IfaceSyn {ifName = tc_occ,
-                            ifFamInst = famInst})
+                              ifFamInst = famInst})
    = famInstCo famInst tc_occ
  
  ifaceDeclSubBndrs _ = []
@@@ -452,46 -452,46 +453,46 @@@ instance Outputable IfaceDecl wher
    ppr = pprIfaceDecl
  
  pprIfaceDecl :: IfaceDecl -> SDoc
- pprIfaceDecl (IfaceId {ifName = var, ifType = ty, 
+ pprIfaceDecl (IfaceId {ifName = var, ifType = ty,
                         ifIdDetails = details, ifIdInfo = info})
-   = sep [ ppr var <+> dcolon <+> ppr ty, 
-         nest 2 (ppr details),
-         nest 2 (ppr info) ]
+   = sep [ ppr var <+> dcolon <+> ppr ty,
+           nest 2 (ppr details),
+           nest 2 (ppr info) ]
  
  pprIfaceDecl (IfaceForeign {ifName = tycon})
    = hsep [ptext (sLit "foreign import type dotnet"), ppr tycon]
  
- pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars, 
-                       ifSynRhs = Just mono_ty, 
+ pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars,
+                         ifSynRhs = Just mono_ty,
                          ifFamInst = mbFamInst})
    = hang (ptext (sLit "type") <+> pprIfaceDeclHead [] tycon tyvars)
         4 (vcat [equals <+> ppr mono_ty, pprFamily mbFamInst])
  
- pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars, 
-                       ifSynRhs = Nothing, ifSynKind = kind })
+ pprIfaceDecl (IfaceSyn {ifName = tycon, ifTyVars = tyvars,
+                         ifSynRhs = Nothing, ifSynKind = kind })
    = hang (ptext (sLit "type family") <+> pprIfaceDeclHead [] tycon tyvars)
         4 (dcolon <+> ppr kind)
  
  pprIfaceDecl (IfaceData {ifName = tycon, ifGeneric = gen, ifCtxt = context,
-                        ifTyVars = tyvars, ifCons = condecls, 
-                        ifRec = isrec, ifFamInst = mbFamInst})
+                          ifTyVars = tyvars, ifCons = condecls,
+                          ifRec = isrec, ifFamInst = mbFamInst})
    = hang (pp_nd <+> pprIfaceDeclHead context tycon tyvars)
         4 (vcat [pprRec isrec, pprGen gen, pp_condecls tycon condecls,
-               pprFamily mbFamInst])
+                 pprFamily mbFamInst])
    where
      pp_nd = case condecls of
-               IfAbstractTyCon -> ptext (sLit "data")
-               IfOpenDataTyCon -> ptext (sLit "data family")
-               IfDataTyCon _   -> ptext (sLit "data")
-               IfNewTyCon _    -> ptext (sLit "newtype")
- pprIfaceDecl (IfaceClass {ifCtxt = context, ifName = clas, ifTyVars = tyvars, 
-                         ifFDs = fds, ifATs = ats, ifSigs = sigs, 
-                         ifRec = isrec})
+                 IfAbstractTyCon -> ptext (sLit "data")
+                 IfOpenDataTyCon -> ptext (sLit "data family")
+                 IfDataTyCon _   -> ptext (sLit "data")
+                 IfNewTyCon _    -> ptext (sLit "newtype")
+ pprIfaceDecl (IfaceClass {ifCtxt = context, ifName = clas, ifTyVars = tyvars,
+                           ifFDs = fds, ifATs = ats, ifSigs = sigs,
+                           ifRec = isrec})
    = hang (ptext (sLit "class") <+> pprIfaceDeclHead context clas tyvars <+> pprFundeps fds)
         4 (vcat [pprRec isrec,
-               sep (map ppr ats),
-               sep (map ppr sigs)])
+                 sep (map ppr ats),
+                 sep (map ppr sigs)])
  
  pprRec :: RecFlag -> SDoc
  pprRec isrec = ptext (sLit "RecFlag") <+> ppr isrec
@@@ -509,68 -509,68 +510,68 @@@ instance Outputable IfaceClassOp wher
  
  pprIfaceDeclHead :: IfaceContext -> OccName -> [IfaceTvBndr] -> SDoc
  pprIfaceDeclHead context thing tyvars
-   = hsep [pprIfaceContext context, parenSymOcc thing (ppr thing), 
-         pprIfaceTvBndrs tyvars]
+   = hsep [pprIfaceContext context, parenSymOcc thing (ppr thing),
+           pprIfaceTvBndrs tyvars]
  
  pp_condecls :: OccName -> IfaceConDecls -> SDoc
  pp_condecls _  IfAbstractTyCon  = ptext (sLit "{- abstract -}")
  pp_condecls tc (IfNewTyCon c)   = equals <+> pprIfaceConDecl tc c
  pp_condecls _  IfOpenDataTyCon  = empty
  pp_condecls tc (IfDataTyCon cs) = equals <+> sep (punctuate (ptext (sLit " |"))
-                                                            (map (pprIfaceConDecl tc) cs))
+                                                             (map (pprIfaceConDecl tc) cs))
  
  pprIfaceConDecl :: OccName -> IfaceConDecl -> SDoc
  pprIfaceConDecl tc
-       (IfCon { ifConOcc = name, ifConInfix = is_infix, ifConWrapper = has_wrap,
-                ifConUnivTvs = univ_tvs, ifConExTvs = ex_tvs, 
-                ifConEqSpec = eq_spec, ifConCtxt = ctxt, ifConArgTys = arg_tys, 
-                ifConStricts = strs, ifConFields = fields })
+         (IfCon { ifConOcc = name, ifConInfix = is_infix, ifConWrapper = has_wrap,
+                  ifConUnivTvs = univ_tvs, ifConExTvs = ex_tvs,
+                  ifConEqSpec = eq_spec, ifConCtxt = ctxt, ifConArgTys = arg_tys,
+                  ifConStricts = strs, ifConFields = fields })
    = sep [main_payload,
-        if is_infix then ptext (sLit "Infix") else empty,
-        if has_wrap then ptext (sLit "HasWrapper") else empty,
-        ppUnless (null strs) $
-           nest 4 (ptext (sLit "Stricts:") <+> hsep (map ppr_bang strs)),
-        ppUnless (null fields) $
-           nest 4 (ptext (sLit "Fields:") <+> hsep (map ppr fields))]
+          if is_infix then ptext (sLit "Infix") else empty,
+          if has_wrap then ptext (sLit "HasWrapper") else empty,
+          ppUnless (null strs) $
+             nest 4 (ptext (sLit "Stricts:") <+> hsep (map ppr_bang strs)),
+          ppUnless (null fields) $
+             nest 4 (ptext (sLit "Fields:") <+> hsep (map ppr fields))]
    where
-     ppr_bang HsNoBang = char '_'      -- Want to see these
+     ppr_bang HsNoBang = char '_'        -- Want to see these
      ppr_bang bang     = ppr bang
-         
-     main_payload = ppr name <+> dcolon <+> 
-                  pprIfaceForAllPart (univ_tvs ++ ex_tvs) (eq_ctxt ++ ctxt) pp_tau
  
-     eq_ctxt = [(IfaceEqPred (IfaceTyVar (occNameFS tv)) ty) 
-             | (tv,ty) <- eq_spec] 
+     main_payload = ppr name <+> dcolon <+>
+                    pprIfaceForAllPart (univ_tvs ++ ex_tvs) (eq_ctxt ++ ctxt) pp_tau
  
-       -- A bit gruesome this, but we can't form the full con_tau, and ppr it,
-       -- because we don't have a Name for the tycon, only an OccName
+     eq_ctxt = [(IfaceEqPred (IfaceTyVar (occNameFS tv)) ty)
+               | (tv,ty) <- eq_spec]
+         -- A bit gruesome this, but we can't form the full con_tau, and ppr it,
+         -- because we don't have a Name for the tycon, only an OccName
      pp_tau = case map pprParendIfaceType arg_tys ++ [pp_res_ty] of
-               (t:ts) -> fsep (t : map (arrow <+>) ts)
-               []     -> panic "pp_con_taus"
+                 (t:ts) -> fsep (t : map (arrow <+>) ts)
+                 []     -> panic "pp_con_taus"
  
      pp_res_ty = ppr tc <+> fsep [ppr tv | (tv,_) <- univ_tvs]
  
  instance Outputable IfaceRule where
    ppr (IfaceRule { ifRuleName = name, ifActivation = act, ifRuleBndrs = bndrs,
-                  ifRuleHead = fn, ifRuleArgs = args, ifRuleRhs = rhs }) 
+                    ifRuleHead = fn, ifRuleArgs = args, ifRuleRhs = rhs })
      = sep [hsep [doubleQuotes (ftext name), ppr act,
-                ptext (sLit "forall") <+> pprIfaceBndrs bndrs],
-          nest 2 (sep [ppr fn <+> sep (map pprParendIfaceExpr args),
-                       ptext (sLit "=") <+> ppr rhs])
+                  ptext (sLit "forall") <+> pprIfaceBndrs bndrs],
+            nest 2 (sep [ppr fn <+> sep (map pprParendIfaceExpr args),
+                         ptext (sLit "=") <+> ppr rhs])
        ]
  
  instance Outputable IfaceInst where
-   ppr (IfaceInst {ifDFun = dfun_id, ifOFlag = flag, 
-                 ifInstCls = cls, ifInstTys = mb_tcs})
-     = hang (ptext (sLit "instance") <+> ppr flag 
-               <+> ppr cls <+> brackets (pprWithCommas ppr_rough mb_tcs))
+   ppr (IfaceInst {ifDFun = dfun_id, ifOFlag = flag,
+                   ifInstCls = cls, ifInstTys = mb_tcs})
+     = hang (ptext (sLit "instance") <+> ppr flag
+                 <+> ppr cls <+> brackets (pprWithCommas ppr_rough mb_tcs))
           2 (equals <+> ppr dfun_id)
  
  instance Outputable IfaceFamInst where
    ppr (IfaceFamInst {ifFamInstFam = fam, ifFamInstTys = mb_tcs,
-                    ifFamInstTyCon = tycon_id})
-     = hang (ptext (sLit "family instance") <+> 
-           ppr fam <+> brackets (pprWithCommas ppr_rough mb_tcs))
+                      ifFamInstTyCon = tycon_id})
+     = hang (ptext (sLit "family instance") <+>
+             ppr fam <+> brackets (pprWithCommas ppr_rough mb_tcs))
           2 (equals <+> ppr tycon_id)
  
  ppr_rough :: Maybe IfaceTyCon -> SDoc
@@@ -588,9 -588,11 +589,11 @@@ instance Outputable IfaceExpr wher
  pprParendIfaceExpr :: IfaceExpr -> SDoc
  pprParendIfaceExpr = pprIfaceExpr parens
  
+ -- | Pretty Print an IfaceExpre
+ --
+ -- The first argument should be a function that adds parens in context that need
+ -- an atomic value (e.g. function args)
  pprIfaceExpr :: (SDoc -> SDoc) -> IfaceExpr -> SDoc
-       -- The function adds parens in context that need
-       -- an atomic value (e.g. function args)
  
  pprIfaceExpr _       (IfaceLcl v)       = ppr v
  pprIfaceExpr _       (IfaceExt v)       = ppr v
@@@ -598,105 -600,111 +601,112 @@@ pprIfaceExpr _       (IfaceLit l
  pprIfaceExpr _       (IfaceFCall cc ty) = braces (ppr cc <+> ppr ty)
  pprIfaceExpr _       (IfaceTick m ix)   = braces (text "tick" <+> ppr m <+> ppr ix)
  pprIfaceExpr _       (IfaceType ty)     = char '@' <+> pprParendIfaceType ty
 +pprIfaceExpr _       (IfaceCo co)       = text "@~" <+> pprParendIfaceType co
  
  pprIfaceExpr add_par app@(IfaceApp _ _) = add_par (pprIfaceApp app [])
  pprIfaceExpr _       (IfaceTuple c as)  = tupleParens c (interpp'SP as)
  
- pprIfaceExpr add_par e@(IfaceLam _ _)   
+ pprIfaceExpr add_par i@(IfaceLam _ _)
    = add_par (sep [char '\\' <+> sep (map ppr bndrs) <+> arrow,
-                 pprIfaceExpr noParens body])
-   where 
-     (bndrs,body) = collect [] e
+                   pprIfaceExpr noParens body])
+   where
+     (bndrs,body) = collect [] i
      collect bs (IfaceLam b e) = collect (b:bs) e
      collect bs e              = (reverse bs, e)
  
 -pprIfaceExpr add_par (IfaceCase scrut bndr ty [(con, bs, rhs)])
 -  = add_par (sep [ptext (sLit "case") <+> char '@' <+> pprParendIfaceType ty
 -                        <+> pprIfaceExpr noParens scrut <+> ptext (sLit "of")
 -                        <+> ppr bndr <+> char '{' <+> ppr_con_bs con bs <+> arrow,
 -                  pprIfaceExpr noParens rhs <+> char '}'])
 +pprIfaceExpr add_par (IfaceCase scrut bndr [(con, bs, rhs)])
 +  = add_par (sep [ptext (sLit "case") 
 +                      <+> pprIfaceExpr noParens scrut <+> ptext (sLit "of") 
 +                      <+> ppr bndr <+> char '{' <+> ppr_con_bs con bs <+> arrow,
 +                pprIfaceExpr noParens rhs <+> char '}'])
  
 -pprIfaceExpr add_par (IfaceCase scrut bndr ty alts)
 -  = add_par (sep [ptext (sLit "case") <+> char '@' <+> pprParendIfaceType ty
 -                        <+> pprIfaceExpr noParens scrut <+> ptext (sLit "of")
 -                        <+> ppr bndr <+> char '{',
 -                  nest 2 (sep (map ppr_alt alts)) <+> char '}'])
 +pprIfaceExpr add_par (IfaceCase scrut bndr alts)
 +  = add_par (sep [ptext (sLit "case") 
 +                      <+> pprIfaceExpr noParens scrut <+> ptext (sLit "of") 
 +                      <+> ppr bndr <+> char '{',
 +                nest 2 (sep (map ppr_alt alts)) <+> char '}'])
  
  pprIfaceExpr _       (IfaceCast expr co)
    = sep [pprParendIfaceExpr expr,
-        nest 2 (ptext (sLit "`cast`")),
-        pprParendIfaceType co]
+          nest 2 (ptext (sLit "`cast`")),
+          pprParendIfaceType co]
  
  pprIfaceExpr add_par (IfaceLet (IfaceNonRec b rhs) body)
-   = add_par (sep [ptext (sLit "let {"), 
-                 nest 2 (ppr_bind (b, rhs)),
-                 ptext (sLit "} in"), 
-                 pprIfaceExpr noParens body])
+   = add_par (sep [ptext (sLit "let {"),
+                   nest 2 (ppr_bind (b, rhs)),
+                   ptext (sLit "} in"),
+                   pprIfaceExpr noParens body])
  
  pprIfaceExpr add_par (IfaceLet (IfaceRec pairs) body)
    = add_par (sep [ptext (sLit "letrec {"),
-                 nest 2 (sep (map ppr_bind pairs)), 
-                 ptext (sLit "} in"),
-                 pprIfaceExpr noParens body])
+                   nest 2 (sep (map ppr_bind pairs)),
+                   ptext (sLit "} in"),
+                   pprIfaceExpr noParens body])
  
- pprIfaceExpr add_par (IfaceNote note body) = add_par (ppr note <+> pprParendIfaceExpr body)
+ pprIfaceExpr add_par (IfaceNote note body) = add_par $ ppr note
+                                                 <+> pprParendIfaceExpr body
  
  ppr_alt :: (IfaceConAlt, [IfLclName], IfaceExpr) -> SDoc
- ppr_alt (con, bs, rhs) = sep [ppr_con_bs con bs, 
-                             arrow <+> pprIfaceExpr noParens rhs]
+ ppr_alt (con, bs, rhs) = sep [ppr_con_bs con bs,
+                          arrow <+> pprIfaceExpr noParens rhs]
  
  ppr_con_bs :: IfaceConAlt -> [IfLclName] -> SDoc
  ppr_con_bs (IfaceTupleAlt tup_con) bs = tupleParens tup_con (interpp'SP bs)
- ppr_con_bs con bs                   = ppr con <+> hsep (map ppr bs)
-   
+ ppr_con_bs con bs                     = ppr con <+> hsep (map ppr bs)
  ppr_bind :: (IfaceLetBndr, IfaceExpr) -> SDoc
- ppr_bind (IfLetBndr b ty info, rhs) 
+ ppr_bind (IfLetBndr b ty info, rhs)
    = sep [hang (ppr b <+> dcolon <+> ppr ty) 2 (ppr info),
-        equals <+> pprIfaceExpr noParens rhs]
+          equals <+> pprIfaceExpr noParens rhs]
  
  ------------------
  pprIfaceApp :: IfaceExpr -> [SDoc] -> SDoc
- pprIfaceApp (IfaceApp fun arg) args = pprIfaceApp fun (nest 2 (pprParendIfaceExpr arg) : args)
- pprIfaceApp fun                      args = sep (pprParendIfaceExpr fun : args)
+ pprIfaceApp (IfaceApp fun arg) args = pprIfaceApp fun $
+                                           nest 2 (pprParendIfaceExpr arg) : args
+ pprIfaceApp fun                args = sep (pprParendIfaceExpr fun : args)
  
  ------------------
  instance Outputable IfaceNote where
      ppr (IfaceSCC cc)     = pprCostCentreCore cc
-     ppr (IfaceCoreNote s) = ptext (sLit "__core_note") <+> pprHsString (mkFastString s)
+     ppr (IfaceCoreNote s) = ptext (sLit "__core_note")
+                             <+> pprHsString (mkFastString s)
  
  
  instance Outputable IfaceConAlt where
      ppr IfaceDefault      = text "DEFAULT"
      ppr (IfaceLitAlt l)   = ppr l
      ppr (IfaceDataAlt d)  = ppr d
-     ppr (IfaceTupleAlt _) = panic "ppr IfaceConAlt" 
+     ppr (IfaceTupleAlt _) = panic "ppr IfaceConAlt"
      -- IfaceTupleAlt is handled by the case-alternative printer
  
  ------------------
  instance Outputable IfaceIdDetails where
-   ppr IfVanillaId    = empty
+   ppr IfVanillaId       = empty
    ppr (IfRecSelId tc b) = ptext (sLit "RecSel") <+> ppr tc
-                                 <+> if b then ptext (sLit "<naughty>") else empty
+                           <+> if b then ptext (sLit "<naughty>") else empty
    ppr (IfDFunId ns)     = ptext (sLit "DFunId") <> brackets (int ns)
  
  instance Outputable IfaceIdInfo where
    ppr NoInfo       = empty
-   ppr (HasInfo is) = ptext (sLit "{-") <+> pprWithCommas ppr is <+> ptext (sLit "-}")
+   ppr (HasInfo is) = ptext (sLit "{-") <+> pprWithCommas ppr is
+                      <+> ptext (sLit "-}")
  
  instance Outputable IfaceInfoItem where
-   ppr (HsUnfold lb unf)  = ptext (sLit "Unfolding") <> ppWhen lb (ptext (sLit "(loop-breaker)")) 
+   ppr (HsUnfold lb unf)  = ptext (sLit "Unfolding")
+                            <> ppWhen lb (ptext (sLit "(loop-breaker)"))
                             <> colon <+> ppr unf
    ppr (HsInline prag)    = ptext (sLit "Inline:") <+> ppr prag
    ppr (HsArity arity)    = ptext (sLit "Arity:") <+> int arity
    ppr (HsStrictness str) = ptext (sLit "Strictness:") <+> pprIfaceStrictSig str
-   ppr HsNoCafRefs      = ptext (sLit "HasNoCafRefs")
+   ppr HsNoCafRefs        = ptext (sLit "HasNoCafRefs")
  
  instance Outputable IfaceUnfolding where
    ppr (IfCompulsory e)     = ptext (sLit "<compulsory>") <+> parens (ppr e)
-   ppr (IfCoreUnfold s e)   = (if s then ptext (sLit "<stable>") else empty) <+> parens (ppr e)
-   ppr (IfInlineRule a uok bok e) = sep [ptext (sLit "InlineRule") <+> ppr (a,uok,bok),
-                                               pprParendIfaceExpr e]
+   ppr (IfCoreUnfold s e)   = (if s then ptext (sLit "<stable>") else empty)
+                               <+> parens (ppr e)
+   ppr (IfInlineRule a uok bok e) = sep [ptext (sLit "InlineRule")
+                                             <+> ppr (a,uok,bok),
+                                         pprParendIfaceExpr e]
    ppr (IfLclWrapper a wkr) = ptext (sLit "Worker(lcl):") <+> ppr wkr
                               <+> parens (ptext (sLit "arity") <+> int a)
    ppr (IfExtWrapper a wkr) = ptext (sLit "Worker(ext0:") <+> ppr wkr
                               <+> brackets (pprWithCommas ppr ns)
  
  -- -----------------------------------------------------------------------------
- -- Finding the Names in IfaceSyn
+ -- | Finding the Names in IfaceSyn
  
  -- This is used for dependency analysis in MkIface, so that we
  -- fingerprint a declaration before the things that depend on it.  It
  -- fingerprinting the instance, so DFuns are not dependencies.
  
  freeNamesIfDecl :: IfaceDecl -> NameSet
- freeNamesIfDecl (IfaceId _s t d i) = 
+ freeNamesIfDecl (IfaceId _s t d i) =
    freeNamesIfType t &&&
    freeNamesIfIdInfo i &&&
    freeNamesIfIdDetails d
- freeNamesIfDecl IfaceForeign{} = 
+ freeNamesIfDecl IfaceForeign{} =
    emptyNameSet
  freeNamesIfDecl d@IfaceData{} =
    freeNamesIfTvBndrs (ifTyVars d) &&&
@@@ -746,7 -754,7 +756,7 @@@ freeNamesIfSynRhs (Just ty) = freeNames
  freeNamesIfSynRhs Nothing   = emptyNameSet
  
  freeNamesIfTcFam :: Maybe (IfaceTyCon, [IfaceType]) -> NameSet
- freeNamesIfTcFam (Just (tc,tys)) = 
+ freeNamesIfTcFam (Just (tc,tys)) =
    freeNamesIfTc tc &&& fnList freeNamesIfType tys
  freeNamesIfTcFam Nothing =
    emptyNameSet
@@@ -766,15 -774,15 +776,15 @@@ freeNamesIfConDecls (IfNewTyCon c)  = f
  freeNamesIfConDecls _               = emptyNameSet
  
  freeNamesIfConDecl :: IfaceConDecl -> NameSet
- freeNamesIfConDecl c = 
+ freeNamesIfConDecl c =
    freeNamesIfTvBndrs (ifConUnivTvs c) &&&
    freeNamesIfTvBndrs (ifConExTvs c) &&&
-   freeNamesIfContext (ifConCtxt c) &&& 
+   freeNamesIfContext (ifConCtxt c) &&&
    fnList freeNamesIfType (ifConArgTys c) &&&
    fnList freeNamesIfType (map snd (ifConEqSpec c)) -- equality constraints
  
  freeNamesIfPredType :: IfacePredType -> NameSet
- freeNamesIfPredType (IfaceClassP cl tys) = 
+ freeNamesIfPredType (IfaceClassP cl tys) =
     unitNameSet cl &&& fnList freeNamesIfType tys
  freeNamesIfPredType (IfaceIParam _n ty) =
     freeNamesIfType ty
@@@ -785,13 -793,11 +795,13 @@@ freeNamesIfType :: IfaceType -> NameSe
  freeNamesIfType (IfaceTyVar _)        = emptyNameSet
  freeNamesIfType (IfaceAppTy s t)      = freeNamesIfType s &&& freeNamesIfType t
  freeNamesIfType (IfacePredTy st)      = freeNamesIfPredType st
- freeNamesIfType (IfaceTyConApp tc ts) = 
+ freeNamesIfType (IfaceTyConApp tc ts) =
     freeNamesIfTc tc &&& fnList freeNamesIfType ts
  freeNamesIfType (IfaceForAllTy tv t)  =
     freeNamesIfTvBndr tv &&& freeNamesIfType t
  freeNamesIfType (IfaceFunTy s t)      = freeNamesIfType s &&& freeNamesIfType t
 +freeNamesIfType (IfaceCoConApp tc ts) = 
 +   freeNamesIfCo tc &&& fnList freeNamesIfType ts
  
  freeNamesIfTvBndrs :: [IfaceTvBndr] -> NameSet
  freeNamesIfTvBndrs = fnList freeNamesIfTvBndr
@@@ -802,7 -808,7 +812,7 @@@ freeNamesIfBndr (IfaceTvBndr b) = freeN
  
  freeNamesIfLetBndr :: IfaceLetBndr -> NameSet
  -- Remember IfaceLetBndr is used only for *nested* bindings
- -- The IdInfo can contain an unfolding (in the case of 
+ -- The IdInfo can contain an unfolding (in the case of
  -- local INLINE pragmas), so look there too
  freeNamesIfLetBndr (IfLetBndr _name ty info) = freeNamesIfType ty
                                               &&& freeNamesIfIdInfo info
@@@ -815,7 -821,7 +825,7 @@@ freeNamesIfIdBndr :: IfaceIdBndr -> Nam
  freeNamesIfIdBndr = freeNamesIfTvBndr
  
  freeNamesIfIdInfo :: IfaceIdInfo -> NameSet
- freeNamesIfIdInfo NoInfo = emptyNameSet
+ freeNamesIfIdInfo NoInfo      = emptyNameSet
  freeNamesIfIdInfo (HasInfo i) = fnList freeNamesItem i
  
  freeNamesItem :: IfaceInfoItem -> NameSet
@@@ -831,28 -837,28 +841,28 @@@ freeNamesIfUnfold (IfLclWrapper {}
  freeNamesIfUnfold (IfDFunUnfold vs)      = fnList freeNamesIfExpr (dfunArgExprs vs)
  
  freeNamesIfExpr :: IfaceExpr -> NameSet
- freeNamesIfExpr (IfaceExt v)    = unitNameSet v
+ freeNamesIfExpr (IfaceExt v)      = unitNameSet v
  freeNamesIfExpr (IfaceFCall _ ty) = freeNamesIfType ty
  freeNamesIfExpr (IfaceType ty)    = freeNamesIfType ty
 +freeNamesIfExpr (IfaceCo co)      = freeNamesIfType co
  freeNamesIfExpr (IfaceTuple _ as) = fnList freeNamesIfExpr as
  freeNamesIfExpr (IfaceLam b body) = freeNamesIfBndr b &&& freeNamesIfExpr body
  freeNamesIfExpr (IfaceApp f a)    = freeNamesIfExpr f &&& freeNamesIfExpr a
  freeNamesIfExpr (IfaceCast e co)  = freeNamesIfExpr e &&& freeNamesIfType co
- freeNamesIfExpr (IfaceNote _n r)   = freeNamesIfExpr r
+ freeNamesIfExpr (IfaceNote _n r)  = freeNamesIfExpr r
  
 -freeNamesIfExpr (IfaceCase s _ ty alts)
 -  = freeNamesIfExpr s
 +freeNamesIfExpr (IfaceCase s _ alts)
 +  = freeNamesIfExpr s 
      &&& fnList fn_alt alts &&& fn_cons alts
 -    &&& freeNamesIfType ty
    where
      fn_alt (_con,_bs,r) = freeNamesIfExpr r
  
      -- Depend on the data constructors.  Just one will do!
      -- Note [Tracking data constructors]
-     fn_cons []                              = emptyNameSet
-     fn_cons ((IfaceDefault    ,_,_) : alts) = fn_cons alts
-     fn_cons ((IfaceDataAlt con,_,_) : _   ) = unitNameSet con    
-     fn_cons (_                      : _   ) = emptyNameSet
+     fn_cons []                            = emptyNameSet
+     fn_cons ((IfaceDefault    ,_,_) : xs) = fn_cons xs
+     fn_cons ((IfaceDataAlt con,_,_) : _ ) = unitNameSet con
+     fn_cons (_                      : _ ) = emptyNameSet
  
  freeNamesIfExpr (IfaceLet (IfaceNonRec bndr rhs) body)
    = freeNamesIfLetBndr bndr &&& freeNamesIfExpr rhs &&& freeNamesIfExpr body
@@@ -869,10 -875,6 +879,10 @@@ freeNamesIfTc (IfaceTc tc) = unitNameSe
  -- ToDo: shouldn't we include IfaceIntTc & co.?
  freeNamesIfTc _ = emptyNameSet
  
 +freeNamesIfCo :: IfaceCoCon -> NameSet
 +freeNamesIfCo (IfaceCoAx tc) = unitNameSet tc
 +freeNamesIfCo _ = emptyNameSet
 +
  freeNamesIfRule :: IfaceRule -> NameSet
  freeNamesIfRule (IfaceRule { ifRuleBndrs = bs, ifRuleHead = f
                             , ifRuleArgs = es, ifRuleRhs = rhs })
@@@ -891,18 -893,18 +901,18 @@@ fnList f = foldr (&&&) emptyNameSet . m
  
  Note [Tracking data constructors]
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- In a case expression 
+ In a case expression
     case e of { C a -> ...; ... }
  You might think that we don't need to include the datacon C
- in the free names, because its type will probably show up in 
+ in the free names, because its type will probably show up in
  the free names of 'e'.  But in rare circumstances this may
  not happen.   Here's the one that bit me:
  
-    module DynFlags where 
+    module DynFlags where
       import {-# SOURCE #-} Packages( PackageState )
       data DynFlags = DF ... PackageState ...
  
-    module Packages where 
+    module Packages where
       import DynFlags
       data PackageState = PS ...
       lookupModule (df :: DynFlags)
  Now, lookupModule depends on DynFlags, but the transitive dependency
  on the *locally-defined* type PackageState is not visible. We need
  to take account of the use of the data constructor PS in the pattern match.
@@@ -77,9 -77,7 +77,7 @@@ module DynFlags 
  
  #include "HsVersions.h"
  
- #ifndef OMIT_NATIVE_CODEGEN
  import Platform
- #endif
  import Module
  import PackageConfig
  import PrelNames        ( mAIN )
@@@ -110,7 -108,7 +108,7 @@@ import Data.Cha
  import Data.List
  import Data.Map (Map)
  import qualified Data.Map as Map
- -- import Data.Maybe
+ import Distribution.System
  import System.FilePath
  import System.IO        ( stderr, hPutChar )
  
@@@ -360,6 -358,7 +358,7 @@@ data ExtensionFla
     | Opt_KindSignatures
     | Opt_ParallelListComp
     | Opt_TransformListComp
+    | Opt_MonadComprehensions
     | Opt_GeneralizedNewtypeDeriving
     | Opt_RecursiveDo
     | Opt_DoRec
@@@ -402,9 -401,7 +401,7 @@@ data DynFlags = DynFlags 
    floatLamArgs          :: Maybe Int,   -- ^ Arg count for lambda floating
                                        --   See CoreMonad.FloatOutSwitches
  
- #ifndef OMIT_NATIVE_CODEGEN
-   targetPlatform      :: Platform,    -- ^ The platform we're compiling for. Used by the NCG.
- #endif
+   targetPlatform        :: Platform.Platform, -- ^ The platform we're compiling for. Used by the NCG.
    cmdlineHcIncludes     :: [String],    -- ^ @\-\#includes@
    importPaths           :: [FilePath],
    mainModIs             :: Module,
@@@ -630,6 -627,14 +627,14 @@@ data HscTarge
    | HscNothing     -- ^ Don't generate any code.  See notes above.
    deriving (Eq, Show)
  
+ showHscTargetFlag :: HscTarget -> String
+ showHscTargetFlag HscC           = "-fvia-c"
+ showHscTargetFlag HscAsm         = "-fasm"
+ showHscTargetFlag HscLlvm        = "-fllvm"
+ showHscTargetFlag HscJava        = panic "No flag for HscJava"
+ showHscTargetFlag HscInterpreted = "-fbyte-code"
+ showHscTargetFlag HscNothing     = "-fno-code"
  -- | Will this target result in an object file on the disk?
  isObjectTarget :: HscTarget -> Bool
  isObjectTarget HscC     = True
@@@ -692,8 -697,9 +697,9 @@@ defaultHscTarget = defaultObjectTarge
  -- object files on the current platform.
  defaultObjectTarget :: HscTarget
  defaultObjectTarget
+   | cGhcUnregisterised    == "YES"      =  HscC
    | cGhcWithNativeCodeGen == "YES"      =  HscAsm
-   | otherwise                           =  HscC
+   | otherwise                           =  HscLlvm
  
  data DynLibLoader
    = Deployable
@@@ -740,9 -746,7 +746,7 @@@ defaultDynFlags mySettings 
          floatLamArgs            = Just 0,     -- Default: float only if no fvs
          strictnessBefore        = [],
  
- #ifndef OMIT_NATIVE_CODEGEN
          targetPlatform          = defaultTargetPlatform,
- #endif
          cmdlineHcIncludes       = [],
          importPaths             = ["."],
          mainModIs               = mAIN,
                            SevOutput -> printOutput (msg style)
                            SevInfo   -> printErrs (msg style)
                            SevFatal  -> printErrs (msg style)
 -                          _         -> do 
 +                          _         -> do
                                  hPutChar stderr '\n'
                                  printErrs ((mkLocMessage srcSpan msg) style)
                       -- careful (#2302): printErrs prints in UTF-8, whereas
@@@ -1099,12 -1103,14 +1103,14 @@@ parseDynamicFlags_ dflags0 args pkg_fla
    when (not (null errs)) $ ghcError $ errorsToGhcException errs
  
    let (pic_warns, dflags2)
- #if !(x86_64_TARGET_ARCH && linux_TARGET_OS)
-         | (not opt_Static || opt_PIC) && hscTarget dflags1 == HscLlvm
-         = ([L noSrcSpan $ "Warning: -fllvm is incompatible with -fPIC and -"
-                 ++ "dynamic on this platform;\n              ignoring -fllvm"],
-                 dflags1{ hscTarget = HscAsm })
- #endif
+         | not (cTargetArch == X86_64 && (cTargetOS == Linux || cTargetOS == OSX)) &&
+           (not opt_Static || opt_PIC) &&
+           hscTarget dflags1 == HscLlvm
+         = ([L noSrcSpan $ "Warning: -fllvm is incompatible with -fPIC and "
+                        ++ "-dynamic on this platform;\n"
+                        ++ "         using "
+                        ++ showHscTargetFlag defaultObjectTarget ++ " instead"],
+                 dflags1{ hscTarget = defaultObjectTarget })
          | otherwise = ([], dflags1)
  
    return (dflags2, leftover, pic_warns ++ warns)
@@@ -1345,10 -1351,11 +1351,11 @@@ dynamic_flags = 
    , Flag "w"      (NoArg (mapM_ unSetDynFlag minuswRemovesOpts))
  
          ------ Optimisation flags ------------------------------------------
-   , Flag "O"      (noArg (setOptLevel 1))
-   , Flag "Onot"   (noArgDF (setOptLevel 0) "Use -O0 instead")
-   , Flag "Odph"   (noArg setDPHOpt)
-   , Flag "O"      (OptIntSuffix (\mb_n -> upd (setOptLevel (mb_n `orElse` 1))))
+   , Flag "O"      (noArgM (setOptLevel 1))
+   , Flag "Onot"   (noArgM (\dflags -> do deprecate "Use -O0 instead"
+                                          setOptLevel 0 dflags))
+   , Flag "Odph"   (noArgM setDPHOpt)
+   , Flag "O"      (optIntSuffixM (\mb_n -> setOptLevel (mb_n `orElse` 1)))
                  -- If the number is missing, use 1
  
    , Flag "fsimplifier-phases"          (intSuffix (\n d -> d{ simplPhases = n }))
@@@ -1615,6 -1622,7 +1622,7 @@@ xFlags = 
    ( "EmptyDataDecls",                   Opt_EmptyDataDecls, nop ),
    ( "ParallelListComp",                 Opt_ParallelListComp, nop ),
    ( "TransformListComp",                Opt_TransformListComp, nop ),
+   ( "MonadComprehensions",              Opt_MonadComprehensions, nop),
    ( "ForeignFunctionInterface",         Opt_ForeignFunctionInterface, nop ),
    ( "UnliftedFFITypes",                 Opt_UnliftedFFITypes, nop ),
    ( "GHCForeignImportPrim",             Opt_GHCForeignImportPrim, nop ),
    ( "RankNTypes",                       Opt_RankNTypes, nop ),
    ( "ImpredicativeTypes",               Opt_ImpredicativeTypes, nop), 
    ( "TypeOperators",                    Opt_TypeOperators, nop ),
-   ( "RecursiveDo",                      Opt_RecursiveDo,
+   ( "RecursiveDo",                      Opt_RecursiveDo,     -- Enables 'mdo'
      deprecatedForExtension "DoRec"),
-   ( "DoRec",                            Opt_DoRec, nop ),
+   ( "DoRec",                            Opt_DoRec, nop ),    -- Enables 'rec' keyword 
    ( "Arrows",                           Opt_Arrows, nop ),
    ( "ParallelArrays",                   Opt_ParallelArrays, nop ),
    ( "TemplateHaskell",                  Opt_TemplateHaskell, checkTemplateHaskellOk ),
@@@ -1904,13 -1912,21 +1912,21 @@@ checkTemplateHaskellOk _ = return (
  type DynP = EwM (CmdLineP DynFlags)
  
  upd :: (DynFlags -> DynFlags) -> DynP ()
- upd f = liftEwM (do { dfs <- getCmdLineState
-                     ; putCmdLineState $! (f dfs) })
+ upd f = liftEwM (do dflags <- getCmdLineState
+                     putCmdLineState $! f dflags)
+ updM :: (DynFlags -> DynP DynFlags) -> DynP ()
+ updM f = do dflags <- liftEwM getCmdLineState
+             dflags' <- f dflags
+             liftEwM $ putCmdLineState $! dflags'
  
  --------------- Constructor functions for OptKind -----------------
  noArg :: (DynFlags -> DynFlags) -> OptKind (CmdLineP DynFlags)
  noArg fn = NoArg (upd fn)
  
+ noArgM :: (DynFlags -> DynP DynFlags) -> OptKind (CmdLineP DynFlags)
+ noArgM fn = NoArg (updM fn)
  noArgDF :: (DynFlags -> DynFlags) -> String -> OptKind (CmdLineP DynFlags)
  noArgDF fn deprec = NoArg (upd fn >> deprecate deprec)
  
@@@ -1924,6 -1940,10 +1940,10 @@@ hasArgDF fn deprec = HasArg (\s -> do 
  intSuffix :: (Int -> DynFlags -> DynFlags) -> OptKind (CmdLineP DynFlags)
  intSuffix fn = IntSuffix (\n -> upd (fn n))
  
+ optIntSuffixM :: (Maybe Int -> DynFlags -> DynP DynFlags)
+               -> OptKind (CmdLineP DynFlags)
+ optIntSuffixM fn = OptIntSuffix (\mi -> updM (fn mi))
  setDumpFlag :: DynFlag -> OptKind (CmdLineP DynFlags)
  setDumpFlag dump_flag = NoArg (setDumpFlag' dump_flag)
  
@@@ -1971,13 -1991,14 +1991,13 @@@ forceRecompile :: DynP (
  -- recompiled which probably isn't what you want
  forceRecompile = do { dfs <- liftEwM getCmdLineState
                    ; when (force_recomp dfs) (setDynFlag Opt_ForceRecomp) }
 -      where
 +        where
          force_recomp dfs = isOneShot (ghcMode dfs)
  
  setVerboseCore2Core :: DynP ()
  setVerboseCore2Core = do forceRecompile
                           setDynFlag Opt_D_verbose_core2core 
                           upd (\dfs -> dfs { shouldDumpSimplPhase = Nothing })
 -                       
  
  setDumpSimplPhases :: String -> DynP ()
  setDumpSimplPhases s = do forceRecompile
@@@ -2021,20 -2042,36 +2041,36 @@@ setTarget l = upd se
  -- not from bytecode to object-code.  The idea is that -fasm/-fllvm
  -- can be safely used in an OPTIONS_GHC pragma.
  setObjTarget :: HscTarget -> DynP ()
- setObjTarget l = upd set
+ setObjTarget l = updM set
    where
-    set dfs
-      | isObjectTarget (hscTarget dfs) = dfs { hscTarget = l }
-      | otherwise = dfs
- setOptLevel :: Int -> DynFlags -> DynFlags
+    set dflags
+      | isObjectTarget (hscTarget dflags)
+        = case l of
+          HscC
+           | cGhcUnregisterised /= "YES" ->
+              do addWarn ("Compiler not unregisterised, so ignoring " ++
+                          showHscTargetFlag l)
+                 return dflags
+          HscAsm
+           | cGhcWithNativeCodeGen /= "YES" ->
+              do addWarn ("Compiler has no native codegen, so ignoring " ++
+                          showHscTargetFlag l)
+                 return dflags
+          HscLlvm
+           | cGhcUnregisterised == "YES" ->
+              do addWarn ("Compiler unregisterised, so ignoring " ++
+                          showHscTargetFlag l)
+                 return dflags
+          _ -> return $ dflags { hscTarget = l }
+      | otherwise = return dflags
+ setOptLevel :: Int -> DynFlags -> DynP DynFlags
  setOptLevel n dflags
     | hscTarget dflags == HscInterpreted && n > 0
-         = dflags
-             -- not in IO any more, oh well:
-             -- putStr "warning: -O conflicts with --interactive; -O ignored.\n"
+         = do addWarn "-O conflicts with --interactive; -O ignored."
+              return dflags
     | otherwise
-         = updOptLevel n dflags
+         = return (updOptLevel n dflags)
  
  
  -- -Odph is equivalent to
  --    -fmax-simplifier-iterations20     this is necessary sometimes
  --    -fsimplifier-phases=3             we use an additional simplifier phase for fusion
  --
- setDPHOpt :: DynFlags -> DynFlags
+ setDPHOpt :: DynFlags -> DynP DynFlags
  setDPHOpt dflags = setOptLevel 2 (dflags { maxSimplIterations  = 20
                                           , simplPhases         = 3
                                           })
@@@ -2095,6 -2132,7 +2131,6 @@@ addImportPath, addLibraryPath, addInclu
  addImportPath "" = upd (\s -> s{importPaths = []})
  addImportPath p  = upd (\s -> s{importPaths = importPaths s ++ splitPathList p})
  
 -
  addLibraryPath p =
    upd (\s -> s{libraryPaths = libraryPaths s ++ splitPathList p})
  
@@@ -160,6 -160,7 +160,7 @@@ basicKnownKeyName
        -- Monad stuff
        thenIOName, bindIOName, returnIOName, failIOName,
        failMName, bindMName, thenMName, returnMName,
+         fmapName,
  
        -- MonadRec stuff
        mfixName,
        -- dotnet interop
        , objectTyConName, marshalObjectName, unmarshalObjectName
        , marshalStringName, unmarshalStringName, checkDotnetResName
+         -- Monad comprehensions
+         , guardMName
+         , liftMName
+         , groupMName
+         , mzipName
      ]
  
  genericTyConNames :: [Name]
@@@ -262,8 -269,9 +269,9 @@@ gHC_PRIM, gHC_TYPES, gHC_UNIT, gHC_ORDE
      gHC_PACK, gHC_CONC, gHC_IO, gHC_IO_Exception,
      gHC_ST, gHC_ARR, gHC_STABLE, gHC_ADDR, gHC_PTR, gHC_ERR, gHC_REAL,
      gHC_FLOAT, gHC_TOP_HANDLER, sYSTEM_IO, dYNAMIC, tYPEABLE, gENERICS,
-     dOTNET, rEAD_PREC, lEX, gHC_INT, gHC_WORD, mONAD, mONAD_FIX, aRROW, cONTROL_APPLICATIVE,
-     gHC_DESUGAR, rANDOM, gHC_EXTS, cONTROL_EXCEPTION_BASE :: Module
+     dOTNET, rEAD_PREC, lEX, gHC_INT, gHC_WORD, mONAD, mONAD_FIX, mONAD_GROUP, mONAD_ZIP,
+     aRROW, cONTROL_APPLICATIVE, gHC_DESUGAR, rANDOM, gHC_EXTS,
+     cONTROL_EXCEPTION_BASE :: Module
  
  gHC_PRIM      = mkPrimModule (fsLit "GHC.Prim")   -- Primitive types and values
  gHC_TYPES       = mkPrimModule (fsLit "GHC.Types")
@@@ -311,6 -319,8 +319,8 @@@ gHC_INT            = mkBaseModule (fsLit "GHC.Int
  gHC_WORD      = mkBaseModule (fsLit "GHC.Word")
  mONAD         = mkBaseModule (fsLit "Control.Monad")
  mONAD_FIX     = mkBaseModule (fsLit "Control.Monad.Fix")
+ mONAD_GROUP     = mkBaseModule (fsLit "Control.Monad.Group")
+ mONAD_ZIP       = mkBaseModule (fsLit "Control.Monad.Zip")
  aRROW         = mkBaseModule (fsLit "Control.Arrow")
  cONTROL_APPLICATIVE = mkBaseModule (fsLit "Control.Applicative")
  gHC_DESUGAR = mkBaseModule (fsLit "GHC.Desugar")
@@@ -597,12 -607,13 +607,13 @@@ inlineIdName :: Nam
  inlineIdName          = varQual gHC_MAGIC (fsLit "inline") inlineIdKey
  
  -- Base classes (Eq, Ord, Functor)
- eqClassName, eqName, ordClassName, geName, functorClassName :: Name
+ fmapName, eqClassName, eqName, ordClassName, geName, functorClassName :: Name
  eqClassName     = clsQual  gHC_CLASSES (fsLit "Eq")      eqClassKey
  eqName                  = methName gHC_CLASSES (fsLit "==")      eqClassOpKey
  ordClassName    = clsQual  gHC_CLASSES (fsLit "Ord")     ordClassKey
  geName                  = methName gHC_CLASSES (fsLit ">=")      geClassOpKey
  functorClassName  = clsQual  gHC_BASE (fsLit "Functor") functorClassKey
+ fmapName          = methName gHC_BASE (fsLit "fmap")    fmapClassOpKey
  
  -- Class Monad
  monadClassName, thenMName, bindMName, returnMName, failMName :: Name
@@@ -834,6 -845,14 +845,14 @@@ appAName    = varQual aRROW (fsLit "app
  choiceAName      = varQual aRROW (fsLit "|||")          choiceAIdKey
  loopAName        = varQual aRROW (fsLit "loop")  loopAIdKey
  
+ -- Monad comprehensions
+ guardMName, liftMName, groupMName, mzipName :: Name
+ guardMName         = varQual mONAD (fsLit "guard") guardMIdKey
+ liftMName          = varQual mONAD (fsLit "liftM") liftMIdKey
+ groupMName         = varQual mONAD_GROUP (fsLit "mgroupWith") groupMIdKey
+ mzipName           = varQual mONAD_ZIP (fsLit "mzip") mzipIdKey
  -- Annotation type checking
  toAnnotationWrapperName :: Name
  toAnnotationWrapperName = varQual gHC_DESUGAR (fsLit "toAnnotationWrapper") toAnnotationWrapperIdKey
@@@ -1003,12 -1022,11 +1022,12 @@@ statePrimTyConKey, stableNamePrimTyConK
      word32PrimTyConKey, word32TyConKey, word64PrimTyConKey, word64TyConKey,
      liftedConKey, unliftedConKey, anyBoxConKey, kindConKey, boxityConKey,
      typeConKey, threadIdPrimTyConKey, bcoPrimTyConKey, ptrTyConKey,
 -    funPtrTyConKey, tVarPrimTyConKey :: Unique
 +    funPtrTyConKey, tVarPrimTyConKey, eqPredPrimTyConKey :: Unique
  statePrimTyConKey                     = mkPreludeTyConUnique 50
  stableNamePrimTyConKey                        = mkPreludeTyConUnique 51
 -stableNameTyConKey                    = mkPreludeTyConUnique 52
 -mutVarPrimTyConKey                    = mkPreludeTyConUnique 55
 +stableNameTyConKey                      = mkPreludeTyConUnique 52
 +eqPredPrimTyConKey                      = mkPreludeTyConUnique 53
 +mutVarPrimTyConKey                      = mkPreludeTyConUnique 55
  ioTyConKey                            = mkPreludeTyConUnique 56
  wordPrimTyConKey                      = mkPreludeTyConUnique 58
  wordTyConKey                          = mkPreludeTyConUnique 59
@@@ -1048,8 -1066,9 +1067,8 @@@ eitherTyConKey :: Uniqu
  eitherTyConKey                                = mkPreludeTyConUnique 84
  
  -- Super Kinds constructors
 -tySuperKindTyConKey, coSuperKindTyConKey :: Unique
 +tySuperKindTyConKey :: Unique
  tySuperKindTyConKey                    = mkPreludeTyConUnique 85
 -coSuperKindTyConKey                    = mkPreludeTyConUnique 86
  
  -- Kind constructors
  liftedTypeKindTyConKey, openTypeKindTyConKey, unliftedTypeKindTyConKey,
@@@ -1238,9 -1257,6 +1257,9 @@@ mapIdKey              = mkPreludeMiscIdUnique 
  groupWithIdKey        = mkPreludeMiscIdUnique 70
  dollarIdKey           = mkPreludeMiscIdUnique 71
  
 +coercionTokenIdKey :: Unique
 +coercionTokenIdKey    = mkPreludeMiscIdUnique 72
 +
  -- Parallel array functions
  singletonPIdKey, nullPIdKey, lengthPIdKey, replicatePIdKey, mapPIdKey,
      filterPIdKey, zipPIdKey, crossMapPIdKey, indexPIdKey, toPIdKey,
@@@ -1283,7 -1299,8 +1302,8 @@@ unboundKey                    = mkPreludeMiscIdUniq
  fromIntegerClassOpKey, minusClassOpKey, fromRationalClassOpKey,
      enumFromClassOpKey, enumFromThenClassOpKey, enumFromToClassOpKey,
      enumFromThenToClassOpKey, eqClassOpKey, geClassOpKey, negateClassOpKey,
-     failMClassOpKey, bindMClassOpKey, thenMClassOpKey, returnMClassOpKey
+     failMClassOpKey, bindMClassOpKey, thenMClassOpKey, returnMClassOpKey,
+     fmapClassOpKey
      :: Unique
  fromIntegerClassOpKey       = mkPreludeMiscIdUnique 102
  minusClassOpKey                     = mkPreludeMiscIdUnique 103
@@@ -1298,6 -1315,7 +1318,7 @@@ negateClassOpKey              = mkPreludeMiscI
  failMClassOpKey                     = mkPreludeMiscIdUnique 112
  bindMClassOpKey                     = mkPreludeMiscIdUnique 113 -- (>>=)
  thenMClassOpKey                     = mkPreludeMiscIdUnique 114 -- (>>)
+ fmapClassOpKey                = mkPreludeMiscIdUnique 115
  returnMClassOpKey           = mkPreludeMiscIdUnique 117
  
  -- Recursive do notation
@@@ -1328,6 -1346,14 +1349,14 @@@ realToFracIdKey      = mkPreludeMiscIdU
  toIntegerClassOpKey  = mkPreludeMiscIdUnique 129
  toRationalClassOpKey = mkPreludeMiscIdUnique 130
  
+ -- Monad comprehensions
+ guardMIdKey, liftMIdKey, groupMIdKey, mzipIdKey :: Unique
+ guardMIdKey     = mkPreludeMiscIdUnique 131
+ liftMIdKey      = mkPreludeMiscIdUnique 132
+ groupMIdKey     = mkPreludeMiscIdUnique 133
+ mzipIdKey       = mkPreludeMiscIdUnique 134
  ---------------- Template Haskell -------------------
  --    USES IdUniques 200-499
  -----------------------------------------------------
@@@ -458,7 -458,7 +458,7 @@@ rnBind :: (Name -> [Name])         -- Signatur
  rnBind _ trim (L loc bind@(PatBind { pat_lhs = pat
                                     , pat_rhs = grhss 
                                        -- pat fvs were stored in bind_fvs
 -                                      -- after processing the LHS          
 +                                      -- after processing the LHS
                                     , bind_fvs = pat_fvs }))
    = setSrcSpan loc $ 
      do        { let bndrs = collectPatBinders pat
@@@ -478,7 -478,7 +478,7 @@@ rnBind sig_fn tri
                              , fun_infix = is_infix 
                              , fun_matches = matches })) 
         -- invariant: no free vars here when it's a FunBind
 -  = setSrcSpan loc $ 
 +  = setSrcSpan loc $
      do        { let plain_name = unLoc name
  
        ; (matches', fvs) <- bindSigTyVarsFV (sig_fn plain_name) $
@@@ -789,9 -789,9 +789,9 @@@ rnGRHS' ctxt (GRHS guards rhs
        -- Standard Haskell 1.4 guards are just a single boolean
        -- expression, rather than a list of qualifiers as in the
        -- Glasgow extension
-     is_standard_guard []                     = True
-     is_standard_guard [L _ (ExprStmt _ _ _)] = True
-     is_standard_guard _                      = False
+     is_standard_guard []                       = True
+     is_standard_guard [L _ (ExprStmt _ _ _ _)] = True
+     is_standard_guard _                        = False
  \end{code}
  
  %************************************************************************
@@@ -7,7 -7,7 +7,7 @@@ Typecheck arrow notatio
  \begin{code}
  module TcArrows ( tcProc ) where
  
- import {-# SOURCE #-} TcExpr( tcMonoExpr, tcInferRho, tcSyntaxOp )
+ import {-# SOURCE #-} TcExpr( tcMonoExpr, tcInferRho, tcSyntaxOp, tcCheckId )
  
  import HsSyn
  import TcMatches
@@@ -17,7 -17,9 +17,9 @@@ import TcBind
  import TcPat
  import TcUnify
  import TcRnMonad
+ import TcEnv
  import Coercion
+ import Id( mkLocalId )
  import Inst
  import Name
  import TysWiredIn
@@@ -41,17 -43,17 +43,17 @@@ import Control.Mona
  \begin{code}
  tcProc :: InPat Name -> LHsCmdTop Name                -- proc pat -> expr
         -> TcRhoType                           -- Expected type of whole proc expression
 -       -> TcM (OutPat TcId, LHsCmdTop TcId, CoercionI)
 +       -> TcM (OutPat TcId, LHsCmdTop TcId, Coercion)
  
  tcProc pat cmd exp_ty
    = newArrowScope $
      do        { (coi, (exp_ty1, res_ty)) <- matchExpectedAppTy exp_ty 
        ; (coi1, (arr_ty, arg_ty)) <- matchExpectedAppTy exp_ty1
        ; let cmd_env = CmdEnv { cmd_arr = arr_ty }
 -      ; (pat', cmd') <- tcPat ProcExpr pat arg_ty $
 +        ; (pat', cmd') <- tcPat ProcExpr pat arg_ty $
                          tcCmdTop cmd_env cmd [] res_ty
 -        ; let res_coi = mkTransCoI coi (mkAppTyCoI coi1 (IdCo res_ty))
 -      ; return (pat', cmd', res_coi) }
 +        ; let res_coi = mkTransCo coi (mkAppCo coi1 (mkReflCo res_ty))
 +        ; return (pat', cmd', res_coi) }
  \end{code}
  
  
@@@ -83,20 -85,12 +85,12 @@@ tcCmdTop :: CmdEn
  
  tcCmdTop env (L loc (HsCmdTop cmd _ _ names)) cmd_stk res_ty
    = setSrcSpan loc $
-     do        { cmd'   <- tcGuardedCmd env cmd cmd_stk res_ty
+     do        { cmd'   <- tcCmd env cmd (cmd_stk, res_ty)
        ; names' <- mapM (tcSyntaxName ProcOrigin (cmd_arr env)) names
        ; return (L loc $ HsCmdTop cmd' cmd_stk res_ty names') }
  
  
  ----------------------------------------
- tcGuardedCmd :: CmdEnv -> LHsExpr Name -> CmdStack
-            -> TcTauType -> TcM (LHsExpr TcId)
- -- A wrapper that deals with the refinement (if any)
- tcGuardedCmd env expr stk res_ty
-   = do        { body <- tcCmd env expr (stk, res_ty)
-       ; return body 
-         }
  tcCmd :: CmdEnv -> LHsExpr Name -> (CmdStack, TcTauType) -> TcM (LHsExpr TcId)
        -- The main recursive function
  tcCmd env (L loc expr) res_ty
@@@ -123,7 -117,7 +117,7 @@@ tc_cmd env in_cmd@(HsCase scrut matches
    where
      match_ctxt = MC { mc_what = CaseAlt,
                        mc_body = mc_body }
-     mc_body body res_ty' = tcGuardedCmd env body stk res_ty'
+     mc_body body res_ty' = tcCmd env body (stk, res_ty')
  
  tc_cmd env (HsIf mb_fun pred b1 b2) (stack_ty,res_ty)
    = do        { pred_ty <- newFlexiTyVarTy openTypeKind
@@@ -187,8 -181,8 +181,8 @@@ tc_cmd env cmd@(HsLam (MatchGroup [L mt
  
                -- Check the patterns, and the GRHSs inside
        ; (pats', grhss') <- setSrcSpan mtch_loc                $
 -                           tcPats LambdaExpr pats cmd_stk     $
 -                           tc_grhss grhss res_ty
 +                             tcPats LambdaExpr pats cmd_stk     $
 +                             tc_grhss grhss res_ty
  
        ; let match' = L mtch_loc (Match pats' Nothing grhss')
        ; return (HsLam (MatchGroup [match'] res_ty))
             ; return (GRHSs grhss' binds') }
  
      tc_grhs res_ty (GRHS guards body)
-       = do { (guards', rhs') <- tcStmts pg_ctxt tcGuardStmt guards res_ty $
-                                 tcGuardedCmd env body stk'
+       = do { (guards', rhs') <- tcStmtsAndThen pg_ctxt tcGuardStmt guards res_ty $
+                                 \ res_ty -> tcCmd env body (stk', res_ty)
             ; return (GRHS guards' rhs') }
  
  -------------------------------------------
  --            Do notation
  
- tc_cmd env cmd@(HsDo do_or_lc stmts body _ty) (cmd_stk, res_ty)
+ tc_cmd env cmd@(HsDo do_or_lc stmts _) (cmd_stk, res_ty)
    = do        { checkTc (null cmd_stk) (nonEmptyCmdStkErr cmd)
-       ; (stmts', body') <- tcStmts do_or_lc (tcMDoStmt tc_rhs) stmts res_ty $
-                            tcGuardedCmd env body []
-       ; return (HsDo do_or_lc stmts' body' res_ty) }
+       ; stmts' <- tcStmts do_or_lc (tcArrDoStmt env) stmts res_ty 
+       ; return (HsDo do_or_lc stmts' res_ty) }
    where
-     tc_rhs rhs = do { ty <- newFlexiTyVarTy liftedTypeKind
-                   ; rhs' <- tcCmd env rhs ([], ty)
-                   ; return (rhs', ty) }
  
  
  -----------------------------------------------------------------
@@@ -249,7 -239,7 +239,7 @@@ tc_cmd env cmd@(HsArrForm expr fixity c
                              e_res_ty
  
                -- Check expr
 -      ; (inst_binds, expr') <- checkConstraints ArrowSkol [w_tv] [] $
 +        ; (inst_binds, expr') <- checkConstraints ArrowSkol [w_tv] [] $
                                   escapeArrowScope (tcMonoExpr expr e_ty)
  
                -- OK, now we are in a position to unscramble 
                -- Check that it has the right shape:
                --      ((w,s1) .. sn)
                -- where the si do not mention w
 -         ; checkTc (corner_ty `tcEqType` mkTyVarTy w_tv && 
 +         ; checkTc (corner_ty `eqType` mkTyVarTy w_tv && 
                      not (w_tv `elemVarSet` tyVarsOfTypes arg_tys))
                     (badFormFun i tup_ty')
  
@@@ -307,6 -297,69 +297,69 @@@ tc_cmd _ cmd 
  
  %************************************************************************
  %*                                                                    *
+               Stmts
+ %*                                                                    *
+ %************************************************************************
+ \begin{code}
+ --------------------------------
+ --    Mdo-notation
+ -- The distinctive features here are
+ --    (a) RecStmts, and
+ --    (b) no rebindable syntax
+ tcArrDoStmt :: CmdEnv -> TcStmtChecker
+ tcArrDoStmt env _ (LastStmt rhs _) res_ty thing_inside
+   = do        { rhs' <- tcCmd env rhs ([], res_ty)
+       ; thing <- thing_inside (panic "tcArrDoStmt")
+       ; return (LastStmt rhs' noSyntaxExpr, thing) }
+ tcArrDoStmt env _ (ExprStmt rhs _ _ _) res_ty thing_inside
+   = do        { (rhs', elt_ty) <- tc_arr_rhs env rhs
+       ; thing          <- thing_inside res_ty
+       ; return (ExprStmt rhs' noSyntaxExpr noSyntaxExpr elt_ty, thing) }
+ tcArrDoStmt env ctxt (BindStmt pat rhs _ _) res_ty thing_inside
+   = do        { (rhs', pat_ty) <- tc_arr_rhs env rhs
+       ; (pat', thing)  <- tcPat (StmtCtxt ctxt) pat pat_ty $
+                             thing_inside res_ty
+       ; return (BindStmt pat' rhs' noSyntaxExpr noSyntaxExpr, thing) }
+ tcArrDoStmt env ctxt (RecStmt { recS_stmts = stmts, recS_later_ids = laterNames
+                             , recS_rec_ids = recNames }) res_ty thing_inside
+   = do        { rec_tys <- newFlexiTyVarTys (length recNames) liftedTypeKind
+       ; let rec_ids = zipWith mkLocalId recNames rec_tys
+       ; tcExtendIdEnv rec_ids $ do
+       { (stmts', (later_ids, rec_rets))
+               <- tcStmtsAndThen ctxt (tcArrDoStmt env) stmts res_ty   $ \ _res_ty' ->
+                       -- ToDo: res_ty not really right
+                  do { rec_rets <- zipWithM tcCheckId recNames rec_tys
+                     ; later_ids <- tcLookupLocalIds laterNames
+                     ; return (later_ids, rec_rets) }
+       ; thing <- tcExtendIdEnv later_ids (thing_inside res_ty)
+               -- NB:  The rec_ids for the recursive things 
+               --      already scope over this part. This binding may shadow
+               --      some of them with polymorphic things with the same Name
+               --      (see note [RecStmt] in HsExpr)
+         ; return (emptyRecStmt { recS_stmts = stmts', recS_later_ids = later_ids
+                                , recS_rec_ids = rec_ids, recS_rec_rets = rec_rets
+                                , recS_ret_ty = res_ty }, thing)
+       }}
+ tcArrDoStmt _ _ stmt _ _
+   = pprPanic "tcArrDoStmt: unexpected Stmt" (ppr stmt)
+ tc_arr_rhs :: CmdEnv -> LHsExpr Name -> TcM (LHsExpr TcId, TcType)
+ tc_arr_rhs env rhs = do { ty <- newFlexiTyVarTy liftedTypeKind
+                       ; rhs' <- tcCmd env rhs ([], ty)
+                       ; return (rhs', ty) }
+ \end{code}
+ %************************************************************************
+ %*                                                                    *
                Helpers
  %*                                                                    *
  %************************************************************************
@@@ -45,6 -45,7 +45,7 @@@ import Typ
  import Coercion
  import Var
  import VarSet
+ import VarEnv
  import TysWiredIn
  import TysPrim( intPrimTy )
  import PrimOp( tagToEnumKey )
@@@ -55,6 -56,7 +56,7 @@@ import SrcLo
  import Util
  import ListSetOps
  import Maybes
+ import ErrUtils
  import Outputable
  import FastString
  import Control.Monad
@@@ -286,8 -288,8 +288,8 @@@ tcExpr (OpApp arg1 op fix arg2) res_t
         ; co_res <- unifyType op_res_ty res_ty
         ; op_id <- tcLookupId op_name
         ; let op' = L loc (HsWrap (mkWpTyApps [arg2_ty, op_res_ty]) (HsVar op_id))
 -       ; return $ mkHsWrapCoI co_res $
 -         OpApp (mkLHsWrapCoI co_arg1 arg1') op' fix arg2' }
 +       ; return $ mkHsWrapCo co_res $
 +         OpApp (mkLHsWrapCo co_arg1 arg1') op' fix arg2' }
  
    | otherwise
    = do { traceTc "Non Application rule" (ppr op)
         ; (co_fn, arg_tys, op_res_ty) <- unifyOpFunTys op 2 op_ty
         ; co_res <- unifyType op_res_ty res_ty
         ; [arg1', arg2'] <- tcArgs op [arg1, arg2] arg_tys
 -       ; return $ mkHsWrapCoI co_res $
 -         OpApp arg1' (mkLHsWrapCoI co_fn op') fix arg2' }
 +       ; return $ mkHsWrapCo co_res $
 +         OpApp arg1' (mkLHsWrapCo co_fn op') fix arg2' }
  
  -- Right sections, equivalent to \ x -> x `op` expr, or
  --    \ x -> op x expr
@@@ -306,8 -308,8 +308,8 @@@ tcExpr (SectionR op arg2) res_t
         ; (co_fn, [arg1_ty, arg2_ty], op_res_ty) <- unifyOpFunTys op 2 op_ty
         ; co_res <- unifyType (mkFunTy arg1_ty op_res_ty) res_ty
         ; arg2' <- tcArg op (arg2, arg2_ty, 2)
 -       ; return $ mkHsWrapCoI co_res $
 -         SectionR (mkLHsWrapCoI co_fn op') arg2' } 
 +       ; return $ mkHsWrapCo co_res $
 +         SectionR (mkLHsWrapCo co_fn op') arg2' } 
  
  tcExpr (SectionL arg1 op) res_ty
    = do { (op', op_ty) <- tcInferFun op
         ; (co_fn, (arg1_ty:arg_tys), op_res_ty) <- unifyOpFunTys op n_reqd_args op_ty
         ; co_res <- unifyType (mkFunTys arg_tys op_res_ty) res_ty
         ; arg1' <- tcArg op (arg1, arg1_ty, 1)
 -       ; return $ mkHsWrapCoI co_res $
 -         SectionL arg1' (mkLHsWrapCoI co_fn op') }
 +       ; return $ mkHsWrapCo co_res $
 +         SectionL arg1' (mkLHsWrapCo co_fn op') }
  
  tcExpr (ExplicitTuple tup_args boxity) res_ty
    | all tupArgPresent tup_args
    = do { let tup_tc = tupleTyCon boxity (length tup_args)
         ; (coi, arg_tys) <- matchExpectedTyConApp tup_tc res_ty
         ; tup_args1 <- tcTupArgs tup_args arg_tys
 -       ; return $ mkHsWrapCoI coi (ExplicitTuple tup_args1 boxity) }
 +       ; return $ mkHsWrapCo coi (ExplicitTuple tup_args1 boxity) }
      
    | otherwise
    = -- The tup_args are a mixture of Present and Missing (for tuple sections)
         -- Handle tuple sections where
         ; tup_args1 <- tcTupArgs tup_args arg_tys
         
 -       ; return $ mkHsWrapCoI coi (ExplicitTuple tup_args1 boxity) }
 +       ; return $ mkHsWrapCo coi (ExplicitTuple tup_args1 boxity) }
  
  tcExpr (ExplicitList _ exprs) res_ty
    = do        { (coi, elt_ty) <- matchExpectedListTy res_ty
        ; exprs' <- mapM (tc_elt elt_ty) exprs
 -      ; return $ mkHsWrapCoI coi (ExplicitList elt_ty exprs') }
 +      ; return $ mkHsWrapCo coi (ExplicitList elt_ty exprs') }
    where
      tc_elt elt_ty expr = tcPolyExpr expr elt_ty
  
  tcExpr (ExplicitPArr _ exprs) res_ty  -- maybe empty
    = do        { (coi, elt_ty) <- matchExpectedPArrTy res_ty
        ; exprs' <- mapM (tc_elt elt_ty) exprs  
 -      ; return $ mkHsWrapCoI coi (ExplicitPArr elt_ty exprs') }
 +      ; return $ mkHsWrapCo coi (ExplicitPArr elt_ty exprs') }
    where
      tc_elt elt_ty expr = tcPolyExpr expr elt_ty
  \end{code}
@@@ -415,12 -417,12 +417,12 @@@ tcExpr (HsIf (Just fun) pred b1 b2) res
         -- and it maintains uniformity with other rebindable syntax
         ; return (HsIf (Just fun') pred' b1' b2') }
  
- tcExpr (HsDo do_or_lc stmts body _) res_ty
-   = tcDoStmts do_or_lc stmts body res_ty
+ tcExpr (HsDo do_or_lc stmts _) res_ty
+   = tcDoStmts do_or_lc stmts res_ty
  
  tcExpr (HsProc pat cmd) res_ty
    = do        { (pat', cmd', coi) <- tcProc pat cmd res_ty
 -      ; return $ mkHsWrapCoI coi (HsProc pat' cmd') }
 +      ; return $ mkHsWrapCo coi (HsProc pat' cmd') }
  
  tcExpr e@(HsArrApp _ _ _ _ _) _
    = failWithTc (vcat [ptext (sLit "The arrow command"), nest 2 (ppr e), 
@@@ -467,7 -469,7 +469,7 @@@ tcExpr (RecordCon (L loc con_name) _ rb
  
          ; co_res <- unifyType actual_res_ty res_ty
          ; rbinds' <- tcRecordBinds data_con arg_tys rbinds
 -      ; return $ mkHsWrapCoI co_res $ 
 +      ; return $ mkHsWrapCo co_res $ 
            RecordCon (L loc con_id) con_expr rbinds' } 
  \end{code}
  
@@@ -603,7 -605,7 +605,7 @@@ tcExpr (RecordUpd record_expr rbinds _ 
  
                -- Take apart a representative constructor
              con1 = ASSERT( not (null relevant_cons) ) head relevant_cons
 -            (con1_tvs, _, _, _, _, con1_arg_tys, _) = dataConFullSig con1
 +            (con1_tvs, _, _, _, con1_arg_tys, _) = dataConFullSig con1
              con1_flds = dataConFieldLabels con1
              con1_res_ty = mkFamilyTyConApp tycon (mkTyVarTys con1_tvs)
              
        ; (_, result_inst_tys, result_inst_env) <- tcInstTyVars con1_tvs
        ; scrut_inst_tys <- zipWithM mk_inst_ty con1_tvs result_inst_tys
  
 -      ; let rec_res_ty    = substTy result_inst_env con1_res_ty
 -            con1_arg_tys' = map (substTy result_inst_env) con1_arg_tys
 +      ; let rec_res_ty    = TcType.substTy result_inst_env con1_res_ty
 +            con1_arg_tys' = map (TcType.substTy result_inst_env) con1_arg_tys
              scrut_subst   = zipTopTvSubst con1_tvs scrut_inst_tys
 -            scrut_ty      = substTy scrut_subst con1_res_ty
 +            scrut_ty      = TcType.substTy scrut_subst con1_res_ty
  
          ; co_res <- unifyType rec_res_ty res_ty
  
  
        -- Step 7: make a cast for the scrutinee, in the case that it's from a type family
        ; let scrut_co | Just co_con <- tyConFamilyCoercion_maybe tycon 
 -                     = WpCast $ mkTyConApp co_con scrut_inst_tys
 +                     = WpCast $ mkAxInstCo co_con scrut_inst_tys
                       | otherwise
                       = idHsWrapper
        -- Phew!
 -        ; return $ mkHsWrapCoI co_res $
 +        ; return $ mkHsWrapCo co_res $
            RecordUpd (mkLHsWrap scrut_co record_expr') rbinds'
                                   relevant_cons scrut_inst_tys result_inst_tys  }
    where
@@@ -703,7 -705,7 +705,7 @@@ tcExpr (ArithSeq _ seq@(From expr)) res
        ; expr' <- tcPolyExpr expr elt_ty
        ; enum_from <- newMethodFromName (ArithSeqOrigin seq) 
                              enumFromName elt_ty 
 -      ; return $ mkHsWrapCoI coi (ArithSeq enum_from (From expr')) }
 +      ; return $ mkHsWrapCo coi (ArithSeq enum_from (From expr')) }
  
  tcExpr (ArithSeq _ seq@(FromThen expr1 expr2)) res_ty
    = do        { (coi, elt_ty) <- matchExpectedListTy res_ty
        ; expr2' <- tcPolyExpr expr2 elt_ty
        ; enum_from_then <- newMethodFromName (ArithSeqOrigin seq) 
                              enumFromThenName elt_ty 
 -      ; return $ mkHsWrapCoI coi 
 +      ; return $ mkHsWrapCo coi 
                      (ArithSeq enum_from_then (FromThen expr1' expr2')) }
  
  tcExpr (ArithSeq _ seq@(FromTo expr1 expr2)) res_ty
        ; expr2' <- tcPolyExpr expr2 elt_ty
        ; enum_from_to <- newMethodFromName (ArithSeqOrigin seq) 
                              enumFromToName elt_ty 
 -      ; return $ mkHsWrapCoI coi 
 +      ; return $ mkHsWrapCo coi 
                       (ArithSeq enum_from_to (FromTo expr1' expr2')) }
  
  tcExpr (ArithSeq _ seq@(FromThenTo expr1 expr2 expr3)) res_ty
        ; expr3' <- tcPolyExpr expr3 elt_ty
        ; eft <- newMethodFromName (ArithSeqOrigin seq) 
                      enumFromThenToName elt_ty 
 -      ; return $ mkHsWrapCoI coi 
 +      ; return $ mkHsWrapCo coi 
                       (ArithSeq eft (FromThenTo expr1' expr2' expr3')) }
  
  tcExpr (PArrSeq _ seq@(FromTo expr1 expr2)) res_ty
        ; expr2' <- tcPolyExpr expr2 elt_ty
        ; enum_from_to <- newMethodFromName (PArrSeqOrigin seq) 
                                 (enumFromToPName basePackageId) elt_ty    -- !!!FIXME: chak
 -      ; return $ mkHsWrapCoI coi 
 +      ; return $ mkHsWrapCo coi 
                       (PArrSeq enum_from_to (FromTo expr1' expr2')) }
  
  tcExpr (PArrSeq _ seq@(FromThenTo expr1 expr2 expr3)) res_ty
        ; expr3' <- tcPolyExpr expr3 elt_ty
        ; eft <- newMethodFromName (PArrSeqOrigin seq)
                      (enumFromThenToPName basePackageId) elt_ty        -- !!!FIXME: chak
 -      ; return $ mkHsWrapCoI coi 
 +      ; return $ mkHsWrapCo coi 
                       (PArrSeq eft (FromThenTo expr1' expr2' expr3')) }
  
  tcExpr (PArrSeq _ _) _ 
@@@ -820,15 -822,15 +822,15 @@@ tcApp fun args res_t
        -- Typecheck the result, thereby propagating 
          -- info (if any) from result into the argument types
          -- Both actual_res_ty and res_ty are deeply skolemised
-         ; co_res <- addErrCtxt (funResCtxt fun) $
+         ; co_res <- addErrCtxtM (funResCtxt fun actual_res_ty res_ty) $
                      unifyType actual_res_ty res_ty
  
        -- Typecheck the arguments
        ; args1 <- tcArgs fun args expected_arg_tys
  
          -- Assemble the result
 -      ; let fun2 = mkLHsWrapCoI co_fun fun1
 -              app  = mkLHsWrapCoI co_res (foldl mkHsApp fun2 args1)
 +      ; let fun2 = mkLHsWrapCo co_fun fun1
 +              app  = mkLHsWrapCo co_res (foldl mkHsApp fun2 args1)
  
          ; return (unLoc app) }
  
@@@ -850,7 -852,7 +852,7 @@@ tcInferApp fun arg
        ; (co_fun, expected_arg_tys, actual_res_ty)
              <- matchExpectedFunTys (mk_app_msg fun) (length args) fun_tau
        ; args1 <- tcArgs fun args expected_arg_tys
 -      ; let fun2 = mkLHsWrapCoI co_fun fun1
 +      ; let fun2 = mkLHsWrapCo co_fun fun1
                app  = foldl mkHsApp fun2 args1
          ; return (unLoc app, actual_res_ty) }
  
@@@ -899,7 -901,7 +901,7 @@@ tcTupArgs args ty
  
  ----------------
  unifyOpFunTys :: LHsExpr Name -> Arity -> TcRhoType
 -              -> TcM (CoercionI, [TcSigmaType], TcRhoType)                    
 +              -> TcM (Coercion, [TcSigmaType], TcRhoType)                     
  -- A wrapper for matchExpectedFunTys
  unifyOpFunTys op arity ty = matchExpectedFunTys herald arity ty
    where
@@@ -1010,7 -1012,7 +1012,7 @@@ instantiateOuter orig i
         ; let theta' = substTheta subst theta
         ; traceTc "Instantiating" (ppr id <+> text "with" <+> (ppr tys $$ ppr theta'))
         ; wrap <- instCall orig tys theta'
 -       ; return (mkHsWrap wrap (HsVar id), substTy subst tau) }
 +       ; return (mkHsWrap wrap (HsVar id), TcType.substTy subst tau) }
    where
      (tvs, theta, tau) = tcSplitSigmaTy (idType id)
  \end{code}
@@@ -1134,7 -1136,7 +1136,7 @@@ tcTagToEnum loc fun_name arg res_t
          ; let fun' = L loc (HsWrap (WpTyApp rep_ty) (HsVar fun))
                rep_ty = mkTyConApp rep_tc rep_args
  
 -      ; return (mkHsWrapCoI coi $ HsApp fun' arg') }
 +      ; return (mkHsWrapCo coi $ HsApp fun' arg') }
    where
      doc1 = vcat [ ptext (sLit "Specify the type by giving a type signature")
                , ptext (sLit "e.g. (tagToEnum# x) :: Bool") ]
      doc3 = ptext (sLit "No family instance for this type")
  
      get_rep_ty :: TcType -> TyCon -> [TcType]
 -               -> TcM (CoercionI, TyCon, [TcType])
 +               -> TcM (Coercion, TyCon, [TcType])
        -- Converts a family type (eg F [a]) to its rep type (eg FList a)
        -- and returns a coercion between the two
      get_rep_ty ty tc tc_args
        | not (isFamilyTyCon tc) 
 -      = return (IdCo ty, tc, tc_args)
 +      = return (mkReflCo ty, tc, tc_args)
        | otherwise 
        = do { mb_fam <- tcLookupFamInst tc tc_args
             ; case mb_fam of 
               Nothing -> failWithTc (tagToEnumError ty doc3)
                 Just (rep_tc, rep_args) 
 -                   -> return ( ACo (mkSymCoercion (mkTyConApp co_tc rep_args))
 +                   -> return ( mkSymCo (mkAxInstCo co_tc rep_args)
                               , rep_tc, rep_args )
                   where
                     co_tc = expectJust "tcTagToEnum" $
@@@ -1386,9 -1388,23 +1388,23 @@@ funAppCtxt fun arg arg_n
                    quotes (ppr fun) <> text ", namely"])
         2 (quotes (ppr arg))
  
- funResCtxt :: LHsExpr Name -> SDoc
- funResCtxt fun
-   = ptext (sLit "In the return type of a call of") <+> quotes (ppr fun)
+ funResCtxt :: LHsExpr Name -> TcType -> TcType 
+            -> TidyEnv -> TcM (TidyEnv, Message)
+ -- When we have a mis-match in the return type of a function
+ -- try to give a helpful message about too many/few arguments
+ funResCtxt fun fun_res_ty res_ty env0
+   = do { fun_res' <- zonkTcType fun_res_ty
+        ; res'     <- zonkTcType res_ty
+        ; let n_fun = length (fst (tcSplitFunTys fun_res'))
+              n_res = length (fst (tcSplitFunTys res'))
+              what  | n_fun > n_res = ptext (sLit "few")
+                    | otherwise     = ptext (sLit "many")
+              extra | n_fun == n_res = empty
+                    | otherwise = ptext (sLit "Probable cause:") <+> quotes (ppr fun)
+                                  <+> ptext (sLit "is applied to too") <+> what 
+                                  <+> ptext (sLit "arguments") 
+              msg = ptext (sLit "In the return type of a call of") <+> quotes (ppr fun)
+        ; return (env0, msg $$ extra) }
  
  badFieldTypes :: [(Name,TcType)] -> SDoc
  badFieldTypes prs
@@@ -50,6 -50,7 +50,6 @@@ import TcTyp
  import TysPrim
  import TysWiredIn
  import Type
 -import Var( TyVar )
  import TypeRep
  import VarSet
  import State
@@@ -778,7 -779,7 +778,7 @@@ gen_Ix_binds loc tyco
      single_con_range
        = mk_easy_FunBind loc range_RDR 
          [nlTuplePat [con_pat as_needed, con_pat bs_needed] Boxed] $
-       nlHsDo ListComp stmts con_expr
+       noLoc (mkHsComp ListComp stmts con_expr)
        where
        stmts = zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed
  
@@@ -892,7 -893,7 +892,7 @@@ gen_Read_binds get_fixity loc tyco
      read_nullary_cons 
        = case nullary_cons of
            []    -> []
-           [con] -> [nlHsDo DoExpr (match_con con) (result_expr con [])]
+           [con] -> [nlHsDo DoExpr (match_con con ++ [noLoc $ mkLastStmt (result_expr con [])])]
              _     -> [nlHsApp (nlHsVar choose_RDR) 
                              (nlList (map mk_pair nullary_cons))]
          -- NB For operators the parens around (:=:) are matched by the
      ------------------------------------------------------------------------
      --                Helpers
      ------------------------------------------------------------------------
-     mk_alt e1 e2       = genOpApp e1 alt_RDR e2                                       -- e1 +++ e2
-     mk_parser p ss b   = nlHsApps prec_RDR [nlHsIntLit p, nlHsDo DoExpr ss b] -- prec p (do { ss ; b })
-     bindLex pat              = noLoc (mkBindStmt pat (nlHsVar lexP_RDR))              -- pat <- lexP
-     con_app con as     = nlHsVarApps (getRdrName con) as                      -- con as
-     result_expr con as = nlHsApp (nlHsVar returnM_RDR) (con_app con as)               -- return (con as)
+     mk_alt e1 e2       = genOpApp e1 alt_RDR e2                               -- e1 +++ e2
+     mk_parser p ss b   = nlHsApps prec_RDR [nlHsIntLit p              -- prec p (do { ss ; b })
+                                            , nlHsDo DoExpr (ss ++ [noLoc $ mkLastStmt b])]
+     bindLex pat              = noLoc (mkBindStmt pat (nlHsVar lexP_RDR))      -- pat <- lexP
+     con_app con as     = nlHsVarApps (getRdrName con) as              -- con as
+     result_expr con as = nlHsApp (nlHsVar returnM_RDR) (con_app con as) -- return (con as)
      
      punc_pat s   = nlConPat punc_RDR   [nlLitPat (mkHsString s)]  -- Punc 'c'
  
@@@ -1835,7 -1837,7 +1836,7 @@@ assoc_ty_id cls_str _ tbl t
                                              text "for primitive type" <+> ppr ty)
    | otherwise = head res
    where
 -    res = [id | (ty',id) <- tbl, ty `tcEqType` ty']
 +    res = [id | (ty',id) <- tbl, ty `eqType` ty']
  
  -----------------------------------------------------------------------
  
@@@ -35,7 -35,6 +35,7 @@@ import TcRnMona
  import PrelNames
  import TcType
  import TcMType
 +import Coercion
  import TysPrim
  import TysWiredIn
  import DataCon
@@@ -44,15 -43,14 +44,15 @@@ import NameSe
  import Var
  import VarSet
  import VarEnv
 +import DynFlags( DynFlag(..) )
  import Literal
  import BasicTypes
  import Maybes
  import SrcLoc
  import Bag
  import FastString
  import Outputable
 +import Data.Traversable( traverse )
  \end{code}
  
  \begin{code}
@@@ -580,11 -578,10 +580,10 @@@ zonkExpr env (HsLet binds expr
      zonkLExpr new_env expr    `thenM` \ new_expr ->
      returnM (HsLet new_binds new_expr)
  
- zonkExpr env (HsDo do_or_lc stmts body ty)
-   = zonkStmts env stmts       `thenM` \ (new_env, new_stmts) ->
-     zonkLExpr new_env body    `thenM` \ new_body ->
+ zonkExpr env (HsDo do_or_lc stmts ty)
+   = zonkStmts env stmts       `thenM` \ (_, new_stmts) ->
      zonkTcTypeToType env ty   `thenM` \ new_ty   ->
-     returnM (HsDo do_or_lc new_stmts new_body new_ty)
+     returnM (HsDo do_or_lc new_stmts new_ty)
  
  zonkExpr env (ExplicitList ty exprs)
    = zonkTcTypeToType env ty   `thenM` \ new_ty ->
@@@ -678,7 -675,7 +677,7 @@@ zonkCoFn env WpHole   = return (env, Wp
  zonkCoFn env (WpCompose c1 c2) = do { (env1, c1') <- zonkCoFn env c1
                                    ; (env2, c2') <- zonkCoFn env1 c2
                                    ; return (env2, WpCompose c1' c2') }
 -zonkCoFn env (WpCast co)    = do { co' <- zonkTcTypeToType env co
 +zonkCoFn env (WpCast co)    = do { co' <- zonkTcCoToCo env co
                                 ; return (env, WpCast co') }
  zonkCoFn env (WpEvLam ev)   = do { (env', ev') <- zonkEvBndrX env ev
                                 ; return (env', WpEvLam ev') }
@@@ -730,22 -727,26 +729,26 @@@ zonkStmts env (s:ss) = do { (env1, s'
                          ; return (env2, s' : ss') }
  
  zonkStmt :: ZonkEnv -> Stmt TcId -> TcM (ZonkEnv, Stmt Id)
- zonkStmt env (ParStmt stmts_w_bndrs)
+ zonkStmt env (ParStmt stmts_w_bndrs mzip_op bind_op return_op)
    = mappM zonk_branch stmts_w_bndrs   `thenM` \ new_stmts_w_bndrs ->
      let 
        new_binders = concat (map snd new_stmts_w_bndrs)
        env1 = extendZonkEnv env new_binders
      in
-     return (env1, ParStmt new_stmts_w_bndrs)
+     zonkExpr env1 mzip_op   `thenM` \ new_mzip ->
+     zonkExpr env1 bind_op   `thenM` \ new_bind ->
+     zonkExpr env1 return_op `thenM` \ new_return ->
+     return (env1, ParStmt new_stmts_w_bndrs new_mzip new_bind new_return)
    where
      zonk_branch (stmts, bndrs) = zonkStmts env stmts  `thenM` \ (env1, new_stmts) ->
                                 returnM (new_stmts, zonkIdOccs env1 bndrs)
  
  zonkStmt env (RecStmt { recS_stmts = segStmts, recS_later_ids = lvs, recS_rec_ids = rvs
                        , recS_ret_fn = ret_id, recS_mfix_fn = mfix_id, recS_bind_fn = bind_id
-                       , recS_rec_rets = rets })
+                       , recS_rec_rets = rets, recS_ret_ty = ret_ty })
    = do { new_rvs <- zonkIdBndrs env rvs
         ; new_lvs <- zonkIdBndrs env lvs
+        ; new_ret_ty  <- zonkTcTypeToType env ret_ty
         ; new_ret_id  <- zonkExpr env ret_id
         ; new_mfix_id <- zonkExpr env mfix_id
         ; new_bind_id <- zonkExpr env bind_id
                   RecStmt { recS_stmts = new_segStmts, recS_later_ids = new_lvs
                           , recS_rec_ids = new_rvs, recS_ret_fn = new_ret_id
                           , recS_mfix_fn = new_mfix_id, recS_bind_fn = new_bind_id
-                          , recS_rec_rets = new_rets }) }
+                          , recS_rec_rets = new_rets, recS_ret_ty = new_ret_ty }) }
  
- zonkStmt env (ExprStmt expr then_op ty)
+ zonkStmt env (ExprStmt expr then_op guard_op ty)
    = zonkLExpr env expr                `thenM` \ new_expr ->
      zonkExpr env then_op      `thenM` \ new_then ->
+     zonkExpr env guard_op     `thenM` \ new_guard ->
      zonkTcTypeToType env ty   `thenM` \ new_ty ->
-     returnM (env, ExprStmt new_expr new_then new_ty)
+     returnM (env, ExprStmt new_expr new_then new_guard new_ty)
  
- zonkStmt env (TransformStmt stmts binders usingExpr maybeByExpr)
-   = do { (env', stmts') <- zonkStmts env stmts 
-     ; let binders' = zonkIdOccs env' binders
-     ; usingExpr' <- zonkLExpr env' usingExpr
-     ; maybeByExpr' <- zonkMaybeLExpr env' maybeByExpr
-     ; return (env', TransformStmt stmts' binders' usingExpr' maybeByExpr') }
-     
- zonkStmt env (GroupStmt stmts binderMap by using)
+ zonkStmt env (LastStmt expr ret_op)
+   = zonkLExpr env expr                `thenM` \ new_expr ->
+     zonkExpr env ret_op               `thenM` \ new_ret ->
+     returnM (env, LastStmt new_expr new_ret)
+ zonkStmt env (TransStmt { trS_stmts = stmts, trS_bndrs = binderMap
+                         , trS_by = by, trS_form = form, trS_using = using
+                         , trS_ret = return_op, trS_bind = bind_op, trS_fmap = liftM_op })
    = do { (env', stmts') <- zonkStmts env stmts 
      ; binderMap' <- mappM (zonkBinderMapEntry env') binderMap
-     ; by' <- fmapMaybeM (zonkLExpr env') by
-     ; using' <- fmapEitherM (zonkLExpr env) (zonkExpr env) using
+     ; by'        <- fmapMaybeM (zonkLExpr env') by
+     ; using'     <- zonkLExpr env using
+     ; return_op' <- zonkExpr env' return_op
+     ; bind_op'   <- zonkExpr env' bind_op
+     ; liftM_op'  <- zonkExpr env' liftM_op
      ; let env'' = extendZonkEnv env' (map snd binderMap')
-     ; return (env'', GroupStmt stmts' binderMap' by' using') }
+     ; return (env'', TransStmt { trS_stmts = stmts', trS_bndrs = binderMap'
+                                , trS_by = by', trS_form = form, trS_using = using'
+                                , trS_ret = return_op', trS_bind = bind_op', trS_fmap = liftM_op' }) }
    where
      zonkBinderMapEntry env (oldBinder, newBinder) = do 
          let oldBinder' = zonkIdOcc env oldBinder
@@@ -797,11 -804,6 +806,6 @@@ zonkStmt env (BindStmt pat expr bind_o
        ; new_fail <- zonkExpr env fail_op
        ; return (env1, BindStmt new_pat new_expr new_bind new_fail) }
  
- zonkMaybeLExpr :: ZonkEnv -> Maybe (LHsExpr TcId) -> TcM (Maybe (LHsExpr Id))
- zonkMaybeLExpr _   Nothing  = return Nothing
- zonkMaybeLExpr env (Just e) = (zonkLExpr env e) >>= (return . Just)
  -------------------------------------------------------------------------
  zonkRecFields :: ZonkEnv -> HsRecordBinds TcId -> TcM (HsRecordBinds TcId)
  zonkRecFields env (HsRecFields flds dd)
@@@ -1006,6 -1008,7 +1010,6 @@@ zonkRule env (HsRule name act (vars{-::
  
     zonk_it env v
       | isId v     = do { v' <- zonkIdBndr env v; return (extendZonkEnv1 env v', v') }
 -     | isCoVar v  = do { v' <- zonkEvBndr env v; return (extendZonkEnv1 env v', v') }
       | otherwise  = ASSERT( isImmutableTyVar v) return (env, v)
  \end{code}
  
@@@ -1035,10 -1038,10 +1039,10 @@@ zonkVect env (HsVect v (Just e)
  zonkEvTerm :: ZonkEnv -> EvTerm -> TcM EvTerm
  zonkEvTerm env (EvId v)           = ASSERT2( isId v, ppr v ) 
                                      return (EvId (zonkIdOcc env v))
 -zonkEvTerm env (EvCoercion co)    = do { co' <- zonkTcTypeToType env co
 +zonkEvTerm env (EvCoercion co)    = do { co' <- zonkTcCoToCo env co
                                         ; return (EvCoercion co') }
  zonkEvTerm env (EvCast v co)      = ASSERT( isId v) 
 -                                    do { co' <- zonkTcTypeToType env co
 +                                    do { co' <- zonkTcCoToCo env co
                                         ; return (EvCast (zonkIdOcc env v) co') }
  zonkEvTerm env (EvSuperClass d n) = return (EvSuperClass (zonkIdOcc env d) n)
  zonkEvTerm env (EvDFunApp df tys tms)
@@@ -1113,28 -1116,4 +1117,28 @@@ zonkTypeZapping t
      zonk_unbound_tyvar tv = do { let ty = anyTypeOfKind (tyVarKind tv)
                               ; writeMetaTyVar tv ty
                               ; return ty }
 +
 +zonkTcCoToCo :: ZonkEnv -> Coercion -> TcM Coercion
 +zonkTcCoToCo env co
 +  = go co
 +  where
 +    go (CoVarCo cv)         = return (CoVarCo (zonkEvVarOcc env cv))
 +    go (Refl ty)            = do { ty' <- zonkTcTypeToType env ty
 +                                 ; return (Refl ty') }
 +    go (TyConAppCo tc cos)  = do { cos' <- mapM go cos; return (mkTyConAppCo tc cos') }
 +    go (AxiomInstCo ax cos) = do { cos' <- mapM go cos; return (AxiomInstCo ax cos') }
 +    go (AppCo co1 co2)      = do { co1' <- go co1; co2' <- go co2
 +                                 ; return (mkAppCo co1' co2') }
 +    go (PredCo pco)         = do { pco' <- go `traverse` pco; return (mkPredCo pco') }
 +    go (UnsafeCo t1 t2)     = do { t1' <- zonkTcTypeToType env t1
 +                                 ; t2' <- zonkTcTypeToType env t2
 +                                 ; return (mkUnsafeCo t1' t2') }
 +    go (SymCo co)           = do { co' <- go co; return (mkSymCo co')  }
 +    go (NthCo n co)         = do { co' <- go co; return (mkNthCo n co')  }
 +    go (TransCo co1 co2)    = do { co1' <- go co1; co2' <- go co2
 +                                 ; return (mkTransCo co1' co2')  }
 +    go (InstCo co ty)       = do { co' <- go co; ty' <- zonkTcTypeToType env ty
 +                                 ; return (mkInstCo co' ty')  }
 +    go (ForAllCo tv co)     = ASSERT( isImmutableTyVar tv )
 +                              do { co' <- go co; return (mkForAllCo tv co') }
- \end{code}
+ \end{code}
@@@ -6,16 -6,18 +6,18 @@@
  TcMatches: Typecheck some @Matches@
  
  \begin{code}
+ {-# OPTIONS_GHC -w #-}   -- debugging
  module TcMatches ( tcMatchesFun, tcGRHSsPat, tcMatchesCase, tcMatchLambda,
-                  TcMatchCtxt(..), 
-                  tcStmts, tcDoStmts, tcBody,
-                  tcDoStmt, tcMDoStmt, tcGuardStmt
+                  TcMatchCtxt(..), TcStmtChecker,
+                  tcStmts, tcStmtsAndThen, tcDoStmts, tcBody,
+                  tcDoStmt, tcGuardStmt
         ) where
  
- import {-# SOURCE #-} TcExpr( tcSyntaxOp, tcInferRhoNC, tcCheckId,
+ import {-# SOURCE #-} TcExpr( tcSyntaxOp, tcInferRhoNC, tcInferRho, tcCheckId,
                                  tcMonoExpr, tcMonoExprNC, tcPolyExpr )
  
  import HsSyn
+ import BasicTypes
  import TcRnMonad
  import TcEnv
  import TcPat
@@@ -28,13 -30,15 +30,15 @@@ import TysWiredI
  import Id
  import TyCon
  import TysPrim
- import Coercion         ( mkSymCo )
 -import Coercion               ( isIdentityCoI, mkSymCoI )
++import Coercion         ( isReflCo, mkSymCo )
  import Outputable
- import BasicTypes     ( Arity )
  import Util
  import SrcLoc
  import FastString
  
+ -- Create chunkified tuple tybes for monad comprehensions
+ import MkCore
  import Control.Monad
  
  #include "HsVersions.h"
@@@ -143,7 -147,7 +147,7 @@@ matchFunTy
  matchFunTys herald arity res_ty thing_inside
    = do        { (coi, pat_tys, res_ty) <- matchExpectedFunTys herald arity res_ty
        ; res <- thing_inside pat_tys res_ty
 -        ; return (coiToHsWrapper (mkSymCoI coi), res) }
 +        ; return (coToHsWrapper (mkSymCo coi), res) }
  \end{code}
  
  %************************************************************************
@@@ -221,7 -225,7 +225,7 @@@ tcGRHSs ctxt (GRHSs grhss binds) res_t
  tcGRHS :: TcMatchCtxt -> TcRhoType -> GRHS Name -> TcM (GRHS TcId)
  
  tcGRHS ctxt res_ty (GRHS guards rhs)
-   = do  { (guards', rhs') <- tcStmts stmt_ctxt tcGuardStmt guards res_ty $
+   = do  { (guards', rhs') <- tcStmtsAndThen stmt_ctxt tcGuardStmt guards res_ty $
                             mc_body ctxt rhs
        ; return (GRHS guards' rhs') }
    where
  \begin{code}
  tcDoStmts :: HsStmtContext Name 
          -> [LStmt Name]
-         -> LHsExpr Name
          -> TcRhoType
          -> TcM (HsExpr TcId)          -- Returns a HsDo
- tcDoStmts ListComp stmts body res_ty
+ tcDoStmts ListComp stmts res_ty
    = do        { (coi, elt_ty) <- matchExpectedListTy res_ty
-       ; (stmts', body') <- tcStmts ListComp (tcLcStmt listTyCon) stmts 
-                                    elt_ty $
-                            tcBody body
-       ; return $ mkHsWrapCo coi 
-                      (HsDo ListComp stmts' body' (mkListTy elt_ty)) }
+         ; let list_ty = mkListTy elt_ty
+       ; stmts' <- tcStmts ListComp (tcLcStmt listTyCon) stmts elt_ty
 -      ; return $ mkHsWrapCoI coi (HsDo ListComp stmts' list_ty) }
++      ; return $ mkHsWrapCo coi (HsDo ListComp stmts' list_ty) }
  
- tcDoStmts PArrComp stmts body res_ty
+ tcDoStmts PArrComp stmts res_ty
    = do        { (coi, elt_ty) <- matchExpectedPArrTy res_ty
-       ; (stmts', body') <- tcStmts PArrComp (tcLcStmt parrTyCon) stmts 
-                                    elt_ty $
-                            tcBody body
-       ; return $ mkHsWrapCo coi 
-                      (HsDo PArrComp stmts' body' (mkPArrTy elt_ty)) }
+         ; let parr_ty = mkPArrTy elt_ty
+       ; stmts' <- tcStmts PArrComp (tcLcStmt parrTyCon) stmts elt_ty
 -      ; return $ mkHsWrapCoI coi (HsDo PArrComp stmts' parr_ty) }
++      ; return $ mkHsWrapCo coi (HsDo PArrComp stmts' parr_ty) }
+ tcDoStmts DoExpr stmts res_ty
+   = do        { stmts' <- tcStmts DoExpr tcDoStmt stmts res_ty
+       ; return (HsDo DoExpr stmts' res_ty) }
  
- tcDoStmts DoExpr stmts body res_ty
-   = do        { (stmts', body') <- tcStmts DoExpr tcDoStmt stmts res_ty $
-                            tcBody body
-       ; return (HsDo DoExpr stmts' body' res_ty) }
+ tcDoStmts MDoExpr stmts res_ty
+   = do  { stmts' <- tcStmts MDoExpr tcDoStmt stmts res_ty
+         ; return (HsDo MDoExpr stmts' res_ty) }
  
- tcDoStmts MDoExpr stmts body res_ty
-   = do  { (stmts', body') <- tcStmts MDoExpr tcDoStmt stmts res_ty $
-                            tcBody body
-         ; return (HsDo MDoExpr stmts' body' res_ty) }
+ tcDoStmts MonadComp stmts res_ty
+   = do  { stmts' <- tcStmts MonadComp tcMcStmt stmts res_ty 
+         ; return (HsDo MonadComp stmts' res_ty) }
  
- tcDoStmts ctxt _ _ _ = pprPanic "tcDoStmts" (pprStmtContext ctxt)
+ tcDoStmts ctxt _ _ = pprPanic "tcDoStmts" (pprStmtContext ctxt)
  
  tcBody :: LHsExpr Name -> TcRhoType -> TcM (LHsExpr TcId)
  tcBody body res_ty
@@@ -296,40 -297,52 +297,52 @@@ tcStmts :: HsStmtContext Nam
        -> TcStmtChecker        -- NB: higher-rank type
          -> [LStmt Name]
        -> TcRhoType
-       -> (TcRhoType -> TcM thing)
-         -> TcM ([LStmt TcId], thing)
+         -> TcM [LStmt TcId]
+ tcStmts ctxt stmt_chk stmts res_ty
+   = do { (stmts', _) <- tcStmtsAndThen ctxt stmt_chk stmts res_ty $
+                         const (return ())
+        ; return stmts' }
+ tcStmtsAndThen :: HsStmtContext Name
+              -> TcStmtChecker -- NB: higher-rank type
+                -> [LStmt Name]
+              -> TcRhoType
+              -> (TcRhoType -> TcM thing)
+                -> TcM ([LStmt TcId], thing)
  
  -- Note the higher-rank type.  stmt_chk is applied at different
  -- types in the equations for tcStmts
  
- tcStmts _ _ [] res_ty thing_inside
+ tcStmtsAndThen _ _ [] res_ty thing_inside
    = do        { thing <- thing_inside res_ty
        ; return ([], thing) }
  
  -- LetStmts are handled uniformly, regardless of context
- tcStmts ctxt stmt_chk (L loc (LetStmt binds) : stmts) res_ty thing_inside
+ tcStmtsAndThen ctxt stmt_chk (L loc (LetStmt binds) : stmts) res_ty thing_inside
    = do        { (binds', (stmts',thing)) <- tcLocalBinds binds $
-                                     tcStmts ctxt stmt_chk stmts res_ty thing_inside
+                                     tcStmtsAndThen ctxt stmt_chk stmts res_ty thing_inside
        ; return (L loc (LetStmt binds') : stmts', thing) }
  
  -- For the vanilla case, handle the location-setting part
- tcStmts ctxt stmt_chk (L loc stmt : stmts) res_ty thing_inside
+ tcStmtsAndThen ctxt stmt_chk (L loc stmt : stmts) res_ty thing_inside
    = do        { (stmt', (stmts', thing)) <- 
-               setSrcSpan loc                          $
-               addErrCtxt (pprStmtInCtxt ctxt stmt)    $
-               stmt_chk ctxt stmt res_ty               $ \ res_ty' ->
-               popErrCtxt                              $
-               tcStmts ctxt stmt_chk stmts res_ty'     $
+               setSrcSpan loc                              $
+               addErrCtxt (pprStmtInCtxt ctxt stmt)        $
+               stmt_chk ctxt stmt res_ty                   $ \ res_ty' ->
+               popErrCtxt                                  $
+               tcStmtsAndThen ctxt stmt_chk stmts res_ty'  $
                thing_inside
        ; return (L loc stmt' : stmts', thing) }
  
- --------------------------------
- --    Pattern guards
+ ---------------------------------------------------
+ --            Pattern guards
+ ---------------------------------------------------
  tcGuardStmt :: TcStmtChecker
- tcGuardStmt _ (ExprStmt guard _ _) res_ty thing_inside
+ tcGuardStmt _ (ExprStmt guard _ _ _) res_ty thing_inside
    = do        { guard' <- tcMonoExpr guard boolTy
        ; thing  <- thing_inside res_ty
-       ; return (ExprStmt guard' noSyntaxExpr boolTy, thing) }
+       ; return (ExprStmt guard' noSyntaxExpr noSyntaxExpr boolTy, thing) }
  
  tcGuardStmt ctxt (BindStmt pat rhs _ _) res_ty thing_inside
    = do        { (rhs', rhs_ty) <- tcInferRhoNC rhs    -- Stmt has a context already
@@@ -341,25 -354,292 +354,292 @@@ tcGuardStmt _ stmt _ 
    = pprPanic "tcGuardStmt: unexpected Stmt" (ppr stmt)
  
  
- --------------------------------
- --    List comprehensions and PArrays
+ ---------------------------------------------------
+ --         List comprehensions and PArrays
+ --             (no rebindable syntax)
+ ---------------------------------------------------
+ -- Dealt with separately, rather than by tcMcStmt, because
+ --   a) PArr isn't (yet) an instance of Monad, so the generality seems overkill
+ --   b) We have special desugaring rules for list comprehensions,
+ --      which avoid creating intermediate lists.  They in turn 
+ --      assume that the bind/return operations are the regular
+ --      polymorphic ones, and in particular don't have any
+ --      coercion matching stuff in them.  It's hard to avoid the
+ --      potential for non-trivial coercions in tcMcStmt
  
  tcLcStmt :: TyCon     -- The list/Parray type constructor ([] or PArray)
         -> TcStmtChecker
  
+ tcLcStmt _ _ (LastStmt body _) elt_ty thing_inside
+   = do { body' <- tcMonoExprNC body elt_ty
+        ; thing <- thing_inside (panic "tcLcStmt: thing_inside")
+        ; return (LastStmt body' noSyntaxExpr, thing) }
  -- A generator, pat <- rhs
- tcLcStmt m_tc ctxt (BindStmt pat rhs _ _) res_ty thing_inside
+ tcLcStmt m_tc ctxt (BindStmt pat rhs _ _) elt_ty thing_inside
   = do { pat_ty <- newFlexiTyVarTy liftedTypeKind
          ; rhs'   <- tcMonoExpr rhs (mkTyConApp m_tc [pat_ty])
        ; (pat', thing)  <- tcPat (StmtCtxt ctxt) pat pat_ty $
-                             thing_inside res_ty
+                             thing_inside elt_ty
        ; return (BindStmt pat' rhs' noSyntaxExpr noSyntaxExpr, thing) }
  
  -- A boolean guard
- tcLcStmt _ _ (ExprStmt rhs _ _) res_ty thing_inside
+ tcLcStmt _ _ (ExprStmt rhs _ _ _) elt_ty thing_inside
    = do        { rhs'  <- tcMonoExpr rhs boolTy
-       ; thing <- thing_inside res_ty
-       ; return (ExprStmt rhs' noSyntaxExpr boolTy, thing) }
+       ; thing <- thing_inside elt_ty
+       ; return (ExprStmt rhs' noSyntaxExpr noSyntaxExpr boolTy, thing) }
+ -- ParStmt: See notes with tcMcStmt
+ tcLcStmt m_tc ctxt (ParStmt bndr_stmts_s _ _ _) elt_ty thing_inside
+   = do        { (pairs', thing) <- loop bndr_stmts_s
+       ; return (ParStmt pairs' noSyntaxExpr noSyntaxExpr noSyntaxExpr, thing) }
+   where
+     -- loop :: [([LStmt Name], [Name])] -> TcM ([([LStmt TcId], [TcId])], thing)
+     loop [] = do { thing <- thing_inside elt_ty
+                ; return ([], thing) }         -- matching in the branches
+     loop ((stmts, names) : pairs)
+       = do { (stmts', (ids, pairs', thing))
+               <- tcStmtsAndThen ctxt (tcLcStmt m_tc) stmts elt_ty $ \ _elt_ty' ->
+                  do { ids <- tcLookupLocalIds names
+                     ; (pairs', thing) <- loop pairs
+                     ; return (ids, pairs', thing) }
+          ; return ( (stmts', ids) : pairs', thing ) }
+ tcLcStmt m_tc ctxt (TransStmt { trS_form = form, trS_stmts = stmts
+                               , trS_bndrs =  bindersMap
+                               , trS_by = by, trS_using = using }) elt_ty thing_inside
+   = do { let (bndr_names, n_bndr_names) = unzip bindersMap
+              unused_ty = pprPanic "tcLcStmt: inner ty" (ppr bindersMap)
+                    -- The inner 'stmts' lack a LastStmt, so the element type
+            --  passed in to tcStmtsAndThen is never looked at
+        ; (stmts', (bndr_ids, by'))
+             <- tcStmtsAndThen (TransStmtCtxt ctxt) (tcLcStmt m_tc) stmts unused_ty $ \_ -> do
+              { by' <- case by of
+                            Nothing -> return Nothing
+                            Just e  -> do { e_ty <- tcInferRho e; return (Just e_ty) }
+                ; bndr_ids <- tcLookupLocalIds bndr_names
+                ; return (bndr_ids, by') }
+        ; let m_app ty = mkTyConApp m_tc [ty]
+        --------------- Typecheck the 'using' function -------------
+        -- using :: ((a,b,c)->t) -> m (a,b,c) -> m (a,b,c)m      (ThenForm)
+        --       :: ((a,b,c)->t) -> m (a,b,c) -> m (m (a,b,c)))  (GroupForm)
+          -- n_app :: Type -> Type   -- Wraps a 'ty' into '[ty]' for GroupForm
+        ; let n_app = case form of
+                        ThenForm -> (\ty -> ty)
+                      _        -> m_app
+              by_arrow :: Type -> Type     -- Wraps 'ty' to '(a->t) -> ty' if the By is present
+              by_arrow = case by' of
+                           Nothing       -> \ty -> ty
+                           Just (_,e_ty) -> \ty -> (alphaTy `mkFunTy` e_ty) `mkFunTy` ty
+              tup_ty        = mkBigCoreVarTupTy bndr_ids
+              poly_arg_ty   = m_app alphaTy
+            poly_res_ty   = m_app (n_app alphaTy)
+            using_poly_ty = mkForAllTy alphaTyVar $ by_arrow $ 
+                              poly_arg_ty `mkFunTy` poly_res_ty
+        ; using' <- tcPolyExpr using using_poly_ty
+        ; let final_using = fmap (HsWrap (WpTyApp tup_ty)) using' 
+            -- 'stmts' returns a result of type (m1_ty tuple_ty),
+            -- typically something like [(Int,Bool,Int)]
+            -- We don't know what tuple_ty is yet, so we use a variable
+        ; let mk_n_bndr :: Name -> TcId -> TcId
+              mk_n_bndr n_bndr_name bndr_id = mkLocalId n_bndr_name (n_app (idType bndr_id))
+              -- Ensure that every old binder of type `b` is linked up with its
+              -- new binder which should have type `n b`
+            -- See Note [GroupStmt binder map] in HsExpr
+              n_bndr_ids  = zipWith mk_n_bndr n_bndr_names bndr_ids
+              bindersMap' = bndr_ids `zip` n_bndr_ids
+        -- Type check the thing in the environment with 
+        -- these new binders and return the result
+        ; thing <- tcExtendIdEnv n_bndr_ids (thing_inside elt_ty)
+        ; return (emptyTransStmt { trS_stmts = stmts', trS_bndrs = bindersMap' 
+                                 , trS_by = fmap fst by', trS_using = final_using 
+                                 , trS_form = form }, thing) }
+     
+ tcLcStmt _ _ stmt _ _
+   = pprPanic "tcLcStmt: unexpected Stmt" (ppr stmt)
+ ---------------------------------------------------
+ --         Monad comprehensions 
+ --      (supports rebindable syntax)
+ ---------------------------------------------------
+ tcMcStmt :: TcStmtChecker
+ tcMcStmt _ (LastStmt body return_op) res_ty thing_inside
+   = do  { a_ty       <- newFlexiTyVarTy liftedTypeKind
+         ; return_op' <- tcSyntaxOp MCompOrigin return_op
+                                    (a_ty `mkFunTy` res_ty)
+         ; body'      <- tcMonoExprNC body a_ty
+         ; thing      <- thing_inside (panic "tcMcStmt: thing_inside")
+         ; return (LastStmt body' return_op', thing) } 
+ -- Generators for monad comprehensions ( pat <- rhs )
+ --
+ --   [ body | q <- gen ]  ->  gen :: m a
+ --                            q   ::   a
+ --
+ tcMcStmt ctxt (BindStmt pat rhs bind_op fail_op) res_ty thing_inside
+  = do   { rhs_ty     <- newFlexiTyVarTy liftedTypeKind
+         ; pat_ty     <- newFlexiTyVarTy liftedTypeKind
+         ; new_res_ty <- newFlexiTyVarTy liftedTypeKind
+          -- (>>=) :: rhs_ty -> (pat_ty -> new_res_ty) -> res_ty
+         ; bind_op'   <- tcSyntaxOp MCompOrigin bind_op 
+                              (mkFunTys [rhs_ty, mkFunTy pat_ty new_res_ty] res_ty)
+            -- If (but only if) the pattern can fail, typecheck the 'fail' operator
+         ; fail_op' <- if isIrrefutableHsPat pat 
+                       then return noSyntaxExpr
+                       else tcSyntaxOp MCompOrigin fail_op (mkFunTy stringTy new_res_ty)
+         ; rhs' <- tcMonoExprNC rhs rhs_ty
+         ; (pat', thing) <- tcPat (StmtCtxt ctxt) pat pat_ty $
+                            thing_inside new_res_ty
+         ; return (BindStmt pat' rhs' bind_op' fail_op', thing) }
+ -- Boolean expressions.
+ --
+ --   [ body | stmts, expr ]  ->  expr :: m Bool
+ --
+ tcMcStmt _ (ExprStmt rhs then_op guard_op _) res_ty thing_inside
+   = do        { -- Deal with rebindable syntax:
+           --    guard_op :: test_ty -> rhs_ty
+           --    then_op  :: rhs_ty -> new_res_ty -> res_ty
+           -- Where test_ty is, for example, Bool
+           test_ty    <- newFlexiTyVarTy liftedTypeKind
+         ; rhs_ty     <- newFlexiTyVarTy liftedTypeKind
+         ; new_res_ty <- newFlexiTyVarTy liftedTypeKind
+         ; rhs'       <- tcMonoExpr rhs test_ty
+         ; guard_op'  <- tcSyntaxOp MCompOrigin guard_op
+                                    (mkFunTy test_ty rhs_ty)
+         ; then_op'   <- tcSyntaxOp MCompOrigin then_op
+                                  (mkFunTys [rhs_ty, new_res_ty] res_ty)
+       ; thing      <- thing_inside new_res_ty
+       ; return (ExprStmt rhs' then_op' guard_op' rhs_ty, thing) }
+ -- Grouping statements
+ --
+ --   [ body | stmts, then group by e ]
+ --     ->  e :: t
+ --   [ body | stmts, then group by e using f ]
+ --     ->  e :: t
+ --         f :: forall a. (a -> t) -> m a -> m (m a)
+ --   [ body | stmts, then group using f ]
+ --     ->  f :: forall a. m a -> m (m a)
+ -- We type [ body | (stmts, group by e using f), ... ]
+ --     f <optional by> [ (a,b,c) | stmts ] >>= \(a,b,c) -> ...body....
+ --
+ -- We type the functions as follows:
+ --     f <optional by> :: m1 (a,b,c) -> m2 (a,b,c)            (ThenForm)
+ --                           :: m1 (a,b,c) -> m2 (n (a,b,c))          (GroupForm)
+ --     (>>=) :: m2 (a,b,c)     -> ((a,b,c)   -> res) -> res   (ThenForm)
+ --           :: m2 (n (a,b,c)) -> (n (a,b,c) -> res) -> res   (GroupForm)
+ -- 
+ tcMcStmt ctxt (TransStmt { trS_stmts = stmts, trS_bndrs = bindersMap
+                          , trS_by = by, trS_using = using, trS_form = form
+                          , trS_ret = return_op, trS_bind = bind_op 
+                          , trS_fmap = fmap_op }) res_ty thing_inside
+   = do { let star_star_kind = liftedTypeKind `mkArrowKind` liftedTypeKind
+        ; m1_ty   <- newFlexiTyVarTy star_star_kind
+        ; m2_ty   <- newFlexiTyVarTy star_star_kind
+        ; tup_ty  <- newFlexiTyVarTy liftedTypeKind
+        ; by_e_ty <- newFlexiTyVarTy liftedTypeKind  -- The type of the 'by' expression (if any)
+          -- n_app :: Type -> Type   -- Wraps a 'ty' into '(n ty)' for GroupForm
+        ; n_app <- case form of
+                     ThenForm -> return (\ty -> ty)
+                   _        -> do { n_ty <- newFlexiTyVarTy star_star_kind
+                                          ; return (n_ty `mkAppTy`) }
+        ; let by_arrow :: Type -> Type     
+              -- (by_arrow res) produces ((alpha->e_ty) -> res)     ('by' present)
+              --                          or res                    ('by' absent) 
+              by_arrow = case by of
+                           Nothing -> \res -> res
+                           Just {} -> \res -> (alphaTy `mkFunTy` by_e_ty) `mkFunTy` res
+              poly_arg_ty  = m1_ty `mkAppTy` alphaTy
+              using_arg_ty = m1_ty `mkAppTy` tup_ty
+            poly_res_ty  = m2_ty `mkAppTy` n_app alphaTy
+            using_res_ty = m2_ty `mkAppTy` n_app tup_ty
+            using_poly_ty = mkForAllTy alphaTyVar $ by_arrow $ 
+                              poly_arg_ty `mkFunTy` poly_res_ty
+            -- 'stmts' returns a result of type (m1_ty tuple_ty),
+            -- typically something like [(Int,Bool,Int)]
+            -- We don't know what tuple_ty is yet, so we use a variable
+        ; let (bndr_names, n_bndr_names) = unzip bindersMap
+        ; (stmts', (bndr_ids, by', return_op')) <-
+             tcStmtsAndThen (TransStmtCtxt ctxt) tcMcStmt stmts using_arg_ty $ \res_ty' -> do
+               { by' <- case by of
+                            Nothing -> return Nothing
+                            Just e  -> do { e' <- tcMonoExpr e by_e_ty; return (Just e') }
+                 -- Find the Ids (and hence types) of all old binders
+                 ; bndr_ids <- tcLookupLocalIds bndr_names
+                 -- 'return' is only used for the binders, so we know its type.
+                 --   return :: (a,b,c,..) -> m (a,b,c,..)
+                 ; return_op' <- tcSyntaxOp MCompOrigin return_op $ 
+                                 (mkBigCoreVarTupTy bndr_ids) `mkFunTy` res_ty'
+                 ; return (bndr_ids, by', return_op') }
+        --------------- Typecheck the 'bind' function -------------
+        -- (>>=) :: m2 (n (a,b,c)) -> ( n (a,b,c) -> new_res_ty ) -> res_ty
+        ; new_res_ty <- newFlexiTyVarTy liftedTypeKind
+        ; bind_op' <- tcSyntaxOp MCompOrigin bind_op $
+                                 using_res_ty `mkFunTy` (n_app tup_ty `mkFunTy` new_res_ty)
+                                              `mkFunTy` res_ty
+        --------------- Typecheck the 'fmap' function -------------
+        ; fmap_op' <- case form of
+                        ThenForm -> return noSyntaxExpr
+                        _ -> fmap unLoc . tcPolyExpr (noLoc fmap_op) $
+                             mkForAllTy alphaTyVar $ mkForAllTy betaTyVar $
+                             (alphaTy `mkFunTy` betaTy)
+                             `mkFunTy` (n_app alphaTy)
+                             `mkFunTy` (n_app betaTy)
+        --------------- Typecheck the 'using' function -------------
+        -- using :: ((a,b,c)->t) -> m1 (a,b,c) -> m2 (n (a,b,c))
+        ; using' <- tcPolyExpr using using_poly_ty
+        ; let final_using = fmap (HsWrap (WpTyApp tup_ty)) using' 
+        --------------- Bulding the bindersMap ----------------
+        ; let mk_n_bndr :: Name -> TcId -> TcId
+              mk_n_bndr n_bndr_name bndr_id = mkLocalId n_bndr_name (n_app (idType bndr_id))
+              -- Ensure that every old binder of type `b` is linked up with its
+              -- new binder which should have type `n b`
+            -- See Note [GroupStmt binder map] in HsExpr
+              n_bndr_ids = zipWith mk_n_bndr n_bndr_names bndr_ids
+              bindersMap' = bndr_ids `zip` n_bndr_ids
+        -- Type check the thing in the environment with 
+        -- these new binders and return the result
+        ; thing <- tcExtendIdEnv n_bndr_ids (thing_inside new_res_ty)
+        ; return (TransStmt { trS_stmts = stmts', trS_bndrs = bindersMap' 
+                            , trS_by = by', trS_using = final_using 
+                            , trS_ret = return_op', trS_bind = bind_op'
+                            , trS_fmap = fmap_op', trS_form = form }, thing) }
  
  -- A parallel set of comprehensions
  --    [ (g x, h x) | ... ; let g v = ...
  -- ensure that g,h and x,y don't duplicate, and simply grow the environment.
  -- So the binders of the first parallel group will be in scope in the second
  -- group.  But that's fine; there's no shadowing to worry about.
- tcLcStmt m_tc ctxt (ParStmt bndr_stmts_s) elt_ty thing_inside
-   = do        { (pairs', thing) <- loop bndr_stmts_s
-       ; return (ParStmt pairs', thing) }
-   where
-     -- loop :: [([LStmt Name], [Name])] -> TcM ([([LStmt TcId], [TcId])], thing)
-     loop [] = do { thing <- thing_inside elt_ty
-                ; return ([], thing) }         -- matching in the branches
-     loop ((stmts, names) : pairs)
-       = do { (stmts', (ids, pairs', thing))
-               <- tcStmts ctxt (tcLcStmt m_tc) stmts elt_ty $ \ _elt_ty' ->
-                  do { ids <- tcLookupLocalIds names
-                     ; (pairs', thing) <- loop pairs
-                     ; return (ids, pairs', thing) }
-          ; return ( (stmts', ids) : pairs', thing ) }
- tcLcStmt m_tc ctxt (TransformStmt stmts binders usingExpr maybeByExpr) elt_ty thing_inside = do
-     (stmts', (binders', usingExpr', maybeByExpr', thing)) <- 
-         tcStmts (TransformStmtCtxt ctxt) (tcLcStmt m_tc) stmts elt_ty $ \elt_ty' -> do
-             let alphaListTy = mkTyConApp m_tc [alphaTy]
-                     
-             (usingExpr', maybeByExpr') <- 
-                 case maybeByExpr of
-                     Nothing -> do
-                         -- We must validate that usingExpr :: forall a. [a] -> [a]
-                         let using_ty = mkForAllTy alphaTyVar (alphaListTy `mkFunTy` alphaListTy)
-                         usingExpr' <- tcPolyExpr usingExpr using_ty
-                         return (usingExpr', Nothing)
-                     Just byExpr -> do
-                         -- We must infer a type such that e :: t and then check that 
-                       -- usingExpr :: forall a. (a -> t) -> [a] -> [a]
-                         (byExpr', tTy) <- tcInferRhoNC byExpr
-                         let using_ty = mkForAllTy alphaTyVar $ 
-                                        (alphaTy `mkFunTy` tTy)
-                                        `mkFunTy` alphaListTy `mkFunTy` alphaListTy
-                         usingExpr' <- tcPolyExpr usingExpr using_ty
-                         return (usingExpr', Just byExpr')
-             
-             binders' <- tcLookupLocalIds binders
-             thing <- thing_inside elt_ty'
-             
-             return (binders', usingExpr', maybeByExpr', thing)
-     return (TransformStmt stmts' binders' usingExpr' maybeByExpr', thing)
- tcLcStmt m_tc ctxt (GroupStmt stmts bindersMap by using) elt_ty thing_inside
-   = do { let (bndr_names, list_bndr_names) = unzip bindersMap
-        ; (stmts', (bndr_ids, by', using_ty, elt_ty')) <-
-             tcStmts (TransformStmtCtxt ctxt) (tcLcStmt m_tc) stmts elt_ty $ \elt_ty' -> do
-               (by', using_ty) <- 
-                    case by of
-                      Nothing   -> -- check that using :: forall a. [a] -> [[a]]
-                                   return (Nothing, mkForAllTy alphaTyVar $
-                                                    alphaListTy `mkFunTy` alphaListListTy)
-                                       
-                    Just by_e -> -- check that using :: forall a. (a -> t) -> [a] -> [[a]]
-                                 -- where by :: t
-                                   do { (by_e', t_ty) <- tcInferRhoNC by_e
-                                      ; return (Just by_e', mkForAllTy alphaTyVar $
-                                                            (alphaTy `mkFunTy` t_ty) 
-                                                            `mkFunTy` alphaListTy 
-                                                            `mkFunTy` alphaListListTy) }
-                 -- Find the Ids (and hence types) of all old binders
-                 bndr_ids <- tcLookupLocalIds bndr_names
-                 
-                 return (bndr_ids, by', using_ty, elt_ty')
-         
-                 -- Ensure that every old binder of type b is linked up with
-               -- its new binder which should have type [b]
-        ; let list_bndr_ids = zipWith mk_list_bndr list_bndr_names bndr_ids
-              bindersMap' = bndr_ids `zip` list_bndr_ids
-            -- See Note [GroupStmt binder map] in HsExpr
-             
-        ; using' <- case using of
-                      Left  e -> do { e' <- tcPolyExpr e         using_ty; return (Left  e') }
-                      Right e -> do { e' <- tcPolyExpr (noLoc e) using_ty; return (Right (unLoc e')) }
-              -- Type check the thing in the environment with 
-            -- these new binders and return the result
-        ; thing <- tcExtendIdEnv list_bndr_ids (thing_inside elt_ty')
-        ; return (GroupStmt stmts' bindersMap' by' using', thing) }
-   where
-     alphaListTy = mkTyConApp m_tc [alphaTy]
-     alphaListListTy = mkTyConApp m_tc [alphaListTy]
-             
-     mk_list_bndr :: Name -> TcId -> TcId
-     mk_list_bndr list_bndr_name bndr_id 
-       = mkLocalId list_bndr_name (mkTyConApp m_tc [idType bndr_id])
-     
- tcLcStmt _ _ stmt _ _
-   = pprPanic "tcLcStmt: unexpected Stmt" (ppr stmt)
-         
- --------------------------------
- --    Do-notation
- -- The main excitement here is dealing with rebindable syntax
+ --
+ -- Note: The `mzip` function will get typechecked via:
+ --
+ --   ParStmt [st1::t1, st2::t2, st3::t3]
+ --   
+ --   mzip :: m st1
+ --        -> (m st2 -> m st3 -> m (st2, st3))   -- recursive call
+ --        -> m (st1, (st2, st3))
+ --
+ tcMcStmt ctxt (ParStmt bndr_stmts_s mzip_op bind_op return_op) res_ty thing_inside
+   = do { let star_star_kind = liftedTypeKind `mkArrowKind` liftedTypeKind
+        ; m_ty   <- newFlexiTyVarTy star_star_kind
+        ; let mzip_ty  = mkForAllTys [alphaTyVar, betaTyVar] $
+                         (m_ty `mkAppTy` alphaTy)
+                         `mkFunTy`
+                         (m_ty `mkAppTy` betaTy)
+                         `mkFunTy`
+                         (m_ty `mkAppTy` mkBoxedTupleTy [alphaTy, betaTy])
+        ; mzip_op' <- unLoc `fmap` tcPolyExpr (noLoc mzip_op) mzip_ty
+        ; return_op' <- fmap unLoc . tcPolyExpr (noLoc return_op) $
+                        mkForAllTy alphaTyVar $
+                        alphaTy `mkFunTy` (m_ty `mkAppTy` alphaTy)
+        ; (pairs', thing) <- loop m_ty bndr_stmts_s
+        -- Typecheck bind:
+        ; let tys      = map (mkBigCoreVarTupTy . snd) pairs'
+              tuple_ty = mk_tuple_ty tys
+        ; bind_op' <- tcSyntaxOp MCompOrigin bind_op $
+                         (m_ty `mkAppTy` tuple_ty)
+                         `mkFunTy` (tuple_ty `mkFunTy` res_ty)
+                         `mkFunTy` res_ty
+        ; return (ParStmt pairs' mzip_op' bind_op' return_op', thing) }
+   where 
+     mk_tuple_ty tys = foldr1 (\tn tm -> mkBoxedTupleTy [tn, tm]) tys
+        -- loop :: Type                                  -- m_ty
+        --      -> [([LStmt Name], [Name])]
+        --      -> TcM ([([LStmt TcId], [TcId])], thing)
+     loop _ [] = do { thing <- thing_inside res_ty
+                    ; return ([], thing) }           -- matching in the branches
+     loop m_ty ((stmts, names) : pairs)
+       = do { -- type dummy since we don't know all binder types yet
+              ty_dummy <- newFlexiTyVarTy liftedTypeKind
+            ; (stmts', (ids, pairs', thing))
+                 <- tcStmtsAndThen ctxt tcMcStmt stmts ty_dummy $ \res_ty' ->
+                    do { ids <- tcLookupLocalIds names
+                     ; let m_tup_ty = m_ty `mkAppTy` mkBigCoreVarTupTy ids
+                     ; check_same m_tup_ty res_ty'
+                     ; check_same m_tup_ty ty_dummy
+                                                        
+                       ; (pairs', thing) <- loop m_ty pairs
+                       ; return (ids, pairs', thing) }
+            ; return ( (stmts', ids) : pairs', thing ) }
+       -- Check that the types match up.
+       -- This is a grevious hack.  They always *will* match 
+       -- If (>>=) and (>>) are polymorpic in the return type,
+       -- but we don't have any good way to incorporate the coercion
+       -- so for now we just check that it's the identity
+     check_same actual expected
+       = do { coi <- unifyType actual expected
+          ; unless (isIdentityCoI coi) $
+              failWithMisMatch [UnifyOrigin { uo_expected = expected
+                                            , uo_actual = actual }] }
+ tcMcStmt _ stmt _ _
+   = pprPanic "tcMcStmt: unexpected Stmt" (ppr stmt)
+ ---------------------------------------------------
+ --         Do-notation
+ --      (supports rebindable syntax)
+ ---------------------------------------------------
  
  tcDoStmt :: TcStmtChecker
  
+ tcDoStmt _ (LastStmt body _) res_ty thing_inside
+   = do { body' <- tcMonoExprNC body res_ty
+        ; thing <- thing_inside (panic "tcDoStmt: thing_inside")
+        ; return (LastStmt body' noSyntaxExpr, thing) }
  tcDoStmt ctxt (BindStmt pat rhs bind_op fail_op) res_ty thing_inside
    = do        {       -- Deal with rebindable syntax:
                --       (>>=) :: rhs_ty -> (pat_ty -> new_res_ty) -> res_ty
        ; return (BindStmt pat' rhs' bind_op' fail_op', thing) }
  
  
- tcDoStmt _ (ExprStmt rhs then_op _) res_ty thing_inside
+ tcDoStmt _ (ExprStmt rhs then_op _ _) res_ty thing_inside
    = do        {       -- Deal with rebindable syntax; 
                  --   (>>) :: rhs_ty -> new_res_ty -> res_ty
                -- See also Note [Treat rebindable syntax first]
  
          ; rhs' <- tcMonoExprNC rhs rhs_ty
        ; thing <- thing_inside new_res_ty
-       ; return (ExprStmt rhs' then_op' rhs_ty, thing) }
+       ; return (ExprStmt rhs' then_op' noSyntaxExpr rhs_ty, thing) }
  
  tcDoStmt ctxt (RecStmt { recS_stmts = stmts, recS_later_ids = later_names
                         , recS_rec_ids = rec_names, recS_ret_fn = ret_op
          ; tcExtendIdEnv tup_ids $ do
          { stmts_ty <- newFlexiTyVarTy liftedTypeKind
          ; (stmts', (ret_op', tup_rets))
-                 <- tcStmts ctxt tcDoStmt stmts stmts_ty   $ \ inner_res_ty ->
+                 <- tcStmtsAndThen ctxt tcDoStmt stmts stmts_ty   $ \ inner_res_ty ->
                     do { tup_rets <- zipWithM tcCheckId tup_names tup_elt_tys
                               -- Unify the types of the "final" Ids (which may 
                               -- be polymorphic) with those of "knot-tied" Ids
                                 (mkFunTys [mfix_res_ty, mkFunTy tup_ty new_res_ty] res_ty)
  
          ; thing <- thing_inside new_res_ty
- --         ; lie_binds <- bindLocalMethods lie tup_ids
    
          ; let rec_ids = takeList rec_names tup_ids
        ; later_ids <- tcLookupLocalIds later_names
          ; return (RecStmt { recS_stmts = stmts', recS_later_ids = later_ids
                            , recS_rec_ids = rec_ids, recS_ret_fn = ret_op' 
                            , recS_mfix_fn = mfix_op', recS_bind_fn = bind_op'
-                           , recS_rec_rets = tup_rets }, thing)
+                           , recS_rec_rets = tup_rets, recS_ret_ty = stmts_ty }, thing)
          }}
  
  tcDoStmt _ stmt _ _
@@@ -577,51 -845,6 +845,6 @@@ rebindable syntax first, and push that 
  Otherwise the error shows up when cheking the rebindable syntax, and
  the expected/inferred stuff is back to front (see Trac #3613).
  
- \begin{code}
- --------------------------------
- --    Mdo-notation
- -- The distinctive features here are
- --    (a) RecStmts, and
- --    (b) no rebindable syntax
- tcMDoStmt :: (LHsExpr Name -> TcM (LHsExpr TcId, TcType))     -- RHS inference
-         -> TcStmtChecker
- tcMDoStmt tc_rhs ctxt (BindStmt pat rhs _ _) res_ty thing_inside
-   = do        { (rhs', pat_ty) <- tc_rhs rhs
-       ; (pat', thing)  <- tcPat (StmtCtxt ctxt) pat pat_ty $
-                             thing_inside res_ty
-       ; return (BindStmt pat' rhs' noSyntaxExpr noSyntaxExpr, thing) }
- tcMDoStmt tc_rhs _ (ExprStmt rhs _ _) res_ty thing_inside
-   = do        { (rhs', elt_ty) <- tc_rhs rhs
-       ; thing          <- thing_inside res_ty
-       ; return (ExprStmt rhs' noSyntaxExpr elt_ty, thing) }
- tcMDoStmt tc_rhs ctxt (RecStmt { recS_stmts = stmts, recS_later_ids = laterNames
-                                , recS_rec_ids = recNames }) res_ty thing_inside
-   = do        { rec_tys <- newFlexiTyVarTys (length recNames) liftedTypeKind
-       ; let rec_ids = zipWith mkLocalId recNames rec_tys
-       ; tcExtendIdEnv rec_ids                 $ do
-       { (stmts', (later_ids, rec_rets))
-               <- tcStmts ctxt (tcMDoStmt tc_rhs) stmts res_ty $ \ _res_ty' ->
-                       -- ToDo: res_ty not really right
-                  do { rec_rets <- zipWithM tcCheckId recNames rec_tys
-                     ; later_ids <- tcLookupLocalIds laterNames
-                     ; return (later_ids, rec_rets) }
-       ; thing <- tcExtendIdEnv later_ids (thing_inside res_ty)
-               -- NB:  The rec_ids for the recursive things 
-               --      already scope over this part. This binding may shadow
-               --      some of them with polymorphic things with the same Name
-               --      (see note [RecStmt] in HsExpr)
-         ; return (RecStmt stmts' later_ids rec_ids noSyntaxExpr noSyntaxExpr noSyntaxExpr rec_rets, thing)
-       }}
- tcMDoStmt _ _ stmt _ _
-   = pprPanic "tcMDoStmt: unexpected Stmt" (ppr stmt)
- \end{code}
  
  %************************************************************************
  %*                                                                    *
@@@ -36,7 -36,6 +36,6 @@@ import PrelName
  import BasicTypes hiding (SuccessFlag(..))
  import DynFlags
  import SrcLoc
- import ErrUtils
  import Util
  import Outputable
  import FastString
@@@ -149,7 -148,7 +148,7 @@@ data TcSigInf
  
  instance Outputable TcSigInfo where
      ppr (TcSigInfo { sig_id = id, sig_tvs = tyvars, sig_theta = theta, sig_tau = tau})
 -        = ppr id <+> ptext (sLit "::") <+> ppr tyvars <+> pprThetaArrow theta <+> ppr tau
 +        = ppr id <+> ptext (sLit "::") <+> ppr tyvars <+> pprThetaArrowTy theta <+> ppr tau
  \end{code}
  
  Note [sig_tau may be polymorphic]
@@@ -193,7 -192,7 +192,7 @@@ res_ty free vars
  %************************************************************************
  
  \begin{code}
 -tcPatBndr :: PatEnv -> Name -> TcSigmaType -> TcM (CoercionI, TcId)
 +tcPatBndr :: PatEnv -> Name -> TcSigmaType -> TcM (Coercion, TcId)
  -- (coi, xp) = tcPatBndr penv x pat_ty
  -- Then coi : pat_ty ~ typeof(xp)
  --
@@@ -205,11 -204,11 +204,11 @@@ tcPatBndr (PE { pe_ctxt = LetPat lookup
        
    | otherwise
    = do { bndr_id <- newNoSigLetBndr no_gen bndr_name pat_ty
 -       ; return (IdCo pat_ty, bndr_id) }
 +       ; return (mkReflCo pat_ty, bndr_id) }
  
  tcPatBndr (PE { pe_ctxt = _lam_or_proc }) bndr_name pat_ty
    = do { bndr <- mkLocalBinder bndr_name pat_ty
 -       ; return (IdCo pat_ty, bndr) }
 +       ; return (mkReflCo pat_ty, bndr) }
  
  ------------
  newSigLetBndr :: LetBndrSpec -> Name -> TcSigInfo -> TcM TcId
@@@ -348,9 -347,9 +347,9 @@@ tc_lpat :: LPat Nam
        -> TcM a
        -> TcM (LPat TcId, a)
  tc_lpat (L span pat) pat_ty penv thing_inside
-   = setSrcSpan span             $
-     maybeAddErrCtxt (patCtxt pat) $
-     do        { (pat', res) <- tc_pat penv pat pat_ty thing_inside
+   = setSrcSpan span $
+     do        { (pat', res) <- maybeWrapPatCtxt pat (tc_pat penv pat pat_ty)
+                                           thing_inside
        ; return (L span pat', res) }
  
  tc_lpats :: PatEnv
@@@ -373,7 -372,7 +372,7 @@@ tc_pat     :: PatEn
  tc_pat penv (VarPat name) pat_ty thing_inside
    = do        { (coi, id) <- tcPatBndr penv name pat_ty
        ; res <- tcExtendIdEnv1 name id thing_inside
 -        ; return (mkHsWrapPatCoI coi (VarPat id) pat_ty, res) }
 +        ; return (mkHsWrapPatCo coi (VarPat id) pat_ty, res) }
  
  tc_pat penv (ParPat pat) pat_ty thing_inside
    = do        { (pat', res) <- tc_lpat pat pat_ty penv thing_inside
@@@ -423,7 -422,7 +422,7 @@@ tc_pat penv (AsPat (L nm_loc name) pat
            -- perhaps be fixed, but only with a bit more work.
            --
            -- If you fix it, don't forget the bindInstsOfPatIds!
 -      ; return (mkHsWrapPatCoI coi (AsPat (L nm_loc bndr_id) pat') pat_ty, res) }
 +      ; return (mkHsWrapPatCo coi (AsPat (L nm_loc bndr_id) pat') pat_ty, res) }
  
  tc_pat penv vpat@(ViewPat expr pat _) overall_pat_ty thing_inside 
    = do        { checkUnboxedTuple overall_pat_ty $
           -- pattern must have pat_ty
          ; (pat', res) <- tc_lpat pat pat_ty penv thing_inside
  
 -      ; return (ViewPat (mkLHsWrapCoI expr_coi expr') pat' overall_pat_ty, res) }
 +      ; return (ViewPat (mkLHsWrapCo expr_coi expr') pat' overall_pat_ty, res) }
  
  -- Type signatures in patterns
  -- See Note [Pattern coercions] below
@@@ -511,7 -510,7 +510,7 @@@ tc_pat _ (LitPat simple_lit) pat_ty thi
        ; coi <- unifyPatType lit_ty pat_ty
                -- coi is of kind: pat_ty ~ lit_ty
        ; res <- thing_inside 
 -      ; return ( mkHsWrapPatCoI coi (LitPat simple_lit) pat_ty 
 +      ; return ( mkHsWrapPatCo coi (LitPat simple_lit) pat_ty 
                   , res) }
  
  ------------------------
@@@ -546,19 -545,19 +545,19 @@@ tc_pat penv (NPlusKPat (L nm_loc name) 
        ; instStupidTheta orig [mkClassPred icls [pat_ty']]     
      
        ; res <- tcExtendIdEnv1 name bndr_id thing_inside
 -      ; return (mkHsWrapPatCoI coi pat' pat_ty, res) }
 +      ; return (mkHsWrapPatCo coi pat' pat_ty, res) }
  
  tc_pat _ _other_pat _ _ = panic "tc_pat"      -- ConPatOut, SigPatOut
  
  ----------------
 -unifyPatType :: TcType -> TcType -> TcM CoercionI
 +unifyPatType :: TcType -> TcType -> TcM Coercion
  -- In patterns we want a coercion from the
  -- context type (expected) to the actual pattern type
  -- But we don't want to reverse the args to unifyType because
  -- that controls the actual/expected stuff in error messages
  unifyPatType actual_ty expected_ty
    = do { coi <- unifyType actual_ty expected_ty
 -       ; return (mkSymCoI coi) }
 +       ; return (mkSymCo coi) }
  \end{code}
  
  Note [Hopping the LIE in lazy patterns]
@@@ -657,7 -656,7 +656,7 @@@ tcConPat penv (L con_span con_name) pat
    = do        { data_con <- tcLookupDataCon con_name
        ; let tycon = dataConTyCon data_con
                  -- For data families this is the representation tycon
 -            (univ_tvs, ex_tvs, eq_spec, eq_theta, dict_theta, arg_tys, _)
 +            (univ_tvs, ex_tvs, eq_spec, theta, arg_tys, _)
                  = dataConFullSig data_con
  
          -- Instantiate the constructor type variables [a->ty]
              tenv     = zipTopTvSubst (univ_tvs     ++ ex_tvs)
                                       (ctxt_res_tys ++ mkTyVarTys ex_tvs')
              arg_tys' = substTys tenv arg_tys
 -            full_theta = eq_theta ++ dict_theta
  
 -      ; if null ex_tvs && null eq_spec && null full_theta
 +      ; if null ex_tvs && null eq_spec && null theta
          then do { -- The common case; no class bindings etc 
                      -- (see Note [Arrows and patterns])
                    (arg_pats', res) <- tcConArgs data_con arg_tys' 
  
          else do   -- The general case, with existential, 
                      -- and local equality constraints
 -      { let eq_preds = [mkEqPred (mkTyVarTy tv, ty) | (tv, ty) <- eq_spec]
 -            theta'   = substTheta tenv (eq_preds ++ full_theta)
 +      { let theta'   = substTheta tenv (eqSpecPreds eq_spec ++ theta)
                             -- order is *important* as we generate the list of
                             -- dictionary binders from theta'
              no_equalities = not (any isEqPred theta')
        } }
  
  ----------------------------
 -matchExpectedPatTy :: (TcRhoType -> TcM (CoercionI, a))
 +matchExpectedPatTy :: (TcRhoType -> TcM (Coercion, a))
                      -> TcRhoType -> TcM (HsWrapper, a) 
  -- See Note [Matching polytyped patterns]
  -- Returns a wrapper : pat_ty ~ inner_ty
  matchExpectedPatTy inner_match pat_ty
    | null tvs && null theta
    = do { (coi, res) <- inner_match pat_ty
 -       ; return (coiToHsWrapper (mkSymCoI coi), res) }
 +       ; return (coToHsWrapper (mkSymCo coi), res) }
                 -- The Sym is because the inner_match returns a coercion
         -- that is the other way round to matchExpectedPatTy
  
    | otherwise
    = do { (_, tys, subst) <- tcInstTyVars tvs
         ; wrap1 <- instCall PatOrigin tys (substTheta subst theta)
 -       ; (wrap2, arg_tys) <- matchExpectedPatTy inner_match (substTy subst tau)
 +       ; (wrap2, arg_tys) <- matchExpectedPatTy inner_match (TcType.substTy subst tau)
         ; return (wrap2 <.> wrap1 , arg_tys) }
    where
      (tvs, theta, tau) = tcSplitSigmaTy pat_ty
  matchExpectedConTy :: TyCon    -- The TyCon that this data 
                                 -- constructor actually returns
                   -> TcRhoType  -- The type of the pattern
 -                 -> TcM (CoercionI, [TcSigmaType])
 +                 -> TcM (Coercion, [TcSigmaType])
  -- See Note [Matching constructor patterns]
  -- Returns a coercion : T ty1 ... tyn ~ pat_ty
  -- This is the same way round as matchExpectedListTy etc
@@@ -762,17 -763,16 +761,16 @@@ matchExpectedConTy data_tc pat_t
         ; coi1 <- unifyType (mkTyConApp fam_tc (substTys subst fam_args)) pat_ty
                     -- coi1 : T (ty1,ty2) ~ pat_ty
  
 -       ; let coi2 = ACo (mkTyConApp co_tc tys)
 +       ; let coi2 = mkAxInstCo co_tc tys
                     -- coi2 : T (ty1,ty2) ~ T7 ty1 ty2
  
 -       ; return (mkTransCoI (mkSymCoI coi2) coi1, tys) }
 +       ; return (mkTransCo (mkSymCo coi2) coi1, tys) }
  
    | otherwise
    = matchExpectedTyConApp data_tc pat_ty
                     -- coi : T tys ~ pat_ty
  \end{code}
  
- Noate [
  Note [Matching constructor patterns]
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Suppose (coi, tys) = matchExpectedConType data_tc pat_ty
@@@ -1004,12 -1004,18 +1002,18 @@@ sigPatCtxt pats bound_tvs pat_tys body_
  -}
  
  \begin{code}
- patCtxt :: Pat Name -> Maybe Message  -- Not all patterns are worth pushing a context
- patCtxt (VarPat _)  = Nothing
- patCtxt (ParPat _)  = Nothing
- patCtxt (AsPat _ _) = Nothing
- patCtxt pat       = Just (hang (ptext (sLit "In the pattern:")) 
-                          2 (ppr pat))
+ maybeWrapPatCtxt :: Pat Name -> (TcM a -> TcM b) -> TcM a -> TcM b
+ -- Not all patterns are worth pushing a context
+ maybeWrapPatCtxt pat tcm thing_inside 
+   | not (worth_wrapping pat) = tcm thing_inside
+   | otherwise                = addErrCtxt msg $ tcm $ popErrCtxt thing_inside
+                              -- Remember to pop before doing thing_inside
+   where
+    worth_wrapping (VarPat {}) = False
+    worth_wrapping (ParPat {}) = False
+    worth_wrapping (AsPat {})  = False
+    worth_wrapping _         = True
+    msg = hang (ptext (sLit "In the pattern:")) 2 (ppr pat)
  
  -----------------------------------------------
  checkExistentials :: [TyVar] -> PatEnv -> TcM ()
@@@ -65,6 -65,7 +65,6 @@@ import Nam
  import NameEnv
  import NameSet
  import TyCon
 -import TysPrim
  import SrcLoc
  import HscTypes
  import ListSetOps
@@@ -72,7 -73,6 +72,7 @@@ import Outputabl
  import DataCon
  import Type
  import Class
 +import Pair
  import TcType   ( orphNamesOfDFunHead )
  import Inst   ( tcGetInstEnvs )
  import Data.List ( sortBy )
@@@ -645,7 -645,7 +645,7 @@@ checkHiBootIfac
      check_inst boot_inst
        = case [dfun | inst <- local_insts, 
                       let dfun = instanceDFunId inst,
 -                     idType dfun `tcEqType` boot_inst_ty ] of
 +                     idType dfun `eqType` boot_inst_ty ] of
            [] -> do { traceTc "check_inst" (vcat [ text "local_insts" <+> vcat (map (ppr . idType . instanceDFunId) local_insts)
                                                    , text "boot_inst"   <+> ppr boot_inst
                                                    , text "boot_inst_ty" <+> ppr boot_inst_ty
@@@ -669,7 -669,7 +669,7 @@@ checkBootDecl :: TyThing -> TyThing -> 
  
  checkBootDecl (AnId id1) (AnId id2)
    = ASSERT(id1 == id2) 
 -    (idType id1 `tcEqType` idType id2)
 +    (idType id1 `eqType` idType id2)
  
  checkBootDecl (ATyCon tc1) (ATyCon tc2)
    = checkBootTyCon tc1 tc2
@@@ -686,7 -686,7 +686,7 @@@ checkBootDecl (AClass c1)  (AClass c2
  
         eqSig (id1, def_meth1) (id2, def_meth2)
           = idName id1 == idName id2 &&
 -           tcEqTypeX env op_ty1 op_ty2 &&
 +           eqTypeX env op_ty1 op_ty2 &&
             def_meth1 == def_meth2
           where
          (_, rho_ty1) = splitForAllTys (idType id1)
            op_ty2 = funResultTy rho_ty2
  
         eqFD (as1,bs1) (as2,bs2) = 
 -         eqListBy (tcEqTypeX env) (mkTyVarTys as1) (mkTyVarTys as2) &&
 -         eqListBy (tcEqTypeX env) (mkTyVarTys bs1) (mkTyVarTys bs2)
 +         eqListBy (eqTypeX env) (mkTyVarTys as1) (mkTyVarTys as2) &&
 +         eqListBy (eqTypeX env) (mkTyVarTys bs1) (mkTyVarTys bs2)
  
         same_kind tv1 tv2 = eqKind (tyVarKind tv1) (tyVarKind tv2)
      in
         eqListBy eqFD clas_fds1 clas_fds2 &&
         (null sc_theta1 && null op_stuff1 && null ats1
          ||   -- Above tests for an "abstract" class
 -        eqListBy (tcEqPredX env) sc_theta1 sc_theta2 &&
 +        eqListBy (eqPredX env) sc_theta1 sc_theta2 &&
          eqListBy eqSig op_stuff1 op_stuff2 &&
          eqListBy checkBootTyCon ats1 ats2)
  
@@@ -728,7 -728,7 +728,7 @@@ checkBootTyCon tc1 tc
          eqSynRhs SynFamilyTyCon SynFamilyTyCon
              = True
          eqSynRhs (SynonymTyCon t1) (SynonymTyCon t2)
 -            = tcEqTypeX env t1 t2
 +            = eqTypeX env t1 t2
          eqSynRhs _ _ = False
      in
      equalLength tvs1 tvs2 &&
    | isAlgTyCon tc1 && isAlgTyCon tc2
    = ASSERT(tc1 == tc2)
      eqKind (tyConKind tc1) (tyConKind tc2) &&
 -    eqListBy tcEqPred (tyConStupidTheta tc1) (tyConStupidTheta tc2) &&
 +    eqListBy eqPred (tyConStupidTheta tc1) (tyConStupidTheta tc2) &&
      eqAlgRhs (algTyConRhs tc1) (algTyConRhs tc2)
  
    | isForeignTyCon tc1 && isForeignTyCon tc2
            && dataConIsInfix c1 == dataConIsInfix c2
            && dataConStrictMarks c1 == dataConStrictMarks c2
            && dataConFieldLabels c1 == dataConFieldLabels c2
 -          && let tvs1 = dataConUnivTyVars c1 ++ dataConExTyVars c1
 -                 tvs2 = dataConUnivTyVars c2 ++ dataConExTyVars c2
 -                 env = rnBndrs2 env0 tvs1 tvs2
 -             in
 -              equalLength tvs1 tvs2 &&              
 -              eqListBy (tcEqPredX env)
 -                        (dataConEqTheta c1 ++ dataConDictTheta c1)
 -                        (dataConEqTheta c2 ++ dataConDictTheta c2) &&
 -              eqListBy (tcEqTypeX env)
 -                        (dataConOrigArgTys c1)
 -                        (dataConOrigArgTys c2)
 +          && eqType (dataConUserType c1) (dataConUserType c2)
  
  ----------------
  missingBootThing :: Name -> String -> SDoc
@@@ -1195,7 -1205,7 +1195,7 @@@ runPlans (p:ps) = tryTcLIE_ (runPlans p
  
  --------------------
  mkPlan :: LStmt Name -> TcM PlanResult
- mkPlan (L loc (ExprStmt expr _ _))    -- An expression typed at the prompt 
+ mkPlan (L loc (ExprStmt expr _ _ _))  -- An expression typed at the prompt 
    = do        { uniq <- newUnique             -- is treated very specially
        ; let fresh_it  = itName uniq
              the_bind  = L loc $ mkFunBind (L loc fresh_it) matches
              bind_stmt = L loc $ BindStmt (nlVarPat fresh_it) expr
                                           (HsVar bindIOName) noSyntaxExpr 
              print_it  = L loc $ ExprStmt (nlHsApp (nlHsVar printName) (nlHsVar fresh_it))
-                                          (HsVar thenIOName) placeHolderType
+                                          (HsVar thenIOName) noSyntaxExpr placeHolderType
  
        -- The plans are:
        --      [it <- e; print it]     but not if it::()
  mkPlan stmt@(L loc (BindStmt {}))
    | [v] <- collectLStmtBinders stmt           -- One binder, for a bind stmt 
    = do        { let print_v  = L loc $ ExprStmt (nlHsApp (nlHsVar printName) (nlHsVar v))
-                                          (HsVar thenIOName) placeHolderType
+                                         (HsVar thenIOName) noSyntaxExpr placeHolderType
  
        ; print_bind_result <- doptM Opt_PrintBindResult
        ; let print_plan = do
@@@ -1259,11 -1269,25 +1259,25 @@@ tcGhciStmts stmt
        let {
            ret_ty    = mkListTy unitTy ;
            io_ret_ty = mkTyConApp ioTyCon [ret_ty] ;
-           tc_io_stmts stmts = tcStmts GhciStmt tcDoStmt stmts io_ret_ty ;
+           tc_io_stmts stmts = tcStmtsAndThen GhciStmt tcDoStmt stmts io_ret_ty ;
            names = collectLStmtsBinders stmts ;
+        } ;
+       -- OK, we're ready to typecheck the stmts
+       traceTc "TcRnDriver.tcGhciStmts: tc stmts" empty ;
+       ((tc_stmts, ids), lie) <- captureConstraints $ 
+                                   tc_io_stmts stmts  $ \ _ ->
+                                 mapM tcLookupId names  ;
+                       -- Look up the names right in the middle,
+                       -- where they will all be in scope
  
-               -- mk_return builds the expression
+       -- Simplify the context
+       traceTc "TcRnDriver.tcGhciStmts: simplify ctxt" empty ;
+       const_binds <- checkNoErrs (simplifyInteractive lie) ;
+               -- checkNoErrs ensures that the plan fails if context redn fails
+       traceTc "TcRnDriver.tcGhciStmts: done" empty ;
+         let {   -- mk_return builds the expression
                --      returnIO @ [()] [coerce () x, ..,  coerce () z]
                --
                -- Despite the inconvenience of building the type applications etc,
                -- then the type checker would instantiate x..z, and we wouldn't
                -- get their *polymorphic* values.  (And we'd get ambiguity errs
                -- if they were overloaded, since they aren't applied to anything.)
-           mk_return ids = nlHsApp (nlHsTyApp ret_id [ret_ty]) 
-                                   (noLoc $ ExplicitList unitTy (map mk_item ids)) ;
+           ret_expr = nlHsApp (nlHsTyApp ret_id [ret_ty]) 
+                      (noLoc $ ExplicitList unitTy (map mk_item ids)) ;
            mk_item id = nlHsApp (nlHsTyApp unsafeCoerceId [idType id, unitTy])
-                                (nlHsVar id) 
-        } ;
-       -- OK, we're ready to typecheck the stmts
-       traceTc "TcRnDriver.tcGhciStmts: tc stmts" empty ;
-       ((tc_stmts, ids), lie) <- captureConstraints $ tc_io_stmts stmts $ \ _ ->
-                                          mapM tcLookupId names ;
-                                       -- Look up the names right in the middle,
-                                       -- where they will all be in scope
-       -- Simplify the context
-       traceTc "TcRnDriver.tcGhciStmts: simplify ctxt" empty ;
-       const_binds <- checkNoErrs (simplifyInteractive lie) ;
-               -- checkNoErrs ensures that the plan fails if context redn fails
-       traceTc "TcRnDriver.tcGhciStmts: done" empty ;
+                                (nlHsVar id) ;
+           stmts = tc_stmts ++ [noLoc (mkLastStmt ret_expr)]
+         } ;
        return (ids, mkHsDictLet (EvBinds const_binds) $
-                    noLoc (HsDo GhciStmt tc_stmts (mk_return ids) io_ret_ty))
+                    noLoc (HsDo GhciStmt stmts io_ret_ty))
      }
  \end{code}
  
@@@ -1315,13 -1326,16 +1316,13 @@@ tcRnExpr hsc_env ictxt rdr_exp
  
        -- Now typecheck the expression; 
        -- it might have a rank-2 type (e.g. :t runST)
 -
      uniq <- newUnique ;
      let { fresh_it  = itName uniq } ;
 -    ((_tc_expr, res_ty), lie)   <- captureConstraints (tcInferRho rn_expr) ;
 -    ((qtvs, dicts, _), lie_top) <- captureConstraints $
 -                                   simplifyInfer TopLevel
 -                                                 False {- No MR for now -}
 +    ((_tc_expr, res_ty), lie) <- captureConstraints (tcInferRho rn_expr) ;
 +    ((qtvs, dicts, _), lie_top) <- captureConstraints $ 
 +                                   simplifyInfer TopLevel False {- No MR for now -}
                                                   [(fresh_it, res_ty)]
                                                   lie  ;
 -
      _ <- simplifyInteractive lie_top ;       -- Ignore the dicionary bindings
  
      let { all_expr_ty = mkForAllTys qtvs (mkPiTypes dicts res_ty) } ;
@@@ -1608,10 -1622,7 +1609,10 @@@ ppr_types insts type_en
  
  ppr_tycons :: [FamInst] -> TypeEnv -> SDoc
  ppr_tycons fam_insts type_env
 -  = text "TYPE CONSTRUCTORS" $$ nest 4 (ppr_tydecls tycons)
 +  = vcat [ text "TYPE CONSTRUCTORS"
 +         ,   nest 2 (ppr_tydecls tycons)
 +         , text "COERCION AXIOMS" 
 +         ,   nest 2 (ppr_axioms (typeEnvCoAxioms type_env)) ]
    where
      fi_tycons = map famInstTyCon fam_insts
      tycons = [tycon | tycon <- typeEnvTyCons type_env, want_tycon tycon]
@@@ -1643,16 -1654,13 +1644,16 @@@ ppr_tydecls tycon
    = vcat (map ppr_tycon (sortLe le_sig tycons))
    where
      le_sig tycon1 tycon2 = getOccName tycon1 <= getOccName tycon2
 -    ppr_tycon tycon 
 -      | isCoercionTyCon tycon 
 -      = sep [ptext (sLit "coercion") <+> ppr tycon <+> ppr tvs
 -            , nest 2 (dcolon <+> pprEqPred (coercionKind (mkTyConApp tycon (mkTyVarTys tvs))))]
 -      | otherwise             = ppr (tyThingToIfaceDecl (ATyCon tycon))
 +    ppr_tycon tycon = ppr (tyThingToIfaceDecl (ATyCon tycon))
        where
 -        tvs = take (tyConArity tycon) alphaTyVars
 +
 +ppr_axioms :: [CoAxiom] -> SDoc
 +ppr_axioms axs
 +  = vcat (map ppr_ax axs)
 +  where
 +    ppr_ax ax = sep [ ptext (sLit "coercion") <+> ppr ax <+> ppr (co_ax_tvs ax)
 +                    , nest 2 (dcolon <+> pprEqPred 
 +                                           (Pair (co_ax_lhs ax) (co_ax_rhs ax))) ]
  
  ppr_rules :: [CoreRule] -> SDoc
  ppr_rules [] = empty
@@@ -406,6 -406,7 +406,6 @@@ traceRn, traceSplice :: SDoc -> TcRn (
  traceRn      = traceOptTcRn Opt_D_dump_rn_trace
  traceSplice  = traceOptTcRn Opt_D_dump_splices
  
 -
  traceIf, traceHiDiffs :: SDoc -> TcRnIf m n ()
  traceIf      = traceOptIf Opt_D_dump_if_trace
  traceHiDiffs = traceOptIf Opt_D_dump_hi_diffs
@@@ -780,11 -781,6 +780,6 @@@ updCtxt :: ([ErrCtxt] -> [ErrCtxt]) -> 
  updCtxt upd = updLclEnv (\ env@(TcLclEnv { tcl_ctxt = ctxt }) -> 
                           env { tcl_ctxt = upd ctxt })
  
- -- Conditionally add an error context
- maybeAddErrCtxt :: Maybe Message -> TcM a -> TcM a
- maybeAddErrCtxt (Just msg) thing_inside = addErrCtxt msg thing_inside
- maybeAddErrCtxt Nothing    thing_inside = thing_inside
  popErrCtxt :: TcM a -> TcM a
  popErrCtxt = updCtxt (\ msgs -> case msgs of { [] -> []; (_ : ms) -> ms })
  
@@@ -896,9 -892,6 +891,9 @@@ add_err_tcm tidy_env err_msg loc ctx
  mkErrInfo :: TidyEnv -> [ErrCtxt] -> TcM SDoc
  -- Tidy the error info, trimming excessive contexts
  mkErrInfo env ctxts
 + | opt_PprStyle_Debug     -- In -dppr-debug style the output 
 + = return empty                 -- just becomes too voluminous
 + | otherwise
   = go 0 env ctxts
   where
     go :: Int -> TidyEnv -> [ErrCtxt] -> TcM SDoc
@@@ -42,7 -42,7 +42,7 @@@ module TcRnTypes
        CtOrigin(..), EqOrigin(..), 
          WantedLoc, GivenLoc, pushErrCtxt,
  
 -        SkolemInfo(..),
 +      SkolemInfo(..),
  
          CtFlavor(..), pprFlavorArising, isWanted, isGiven, isDerived,
          FlavoredEvVar,
@@@ -62,7 -62,6 +62,7 @@@
  import HsSyn
  import HscTypes
  import Type
 +import Id     ( evVarPred )
  import Class    ( Class )
  import DataCon  ( DataCon, dataConUserType )
  import TcType
@@@ -325,7 -324,6 +325,7 @@@ data IfLclEn
                -- plus which bit is currently being examined
  
        if_tv_env  :: UniqFM TyVar,     -- Nested tyvar bindings
 +                                      -- (and coercions)
        if_id_env  :: UniqFM Id         -- Nested id binding
      }
  \end{code}
@@@ -676,6 -674,7 +676,6 @@@ instance Outputable WhereFrom wher
  %************************************************************************
  %*                                                                    *
                Wanted constraints
 -
       These are forced to be in TcRnTypes because
           TcLclEnv mentions WantedConstraints
           WantedConstraint mentions CtLoc
@@@ -902,7 -901,7 +902,7 @@@ pprEvVarTheta :: [EvVar] -> SDo
  pprEvVarTheta ev_vars = pprTheta (map evVarPred ev_vars)
                                
  pprEvVarWithType :: EvVar -> SDoc
 -pprEvVarWithType v = ppr v <+> dcolon <+> pprPred (evVarPred v)
 +pprEvVarWithType v = ppr v <+> dcolon <+> pprPredTy (evVarPred v)
  
  pprWantedsWithLocs :: WantedConstraints -> SDoc
  pprWantedsWithLocs wcs
@@@ -1113,6 -1112,7 +1113,7 @@@ data CtOrigi
    | StandAloneDerivOrigin -- Typechecking stand-alone deriving
    | DefaultOrigin     -- Typechecking a default decl
    | DoOrigin          -- Arising from a do expression
+   | MCompOrigin         -- Arising from a monad comprehension
    | IfOrigin            -- Arising from an if statement
    | ProcOrigin                -- Arising from a proc expression
    | AnnOrigin           -- An annotation
@@@ -1148,6 -1148,7 +1149,7 @@@ pprO DerivOrigin           = ptext (sLit "the 
  pprO StandAloneDerivOrigin = ptext (sLit "a 'deriving' declaration")
  pprO DefaultOrigin       = ptext (sLit "a 'default' declaration")
  pprO DoOrigin            = ptext (sLit "a do statement")
+ pprO MCompOrigin           = ptext (sLit "a statement in a monad comprehension")
  pprO ProcOrigin                  = ptext (sLit "a proc expression")
  pprO (TypeEqOrigin eq)     = ptext (sLit "an equality") <+> ppr eq
  pprO AnnOrigin             = ptext (sLit "an annotation")
@@@ -82,7 -82,6 +82,7 @@@ import qualified TcRnMonad as Tc
  import qualified TcMType as TcM
  import qualified TcEnv as TcM 
         ( checkWellStaged, topIdLvl, tcLookupFamInst, tcGetDefaultTys )
 +import Kind
  import TcType
  import DynFlags
  
@@@ -98,17 -97,17 +98,18 @@@ import Outputabl
  import Bag
  import MonadUtils
  import VarSet
 +import Pair
  import FastString
  
  import HsBinds               -- for TcEvBinds stuff 
  import Id 
  import TcRnTypes
+ import Data.IORef
  #ifdef DEBUG
+ import StaticFlags( opt_PprStyle_Debug )
  import Control.Monad( when )
  #endif
- import Data.IORef
  \end{code}
  
  
@@@ -208,9 -207,9 +209,9 @@@ instance Outputable CanonicalCt wher
    ppr (CIPCan ip fl ip_nm ty)     
        = ppr fl <+> ppr ip <+> dcolon <+> parens (ppr ip_nm <> dcolon <> ppr ty)
    ppr (CTyEqCan co fl tv ty)      
 -      = ppr fl <+> ppr co <+> dcolon <+> pprEqPred (mkTyVarTy tv, ty)
 +      = ppr fl <+> ppr co <+> dcolon <+> pprEqPred (Pair (mkTyVarTy tv) ty)
    ppr (CFunEqCan co fl tc tys ty) 
 -      = ppr fl <+> ppr co <+> dcolon <+> pprEqPred (mkTyConApp tc tys, ty)
 +      = ppr fl <+> ppr co <+> dcolon <+> pprEqPred (Pair (mkTyConApp tc tys) ty)
    ppr (CFrozenErr co fl)
        = ppr fl <+> pprEvVarWithType co
  \end{code}
@@@ -529,7 -528,7 +530,7 @@@ runTcS context untouch tc
  
  #ifdef DEBUG
         ; count <- TcM.readTcRef step_count
-        ; when (count > 0) $
+        ; when (opt_PprStyle_Debug && count > 0) $
           TcM.debugDumpTcRn (ptext (sLit "Constraint solver steps =") 
                              <+> int count <+> ppr context)
  #endif
@@@ -678,7 -677,7 +679,7 @@@ checkWellStagedDFun pred dfun_id lo
      bind_lvl = TcM.topIdLvl dfun_id
  
  pprEq :: TcType -> TcType -> SDoc
 -pprEq ty1 ty2 = pprPred $ mkEqPred (ty1,ty2)
 +pprEq ty1 ty2 = pprPredTy $ mkEqPred (ty1,ty2)
  
  isTouchableMetaTyVar :: TcTyVar -> TcS Bool
  isTouchableMetaTyVar tv 
@@@ -20,7 -20,7 +20,7 @@@ module TcUnify 
    matchExpectedListTy, matchExpectedPArrTy, 
    matchExpectedTyConApp, matchExpectedAppTy, 
    matchExpectedFunTys, matchExpectedFunKind,
-   wrapFunResCoercion
+   wrapFunResCoercion, failWithMisMatch
    ) where
  
  #include "HsVersions.h"
@@@ -28,7 -28,7 +28,7 @@@
  import HsSyn
  import TypeRep
  import CoreUtils( mkPiTypes )
 -import TcErrors ( unifyCtxt )
 +import TcErrors       ( unifyCtxt )
  import TcMType
  import TcIface
  import TcRnMonad
@@@ -44,6 -44,7 +44,6 @@@ import VarEn
  import Name
  import ErrUtils
  import BasicTypes
 -
  import Maybes ( allMaybes )  
  import Util
  import Outputable
@@@ -102,7 -103,7 +102,7 @@@ expected type, becuase it expects that 
  matchExpectedFunTys :: SDoc   -- See Note [Herald for matchExpectedFunTys]
                    -> Arity
                    -> TcRhoType 
 -                  -> TcM (CoercionI, [TcSigmaType], TcRhoType)                        
 +                    -> TcM (Coercion, [TcSigmaType], TcRhoType)
  
  -- If    matchExpectFunTys n ty = (co, [t1,..,tn], ty_r)
  -- then  co : ty ~ (t1 -> ... -> tn -> ty_r)
@@@ -121,7 -122,7 +121,7 @@@ matchExpectedFunTys herald arity orig_t
      -- then   co : ty ~ t1 -> .. -> tn -> ty_r
  
      go n_req ty
 -      | n_req == 0 = return (IdCo ty, [], ty)
 +      | n_req == 0 = return (mkReflCo ty, [], ty)
  
      go n_req ty
        | Just ty' <- tcView ty = go n_req ty'
      go n_req (FunTy arg_ty res_ty)
        | not (isPredTy arg_ty) 
        = do { (coi, tys, ty_r) <- go (n_req-1) res_ty
 -           ; return (mkFunTyCoI (IdCo arg_ty) coi, arg_ty:tys, ty_r) }
 +           ; return (mkFunCo (mkReflCo arg_ty) coi, arg_ty:tys, ty_r) }
  
      go _ (TyConApp tc _)            -- A common case
        | not (isSynFamilyTyCon tc)
  
  \begin{code}
  ----------------------
 -matchExpectedListTy :: TcRhoType -> TcM (CoercionI, TcRhoType)
 +matchExpectedListTy :: TcRhoType -> TcM (Coercion, TcRhoType)
  -- Special case for lists
  matchExpectedListTy exp_ty
   = do { (coi, [elt_ty]) <- matchExpectedTyConApp listTyCon exp_ty
        ; return (coi, elt_ty) }
  
  ----------------------
 -matchExpectedPArrTy :: TcRhoType -> TcM (CoercionI, TcRhoType)
 +matchExpectedPArrTy :: TcRhoType -> TcM (Coercion, TcRhoType)
  -- Special case for parrs
  matchExpectedPArrTy exp_ty
    = do { (coi, [elt_ty]) <- matchExpectedTyConApp parrTyCon exp_ty
  ----------------------
  matchExpectedTyConApp :: TyCon                -- T :: k1 -> ... -> kn -> *
                        -> TcRhoType          -- orig_ty
 -                      -> TcM (CoercionI,      -- T a b c ~ orig_ty
 +                      -> TcM (Coercion,      -- T a b c ~ orig_ty
                                [TcSigmaType])  -- Element types, a b c
                                
  -- It's used for wired-in tycons, so we call checkWiredInTyCon
@@@ -199,7 -200,7 +199,7 @@@ matchExpectedTyConApp tc orig_t
    = do  { checkWiredInTyCon tc
          ; go (tyConArity tc) orig_ty [] }
    where
 -    go :: Int -> TcRhoType -> [TcSigmaType] -> TcM (CoercionI, [TcSigmaType])
 +    go :: Int -> TcRhoType -> [TcSigmaType] -> TcM (Coercion, [TcSigmaType])
      -- If     go n ty tys = (co, [t1..tn] ++ tys)
      -- then   co : T t1..tn ~ ty
  
      go n_req ty@(TyConApp tycon args) tys
        | tc == tycon
        = ASSERT( n_req == length args)   -- ty::*
 -        return (IdCo ty, args ++ tys)
 +        return (mkReflCo ty, args ++ tys)
  
      go n_req (AppTy fun arg) tys
        | n_req > 0
        = do { (coi, args) <- go (n_req - 1) fun (arg : tys) 
 -           ; return (mkAppTyCoI coi (IdCo arg), args) }
 +           ; return (mkAppCo coi (mkReflCo arg), args) }
  
      go n_req ty tys = defer n_req ty tys
  
  
  ----------------------
  matchExpectedAppTy :: TcRhoType                         -- orig_ty
 -                   -> TcM (CoercionI,                   -- m a ~ orig_ty
 +                   -> TcM (Coercion,                   -- m a ~ orig_ty
                             (TcSigmaType, TcSigmaType))  -- Returns m, a
  -- If the incoming type is a mutable type variable of kind k, then
  -- matchExpectedAppTy returns a new type variable (m: * -> k); note the *.
@@@ -247,7 -248,7 +247,7 @@@ matchExpectedAppTy orig_t
        | Just ty' <- tcView ty = go ty'
  
        | Just (fun_ty, arg_ty) <- tcSplitAppTy_maybe ty
 -      = return (IdCo orig_ty, (fun_ty, arg_ty))
 +      = return (mkReflCo orig_ty, (fun_ty, arg_ty))
  
      go (TyVarTy tv)
        | ASSERT( isTcTyVar tv) isMetaTyVar tv
@@@ -305,14 -306,14 +305,14 @@@ tcSubType origin ctxt ty_actual ty_expe
              <- tcGen ctxt ty_expected $ \ _ sk_rho -> do
              { (in_wrap, in_rho) <- deeplyInstantiate origin ty_actual
              ; coi <- unifyType in_rho sk_rho
 -            ; return (coiToHsWrapper coi <.> in_wrap) }
 +            ; return (coToHsWrapper coi <.> in_wrap) }
         ; return (sk_wrap <.> inst_wrap) }
  
    | otherwise -- Urgh!  It seems deeply weird to have equality
                -- when actual is not a polytype, and it makes a big 
                -- difference e.g. tcfail104
    = do { coi <- unifyType ty_actual ty_expected
 -       ; return (coiToHsWrapper coi) }
 +       ; return (coToHsWrapper coi) }
    
  tcInfer :: (TcType -> TcM a) -> TcM (a, TcType)
  tcInfer tc_infer = do { ty  <- newFlexiTyVarTy openTypeKind
@@@ -324,7 -325,7 +324,7 @@@ tcWrapResult :: HsExpr TcId -> TcRhoTyp
  tcWrapResult expr actual_ty res_ty
    = do { coi <- unifyType actual_ty res_ty
                        -- Both types are deeply skolemised
 -       ; return (mkHsWrapCoI coi expr) }
 +       ; return (mkHsWrapCo coi expr) }
  
  -----------------------------------
  wrapFunResCoercion
@@@ -450,18 -451,18 +450,18 @@@ non-exported generic functions
  
  \begin{code}
  ---------------
 -unifyType :: TcTauType -> TcTauType -> TcM CoercionI
 +unifyType :: TcTauType -> TcTauType -> TcM Coercion
  -- Actual and expected types
  -- Returns a coercion : ty1 ~ ty2
  unifyType ty1 ty2 = uType [] ty1 ty2
  
  ---------------
 -unifyPred :: PredType -> PredType -> TcM CoercionI
 +unifyPred :: PredType -> PredType -> TcM Coercion
  -- Actual and expected types
  unifyPred p1 p2 = uPred [UnifyOrigin (mkPredTy p1) (mkPredTy p2)] p1 p2
  
  ---------------
 -unifyTheta :: TcThetaType -> TcThetaType -> TcM [CoercionI]
 +unifyTheta :: TcThetaType -> TcThetaType -> TcM [Coercion]
  -- Actual and expected types
  unifyTheta theta1 theta2
    = do  { checkTc (equalLength theta1 theta2)
@@@ -512,7 -513,7 +512,7 @@@ uType, uType_np, uType_defe
    :: [EqOrigin]
    -> TcType    -- ty1 is the *actual* type
    -> TcType    -- ty2 is the *expected* type
 -  -> TcM CoercionI
 +  -> TcM Coercion
  
  --------------
  -- It is always safe to defer unification to the main constraint solver
@@@ -528,7 -529,7 +528,7 @@@ uType_defer (item : origin) ty1 ty
         ; doc <- mkErrInfo emptyTidyEnv ctxt
         ; traceTc "utype_defer" (vcat [ppr co_var, ppr ty1, ppr ty2, ppr origin, doc])
  
 -       ; return $ ACo $ mkTyVarTy co_var }
 +       ; return $ mkCoVarCo co_var }
  uType_defer [] _ _
    = panic "uType_defer"
  
@@@ -544,15 -545,15 +544,15 @@@ uType_np origin orig_ty1 orig_ty
                [ sep [ ppr orig_ty1, text "~", ppr orig_ty2]
                , ppr origin]
         ; coi <- go orig_ty1 orig_ty2
 -       ; case coi of
 -            ACo co -> traceTc "u_tys yields coercion:" (ppr co)
 -            IdCo _ -> traceTc "u_tys yields no coercion" empty
 +       ; if isReflCo coi
 +            then traceTc "u_tys yields no coercion" empty
 +            else traceTc "u_tys yields coercion:" (ppr coi)
         ; return coi }
    where
      bale_out :: [EqOrigin] -> TcM a
      bale_out origin = failWithMisMatch origin
  
 -    go :: TcType -> TcType -> TcM CoercionI
 +    go :: TcType -> TcType -> TcM Coercion
        -- The arguments to 'go' are always semantically identical 
        -- to orig_ty{1,2} except for looking through type synonyms
  
        | Just ty1' <- tcView ty1 = go ty1' ty2
        | Just ty2' <- tcView ty2 = go ty1  ty2'
                     
          -- Predicates
      go (PredTy p1) (PredTy p2) = uPred origin p1 p2
  
 -        -- Coercion functions: (t1a ~ t1b) => t1c  ~  (t2a ~ t2b) => t2c
 -    go ty1 ty2 
 -      | Just (t1a,t1b,t1c) <- splitCoPredTy_maybe ty1, 
 -        Just (t2a,t2b,t2c) <- splitCoPredTy_maybe ty2
 -      = do { co1 <- uType origin t1a t2a 
 -           ; co2 <- uType origin t1b t2b
 -           ; co3 <- uType origin t1c t2c 
 -           ; return $ mkCoPredCoI co1 co2 co3 }
 -
          -- Functions (or predicate functions) just check the two parts
      go (FunTy fun1 arg1) (FunTy fun2 arg2)
        = do { coi_l <- uType origin fun1 fun2
             ; coi_r <- uType origin arg1 arg2
 -           ; return $ mkFunTyCoI coi_l coi_r }
 +           ; return $ mkFunCo coi_l coi_r }
  
          -- Always defer if a type synonym family (type function)
                -- is involved.  (Data families behave rigidly.)
      go (TyConApp tc1 tys1) (TyConApp tc2 tys2)
        | tc1 == tc2       -- See Note [TyCon app]
        = do { cois <- uList origin uType tys1 tys2
 -           ; return $ mkTyConAppCoI tc1 cois }
 +           ; return $ mkTyConAppCo tc1 cois }
       
        -- See Note [Care with type applications]
      go (AppTy s1 t1) ty2
        | Just (s2,t2) <- tcSplitAppTy_maybe ty2
        = do { coi_s <- uType_np origin s1 s2  -- See Note [Unifying AppTy]
             ; coi_t <- uType origin t1 t2        
 -           ; return $ mkAppTyCoI coi_s coi_t }
 +           ; return $ mkAppCo coi_s coi_t }
  
      go ty1 (AppTy s2 t2)
        | Just (s1,t1) <- tcSplitAppTy_maybe ty1
        = do { coi_s <- uType_np origin s1 s2
             ; coi_t <- uType origin t1 t2
 -           ; return $ mkAppTyCoI coi_s coi_t }
 +           ; return $ mkAppCo coi_s coi_t }
  
      go ty1 ty2
        | tcIsForAllTy ty1 || tcIsForAllTy ty2 
          -- Anything else fails
      go _ _ = bale_out origin
  
 -unifySigmaTy :: [EqOrigin] -> TcType -> TcType -> TcM CoercionI
 +unifySigmaTy :: [EqOrigin] -> TcType -> TcType -> TcM Coercion
  unifySigmaTy origin ty1 ty2
    = do { let (tvs1, body1) = tcSplitForAllTys ty1
               (tvs2, body2) = tcSplitForAllTys ty2
                    -- Get location from monad, not from tvs1
         ; let tys      = mkTyVarTys skol_tvs
               in_scope = mkInScopeSet (mkVarSet skol_tvs)
 -             phi1     = substTy (mkTvSubst in_scope (zipTyEnv tvs1 tys)) body1
 -             phi2     = substTy (mkTvSubst in_scope (zipTyEnv tvs2 tys)) body2
 ---             untch = tyVarsOfType ty1 `unionVarSet` tyVarsOfType ty2
 +             phi1     = Type.substTy (mkTvSubst in_scope (zipTyEnv tvs1 tys)) body1
 +             phi2     = Type.substTy (mkTvSubst in_scope (zipTyEnv tvs2 tys)) body2
  
         ; ((coi, _untch), lie) <- captureConstraints $ 
                                   captureUntouchables $ 
                (failWithMisMatch origin)       -- ToDo: give details from bad_lie
  
         ; emitConstraints lie
 -       ; return (foldr mkForAllTyCoI coi skol_tvs) }
 +       ; return (foldr mkForAllCo coi skol_tvs) }
  
  ----------
 -uPred :: [EqOrigin] -> PredType -> PredType -> TcM CoercionI
 +uPred :: [EqOrigin] -> PredType -> PredType -> TcM Coercion
  uPred origin (IParam n1 t1) (IParam n2 t2)
    | n1 == n2
    = do { coi <- uType origin t1 t2
 -       ; return $ mkIParamPredCoI n1 coi }
 +       ; return $ mkPredCo $ IParam n1 coi }
  uPred origin (ClassP c1 tys1) (ClassP c2 tys2)
    | c1 == c2 
    = do { cois <- uList origin uType tys1 tys2
            -- Guaranteed equal lengths because the kinds check
 -       ; return $ mkClassPPredCoI c1 cois }
 +       ; return $ mkPredCo $ ClassP c1 cois }
 +
  uPred origin (EqPred ty1a ty1b) (EqPred ty2a ty2b)
 -  = do { coia <- uType origin ty1a ty2a
 -       ; coib <- uType origin ty1b ty2b
 -       ; return $ mkEqPredCoI coia coib }
 +  = do { coa <- uType origin ty1a ty2a
 +       ; cob <- uType origin ty1b ty2b
 +       ; return $ mkPredCo $ EqPred coa cob }
  
  uPred origin _ _ = failWithMisMatch origin
  
@@@ -805,7 -816,7 +805,7 @@@ of the substitution; rather, notice tha
  back into @uTys@ if it turns out that the variable is already bound.
  
  \begin{code}
 -uVar :: [EqOrigin] -> SwapFlag -> TcTyVar -> TcTauType -> TcM CoercionI
 +uVar :: [EqOrigin] -> SwapFlag -> TcTyVar -> TcTauType -> TcM Coercion
  uVar origin swapped tv1 ty2
    = do  { traceTc "uVar" (vcat [ ppr origin
                                  , ppr swapped
@@@ -823,13 -834,13 +823,13 @@@ uUnfilledVar :: [EqOrigin
               -> SwapFlag
               -> TcTyVar -> TcTyVarDetails       -- Tyvar 1
               -> TcTauType                     -- Type 2
 -             -> TcM CoercionI
 +             -> TcM Coercion
  -- "Unfilled" means that the variable is definitely not a filled-in meta tyvar
  --            It might be a skolem, or untouchable, or meta
  
  uUnfilledVar origin swapped tv1 details1 (TyVarTy tv2)
    | tv1 == tv2  -- Same type variable => no-op
 -  = return (IdCo (mkTyVarTy tv1))
 +  = return (mkReflCo (mkTyVarTy tv1))
  
    | otherwise  -- Distinct type variables
    = do  { lookup2 <- lookupTcTyVar tv2
@@@ -863,7 -874,7 +863,7 @@@ uUnfilledVars :: [EqOrigin
                -> SwapFlag
                -> TcTyVar -> TcTyVarDetails      -- Tyvar 1
                -> TcTyVar -> TcTyVarDetails      -- Tyvar 2
 -              -> TcM CoercionI
 +              -> TcM Coercion
  -- Invarant: The type variables are distinct,
  --           Neither is filled in yet
  
@@@ -1042,10 -1053,10 +1042,10 @@@ lookupTcTyVar tyva
      details = ASSERT2( isTcTyVar tyvar, ppr tyvar )
                tcTyVarDetails tyvar
  
 -updateMeta :: TcTyVar -> TcRef MetaDetails -> TcType -> TcM CoercionI
 +updateMeta :: TcTyVar -> TcRef MetaDetails -> TcType -> TcM Coercion
  updateMeta tv1 ref1 ty2
    = do { writeMetaTyVarRef tv1 ref1 ty2
 -       ; return (IdCo ty2) }
 +       ; return (mkReflCo ty2) }
  \end{code}
  
  Note [Unifying untouchables]