Add -fwarn-context-quantification (#4426)
authorKrzysztof Gogolewski <krz.gogolewski@gmail.com>
Thu, 18 Sep 2014 21:52:50 +0000 (14:52 -0700)
committerEdward Z. Yang <ezyang@cs.stanford.edu>
Thu, 18 Sep 2014 21:53:46 +0000 (14:53 -0700)
Summary:
This warning (enabled by default) reports places where a context
implicitly binds a type variable, for example

type T a = {-forall m.-} Monad m => a -> m a

Also update Haddock submodule.

Test Plan: validate

Reviewers: hvr, goldfire, simonpj, austin

Reviewed By: austin

Subscribers: simonmar, ezyang, carter

Differential Revision: https://phabricator.haskell.org/D211

GHC Trac Issues: #4426

19 files changed:
compiler/hsSyn/HsDecls.lhs
compiler/hsSyn/HsTypes.lhs
compiler/main/DynFlags.hs
compiler/main/GhcMonad.hs
compiler/parser/Parser.y.pp
compiler/parser/RdrHsSyn.lhs
compiler/rename/RnSource.lhs
compiler/rename/RnTypes.lhs
docs/users_guide/7.10.1-notes.xml
docs/users_guide/glasgow_exts.xml
docs/users_guide/using.xml
testsuite/tests/rename/should_compile/T4426.hs [new file with mode: 0644]
testsuite/tests/rename/should_compile/T4426.stderr [new file with mode: 0644]
testsuite/tests/rename/should_compile/all.T
testsuite/tests/th/T7021a.hs
testsuite/tests/th/T8807.hs
testsuite/tests/typecheck/should_compile/T3018.hs
testsuite/tests/typecheck/should_compile/tc092.hs
utils/haddock

index 3d41287..52807ff 100644 (file)
@@ -50,6 +50,7 @@ module HsDecls (
   -- ** @default@ declarations
   DefaultDecl(..), LDefaultDecl,
   -- ** Template haskell declaration splice
+  SpliceExplicitFlag(..),
   SpliceDecl(..), LSpliceDecl,
   -- ** Foreign function interface declarations
   ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..),
@@ -294,12 +295,15 @@ instance OutputableBndr name => Outputable (HsGroup name) where
           vcat_mb gap (Nothing : ds) = vcat_mb gap ds
           vcat_mb gap (Just d  : ds) = gap $$ d $$ vcat_mb blankLine ds
 
+data SpliceExplicitFlag = ExplicitSplice | -- <=> $(f x y)
+                          ImplicitSplice   -- <=> f x y,  i.e. a naked top level expression
+    deriving (Data, Typeable)
+
 type LSpliceDecl name = Located (SpliceDecl name)
 data SpliceDecl id
   = SpliceDecl                  -- Top level splice
         (Located (HsSplice id))
-        HsExplicitFlag          -- Explicit <=> $(f x y)
-                                -- Implicit <=> f x y,  i.e. a naked top level expression
+        SpliceExplicitFlag
     deriving (Typeable)
 deriving instance (DataId id) => Data (SpliceDecl id)
 
index fdd613a..9bd5845 100644 (file)
@@ -33,7 +33,8 @@ module HsTypes (
         ConDeclField(..), pprConDeclFields,
         
         mkHsQTvs, hsQTvBndrs, isHsKindedTyVar, hsTvbAllKinded,
-        mkExplicitHsForAllTy, mkImplicitHsForAllTy, hsExplicitTvs,
+        mkExplicitHsForAllTy, mkImplicitHsForAllTy, mkQualifiedHsForAllTy,
+        hsExplicitTvs,
         hsTyVarName, mkHsWithBndrs, hsLKiTyVarNames,
         hsLTyVarName, hsLTyVarNames, hsLTyVarLocName, hsLTyVarLocNames,
         splitLHsInstDeclTy_maybe,
@@ -301,6 +302,13 @@ After renaming
   * Implicit => the *type* variables free in the type
     Explicit => the variables the user wrote (renamed)
 
+Qualified currently behaves exactly as Implicit,
+but it is deprecated to use it for implicit quantification.
+In this case, GHC 7.10 gives a warning; see
+Note [Context quantification] and Trac #4426.
+In GHC 7.12, Qualified will no longer bind variables
+and this will become an error.
+
 The kind variables bound in the hsq_kvs field come both
   a) from the kind signatures on the kind vars (eg k1)
   b) from the scope of the forall (eg k2)
