Refactor wild card renaming
authorThomas Winant <thomas.winant@cs.kuleuven.be>
Tue, 9 Jun 2015 04:45:48 +0000 (23:45 -0500)
committerAustin Seipp <austin@well-typed.com>
Tue, 9 Jun 2015 05:10:21 +0000 (00:10 -0500)
Summary:
Refactor wild card error reporting

* Merge `HsWildcardTy` and `HsNamedWildcardTy` into one constructor
  `HsWildCardTy` with as field the new type `HsWildCardInfo`, which has two
  constructors: `AnonWildCard` and `NamedWildCard`.

* All partial type checks are removed from `RdrHsSyn.hs` and are now done
  during renaming in order to report better error messages. When wild cards
  are allowed in a type, the new function `rnLHsTypeWithWildCards` (or
  `rnHsSigTypeWithWildCards`) should be used. This will bring the named wild
  cards into scope before renaming them. When this is not done, renaming will
  trigger "Unexpected wild card..." errors.

  Unfortunately, this has to be done separately for anonymous wild cards
  because they are given a fresh name during renaming, so they will not cause
  an out-of-scope error. They are handled in `tc_hs_type`, as a special case
  of a lookup that fails.

  The previous opt-out approach is replaced with an opt-in approach. No more
  panics because of forgotten checks!

* `[t| _ |]` isn't caught by the above two checks, so it is currently handled
  by a special case. The error message (generated in the `DsM` monad) doesn't
  provide as much context information as the other cases.

* Instead of three (!) functions that walk `HsType`, there is now only one
  pure function called `collectWildCards`.

* Alternative approach: catch all unwanted wild cards in `rnHsTyKi` by looking
  at the `HsDocContext`. This will reduce the number of places to catch
  unwanted wild cards form three to one, and make the error messages more
  uniform, albeit less informative, as the error context for renaming is not
  as informative as the one for type checking. A new constructor of
  `HsDocContext` will be required for pattern synonyms signatures.

  Small problem: currently type-class type signatures can't be distinguished
  from type signatures using the `HsDocContext`.

This requires an update to the Haddock submodule.

Test Plan: validate

Reviewers: goldfire, simonpj, austin

Reviewed By: simonpj

Subscribers: bgamari, thomie, goldfire

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

GHC Trac Issues: #10098

49 files changed:
compiler/deSugar/DsMeta.hs
compiler/hsSyn/HsTypes.hs
compiler/hsSyn/PlaceHolder.hs
compiler/parser/Parser.y
compiler/parser/RdrHsSyn.hs
compiler/rename/RnBinds.hs
compiler/rename/RnExpr.hs
compiler/rename/RnTypes.hs
compiler/typecheck/TcEnv.hs
compiler/typecheck/TcHsType.hs
compiler/typecheck/TcRnDriver.hs
compiler/typecheck/TcRnMonad.hs
testsuite/tests/partial-sigs/should_fail/ExtraConstraintsWildcardNotLast.stderr
testsuite/tests/partial-sigs/should_fail/ExtraConstraintsWildcardTwice.hs [new file with mode: 0644]
testsuite/tests/partial-sigs/should_fail/ExtraConstraintsWildcardTwice.stderr [new file with mode: 0644]
testsuite/tests/partial-sigs/should_fail/NamedExtraConstraintsWildcard.stderr
testsuite/tests/partial-sigs/should_fail/NamedWildcardsNotInMonotype.stderr
testsuite/tests/partial-sigs/should_fail/NestedExtraConstraintsWildcard.stderr
testsuite/tests/partial-sigs/should_fail/NestedNamedExtraConstraintsWildcard.stderr
testsuite/tests/partial-sigs/should_fail/PartialClassMethodSignature.hs
testsuite/tests/partial-sigs/should_fail/PartialClassMethodSignature.stderr
testsuite/tests/partial-sigs/should_fail/PartialClassMethodSignature2.hs [new file with mode: 0644]
testsuite/tests/partial-sigs/should_fail/PartialClassMethodSignature2.stderr [new file with mode: 0644]
testsuite/tests/partial-sigs/should_fail/UnnamedConstraintWildcard1.stderr
testsuite/tests/partial-sigs/should_fail/UnnamedConstraintWildcard2.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInADT1.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInADT2.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInADT3.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInADTContext1.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInADTContext2.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInDefault.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInDefaultSignature.hs
testsuite/tests/partial-sigs/should_fail/WildcardInDefaultSignature.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInDeriving.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInForeignExport.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInForeignImport.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInGADT1.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInGADT2.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInInstanceHead.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInInstanceSig.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInNewtype.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInPatSynSig.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInStandaloneDeriving.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInTypeBrackets.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInTypeFamilyInstanceLHS.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInTypeFamilyInstanceRHS.stderr
testsuite/tests/partial-sigs/should_fail/WildcardInTypeSynonymRHS.stderr
testsuite/tests/partial-sigs/should_fail/all.T
utils/haddock

index 010af3c..70bc690 100644 (file)
@@ -909,7 +909,12 @@ repTy (HsExplicitTupleTy _ tys) = do
 repTy (HsTyLit lit) = do
                         lit' <- repTyLit lit
                         repTLit lit'
-                          
+repTy (HsWildCardTy wc) = do
+                            let name = HsSyn.wildCardName wc
+                            putSrcSpanDs (nameSrcSpan name) $
+                              failWithDs $ text "Unexpected wild card:" <+>
+                                           quotes (ppr name)
+
 repTy ty                      = notHandled "Exotic form of type" (ppr ty)
 
 repTyLit :: HsTyLit -> DsM (Core TH.TyLitQ)
