Support for -fwarn-unused-do-bind and -fwarn-wrong-do-bind, as per #3263
[ghc-hetmet.git] / compiler / typecheck / TcBinds.lhs
index 45e3264..eae66a8 100644 (file)
@@ -5,15 +5,8 @@
 \section[TcBinds]{TcBinds}
 
 \begin{code}
-{-# OPTIONS -w #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and fix
--- any warnings in the module. See
---     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
--- for details
-
 module TcBinds ( tcLocalBinds, tcTopBinds, 
-                 tcHsBootSigs, tcMonoBinds, 
+                 tcHsBootSigs, tcMonoBinds, tcPolyBinds,
                  TcPragFun, tcSpecPrag, tcPrags, mkPragFun, 
                  TcSigInfo(..), TcSigFun, mkTcSigFun,
                  badBootDeclErr ) where
@@ -23,7 +16,6 @@ import {-# SOURCE #-} TcExpr  ( tcMonoExpr )
 
 import DynFlags
 import HsSyn
-import TcHsSyn
 
 import TcRnMonad
 import Inst
@@ -39,8 +31,7 @@ import Coercion
 import VarEnv
 import TysPrim
 import Id
-import IdInfo
-import Var ( TyVar, varType )
+import Var
 import Name
 import NameSet
 import NameEnv
@@ -107,12 +98,13 @@ tcHsBootSigs :: HsValBinds Name -> TcM [Id]
 -- signatures in it.  The renamer checked all this
 tcHsBootSigs (ValBindsOut binds sigs)
   = do  { checkTc (null binds) badBootDeclErr
-        ; mapM (addLocM tc_boot_sig) (filter isVanillaLSig sigs) }
+        ; mapM (addLocM tc_boot_sig) (filter isTypeLSig sigs) }
   where
     tc_boot_sig (TypeSig (L _ name) ty)
       = do { sigma_ty <- tcHsSigType (FunSigCtxt name) ty
-           ; return (mkVanillaGlobal name sigma_ty vanillaIdInfo) }
+           ; return (mkVanillaGlobal name sigma_ty) }
         -- Notice that we make GlobalIds, not LocalIds
+    tc_boot_sig s = pprPanic "tcHsBootSigs/tc_boot_sig" (ppr s)
 tcHsBootSigs groups = pprPanic "tcHsBootSigs" (ppr groups)
 
 badBootDeclErr :: Message
@@ -153,16 +145,16 @@ tcValBinds :: TopLevelFlag
            -> HsValBinds Name -> TcM thing
            -> TcM (HsValBinds TcId, thing) 
 
