diff --git a/ghc/compiler/typecheck/TcMatches.lhs b/ghc/compiler/typecheck/TcMatches.lhs
index edebb87d88ef178e2f3e11679ae5c399e3ae4e41..eddaca16759c37fcca5b051c38c2e0bbd73091e4 100644
--- a/ghc/compiler/typecheck/TcMatches.lhs
+++ b/ghc/compiler/typecheck/TcMatches.lhs
@@ -19,7 +19,7 @@ import RnHsSyn		( RenamedMatch, RenamedGRHSs, RenamedStmt )
 import TcHsSyn		( TcMatch, TcGRHSs, TcStmt )
 
 import TcMonad
-import TcMonoType	( kcHsSigType, kcTyVarScope, checkSigTyVars, tcHsTyVar, tcHsSigType, sigPatCtxt )
+import TcMonoType	( kcHsSigType, kcTyVarScope, newSigTyVars, checkSigTyVars, tcHsSigType, sigPatCtxt )
 import Inst		( Inst, LIE, plusLIE, emptyLIE, plusLIEs )
 import TcEnv		( tcExtendTyVarEnv, tcExtendLocalValEnv, tcExtendGlobalTyVars, tcGetGlobalTyVars )
 import TcPat		( tcPat, tcPatBndr_NoSigs, polyPatSig )
@@ -141,10 +141,9 @@ tcMatch xve1 match@(Match sig_tvs pats maybe_rhs_sig grhss) expected_ty ctxt
 	newTyVarTy openTypeKind		`thenNF_Tc` \ tyvar_ty ->
 
 	-- Extend the tyvar env and check the match itself
-	kcTyVarScope sig_tvs (mapTc_ kcHsSigType sig_tys)	`thenTc` \ sig_tyvars ->
-	tcExtendTyVarEnv sig_tyvars (
-		tc_match tyvar_ty	
-	)				`thenTc` \ (pat_ids, match_and_lie) ->
+	kcTyVarScope sig_tvs (mapTc_ kcHsSigType sig_tys)	`thenTc` \ sig_tv_kinds ->
+	newSigTyVars sig_tv_kinds				`thenNF_Tc` \ sig_tyvars ->
+	tcExtendTyVarEnv sig_tyvars (tc_match tyvar_ty)		`thenTc` \ (pat_ids, match_and_lie) ->
 
 	-- Check that the scoped type variables from the patterns
 	-- have not been constrained
diff --git a/ghc/compiler/typecheck/TcModule.lhs b/ghc/compiler/typecheck/TcModule.lhs
index f4a3934faebe4d0d2e86cc0b527d226ea52f9468..86f20cace2d081b8735343b771de81eab0ad0391 100644
--- a/ghc/compiler/typecheck/TcModule.lhs
+++ b/ghc/compiler/typecheck/TcModule.lhs
@@ -147,7 +147,7 @@ tcModule rn_name_supply fixities
 		 -- Type-check the type and class decls
 	tcTyAndClassDecls unf_env decls	`thenTc` \ env ->
     
-		    -- Typecheck the instance decls, includes deriving
+		 -- Typecheck the instance decls, includes deriving
 	tcSetEnv env $
 
 	tcInstDecls1 unf_env decls 