index 09c4a2f..9b86393 100644 (file)
@@ -33,6 +33,9 @@ module HsTypes (
 
         ConDeclField(..), LConDeclField, pprConDeclFields,
 
+        HsWildCardInfo(..), mkAnonWildCardTy, mkNamedWildCardTy,
+        wildCardName, sameWildCard, isAnonWildCard, isNamedWildCard,
+
         mkHsQTvs, hsQTvBndrs, isHsKindedTyVar, hsTvbAllKinded,
         mkExplicitHsForAllTy, mkImplicitHsForAllTy, mkQualifiedHsForAllTy,
         mkHsForAllTy,
@@ -45,7 +48,7 @@ module HsTypes (
         splitHsClassTy_maybe, splitLHsClassTy_maybe,
         splitHsFunType,
         splitHsAppTys, hsTyGetAppHead_maybe, mkHsAppTys, mkHsOpTy,
-        isWildcardTy, isNamedWildcardTy,
+        ignoreParens,
 
         -- Printing
         pprParendHsType, pprHsForAll, pprHsForAllExtra,
@@ -179,7 +182,7 @@ data HsWithBndrs name thing
   = HsWB { hswb_cts :: thing             -- Main payload (type or list of types)
          , hswb_kvs :: PostRn name [Name] -- Kind vars
          , hswb_tvs :: PostRn name [Name] -- Type vars
-         , hswb_wcs :: PostRn name [Name] -- Wildcards
+         , hswb_wcs :: PostRn name [Name] -- Wild cards
     }
   deriving (Typeable)
 deriving instance (Data name, Data thing, Data (PostRn name [Name]))
@@ -387,12 +390,7 @@ data HsType name
 
       -- For details on above see note [Api annotations] in ApiAnnotation
 
-  | HsWildcardTy           -- A type wildcard
-      -- ^ - 'ApiAnnotation.AnnKeywordId' : None
-
-      -- For details on above see note [Api annotations] in ApiAnnotation
-
-  | HsNamedWildcardTy name -- A named wildcard
+  | HsWildCardTy (HsWildCardInfo name)  -- A type wildcard
       -- ^ - 'ApiAnnotation.AnnKeywordId' : None
 
       -- For details on above see note [Api annotations] in ApiAnnotation
@@ -416,6 +414,14 @@ type HsTyOp name = (HsTyWrapper, name)
 mkHsOpTy :: LHsType name -> Located name -> LHsType name -> HsType name
 mkHsOpTy ty1 op ty2 = HsOpTy ty1 (WpKiApps [], op) ty2
 
+data HsWildCardInfo name
+    = AnonWildCard (PostRn name Name)
+      -- A anonymous wild card ('_'). A name is generated during renaming.
+    | NamedWildCard name
+      -- A named wild card ('_a').
+    deriving (Typeable)
+deriving instance (DataId name) => Data (HsWildCardInfo name)
+
 {-
 Note [HsForAllTy tyvar binders]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -568,17 +574,8 @@ mkQualifiedHsForAllTy     ctxt ty = mkHsForAllTy Qualified []  ctxt ty
 -- |Smart constructor for HsForAllTy, which populates the extra-constraints
 -- field if a wildcard is present in the context.
 mkHsForAllTy :: HsExplicitFlag -> [LHsTyVarBndr RdrName] -> LHsContext RdrName -> LHsType RdrName -> HsType RdrName
-mkHsForAllTy exp tvs (L l []) ty
-  = HsForAllTy exp Nothing (mkHsQTvs tvs) (L l []) ty
-mkHsForAllTy exp tvs ctxt     ty
-  = HsForAllTy exp extra   (mkHsQTvs tvs) cleanCtxt        ty
-  where -- Separate the extra-constraints wildcard when present
-        (cleanCtxt, extra)
-          | (L l HsWildcardTy) <- ignoreParens (last (unLoc ctxt)) = (init `fmap` ctxt, Just l)
-          | otherwise = (ctxt, Nothing)
-        ignoreParens (L _ (HsParTy ty)) = ty
-        ignoreParens ty                 = ty
-
+mkHsForAllTy exp tvs ctxt ty
+  = HsForAllTy exp Nothing (mkHsQTvs tvs) ctxt ty
 
 -- |When a sigtype is parsed, the type found is wrapped in an Implicit
 -- HsForAllTy via mkImplicitHsForAllTy, to ensure that a signature always has a
@@ -659,13 +656,31 @@ hsLTyVarLocNames :: LHsTyVarBndrs name -> [Located name]
 hsLTyVarLocNames qtvs = map hsLTyVarLocName (hsQTvBndrs qtvs)
 
 ---------------------
-isWildcardTy :: HsType a -> Bool
-isWildcardTy HsWildcardTy = True
-isWildcardTy _ = False
+mkAnonWildCardTy :: HsType RdrName
+mkAnonWildCardTy = HsWildCardTy (AnonWildCard PlaceHolder)
 
-isNamedWildcardTy :: HsType a -> Bool
-isNamedWildcardTy (HsNamedWildcardTy _) = True
-isNamedWildcardTy _ = False
+mkNamedWildCardTy :: n -> HsType n
+mkNamedWildCardTy = HsWildCardTy . NamedWildCard
+
+isAnonWildCard :: HsWildCardInfo name -> Bool
+isAnonWildCard (AnonWildCard _) = True
+isAnonWildCard _                = False
+
+isNamedWildCard :: HsWildCardInfo name -> Bool
+isNamedWildCard = not . isAnonWildCard
+
+wildCardName :: HsWildCardInfo Name -> Name
+wildCardName (NamedWildCard n) = n
+wildCardName (AnonWildCard  n) = n
+
+-- Two wild cards are the same when: they're both named and have the same
+-- name, or they're both anonymous and have the same location.
+sameWildCard :: Eq name
+             => Located (HsWildCardInfo name)
+             -> Located (HsWildCardInfo name) -> Bool
+sameWildCard (L l1 (AnonWildCard _))   (L l2 (AnonWildCard _))   = l1 == l2
+sameWildCard (L _  (NamedWildCard n1)) (L _  (NamedWildCard n2)) = n1 == n2
+sameWildCard _ _ = False
 
 splitHsAppTys :: LHsType n -> [LHsType n] -> (LHsType n, [LHsType n])
 splitHsAppTys (L _ (HsAppTy f a)) as = splitHsAppTys f (a:as)
@@ -761,6 +776,10 @@ splitHsFunType orig_ty@(L _ (HsAppTy t1 t2))
 
 splitHsFunType other = ([], other)
 
+ignoreParens :: LHsType name -> LHsType name
+ignoreParens (L _ (HsParTy ty)) = ignoreParens ty
+ignoreParens ty                 = ty
+
 {-
 ************************************************************************
 *                                                                      *
@@ -786,6 +805,10 @@ instance (OutputableBndr name) => Outputable (HsTyVarBndr name) where
 instance (Outputable thing) => Outputable (HsWithBndrs name thing) where
     ppr (HsWB { hswb_cts = ty }) = ppr ty
 
+instance (Outputable name) => Outputable (HsWildCardInfo name) where
+    ppr (AnonWildCard _)  = char '_'
+    ppr (NamedWildCard n) = ppr n
+
 pprHsForAll :: OutputableBndr name => HsExplicitFlag -> LHsTyVarBndrs name -> LHsContext name -> SDoc
 pprHsForAll exp = pprHsForAllExtra exp Nothing
 
@@ -889,8 +912,8 @@ ppr_mono_ty _    (HsCoreTy ty)       = ppr ty
 ppr_mono_ty _    (HsExplicitListTy _ tys) = quote $ brackets (interpp'SP tys)
 ppr_mono_ty _    (HsExplicitTupleTy _ tys) = quote $ parens (interpp'SP tys)
 ppr_mono_ty _    (HsTyLit t)         = ppr_tylit t
-ppr_mono_ty _    HsWildcardTy        = char '_'
-ppr_mono_ty _    (HsNamedWildcardTy name) = ppr name
+ppr_mono_ty _    (HsWildCardTy (AnonWildCard _))     = char '_'
+ppr_mono_ty _    (HsWildCardTy (NamedWildCard name)) = ppr name
 
 ppr_mono_ty ctxt_prec (HsWrapTy (WpKiApps _kis) ty)
   = ppr_mono_ty ctxt_prec ty
index 246abc0..00a2cdf 100644 (file)
@@ -97,6 +97,7 @@ type DataId id =
   , Data (PostRn id NameSet)
   , Data (PostRn id Fixity)
   , Data (PostRn id Bool)
+  , Data (PostRn id Name)
   , Data (PostRn id [Name])
 
   , Data (PostTc id Type)
index 2739e10..b88a3b1 100644 (file)
@@ -841,10 +841,9 @@ topdecl :: { OrdList (LHsDecl RdrName) }
         | inst_decl                             { unitOL (sL1 $1 (InstD (unLoc $1))) }
         | stand_alone_deriving                  { unitOL (sLL $1 $> (DerivD (unLoc $1))) }
         | role_annot                            { unitOL (sL1 $1 (RoleAnnotD (unLoc $1))) }
-        | 'default' '(' comma_types0 ')'    {% do { def <- checkValidDefaults $3
-                                                  ; amsu (sLL $1 $> (DefD def))
+        | 'default' '(' comma_types0 ')'    {% amsu (sLL $1 $> (DefD (DefaultDecl $3)))
                                                          [mj AnnDefault $1
-                                                         ,mop $2,mcp $4] }}
+                                                         ,mop $2,mcp $4] }
         | 'foreign' fdecl          {% amsu (sLL $1 $> (snd $ unLoc $2))
                                            (mj AnnForeign $1:(fst $ unLoc $2)) }
         | '{-# DEPRECATED' deprecations '#-}'   {% amsu (sLL $1 $> $ WarningD (Warnings (getDEPRECATED_PRAGs $1) (fromOL $2)))
@@ -950,12 +949,6 @@ inst_decl :: { LInstDecl RdrName }
                                      , cid_sigs = sigs, cid_tyfam_insts = ats
                                      , cid_overlap_mode = $2
                                      , cid_datafam_insts = adts }
-             ; let err = text "In instance head:" <+> ppr $3
-             ; checkNoPartialType err $3
-             ; sequence_ [ checkNoPartialType err ty
-                         | sig@(L _ (TypeSig _ ty _ )) <- sigs
-                         , let err = text "in instance signature" <> colon
-                                     <+> quotes (ppr sig) ]
              ; ams (L (comb3 $1 $3 $4) (ClsInstD { cid_inst = cid }))
                    (mj AnnInstance $1 : (fst $ unLoc $4)) } }
 
@@ -1138,7 +1131,6 @@ stand_alone_deriving :: { LDerivDecl RdrName }
                          {% do {
                                  let err = text "in the stand-alone deriving instance"
                                             <> colon <+> quotes (ppr $4)
-                               ; checkNoPartialType err $4
                                ; ams (sLL $1 $> (DerivDecl $4 $3))
                                      [mj AnnDeriving $1,mj AnnInstance $2] }}
 
@@ -1204,7 +1196,6 @@ pattern_synonym_sig :: { LSig RdrName }
         : 'pattern' con '::' ptype
             {% do { let (flag, qtvs, prov, req, ty) = snd $ unLoc $4
                   ; let sig = PatSynSig $2 (flag, mkHsQTvs qtvs) prov req ty
-                  ; checkValidPatSynSig sig
                   ; ams (sLL $1 $> $ sig)
                         (mj AnnPattern $1:mj AnnDcolon $3:(fst $ unLoc $4)) } }
 
@@ -1239,7 +1230,6 @@ decl_cls  : at_decl_cls                 { sLL $1 $> (unitOL $1) }
                     {% do { (TypeSig l ty _) <- checkValSig $2 $4
                           ; let err = text "in default signature" <> colon <+>
                                       quotes (ppr ty)
-                          ; checkNoPartialType err ty
                           ; ams (sLL $1 $> $ unitOL (sLL $1 $> $ SigD (GenericSig l ty)))
                                 [mj AnnDefault $1,mj AnnDcolon $3] } }
 
@@ -1657,10 +1647,10 @@ btype :: { LHsType RdrName }
 
 atype :: { LHsType RdrName }
         : ntgtycon                       { sL1 $1 (HsTyVar (unLoc $1)) }      -- Not including unit tuples
-        | tyvar                          {% do { nwc <- namedWildcardsEnabled -- (See Note [Unit tuples])
+        | tyvar                          {% do { nwc <- namedWildCardsEnabled -- (See Note [Unit tuples])
                                                ; let tv@(Unqual name) = unLoc $1
                                                ; return $ if (startsWithUnderscore name && nwc)
-                                                          then (sL1 $1 (HsNamedWildcardTy tv))
+                                                          then (sL1 $1 (mkNamedWildCardTy tv))
                                                           else (sL1 $1 (HsTyVar tv)) } }
 
         | strict_mark atype              {% ams (sLL $1 $> (HsBangTy (snd $ unLoc $1) $2))
@@ -1717,7 +1707,7 @@ atype :: { LHsType RdrName }
                                                                (getINTEGER $1) }
         | STRING               { sLL $1 $> $ HsTyLit $ HsStrTy (getSTRINGs $1)
                                                                (getSTRING  $1) }
-        | '_'                  { sL1 $1 $ HsWildcardTy }
+        | '_'                  { sL1 $1 $ mkAnonWildCardTy }
 
 -- An inst_type is what occurs in the head of an instance decl
 --      e.g.  (Foo a, Gaz b) => Wibble a b
@@ -2039,14 +2029,12 @@ sigdecl :: { Located (OrdList (LHsDecl RdrName)) }
         :
         -- See Note [Declaration/signature overlap] for why we need infixexp here
           infixexp '::' sigtypedoc
-                        {% do ty <- checkPartialTypeSignature $3
-                        ; s <- checkValSig $1 ty
+                        {% do s <- checkValSig $1 $3
                         ; _ <- ams (sLL $1 $> ()) [mj AnnDcolon $2]
                         ; return (sLL $1 $> $ unitOL (sLL $1 $> $ SigD s)) }
 
         | var ',' sig_vars '::' sigtypedoc
-           {% do { ty <- checkPartialTypeSignature $5
-                 ; let sig = TypeSig ($1 : reverse (unLoc $3)) ty PlaceHolder
+           {% do { let sig = TypeSig ($1 : reverse (unLoc $3)) $5 PlaceHolder
                  ; addAnnotation (gl $1) AnnComma (gl $2)
                  ; ams (sLL $1 $> $ toOL [ sLL $1 $> $ SigD sig ])
                        [mj AnnDcolon $4] } }
@@ -2318,10 +2306,7 @@ aexp2   :: { LHsExpr RdrName }
         | TH_TY_QUOTE gtycon    {% ams (sLL $1 $> $ HsBracket (VarBr False (unLoc $2))) [mj AnnThTyQuote $1,mj AnnName $2] }
         | '[|' exp '|]'       {% ams (sLL $1 $> $ HsBracket (ExpBr $2)) [mo $1,mc $3] }
         | '[||' exp '||]'     {% ams (sLL $1 $> $ HsBracket (TExpBr $2)) [mo $1,mc $3]}
-        | '[t|' ctype '|]'    {% checkNoPartialType
-                                   (text "in type brackets" <> colon
-                                    <+> quotes (text "[t|" <+> ppr $2 <+> text "|]")) $2 >>
-                                 ams (sLL $1 $> $ HsBracket (TypBr $2)) [mo $1,mc $3] }
+        | '[t|' ctype '|]'    {% ams (sLL $1 $> $ HsBracket (TypBr $2)) [mo $1,mc $3] }
         | '[p|' infixexp '|]' {% checkPattern empty $2 >>= \p ->
                                       ams (sLL $1 $> $ HsBracket (PatBr p))
                                           [mo $1,mc $3] }
@@ -3301,8 +3286,8 @@ hintExplicitForall span = do
       , text "extension to enable explicit-forall syntax: \x2200 <tvs>. <type>"
       ]
 
-namedWildcardsEnabled :: P Bool
-namedWildcardsEnabled = liftM ((Opt_NamedWildCards `xopt`) . dflags) getPState
+namedWildCardsEnabled :: P Bool
+namedWildCardsEnabled = liftM ((Opt_NamedWildCards `xopt`) . dflags) getPState
 
 {-
 %************************************************************************
index 98fa8f7..d7af65d 100644 (file)
@@ -49,12 +49,8 @@ module RdrHsSyn (
         checkCommand,         -- LHsExpr RdrName -> P (LHsCmd RdrName)
         checkValDef,          -- (SrcLoc, HsExp, HsRhs, [HsDecl]) -> P HsDecl
         checkValSig,          -- (SrcLoc, HsExp, HsRhs, [HsDecl]) -> P HsDecl
-        checkPartialTypeSignature,
-        checkNoPartialType,
-        checkValidPatSynSig,
         checkDoAndIfThenElse,
         checkRecordSyntax,
-        checkValidDefaults,
         parseErrorSDoc,
 
         -- Help with processing exports
@@ -101,8 +97,6 @@ import Text.ParserCombinators.ReadP as ReadP
 import Data.Char
 
 import Data.Data       ( dataTypeOf, fromConstr, dataTypeConstrs )
-import Data.List       ( partition )
-import qualified Data.Set as Set ( fromList, difference, member )
 
 #include "HsVersions.h"
 
@@ -140,8 +134,6 @@ mkClassDecl loc (L _ (mcxt, tycl_hdr)) fds where_cls
        ; let cxt = fromMaybe (noLoc []) mcxt
        ; (cls, tparams,ann) <- checkTyClHdr True tycl_hdr
        ; mapM_ (\a -> a loc) ann -- Add any API Annotations to the top SrcSpan
-       -- Partial type signatures are not allowed in a class definition
-       ; checkNoPartialSigs sigs cls
        ; tyvars <- checkTyVarsP (ptext (sLit "class")) whereDots cls tparams
        ; at_defs <- mapM (eitherToP . mkATDefault) at_insts
        ; return (L loc (ClassDecl { tcdCtxt = cxt, tcdLName = cls, tcdTyVars = tyvars,
@@ -165,104 +157,6 @@ mkATDefault (L loc (TyFamInstDecl { tfid_eqn = L _ e }))
                                      , tfe_pats = tvs
                                      , tfe_rhs = rhs })) }
 
--- | Check that none of the given type signatures of the class definition
--- ('Located RdrName') are partial type signatures. An error will be reported
--- for each wildcard found in a (partial) type signature. We do this check
--- because we want the signatures in a class definition to be fully specified.
-checkNoPartialSigs :: [LSig RdrName] -> Located RdrName -> P ()
-checkNoPartialSigs sigs cls_name =
-  sequence_ [ whenIsJust mb_loc $ \loc -> parseErrorSDoc loc $ err sig
-            | L _ sig@(TypeSig _ ty _) <- sigs
-            , let mb_loc = maybeLocation $ findWildcards ty ]
-  where err sig =
-          vcat [ text "The type signature of a class method cannot be partial:"
-               , ppr sig
-               , text "In the class declaration for " <> quotes (ppr cls_name) ]
-
--- | Check that none of the given constructors contain a wildcard (like in a
--- partial type signature). An error will be reported for each wildcard found
--- in a (partial) constructor definition. We do this check because we want the
--- type of a constructor to be fully specified.
-checkNoPartialCon :: [LConDecl RdrName] -> P ()
-checkNoPartialCon con_decls =
-  sequence_ [ whenIsJust mb_loc $ \loc -> parseErrorSDoc loc $ err cd
-            | L _ cd@(ConDecl { con_cxt = cxt, con_res = res,
-                                con_details = details }) <- con_decls
-            , let mb_loc = maybeLocation $
-                           concatMap findWildcards (unLoc cxt) ++
-                           containsWildcardRes res ++
-                           concatMap findWildcards
-                           (hsConDeclArgTys details) ]
-  where err con_decl = text "A constructor cannot have a partial type:" $$
-                       ppr con_decl
-        containsWildcardRes (ResTyGADT _ ty) = findWildcards ty
-        containsWildcardRes ResTyH98 = notFound
-
--- | Check that the given type does not contain wildcards, and is thus not a
--- partial type. If it contains wildcards, report an error with the given
--- message.
-checkNoPartialType :: SDoc -> LHsType RdrName -> P ()
-checkNoPartialType context_msg ty =
-  whenFound (findWildcards ty) $ \loc -> parseErrorSDoc loc err
-  where err = text "Wildcard not allowed" $$ context_msg
-
--- | Represent wildcards found in a type. Used for reporting errors for types
--- that mustn't contain wildcards.
-data FoundWildcard = Found      { location :: SrcSpan }
-                   | FoundNamed { location :: SrcSpan, _name :: RdrName }
-
--- | Indicate that no wildcards were found.
-notFound :: [FoundWildcard]
-notFound = []
-
--- | Call the function (second argument), accepting the location of the
--- wildcard, on the first wildcard that was found, if any.
-whenFound :: [FoundWildcard] -> (SrcSpan -> P ()) -> P ()
-whenFound (Found loc:_)        f = f loc
-whenFound (FoundNamed loc _:_) f = f loc
-whenFound _                    _ = return ()
-
--- | Extract the location of the first wildcard, if any.
-maybeLocation :: [FoundWildcard] -> Maybe SrcSpan
-maybeLocation fws = location <$> listToMaybe fws
-
--- | Extract the named wildcards from the wildcards that were found.
-namedWildcards :: [FoundWildcard] -> [RdrName]
-namedWildcards fws = [name | FoundNamed _ name <- fws]
-
--- | Split the found wildcards into a list of found unnamed wildcard and found
--- named wildcards.
-splitUnnamedNamed :: [FoundWildcard] -> ([FoundWildcard], [FoundWildcard])
-splitUnnamedNamed = partition (\f -> case f of { Found _ -> True ; _ -> False})
-
--- | Return a list of the wildcards found while traversing the given type.
-findWildcards :: LHsType RdrName -> [FoundWildcard]
-findWildcards (L l ty) = case ty of
-    (HsForAllTy _ xtr _ (L _ ctxt) x) -> (map Found $ maybeToList xtr) ++
-                                         concatMap go ctxt ++ go x
-    (HsAppTy x y)            -> go x ++ go y
-    (HsFunTy x y)            -> go x ++ go y
-    (HsListTy x)             -> go x
-    (HsPArrTy x)             -> go x
-    (HsTupleTy _ xs)         -> concatMap go xs
-    (HsOpTy x _ y)           -> go x ++ go y
-    (HsParTy x)              -> go x
-    (HsIParamTy _ x)         -> go x
-    (HsEqTy x y)             -> go x ++ go y
-    (HsKindSig x y)          -> go x ++ go y
-    (HsDocTy x _)            -> go x
-    (HsBangTy _ x)           -> go x
-    (HsRecTy xs)             ->
-      concatMap (go . getBangType . cd_fld_type . unLoc) xs
-    (HsExplicitListTy _ xs)  -> concatMap go xs
-    (HsExplicitTupleTy _ xs) -> concatMap go xs
-    (HsWrapTy _ x)           -> go (noLoc x)
-    HsWildcardTy             -> [Found l]
-    (HsNamedWildcardTy n)    -> [FoundNamed l n]
-    -- HsTyVar, HsQuasiQuoteTy, HsSpliceTy, HsCoreTy, HsTyLit
-    _                        -> notFound
-  where go = findWildcards
-
 mkTyData :: SrcSpan
          -> NewOrData
          -> Maybe (Located CType)
@@ -289,17 +183,12 @@ mkDataDefn :: NewOrData
            -> P (HsDataDefn RdrName)
 mkDataDefn new_or_data cType mcxt ksig data_cons maybe_deriv
   = do { checkDatatypeContext mcxt
-       ; checkNoPartialCon data_cons
-       ; whenIsJust maybe_deriv $
-         \(L _ deriv) -> mapM_ (checkNoPartialType (errDeriv deriv)) deriv
        ; let cxt = fromMaybe (noLoc []) mcxt
        ; return (HsDataDefn { dd_ND = new_or_data, dd_cType = cType
                             , dd_ctxt = cxt
                             , dd_cons = data_cons
                             , dd_kindSig = ksig
                             , dd_derivs = maybe_deriv }) }
-    where errDeriv deriv = text "In the deriving items:" <+>
-                           pprHsContextNoArrow deriv
 
 
 mkTySynonym :: SrcSpan
@@ -310,9 +199,6 @@ mkTySynonym loc lhs rhs
   = do { (tc, tparams,ann) <- checkTyClHdr False lhs
        ; mapM_ (\a -> a loc) ann -- Add any API Annotations to the top SrcSpan
        ; tyvars <- checkTyVarsP (ptext (sLit "type")) equalsDots tc tparams
-       ; let err = text "In type synonym" <+> quotes (ppr tc) <>
-                   colon <+> ppr rhs
-       ; checkNoPartialType err rhs
        ; return (L loc (SynDecl { tcdLName = tc, tcdTyVars = tyvars
                                 , tcdRhs = rhs, tcdFVs = placeHolderNames })) }
 
@@ -320,12 +206,7 @@ mkTyFamInstEqn :: LHsType RdrName
                -> LHsType RdrName
                -> P (TyFamInstEqn RdrName,[AddAnn])
 mkTyFamInstEqn lhs rhs
-  = do { (tc, tparams,ann) <- checkTyClHdr False lhs
-       ; let err xhs = hang (text "In type family instance equation of" <+>
-                             quotes (ppr tc) <> colon)
-                       2 (ppr xhs)
-       ; checkNoPartialType (err lhs) lhs
-       ; checkNoPartialType (err rhs) rhs
+  = do { (tc, tparams, ann) <- checkTyClHdr False lhs
        ; return (TyFamEqn { tfe_tycon = tc
                           , tfe_pats  = mkHsWithBndrs tparams
                           , tfe_rhs   = rhs },
@@ -637,11 +518,7 @@ mkGadtDecl' :: [Located RdrName]
 -- and expand it as if it had been
 --    C :: ty; D :: ty
 -- (Just like type signatures in general.)
-mkGadtDecl' _ ty@(L _ (HsForAllTy _ (Just l) _ _ _))
-  = parseErrorSDoc l $
-    text "A constructor cannot have a partial type:" $$
-    ppr ty
-mkGadtDecl' names (L ls (HsForAllTy imp Nothing qvars cxt tau))
+mkGadtDecl' names (L ls (HsForAllTy imp _ qvars cxt tau))
   = return $ mk_gadt_con names
   where
     (details, res_ty)           -- See Note [Sorting out the result type]
@@ -822,8 +699,6 @@ checkDatatypeContext (Just (L loc c))
              parseErrorSDoc loc
                  (text "Illegal datatype context (use DatatypeContexts):" <+>
                   pprHsContext c)
-         mapM_ (checkNoPartialType err) c
-      where err = text "In the context:" <+> pprHsContextNoArrow c
 
 checkRecordSyntax :: Outputable a => Located a -> P (Located a)
 checkRecordSyntax lr@(L loc r)
@@ -1096,144 +971,6 @@ checkValSig lhs@(L l _) ty
     default_RDR = mkUnqual varName (fsLit "default")
 
 
--- | Check that the default declarations do not contain wildcards in their
--- types, which we do not want as the types in the default declarations must
--- be fully specified.
-checkValidDefaults :: [LHsType RdrName] -> P (DefaultDecl RdrName)
-checkValidDefaults tys = mapM_ (checkNoPartialType err) tys >> return ret
-  where ret = DefaultDecl tys
-        err = text "In declaration:" <+> ppr ret
-
--- | Check that the pattern synonym type signature does not contain wildcards.
-checkValidPatSynSig :: Sig RdrName -> P (Sig RdrName)
-checkValidPatSynSig psig@(PatSynSig _ _ prov req ty)
-  = mapM_ (checkNoPartialType err) (unLoc prov ++ unLoc req ++ [ty])
-    >> return psig
-  where err = hang (text "In pattern synonym type signature: ")
-                   2 (ppr psig)
-checkValidPatSynSig sig = return sig
--- Should only be called with a pattern synonym type signature
-
--- | Check the validity of a partial type signature. We check the following
--- things:
---
--- * There should only be one extra-constraints wildcard in the type
--- signature, i.e. the @_@ in @_ => a -> String@.
--- This would be invalid: @(Eq a, _) => a -> (Num a, _) => a -> Bool@.
--- Extra-constraints wildcards are only allowed in the top-level context.
---
--- * Named extra-constraints wildcards aren't allowed,
--- e.g. invalid: @(Show a, _x) => a -> String@.
---
--- * There is only one extra-constraints wildcard in the context and it must
--- come last, e.g. invalid: @(_, Show a) => a -> String@
--- or @(_, Show a, _) => a -> String@.
---
--- * There should be no unnamed wildcards in the context.
---
--- * Named wildcards occurring in the context must also occur in the monotype.
---
--- An error is reported when an invalid wildcard is found.
-checkPartialTypeSignature :: LHsType RdrName -> P (LHsType RdrName)
-checkPartialTypeSignature fullTy = case fullTy of
-
-  (L l (HsForAllTy flag extra bndrs (L lc ctxtP) ty)) -> do
-    -- Remove parens around types in the context
-    let ctxt = map ignoreParens ctxtP
-    -- Check that the type doesn't contain any more extra-constraints wildcards
-    checkNoExtraConstraintsWildcard ty
-    -- Named extra-constraints wildcards aren't allowed
-    whenIsJust (firstMatch isNamedWildcardTy ctxt) $
-      \(L l _) -> err hintNamed l fullTy
-    -- There should be no more (extra-constraints) wildcards in the context.
-    -- If there was one at the end of the context, it is by now already
-    -- removed from the context and stored in the @extra@ field of the
-    -- 'HsForAllTy' by 'HsTypes.mkHsForAllTy'.
-    whenIsJust (firstMatch isWildcardTy ctxt) $
-      \(L l _) -> err hintLast l fullTy
-    -- Find all wildcards in the context and the monotype, then divide
-    -- them in unnamed and named wildcards
-    let (unnamedInCtxt, namedInCtxt) = splitUnnamedNamed $
-                                       concatMap findWildcards ctxt
-        (_            , namedInTy)   = splitUnnamedNamed $
-                                       findWildcards ty
-    -- Unnamed wildcards aren't allowed in the context
-    case unnamedInCtxt of
-      (Found lc : _) -> err hintUnnamedConstraint lc fullTy
-      _              -> return ()
-    -- Calculcate the set of named wildcards in the context that aren't in the
-    -- monotype (tau)
-    let namedWildcardsNotInTau = Set.fromList (namedWildcards namedInCtxt)
-                                 `Set.difference`
-                                 Set.fromList (namedWildcards namedInTy)
-    -- Search for the first named wildcard that we encountered in the
-    -- context that isn't present in the monotype (we lose the order
-    -- in which they occur when using the Set directly).
-    case filter (\(FoundNamed _ name) -> Set.member name namedWildcardsNotInTau)
-                namedInCtxt of
-      (FoundNamed lc name:_) -> err (hintNamedNotInMonotype name) lc fullTy
-      _                      -> return ()
-
-    -- Return the checked type
-    return $ L l (HsForAllTy flag extra bndrs (L lc ctxtP) ty)
-
-
-  ty -> do
-    checkNoExtraConstraintsWildcard ty
-    return ty
-
-  where
-    ignoreParens (L _ (HsParTy ty)) = ty
-    ignoreParens ty                 = ty
-
-    firstMatch :: (HsType a -> Bool) -> HsContext a -> Maybe (LHsType a)
-    firstMatch pred ctxt = listToMaybe (filter (pred . unLoc) ctxt)
-
-    err hintSDoc lc ty = parseErrorSDoc lc $
-                         text "Invalid partial type signature:" $$
-                         ppr ty $$ hintSDoc
-    hintLast    = sep [ text "An extra-constraints wildcard is only allowed"
-                      , text "at the end of the constraints" ]
-    hintNamed   = text "A named wildcard cannot occur as a constraint"
-    hintNested  = sep [ text "An extra-constraints wildcard is only allowed"
-                      , text "at the top-level of the signature" ]
-    hintUnnamedConstraint
-      = text "Wildcards are not allowed within the constraints"
-    hintNamedNotInMonotype name
-      = sep [ text "The named wildcard" <+> quotes (ppr name) <+>
-              text "is only allowed in the constraints"
-            , text "when it also occurs in the (mono)type" ]
-
-    checkNoExtraConstraintsWildcard (L _ ty) = go ty
-      where
-        -- Report nested (named) extra-constraints wildcards
-        go' = go . unLoc
-        go (HsAppTy x y)            = go' x >> go' y
-        go (HsFunTy x y)            = go' x >> go' y
-        go (HsListTy x)             = go' x
-        go (HsPArrTy x)             = go' x
-        go (HsTupleTy _ xs)         = mapM_ go' xs
-        go (HsOpTy x _ y)           = go' x >> go' y
-        go (HsParTy x)              = go' x
-        go (HsIParamTy _ x)         = go' x
-        go (HsEqTy x y)             = go' x >> go' y
-        go (HsKindSig x y)          = go' x >> go' y
-        go (HsDocTy x _)            = go' x
-        go (HsBangTy _ x)           = go' x
-        go (HsRecTy xs)             = mapM_ (go' . getBangType . cd_fld_type . unLoc) xs
-        go (HsExplicitListTy _ xs)  = mapM_ go' xs
-        go (HsExplicitTupleTy _ xs) = mapM_ go' xs
-        go (HsWrapTy _ x)           = go' (noLoc x)
-        go (HsForAllTy _ (Just l) _ _ _) = err hintNested l ty
-        go (HsForAllTy _ Nothing  _ (L _ ctxt) x)
-          | Just (L l _) <- firstMatch isWildcardTy      ctxt
-          = err hintNested l ty
-          | Just (L l _) <- firstMatch isNamedWildcardTy ctxt
-          = err hintNamed l ty
-          | otherwise               = go' x
-        go _                        = return ()
-
-
 checkDoAndIfThenElse :: LHsExpr RdrName
                      -> Bool
                      -> LHsExpr RdrName
@@ -1475,11 +1212,6 @@ mkImport :: Located CCallConv
          -> (Located (SourceText,FastString), Located RdrName, LHsType RdrName)
          -> P (HsDecl RdrName)
 mkImport (L lc cconv) (L ls safety) (L loc (esrc,entity), v, ty)
-  | Just loc <- maybeLocation $ findWildcards ty
-    = parseErrorSDoc loc $
-      text "Wildcard not allowed" $$
-      text "In foreign import declaration" <+>
-      quotes (ppr v) $$ ppr ty
   | cconv == PrimCallConv                      = do
   let funcTarget = CFunction (StaticTarget esrc entity Nothing True)
       importSpec = CImport (L lc PrimCallConv) (L ls safety) Nothing funcTarget
@@ -1559,8 +1291,6 @@ mkExport :: Located CCallConv
          -> (Located (SourceText,FastString), Located RdrName, LHsType RdrName)
          -> P (HsDecl RdrName)
 mkExport (L lc cconv) (L le (esrc,entity), v, ty) = do
-  checkNoPartialType (ptext (sLit "In foreign export declaration") <+>
-                      quotes (ppr v) $$ ppr ty) ty
   return $ ForD (ForeignExport v ty noForeignExportCoercionYet
                  (CExport (L lc (CExportStatic esrc entity' cconv))
                           (L le (unpackFS entity))))
index f1a18d6..aa39b59 100644 (file)
@@ -813,11 +813,17 @@ renameSig _ (IdSig x)
 
 renameSig ctxt sig@(TypeSig vs ty _)
   = do  { new_vs <- mapM (lookupSigOccRn ctxt sig) vs
-        -- (named and anonymous) wildcards are bound here.
-        ; (wcs, ty') <- extractWildcards ty
-        ; bindLocatedLocalsFV wcs $ \wcs_new -> do {
-          (new_ty, fvs) <- rnHsSigType (ppr_sig_bndrs vs) ty'
-        ; return (TypeSig new_vs new_ty wcs_new, fvs) } }
+        ; let doc = ppr_sig_bndrs vs
+              wildCardsAllowed = case ctxt of
+                TopSigCtxt _    -> True
+                LocalBindCtxt _ -> True
+                _               -> False
+        ; (new_ty, fvs, wcs)
+            <- if wildCardsAllowed
+               then rnHsSigTypeWithWildCards doc ty
+               else do { (new_ty, fvs) <- rnHsSigType doc ty
+                       ; return (new_ty, fvs, []) }
+        ; return (TypeSig new_vs new_ty wcs, fvs) }
 
 renameSig ctxt sig@(GenericSig vs ty)
   = do  { defaultSigs_on <- xoptM Opt_DefaultSignatures
index 71fa1cb..ef77247 100644 (file)
@@ -247,12 +247,10 @@ rnExpr (RecordUpd expr rbinds _ _ _)
                   fvExpr `plusFV` fvRbinds) }
 
 rnExpr (ExprWithTySig expr pty PlaceHolder)
-  = do  { (wcs, pty') <- extractWildcards pty
-        ; bindLocatedLocalsFV wcs $ \wcs_new -> do {
-          (pty'', fvTy) <- rnLHsType ExprWithTySigCtx pty'
-        ; (expr', fvExpr) <- bindSigTyVarsFV (hsExplicitTvs pty'') $
-                             rnLExpr expr
-        ; return (ExprWithTySig expr' pty'' wcs_new, fvExpr `plusFV` fvTy) } }
+  = do  { (pty', fvTy, wcs) <- rnLHsTypeWithWildCards ExprWithTySigCtx pty
+        ; (expr', fvExpr)   <- bindSigTyVarsFV (hsExplicitTvs pty') $
+                               rnLExpr expr
+        ; return (ExprWithTySig expr' pty' wcs, fvExpr `plusFV` fvTy) }
 
 rnExpr (HsIf _ p b1 b2)
   = do { (p', fvP) <- rnLExpr p
index 93a7dfd..743f460 100644 (file)
@@ -5,13 +5,15 @@
 -}
 
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 
 module RnTypes (
         -- Type related stuff
         rnHsType, rnLHsType, rnLHsTypes, rnContext,
         rnHsKind, rnLHsKind, rnLHsMaybeKind,
         rnHsSigType, rnLHsInstType, rnConDeclFields,
-        newTyVarNameRn,
+        newTyVarNameRn, rnLHsTypeWithWildCards,
+        rnHsSigTypeWithWildCards,
 
         -- Precence related stuff
         mkOpAppRn, mkNegAppRn, mkOpFormRn, mkConOpPatRn,
@@ -22,7 +24,7 @@ module RnTypes (
         bindSigTyVarsFV, bindHsTyVars, rnHsBndrSig,
         extractHsTyRdrTyVars, extractHsTysRdrTyVars,
         extractRdrKindSigVars, extractDataDefnKindVars,
-        extractWildcards, filterInScope
+        filterInScope
   ) where
 
 import {-# SOURCE #-} RnSplice( rnSpliceType )
@@ -45,9 +47,13 @@ import BasicTypes       ( compareFixity, funTyFixity, negateFixity,
 import Outputable
 import FastString
 import Maybes
-import Data.List        ( nub, nubBy )
+import Data.List        ( nub, nubBy, deleteFirstsBy )
 import Control.Monad    ( unless, when )
 
+#if __GLASGOW_HASKELL__ < 709
+import Data.Monoid      ( mappend, mempty, mconcat )
+#endif
+
 #include "HsVersions.h"
 
 {-
@@ -274,13 +280,24 @@ rnHsTyKi isType doc ty@(HsExplicitTupleTy kis tys)
        ; (tys', fvs) <- rnLHsTypes doc tys
        ; return (HsExplicitTupleTy kis tys', fvs) }
 
-rnHsTyKi _ _ HsWildcardTy = panic "rnHsTyKi HsWildcardTy"
-                            -- Should be replaced by a HsNamedWildcardTy
+rnHsTyKi isType _doc (HsWildCardTy (AnonWildCard PlaceHolder))
+  = ASSERT( isType )
+    do { loc <- getSrcSpanM
+       ; uniq <- newUnique
+       ; let name = mkInternalName uniq (mkTyVarOcc "_") loc
+       ; return (HsWildCardTy (AnonWildCard name), unitFV name) }
 
-rnHsTyKi isType _doc (HsNamedWildcardTy rdr_name)
+rnHsTyKi isType doc (HsWildCardTy (NamedWildCard rdr_name))
   = ASSERT( isType )
-    do { name <- rnTyVar isType rdr_name
-       ; return (HsNamedWildcardTy name, unitFV name) }
+    do { not_in_scope <- isNothing `fmap` lookupOccRn_maybe rdr_name
+       ; when not_in_scope $
+         -- When the named wild card is not in scope, it means it shouldn't be
+         -- there in the first place, i.e. rnHsSigTypeWithWildCards wasn't
+         -- used, so fail.
+         failWith $ text "Unexpected wild card:" <+> quotes (ppr rdr_name) $$
+                    docOfHsDocContext doc
+       ; name <- rnTyVar isType rdr_name
+       ; return (HsWildCardTy (NamedWildCard name), unitFV name) }
 
 --------------
 rnHsTyKiForAll :: Bool -> HsDocContext -> HsType RdrName
@@ -474,13 +491,11 @@ rnHsBndrSig doc (HsWB { hswb_cts = ty@(L loc _) }) thing_inside
                                                , not (tv `elemLocalRdrEnv` name_env) ]
        ; kv_names <- newLocalBndrsRn [L loc kv | kv <- kv_bndrs
                                                , not (kv `elemLocalRdrEnv` name_env) ]
-       ; (wcs, ty') <- extractWildcards ty
        ; bindLocalNamesFV kv_names $
          bindLocalNamesFV tv_names $
-         bindLocatedLocalsFV wcs $ \wcs_new ->
-    do { (ty'', fvs1) <- rnLHsType doc ty'
-       ; (res, fvs2) <- thing_inside (HsWB { hswb_cts = ty'', hswb_kvs = kv_names,
-                                             hswb_tvs = tv_names, hswb_wcs = wcs_new })
+    do { (ty', fvs1, wcs) <- rnLHsTypeWithWildCards doc ty
+       ; (res, fvs2) <- thing_inside (HsWB { hswb_cts = ty', hswb_kvs = kv_names,
+                                             hswb_tvs = tv_names, hswb_wcs = wcs })
        ; return (res, fvs1 `plusFV` fvs2) } }
 
 overlappingKindVars :: HsDocContext -> [RdrName] -> SDoc
@@ -518,6 +533,157 @@ dataKindsErr is_type thing
     what | is_type   = ptext (sLit "type")
          | otherwise = ptext (sLit "kind")
 
+--------------------------------
+-- | Variant of @rnHsSigType@ that supports wild cards. Also returns the wild
+-- cards to bind.
+rnHsSigTypeWithWildCards :: SDoc -> LHsType RdrName
+                         -> RnM (LHsType Name, FreeVars, [Name])
+rnHsSigTypeWithWildCards doc_str = rnLHsTypeWithWildCards (TypeSigCtx doc_str)
+
+-- | Variant of @rnLHsType@ that supports wild cards. The third element of the
+-- tuple consists of the freshly generated names of the anonymous wild cards
+-- occurring in the type, as well as the names of the named wild cards in the
+-- type that are not yet in scope.
+rnLHsTypeWithWildCards  :: HsDocContext -> LHsType RdrName
+                        -> RnM (LHsType Name, FreeVars, [Name])
+rnLHsTypeWithWildCards doc ty
+  = do { -- When there is a wild card at the end of the context, remove it and
+         -- add its location as the extra-constraints wild card in the
+         -- HsForAllTy.
+         let ty' = extractExtraCtsWc `fmap` ty
+
+       ; checkValidPartialType doc ty'
+
+       ; rdr_env <- getLocalRdrEnv
+       -- Filter out named wildcards that are already in scope
+       ; let (_, wcs) = collectWildCards ty'
+             nwcs = [L loc n | L loc (NamedWildCard n) <- wcs
+                             , not (elemLocalRdrEnv n rdr_env) ]
+       ; bindLocatedLocalsRn nwcs $ \nwcs' -> do {
+         (ty'', fvs) <- rnLHsType doc ty'
+       -- Add the anonymous wildcards that have been given names during
+       -- renaming
+       ; let (_, wcs') = collectWildCards ty''
+             awcs      = filter (isAnonWildCard . unLoc) wcs'
+       ; return (ty'', fvs, nwcs' ++ map (HsSyn.wildCardName . unLoc) awcs) } }
+  where
+    extractExtraCtsWc (HsForAllTy flag _ bndrs (L l ctxt) ty)
+      | Just (ctxt', ct) <- snocView ctxt
+      , L lx (HsWildCardTy (AnonWildCard _)) <- ignoreParens ct
+      = HsForAllTy flag (Just lx) bndrs (L l ctxt') ty
+    extractExtraCtsWc ty = ty
+
+-- | Extract all wild cards from a type. The named and anonymous
+-- extra-constraints wild cards are returned separately to be able to give
+-- more accurate error messages.
+collectWildCards
+  :: Eq name => LHsType name
+  -> ([Located (HsWildCardInfo name)],  -- extra-constraints wild cards
+      [Located (HsWildCardInfo name)])  -- wild cards
+collectWildCards lty = (nubBy sameWildCard extra, nubBy sameWildCard wcs)
+  where
+    (extra, wcs) = go lty
+    go (L loc ty) = case ty of
+      HsAppTy ty1 ty2         -> go ty1 `mappend` go ty2
+      HsFunTy ty1 ty2         -> go ty1 `mappend` go ty2
+      HsListTy ty             -> go ty
+      HsPArrTy ty             -> go ty
+      HsTupleTy _ tys         -> gos tys
+      HsOpTy ty1 _ ty2        -> go ty1 `mappend` go ty2
+      HsParTy ty              -> go ty
+      HsIParamTy _ ty         -> go ty
+      HsEqTy ty1 ty2          -> go ty1 `mappend` go ty2
+      HsKindSig ty kind       -> go ty `mappend` go kind
+      HsDocTy ty _            -> go ty
+      HsBangTy _ ty           -> go ty
+      HsRecTy flds            -> gos $ map (cd_fld_type . unLoc) flds
+      HsExplicitListTy _ tys  -> gos tys
+      HsExplicitTupleTy _ tys -> gos tys
+      HsWrapTy _ ty           -> go (L loc ty)
+      -- Interesting cases
+      HsWildCardTy wc         -> ([], [L loc wc])
+      HsForAllTy _ _ _ (L _ ctxt) ty -> ctxtWcs `mappend` go ty
+        where
+          ctxt' = map ignoreParens ctxt
+          extraWcs  = [L l wc | L l (HsWildCardTy wc) <- ctxt']
+          (_, wcs) = gos ctxt'
+          -- Remove extra-constraints wild cards from wcs
+          ctxtWcs = (extraWcs, deleteFirstsBy sameWildCard
+                               (nubBy sameWildCard wcs) extraWcs)
+      -- HsQuasiQuoteTy, HsSpliceTy, HsCoreTy, HsTyLit
+      _ -> mempty
+    gos = mconcat . map go
+
+-- | Check the validity of a partial type signature. The following things are
+-- checked:
+--
+-- * Named extra-constraints wild cards aren't allowed,
+-- e.g. invalid: @(Show a, _x) => a -> String@.
+--
+-- * There is only one extra-constraints wild card in the context and it must
+-- come last, e.g. invalid: @(_, Show a) => a -> String@
+-- or @(_, Show a, _) => a -> String@.
+--
+-- * There should be no unnamed wild cards in the context.
+--
+-- * An extra-constraints wild card can only occur in the top-level context.
+-- This would be invalid: @(Eq a, _) => a -> (Num a, _) => a -> Bool@.
+--
+-- * Named wild cards occurring in the context must also occur in the monotype.
+--
+-- When an invalid wild card is found, we fail with an error.
+checkValidPartialType :: HsDocContext -> LHsType RdrName -> RnM ()
+checkValidPartialType doc lty
+  = do { whenNonEmpty isNamedWildCard inExtra $ \(L loc _) ->
+           failAt loc $ typeDoc $$
+           text "An extra-constraints wild card cannot be named" $$
+           docOfHsDocContext doc
+
+       ; whenNonEmpty isAnonWildCard extraTopLevel $ \(L loc _) ->
+           failAt loc $ typeDoc $$
+           -- If there was a valid extra-constraints wild card, it should have
+           -- already been removed and its location should be stored in the
+           -- HsForAllTy
+           (if isJust extra
+            then text "Only a single extra-constraints wild card is allowed"
+            else fcat [ text "An extra-constraints wild card must occur"
+                      , text "at the end of the constraints" ]) $$
+           docOfHsDocContext doc
+
+       ; whenNonEmpty isAnonWildCard inCtxt $ \(L loc _) ->
+           failAt loc $ typeDoc $$
+           text "Anonymous wild cards are not allowed in constraints" $$
+           docOfHsDocContext doc
+
+       ; whenNonEmpty isAnonWildCard nestedExtra $ \(L loc _) ->
+           failAt loc $ typeDoc $$
+           fcat [ text "An extra-constraints wild card is only allowed"
+                , text "in the top-level context" ] $$
+           docOfHsDocContext doc
+
+       ; whenNonEmpty isNamedWildCard inCtxtNotInTau $ \(L loc name) ->
+           failAt loc $ typeDoc $$
+           fcat [ text "The named wild card" <+> quotes (ppr name) <> space
+                , text "is only allowed in the constraints"
+                , text "when it also occurs in the rest of the type" ] $$
+           docOfHsDocContext doc }
+  where
+    typeDoc               = hang (text "Invalid partial type:") 2 (ppr lty)
+    (extra, ctxt, tau)    = splitPartialType lty
+    (inExtra,     _)      = collectWildCards lty
+    (nestedExtra, inTau)  = collectWildCards tau
+    (_,           inCtxt) = mconcat $ map collectWildCards ctxt
+    inCtxtNotInTau        = deleteFirstsBy sameWildCard inCtxt inTau
+    extraTopLevel         = deleteFirstsBy sameWildCard inExtra nestedExtra
+
+    splitPartialType (L _ (HsForAllTy _ extra _ (L _ ctxt) ty))
+      = (extra, map ignoreParens ctxt, ty)
+    splitPartialType ty = (Nothing, [], ty)
+
+    whenNonEmpty test wcs f
+      = whenIsJust (listToMaybe $ filter (test . unLoc) wcs) f
+
+
 {-
 *********************************************************
 *                                                      *
@@ -999,10 +1165,8 @@ extract_lty (L _ ty) acc
       HsForAllTy _ _ tvs cx ty  -> extract_hs_tv_bndrs tvs acc $
                                    extract_lctxt cx   $
                                    extract_lty ty ([],[])
-      -- We deal with these to in a later stage, because they need to be
-      -- replaced by fresh HsTyVars.
-      HsWildcardTy              -> acc
-      HsNamedWildcardTy _       -> acc
+      -- We deal with these separately in rnLHsTypeWithWildCards
+      HsWildCardTy _            -> acc
 
 extract_hs_tv_bndrs :: LHsTyVarBndrs RdrName -> FreeKiTyVars
                     -> FreeKiTyVars -> FreeKiTyVars
@@ -1023,60 +1187,3 @@ extract_tv :: RdrName -> FreeKiTyVars -> FreeKiTyVars
 extract_tv tv acc
   | isRdrTyVar tv = case acc of (kvs,tvs) -> (kvs, tv : tvs)
   | otherwise     = acc
-
--- | Replace all unnamed wildcards in the given type with named wildcards.
--- These names are freshly generated, based on "_". Return a tuple of the
--- named wildcards that weren't already in scope (amongst them the named
--- wildcards the unnamed ones were converted into), and the type in which the
--- unnamed wildcards are replaced by named wildcards.
-extractWildcards :: LHsType RdrName -> RnM ([Located RdrName], LHsType RdrName)
-extractWildcards ty
-  = do { (nwcs, awcs, ty') <- go ty
-       ; rdr_env <- getLocalRdrEnv
-       -- Filter out named wildcards that are already in scope
-       ; let nwcs' = nubBy eqLocated $ filterOut (flip (elemLocalRdrEnv . unLoc) rdr_env) nwcs
-       ; return (nwcs' ++ awcs, ty') }
-  where
-    go orig@(L l ty) = case ty of
-      (HsForAllTy exp extra bndrs (L locCxt cxt) ty) ->
-        do (nwcs1, awcs1, cxt') <- extList cxt
-           (nwcs2, awcs2, ty')  <- go ty
-           return (nwcs1 ++ nwcs2, awcs1 ++ awcs2,
-                   L l (HsForAllTy exp extra bndrs (L locCxt cxt') ty'))
-      (HsAppTy ty1 ty2)           -> go2 HsAppTy ty1 ty2
-      (HsFunTy ty1 ty2)           -> go2 HsFunTy ty1 ty2
-      (HsListTy ty)               -> go1 HsListTy ty
-      (HsPArrTy ty)               -> go1 HsPArrTy ty
-      (HsTupleTy con tys)         -> goList (HsTupleTy con) tys
-      (HsOpTy ty1 op ty2)         -> go2 (\t1 t2 -> HsOpTy t1 op t2) ty1 ty2
-      (HsParTy ty)                -> go1 HsParTy ty
-      (HsIParamTy n ty)           -> go1 (HsIParamTy n) ty
-      (HsEqTy ty1 ty2)            -> go2 HsEqTy ty1 ty2
-      (HsKindSig ty kind)         -> go2 HsKindSig ty kind
-      (HsDocTy ty doc)            -> go1 (flip HsDocTy doc) ty
-      (HsBangTy b ty)             -> go1 (HsBangTy b) ty
-      (HsExplicitListTy ptk tys)  -> goList (HsExplicitListTy ptk) tys
-      (HsExplicitTupleTy ptk tys) -> goList (HsExplicitTupleTy ptk) tys
-      HsWildcardTy                -> do
-        uniq <- newUnique
-        let name = mkInternalName uniq (mkTyVarOcc "_") l
-            rdrName = nameRdrName name
-        return ([], [L l rdrName], L l $ HsNamedWildcardTy rdrName)
-      (HsNamedWildcardTy name)    -> return ([L l name], [], orig)
-      -- HsQuasiQuoteTy, HsSpliceTy, HsRecTy, HsCoreTy, HsTyLit, HsWrapTy
-      _                           -> return ([], [], orig)
-      where
-        go1 f t = do (nwcs, awcs, t') <- go t
-                     return (nwcs, awcs, L l $ f t')
-        go2 f t1 t2 =
-          do (nwcs1, awcs1, t1') <- go t1
-             (nwcs2, awcs2, t2') <- go t2
-             return (nwcs1 ++ nwcs2, awcs1 ++ awcs2, L l $ f t1' t2')
-        extList l = do rec_res <- mapM go l
-                       let (nwcs, awcs, tys') =
-                             foldr (\(nwcs, awcs, ty) (nwcss, awcss, tys) ->
-                                     (nwcs ++ nwcss, awcs ++ awcss, ty : tys))
-                                   ([], [], []) rec_res
-                       return (nwcs, awcs, tys')
-        goList f tys = do (nwcs, awcs, tys') <- extList tys
-                          return (nwcs, awcs, L l $ f tys')
index c342410..6337b3d 100644 (file)
@@ -827,9 +827,16 @@ pprBinders bndrs  = pprWithCommas ppr bndrs
 notFound :: Name -> TcM TyThing
 notFound name
   = do { lcl_env <- getLclEnv
+       ; namedWildCardsEnabled <- xoptM Opt_NamedWildCards
        ; let stage = tcl_th_ctxt lcl_env
+             isWildCard = case getOccString name of
+               ('_':_:_) | namedWildCardsEnabled -> True
+               "_"                               -> True
+               _                                 -> False
        ; case stage of   -- See Note [Out of scope might be a staging error]
            Splice {} -> stageRestrictionError (quotes (ppr name))
+           _ | isWildCard -> failWithTc $
+                             text "Unexpected wild card:" <+> quotes (ppr name)
            _ -> failWithTc $
                 vcat[ptext (sLit "GHC internal error:") <+> quotes (ppr name) <+>
                      ptext (sLit "is not in scope during type checking, but it passed the renamer"),
index 15d647b..677b5a8 100644 (file)
@@ -536,12 +536,9 @@ tc_hs_type hs_ty@(HsTyLit (HsStrTy _ s)) exp_kind
        ; checkWiredInTyCon typeSymbolKindCon
        ; return (mkStrLitTy s) }
 
-
-tc_hs_type HsWildcardTy _ = panic "tc_hs_type HsWildcardTy"
--- unnamed wildcards should have been replaced by named wildcards
-
-tc_hs_type hs_ty@(HsNamedWildcardTy name) exp_kind
-  = do { (ty, k) <- tcTyVar name
+tc_hs_type hs_ty@(HsWildCardTy wc) exp_kind
+  = do { let name = wildCardName wc
+       ; (ty, k) <- tcTyVar name
        ; checkExpectedKind hs_ty k exp_kind
        ; return ty }
 
index de31816..16c8d37 100644 (file)
@@ -1845,11 +1845,8 @@ tcRnType :: HscEnv
 tcRnType hsc_env normalise rdr_type
   = runTcInteractive hsc_env $
     setXOptM Opt_PolyKinds $   -- See Note [Kind-generalise in tcRnType]
-    do { (wcs, rdr_type') <- extractWildcards rdr_type
-       ; (rn_type, wcs)   <- bindLocatedLocalsRn wcs $ \wcs_new -> do {
-       ; (rn_type, _fvs)  <- rnLHsType GHCiCtx rdr_type'
+    do { (rn_type, _fvs, wcs) <- rnLHsTypeWithWildCards GHCiCtx rdr_type
        ; failIfErrsM
-       ; return (rn_type, wcs_new) }
 
         -- Now kind-check the type
         -- It can have any rank or kind
index 820e969..c299f29 100644 (file)
@@ -691,6 +691,9 @@ addErr msg = do { loc <- getSrcSpanM; addErrAt loc msg }
 failWith :: MsgDoc -> TcRn a
 failWith msg = addErr msg >> failM
 
+failAt :: SrcSpan -> MsgDoc -> TcRn a
+failAt loc msg = addErrAt loc msg >> failM
+
 addErrAt :: SrcSpan -> MsgDoc -> TcRn ()
 -- addErrAt is mainly (exclusively?) used by the renamer, where
 -- tidying is not an issue, but it's all lazy so the extra
index 3b96a38..faf3ad1 100644 (file)
@@ -1,6 +1,6 @@
 
 ExtraConstraintsWildcardNotLast.hs:4:9:
-    Invalid partial type signature:
-    (_, Eq a) => a -> a
-    An extra-constraints wildcard is only allowed
+    Invalid partial type: (_, Eq a) => a -> a
+    An extra-constraints wild card must occur
     at the end of the constraints
+    In the type signature for ‘foo’
diff --git a/testsuite/tests/partial-sigs/should_fail/ExtraConstraintsWildcardTwice.hs b/testsuite/tests/partial-sigs/should_fail/ExtraConstraintsWildcardTwice.hs
new file mode 100644 (file)
index 0000000..e1aaf23
--- /dev/null
@@ -0,0 +1,5 @@
+{-# LANGUAGE PartialTypeSignatures #-}
+module ExtraConstraintsWildcardTwice where
+
+foo :: ((_), _) => a -> a
+foo = undefined
diff --git a/testsuite/tests/partial-sigs/should_fail/ExtraConstraintsWildcardTwice.stderr b/testsuite/tests/partial-sigs/should_fail/ExtraConstraintsWildcardTwice.stderr
new file mode 100644 (file)
index 0000000..7110de0
--- /dev/null
@@ -0,0 +1,5 @@
+
+ExtraConstraintsWildcardTwice.hs:4:10:
+    Invalid partial type: (_, _) => a -> a
+    Only a single extra-constraints wild card is allowed
+    In the type signature for ‘foo’
index 783b2c0..ca674c4 100644 (file)
@@ -1,5 +1,5 @@
 
 NamedExtraConstraintsWildcard.hs:4:15:
-    Invalid partial type signature:
-    (Eq a, _a) => a -> a
-    A named wildcard cannot occur as a constraint
+    Invalid partial type: (Eq a, _a) => a -> a
+    An extra-constraints wild card cannot be named
+    In the type signature for ‘foo’
index 82b8f83..8e64437 100644 (file)
@@ -1,6 +1,6 @@
 
 NamedWildcardsNotInMonotype.hs:4:21:
-    Invalid partial type signature:
-    (Show _a, Eq _c, Eq _b) => _a -> _b -> String
-    The named wildcard ‘_c’ is only allowed in the constraints
-    when it also occurs in the (mono)type
+    Invalid partial type: (Show _a, Eq _c, Eq _b) => _a -> _b -> String
+    The named wild card ‘_c’ is only allowed in the constraints
+    when it also occurs in the rest of the type
+    In the type signature for ‘foo’
index 5820047..784b282 100644 (file)
@@ -1,6 +1,6 @@
 
 NestedExtraConstraintsWildcard.hs:4:23:
-    Invalid partial type signature:
-    Bool -> (Eq a, _) => a
-    An extra-constraints wildcard is only allowed
-    at the top-level of the signature
+    Invalid partial type: Bool -> (Eq a, _) => a
+    An extra-constraints wild card is only allowed
+    in the top-level context
+    In the type signature for ‘foo’
index a5cb766..07e5839 100644 (file)
@@ -1,5 +1,5 @@
 
 NestedNamedExtraConstraintsWildcard.hs:4:23:
-    Invalid partial type signature:
-    Bool -> (Eq a, _a) => a
-    A named wildcard cannot occur as a constraint
+    Invalid partial type: Bool -> (Eq a, _a) => a
+    An extra-constraints wild card cannot be named
+    In the type signature for ‘foo’
index c6a8788..c3dcd7c 100644 (file)
@@ -1,5 +1,5 @@
 
-PartialClassMethodSignature.hs:6:17:
-    The type signature of a class method cannot be partial:
-    foo :: (Eq a, _) => a -> _
+PartialClassMethodSignature.hs:6:15:
+    Unexpected wild card: ‘_’
+    In the type ‘a -> _’
     In the class declaration for ‘Foo’
diff --git a/testsuite/tests/partial-sigs/should_fail/PartialClassMethodSignature2.hs b/testsuite/tests/partial-sigs/should_fail/PartialClassMethodSignature2.hs
new file mode 100644 (file)
index 0000000..d46000a
--- /dev/null
@@ -0,0 +1,5 @@
+{-# LANGUAGE PartialTypeSignatures #-}
+module PartialClassMethodSignature2 where
+
+class Foo a where
+  foo :: (Eq a, _) => a -> a
diff --git a/testsuite/tests/partial-sigs/should_fail/PartialClassMethodSignature2.stderr b/testsuite/tests/partial-sigs/should_fail/PartialClassMethodSignature2.stderr
new file mode 100644 (file)
index 0000000..1dfa192
--- /dev/null
@@ -0,0 +1,5 @@
+
+PartialClassMethodSignature2.hs:5:17:
+    Unexpected wild card: ‘_’
+    In the type ‘(Eq a, _) => a -> a’
+    In the class declaration for ‘Foo’
index 5ade516..cb3a6a9 100644 (file)
@@ -1,5 +1,5 @@
 
 UnnamedConstraintWildcard1.hs:4:13:
-    Invalid partial type signature:
-    Show _ => a -> String
-    Wildcards are not allowed within the constraints
+    Invalid partial type: Show _ => a -> String
+    Anonymous wild cards are not allowed in constraints
+    In the type signature for ‘foo’
index e0872ba..6af7534 100644 (file)
@@ -1,5 +1,5 @@
 
 UnnamedConstraintWildcard2.hs:4:8:
-    Invalid partial type signature:
-    _ a => a -> String
-    Wildcards are not allowed within the constraints
+    Invalid partial type: _ a => a -> String
+    Anonymous wild cards are not allowed in constraints
+    In the type signature for ‘foo’
index 617d2b8..851767a 100644 (file)
@@ -1,4 +1,6 @@
 
 WildcardInADT1.hs:4:26:
-    A constructor cannot have a partial type:
-    Foo (Either _ a)
+    Unexpected wild card: ‘_’
+    In the type ‘Either _ a’
+    In the definition of data constructor ‘Foo’
+    In the data declaration for ‘Foo’
index b8c57b6..e96d385 100644 (file)
@@ -1,4 +1,6 @@
 
 WildcardInADT2.hs:4:34:
-    A constructor cannot have a partial type:
-    Foo {get :: Either _ a}
+    Unexpected wild card: ‘_’
+    In the type ‘Either _ a’
+    In the definition of data constructor ‘Foo’
+    In the data declaration for ‘Foo’
index 85e0525..1c504f6 100644 (file)
@@ -1,4 +1,6 @@
 
 WildcardInADT3.hs:4:27:
-    A constructor cannot have a partial type:
-    Foo {get :: _ => a}
+    Unexpected wild card: ‘_’
+    In the type ‘_ => a’
+    In the definition of data constructor ‘Foo’
+    In the data declaration for ‘Foo’
index 29a3dbb..419c63e 100644 (file)
@@ -3,5 +3,5 @@ WildcardInADTContext1.hs:1:37: Warning:
     -XDatatypeContexts is deprecated: It was widely considered a misfeature, and has been removed from the Haskell language.
 
 WildcardInADTContext1.hs:4:13:
-    Wildcard not allowed
-    In the context: (Eq a, _)
+    Unexpected wild card: ‘_’
+    In the data declaration for ‘Foo’
index 96ba835..2082084 100644 (file)
@@ -3,5 +3,5 @@ WildcardInADTContext2.hs:1:53: Warning:
     -XDatatypeContexts is deprecated: It was widely considered a misfeature, and has been removed from the Haskell language.
 
 WildcardInADTContext2.hs:4:10:
-    Wildcard not allowed
-    In the context: (Eq _a)
+    Unexpected wild card: ‘_a’
+    In the data type declaration for ‘Foo’
index a0a7e38..e4c2b1a 100644 (file)
@@ -1,4 +1,5 @@
 
 WildcardInDefault.hs:4:10:
-    Wildcard not allowed
-    In declaration: default (_)
+    Unexpected wild card: ‘_’
+    In a type in a `default' declaration: _
+    When checking the types in a default declaration
index 5e85e59..a2f25e4 100644 (file)
@@ -1,4 +1,7 @@
 {-# LANGUAGE DefaultSignatures #-}
 module WildcardInDefaultSignature where
 
-class C a where default f :: _
+
+class C a where
+  f :: a
+  default f :: _
index 38cb4ce..92e7c8f 100644 (file)
@@ -1,4 +1,5 @@
 
-WildcardInDefaultSignature.hs:4:30:
-    Wildcard not allowed
-    in default signature: ‘_’
+WildcardInDefaultSignature.hs:7:16:
+    Unexpected wild card: ‘_’
+    In the type ‘_’
+    In the class declaration for ‘C’
index 18397f5..6c3f76d 100644 (file)
@@ -1,4 +1,4 @@
 
 WildcardInDeriving.hs:5:22:
-    Wildcard not allowed
-    In the deriving items: (_)
+    Unexpected wild card: ‘_’
+    In the data declaration for ‘Foo’
index a56145e..00cdfa0 100644 (file)
@@ -1,5 +1,6 @@
 
 WildcardInForeignExport.hs:6:37:
-    Wildcard not allowed
-    In foreign export declaration ‘foo’
-    CInt -> _
+    Unexpected wild card: ‘_’
+    In the foreign declaration for ‘foo’: foo :: CInt -> _
+    When checking declaration:
+      foreign export ccall "foo" foo :: CInt -> _
index b6a781a..5930e33 100644 (file)
@@ -1,5 +1,6 @@
 
 WildcardInForeignImport.hs:6:48:
-    Wildcard not allowed
-    In foreign import declaration ‘c_sin’
-    CDouble -> _
+    Unexpected wild card: ‘_’
+    In the foreign declaration for ‘c_sin’: c_sin :: CDouble -> _
+    When checking declaration:
+      foreign import ccall safe "static sin" c_sin :: CDouble -> _
index bd20ffb..f3a07de 100644 (file)
@@ -1,4 +1,6 @@
 
 WildcardInGADT1.hs:5:19:
-    A constructor cannot have a partial type:
-    Foo :: Either a _ -> Foo a
+    Unexpected wild card: ‘_’
+    In the type ‘Either a _’
+    In the definition of data constructor ‘Foo’
+    In the data declaration for ‘Foo’
index a2e9d10..d183907 100644 (file)
@@ -1,4 +1,5 @@
 
 WildcardInGADT2.hs:5:17:
-    A constructor cannot have a partial type:
-    (Eq a, _) => Maybe a -> Foo a
+    Unexpected wild card: ‘_’
+    In the definition of data constructor ‘Foo’
+    In the data declaration for ‘Foo’
index 3b5e078..d85fd4d 100644 (file)
@@ -1,4 +1,4 @@
 
 WildcardInInstanceHead.hs:7:14:
-    Wildcard not allowed
-    In instance head: Foo _
+    Unexpected wild card: ‘_’
+    In the instance declaration for ‘Foo _’
index e8148f1..339f9fa 100644 (file)
@@ -1,4 +1,5 @@
 
 WildcardInInstanceSig.hs:4:35:
-    Wildcard not allowed
-    in instance signature: ‘negate :: _’
+    Unexpected wild card: ‘_’
+    In the type signature for ‘negate’: negate :: _
+    In the instance declaration for ‘Num Bool’
index f776733..a5f236c 100644 (file)
@@ -1,4 +1,6 @@
 
 WildcardInNewtype.hs:7:29:
-    A constructor cannot have a partial type:
-    Foo (Either _ a)
+    Unexpected wild card: ‘_’
+    In the type ‘Either _ a’
+    In the definition of data constructor ‘Foo’
+    In the newtype declaration for ‘Foo’
index 06ee17e..9a4aca1 100644 (file)
@@ -1,5 +1,4 @@
 
 WildcardInPatSynSig.hs:4:37:
-    Wildcard not allowed
-    In pattern synonym type signature: 
-      pattern Single :: () => (Show a) => _ -> [a]
+    Unexpected wild card: ‘_’
+    In the type signature for ‘Single’: Single :: _ -> [a]
index 921d7a0..d5b3dd1 100644 (file)
@@ -1,4 +1,2 @@
 
-WildcardInStandaloneDeriving.hs:4:19:
-    Wildcard not allowed
-    in the stand-alone deriving instance: ‘_’
+WildcardInStandaloneDeriving.hs:4:19: Malformed instance: _
index dd6feb9..f72fa7a 100644 (file)
@@ -1,4 +1,2 @@
 
-WildcardInTypeBrackets.hs:4:11:
-    Wildcard not allowed
-    in type brackets: ‘[t| _ |]’
+WildcardInTypeBrackets.hs:4:11: Unexpected wild card: ‘_’
index 2aac87c..fda3e6b 100644 (file)
@@ -1,4 +1,6 @@
 
 WildcardInTypeFamilyInstanceLHS.hs:8:13:
-    Wildcard not allowed
-    In type family instance equation of ‘Dual’: Dual _
+    Unexpected wild card: ‘_’
+    In the type ‘_’
+    In the type instance declaration for ‘Dual’
+    In the instance declaration for ‘Foo Int’
index e74b473..46ca25b 100644 (file)
@@ -1,4 +1,6 @@
 
 WildcardInTypeFamilyInstanceRHS.hs:8:25:
-    Wildcard not allowed
-    In type family instance equation of ‘Dual’: Maybe _
+    Unexpected wild card: ‘_’
+    In the type ‘Maybe _’
+    In the type instance declaration for ‘Dual’
+    In the instance declaration for ‘Foo Int’
index ea9b246..929980e 100644 (file)
@@ -1,4 +1,5 @@
 
 WildcardInTypeSynonymRHS.hs:4:18:
-    Wildcard not allowed
-    In type synonym ‘Foo’: Maybe _
+    Unexpected wild card: ‘_’
+    In the type ‘Maybe _’
+    In the type declaration for ‘Foo’
index c49a36f..412dd77 100644 (file)
@@ -4,6 +4,7 @@ test('Defaulting1MROff', normal, compile_fail, [''])
 test('ExtraConstraintsWildcardNotEnabled', normal, compile_fail, [''])
 test('ExtraConstraintsWildcardNotLast', normal, compile_fail, [''])
 test('ExtraConstraintsWildcardNotPresent', normal, compile_fail, [''])
+test('ExtraConstraintsWildcardTwice', normal, compile_fail, [''])
 test('Forall1Bad', normal, compile_fail, [''])
 test('InstantiatedNamedWildcardsInConstraints', normal, compile_fail, [''])
 test('NamedExtraConstraintsWildcard', normal, compile_fail, [''])
@@ -13,6 +14,7 @@ test('NamedWildcardsNotInMonotype', normal, compile_fail, [''])
 test('NestedExtraConstraintsWildcard', normal, compile_fail, [''])
 test('NestedNamedExtraConstraintsWildcard', normal, compile_fail, [''])
 test('PartialClassMethodSignature', normal, compile_fail, [''])
+test('PartialClassMethodSignature2', normal, compile_fail, [''])
 test('PartialTypeSignaturesDisabled', normal, compile_fail, [''])
 test('ScopedNamedWildcardsBad', normal, compile_fail, [''])
 test('TidyClash', normal, compile_fail, [''])
index 45df734..553c719 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 45df734c8e0242ca2e88fba5359207e49d7bf158
+Subproject commit 553c719236972f3a1d445146352ec94614979b63