-tcValBinds top_lvl (ValBindsIn binds sigs) thing_inside
+tcValBinds _ (ValBindsIn binds _) _
   = pprPanic "tcValBinds" (ppr binds)
 
 tcValBinds top_lvl (ValBindsOut binds sigs) thing_inside
   = do  {       -- Typecheck the signature
         ; let { prag_fn = mkPragFun sigs
-              ; ty_sigs = filter isVanillaLSig sigs
+              ; ty_sigs = filter isTypeLSig sigs
               ; sig_fn  = mkTcSigFun ty_sigs }
 
-        ; poly_ids <- mapM tcTySig ty_sigs
+        ; poly_ids <- checkNoErrs (mapAndRecoverM tcTySig ty_sigs)
                 -- No recovery from bad signatures, because the type sigs
                 -- may bind type variables, so proceeding without them
                 -- can lead to a cascade of errors
@@ -173,26 +165,29 @@ tcValBinds top_lvl (ValBindsOut binds sigs) thing_inside
                 -- the Ids declared with type signatures
         ; poly_rec <- doptM Opt_RelaxedPolyRec
         ; (binds', thing) <- tcExtendIdEnv poly_ids $
-                             tc_val_binds poly_rec top_lvl sig_fn prag_fn 
+                             tcBindGroups poly_rec top_lvl sig_fn prag_fn 
                                           binds thing_inside
 
         ; return (ValBindsOut binds' sigs, thing) }
 
 ------------------------
-tc_val_binds :: Bool -> TopLevelFlag -> TcSigFun -> TcPragFun
+tcBindGroups :: Bool -> TopLevelFlag -> TcSigFun -> TcPragFun
              -> [(RecFlag, LHsBinds Name)] -> TcM thing
              -> TcM ([(RecFlag, LHsBinds TcId)], thing)
 -- Typecheck a whole lot of value bindings,
 -- one strongly-connected component at a time
+-- Here a "strongly connected component" has the strightforward
+-- meaning of a group of bindings that mention each other, 
+-- ignoring type signatures (that part comes later)
 
-tc_val_binds poly_rec top_lvl sig_fn prag_fn [] thing_inside
+tcBindGroups _ _ _ _ [] thing_inside
   = do  { thing <- thing_inside
         ; return ([], thing) }
 
-tc_val_binds poly_rec top_lvl sig_fn prag_fn (group : groups) thing_inside
+tcBindGroups poly_rec top_lvl sig_fn prag_fn (group : groups) thing_inside
   = do  { (group', (groups', thing))
                 <- tc_group poly_rec top_lvl sig_fn prag_fn group $ 
-                   tc_val_binds poly_rec top_lvl sig_fn prag_fn groups thing_inside
+                   tcBindGroups poly_rec top_lvl sig_fn prag_fn groups thing_inside
         ; return (group' ++ groups', thing) }
 
 ------------------------
@@ -204,52 +199,61 @@ tc_group :: Bool -> TopLevelFlag -> TcSigFun -> TcPragFun
 -- We get a list of groups back, because there may 
 -- be specialisations etc as well
 
-tc_group poly_rec top_lvl sig_fn prag_fn (NonRecursive, binds) thing_inside
+tc_group _ top_lvl sig_fn prag_fn (NonRecursive, binds) thing_inside
         -- A single non-recursive binding
         -- We want to keep non-recursive things non-recursive
         -- so that we desugar unlifted bindings correctly
- =  do  { (binds, thing) <- tc_haskell98 top_lvl sig_fn prag_fn NonRecursive binds thing_inside
-        ; return ([(NonRecursive, b) | b <- binds], thing) }
+ =  do  { (binds1, lie_binds, thing) <- tc_haskell98 top_lvl sig_fn prag_fn 
+                                                    NonRecursive binds thing_inside
+        ; return ( [(NonRecursive, unitBag b) | b <- bagToList binds1]
+                    ++ [(Recursive, lie_binds)]  -- TcDictBinds have scrambled dependency order
+                , thing) }
 
 tc_group poly_rec top_lvl sig_fn prag_fn (Recursive, binds) thing_inside
   | not poly_rec        -- Recursive group, normal Haskell 98 route
-  = do  { (binds1, thing) <- tc_haskell98 top_lvl sig_fn prag_fn Recursive binds thing_inside
-        ; return ([(Recursive, unionManyBags binds1)], thing) }
+  = do  { (binds1, lie_binds, thing) <- tc_haskell98 top_lvl sig_fn prag_fn 
+                                                    Recursive binds thing_inside
+        ; return ([(Recursive, binds1 `unionBags` lie_binds)], thing) }
 
-  | otherwise           -- Recursive group, with gla-exts
-  =     -- To maximise polymorphism (with -fglasgow-exts), we do a new 
+  | otherwise           -- Recursive group, with -XRelaxedPolyRec
+  =     -- To maximise polymorphism (with -XRelaxedPolyRec), we do a new 
         -- strongly-connected-component analysis, this time omitting 
         -- any references to variables with type signatures.
         --
-        -- Notice that the bindInsts thing covers *all* the bindings in the original
-        -- group at once; an earlier one may use a later one!
+        -- Notice that the bindInsts thing covers *all* the bindings in
+        -- the original group at once; an earlier one may use a later one!
     do  { traceTc (text "tc_group rec" <+> pprLHsBinds binds)
-        ; (binds1,thing) <- bindLocalInsts top_lvl $
-                            go (stronglyConnComp (mkEdges sig_fn binds))
-        ; return ([(Recursive, unionManyBags binds1)], thing) }
+        ; (binds1,lie_binds,thing) <- bindLocalInsts top_lvl $
+                            go (stronglyConnCompFromEdgedVertices (mkEdges sig_fn binds))
+        ; return ([(Recursive, binds1 `unionBags` lie_binds)], thing) }
                 -- Rec them all together
   where
---  go :: SCC (LHsBind Name) -> TcM ([LHsBind TcId], [TcId], thing)
+--  go :: SCC (LHsBind Name) -> TcM (LHsBinds TcId, [TcId], thing)
     go (scc:sccs) = do  { (binds1, ids1) <- tc_scc scc
                         ; (binds2, ids2, thing) <- tcExtendIdEnv ids1 $ go sccs
-                        ; return (binds1 ++ binds2, ids1 ++ ids2, thing) }
-    go []         = do  { thing <- thing_inside; return ([], [], thing) }
+                        ; return (binds1 `unionBags` binds2, ids1 ++ ids2, thing) }
+    go []         = do  { thing <- thing_inside; return (emptyBag, [], thing) }
 
     tc_scc (AcyclicSCC bind) = tc_sub_group NonRecursive (unitBag bind)
     tc_scc (CyclicSCC binds) = tc_sub_group Recursive    (listToBag binds)
 
     tc_sub_group = tcPolyBinds top_lvl sig_fn prag_fn Recursive
 
