From 831297f162bbaa1e41e0937d2207df8a2532e9b8 Mon Sep 17 00:00:00 2001
From: simonpj <unknown>
Date: Tue, 16 Mar 1999 12:31:55 +0000
Subject: [PATCH] [project @ 1999-03-16 12:31:55 by simonpj] Make it only a
 warning if you have a type like this:

	forall a. Int -> Int

These show up in interface files occasionally, just because
the simplifier is a bit blase about adding type arguments.

But it's an error to have

	forall a. Eq a => Int -> Int

The flag -fwarn-unused-matches reports a warning for these
redundant for-alls.
---
 ghc/compiler/rename/RnSource.lhs | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/ghc/compiler/rename/RnSource.lhs b/ghc/compiler/rename/RnSource.lhs
index 1dddb2291d9c..b43f6cbe4055 100644
--- a/ghc/compiler/rename/RnSource.lhs
+++ b/ghc/compiler/rename/RnSource.lhs
@@ -48,8 +48,10 @@ import PrelInfo		( derivingOccurrences, numClass_RDR,
 			  bindIO_NAME
 			)
 import Bag		( bagToList )
+import List		( partition )
 import Outputable
 import SrcLoc		( SrcLoc )
+import CmdLineOpts	( opt_WarnUnusedMatches )	-- Warn of unused for-all'd tyvars
 import UniqFM		( lookupUFM )
 import Maybes		( maybeToBool, catMaybes )
 import Util
@@ -540,12 +542,19 @@ rnHsType doc (HsForAllTy (Just forall_tyvars) ctxt ty)
 	-- Explicit quantification.
 	-- Check that the forall'd tyvars are a subset of the
 	-- free tyvars in the tau-type part
+	-- That's only a warning... unless the tyvar is constrained by a 
+	-- context in which case it's an error
   = let
-	mentioned_tyvars   = extractHsTyVars ty
-	bad_guys	   = filter (`notElem` mentioned_tyvars) forall_tyvar_names
-	forall_tyvar_names = map getTyVarName forall_tyvars
+	mentioned_tyvars      = extractHsTyVars ty
+	constrained_tyvars    = [tv | (_,tys) <- ctxt,
+				      ty <- tys,
+				      tv <- extractHsTyVars ty]
+	dubious_guys	      = filter (`notElem` mentioned_tyvars) forall_tyvar_names
+	(bad_guys, warn_guys) = partition (`elem` constrained_tyvars) dubious_guys
+	forall_tyvar_names    = map getTyVarName forall_tyvars
     in
-    mapRn (forAllErr doc ty) bad_guys				`thenRn_`
+    mapRn (forAllErr doc ty) bad_guys 				`thenRn_`
+    mapRn (forAllWarn doc ty) warn_guys				`thenRn_`
     checkConstraints True doc forall_tyvar_names ctxt ty	`thenRn` \ ctxt' ->
     rnForAll doc forall_tyvars ctxt' ty
 
@@ -791,9 +800,18 @@ dupClassAssertWarn ctxt (assertion : dups)
 badDataCon name
    = hsep [ptext SLIT("Illegal data constructor name"), quotes (ppr name)]
 
+forAllWarn doc ty tyvar
+  | not opt_WarnUnusedMatches = returnRn ()
+  | otherwise
+  = addWarnRn (
+      sep [ptext SLIT("The universally quantified type variable") <+> quotes (ppr tyvar),
+	   nest 4 (ptext SLIT("does not appear in the type") <+> quotes (ppr ty))]
+      $$
+      (ptext SLIT("In") <+> doc))
+
 forAllErr doc ty tyvar
   = addErrRn (
-      sep [ptext SLIT("The universally quantified type variable") <+> quotes (ppr tyvar),
+      sep [ptext SLIT("The constrained type variable") <+> quotes (ppr tyvar),
 	   nest 4 (ptext SLIT("does not appear in the type") <+> quotes (ppr ty))]
       $$
       (ptext SLIT("In") <+> doc))
-- 
GitLab