diff --git a/ghc/compiler/typecheck/TcMonoType.lhs b/ghc/compiler/typecheck/TcMonoType.lhs
index ee3b281ac78703cf3ab05d5076cfaf7fb94806ec..17189bd9f4ee60357ff9ae6edd9ed6f3be0facd1 100644
--- a/ghc/compiler/typecheck/TcMonoType.lhs
+++ b/ghc/compiler/typecheck/TcMonoType.lhs
@@ -5,12 +5,12 @@
 
 \begin{code}
 module TcMonoType ( tcHsType, tcHsSigType, tcHsBoxedSigType, 
-		    tcContext, tcClassContext, tcHsTyVar, 
+		    tcContext, tcClassContext,
 
 			-- Kind checking
 		    kcHsTyVar, kcHsTyVars, mkTyClTyVars,
 		    kcHsType, kcHsSigType, kcHsBoxedSigType, kcHsContext,
-		    kcTyVarScope, 
+		    kcTyVarScope, newSigTyVars, mkImmutTyVars,
 
 		    TcSigInfo(..), tcTySig, mkTcSig, maybeSig,
 		    checkSigTyVars, sigCtxt, sigPatCtxt
@@ -69,12 +69,73 @@ import Outputable
 
 %************************************************************************
 %*									*
-\subsection{Checking types}
+\subsection{Kind checking}
 %*									*
 %************************************************************************
 
+Kind checking
+~~~~~~~~~~~~~
+When we come across the binding site for some type variables, we
+proceed in two stages
+
+1. Figure out what kind each tyvar has
+
+2. Create suitably-kinded tyvars, 
+   extend the envt, 
+   and typecheck the body
+
+To do step 1, we proceed thus:
+
+1a. Bind each type variable to a kind variable
+1b. Apply the kind checker
+1c. Zonk the resulting kinds
+
+The kind checker is passed to kcTyVarScope as an argument.  
+
+For example, when we find
+	(forall a m. m a -> m a)
+we bind a,m to kind varibles and kind-check (m a -> m a).  This
+makes a get kind *, and m get kind *->*.  Now we typecheck (m a -> m a)
+in an environment that binds a and m suitably.
+
+The kind checker passed to kcTyVarScope needs to look at enough to
+establish the kind of the tyvar:
+  * For a group of type and class decls, it's just the group, not
+	the rest of the program
+  * For a tyvar bound in a pattern type signature, its the types
+	mentioned in the other type signatures in that bunch of patterns
+  * For a tyvar bound in a RULE, it's the type signatures on other
+	universally quantified variables in the rule
+
+Note that this may occasionally give surprising results.  For example:
+
+	data T a b = MkT (a b)
+
+Here we deduce			a::*->*, b::*.
+But equally valid would be
+				a::(*->*)-> *, b::*->*
+
 \begin{code}
+kcTyVarScope :: [HsTyVarBndr Name] 
+	     -> TcM s a				-- The kind checker
+	     -> TcM s [(Name,Kind)]
+	-- Do a kind check to find out the kinds of the type variables
+	-- Then return a bunch of name-kind pairs, from which to 
+	-- construct the type variables.  We don't return the tyvars
+	-- themselves because sometimes we want mutable ones and 
+	-- sometimes we want immutable ones.
 
+kcTyVarScope [] kind_check = returnTc []
+	-- A useful short cut for a common case!
+  
+kcTyVarScope tv_names kind_check 
+  = kcHsTyVars tv_names 				`thenNF_Tc` \ tv_names_w_kinds ->
+    tcExtendKindEnv tv_names_w_kinds kind_check		`thenTc_`
+    zonkKindEnv tv_names_w_kinds
+\end{code}
+    
+
+\begin{code}
 kcHsTyVar  :: HsTyVarBndr name   -> NF_TcM s (name, TcKind)
 kcHsTyVars :: [HsTyVarBndr name] -> NF_TcM s [(name, TcKind)]
 
@@ -189,24 +250,6 @@ kcHsPred pred@(HsPClass cls tys)
     unifyKind kind (mkArrowKinds arg_kinds boxedTypeKind)
 \end{code}
 
-\begin{code}
-kcTyVarScope :: [HsTyVarBndr Name] 
-	     -> TcM s a				-- The kind checker
-	     -> TcM s [TyVar]
-	-- Do a kind check to find out the kinds of the type variables
-	-- Then return the type variables
-
-kcTyVarScope [] kind_check = returnTc []
-	-- A useful short cut for a common case!
-  
-kcTyVarScope tv_names kind_check 
-  = kcHsTyVars tv_names 				`thenNF_Tc` \ tv_names_w_kinds ->
-    tcExtendKindEnv tv_names_w_kinds kind_check		`thenTc_`
-    zonkKindEnv tv_names_w_kinds			`thenNF_Tc` \ zonked_pairs ->
-    returnTc (map mk_tyvar zonked_pairs)
-\end{code}
-    
-
 %************************************************************************
 %*									*
 \subsection{Checking types}
@@ -287,13 +330,14 @@ tcHsType (HsUsgForAllTy uv_name ty)
     tcHsType ty                     `thenTc` \ tc_ty ->
     returnTc (mkUsForAllTy uv tc_ty)
 
-tcHsType full_ty@(HsForAllTy (Just tv_names) context ty)
-  = let
-	kind_check = kcHsContext context `thenTc_` kcHsType ty
+tcHsType full_ty@(HsForAllTy (Just tv_names) ctxt ty)
+  = kcTyVarScope tv_names 
+		 (kcHsContext ctxt `thenTc_` kcHsType ty)  `thenTc` \ tv_kinds ->
+    let
+	forall_tyvars = mkImmutTyVars tv_kinds
     in
-    kcTyVarScope tv_names kind_check 	`thenTc` \ forall_tyvars ->
     tcExtendTyVarEnv forall_tyvars	$
-    tcContext context			`thenTc` \ theta ->
+    tcContext ctxt			`thenTc` \ theta ->
     tcHsType ty				`thenTc` \ tau ->
     let
 	-- Check for ambiguity
@@ -387,7 +431,7 @@ tc_fun_type (HsTyVar name) arg_tys
 			--	data Tree a b = ...
 			--	type Foo a = Tree [a]
 			--	f :: Foo a b -> ...
-		    err_msg = arityErr "type synonym" name arity n_args
+		    err_msg = arityErr "Type synonym" name arity n_args
 		    n_args  = length arg_tys
 
 	other -> failWithTc (wrongThingErr "type constructor" thing name)
@@ -438,24 +482,19 @@ tcClassAssertion ccall_ok assn@(HsPIParam name ty)
 %************************************************************************
 
 \begin{code}
-mk_tyvar (tv_bndr, kind) = mkTyVar tv_bndr kind
+mkImmutTyVars :: [(Name,Kind)] -> [TyVar]
+newSigTyVars  :: [(Name,Kind)] -> NF_TcM s [TcTyVar]
+
+mkImmutTyVars pairs = [mkTyVar name kind | (name, kind) <- pairs]
+newSigTyVars  pairs = listNF_Tc [tcNewSigTyVar name kind | (name,kind) <- pairs]
 
 mkTyClTyVars :: Kind 			-- Kind of the tycon or class
 	     -> [HsTyVarBndr Name]
 	     -> [TyVar]
 mkTyClTyVars kind tyvar_names
-  = map mk_tyvar tyvars_w_kinds
+  = mkImmutTyVars tyvars_w_kinds
   where
     (tyvars_w_kinds, _) = zipFunTys (hsTyVarNames tyvar_names) kind
-
-tcHsTyVar :: HsTyVarBndr Name -> NF_TcM s TcTyVar
-tcHsTyVar (UserTyVar name)       = newKindVar		`thenNF_Tc` \ kind ->
-			           tcNewMutTyVar name kind
-	-- NB: mutable kind => mutable tyvar, so that zonking can bind
-	-- the tyvar to its immutable form
-
-tcHsTyVar (IfaceTyVar name kind) = returnNF_Tc (mkTyVar name kind)
-
 \end{code}
 
 
diff --git a/ghc/compiler/typecheck/TcRules.lhs b/ghc/compiler/typecheck/TcRules.lhs
index ec9176134b19f16f31a5ba00f34e8a250d86b212..808165d1eddcbcf50e51d6e328468627ab51c6ad 100644
--- a/ghc/compiler/typecheck/TcRules.lhs
+++ b/ghc/compiler/typecheck/TcRules.lhs
@@ -14,9 +14,9 @@ import RnHsSyn		( RenamedHsDecl )
 import TcHsSyn		( TypecheckedRuleDecl, mkHsLet )
 import TcMonad
 import TcSimplify	( tcSimplifyToDicts, tcSimplifyAndCheck )
-import TcType		( zonkTcTypes, newTyVarTy )
+import TcType		( zonkTcTypes, zonkTcTyVarToTyVar, newTyVarTy )
 import TcIfaceSig	( tcCoreExpr, tcCoreLamBndrs, tcVar )
-import TcMonoType	( tcHsSigType, tcHsTyVar, checkSigTyVars )
+import TcMonoType	( kcTyVarScope, kcHsSigType, tcHsSigType, newSigTyVars, checkSigTyVars )
 import TcExpr		( tcExpr )
 import TcEnv		( tcExtendLocalValEnv, newLocalId,
 			  tcExtendTyVarEnv
@@ -55,11 +55,13 @@ tcRule (HsRule name sig_tvs vars lhs rhs src_loc)
 
 	-- Deal with the tyvars mentioned in signatures
 	-- Yuk to the UserTyVar
-    mapNF_Tc (tcHsTyVar . UserTyVar) sig_tvs 		`thenNF_Tc` \ sig_tyvars ->
+    kcTyVarScope (map UserTyVar sig_tvs)
+		 (mapTc_ kcHsSigType sig_tys)	`thenTc` \ sig_tv_kinds ->
+    newSigTyVars sig_tv_kinds			`thenNF_Tc` \ sig_tyvars ->
     tcExtendTyVarEnv sig_tyvars 		(	
 
 		-- Ditto forall'd variables
-	mapNF_Tc new_id vars				`thenNF_Tc` \ ids ->
+	mapNF_Tc new_id vars					`thenNF_Tc` \ ids ->
 	tcExtendLocalValEnv [(idName id, id) | id <- ids]	$
 	
 		-- Now LHS and RHS
@@ -90,22 +92,23 @@ tcRule (HsRule name sig_tvs vars lhs rhs src_loc)
     in
 
 	-- Gather type variables to quantify over
-    zonkTcTypes (rule_ty : map idType tpl_ids)		`thenNF_Tc` \ zonked_tys ->
-    let
-	tpl_tvs = tyVarsOfTypes zonked_tys
-    in
+	-- and turn them into real TyVars (just as in TcBinds.tcBindWithSigs)
+    zonkTcTypes (rule_ty : map idType tpl_ids)				`thenNF_Tc` \ zonked_tys ->
+    mapTc zonkTcTyVarToTyVar (varSetElems (tyVarsOfTypes zonked_tys))	`thenTc` \ tvs ->
 
 	-- RHS can be a bit more lenient.  In particular,
 	-- we let constant dictionaries etc float outwards
-    tcSimplifyAndCheck (text "tcRule") tpl_tvs 
+    tcSimplifyAndCheck (text "tcRule") (mkVarSet tvs)
 		       lhs_dicts rhs_lie		`thenTc` \ (lie', rhs_binds) ->
 
-    returnTc (lie', HsRule	name (varSetElems tpl_tvs)
+    returnTc (lie', HsRule	name tvs
 				(map RuleBndr tpl_ids)	-- yuk
 				(mkHsLet lhs_binds lhs')
 				(mkHsLet rhs_binds rhs')
 				src_loc)
   where
+    sig_tys = [t | RuleBndrSig _ t <- vars]
+
     new_id (RuleBndr var) 	   = newTyVarTy openTypeKind	`thenNF_Tc` \ ty ->
 		          	     returnNF_Tc (mkVanillaId var ty)
     new_id (RuleBndrSig var rn_ty) = tcHsSigType rn_ty	`thenTc` \ ty ->
diff --git a/ghc/compiler/typecheck/TcTyDecls.lhs b/ghc/compiler/typecheck/TcTyDecls.lhs
index 5efdb208f0bcb88bc08c70349cdca200efb86669..2340aef36a80610de61f614fa978fa05b7c8f2cc 100644
--- a/ghc/compiler/typecheck/TcTyDecls.lhs
+++ b/ghc/compiler/typecheck/TcTyDecls.lhs
@@ -21,7 +21,7 @@ import TcHsSyn		( TcMonoBinds, idsToMonoBinds )
 import BasicTypes	( RecFlag(..), NewOrData(..) )
 
 import TcMonoType	( tcHsSigType, tcHsBoxedSigType, kcTyVarScope, tcClassContext,
-			  kcHsContext, kcHsSigType
+			  kcHsContext, kcHsSigType, mkImmutTyVars
 			)
 import TcEnv		( tcExtendTyVarEnv, tcLookupTy, tcLookupValueByKey, TyThing(..), TyThingDetails(..) )
 import TcMonad
@@ -141,7 +141,10 @@ tcConDecl :: TyCon -> [TyVar] -> ClassContext -> RenamedConDecl -> TcM s DataCon
 
 tcConDecl tycon tyvars ctxt (ConDecl name wkr_name ex_tvs ex_ctxt details src_loc)
   = tcAddSrcLoc src_loc					$
-    kcTyVarScope ex_tvs (kcConDetails ex_ctxt details)	`thenTc` \ ex_tyvars -> 
+    kcTyVarScope ex_tvs (kcConDetails ex_ctxt details)	`thenTc` \ ex_tv_kinds ->
+    let
+	ex_tyvars = mkImmutTyVars ex_tv_kinds
+    in
     tcExtendTyVarEnv ex_tyvars				$
     tcClassContext ex_ctxt				`thenTc` \ ex_theta ->
     case details of
diff --git a/ghc/compiler/typecheck/TcUnify.lhs b/ghc/compiler/typecheck/TcUnify.lhs
index 7c92681dd5719e5ba095c93a1a8453c08d4d490b..a9aa01ef41b5048ccded3c3f8cb6bd76efc911c0 100644
--- a/ghc/compiler/typecheck/TcUnify.lhs
+++ b/ghc/compiler/typecheck/TcUnify.lhs
@@ -325,8 +325,10 @@ uUnboundVar swapped tv1 maybe_ty1 ps_ty2 non_var_ty2
     checkTcM (not (isSigTyVar tv1))
 	     (failWithTcM (unifyWithSigErr tv1 ps_ty2))	`thenTc_`
 
-    WARN( not (typeKind non_var_ty2 `hasMoreBoxityInfo` tyVarKind tv1), (ppr tv1 <+> ppr (tyVarKind tv1)) $$
-									(ppr non_var_ty2 <+> ppr (typeKind non_var_ty2)) )
+    warnTc (not (typeKind non_var_ty2 `hasMoreBoxityInfo` tyVarKind tv1))
+	   ((ppr tv1 <+> ppr (tyVarKind tv1)) $$ 
+	     (ppr non_var_ty2 <+> ppr (typeKind non_var_ty2)))		`thenNF_Tc_` 
+
     tcPutTyVar tv1 non_var_ty2				`thenNF_Tc_`
 	-- This used to say "ps_ty2" instead of "non_var_ty2"