+tc_haskell98 :: TopLevelFlag -> TcSigFun -> TcPragFun -> RecFlag
+             -> LHsBinds Name -> TcM a -> TcM (LHsBinds TcId, TcDictBinds, a)
 tc_haskell98 top_lvl sig_fn prag_fn rec_flag binds thing_inside
-  = bindLocalInsts top_lvl $ do
-    { (binds1, ids) <- tcPolyBinds top_lvl sig_fn prag_fn rec_flag rec_flag binds
-    ; thing <- tcExtendIdEnv ids thing_inside
-    ; return (binds1, ids, thing) }
+  = bindLocalInsts top_lvl $ 
+    do { (binds1, ids) <- tcPolyBinds top_lvl sig_fn prag_fn rec_flag rec_flag binds
+       ; thing <- tcExtendIdEnv ids thing_inside
+       ; return (binds1, ids, thing) }
 
 ------------------------
-bindLocalInsts :: TopLevelFlag -> TcM ([LHsBinds TcId], [TcId], a) -> TcM ([LHsBinds TcId], a)
+bindLocalInsts :: TopLevelFlag
+              -> TcM (LHsBinds TcId, [TcId],      a)
+              -> TcM (LHsBinds TcId, TcDictBinds, a)
 bindLocalInsts top_lvl thing_inside
-  | isTopLevel top_lvl = do { (binds, ids, thing) <- thing_inside; return (binds, thing) }
+  | isTopLevel top_lvl
+  = do { (binds, _, thing) <- thing_inside; return (binds, emptyBag, thing) }
         -- For the top level don't bother with all this bindInstsOfLocalFuns stuff. 
         -- All the top level things are rec'd together anyway, so it's fine to
         -- leave them to the tcSimplifyTop, and quite a bit faster too
@@ -257,7 +261,7 @@ bindLocalInsts top_lvl thing_inside
   | otherwise   -- Nested case
   = do  { ((binds, ids, thing), lie) <- getLIE thing_inside
         ; lie_binds <- bindInstsOfLocalFuns lie ids
-        ; return (binds ++ [lie_binds], thing) }
+        ; return (binds, lie_binds, thing) }
 
 ------------------------
 mkEdges :: TcSigFun -> LHsBinds Name
@@ -283,6 +287,8 @@ mkEdges sig_fn binds
 bindersOfHsBind :: HsBind Name -> [Name]
 bindersOfHsBind (PatBind { pat_lhs = pat })  = collectPatBinders pat
 bindersOfHsBind (FunBind { fun_id = L _ f }) = [f]
+bindersOfHsBind (AbsBinds {})                = panic "bindersOfHsBind AbsBinds"
+bindersOfHsBind (VarBind {})                 = panic "bindersOfHsBind VarBind"
 
 ------------------------
 tcPolyBinds :: TopLevelFlag -> TcSigFun -> TcPragFun
@@ -290,7 +296,7 @@ tcPolyBinds :: TopLevelFlag -> TcSigFun -> TcPragFun
             -> RecFlag                  -- Whether it's recursive after breaking
                                         -- dependencies based on type signatures
             -> LHsBinds Name
