[project @ 2001-05-03 09:01:29 by simonpj]
[ghc-hetmet.git] / ghc / compiler / typecheck / TcBinds.lhs
index 49dfed2..1192ef3 100644 (file)
@@ -4,60 +4,59 @@
 \section[TcBinds]{TcBinds}
 
 \begin{code}
-module TcBinds ( tcBindsAndThen, tcTopBindsAndThen,
-                tcPragmaSigs, tcBindWithSigs ) where
+module TcBinds ( tcBindsAndThen, tcTopBinds,
+                tcSpecSigs, tcBindWithSigs ) where
 
 #include "HsVersions.h"
 
 import {-# SOURCE #-} TcMatches ( tcGRHSs, tcMatchesFun )
 import {-# SOURCE #-} TcExpr  ( tcExpr )
 
-import HsSyn           ( HsExpr(..), HsBinds(..), MonoBinds(..), Sig(..), InPat(..), StmtCtxt(..),
-                         collectMonoBinders, andMonoBindList, andMonoBinds
+import CmdLineOpts     ( opt_NoMonomorphismRestriction )
+import HsSyn           ( HsExpr(..), HsBinds(..), MonoBinds(..), Sig(..), 
+                         Match(..), HsMatchContext(..), 
+                         collectMonoBinders, andMonoBinds
                        )
 import RnHsSyn         ( RenamedHsBinds, RenamedSig, RenamedMonoBinds )
-import TcHsSyn         ( TcHsBinds, TcMonoBinds, TcId, zonkId )
+import TcHsSyn         ( TcMonoBinds, TcId, zonkId, mkHsLet )
 
 import TcMonad
-import Inst            ( Inst, LIE, emptyLIE, mkLIE, plusLIE, plusLIEs, InstOrigin(..),
-                         newDicts, tyVarsOfInst, instToId,
+import Inst            ( LIE, emptyLIE, mkLIE, plusLIE, InstOrigin(..),
+                         newDicts, instToId
                        )
 import TcEnv           ( tcExtendLocalValEnv,
-                         newSpecPragmaId,
-                         tcLookupTyCon, 
-                         tcGetGlobalTyVars, tcExtendGlobalTyVars
+                         newSpecPragmaId, newLocalId
                        )
-import TcSimplify      ( tcSimplify, tcSimplifyAndCheck )
-import TcMonoType      ( tcHsType, checkSigTyVars,
+import TcSimplify      ( tcSimplifyInfer, tcSimplifyInferCheck, tcSimplifyCheck, tcSimplifyRestricted, tcSimplifyToDicts )
+import TcMonoType      ( tcHsSigType, checkSigTyVars,
                          TcSigInfo(..), tcTySig, maybeSig, sigCtxt
                        )
-import TcPat           ( tcVarPat, tcPat )
+import TcPat           ( tcPat )
 import TcSimplify      ( bindInstsOfLocalFuns )
-import TcType          ( TcType, TcThetaType,
-                         TcTyVar,
-                         newTyVarTy, newTyVar, newTyVarTy_OpenKind, tcInstTcType,
-                         zonkTcType, zonkTcTypes, zonkTcThetaType, zonkTcTyVarToTyVar
+import TcType          ( newTyVarTy, newTyVar, 
+                         zonkTcTyVarToTyVar
                        )
 import TcUnify         ( unifyTauTy, unifyTauTyLists )
 
-import PrelInfo                ( main_NAME, ioTyCon_NAME )
-
-import Id              ( mkUserId )
-import Var             ( idType, idName, setIdInfo )
-import IdInfo          ( IdInfo, noIdInfo, setInlinePragInfo, InlinePragInfo(..) )
-import Name            ( Name, getName )
-import Type            ( mkTyVarTy, tyVarsOfTypes, mkTyConApp,
-                         splitSigmaTy, mkForAllTys, mkFunTys, getTyVar, 
-                         mkDictTy, splitRhoTy, mkForAllTy, isUnLiftedType, 
-                         isUnboxedType, unboxedTypeKind, boxedTypeKind
+import CoreFVs         ( idFreeTyVars )
+import Id              ( mkLocalId, setInlinePragma )
+import Var             ( idType, idName )
+import IdInfo          ( InlinePragInfo(..) )
+import Name            ( Name, getOccName, getSrcLoc )
+import NameSet
+import Type            ( mkTyVarTy, tyVarsOfTypes,
+                         mkForAllTys, mkFunTys, tyVarsOfType, 
+                         mkPredTy, mkForAllTy, isUnLiftedType, 
+                         unliftedTypeKind, liftedTypeKind, openTypeKind
                        )
-import Var             ( TyVar, tyVarKind )
+import Var             ( tyVarKind )
 import VarSet
 import Bag
 import Util            ( isIn )
+import ListSetOps      ( minusList )
 import Maybes          ( maybeToBool )
-import BasicTypes      ( TopLevelFlag(..), RecFlag(..) )
-import SrcLoc           ( SrcLoc )
+import BasicTypes      ( TopLevelFlag(..), RecFlag(..), isNonRec, isNotTopLevel )
+import FiniteMap       ( listToFM, lookupFM )
 import Outputable
 \end{code}
 
@@ -94,14 +93,22 @@ At the top-level the LIE is sure to contain nothing but constant
 dictionaries, which we resolve at the module level.
 
 \begin{code}
-tcTopBindsAndThen, tcBindsAndThen
+tcTopBinds :: RenamedHsBinds -> TcM ((TcMonoBinds, TcEnv), LIE)
+tcTopBinds binds
+  = tc_binds_and_then TopLevel glue binds      $
+    tcGetEnv                                   `thenNF_Tc` \ env ->
+    returnTc ((EmptyMonoBinds, env), emptyLIE)
+  where
+    glue is_rec binds1 (binds2, thing) = (binds1 `AndMonoBinds` binds2, thing)
+
+
+tcBindsAndThen
        :: (RecFlag -> TcMonoBinds -> thing -> thing)           -- Combinator
        -> RenamedHsBinds
-       -> TcM s (thing, LIE)
-       -> TcM s (thing, LIE)
+       -> TcM (thing, LIE)
+       -> TcM (thing, LIE)
 
-tcTopBindsAndThen = tc_binds_and_then TopLevel
-tcBindsAndThen    = tc_binds_and_then NotTopLevel
+tcBindsAndThen = tc_binds_and_then NotTopLevel
 
 tc_binds_and_then top_lvl combiner EmptyBinds do_next
   = do_next
@@ -114,37 +121,31 @@ tc_binds_and_then top_lvl combiner (ThenBinds b1 b2) do_next
     do_next
 
 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.
-
-       -- TYPECHECK THE SIGNATURES
+  =    -- 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) ->
+      tcBindWithSigs top_lvl bind tc_ty_sigs
+                    sigs is_rec                        `thenTc` \ (poly_binds, poly_lie, poly_ids) ->
   
          -- Extend the environment to bind the new polymorphic Ids
       tcExtendLocalValEnv [(idName poly_id, poly_id) | poly_id <- poly_ids] $
   
          -- Build bindings and IdInfos corresponding to user pragmas
-      tcPragmaSigs sigs                `thenTc` \ (prag_info_fn, prag_binds, prag_lie) ->
+      tcSpecSigs sigs          `thenTc` \ (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
+       -- so that we desugar unlifted 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,
+               -> returnTc (combiner Recursive (poly_binds `andMonoBinds` prag_binds) thing,
                             thing_lie `plusLIE` prag_lie `plusLIE` poly_lie)
 
        (NotTopLevel, NonRecursive) 
@@ -153,7 +154,6 @@ tc_binds_and_then top_lvl combiner (MonoBind bind sigs is_rec) do_next
                                poly_ids                        `thenTc` \ (thing_lie', lie_binds) ->
 
                   returnTc (
-                       prag_info_fn,
                        combiner NonRecursive poly_binds $
                        combiner NonRecursive prag_binds $
                        combiner Recursive lie_binds  $
@@ -171,43 +171,14 @@ tc_binds_and_then top_lvl combiner (MonoBind bind sigs is_rec) do_next
                                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}
 
-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, thing_ty))
-%      -> TcM s ((TcHsBinds, thing), LIE, 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}
-
 
 %************************************************************************
 %*                                                                     *
@@ -230,189 +201,153 @@ tcBindWithSigs
        :: TopLevelFlag
        -> RenamedMonoBinds
        -> [TcSigInfo]
+       -> [RenamedSig]         -- Used solely to get INLINE, NOINLINE sigs
        -> RecFlag
-       -> (Name -> IdInfo)
-       -> TcM s (TcMonoBinds, LIE, [TcId])
+       -> TcM (TcMonoBinds, LIE, [TcId])
 
-tcBindWithSigs top_lvl mbind tc_ty_sigs is_rec prag_info_fn
+tcBindWithSigs top_lvl mbind tc_ty_sigs inline_sigs is_rec
   = recoverTc (
        -- If typechecking the binds fails, then return with each
        -- signature-less binder given type (forall a.a), to minimise subsequent
        -- error messages
-       newTyVar boxedTypeKind          `thenNF_Tc` \ alpha_tv ->
+       newTyVar liftedTypeKind         `thenNF_Tc` \ alpha_tv ->
        let
          forall_a_a    = mkForAllTy alpha_tv (mkTyVarTy alpha_tv)
-          binder_names  = map fst (bagToList (collectMonoBinders mbind))
+          binder_names  = 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
+                           Nothing -> mkLocalId 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) ->
-
-       -- CHECK THAT THE SIGNATURES MATCH
-       -- (must do this before getTyVarsToGen)
-    checkSigMatch top_lvl binder_names mono_ids tc_ty_sigs     `thenTc` \ maybe_sig_theta ->   
-
-       -- 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
+    tcMonoBinds mbind tc_ty_sigs is_rec                `thenTc` \ (mbind', lie_req, binder_names, mono_ids) ->
     let
-       mono_id_tys = map idType mono_ids
-    in
-    getTyVarsToGen is_unrestricted mono_id_tys lie_req `thenNF_Tc` \ (tyvars_not_to_gen, tyvars_to_gen) ->
-
-       -- Finally, zonk the generalised type variables to real TyVars
-       -- This commits any unbound kind variables to boxed kind
-       -- I'm a little worried that such a kind variable might be
-       -- free in the environment, but I don't think it's possible for
-       -- this to happen when the type variable is not free in the envt
-       -- (which it isn't).            SLPJ Nov 98
-    mapTc zonkTcTyVarToTyVar (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
+       tau_tvs = varSetElems (foldr (unionVarSet . tyVarsOfType . idType) emptyVarSet mono_ids)
     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
-       case maybe_sig_theta of
-         Nothing ->
-               -- 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))
-
-         Just (sig_theta, lie_avail) ->
-               -- There are signatures, and their context is sig_theta
-               -- Furthermore, lie_avail is an LIE containing the 'method insts'
-               -- for the things bound here
-
-           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_`
+       -- GENERALISE
+    generalise binder_names mbind tau_tvs lie_req tc_ty_sigs
+                               `thenTc` \ (tc_tyvars_to_gen, lie_free, dict_binds, dict_ids) ->
 
-    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.
 
+       -- ZONK THE GENERALISED TYPE VARIABLES TO REAL TyVars
+       -- This commits any unbound kind variables to boxed kind, by unification
+       -- It's important that the final quanfified type variables
+       -- are fully zonked, *including boxity*, because they'll be 
+       -- included in the forall types of the polymorphic Ids.
+       -- At calls of these Ids we'll instantiate fresh type variables from
+       -- them, and we use their boxity then.
+    mapNF_Tc zonkTcTyVarToTyVar tc_tyvars_to_gen       `thenNF_Tc` \ real_tyvars_to_gen ->
+
+       -- ZONK THE Ids
+       -- It's important that the dict Ids are zonked, including the boxity set
+       -- in the previous step, because they are later used to form the type of 
+       -- the polymorphic thing, and forall-types must be zonked so far as 
+       -- their bound variables are concerned
+    mapNF_Tc zonkId dict_ids                           `thenNF_Tc` \ zonked_dict_ids ->
+    mapNF_Tc zonkId mono_ids                           `thenNF_Tc` \ zonked_mono_ids ->
+
+       -- CHECK FOR BOGUS UNLIFTED BINDINGS
+    checkUnliftedBinds top_lvl is_rec real_tyvars_to_gen mbind zonked_mono_ids `thenTc_`
 
-        -- BUILD THE POLYMORPHIC RESULT IDs
-    mapNF_Tc zonkId mono_ids           `thenNF_Tc` \ zonked_mono_ids ->
+       -- BUILD THE POLYMORPHIC RESULT IDs
     let
        exports  = zipWith mk_export binder_names zonked_mono_ids
-       dict_tys = map idType dicts_bound
+       dict_tys = map idType zonked_dict_ids
+
+       inlines    = mkNameSet [name | InlineSig name _ loc <- inline_sigs]
+        no_inlines = listToFM ([(name, IMustNotBeINLINEd False phase) | NoInlineSig name phase loc <- inline_sigs] ++
+                              [(name, IMustNotBeINLINEd True  phase) | InlineSig   name phase loc <- inline_sigs, maybeToBool phase])
+               -- "INLINE n foo" means inline foo, but not until at least phase n
+               -- "NOINLINE n foo" means don't inline foo until at least phase n, and even 
+               --                  then only if it is small enough etc.
+               -- "NOINLINE foo" means don't inline foo ever, which we signal with a (IMustNotBeINLINEd Nothing)
+               -- See comments in CoreUnfold.blackListed for the Authorised Version
 
        mk_export binder_name zonked_mono_id
          = (tyvars, 
-            setIdInfo poly_id (prag_info_fn binder_name),
+            attachNoInlinePrag no_inlines poly_id,
             zonked_mono_id)
          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)
+                 Nothing -> (real_tyvars_to_gen, new_poly_id)
 
-           new_poly_id = mkUserId binder_name poly_ty
-           poly_ty = mkForAllTys real_tyvars_to_gen_list 
+           new_poly_id = mkLocalId binder_name poly_ty
+           poly_ty = mkForAllTys real_tyvars_to_gen
                        $ mkFunTys dict_tys 
-                       $ idType (zonked_mono_id)
+                       $ 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_`
+
+    traceTc (text "binding:" <+> ppr ((zonked_dict_ids, dict_binds),
+            exports, [idType poly_id | (_, poly_id, _) <- exports])) `thenTc_`
 
         -- BUILD RESULTS
     returnTc (
-        AbsBinds real_tyvars_to_gen_list
-                 dicts_bound
-                 exports
-                 (dict_binds `andMonoBinds` mbind'),
-        lie_free,
-        [poly_id | (_, poly_id, _) <- exports]
+       AbsBinds real_tyvars_to_gen
+                zonked_dict_ids
+                exports
+                inlines
+                (dict_binds `andMonoBinds` mbind'),
+       lie_free,
+       [poly_id | (_, poly_id, _) <- exports]
     )
+
+attachNoInlinePrag no_inlines bndr
+  = case lookupFM no_inlines (idName bndr) of
+       Just prag -> bndr `setInlinePragma` prag
+       Nothing   -> bndr
+
+checkUnliftedBinds top_lvl is_rec real_tyvars_to_gen mbind zonked_mono_ids
+  = ASSERT( not (any ((== unliftedTypeKind) . tyVarKind) real_tyvars_to_gen) )
+               -- 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.
+
+       -- Check that pattern-bound variables are not unlifted
+    (if or [ (idName id `elem` pat_binders) && isUnLiftedType (idType id) 
+          | id <- zonked_mono_ids ] then
+       addErrTc (unliftedBindErr "Pattern" mbind)
+     else
+       returnTc ()
+    )                                                          `thenTc_`
+
+       -- Unlifted bindings must be non-recursive,
+       -- not top level, non-polymorphic, and not pattern bound
+    if any (isUnLiftedType . idType) zonked_mono_ids then
+       checkTc (isNotTopLevel top_lvl)
+               (unliftedBindErr "Top-level" mbind)             `thenTc_`
+       checkTc (isNonRec is_rec)
+               (unliftedBindErr "Recursive" mbind)             `thenTc_`
+       checkTc (null real_tyvars_to_gen)
+               (unliftedBindErr "Polymorphic" mbind)
+     else
+       returnTc ()
+
   where
-    tysig_names     = [name | (TySigInfo name _ _ _ _ _ _ _) <- tc_ty_sigs]
-    is_unrestricted = isUnRestrictedGroup tysig_names mbind
+    pat_binders :: [Name]
+    pat_binders = collectMonoBinders (justPatBindings mbind EmptyMonoBinds)
 
-justPatBindings bind@(PatMonoBind _ _ _) binds = bind `andMonoBinds` binds
-justPatBindings (AndMonoBinds b1 b2) binds = 
-       justPatBindings b1 (justPatBindings b2 binds) 
-justPatBindings other_bind binds = binds
+    justPatBindings bind@(PatMonoBind _ _ _) binds = bind `andMonoBinds` binds
+    justPatBindings (AndMonoBinds b1 b2) binds = 
+           justPatBindings b1 (justPatBindings b2 binds) 
+    justPatBindings other_bind binds = binds
 \end{code}
 
+
 Polymorphic recursion
 ~~~~~~~~~~~~~~~~~~~~~
 The game plan for polymorphic recursion in the code above is 
@@ -475,7 +410,113 @@ is doing.
 %*                                                                     *
 %************************************************************************
 
-@getTyVarsToGen@ decides what type variables generalise over.
+\begin{code}
+generalise_help doc tau_tvs lie_req sigs
+
+-----------------------
+  | null sigs
+  =    -- INFERENCE CASE: Unrestricted group, no type signatures
+    tcSimplifyInfer doc tau_tvs lie_req
+
+-----------------------
+  | otherwise
+  =    -- CHECKING CASE: Unrestricted group, there are type signatures
+       -- Check signature contexts are empty 
+    checkSigsCtxts sigs                                `thenTc` \ (sig_avails, sig_dicts) ->
+
+       -- Check that the needed dicts can be
+       -- expressed in terms of the signature ones
+    tcSimplifyInferCheck doc tau_tvs sig_avails lie_req        `thenTc` \ (forall_tvs, lie_free, dict_binds) ->
+       
+       -- Check that signature type variables are OK
+    checkSigsTyVars sigs                                       `thenTc_`
+
+    returnTc (forall_tvs, lie_free, dict_binds, sig_dicts)
+
+generalise binder_names mbind tau_tvs lie_req sigs
+  | is_unrestricted    -- UNRESTRICTED CASE
+  = generalise_help doc tau_tvs lie_req sigs
+
+  | otherwise          -- RESTRICTED CASE
+  =    -- Do a simplification to decide what type variables
+       -- are constrained.  We can't just take the free vars
+       -- of lie_req because that'll have methods that may
+       -- incidentally mention entirely unconstrained variables
+       --      e.g. a call to  f :: Eq a => a -> b -> b
+       -- Here, b is unconstrained.  A good example would be
+       --      foo = f (3::Int)
+       -- We want to infer the polymorphic type
+       --      foo :: forall b. b -> b
+    generalise_help doc tau_tvs lie_req sigs   `thenTc` \ (forall_tvs, lie_free, dict_binds, dict_ids) ->
+
+       -- Check signature contexts are empty 
+    checkTc (null sigs || null dict_ids)
+           (restrictedBindCtxtErr binder_names)        `thenTc_`
+
+       -- Identify constrained tyvars
+    let
+       constrained_tvs = varSetElems (tyVarsOfTypes (map idType dict_ids))
+                               -- The dict_ids are fully zonked
+       final_forall_tvs = forall_tvs `minusList` constrained_tvs
+    in
+
+       -- Now simplify with exactly that set of tyvars
+       -- We have to squash those Methods
+    tcSimplifyRestricted doc final_forall_tvs [] lie_req       `thenTc` \ (lie_free, binds) ->
+
+    returnTc (final_forall_tvs, lie_free, binds, [])
+
+  where
+    is_unrestricted | opt_NoMonomorphismRestriction = True
+                   | otherwise                     = isUnRestrictedGroup tysig_names mbind
+
+    tysig_names = [name | (TySigInfo name _ _ _ _ _ _ _) <- sigs]
+
+    doc = ptext SLIT("type signature(s) for") <+> pprBinders binder_names
+
+-----------------------
+       -- 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
+checkSigsCtxts sigs@(TySigInfo _ id1 sig_tvs theta1 _ _ _ _ : other_sigs)
+  = mapTc_ check_one other_sigs                `thenTc_` 
+    if null theta1 then
+       returnTc ([], [])               -- Non-overloaded type signatures
+    else
+    newDicts SignatureOrigin theta1    `thenNF_Tc` \ sig_dicts ->
+    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)
+       sig_avails = sig_dicts ++ sig_meths
+    in
+    returnTc (sig_avails, map instToId sig_dicts)
+  where
+    sig1_dict_tys = map mkPredTy theta1
+    n_sig1_theta  = length theta1
+    sig_meths    = concat [insts | TySigInfo _ _ _ _ _ _ insts _ <- sigs]
+
+    check_one sig@(TySigInfo _ id _ theta _ _ _ src_loc)
+       = tcAddSrcLoc src_loc                                   $
+        tcAddErrCtxt (sigContextsCtxt id1 id)                  $
+        checkTc (length theta == n_sig1_theta) sigContextsErr  `thenTc_`
+        unifyTauTyLists sig1_dict_tys (map mkPredTy theta)
+
+checkSigsTyVars sigs = mapTc_ check_one sigs
+  where
+    check_one (TySigInfo _ id sig_tyvars sig_theta sig_tau _ _ src_loc)
+      = tcAddSrcLoc src_loc                                                    $
+       tcAddErrCtxtM (sigCtxt (sig_msg id) sig_tyvars sig_theta sig_tau)       $
+       checkSigTyVars sig_tyvars (idFreeTyVars id)
+
+    sig_msg id = ptext SLIT("When checking the type signature for") <+> quotes (ppr id)
+\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
@@ -503,6 +544,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.
+  [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
@@ -513,45 +556,22 @@ constrained tyvars. We don't use any of the results, except to
 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
 
 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 (FunMonoBind v _ matches _)   = any isUnRestrictedMatch matches || 
+                                                         v `is_elem` sigs
 isUnRestrictedGroup sigs (AndMonoBinds mb1 mb2)                = isUnRestrictedGroup sigs mb1 &&
                                                          isUnRestrictedGroup sigs mb2
 isUnRestrictedGroup sigs EmptyMonoBinds                        = True
+
+isUnRestrictedMatch (Match _ [] Nothing _) = False     -- No args, no signature
+isUnRestrictedMatch other                 = True       -- Some args or a signature
 \end{code}
 
 
@@ -568,15 +588,14 @@ The signatures have been dealt with already.
 tcMonoBinds :: RenamedMonoBinds 
            -> [TcSigInfo]
            -> RecFlag
-           -> TcM s (TcMonoBinds, 
+           -> TcM (TcMonoBinds, 
                      LIE,              -- LIE required
                      [Name],           -- Bound names
-                     [TcId])   -- Corresponding monomorphic bound things
+                     [TcId])           -- 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
        id_list           = bagToList ids
        (names, mono_ids) = unzip id_list
 
@@ -609,9 +628,23 @@ tcMonoBinds mbinds tc_ty_sigs is_rec
 
     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
+
+       -- This function is used when dealing with a LHS binder; 
+       -- we make a monomorphic version of the Id.  
+       -- We check for a type signature; if there is one, we use the mono_id
+       -- from the signature.  This is how we make sure the tau part of the
+       -- signature actually maatches the type of the LHS; then tc_mb_pats
+       -- ensures the LHS and RHS have the same type
+       
+    tc_pat_bndr name pat_ty
+       = case maybeSig tc_ty_sigs name of
+           Nothing
+               -> newLocalId (getOccName name) pat_ty (getSrcLoc name)
+
+           Just (TySigInfo _ _ _ _ _ mono_id _ _)
+               -> tcAddSrcLoc (getSrcLoc name)         $
+                  unifyTauTy (idType mono_id) pat_ty   `thenTc_`
+                  returnTc mono_id
 
     mk_bind (name, mono_id) = case maybeSig tc_ty_sigs name of
                                Nothing                                   -> (name, mono_id)
@@ -635,8 +668,8 @@ tcMonoBinds mbinds tc_ty_sigs is_rec
                  lie_avail1 `plusLIE` lie_avail2)
 
     tc_mb_pats (FunMonoBind name inf matches locn)
-      = newTyVarTy boxedTypeKind       `thenNF_Tc` \ bndr_ty ->
-       tcVarPat sig_fn name bndr_ty    `thenTc` \ bndr_id ->
+      = newTyVarTy kind                `thenNF_Tc` \ bndr_ty -> 
+       tc_pat_bndr name bndr_ty        `thenTc` \ bndr_id ->
        let
           complete_it xve = tcAddSrcLoc locn                           $
                             tcMatchesFun xve name bndr_ty  matches     `thenTc` \ (matches', lie) ->
@@ -646,13 +679,7 @@ tcMonoBinds mbinds tc_ty_sigs is_rec
 
     tc_mb_pats bind@(PatMonoBind pat grhss locn)
       = tcAddSrcLoc locn               $
-
-               -- Figure out the appropriate kind for the pattern,
-               -- and generate a suitable type variable 
-       (case is_rec of
-            Recursive    -> newTyVarTy boxedTypeKind   -- Recursive, so no unboxed types
-            NonRecursive -> newTyVarTy_OpenKind        -- Non-recursive, so we permit unboxed types
-       )                                       `thenNF_Tc` \ pat_ty ->
+       newTyVarTy kind                 `thenNF_Tc` \ pat_ty -> 
 
                --      Now typecheck the pattern
                -- We don't support binding fresh type variables in the
@@ -664,7 +691,7 @@ tcMonoBinds mbinds tc_ty_sigs is_rec
                -- We don't check explicitly for this problem.  Instead, we simply
                -- type check the pattern with tcPat.  If the pattern mentions any
                -- fresh tyvars we simply get an out-of-scope type variable error
-       tcPat sig_fn pat pat_ty         `thenTc` \ (pat', lie_req, tvs, ids, lie_avail) ->
+       tcPat tc_pat_bndr pat pat_ty            `thenTc` \ (pat', lie_req, tvs, ids, lie_avail) ->
        let
           complete_it xve = tcAddSrcLoc locn                           $
                             tcAddErrCtxt (patMonoBindsCtxt bind)       $
@@ -673,104 +700,12 @@ tcMonoBinds mbinds tc_ty_sigs is_rec
                             returnTc (PatMonoBind pat' grhss' 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 top_lvl binder_names mono_ids sigs
-  | main_bound_here
-  =    -- First unify the main_id with IO t, for any old t
-    tcSetErrCtxt mainTyCheckCtxt (
-       tcLookupTyCon ioTyCon_NAME              `thenTc`    \ ioTyCon ->
-       newTyVarTy boxedTypeKind                `thenNF_Tc` \ t_tv ->
-       unifyTauTy ((mkTyConApp ioTyCon [t_tv]))
-                  (idType main_mono_id)
-    )                                          `thenTc_`
-
-       -- Now check the signatures
-       -- Must do this after the unification with IO t, 
-       -- in case of a silly signature like
-       --      main :: forall a. a
-       -- The unification to IO t will bind the type variable 'a',
-       -- which is just waht check_one_sig looks for
-    mapTc check_one_sig sigs                   `thenTc_`
-    mapTc check_main_ctxt sigs                 `thenTc_` 
-
-           returnTc (Just ([], emptyLIE))
-
-  | not (null sigs)
-  = mapTc check_one_sig sigs                   `thenTc_`
-    mapTc check_one_ctxt all_sigs_but_first    `thenTc_`
-    returnTc (Just (theta1, sig_lie))
-
-  | otherwise
-  = returnTc Nothing           -- No constraints from type sigs
-
-  where
-    (TySigInfo _ id1 _ theta1 _ _ _ _ : all_sigs_but_first) = sigs
-
-    sig1_dict_tys      = mk_dict_tys theta1
-    n_sig1_dict_tys    = length sig1_dict_tys
-    sig_lie            = mkLIE [inst | TySigInfo _ _ _ _ _ _ inst _ <- sigs]
-
-    maybe_main        = find_main top_lvl binder_names mono_ids
-    main_bound_here   = maybeToBool maybe_main
-    Just main_mono_id = maybe_main
-                     
-       -- CHECK THAT THE SIGNATURE TYVARS AND TAU_TYPES ARE OK
-       -- Doesn't affect substitution
-    check_one_sig (TySigInfo _ id sig_tyvars _ sig_tau _ _ src_loc)
-      = tcAddSrcLoc src_loc                                    $
-       tcAddErrCtxtM (sigCtxt (sig_msg id) (idType id))        $
-       checkSigTyVars sig_tyvars
-
-
-       -- 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
-    check_one_ctxt 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 THAT FOR A GROUP INVOLVING Main.main, all 
-       -- the signature contexts are empty (what a bore)
-    check_main_ctxt sig@(TySigInfo _ id _ theta _ _ _ src_loc)
-       = tcAddSrcLoc src_loc   $
-         checkTc (null theta) (mainContextsErr id)
-
-    mk_dict_tys theta = [mkDictTy c ts | (c,ts) <- theta]
-
-    sig_msg id tidy_ty = sep [ptext SLIT("When checking the type signature"),
-                             nest 4 (ppr id <+> dcolon <+> ppr tidy_ty)]
-
-       -- Search for Main.main in the binder_names, return corresponding mono_id
-    find_main NotTopLevel binder_names mono_ids = Nothing
-    find_main TopLevel    binder_names mono_ids = go binder_names mono_ids
-    go [] [] = Nothing
-    go (n:ns) (m:ms) | n == main_NAME = Just m
-                    | otherwise      = go ns ms
+       -- Figure out the appropriate kind for the pattern,
+       -- and generate a suitable type variable 
+    kind = case is_rec of
+               Recursive    -> liftedTypeKind  -- Recursive, so no unlifted types
+               NonRecursive -> openTypeKind    -- Non-recursive, so we permit unlifted types
 \end{code}
 
 
@@ -780,28 +715,13 @@ checkSigMatch top_lvl binder_names mono_ids sigs
 %*                                                                     *
 %************************************************************************
 
-
-@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.
 
-\begin{code}
-tcPragmaSigs :: [RenamedSig]           -- The pragma signatures
-            -> TcM s (Name -> IdInfo,  -- Maps name to the appropriate IdInfo
-                      TcMonoBinds,
-                      LIE)
-
-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 #-}
@@ -824,88 +744,41 @@ 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.
 
-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:
+       {-# SPECIALISE (f::<type) = g #-}
 
 \begin{code}
-tcPragmaSig :: RenamedSig -> TcM s (Maybe (Name, IdInfo -> IdInfo), TcMonoBinds, LIE)
-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 :: [RenamedSig] -> TcM (TcMonoBinds, LIE)
+tcSpecSigs (SpecSig name poly_ty src_loc : sigs)
   =    -- SPECIALISE f :: forall b. theta => tau  =  g
     tcAddSrcLoc src_loc                                $
     tcAddErrCtxt (valSpecSigCtxt name poly_ty) $
 
        -- Get and instantiate its alleged specialised type
-    tcHsType poly_ty                           `thenTc` \ sig_ty ->
+    tcHsSigType poly_ty                                `thenTc` \ sig_ty ->
 
        -- 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 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
-                   tcLookupValue 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)
+       -- Squeeze out any Methods (see comments with tcSimplifyToDicts)
+    tcSimplifyToDicts spec_lie                 `thenTc` \ (spec_dicts, 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.
+    newSpecPragmaId name sig_ty                `thenNF_Tc` \ spec_id ->
+
+       -- Do the rest and combine
+    tcSpecSigs sigs                    `thenTc` \ (binds_rest, lie_rest) ->
+    returnTc (binds_rest `andMonoBinds` VarMonoBind spec_id (mkHsLet spec_binds spec_expr),
+             lie_rest   `plusLIE`      mkLIE spec_dicts)
+
+tcSpecSigs (other_sig : sigs) = tcSpecSigs sigs
+tcSpecSigs []                = returnTc (EmptyMonoBinds, emptyLIE)
 \end{code}
 
 
@@ -926,55 +799,31 @@ valSpecSigCtxt v ty
         nest 4 (ppr v <+> dcolon <+> 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)
-          ])
-
------------------------------------------------
-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
-
------------------------------------------------
-sigContextsErr
-  = ptext SLIT("Mismatched contexts")
+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)"))
 
-mainContextsErr id
-  | getName id == main_NAME = ptext SLIT("Main.main cannot be overloaded")
-  | otherwise
-  = quotes (ppr id) <+> ptext SLIT("cannot be overloaded") <> char ',' <> -- sigh; workaround for cpp's inability to deal
-    ptext SLIT("because it is mutually recursive with Main.main")         -- with commas inside SLIT strings.
-
-mainTyCheckCtxt
-  = hsep [ptext SLIT("When checking that"), ppr main_NAME, ptext SLIT("has the required type")]
-
 -----------------------------------------------
 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)
 
+-----------------------------------------------
 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")])
+
+-- Used in error messages
+pprBinders bndrs = pprWithCommas ppr bndrs
 \end{code}