@@ -386,7 +394,7 @@ data HsTupleSort = HsUnboxedTuple
                  | HsBoxedOrConstraintTuple
                  deriving (Data, Typeable)
 
-data HsExplicitFlag = Explicit | Implicit deriving (Data, Typeable)
+data HsExplicitFlag = Qualified | Implicit | Explicit deriving (Data, Typeable)
 
 data ConDeclField name  -- Record fields have Haddoc docs on them
   = ConDeclField { cd_fld_name :: Located name,
@@ -405,10 +413,12 @@ deriving instance (DataId name) => Data (ConDeclField name)
 --
 -- A valid type must have one for-all at the top of the type, or of the fn arg types
 
-mkImplicitHsForAllTy ::                           LHsContext RdrName -> LHsType RdrName -> HsType RdrName
-mkExplicitHsForAllTy :: [LHsTyVarBndr RdrName] -> LHsContext RdrName -> LHsType RdrName -> HsType RdrName
-mkImplicitHsForAllTy     ctxt ty = mkHsForAllTy Implicit []  ctxt ty
-mkExplicitHsForAllTy tvs ctxt ty = mkHsForAllTy Explicit tvs ctxt ty
+mkImplicitHsForAllTy  ::                           LHsContext RdrName -> LHsType RdrName -> HsType RdrName
+mkExplicitHsForAllTy  :: [LHsTyVarBndr RdrName] -> LHsContext RdrName -> LHsType RdrName -> HsType RdrName
+mkQualifiedHsForAllTy ::                           LHsContext RdrName -> LHsType RdrName -> HsType RdrName
+mkImplicitHsForAllTy      ctxt ty = mkHsForAllTy Implicit  []  ctxt ty
+mkExplicitHsForAllTy  tvs ctxt ty = mkHsForAllTy Explicit  tvs ctxt ty
+mkQualifiedHsForAllTy     ctxt ty = mkHsForAllTy Qualified []  ctxt ty
 
 mkHsForAllTy :: HsExplicitFlag -> [LHsTyVarBndr RdrName] -> LHsContext RdrName -> LHsType RdrName -> HsType RdrName
 -- Smart constructor for HsForAllTy
@@ -427,8 +437,10 @@ mk_forall_ty exp  tvs  ty                                    = HsForAllTy exp (m
         --      so that (forall. ty) isn't implicitly quantified
 
 plus :: HsExplicitFlag -> HsExplicitFlag -> HsExplicitFlag
-Implicit `plus` Implicit = Implicit
-_        `plus` _        = Explicit
+Qualified `plus` Qualified = Qualified
+Explicit  `plus` _         = Explicit
+_         `plus` Explicit  = Explicit
+_         `plus` _         = Implicit
 
 hsExplicitTvs :: LHsType Name -> [Name]
 -- The explicitly-given forall'd type variables of a HsType
@@ -588,7 +600,7 @@ pprHsForAll exp qtvs cxt
   where
     show_forall =  opt_PprStyle_Debug
                 || (not (null (hsQTvBndrs qtvs)) && is_explicit)
-    is_explicit = case exp of {Explicit -> True; Implicit -> False}
+    is_explicit = case exp of {Explicit -> True; Implicit -> False; Qualified -> False}
     forall_part = forAllLit <+> ppr qtvs <> dot
 
 pprHsContext :: (OutputableBndr name) => HsContext name -> SDoc
index 5d0e2a2..7ae04ee 100644 (file)
@@ -452,6 +452,7 @@ data WarningFlag =
    | Opt_WarnUnusedBinds
    | Opt_WarnUnusedImports
    | Opt_WarnUnusedMatches
+   | Opt_WarnContextQuantification
    | Opt_WarnWarningsDeprecations
    | Opt_WarnDeprecatedFlags
    | Opt_WarnAMP
@@ -2624,6 +2625,7 @@ fWarningFlags = [
   ( "warn-unused-binds",                Opt_WarnUnusedBinds, nop ),
   ( "warn-unused-imports",              Opt_WarnUnusedImports, nop ),
   ( "warn-unused-matches",              Opt_WarnUnusedMatches, nop ),
+  ( "warn-context-quantification",      Opt_WarnContextQuantification, nop ),
   ( "warn-warnings-deprecations",       Opt_WarnWarningsDeprecations, nop ),
   ( "warn-deprecations",                Opt_WarnWarningsDeprecations, nop ),
   ( "warn-deprecated-flags",            Opt_WarnDeprecatedFlags, nop ),
@@ -3070,7 +3072,8 @@ standardWarnings
         Opt_WarnDodgyForeignImports,
         Opt_WarnInlineRuleShadowing,
         Opt_WarnAlternativeLayoutRuleTransitional,
-        Opt_WarnUnsupportedLlvmVersion
+        Opt_WarnUnsupportedLlvmVersion,
+        Opt_WarnContextQuantification
       ]
 
 minusWOpts :: [WarningFlag]
index 5fa6452..ebcaf36 100644 (file)
@@ -199,7 +199,7 @@ printException err = do
   liftIO $ printBagOfErrors dflags (srcErrorMessages err)
 
 -- | A function called to log warnings and errors.
-type WarnErrLogger = GhcMonad m => Maybe SourceError -> m ()
+type WarnErrLogger = forall m. GhcMonad m => Maybe SourceError -> m ()
 
 defaultWarnErrLogger :: WarnErrLogger
 defaultWarnErrLogger Nothing  = return ()
index db7cb10..fcc21e1 100644 (file)
@@ -1115,8 +1115,7 @@ strict_mark :: { Located HsBang }
 ctype   :: { LHsType RdrName }
         : 'forall' tv_bndrs '.' ctype   {% hintExplicitForall (getLoc $1) >>
                                             return (LL $ mkExplicitHsForAllTy $2 (noLoc []) $4) }
-        | context '=>' ctype            { LL $ mkImplicitHsForAllTy   $1 $3 }
-        -- A type of form (context => type) is an *implicit* HsForAllTy
+        | context '=>' ctype            { LL $ mkQualifiedHsForAllTy   $1 $3 }
         | ipvar '::' type               { LL (HsIParamTy (unLoc $1) $3) }
         | type                          { $1 }
 
@@ -1134,8 +1133,7 @@ ctype   :: { LHsType RdrName }
 ctypedoc :: { LHsType RdrName }
         : 'forall' tv_bndrs '.' ctypedoc {% hintExplicitForall (getLoc $1) >>
                                             return (LL $ mkExplicitHsForAllTy $2 (noLoc []) $4) }
-        | context '=>' ctypedoc         { LL $ mkImplicitHsForAllTy   $1 $3 }
-        -- A type of form (context => type) is an *implicit* HsForAllTy
+        | context '=>' ctypedoc         { LL $ mkQualifiedHsForAllTy   $1 $3 }
         | ipvar '::' type               { LL (HsIParamTy (unLoc $1) $3) }
         | typedoc                       { $1 }
 
index b13251c..823be85 100644 (file)
@@ -256,8 +256,8 @@ mkSpliceDecl :: LHsExpr RdrName -> HsDecl RdrName
 mkSpliceDecl lexpr@(L loc expr)
   | HsQuasiQuoteE qq <- expr          = QuasiQuoteD qq
   | HsSpliceE is_typed splice <- expr = ASSERT( not is_typed )
-                                        SpliceD (SpliceDecl (L loc splice) Explicit)
-  | otherwise                         = SpliceD (SpliceDecl (L loc splice) Implicit)
+                                        SpliceD (SpliceDecl (L loc splice) ExplicitSplice)
+  | otherwise                         = SpliceD (SpliceDecl (L loc splice) ImplicitSplice)
   where
     splice = mkHsSplice lexpr
 
index 2dc71db..4af8be3 100644 (file)
@@ -1286,8 +1286,13 @@ rnConDecl decl@(ConDecl { con_name = name, con_qvars = tvs
 
          -- With an Explicit forall, check for unused binders
          -- With Implicit, find the mentioned ones, and use them as binders
+         -- With Qualified, do the same as with Implicit, but give a warning
+         --   See Note [Context quantification]
         ; new_tvs <- case expl of
                        Implicit -> return (mkHsQTvs (userHsTyVarBndrs loc free_tvs))
+                       Qualified -> do { warnContextQuantification (docOfHsDocContext doc)
+                                                                   (userHsTyVarBndrs loc free_tvs)
+                                       ; return (mkHsQTvs (userHsTyVarBndrs loc free_tvs)) }
                        Explicit -> do { warnUnusedForAlls (docOfHsDocContext doc) tvs free_tvs
                                       ; return tvs }
 
@@ -1471,10 +1476,10 @@ add gp loc (SpliceD splice@(SpliceDecl _ flag)) ds
   = do { -- We've found a top-level splice.  If it is an *implicit* one
          -- (i.e. a naked top level expression)
          case flag of
-           Explicit -> return ()
-           Implicit -> do { th_on <- xoptM Opt_TemplateHaskell
-                          ; unless th_on $ setSrcSpan loc $
-                            failWith badImplicitSplice }
+           ExplicitSplice -> return ()
+           ImplicitSplice -> do { th_on <- xoptM Opt_TemplateHaskell
+                                ; unless th_on $ setSrcSpan loc $
+                                  failWith badImplicitSplice }
 
        ; return (gp, Just (splice, ds)) }
   where
index 49eaa11..c719191 100644 (file)
@@ -15,9 +15,10 @@ module RnTypes (
 
         -- Precence related stuff
         mkOpAppRn, mkNegAppRn, mkOpFormRn, mkConOpPatRn,
-        checkPrecMatch, checkSectionPrec, warnUnusedForAlls,
+        checkPrecMatch, checkSectionPrec,
 
         -- Binding related stuff
+        warnContextQuantification, warnUnusedForAlls,
         bindSigTyVarsFV, bindHsTyVars, rnHsBndrSig,
         extractHsTyRdrTyVars, extractHsTysRdrTyVars,
         extractRdrKindSigVars, extractDataDefnKindVars, filterInScope
@@ -84,6 +85,25 @@ badInstTy ty = ptext (sLit "Malformed instance:") <+> ppr ty
 rnHsType is here because we call it from loadInstDecl, and I didn't
 want a gratuitous knot.
 
+Note [Context quantification]
+-----------------------------
+Variables in type signatures are implicitly quantified
+when (1) they are in a type signature not beginning
+with "forall" or (2) in any qualified type T => R.
+We are phasing out (2) since it leads to inconsistencies
+(Trac #4426):
+
+data A = A (a -> a)           is an error
+data A = A (Eq a => a -> a)   binds "a"
+data A = A (Eq a => a -> b)   binds "a" and "b"
+data A = A (() => a -> b)     binds "a" and "b"
+f :: forall a. a -> b         is an error
+f :: forall a. () => a -> b   is an error
+f :: forall a. a -> (() => b) binds "a" and "b"
+
+The -fwarn-context-quantification flag warns about
+this situation. See rnHsTyKi for case HsForAllTy Qualified.
+
 \begin{code}
 rnLHsTyKi  :: Bool --  True <=> renaming a type, False <=> a kind
            -> HsDocContext -> LHsType RdrName -> RnM (LHsType Name, FreeVars)
@@ -136,6 +156,20 @@ rnHsTyKi isType doc (HsForAllTy Implicit _ lctxt@(L _ ctxt) ty)
 
     rnForAll doc Implicit forall_kvs (mkHsQTvs tyvar_bndrs) lctxt ty
 
+rnHsTyKi isType doc fulltype@(HsForAllTy Qualified _ lctxt@(L _ ctxt) ty)
+  = ASSERT( isType ) do
+    rdr_env <- getLocalRdrEnv
+    loc <- getSrcSpanM
+    let
+        (forall_kvs, forall_tvs) = filterInScope rdr_env $
+                                   extractHsTysRdrTyVars (ty:ctxt)
+        tyvar_bndrs = userHsTyVarBndrs loc forall_tvs
+        in_type_doc = ptext (sLit "In the type") <+> quotes (ppr fulltype)
+
+    -- See Note [Context quantification]
+    warnContextQuantification (in_type_doc $$ docOfHsDocContext doc) tyvar_bndrs
+    rnForAll doc Implicit forall_kvs (mkHsQTvs tyvar_bndrs) lctxt ty
+
 rnHsTyKi isType doc ty@(HsForAllTy Explicit forall_tyvars lctxt@(L _ ctxt) tau)
   = ASSERT( isType ) do {      -- Explicit quantification.
          -- Check that the forall'd tyvars are actually
@@ -825,6 +859,19 @@ warnUnusedForAlls in_doc bound mentioned_rdrs
         vcat [ ptext (sLit "Unused quantified type variable") <+> quotes (ppr tv)
              , in_doc ]
 
+warnContextQuantification :: SDoc -> [LHsTyVarBndr RdrName] -> TcM ()
+warnContextQuantification in_doc tvs
+  = whenWOptM Opt_WarnContextQuantification $
+    mapM_ add_warn tvs
+  where
+    add_warn (L loc tv)
+      = addWarnAt loc $
+        vcat [ ptext (sLit "Variable") <+> quotes (ppr tv) <+>
+               ptext (sLit "is implicitly quantified due to a context") $$
+               ptext (sLit "Use explicit forall syntax instead.") $$
+               ptext (sLit "This will become an error in GHC 7.12.")
+             , in_doc ]
+
 opTyErr :: RdrName -> HsType RdrName -> SDoc
 opTyErr op ty@(HsOpTy ty1 _ _)
   = hang (ptext (sLit "Illegal operator") <+> quotes (ppr op) <+> ptext (sLit "in type") <+> quotes (ppr ty))
index 404d239..d319cc5 100644 (file)
                     Added support for <link linkend="binary-literals">binary integer literals</link>
                </para>
            </listitem>
+            <listitem>
+                <para>
+                    Simplified rules for implicit quantification. In previous versions of GHC,
+                    it was possible to use the <literal>=></literal> arrow
+                    to quantify over type variables in <literal>data</literal> and
+                    <literal>type</literal> declarations without a
+                    <literal>forall</literal> quantifier. For example,
+                    <literal>data Fun = Fun (Ord a => a -> b)</literal> was identical to
+                    <literal>data Fun = Fun (forall a b. Ord a => a -> b)</literal>, while
+                    <literal>data Fun = Fun (a -> b)</literal> caused a not-in-scope error.
+                    This implicit quantification is now deprecated, and variables
+                    in higher-rank constructors should be quantified with <literal>forall</literal>
+                    regardless of whether a class context is present or not.
+                    GHC 7.10 raises a warning (controlled by
+                    <option>-fwarn-context-quantification</option>, enabled by default)
+                    and GHC 7.12 will raise an error. See <link linkend="univ">examples</link>
+                    in GHC documentation.
+                </para>
+                <para>
+                    The change also applies to Template Haskell splices such as
+                    <literal>[t|Ord a => a|]</literal>, which should be written as
+                    <literal>[t|forall a. Ord a => a|]</literal>.
+                </para>
+           </listitem>
        </itemizedlist>
     </sect3>
 
index 7cfc2be..13090c6 100644 (file)
@@ -7702,7 +7702,7 @@ data MonadT m = MkMonad { return :: forall a. a -> m a,
                           bind   :: forall a b. m a -> (a -> m b) -> m b
                         }
 
-newtype Swizzle = MkSwizzle (Ord a => [a] -> [a])
+newtype Swizzle = MkSwizzle (forall a. Ord a => [a] -> [a])
 </programlisting>
 
 </para>
@@ -7718,22 +7718,22 @@ T1 :: forall a. (forall b. b -> b -> b) -> a -> T a
 MkMonad :: forall m. (forall a. a -> m a)
                   -> (forall a b. m a -> (a -> m b) -> m b)
                   -> MonadT m
-MkSwizzle :: (Ord a => [a] -> [a]) -> Swizzle
+MkSwizzle :: (forall a. Ord a => [a] -> [a]) -> Swizzle
 </programlisting>
 
 </para>
 
 <para>
-Notice that you don't need to use a <literal>forall</literal> if there's an
-explicit context.  For example in the first argument of the
-constructor <function>MkSwizzle</function>, an implicit "<literal>forall a.</literal>" is
-prefixed to the argument type.  The implicit <literal>forall</literal>
-quantifies all type variables that are not already in scope, and are
-mentioned in the type quantified over. (Arguably, it would be better
-to <emphasis>require</emphasis> explicit quantification on constructor arguments
-where that is what is wanted.
-See <ulink url="http://ghc.haskell.org/trac/ghc/ticket/4426">Trac #4426</ulink>.)
+In earlier versions of GHC, it was possible to omit the <literal>forall</literal>
+in the type of the constructor if there was an explicit context. For example:
 
+<programlisting>
+newtype Swizzle' = MkSwizzle' (Ord a => [a] -> [a])
+</programlisting>
+
+As of GHC 7.10, this is deprecated. The <literal>-fwarn-context-quantification</literal>
+flag detects this situation and issues a warning. In GHC 7.12, declarations
+such as <literal>MkSwizzle'</literal> will cause an out-of-scope error.
 </para>
 
 <para>
index 921d5a3..09747ae 100644 (file)
@@ -1033,8 +1033,9 @@ test.hs:(5,4)-(6,7):
     <option>-fwarn-wrong-do-bind</option>,
     <option>-fwarn-unsupported-calling-conventions</option>,
     <option>-fwarn-dodgy-foreign-imports</option>,
-    <option>-fwarn-inline-rule-shadowing</option>, and
-    <option>-fwarn-unsupported-llvm-version</option>.
+    <option>-fwarn-inline-rule-shadowing</option>,
+    <option>-fwarn-unsupported-llvm-version</option>, and
+    <option>-fwarn-context-quantification</option>.
     The following flags are simple ways to select standard
     &ldquo;packages&rdquo; of warnings:
     </para>
@@ -1842,6 +1843,27 @@ _  = rhs3        -- No warning: lone wild-card pattern
       </varlistentry>
 
       <varlistentry>
+        <term><option>-fwarn-context-quantification</option>:</term>
+        <listitem>
+          <indexterm><primary><option>-fwarn-context-quantification</option></primary></indexterm>
+          <indexterm><primary>implicit context quantification, warning</primary></indexterm>
+          <indexterm><primary>context, implicit quantification</primary></indexterm>
+
+          <para>Report if a variable is quantified only due to its presence
+          in a context (see <xref linkend="universal-quantification"/>). For example,
+            <programlisting>
+              type T a = Monad m => a -> f a
+            </programlisting>
+          It is recommended to write this polymorphic type as
+            <programlisting>
+              type T a = forall m. Monad m => a -> f a
+            </programlisting>
+          instead.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>-fwarn-wrong-do-bind</option>:</term>
         <listitem>
           <indexterm><primary><option>-fwarn-wrong-do-bind</option></primary></indexterm>
diff --git a/testsuite/tests/rename/should_compile/T4426.hs b/testsuite/tests/rename/should_compile/T4426.hs
new file mode 100644 (file)
index 0000000..b04f59c
--- /dev/null
@@ -0,0 +1,22 @@
+{-# LANGUAGE RankNTypes #-}
+{-# OPTIONS_GHC -fwarn-context-quantification #-}
+
+module T4426 where
+
+type F a = Monad m => a -> m a
+
+data X a = X (Eq b => a -> b)
+
+data Y a = Y { k :: Eq b => a -> b -> c }
+
+f :: forall b. (Monad m => m b) -> b
+f = undefined
+
+type F' a = forall m. Monad m => a -> m a
+
+data X' a = X' (forall b. Eq b => a -> b)
+
+data Y' a = Y' { k' :: forall b c. Eq b => a -> b -> c }
+
+f' :: forall b. (forall m. Monad m => m b) -> b
+f' = undefined
diff --git a/testsuite/tests/rename/should_compile/T4426.stderr b/testsuite/tests/rename/should_compile/T4426.stderr
new file mode 100644 (file)
index 0000000..f4e0c47
--- /dev/null
@@ -0,0 +1,35 @@
+
+T4426.hs:6:12: Warning:
+    Variable ‘m’ is implicitly quantified due to a context
+    Use explicit forall syntax instead.
+    This will become an error in GHC 7.12.
+    In the type ‘Monad m => a -> m a’
+    In the declaration for type synonym ‘F’
+
+T4426.hs:8:15: Warning:
+    Variable ‘b’ is implicitly quantified due to a context
+    Use explicit forall syntax instead.
+    This will become an error in GHC 7.12.
+    In the type ‘Eq b => a -> b’
+    In the definition of data constructor ‘X’
+
+T4426.hs:10:21: Warning:
+    Variable ‘b’ is implicitly quantified due to a context
+    Use explicit forall syntax instead.
+    This will become an error in GHC 7.12.
+    In the type ‘Eq b => a -> b -> c’
+    In the definition of data constructor ‘Y’
+
+T4426.hs:10:21: Warning:
+    Variable ‘c’ is implicitly quantified due to a context
+    Use explicit forall syntax instead.
+    This will become an error in GHC 7.12.
+    In the type ‘Eq b => a -> b -> c’
+    In the definition of data constructor ‘Y’
+
+T4426.hs:12:17: Warning:
+    Variable ‘m’ is implicitly quantified due to a context
+    Use explicit forall syntax instead.
+    This will become an error in GHC 7.12.
+    In the type ‘Monad m => m b’
+    In the type signature for ‘f’
index d104df4..7185fba 100644 (file)
@@ -217,3 +217,4 @@ test('T7969',
      run_command,
      ['$MAKE -s --no-print-directory T7969'])
 test('T9127', normal, compile, [''])
+test('T4426', normal, compile, [''])
index bd19133..0eadecf 100644 (file)
@@ -1,4 +1,4 @@
-{-# LANGUAGE ConstraintKinds, TemplateHaskell, PolyKinds, TypeFamilies #-}
+{-# LANGUAGE ConstraintKinds, TemplateHaskell, PolyKinds, TypeFamilies, RankNTypes #-}
 
 module T7021a where
 
@@ -27,5 +27,5 @@ test = do
     reify fooName
     reify bazName
     reify barName
-    [t| (Show a, (Read a, Num a)) => a -> a |]
+    [t| forall a. (Show a, (Read a, Num a)) => a -> a |]
     [| \_ -> 0 |]
index 3090123..7d21796 100644 (file)
@@ -1,8 +1,8 @@
-{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE ConstraintKinds, RankNTypes #-}
 
 module T8807 where
 
 import Data.Proxy
 
-foo :: $( [t| a b => Proxy a -> b -> b |] )
-foo = undefined
\ No newline at end of file
+foo :: $( [t| forall a b. a b => Proxy a -> b -> b |] )
+foo = undefined
index 443d73a..296185d 100644 (file)
@@ -20,7 +20,7 @@ class Sat a where dict :: a
 class Subst_A a t t' where
     subst_A :: (Monad m) => a -> t -> t' -> m t'
 
-data SubstD_A a t t' = SubstD_A {substD_A:: (Monad m) => a -> t -> t' -> m t'}
+data SubstD_A a t t' = SubstD_A {substD_A:: forall m. (Monad m) => a -> t -> t' -> m t'}
 
 -- Allow override dictionary verion with implementation of type class Subst
 instance Subst_A a t t' => Sat (SubstD_A a t t') where
@@ -103,4 +103,4 @@ constraints, and only makes the attempt when it has all the evidence
 in hand. I'm thinking quite a bit about constraint solving at the
 moment and will bear that in mind. But I can't offer you an immediate
 solution. At least I hope I've explained the problem.
--}
\ No newline at end of file
+-}
index b421809..58493c6 100644 (file)
@@ -2,7 +2,7 @@
 
 module ShouldSucceed where
 
-data Empty q                   =  Empty (Ord a => q a)
+data Empty q                   =  Empty (forall a. Ord a => q a)
 q                              :: (Ord a) => [a]
 q                              =  []
 e0, e1, e2                     :: Empty []
index c3a7d47..4023817 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c3a7d4701ee64f6c29b95a6bed519f6c16b9bffd
+Subproject commit 4023817d7c0e46db012ba2eea28022626841ca9b