-            -> TcM ([LHsBinds TcId], [TcId])
+            -> TcM (LHsBinds TcId, [TcId])
 
 -- Typechecks a single bunch of bindings all together, 
 -- and generalises them.  The bunch may be only part of a recursive
@@ -332,10 +338,10 @@ tcPolyBinds top_lvl sig_fn prag_fn rec_group rec_tc binds
     do  { extendLIEs lie_req
         ; let exports = zipWith mk_export mono_bind_infos zonked_mono_tys
               mk_export (name, Nothing,  mono_id) mono_ty = ([], mkLocalId name mono_ty, mono_id, [])
-              mk_export (name, Just sig, mono_id) mono_ty = ([], sig_id sig,             mono_id, [])
+              mk_export (_,    Just sig, mono_id) _       = ([], sig_id sig,             mono_id, [])
                         -- ToDo: prags for unlifted bindings
 
-        ; return ( [unitBag $ L loc $ AbsBinds [] [] exports binds'],
+        ; return ( unitBag $ L loc $ AbsBinds [] [] exports binds',
                    [poly_id | (_, poly_id, _, _) <- exports]) } -- Guaranteed zonked
 
     else do     -- The normal lifted case: GENERALISE
@@ -356,7 +362,7 @@ tcPolyBinds top_lvl sig_fn prag_fn rec_group rec_tc binds
                                     dict_vars exports
                                     (dict_binds `unionBags` binds')
 
-  ; return ([unitBag abs_bind], poly_ids)       -- poly_ids are guaranteed zonked by mkExport
+  ; return (unitBag abs_bind, poly_ids)       -- poly_ids are guaranteed zonked by mkExport
   } }
 
 
@@ -391,7 +397,7 @@ mkExport top_lvl prag_fn inferred_tvs dict_tys (poly_name, mb_sig, mono_id)
     mk_poly_id warn Nothing    = do { poly_ty' <- zonkTcType poly_ty
                                     ; missingSigWarn warn poly_name poly_ty'
                                     ; return (inferred_tvs, mkLocalId poly_name poly_ty') }
-    mk_poly_id warn (Just sig) = do { tvs <- mapM zonk_tv (sig_tvs sig)
+    mk_poly_id _    (Just sig) = do { tvs <- mapM zonk_tv (sig_tvs sig)
                                     ; return (tvs,  sig_id sig) }
 
     zonk_tv tv = do { ty <- zonkTcTyVar tv; return (tcGetTyVar "mkExport" ty) }
@@ -413,14 +419,16 @@ tcPrags poly_id prags = mapM (wrapLocM tc_prag) prags
     tc_prag prag = addErrCtxt (pragSigCtxt prag) $ 
                    tcPrag poly_id prag
 
+pragSigCtxt :: Sig Name -> SDoc
 pragSigCtxt prag = hang (ptext (sLit "In the pragma")) 2 (ppr prag)
 
 tcPrag :: TcId -> Sig Name -> TcM Prag
 -- Pre-condition: the poly_id is zonked
 -- Reason: required by tcSubExp
-tcPrag poly_id (SpecSig orig_name hs_ty inl) = tcSpecPrag poly_id hs_ty inl
-tcPrag poly_id (SpecInstSig hs_ty)           = tcSpecPrag poly_id hs_ty defaultInlineSpec
-tcPrag poly_id (InlineSig v inl)             = return (InlinePrag inl)
+tcPrag poly_id (SpecSig _ hs_ty inl) = tcSpecPrag poly_id hs_ty inl
+tcPrag poly_id (SpecInstSig hs_ty)   = tcSpecPrag poly_id hs_ty defaultInlineSpec
+tcPrag _       (InlineSig _ inl)     = return (InlinePrag inl)
+tcPrag _       sig                  = pprPanic "tcPrag" (ppr sig)
 
 
 tcSpecPrag :: TcId -> LHsType Name -> InlineSpec -> TcM Prag
@@ -436,10 +444,12 @@ tcSpecPrag poly_id hs_ty inl
 -- If typechecking the binds fails, then return with each
 -- signature-less binder given type (forall a.a), to minimise 
 -- subsequent error messages
+recoveryCode :: [Name] -> (Name -> Maybe [Name])
+             -> TcM (LHsBinds TcId, [Id])
 recoveryCode binder_names sig_fn
   = do  { traceTc (text "tcBindsWithSigs: error recovery" <+> ppr binder_names)
         ; poly_ids <- mapM mk_dummy binder_names
-        ; return ([], poly_ids) }
+        ; return (emptyBag, poly_ids) }
   where
     mk_dummy name 
         | isJust (sig_fn name) = tcLookupId name        -- Had signature; look it up
@@ -465,6 +475,12 @@ checkStrictBinds top_lvl rec_group mbind mono_tys infos
                   (strictBindErr "Recursive" unlifted mbind)
         ; checkTc (isSingletonBag mbind)
                   (strictBindErr "Multiple" unlifted mbind) 
+        -- This should be a checkTc, not a warnTc, but as of GHC 6.11
+        -- the versions of alex and happy available have non-conforming
+        -- templates, so the GHC build fails if it's an error:
+        ; warnUnlifted <- doptM Opt_WarnLazyUnliftedBindings
+        ; warnTc (warnUnlifted && not bang_pat)
+                 (unliftedMustBeBang mbind)
         ; mapM_ check_sig infos
         ; return True }
   | otherwise
@@ -474,8 +490,15 @@ checkStrictBinds top_lvl rec_group mbind mono_tys infos
     bang_pat = anyBag (isBangHsBind . unLoc) mbind
     check_sig (_, Just sig, _) = checkTc (null (sig_tvs sig) && null (sig_theta sig))
                                          (badStrictSig unlifted sig)
-    check_sig other            = return ()
+    check_sig _                = return ()
+
+unliftedMustBeBang :: LHsBindsLR Var Var -> SDoc
+unliftedMustBeBang mbind
+  = hang (text "Bindings containing unlifted types must use an outermost bang pattern:")
+         4 (pprLHsBinds mbind)
+ $$ text "*** This will be an error in GHC 6.14! Fix your code now!"
 
+strictBindErr :: String -> Bool -> LHsBindsLR Var Var -> SDoc
 strictBindErr flavour unlifted mbind
   = hang (text flavour <+> msg <+> ptext (sLit "aren't allowed:")) 
          4 (pprLHsBinds mbind)
@@ -483,6 +506,7 @@ strictBindErr flavour unlifted mbind
     msg | unlifted  = ptext (sLit "bindings for unlifted types")
         | otherwise = ptext (sLit "bang-pattern bindings")
 
+badStrictSig :: Bool -> TcSigInfo -> SDoc
 badStrictSig unlifted sig
   = hang (ptext (sLit "Illegal polymorphic signature in") <+> msg)
          4 (ppr sig)
@@ -539,9 +563,9 @@ tcMonoBinds [L b_loc (FunBind { fun_id = L nm_loc name, fun_infix = inf,
                   [(name, Nothing, mono_id)]) }
 
 tcMonoBinds [L b_loc (FunBind { fun_id = L nm_loc name, fun_infix = inf, 
-                                fun_matches = matches, bind_fvs = fvs })]
+                                fun_matches = matches })]
             sig_fn              -- Single function binding
