[project @ 2005-03-01 21:40:40 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcBinds.lhs
index e323153..c4e1b92 100644 (file)
@@ -4,61 +4,57 @@
 \section[TcBinds]{TcBinds}
 
 \begin{code}
 \section[TcBinds]{TcBinds}
 
 \begin{code}
-module TcBinds ( tcBindsAndThen, tcTopBindsAndThen,
-                tcPragmaSigs, tcBindWithSigs ) where
+module TcBinds ( tcBindsAndThen, tcTopBinds, tcHsBootSigs, tcMonoBinds, tcSpecSigs ) where
 
 #include "HsVersions.h"
 
 
 #include "HsVersions.h"
 
-import {-# SOURCE #-} TcGRHSs ( tcGRHSsAndBinds )
-import {-# SOURCE #-} TcExpr  ( tcExpr )
+import {-# SOURCE #-} TcMatches ( tcGRHSsPat, tcMatchesFun )
+import {-# SOURCE #-} TcExpr  ( tcCheckSigma, tcCheckRho )
 
 
-import HsSyn           ( HsExpr(..), HsBinds(..), MonoBinds(..), Sig(..), InPat(..), StmtCtxt(..),
-                         collectMonoBinders, andMonoBindList, andMonoBinds
+import CmdLineOpts     ( DynFlag(Opt_MonomorphismRestriction) )
+import HsSyn           ( HsExpr(..), HsBind(..), LHsBinds, Sig(..),
+                         LSig, Match(..), HsBindGroup(..), IPBind(..), 
+                         HsType(..), hsLTyVarNames, isVanillaLSig,
+                         LPat, GRHSs, MatchGroup(..), emptyLHsBinds, isEmptyLHsBinds,
+                         collectHsBindBinders, collectPatBinders, pprPatBind
                        )
                        )
-import RnHsSyn         ( RenamedHsBinds, RenamedSig, RenamedMonoBinds )
-import TcHsSyn         ( TcHsBinds, TcMonoBinds,
-                         TcIdOcc(..), TcIdBndr, 
-                         tcIdType, zonkId
+import TcHsSyn         ( TcId, TcDictBinds, zonkId, mkHsLet )
+
+import TcRnMonad
+import Inst            ( InstOrigin(..), newDictsAtLoc, newIPDict, instToId )
+import TcEnv           ( tcExtendIdEnv, tcExtendIdEnv2, tcExtendTyVarEnv2, 
+                         newLocalName, tcLookupLocalIds, pprBinders,
+                         tcGetGlobalTyVars )
+import TcUnify         ( Expected(..), tcInfer, unifyTheta, 
+                         bleatEscapedTvs, sigCtxt )
+import TcSimplify      ( tcSimplifyInfer, tcSimplifyInferCheck, tcSimplifyRestricted, 
+                         tcSimplifyToDicts, tcSimplifyIPs )
+import TcHsType                ( tcHsSigType, UserTypeCtxt(..), tcAddLetBoundTyVars,
+                         TcSigInfo(..), TcSigFun, lookupSig
                        )
                        )
-
-import TcMonad
-import Inst            ( Inst, LIE, emptyLIE, mkLIE, plusLIE, plusLIEs, InstOrigin(..),
-                         newDicts, tyVarsOfInst, instToId,
-                       )
-import TcEnv           ( tcExtendLocalValEnv, tcExtendEnvWithPat, 
-                         tcLookupLocalValueOK,
-                         newSpecPragmaId,
-                         tcGetGlobalTyVars, tcExtendGlobalTyVars
-                       )
-import TcMatches       ( tcMatchesFun )
-import TcSimplify      ( tcSimplify, tcSimplifyAndCheck )
-import TcMonoType      ( tcHsTcType, checkSigTyVars,
-                         TcSigInfo(..), tcTySig, maybeSig, sigCtxt
-                       )
-import TcPat           ( tcVarPat, tcPat )
+import TcPat           ( tcPat, PatCtxt(..) )
 import TcSimplify      ( bindInstsOfLocalFuns )
 import TcSimplify      ( bindInstsOfLocalFuns )
-import TcType          ( TcType, TcThetaType,
-                         TcTyVar,
-                         newTyVarTy, newTcTyVar, tcInstTcType,
-                         zonkTcType, zonkTcTypes, zonkTcThetaType )
-import TcUnify         ( unifyTauTy, unifyTauTyLists )
-
-import Id              ( mkUserId )
-import Var             ( idType, idName, setIdInfo )
-import IdInfo          ( IdInfo, noIdInfo, setInlinePragInfo, InlinePragInfo(..) )
+import TcMType         ( newTyFlexiVarTy, zonkQuantifiedTyVar, 
+                         tcInstSigType, zonkTcTypes, zonkTcTyVar )
+import TcType          ( TcTyVar, SkolemInfo(SigSkol), 
+                         TcTauType, TcSigmaType, 
+                         mkTyVarTy, mkForAllTys, mkFunTys, tyVarsOfType, 
+                         mkForAllTy, isUnLiftedType, tcGetTyVar, 
+                         mkTyVarTys, tidyOpenTyVar, tidyOpenType )
+import Kind            ( argTypeKind )
+import VarEnv          ( TyVarEnv, emptyVarEnv, lookupVarEnv, extendVarEnv, emptyTidyEnv ) 
+import TysPrim         ( alphaTyVar )
+import Id              ( mkLocalId, mkSpecPragmaId, setInlinePragma )
+import Var             ( idType, idName )
 import Name            ( Name )
 import Name            ( Name )
-import Type            ( mkTyVarTy, tyVarsOfTypes,
-                         splitSigmaTy, mkForAllTys, mkFunTys, getTyVar, 
-                         mkDictTy, splitRhoTy, mkForAllTy, isUnLiftedType, 
-                         isUnboxedType, openTypeKind, 
-                         unboxedTypeKind, boxedTypeKind
-                       )
-import Var             ( TyVar, tyVarKind )
+import NameSet
 import VarSet
 import VarSet
+import SrcLoc          ( Located(..), unLoc, noLoc, getLoc )
 import Bag
 import Util            ( isIn )
 import Bag
 import Util            ( isIn )
-import BasicTypes      ( TopLevelFlag(..), RecFlag(..) )
-import SrcLoc           ( SrcLoc )
+import BasicTypes      ( TopLevelFlag(..), RecFlag(..), isNonRec, isRec, 
+                         isNotTopLevel, isAlwaysActive )
+import FiniteMap       ( listToFM, lookupFM )
 import Outputable
 \end{code}
 
 import Outputable
 \end{code}
 
@@ -95,119 +91,143 @@ At the top-level the LIE is sure to contain nothing but constant
 dictionaries, which we resolve at the module level.
 
 \begin{code}
 dictionaries, which we resolve at the module level.
 
 \begin{code}
-tcTopBindsAndThen, tcBindsAndThen
-       :: (RecFlag -> TcMonoBinds s -> thing -> thing)         -- Combinator
-       -> RenamedHsBinds
-       -> TcM s (thing, LIE s)
-       -> TcM s (thing, LIE s)
+tcTopBinds :: [HsBindGroup Name] -> TcM (LHsBinds TcId, TcLclEnv)
+       -- Note: returning the TcLclEnv is more than we really
+       --       want.  The bit we care about is the local bindings
+       --       and the free type variables thereof
+tcTopBinds binds
+  = tc_binds_and_then TopLevel glue binds $
+           do  { env <- getLclEnv
+               ; return (emptyLHsBinds, env) }
+  where
+       -- The top level bindings are flattened into a giant 
+       -- implicitly-mutually-recursive MonoBinds
+    glue (HsBindGroup binds1 _ _) (binds2, env) = (binds1 `unionBags` binds2, env)
+    glue (HsIPBinds _)                   _             = panic "Top-level HsIpBinds"
+       -- Can't have a HsIPBinds at top level
+
+tcHsBootSigs :: [HsBindGroup Name] -> TcM (LHsBinds TcId, TcLclEnv)
+-- A hs-boot file has only one BindGroup, and it only has type
+-- signatures in it.  The renamer checked all this
+tcHsBootSigs [HsBindGroup _ sigs _]
+  = do { ids <- mapM (addLocM tc_sig) (filter isVanillaLSig sigs)
+       ; tcExtendIdEnv ids $ do 
+       { env <- getLclEnv
+       ; return (emptyLHsBinds, env) }}
+  where
+    tc_sig (Sig (L _ name) ty)
+      = do { sigma_ty <- tcHsSigType (FunSigCtxt name) ty
+          ; return (mkLocalId name sigma_ty) }
 
 
-tcTopBindsAndThen = tc_binds_and_then TopLevel
-tcBindsAndThen    = tc_binds_and_then NotTopLevel
+tcBindsAndThen
+       :: (HsBindGroup TcId -> thing -> thing)         -- Combinator
+       -> [HsBindGroup Name]
+       -> TcM thing
+       -> TcM thing
 
 
-tc_binds_and_then top_lvl combiner EmptyBinds do_next
-  = do_next
-tc_binds_and_then top_lvl combiner (MonoBind EmptyMonoBinds sigs is_rec) do_next
+tcBindsAndThen = tc_binds_and_then NotTopLevel
+
+tc_binds_and_then top_lvl combiner [] do_next
   = do_next
   = do_next
+tc_binds_and_then top_lvl combiner (group : groups) do_next
+  = tc_bind_and_then top_lvl combiner group $ 
+    tc_binds_and_then top_lvl combiner groups do_next
 
 
-tc_binds_and_then top_lvl combiner (ThenBinds b1 b2) do_next
-  = tc_binds_and_then top_lvl combiner b1      $
-    tc_binds_and_then top_lvl combiner b2      $
-    do_next
+tc_bind_and_then top_lvl combiner (HsIPBinds binds) do_next
+  = getLIE do_next                             `thenM` \ (result, expr_lie) ->
+    mapAndUnzipM (wrapLocSndM tc_ip_bind) binds        `thenM` \ (avail_ips, binds') ->
 
 
-tc_binds_and_then top_lvl combiner (MonoBind bind sigs is_rec) do_next
-  = fixTc (\ ~(prag_info_fn, _, _) ->
-       -- This is the usual prag_info fix; the PragmaInfo field of an Id
-       -- is not inspected till ages later in the compiler, so there
-       -- should be no black-hole problems here.
+       -- If the binding binds ?x = E, we  must now 
+       -- discharge any ?x constraints in expr_lie
+    tcSimplifyIPs avail_ips expr_lie   `thenM` \ dict_binds ->
 
 
-       -- TYPECHECK THE SIGNATURES
-      mapTc tcTySig [sig | sig@(Sig name _ _) <- sigs] `thenTc` \ tc_ty_sigs ->
-  
-      tcBindWithSigs top_lvl bind 
-                    tc_ty_sigs is_rec prag_info_fn     `thenTc` \ (poly_binds, poly_lie, poly_ids) ->
-  
-         -- Extend the environment to bind the new polymorphic Ids
-      tcExtendLocalValEnv (map idName poly_ids) poly_ids $
+    returnM (combiner (HsIPBinds binds') $
+            combiner (HsBindGroup dict_binds [] Recursive) result)
+  where
+       -- I wonder if we should do these one at at time
+       -- Consider     ?x = 4
+       --              ?y = ?x + 1
+    tc_ip_bind (IPBind ip expr)
+      = newTyFlexiVarTy argTypeKind            `thenM` \ ty ->
+       newIPDict (IPBindOrigin ip) ip ty       `thenM` \ (ip', ip_inst) ->
+       tcCheckRho expr ty                      `thenM` \ expr' ->
+       returnM (ip_inst, (IPBind ip' expr'))
+
+tc_bind_and_then top_lvl combiner (HsBindGroup binds sigs is_rec) do_next
+  | isEmptyLHsBinds binds 
+  = do_next
+  | otherwise
+ =      -- BRING ANY SCOPED TYPE VARIABLES INTO SCOPE
+          -- Notice that they scope over 
+          --       a) the type signatures in the binding group
+          --       b) the bindings in the group
+          --       c) the scope of the binding group (the "in" part)
+      tcAddLetBoundTyVars binds  $
+      case top_lvl of
+          TopLevel       -- For the top level don't bother will 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
+               -> tcBindWithSigs top_lvl binds sigs is_rec     `thenM` \ (poly_binds, poly_ids) ->
+                  tc_body poly_ids                             `thenM` \ (prag_binds, thing) ->
+                  returnM (combiner (HsBindGroup
+                                       (poly_binds `unionBags` prag_binds)
+                                        [] -- no sigs
+                                        Recursive)
+                                     thing)
+          NotTopLevel   -- For nested bindings we must do the bindInstsOfLocalFuns thing.
+               | not (isRec is_rec)            -- Non-recursive group
+               ->      -- We want to keep non-recursive things non-recursive
+                        -- so that we desugar unlifted bindings correctly
+                   tcBindWithSigs top_lvl binds sigs is_rec    `thenM` \ (poly_binds, poly_ids) ->
+                    getLIE (tc_body poly_ids)                  `thenM` \ ((prag_binds, thing), lie) ->
+                             -- Create specialisations of functions bound here
+                   bindInstsOfLocalFuns lie poly_ids `thenM` \ lie_binds ->
+                   returnM (
+                       combiner (HsBindGroup poly_binds [] NonRecursive) $
+                       combiner (HsBindGroup prag_binds [] NonRecursive) $
+                       combiner (HsBindGroup lie_binds  [] Recursive)    $
+                        -- NB: the binds returned by tcSimplify and
+                        -- bindInstsOfLocalFuns aren't guaranteed in
+                        -- dependency order (though we could change that);
+                        -- hence the Recursive marker.
+                        thing)
+
+               | otherwise
+               ->      -- NB: polymorphic recursion means that a function
+                       -- may use an instance of itself, we must look at the LIE arising
+                       -- from the function's own right hand side.  Hence the getLIE
+                       -- encloses the tcBindWithSigs.
+
+                  getLIE (
+                     tcBindWithSigs top_lvl binds sigs is_rec  `thenM` \ (poly_binds, poly_ids) ->
+                     tc_body poly_ids                          `thenM` \ (prag_binds, thing) ->
+                     returnM (poly_ids, poly_binds `unionBags` prag_binds, thing)
+                   )   `thenM` \ ((poly_ids, extra_binds, thing), lie) ->
+                  bindInstsOfLocalFuns lie poly_ids    `thenM` \ lie_binds ->
+
+                   returnM (combiner (HsBindGroup
+                                        (extra_binds `unionBags` lie_binds)
+                                        [] Recursive) thing
+                  )
+  where
+    tc_body poly_ids   -- Type check the pragmas and "thing inside"
+      =   -- Extend the environment to bind the new polymorphic Ids
+         tcExtendIdEnv poly_ids        $
   
          -- Build bindings and IdInfos corresponding to user pragmas
   
          -- Build bindings and IdInfos corresponding to user pragmas
-      tcPragmaSigs sigs                `thenTc` \ (prag_info_fn, prag_binds, prag_lie) ->
-
-       -- Now do whatever happens next, in the augmented envt
-      do_next                  `thenTc` \ (thing, thing_lie) ->
-
-       -- Create specialisations of functions bound here
-       -- We want to keep non-recursive things non-recursive
-       -- so that we desugar unboxed bindings correctly
-      case (top_lvl, is_rec) of
-
-               -- For the top level don't bother will 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
-       (TopLevel, _)
-               -> returnTc (prag_info_fn, 
-                            combiner Recursive (poly_binds `andMonoBinds` prag_binds) thing,
-                            thing_lie `plusLIE` prag_lie `plusLIE` poly_lie)
-
-       (NotTopLevel, NonRecursive) 
-               -> bindInstsOfLocalFuns 
-                               (thing_lie `plusLIE` prag_lie)
-                               poly_ids                        `thenTc` \ (thing_lie', lie_binds) ->
-
-                  returnTc (
-                       prag_info_fn,
-                       combiner NonRecursive poly_binds $
-                       combiner NonRecursive prag_binds $
-                       combiner Recursive lie_binds  $
-                               -- NB: the binds returned by tcSimplify and bindInstsOfLocalFuns
-                               -- aren't guaranteed in dependency order (though we could change
-                               -- that); hence the Recursive marker.
-                       thing,
-
-                       thing_lie' `plusLIE` poly_lie
-                  )
+         tcSpecSigs sigs               `thenM` \ prag_binds ->
 
 
-       (NotTopLevel, Recursive)
-               -> bindInstsOfLocalFuns 
-                               (thing_lie `plusLIE` poly_lie `plusLIE` prag_lie) 
-                               poly_ids                        `thenTc` \ (final_lie, lie_binds) ->
-
-                  returnTc (
-                       prag_info_fn,
-                       combiner Recursive (
-                               poly_binds `andMonoBinds`
-                               lie_binds  `andMonoBinds`
-                               prag_binds) thing,
-                       final_lie
-                 )
-    )                                          `thenTc` \ (_, thing, lie) ->
-    returnTc (thing, lie)
-\end{code}
+         -- Now do whatever happens next, in the augmented envt
+         do_next                       `thenM` \ thing ->
 
 
-An aside.  The original version of @tcBindsAndThen@ which lacks a
-combiner function, appears below.  Though it is perfectly well
-behaved, it cannot be typed by Haskell, because the recursive call is
-at a different type to the definition itself.  There aren't too many
-examples of this, which is why I thought it worth preserving! [SLPJ]
-
-\begin{pseudocode}
-% tcBindsAndThen
-%      :: RenamedHsBinds
-%      -> TcM s (thing, LIE s, thing_ty))
-%      -> TcM s ((TcHsBinds s, thing), LIE s, thing_ty)
-% 
-% tcBindsAndThen EmptyBinds do_next
-%   = do_next          `thenTc` \ (thing, lie, thing_ty) ->
-%     returnTc ((EmptyBinds, thing), lie, thing_ty)
-% 
-% tcBindsAndThen (ThenBinds binds1 binds2) do_next
-%   = tcBindsAndThen binds1 (tcBindsAndThen binds2 do_next)
-%      `thenTc` \ ((binds1', (binds2', thing')), lie1, thing_ty) ->
-% 
-%     returnTc ((binds1' `ThenBinds` binds2', thing'), lie1, thing_ty)
-% 
-% tcBindsAndThen (MonoBind bind sigs is_rec) do_next
-%   = tcBindAndThen bind sigs do_next
-\end{pseudocode}
+         returnM (prag_binds, thing)
+\end{code}
 
 
 %************************************************************************
 
 
 %************************************************************************
@@ -227,185 +247,138 @@ so all the clever stuff is in here.
   as the Name in the tc_ty_sig
 
 \begin{code}
   as the Name in the tc_ty_sig
 
 \begin{code}
-tcBindWithSigs 
-       :: TopLevelFlag
-       -> RenamedMonoBinds
-       -> [TcSigInfo s]
-       -> RecFlag
-       -> (Name -> IdInfo)
-       -> TcM s (TcMonoBinds s, LIE s, [TcIdBndr s])
-
-tcBindWithSigs top_lvl mbind tc_ty_sigs is_rec prag_info_fn
-  = recoverTc (
-       -- If typechecking the binds fails, then return with each
-       -- signature-less binder given type (forall a.a), to minimise subsequent
-       -- error messages
-       newTcTyVar boxedTypeKind                `thenNF_Tc` \ alpha_tv ->
-       let
-         forall_a_a    = mkForAllTy alpha_tv (mkTyVarTy alpha_tv)
-          binder_names  = map fst (bagToList (collectMonoBinders mbind))
-         poly_ids      = map mk_dummy binder_names
-         mk_dummy name = case maybeSig tc_ty_sigs name of
-                           Just (TySigInfo _ poly_id _ _ _ _ _ _) -> poly_id   -- Signature
-                           Nothing -> mkUserId name forall_a_a                 -- No signature
-       in
-       returnTc (EmptyMonoBinds, emptyLIE, poly_ids)
-    ) $
-
-       -- TYPECHECK THE BINDINGS
-    tcMonoBinds mbind tc_ty_sigs is_rec        `thenTc` \ (mbind', lie_req, binder_names, mono_ids) ->
-
-    let
-       mono_id_tys = map idType mono_ids
-    in
-
-       -- CHECK THAT THE SIGNATURES MATCH
-       -- (must do this before getTyVarsToGen)
-    checkSigMatch tc_ty_sigs                           `thenTc` \ (sig_theta, lie_avail) ->    
-
-       -- COMPUTE VARIABLES OVER WHICH TO QUANTIFY, namely tyvars_to_gen
-       -- The tyvars_not_to_gen are free in the environment, and hence
-       -- candidates for generalisation, but sometimes the monomorphism
-       -- restriction means we can't generalise them nevertheless
-    getTyVarsToGen is_unrestricted mono_id_tys lie_req `thenNF_Tc` \ (tyvars_not_to_gen, tyvars_to_gen) ->
-
-       -- DEAL WITH TYPE VARIABLE KINDS
-       -- **** This step can do unification => keep other zonking after this ****
-    mapTc defaultUncommittedTyVar (varSetElems tyvars_to_gen)  `thenTc` \ real_tyvars_to_gen_list ->
-    let
-       real_tyvars_to_gen = mkVarSet real_tyvars_to_gen_list
-               -- It's important that the final list 
-               -- (real_tyvars_to_gen and real_tyvars_to_gen_list) is fully
-               -- zonked, *including boxity*, because they'll be included in the forall types of
-               -- the polymorphic Ids, and instances of these Ids will be generated from them.
-               -- 
-               -- Also NB that tcSimplify takes zonked tyvars as its arg, hence we pass
-               -- real_tyvars_to_gen
-    in
-
-       -- SIMPLIFY THE LIE
-    tcExtendGlobalTyVars tyvars_not_to_gen (
-       if null real_tyvars_to_gen_list then
-               -- No polymorphism, so no need to simplify context
-           returnTc (lie_req, EmptyMonoBinds, [])
-       else
-       if null tc_ty_sigs then
-               -- No signatures, so just simplify the lie
-               -- NB: no signatures => no polymorphic recursion, so no
-               -- need to use lie_avail (which will be empty anyway)
-           tcSimplify (text "tcBinds1" <+> ppr binder_names)
-                      top_lvl real_tyvars_to_gen lie_req       `thenTc` \ (lie_free, dict_binds, lie_bound) ->
-           returnTc (lie_free, dict_binds, map instToId (bagToList lie_bound))
-
-       else
-           zonkTcThetaType sig_theta                   `thenNF_Tc` \ sig_theta' ->
-           newDicts SignatureOrigin sig_theta'         `thenNF_Tc` \ (dicts_sig, dict_ids) ->
-               -- It's important that sig_theta is zonked, because
-               -- dict_id is later used to form the type of the polymorphic thing,
-               -- and forall-types must be zonked so far as their bound variables
-               -- are concerned
-
-           let
-               -- The "givens" is the stuff available.  We get that from
-               -- the context of the type signature, BUT ALSO the lie_avail
-               -- so that polymorphic recursion works right (see comments at end of fn)
-               givens = dicts_sig `plusLIE` lie_avail
-           in
-
-               -- Check that the needed dicts can be expressed in
-               -- terms of the signature ones
-           tcAddErrCtxt  (bindSigsCtxt tysig_names) $
-           tcSimplifyAndCheck
-               (ptext SLIT("type signature for") <+> pprQuotedList binder_names)
-               real_tyvars_to_gen givens lie_req       `thenTc` \ (lie_free, dict_binds) ->
-
-           returnTc (lie_free, dict_binds, dict_ids)
-
-    )                                          `thenTc` \ (lie_free, dict_binds, dicts_bound) ->
-
-       -- GET THE FINAL MONO_ID_TYS
-    zonkTcTypes mono_id_tys                    `thenNF_Tc` \ zonked_mono_id_types ->
-
-
-       -- CHECK FOR BOGUS UNPOINTED BINDINGS
-    (if any isUnLiftedType zonked_mono_id_types then
-               -- Unlifted bindings must be non-recursive,
-               -- not top level, and non-polymorphic
-       checkTc (case top_lvl of {TopLevel -> False; NotTopLevel -> True})
-               (unliftedBindErr "Top-level" mbind)             `thenTc_`
-       checkTc (case is_rec of {Recursive -> False; NonRecursive -> True})
-               (unliftedBindErr "Recursive" mbind)             `thenTc_`
-       checkTc (null real_tyvars_to_gen_list)
-               (unliftedBindErr "Polymorphic" mbind)
-     else
-       returnTc ()
-    )                                                  `thenTc_`
-
-    ASSERT( not (any ((== unboxedTypeKind) . tyVarKind) real_tyvars_to_gen_list) )
-               -- The instCantBeGeneralised stuff in tcSimplify should have
-               -- already raised an error if we're trying to generalise an 
-               -- unboxed tyvar (NB: unboxed tyvars are always introduced 
-               -- along with a class constraint) and it's better done there 
-               -- because we have more precise origin information.
-               -- That's why we just use an ASSERT here.
-
-
-        -- BUILD THE POLYMORPHIC RESULT IDs
-    mapNF_Tc zonkId mono_ids           `thenNF_Tc` \ zonked_mono_ids ->
-    let
-       exports  = zipWith mk_export binder_names zonked_mono_ids
-       dict_tys = map tcIdType dicts_bound
-
-       mk_export binder_name zonked_mono_id
-         = (tyvars, 
-            TcId (setIdInfo poly_id (prag_info_fn binder_name)), 
-            TcId zonked_mono_id)
+tcBindWithSigs :: TopLevelFlag
+               -> LHsBinds Name
+               -> [LSig Name]
+               -> RecFlag
+               -> TcM (LHsBinds TcId, [TcId])
+       -- The returned TcIds are guaranteed zonked
+
+tcBindWithSigs top_lvl mbind sigs is_rec = do  
+  {    -- TYPECHECK THE SIGNATURES
+    tc_ty_sigs <- recoverM (returnM []) $
+                 tcTySigs (filter isVanillaLSig sigs)
+  ; let lookup_sig = lookupSig tc_ty_sigs
+
+       -- SET UP THE MAIN RECOVERY; take advantage of any type sigs
+  ; recoverM (recoveryCode mbind lookup_sig) $ do
+
+  { traceTc (ptext SLIT("--------------------------------------------------------"))
+  ; traceTc (ptext SLIT("Bindings for") <+> ppr (collectHsBindBinders mbind))
+
+       -- TYPECHECK THE BINDINGS
+  ; ((mbind', mono_bind_infos), lie_req) 
+       <- getLIE (tcMonoBinds mbind lookup_sig is_rec)
+
+       -- CHECK FOR UNLIFTED BINDINGS
+       -- These must be non-recursive etc, and are not generalised
+       -- They desugar to a case expression in the end
+  ; zonked_mono_tys <- zonkTcTypes (map getMonoType mono_bind_infos)
+  ; if any isUnLiftedType zonked_mono_tys then
+    do {       -- Unlifted bindings
+         checkUnliftedBinds top_lvl is_rec mbind
+       ; 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)
+
+       ; return ( unitBag $ noLoc $ AbsBinds [] [] exports emptyNameSet mbind',
+                  [poly_id | (_, poly_id, _) <- exports]) }    -- Guaranteed zonked
+
+    else do    -- The normal lifted case: GENERALISE
+  { is_unres <- isUnRestrictedGroup mbind tc_ty_sigs
+  ; (tyvars_to_gen, dict_binds, dict_ids)
+       <- setSrcSpan (getLoc (head (bagToList mbind)))     $
+               -- TODO: location a bit awkward, but the mbinds have been
+               --       dependency analysed and may no longer be adjacent
+          addErrCtxt (genCtxt (bndrNames mono_bind_infos)) $
+          generalise top_lvl is_unres mono_bind_infos tc_ty_sigs lie_req
+
+       -- FINALISE THE QUANTIFIED TYPE VARIABLES
+       -- The quantified type variables often include meta type variables
+       -- we want to freeze them into ordinary type variables, and
+       -- default their kind (e.g. from OpenTypeKind to TypeKind)
+  ; tyvars_to_gen' <- mappM zonkQuantifiedTyVar tyvars_to_gen
+
+       -- BUILD THE POLYMORPHIC RESULT IDs
+  ; let
+       exports  = map mk_export mono_bind_infos
+       poly_ids = [poly_id | (_, poly_id, _) <- exports]
+       dict_tys = map idType dict_ids
+
+       inlines = mkNameSet [ name
+                           | L _ (InlineSig True (L _ name) _) <- sigs]
+                       -- Any INLINE sig (regardless of phase control) 
+                       -- makes the RHS look small
+        inline_phases = listToFM [ (name, phase)
+                                | L _ (InlineSig _ (L _ name) phase) <- sigs, 
+                                  not (isAlwaysActive phase)]
+                       -- Set the IdInfo field to control the inline phase
+                       -- AlwaysActive is the default, so don't bother with them
+       add_inlines id = attachInlinePhase inline_phases id
+
+       mk_export (binder_name, mb_sig, mono_id)
+         = case mb_sig of
+             Just sig -> (sig_tvs sig, add_inlines (sig_id sig),  mono_id)
+             Nothing  -> (tyvars_to_gen', add_inlines new_poly_id, mono_id)
          where
          where
-           (tyvars, poly_id) = 
-               case maybeSig tc_ty_sigs binder_name of
-                 Just (TySigInfo _ sig_poly_id sig_tyvars _ _ _ _ _) -> 
-                       (sig_tyvars, sig_poly_id)
-                 Nothing -> (real_tyvars_to_gen_list, new_poly_id)
-
-           new_poly_id = mkUserId binder_name poly_ty
-           poly_ty = mkForAllTys real_tyvars_to_gen_list 
-                       $ mkFunTys dict_tys 
-                       $ idType (zonked_mono_id)
-               -- It's important to build a fully-zonked poly_ty, because
-               -- we'll slurp out its free type variables when extending the
-               -- local environment (tcExtendLocalValEnv); if it's not zonked
-               -- it appears to have free tyvars that aren't actually free 
-               -- at all.
-       
-       pat_binders :: [Name]
-       pat_binders = map fst $ bagToList $ collectMonoBinders $ 
-                     (justPatBindings mbind EmptyMonoBinds)
-    in
-       -- CHECK FOR UNBOXED BINDERS IN PATTERN BINDINGS
-    mapTc (\id -> checkTc (not (idName id `elem` pat_binders
-                               && isUnboxedType (idType id)))
-                         (unboxedPatBindErr id)) zonked_mono_ids
-                               `thenTc_`
-
-        -- BUILD RESULTS
-    returnTc (
-        AbsBinds real_tyvars_to_gen_list
-                 dicts_bound
-                 exports
-                 (dict_binds `andMonoBinds` mbind'),
-        lie_free,
-        [poly_id | (_, TcId poly_id, _) <- exports]
-    )
+           new_poly_id = mkLocalId binder_name poly_ty
+           poly_ty = mkForAllTys tyvars_to_gen'
+                   $ mkFunTys dict_tys 
+                   $ idType mono_id
+
+       -- ZONK THE poly_ids, because they are used to extend the type 
+       -- environment; see the invariant on TcEnv.tcExtendIdEnv 
+  ; zonked_poly_ids <- mappM zonkId poly_ids
+
+  ; traceTc (text "binding:" <+> ppr ((dict_ids, dict_binds),
+                                     exports, map idType zonked_poly_ids))
+
+  ; return (
+           unitBag $ noLoc $
+           AbsBinds tyvars_to_gen'
+                    dict_ids
+                    exports
+                    inlines
+                    (dict_binds `unionBags` mbind'),
+           zonked_poly_ids
+        )
+  } } }
+
+-- If typechecking the binds fails, then return with each
+-- signature-less binder given type (forall a.a), to minimise 
+-- subsequent error messages
+recoveryCode mbind lookup_sig
+  = do { traceTc (text "tcBindsWithSigs: error recovery" <+> ppr binder_names)
+       ; return (emptyLHsBinds, poly_ids) }
   where
   where
-    tysig_names     = [name | (TySigInfo name _ _ _ _ _ _ _) <- tc_ty_sigs]
-    is_unrestricted = isUnRestrictedGroup tysig_names mbind
-
-justPatBindings bind@(PatMonoBind _ _ _) binds = bind `andMonoBinds` binds
-justPatBindings (AndMonoBinds b1 b2) binds = 
-       justPatBindings b1 (justPatBindings b2 binds) 
-justPatBindings other_bind binds = binds
+    forall_a_a    = mkForAllTy alphaTyVar (mkTyVarTy alphaTyVar)
+    binder_names  = collectHsBindBinders mbind
+    poly_ids      = map mk_dummy binder_names
+    mk_dummy name = case lookup_sig name of
+                     Just sig -> sig_id sig                    -- Signature
+                     Nothing  -> mkLocalId name forall_a_a     -- No signature
+
+attachInlinePhase inline_phases bndr
+  = case lookupFM inline_phases (idName bndr) of
+       Just prag -> bndr `setInlinePragma` prag
+       Nothing   -> bndr
+
+-- Check that non-overloaded unlifted bindings are
+--     a) non-recursive,
+--     b) not top level, 
+--     c) not a multiple-binding group (more or less implied by (a))
+
+checkUnliftedBinds top_lvl is_rec mbind
+  = checkTc (isNotTopLevel top_lvl)
+           (unliftedBindErr "Top-level" mbind)         `thenM_`
+    checkTc (isNonRec is_rec)
+           (unliftedBindErr "Recursive" mbind)         `thenM_`
+    checkTc (isSingletonBag mbind)
+           (unliftedBindErr "Multiple" mbind)
 \end{code}
 
 \end{code}
 
+
 Polymorphic recursion
 ~~~~~~~~~~~~~~~~~~~~~
 The game plan for polymorphic recursion in the code above is 
 Polymorphic recursion
 ~~~~~~~~~~~~~~~~~~~~~
 The game plan for polymorphic recursion in the code above is 
@@ -464,11 +437,295 @@ is doing.
 
 %************************************************************************
 %*                                                                     *
 
 %************************************************************************
 %*                                                                     *
+\subsection{tcMonoBind}
+%*                                                                     *
+%************************************************************************
+
+@tcMonoBinds@ deals with a single @MonoBind@.  
+The signatures have been dealt with already.
+
+\begin{code}
+tcMonoBinds :: LHsBinds Name
+           -> TcSigFun -> RecFlag
+           -> TcM (LHsBinds TcId, [MonoBindInfo])
+
+tcMonoBinds binds lookup_sig is_rec
+  = do { tc_binds <- mapBagM (wrapLocM (tcLhs lookup_sig)) binds
+
+       -- Bring (a) the scoped type variables, and (b) the Ids, into scope for the RHSs
+       -- For (a) it's ok to bring them all into scope at once, even
+       -- though each type sig should scope only over its own RHS,
+       -- because the renamer has sorted all that out.
+       ; let mono_info  = getMonoBindInfo tc_binds
+             rhs_tvs    = [ (name, mkTyVarTy tv)
+                          | (_, Just sig, _) <- mono_info, 
+                            (name, tv) <- sig_scoped sig `zip` sig_tvs sig ]
+             rhs_id_env = map mk mono_info     -- A binding for each term variable
+
+       ; binds' <- tcExtendTyVarEnv2 rhs_tvs   $
+                   tcExtendIdEnv2   rhs_id_env $
+                   traceTc (text "tcMonoBinds" <+> vcat [ppr n <+> ppr id <+> ppr (idType id) | (n,id) <- rhs_id_env]) `thenM_`
+                   mapBagM (wrapLocM tcRhs) tc_binds
+       ; return (binds', mono_info) }
+   where
+    mk (name, Just sig, _)       = (name, sig_id sig)  -- Use the type sig if there is one
+    mk (name, Nothing,  mono_id) = (name, mono_id)     -- otherwise use a monomorphic version
+
+------------------------
+-- tcLhs typechecks the LHS of the bindings, to construct the environment in which
+-- we typecheck the RHSs.  Basically what we are doing is this: for each binder:
+--     if there's a signature for it, use the instantiated signature type
+--     otherwise invent a type variable
+-- You see that quite directly in the FunBind case.
+-- 
+-- But there's a complication for pattern bindings:
+--     data T = MkT (forall a. a->a)
+--     MkT f = e
+-- Here we can guess a type variable for the entire LHS (which will be refined to T)
+-- but we want to get (f::forall a. a->a) as the RHS environment.
+-- The simplest way to do this is to typecheck the pattern, and then look up the
+-- bound mono-ids.  Then we want to retain the typechecked pattern to avoid re-doing
+-- it; hence the TcMonoBind data type in which the LHS is done but the RHS isn't
+
+data TcMonoBind                -- Half completed; LHS done, RHS not done
+  = TcFunBind  MonoBindInfo  (Located TcId) Bool (MatchGroup Name) 
+  | TcPatBind [MonoBindInfo] (LPat TcId) (GRHSs Name) TcSigmaType
+
+type MonoBindInfo = (Name, Maybe TcSigInfo, TcId)
+       -- Type signature (if any), and
+       -- the monomorphic bound things
+
+bndrNames :: [MonoBindInfo] -> [Name]
+bndrNames mbi = [n | (n,_,_) <- mbi]
+
+getMonoType :: MonoBindInfo -> TcTauType
+getMonoType (_,_,mono_id) = idType mono_id
+
+tcLhs :: TcSigFun -> HsBind Name -> TcM TcMonoBind
+tcLhs lookup_sig (FunBind (L nm_loc name) inf matches)
+  = do { let mb_sig = lookup_sig name
+       ; mono_name <- newLocalName name
+       ; mono_ty   <- mk_mono_ty mb_sig
+       ; let mono_id = mkLocalId mono_name mono_ty
+       ; return (TcFunBind (name, mb_sig, mono_id) (L nm_loc mono_id) inf matches) }
+  where
+    mk_mono_ty (Just sig) = return (sig_tau sig)
+    mk_mono_ty Nothing    = newTyFlexiVarTy argTypeKind
+
+tcLhs lookup_sig bind@(PatBind pat grhss _)
+  = do { let tc_pat exp_ty = tcPat (LetPat lookup_sig) pat exp_ty lookup_infos
+       ; ((pat', ex_tvs, infos), pat_ty) 
+               <- addErrCtxt (patMonoBindsCtxt pat grhss)
+                             (tcInfer tc_pat)
+
+       -- Don't know how to deal with pattern-bound existentials yet
+       ; checkTc (null ex_tvs) (existentialExplode bind)
+
+       ; return (TcPatBind infos pat' grhss pat_ty) }
+  where
+    names = collectPatBinders pat
+
+       -- After typechecking the pattern, look up the binder
+       -- names, which the pattern has brought into scope.
+    lookup_infos :: TcM [MonoBindInfo]
+    lookup_infos = do { mono_ids <- tcLookupLocalIds names
+                     ; return [ (name, lookup_sig name, mono_id)
+                              | (name, mono_id) <- names `zip` mono_ids] }
+
+-------------------
+tcRhs :: TcMonoBind -> TcM (HsBind TcId)
+tcRhs (TcFunBind info fun'@(L _ mono_id) inf matches)
+  = do { matches' <- tcMatchesFun (idName mono_id) matches 
+                                  (Check (idType mono_id))
+       ; return (FunBind fun' inf matches') }
+
+tcRhs bind@(TcPatBind _ pat' grhss pat_ty)
+  = do { grhss' <- addErrCtxt (patMonoBindsCtxt pat' grhss) $
+                   tcGRHSsPat grhss (Check pat_ty)
+       ; return (PatBind pat' grhss' pat_ty) }
+
+
+---------------------
+getMonoBindInfo :: Bag (Located TcMonoBind) -> [MonoBindInfo]
+getMonoBindInfo tc_binds
+  = foldrBag (get_info . unLoc) [] tc_binds
+  where
+    get_info (TcFunBind info _ _ _)  rest = info : rest
+    get_info (TcPatBind infos _ _ _) rest = infos ++ rest
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
 \subsection{getTyVarsToGen}
 %*                                                                     *
 %************************************************************************
 
 \subsection{getTyVarsToGen}
 %*                                                                     *
 %************************************************************************
 
-@getTyVarsToGen@ decides what type variables generalise over.
+Type signatures are tricky.  See Note [Signature skolems] in TcType
+
+\begin{code}
+tcTySigs :: [LSig Name] -> TcM [TcSigInfo]
+-- The trick here is that all the signatures should have the same
+-- context, and we want to share type variables for that context, so that
+-- all the right hand sides agree a common vocabulary for their type
+-- constraints
+tcTySigs [] = return []
+
+tcTySigs sigs
+  = do { (tc_sig1 : tc_sigs) <- mappM tcTySig sigs
+       ; mapM (check_ctxt tc_sig1) tc_sigs
+        ; return (tc_sig1 : tc_sigs) }
+  where
+       -- Check tha all the signature contexts are the same
+       -- The type signatures on a mutually-recursive group of definitions
+       -- must all have the same context (or none).
+       --
+       -- We unify them because, with polymorphic recursion, their types
+       -- might not otherwise be related.  This is a rather subtle issue.
+    check_ctxt :: TcSigInfo -> TcSigInfo -> TcM ()
+    check_ctxt sig1@(TcSigInfo { sig_theta = theta1 }) sig@(TcSigInfo { sig_theta = theta })
+       = setSrcSpan (instLocSrcSpan (sig_loc sig))     $
+         addErrCtxt (sigContextsCtxt sig1 sig)         $
+         unifyTheta theta1 theta
+
+
+tcTySig :: LSig Name -> TcM TcSigInfo
+tcTySig (L span (Sig (L _ name) ty))
+  = setSrcSpan span            $
+    do { sigma_ty <- tcHsSigType (FunSigCtxt name) ty
+       ; (tvs, theta, tau) <- tcInstSigType name sigma_ty
+       ; loc <- getInstLoc (SigOrigin (SigSkol name))
+
+       ; let poly_id = mkLocalId name sigma_ty
+
+               -- 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 [Scoped] with TcSigInfo.)
+             scoped_names = case ty of
+                               L _ (HsForAllTy _ tvs _ _) -> hsLTyVarNames tvs
+                               other                      -> []
+
+       ; return (TcSigInfo { sig_id = poly_id, sig_scoped = scoped_names,
+                             sig_tvs = tvs, sig_theta = theta, sig_tau = tau, 
+                             sig_loc = loc }) }
+\end{code}
+
+\begin{code}
+generalise :: TopLevelFlag -> Bool -> [MonoBindInfo] -> [TcSigInfo] -> [Inst]
+          -> TcM ([TcTyVar], TcDictBinds, [TcId])
+generalise top_lvl is_unrestricted mono_infos sigs lie_req
+  | not is_unrestricted        -- RESTRICTED CASE
+  =    -- Check signature contexts are empty 
+    do { checkTc (all is_mono_sig sigs)
+                 (restrictedBindCtxtErr bndr_names)
+
+       -- Now simplify with exactly that set of tyvars
+       -- We have to squash those Methods
+       ; (qtvs, binds) <- tcSimplifyRestricted doc top_lvl bndr_names 
+                                               tau_tvs lie_req
+
+       -- Check that signature type variables are OK
+       ; final_qtvs <- checkSigsTyVars qtvs sigs
+
+       ; return (final_qtvs, binds, []) }
+
+  | null sigs  -- UNRESTRICTED CASE, NO TYPE SIGS
+  = tcSimplifyInfer doc tau_tvs lie_req
+
+  | otherwise  -- UNRESTRICTED CASE, WITH TYPE SIGS
+  = do { let sig1 = head sigs
+       ; sig_lie <- newDictsAtLoc (sig_loc sig1) (sig_theta sig1)
+       ; let   -- The "sig_avails" is the stuff available.  We get that from
+               -- the context of the type signature, BUT ALSO the lie_avail
+               -- so that polymorphic recursion works right (see comments at end of fn)
+               local_meths = [mkMethInst sig mono_id | (_, Just sig, mono_id) <- mono_infos]
+               sig_avails = sig_lie ++ local_meths
+
+       -- Check that the needed dicts can be
+       -- expressed in terms of the signature ones
+       ; (forall_tvs, dict_binds) <- tcSimplifyInferCheck doc tau_tvs sig_avails lie_req
+       
+       -- Check that signature type variables are OK
+       ; final_qtvs <- checkSigsTyVars forall_tvs sigs
+
+       ; returnM (final_qtvs, dict_binds, map instToId sig_lie) }
+
+  where
+    bndr_names = bndrNames mono_infos
+    tau_tvs = foldr (unionVarSet . tyVarsOfType . getMonoType) emptyVarSet mono_infos
+    is_mono_sig sig = null (sig_theta sig)
+    doc = ptext SLIT("type signature(s) for") <+> pprBinders bndr_names
+
+    mkMethInst (TcSigInfo { sig_id = poly_id, sig_tvs = tvs, 
+                           sig_theta = theta, sig_tau = tau, sig_loc = loc }) mono_id
+      = Method mono_id poly_id (mkTyVarTys tvs) theta tau loc
+
+checkSigsTyVars :: [TcTyVar] -> [TcSigInfo] -> TcM [TcTyVar]
+checkSigsTyVars qtvs sigs 
+  = do { gbl_tvs <- tcGetGlobalTyVars
+       ; sig_tvs_s <- mappM (check_sig gbl_tvs) sigs
+
+       ; let   -- Sigh.  Make sure that all the tyvars in the type sigs
+               -- appear in the returned ty var list, which is what we are
+               -- going to generalise over.  Reason: we occasionally get
+               -- silly types like
+               --      type T a = () -> ()
+               --      f :: T a
+               --      f () = ()
+               -- Here, 'a' won't appear in qtvs, so we have to add it
+               sig_tvs = foldl extendVarSetList emptyVarSet sig_tvs_s
+               all_tvs = varSetElems (extendVarSetList sig_tvs qtvs)
+       ; returnM all_tvs }
+  where
+    check_sig gbl_tvs (TcSigInfo {sig_id = id, sig_tvs = tvs, 
+                                 sig_theta = theta, sig_tau = tau})
+      = addErrCtxt (ptext SLIT("In the type signature for") <+> quotes (ppr id))       $
+       addErrCtxtM (sigCtxt id tvs theta tau)                                          $
+       do { tvs' <- checkDistinctTyVars tvs
+          ; ifM (any (`elemVarSet` gbl_tvs) tvs')
+                (bleatEscapedTvs gbl_tvs tvs tvs') 
+          ; return tvs' }
+
+checkDistinctTyVars :: [TcTyVar] -> TcM [TcTyVar]
+-- (checkDistinctTyVars tvs) checks that the tvs from one type signature
+-- are still all type variables, and all distinct from each other.  
+-- It returns a zonked set of type variables.
+-- For example, if the type sig is
+--     f :: forall a b. a -> b -> b
+-- we want to check that 'a' and 'b' haven't 
+--     (a) been unified with a non-tyvar type
+--     (b) been unified with each other (all distinct)
+
+checkDistinctTyVars sig_tvs
+  = do { zonked_tvs <- mapM zonk_one sig_tvs
+       ; foldlM check_dup emptyVarEnv (sig_tvs `zip` zonked_tvs)
+       ; return zonked_tvs }
+  where
+    zonk_one sig_tv = do { ty <- zonkTcTyVar sig_tv
+                        ; return (tcGetTyVar "checkDistinctTyVars" ty) }
+       -- 'ty' is bound to be a type variable, because SigSkolTvs
+       -- can only be unified with type variables
+
+    check_dup :: TyVarEnv TcTyVar -> (TcTyVar, TcTyVar) -> TcM (TyVarEnv TcTyVar)
+       -- The TyVarEnv maps each zonked type variable back to its
+       -- corresponding user-written signature type variable
+    check_dup acc (sig_tv, zonked_tv)
+       = case lookupVarEnv acc zonked_tv of
+               Just sig_tv' -> bomb_out sig_tv sig_tv'
+
+               Nothing -> return (extendVarEnv acc zonked_tv sig_tv)
+
+    bomb_out sig_tv1 sig_tv2
+       = failWithTc (ptext SLIT("Quantified type variable") <+> quotes (ppr tidy_tv1) 
+                    <+> ptext SLIT("is unified with another quantified type variable") 
+                    <+> ppr tidy_tv2)
+       where
+        (env1,  tidy_tv1) = tidyOpenTyVar emptyTidyEnv sig_tv1
+        (_env2, tidy_tv2) = tidyOpenTyVar env1         sig_tv2
+\end{code}    
+
+
+@getTyVarsToGen@ decides what type variables to generalise over.
 
 For a "restricted group" -- see the monomorphism restriction
 for a definition -- we bind no dictionaries, and
 
 For a "restricted group" -- see the monomorphism restriction
 for a definition -- we bind no dictionaries, and
@@ -496,6 +753,8 @@ generalise.  We must be careful about doing this:
        Another, more common, example is when there's a Method inst in
        the LIE, whose type might very well involve non-overloaded
        type variables.
        Another, more common, example is when there's a Method inst in
        the LIE, whose type might very well involve non-overloaded
        type variables.
+  [NOTE: Jan 2001: I don't understand the problem here so I'm doing 
+       the simple thing instead]
 
  (b) On the other hand, we mustn't generalise tyvars which are constrained,
        because we are going to pass on out the unmodified LIE, with those
 
  (b) On the other hand, we mustn't generalise tyvars which are constrained,
        because we are going to pass on out the unmodified LIE, with those
@@ -506,202 +765,25 @@ constrained tyvars. We don't use any of the results, except to
 find which tyvars are constrained.
 
 \begin{code}
 find which tyvars are constrained.
 
 \begin{code}
-getTyVarsToGen is_unrestricted mono_id_tys lie
-  = tcGetGlobalTyVars                  `thenNF_Tc` \ free_tyvars ->
-    zonkTcTypes mono_id_tys            `thenNF_Tc` \ zonked_mono_id_tys ->
-    let
-       tyvars_to_gen = tyVarsOfTypes zonked_mono_id_tys `minusVarSet` free_tyvars
-    in
-    if is_unrestricted
-    then
-       returnNF_Tc (emptyVarSet, tyvars_to_gen)
-    else
-       -- This recover and discard-errs is to avoid duplicate error
-       -- messages; this, after all, is an "extra" call to tcSimplify
-       recoverNF_Tc (returnNF_Tc (emptyVarSet, tyvars_to_gen))         $
-       discardErrsTc                                                   $
-
-       tcSimplify (text "getTVG") NotTopLevel tyvars_to_gen lie    `thenTc` \ (_, _, constrained_dicts) ->
-       let
-         -- ASSERT: dicts_sig is already zonked!
-           constrained_tyvars    = foldrBag (unionVarSet . tyVarsOfInst) emptyVarSet constrained_dicts
-           reduced_tyvars_to_gen = tyvars_to_gen `minusVarSet` constrained_tyvars
-        in
-        returnTc (constrained_tyvars, reduced_tyvars_to_gen)
-\end{code}
-
-
-\begin{code}
-isUnRestrictedGroup :: [Name]          -- Signatures given for these
-                   -> RenamedMonoBinds
-                   -> Bool
+isUnRestrictedGroup :: LHsBinds Name -> [TcSigInfo] -> TcM Bool
+isUnRestrictedGroup binds sigs
+  = do { mono_restriction <- doptM Opt_MonomorphismRestriction
+       ; return (not mono_restriction || all_unrestricted) }
+  where 
+    all_unrestricted = all (unrestricted . unLoc) (bagToList binds)
+    tysig_names      = map (idName . sig_id) sigs
+
+    unrestricted (PatBind other _ _)   = False
+    unrestricted (VarBind v _)        = v `is_elem` tysig_names
+    unrestricted (FunBind v _ matches) = unrestricted_match matches 
+                                        || unLoc v `is_elem` tysig_names
+
+    unrestricted_match (MatchGroup (L _ (Match [] _ _) : _) _) = False
+       -- No args => like a pattern binding
+    unrestricted_match other             = True
+       -- Some args => a function binding
 
 is_elem v vs = isIn "isUnResMono" v vs
 
 is_elem v vs = isIn "isUnResMono" v vs
-
-isUnRestrictedGroup sigs (PatMonoBind (VarPatIn v) _ _) = v `is_elem` sigs
-isUnRestrictedGroup sigs (PatMonoBind other      _ _)  = False
-isUnRestrictedGroup sigs (VarMonoBind v _)             = v `is_elem` sigs
-isUnRestrictedGroup sigs (FunMonoBind _ _ _ _)         = True
-isUnRestrictedGroup sigs (AndMonoBinds mb1 mb2)                = isUnRestrictedGroup sigs mb1 &&
-                                                         isUnRestrictedGroup sigs mb2
-isUnRestrictedGroup sigs EmptyMonoBinds                        = True
-\end{code}
-
-@defaultUncommittedTyVar@ checks for generalisation over unboxed
-types, and defaults any TypeKind TyVars to BoxedTypeKind.
-
-\begin{code}
-defaultUncommittedTyVar tyvar
-  | tyVarKind tyvar == openTypeKind
-  = newTcTyVar boxedTypeKind                                   `thenNF_Tc` \ boxed_tyvar ->
-    unifyTauTy (mkTyVarTy tyvar) (mkTyVarTy boxed_tyvar)       `thenTc_`
-    returnTc boxed_tyvar
-
-  | otherwise
-  = returnTc tyvar
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-\subsection{tcMonoBind}
-%*                                                                     *
-%************************************************************************
-
-@tcMonoBinds@ deals with a single @MonoBind@.  
-The signatures have been dealt with already.
-
-\begin{code}
-tcMonoBinds :: RenamedMonoBinds 
-           -> [TcSigInfo s]
-           -> RecFlag
-           -> TcM s (TcMonoBinds s, 
-                     LIE s,            -- LIE required
-                     [Name],           -- Bound names
-                     [TcIdBndr s])     -- Corresponding monomorphic bound things
-
-tcMonoBinds mbinds tc_ty_sigs is_rec
-  = tc_mb_pats mbinds          `thenTc` \ (complete_it, lie_req_pat, tvs, ids, lie_avail) ->
-    let
-       tv_list           = bagToList tvs
-       (names, mono_ids) = unzip (bagToList ids)
-    in
-       -- Don't know how to deal with pattern-bound existentials yet
-    checkTc (isEmptyBag tvs && isEmptyBag lie_avail) 
-           (existentialExplode mbinds)                 `thenTc_` 
-
-       -- *Before* checking the RHSs, but *after* checking *all* the patterns, 
-       -- extend the envt with bindings for all the bound ids;
-       --   and *then* override with the polymorphic Ids from the signatures
-       -- That is the whole point of the "complete_it" stuff.
-    tcExtendEnvWithPat ids (tcExtendEnvWithPat sig_ids 
-               complete_it
-    )                                          `thenTc` \ (mbinds', lie_req_rhss) ->
-    returnTc (mbinds', lie_req_pat `plusLIE` lie_req_rhss, names, mono_ids)
-  where
-    sig_fn name = case maybeSig tc_ty_sigs name of
-                       Nothing                                -> Nothing
-                       Just (TySigInfo _ _ _ _ _ mono_id _ _) -> Just mono_id
-
-    sig_ids = listToBag [(name,poly_id) | TySigInfo name poly_id _ _ _ _ _ _ <- tc_ty_sigs]
-
-    kind = case is_rec of
-            Recursive    -> boxedTypeKind      -- Recursive, so no unboxed types
-            NonRecursive -> openTypeKind       -- Non-recursive, so we permit unboxed types
-
-    tc_mb_pats EmptyMonoBinds
-      = returnTc (returnTc (EmptyMonoBinds, emptyLIE), emptyLIE, emptyBag, emptyBag, emptyLIE)
-
-    tc_mb_pats (AndMonoBinds mb1 mb2)
-      = tc_mb_pats mb1         `thenTc` \ (complete_it1, lie_req1, tvs1, ids1, lie_avail1) ->
-        tc_mb_pats mb2         `thenTc` \ (complete_it2, lie_req2, tvs2, ids2, lie_avail2) ->
-       let
-          complete_it = complete_it1   `thenTc` \ (mb1', lie1) ->
-                        complete_it2   `thenTc` \ (mb2', lie2) ->
-                        returnTc (AndMonoBinds mb1' mb2', lie1 `plusLIE` lie2)
-       in
-       returnTc (complete_it,
-                 lie_req1 `plusLIE` lie_req2,
-                 tvs1 `unionBags` tvs2,
-                 ids1 `unionBags` ids2,
-                 lie_avail1 `plusLIE` lie_avail2)
-
-    tc_mb_pats (FunMonoBind name inf matches locn)
-      = newTyVarTy boxedTypeKind       `thenNF_Tc` \ pat_ty ->
-       tcVarPat sig_fn name pat_ty     `thenTc` \ bndr_id ->
-       let
-          complete_it = tcAddSrcLoc locn                       $
-                        tcMatchesFun name pat_ty matches       `thenTc` \ (matches', lie) ->
-                        returnTc (FunMonoBind (TcId bndr_id) inf matches' locn, lie)
-       in
-       returnTc (complete_it, emptyLIE, emptyBag, unitBag (name, bndr_id), emptyLIE)
-
-    tc_mb_pats bind@(PatMonoBind pat grhss_and_binds locn)
-      = tcAddSrcLoc locn               $
-       newTyVarTy kind                 `thenNF_Tc` \ pat_ty ->
-       tcPat sig_fn pat pat_ty         `thenTc` \ (pat', lie_req, tvs, ids, lie_avail) ->
-       let
-          complete_it = tcAddSrcLoc locn                               $
-                        tcAddErrCtxt (patMonoBindsCtxt bind)           $
-                        tcGRHSsAndBinds grhss_and_binds pat_ty PatBindRhs      `thenTc` \ (grhss_and_binds', lie) ->
-                        returnTc (PatMonoBind pat' grhss_and_binds' locn, lie)
-       in
-       returnTc (complete_it, lie_req, tvs, ids, lie_avail)
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection{Signatures}
-%*                                                                     *
-%************************************************************************
-
-@checkSigMatch@ does the next step in checking signature matching.
-The tau-type part has already been unified.  What we do here is to
-check that this unification has not over-constrained the (polymorphic)
-type variables of the original signature type.
-
-The error message here is somewhat unsatisfactory, but it'll do for
-now (ToDo).
-
-\begin{code}
-checkSigMatch []
-  = returnTc (error "checkSigMatch", emptyLIE)
-
-checkSigMatch tc_ty_sigs@( sig1@(TySigInfo _ id1 _ theta1 _ _ _ _) : all_sigs_but_first )
-  =    -- CHECK THAT THE SIGNATURE TYVARS AND TAU_TYPES ARE OK
-       -- Doesn't affect substitution
-    mapTc check_one_sig tc_ty_sigs     `thenTc_`
-
-       -- CHECK THAT ALL THE SIGNATURE CONTEXTS ARE UNIFIABLE
-       -- The type signatures on a mutually-recursive group of definitions
-       -- must all have the same context (or none).
-       --
-       -- We unify them because, with polymorphic recursion, their types
-       -- might not otherwise be related.  This is a rather subtle issue.
-       -- ToDo: amplify
-    mapTc check_one_cxt all_sigs_but_first             `thenTc_`
-
-    returnTc (theta1, sig_lie)
-  where
-    sig1_dict_tys      = mk_dict_tys theta1
-    n_sig1_dict_tys    = length sig1_dict_tys
-    sig_lie            = mkLIE [inst | TySigInfo _ _ _ _ _ _ inst _ <- tc_ty_sigs]
-
-    check_one_cxt sig@(TySigInfo _ id _ theta _ _ _ src_loc)
-       = tcAddSrcLoc src_loc   $
-        tcAddErrCtxt (sigContextsCtxt id1 id) $
-        checkTc (length this_sig_dict_tys == n_sig1_dict_tys)
-                               sigContextsErr          `thenTc_`
-        unifyTauTyLists sig1_dict_tys this_sig_dict_tys
-      where
-        this_sig_dict_tys = mk_dict_tys theta
-
-    check_one_sig (TySigInfo _ id sig_tyvars _ sig_tau _ _ src_loc)
-      = tcAddSrcLoc src_loc                                    $
-       tcAddErrCtxtM (sigCtxt (quotes (ppr id)) sig_tau)       $
-       checkSigTyVars sig_tyvars
-
-    mk_dict_tys theta = [mkDictTy c ts | (c,ts) <- theta]
 \end{code}
 
 
 \end{code}
 
 
@@ -711,28 +793,13 @@ checkSigMatch tc_ty_sigs@( sig1@(TySigInfo _ id1 _ theta1 _ _ _ _) : all_sigs_bu
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
-
-@tcPragmaSigs@ munches up the "signatures" that arise through *user*
+@tcSpecSigs@ munches up the specialisation "signatures" that arise through *user*
 pragmas.  It is convenient for them to appear in the @[RenamedSig]@
 part of a binding because then the same machinery can be used for
 moving them into place as is done for type signatures.
 
 pragmas.  It is convenient for them to appear in the @[RenamedSig]@
 part of a binding because then the same machinery can be used for
 moving them into place as is done for type signatures.
 
-\begin{code}
-tcPragmaSigs :: [RenamedSig]           -- The pragma signatures
-            -> TcM s (Name -> IdInfo,  -- Maps name to the appropriate IdInfo
-                      TcMonoBinds s,
-                      LIE s)
-
-tcPragmaSigs sigs
-  = mapAndUnzip3Tc tcPragmaSig sigs    `thenTc` \ (maybe_info_modifiers, binds, lies) ->
-    let
-       prag_fn name = foldr ($) noIdInfo [f | Just (n,f) <- maybe_info_modifiers, n==name]
-    in
-    returnTc (prag_fn, andMonoBindList binds, plusLIEs lies)
-\end{code}
+They look like this:
 
 
-The interesting case is for SPECIALISE pragmas.  There are two forms.
-Here's the first form:
 \begin{verbatim}
        f :: Ord a => [a] -> b -> b
        {-# SPECIALIZE f :: [Int] -> b -> b #-}
 \begin{verbatim}
        f :: Ord a => [a] -> b -> b
        {-# SPECIALIZE f :: [Int] -> b -> b #-}
@@ -755,90 +822,45 @@ specialiser will subsequently discover that there's a call of @f@ at
 Int, and will create a specialisation for @f@.  After that, the
 binding for @f*@ can be discarded.
 
 Int, and will create a specialisation for @f@.  After that, the
 binding for @f*@ can be discarded.
 
-The second form is this:
-\begin{verbatim}
-       f :: Ord a => [a] -> b -> b
-       {-# SPECIALIZE f :: [Int] -> b -> b = g #-}
-\end{verbatim}
-
-Here @g@ is specified as a function that implements the specialised
-version of @f@.  Suppose that g has type (a->b->b); that is, g's type
-is more general than that required.  For this we generate
-\begin{verbatim}
-       f@Int = /\b -> g Int b
-       f* = f@Int
-\end{verbatim}
-
-Here @f@@Int@ is a SpecId, the specialised version of @f@.  It inherits
-f's export status etc.  @f*@ is a SpecPragmaId, as before, which just serves
-to prevent @f@@Int@ from being discarded prematurely.  After specialisation,
-if @f@@Int@ is going to be used at all it will be used explicitly, so the simplifier can
-discard the f* binding.
-
-Actually, there is really only point in giving a SPECIALISE pragma on exported things,
-and the simplifer won't discard SpecIds for exporte things anyway, so maybe this is
-a bit of overkill.
+We used to have a form
+       {-# SPECIALISE f :: <type> = g #-}
+which promised that g implemented f at <type>, but we do that with 
+a RULE now:
+       {-# RULES (f::<type>) = g #-}
 
 \begin{code}
 
 \begin{code}
-tcPragmaSig :: RenamedSig -> TcM s (Maybe (Name, IdInfo -> IdInfo), TcMonoBinds s, LIE s)
-tcPragmaSig (Sig _ _ _)       = returnTc (Nothing, EmptyMonoBinds, emptyLIE)
-tcPragmaSig (SpecInstSig _ _) = returnTc (Nothing, EmptyMonoBinds, emptyLIE)
-
-tcPragmaSig (InlineSig name loc)
-  = returnTc (Just (name, setInlinePragInfo IWantToBeINLINEd), EmptyMonoBinds, emptyLIE)
-
-tcPragmaSig (NoInlineSig name loc)
-  = returnTc (Just (name, setInlinePragInfo IMustNotBeINLINEd), EmptyMonoBinds, emptyLIE)
-
-tcPragmaSig (SpecSig name poly_ty maybe_spec_name src_loc)
+tcSpecSigs :: [LSig Name] -> TcM (LHsBinds TcId)
+tcSpecSigs (L loc (SpecSig (L nm_loc name) poly_ty) : sigs)
   =    -- SPECIALISE f :: forall b. theta => tau  =  g
   =    -- SPECIALISE f :: forall b. theta => tau  =  g
-    tcAddSrcLoc src_loc                                $
-    tcAddErrCtxt (valSpecSigCtxt name poly_ty) $
+    setSrcSpan loc                             $
+    addErrCtxt (valSpecSigCtxt name poly_ty)   $
 
        -- Get and instantiate its alleged specialised type
 
        -- Get and instantiate its alleged specialised type
-    tcHsTcType poly_ty                         `thenTc` \ sig_ty ->
+    tcHsSigType (FunSigCtxt name) poly_ty      `thenM` \ sig_ty ->
 
        -- Check that f has a more general type, and build a RHS for
        -- the spec-pragma-id at the same time
 
        -- Check that f has a more general type, and build a RHS for
        -- the spec-pragma-id at the same time
-    tcExpr (HsVar name) sig_ty                 `thenTc` \ (spec_expr, spec_lie) ->
-
-    case maybe_spec_name of
-       Nothing ->      -- Just specialise "f" by building a SpecPragmaId binding
-                       -- It is the thing that makes sure we don't prematurely 
-                       -- dead-code-eliminate the binding we are really interested in.
-                  newSpecPragmaId name sig_ty          `thenNF_Tc` \ spec_id ->
-                  returnTc (Nothing, VarMonoBind (TcId spec_id) spec_expr, spec_lie)
-
-       Just g_name ->  -- Don't create a SpecPragmaId.  Instead add some suitable IdIfo
-               
-               panic "Can't handle SPECIALISE with a '= g' part"
-
-       {-  Not yet.  Because we're still in the TcType world we
-           can't really add to the SpecEnv of the Id.  Instead we have to
-           record the information in a different sort of Sig, and add it to
-           the IdInfo after zonking.
-
-           For now we just leave out this case
-
-                       -- Get the type of f, and find out what types
-                       --  f has to be instantiated at to give the signature type
-                   tcLookupLocalValueOK "tcPragmaSig" name     `thenNF_Tc` \ f_id ->
-                   tcInstTcType (idType f_id)          `thenNF_Tc` \ (f_tyvars, f_rho) ->
-
-                   let
-                       (sig_tyvars, sig_theta, sig_tau) = splitSigmaTy sig_ty
-                       (f_theta, f_tau)                 = splitRhoTy f_rho
-                       sig_tyvar_set                    = mkVarSet sig_tyvars
-                   in
-                   unifyTauTy sig_tau f_tau            `thenTc_`
-
-                   tcPolyExpr str (HsVar g_name) (mkSigmaTy sig_tyvars f_theta sig_tau)        `thenTc` \ (_, _, 
-       -}
-
-tcPragmaSig other = pprTrace "tcPragmaSig: ignoring" (ppr other) $
-                   returnTc (Nothing, EmptyMonoBinds, emptyLIE)
-\end{code}
+    getLIE (tcCheckSigma (L nm_loc (HsVar name)) sig_ty)       `thenM` \ (spec_expr, spec_lie) ->
+
+       -- Squeeze out any Methods (see comments with tcSimplifyToDicts)
+    tcSimplifyToDicts spec_lie                 `thenM` \ spec_binds ->
+
+       -- Just specialise "f" by building a SpecPragmaId binding
+       -- It is the thing that makes sure we don't prematurely 
+       -- dead-code-eliminate the binding we are really interested in.
+    newLocalName name                  `thenM` \ spec_name ->
+    let
+       spec_bind = VarBind (mkSpecPragmaId spec_name sig_ty)
+                               (mkHsLet spec_binds spec_expr)
+    in
+
+       -- Do the rest and combine
+    tcSpecSigs sigs                    `thenM` \ binds_rest ->
+    returnM (binds_rest `snocBag` L loc spec_bind)
 
 
+tcSpecSigs (other_sig : sigs) = tcSpecSigs sigs
+tcSpecSigs []                = returnM emptyLHsBinds
+\end{code}
 
 %************************************************************************
 %*                                                                     *
 
 %************************************************************************
 %*                                                                     *
@@ -848,54 +870,45 @@ tcPragmaSig other = pprTrace "tcPragmaSig: ignoring" (ppr other) $
 
 
 \begin{code}
 
 
 \begin{code}
-patMonoBindsCtxt bind
-  = hang (ptext SLIT("In a pattern binding:")) 4 (ppr bind)
+-- 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 pat grhss
+  = hang (ptext SLIT("In a pattern binding:")) 4 (pprPatBind pat grhss)
 
 -----------------------------------------------
 valSpecSigCtxt v ty
   = sep [ptext SLIT("In a SPECIALIZE pragma for a value:"),
 
 -----------------------------------------------
 valSpecSigCtxt v ty
   = sep [ptext SLIT("In a SPECIALIZE pragma for a value:"),
-        nest 4 (ppr v <+> ptext SLIT(" ::") <+> ppr ty)]
-
------------------------------------------------
-notAsPolyAsSigErr sig_tau mono_tyvars
-  = hang (ptext SLIT("A type signature is more polymorphic than the inferred type"))
-       4  (vcat [text "Can't for-all the type variable(s)" <+> 
-                 pprQuotedList mono_tyvars,
-                 text "in the type" <+> quotes (ppr sig_tau)
-          ])
+        nest 4 (ppr v <+> dcolon <+> ppr ty)]
 
 -----------------------------------------------
 
 -----------------------------------------------
-badMatchErr sig_ty inferred_ty
-  = hang (ptext SLIT("Type signature doesn't match inferred type"))
-        4 (vcat [hang (ptext SLIT("Signature:")) 4 (ppr sig_ty),
-                     hang (ptext SLIT("Inferred :")) 4 (ppr inferred_ty)
-          ])
-
------------------------------------------------
-unboxedPatBindErr id
-  = ptext SLIT("variable in a lazy pattern binding has unboxed type: ")
-        <+> quotes (ppr id)
-
------------------------------------------------
-bindSigsCtxt ids
-  = ptext SLIT("When checking the type signature(s) for") <+> pprQuotedList ids
+sigContextsCtxt sig1 sig2
+  = vcat [ptext SLIT("When matching the contexts of the signatures for"), 
+         nest 2 (vcat [ppr id1 <+> dcolon <+> ppr (idType id1),
+                       ppr id2 <+> dcolon <+> ppr (idType id2)]),
+         ptext SLIT("The signature contexts in a mutually recursive group should all be identical")]
+  where
+    id1 = sig_id sig1
+    id2 = sig_id sig2
 
 
------------------------------------------------
-sigContextsErr
-  = ptext SLIT("Mismatched contexts")
-sigContextsCtxt s1 s2
-  = hang (hsep [ptext SLIT("When matching the contexts of the signatures for"), 
-               quotes (ppr s1), ptext SLIT("and"), quotes (ppr s2)])
-        4 (ptext SLIT("(the signature contexts in a mutually recursive group should all be identical)"))
 
 -----------------------------------------------
 unliftedBindErr flavour mbind
 
 -----------------------------------------------
 unliftedBindErr flavour mbind
-  = hang (text flavour <+> ptext SLIT("bindings for unlifted types aren't allowed"))
+  = hang (text flavour <+> ptext SLIT("bindings for unlifted types aren't allowed:"))
         4 (ppr mbind)
 
         4 (ppr mbind)
 
+-----------------------------------------------
 existentialExplode mbinds
   = hang (vcat [text "My brain just exploded.",
                text "I can't handle pattern bindings for existentially-quantified constructors.",
                text "In the binding group"])
        4 (ppr mbinds)
 existentialExplode mbinds
   = hang (vcat [text "My brain just exploded.",
                text "I can't handle pattern bindings for existentially-quantified constructors.",
                text "In the binding group"])
        4 (ppr mbinds)
+
+-----------------------------------------------
+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 binder_names
+  = ptext SLIT("When generalising the type(s) for") <+> pprBinders binder_names
 \end{code}
 \end{code}