-            non_rec     
+            _
   | Just scoped_tvs <- sig_fn name      -- ...with a type signature
   =     -- When we have a single function binding, with a type signature
         -- we can (a) use genuine, rigid skolem constants for the type variables
@@ -557,8 +581,14 @@ tcMonoBinds [L b_loc (FunBind { fun_id = L nm_loc name, fun_infix = inf,
                         -- Note that the scoped_tvs and the (sig_tvs sig) 
                         -- may have different Names. That's quite ok.
 
+       ; traceTc (text "tcMoonBinds" <+> ppr scoped_tvs $$ ppr tc_sig)
         ; (co_fn, matches') <- tcExtendTyVarEnv2 rhs_tvs $
                                tcMatchesFun mono_name inf matches mono_ty
+            -- Note that "mono_ty" might actually be a polymorphic type,
+            -- if the original function had a signature like
+            --    forall a. Eq a => forall b. Ord b => ....
+            -- But that's ok: tcMatchesFun can deal with that
+            -- It happens, too!  See Note [Polymorphic methods] in TcClassDcl.
 
         ; let fun_bind' = FunBind { fun_id = L nm_loc mono_id, 
                                     fun_infix = inf, fun_matches = matches',
@@ -567,7 +597,7 @@ tcMonoBinds [L b_loc (FunBind { fun_id = L nm_loc name, fun_infix = inf,
         ; return (unitBag (L b_loc fun_bind'),
                   [(name, Just tc_sig, mono_id)]) }
 
-tcMonoBinds binds sig_fn non_rec
+tcMonoBinds binds sig_fn _
   = do  { tc_binds <- mapM (wrapLocM (tcLhs sig_fn)) binds
 
         -- Bring the monomorphic Ids, into scope for the RHSs
@@ -623,17 +653,17 @@ tcLhs sig_fn (FunBind { fun_id = L nm_loc name, fun_infix = inf, fun_matches = m
     mk_mono_ty (Just sig) = return (sig_tau sig)
     mk_mono_ty Nothing    = newFlexiTyVarTy argTypeKind
 
-tcLhs sig_fn bind@(PatBind { pat_lhs = pat, pat_rhs = grhss })
+tcLhs sig_fn (PatBind { pat_lhs = pat, pat_rhs = grhss })
   = do  { mb_sigs <- mapM (tcInstSig_maybe sig_fn) names
         ; mono_pat_binds <- doptM Opt_MonoPatBinds
-                -- With -fmono-pat-binds, we do no generalisation of pattern bindings
+                -- With -XMonoPatBinds, we do no generalisation of pattern bindings
                 -- But the signature can still be polymoprhic!
                 --      data T = MkT (forall a. a->a)
                 --      x :: forall a. a->a
                 --      MkT x = <rhs>
                 -- The function get_sig_ty decides whether the pattern-bound variables
-                -- should have exactly the type in the type signature (-fmono-pat-binds), 
-                -- or the instantiated version (-fmono-pat-binds)
+                -- should have exactly the type in the type signature (-XMonoPatBinds), 
+                -- or the instantiated version (-XMonoPatBinds)
 
         ; let nm_sig_prs  = names `zip` mb_sigs
               get_sig_ty | mono_pat_binds = idType . sig_id
@@ -659,7 +689,7 @@ tcLhs sig_fn bind@(PatBind { pat_lhs = pat, pat_rhs = grhss })
     names = collectPatBinders pat
 
 
-tcLhs sig_fn other_bind = pprPanic "tcLhs" (ppr other_bind)
+tcLhs _ other_bind = pprPanic "tcLhs" (ppr other_bind)
         -- AbsBind, VarBind impossible
 
 -------------------
@@ -675,7 +705,7 @@ tcRhs (TcFunBind (_,_,mono_id) fun' inf matches)
                             bind_fvs = placeHolderNames, fun_co_fn = co_fn,
                             fun_tick = Nothing }) }
 
-tcRhs bind@(TcPatBind _ pat' grhss pat_ty)
+tcRhs (TcPatBind _ pat' grhss pat_ty)
   = do  { grhss' <- addErrCtxt (patMonoBindsCtxt pat' grhss) $
                     tcGRHSsPat grhss pat_ty
         ; return (PatBind { pat_lhs = pat', pat_rhs = grhss', pat_rhs_ty = pat_ty, 
@@ -706,7 +736,7 @@ generalise :: DynFlags -> TopLevelFlag
 -- The returned [TyVar] are all ready to quantify
 
 generalise dflags top_lvl bind_list sig_fn mono_infos lie_req
-  | isMonoGroup dflags bind_list
+  | isMonoGroup dflags top_lvl bind_list sigs
   = do  { extendLIEs lie_req
         ; return ([], [], emptyBag) }
 
@@ -775,8 +805,9 @@ might not otherwise be related.  This is a rather subtle issue.
 \begin{code}
 unifyCtxts :: [TcSigInfo] -> TcM [Inst]
 -- Post-condition: the returned Insts are full zonked
+unifyCtxts [] = panic "unifyCtxts []"
 unifyCtxts (sig1 : sigs)        -- Argument is always non-empty
-  = do  { mapM unify_ctxt sigs
+  = do  { mapM_ unify_ctxt sigs
         ; theta <- zonkTcThetaType (sig_theta sig1)
         ; newDictBndrs (sig_loc sig1) theta }
   where
@@ -793,7 +824,7 @@ unifyCtxts (sig1 : sigs)        -- Argument is always non-empty
                -- where F is a type function and (F a ~ [a])
                -- Then unification might succeed with a coercion.  But it's much
                -- much simpler to require that such signatures have identical contexts
-               checkTc (all isIdentityCoercion cois)
+               checkTc (all isIdentityCoI cois)
                        (ptext (sLit "Mutually dependent functions have syntactically distinct contexts"))
              }
 
@@ -835,7 +866,7 @@ checkDistinctTyVars :: [TcTyVar] -> TcM [TcTyVar]
 
 checkDistinctTyVars sig_tvs
   = do  { zonked_tvs <- mapM zonkSigTyVar sig_tvs
-        ; foldlM check_dup emptyVarEnv (sig_tvs `zip` zonked_tvs)
+        ; foldlM_ check_dup emptyVarEnv (sig_tvs `zip` zonked_tvs)
         ; return zonked_tvs }
   where
     check_dup :: TyVarEnv TcTyVar -> (TcTyVar, TcTyVar) -> TcM (TyVarEnv TcTyVar)
@@ -855,7 +886,6 @@ checkDistinctTyVars sig_tvs
                          <+> ptext (sLit "is unified with another quantified type variable") 
                          <+> quotes (ppr tidy_tv2)
             ; failWithTcM (env2, msg) }
-       where
 \end{code}
 
 
@@ -1026,8 +1056,10 @@ mkTcSigFun :: [LSig Name] -> TcSigFun
 -- Precondition: no duplicates
 mkTcSigFun sigs = lookupNameEnv env
   where
-    env = mkNameEnv [(name, hsExplicitTvs lhs_ty)
-                    | L span (TypeSig (L _ name) lhs_ty) <- sigs]
+    env = mkNameEnv (mapCatMaybes mk_pair sigs)
+    mk_pair (L _ (TypeSig (L _ name) lhs_ty)) = Just (name, hsExplicitTvs lhs_ty)
+    mk_pair (L _ (IdSig id))                  = Just (idName id, [])
+    mk_pair _                                 = Nothing    
         -- The scoped names are the ones explicitly mentioned
         -- in the HsForAll.  (There may be more in sigma_ty, because
         -- of nested type synonyms.  See Note [More instantiated than scoped].)
@@ -1081,6 +1113,9 @@ tcTySig (L span (TypeSig (L _ name) ty))
   = setSrcSpan span             $
     do  { sigma_ty <- tcHsSigType (FunSigCtxt name) ty
         ; return (mkLocalId name sigma_ty) }
+tcTySig (L _ (IdSig id))
+  = return id
+tcTySig s = pprPanic "tcTySig" (ppr s)
 
 -------------------
 tcInstSig_maybe :: TcSigFun -> Name -> TcM (Maybe TcSigInfo)
@@ -1088,10 +1123,10 @@ tcInstSig_maybe :: TcSigFun -> Name -> TcM (Maybe TcSigInfo)
 -- this signature is part of a multi-signature group
 tcInstSig_maybe sig_fn name 
   = case sig_fn name of
-        Nothing  -> return Nothing
-        Just scoped_tvs -> do   { tc_sig <- tcInstSig False name
-                                ; return (Just tc_sig) }
-        -- NB: the scoped_tvs may be non-empty, but we can 
+        Nothing -> return Nothing
+        Just _scoped_tvs -> do   { tc_sig <- tcInstSig False name
+                                 ; return (Just tc_sig) }
+        -- NB: the _scoped_tvs may be non-empty, but we can 
         -- just ignore them.  See Note [Scoped tyvars].
 
 tcInstSig :: Bool -> Name -> TcM TcSigInfo
@@ -1116,22 +1151,23 @@ tcInstSig :: Bool -> Name -> TcM TcSigInfo
 tcInstSig use_skols name
   = do  { poly_id <- tcLookupId name    -- Cannot fail; the poly ids are put into 
                                         -- scope when starting the binding group
-        ; let skol_info = SigSkol (FunSigCtxt name)
-              inst_tyvars = tcInstSigTyVars use_skols skol_info
-        ; (tvs, theta, tau) <- tcInstType inst_tyvars (idType poly_id)
+       ; let skol_info = SigSkol (FunSigCtxt name)
+        ; (tvs, theta, tau) <- tcInstSigType use_skols skol_info (idType poly_id)
         ; loc <- getInstLoc (SigOrigin skol_info)
         ; return (TcSigInfo { sig_id = poly_id,
                               sig_tvs = tvs, sig_theta = theta, sig_tau = tau, 
                               sig_loc = loc }) }
 
 -------------------
-isMonoGroup :: DynFlags -> [LHsBind Name] -> Bool
+isMonoGroup :: DynFlags -> TopLevelFlag -> [LHsBind Name]
+            -> [TcSigInfo] ->  Bool
 -- No generalisation at all
-isMonoGroup dflags binds
-  = dopt Opt_MonoPatBinds dflags && any is_pat_bind binds
+isMonoGroup dflags top_lvl binds sigs
+  =  (dopt Opt_MonoPatBinds dflags && any is_pat_bind binds)
+  || (dopt Opt_MonoLocalBinds dflags && null sigs && not (isTopLevel top_lvl))
   where
     is_pat_bind (L _ (PatBind {})) = True
-    is_pat_bind other              = False
+    is_pat_bind _                  = False
 
 -------------------
 isRestrictedGroup :: DynFlags -> [LHsBind Name] -> TcSigFun -> Bool
@@ -1146,10 +1182,12 @@ isRestrictedGroup dflags binds sig_fn
     unrestricted (VarBind { var_id = v })                        = has_sig v
     unrestricted (FunBind { fun_id = v, fun_matches = matches }) = unrestricted_match matches 
                                                                  || has_sig (unLoc v)
+    unrestricted (AbsBinds {})
+        = panic "isRestrictedGroup/unrestricted AbsBinds"
 
     unrestricted_match (MatchGroup (L _ (Match [] _ _) : _) _) = False
         -- No args => like a pattern binding
-    unrestricted_match other              = True
+    unrestricted_match _                                       = True
         -- Some args => a function binding
 \end{code}
 
@@ -1164,10 +1202,12 @@ isRestrictedGroup dflags binds sig_fn
 \begin{code}
 -- This one is called on LHS, when pat and grhss are both Name 
 -- and on RHS, when pat is TcId and grhss is still Name
+patMonoBindsCtxt :: OutputableBndr id => LPat id -> GRHSs Name -> SDoc
 patMonoBindsCtxt pat grhss
   = hang (ptext (sLit "In a pattern binding:")) 4 (pprPatBind pat grhss)
 
 -----------------------------------------------
+sigContextsCtxt :: TcSigInfo -> TcSigInfo -> SDoc
 sigContextsCtxt sig1 sig2
   = vcat [ptext (sLit "When matching the contexts of the signatures for"), 
           nest 2 (vcat [ppr id1 <+> dcolon <+> ppr (idType id1),
@@ -1179,20 +1219,24 @@ sigContextsCtxt sig1 sig2
 
 
 -----------------------------------------------
+unboxedTupleErr :: Name -> Type -> SDoc
 unboxedTupleErr name ty
   = hang (ptext (sLit "Illegal binding of unboxed tuple"))
          4 (ppr name <+> dcolon <+> ppr ty)
 
 -----------------------------------------------
+restrictedBindCtxtErr :: [Name] -> SDoc
 restrictedBindCtxtErr binder_names
   = hang (ptext (sLit "Illegal overloaded type signature(s)"))
        4 (vcat [ptext (sLit "in a binding group for") <+> pprBinders binder_names,
                 ptext (sLit "that falls under the monomorphism restriction")])
 
+genCtxt :: [Name] -> SDoc
 genCtxt binder_names
   = ptext (sLit "When generalising the type(s) for") <+> pprBinders binder_names
 
-missingSigWarn False name ty = return ()
+missingSigWarn :: Bool -> Name -> Type -> TcM ()
+missingSigWarn False _    _  = return ()
 missingSigWarn True  name ty
   = do  { env0 <- tcInitTidyEnv
         ; let (env1, tidy_ty) = tidyOpenType env0 ty