Custom `Typeable` solver, that keeps track of kinds.
authorIavor S. Diatchki <diatchki@galois.com>
Sat, 7 Mar 2015 16:37:31 +0000 (10:37 -0600)
committerAustin Seipp <aseipp@pobox.com>
Fri, 13 Mar 2015 21:46:17 +0000 (16:46 -0500)
Summary:
This implements the new `Typeable` solver: when GHC sees `Typeable` constraints
it solves them on the spot.

The current implementation creates `TyCon` representations on the spot.

Pro: No overhead at all in code that does not use `Typeable`
Cons: Code that uses `Typeable` may create multipe `TyCon` represntations.

We have discussed an implementation where representations of `TyCons` are
computed once, in the module, where a datatype is declared.  This would
lead to more code being generated:  for a promotable datatype we need to
generate `2 + number_of_data_cons` type-constructro representations,
and we have to do that for all programs, even ones that do not intend to
use typeable.

I added code to emit warning whenevar `deriving Typeable` is encountered---
the idea being that this is not needed anymore, and shold be fixed.

Also, we allow `instance Typeable T` in .hs-boot files, but they result
in a warning, and are ignored.  This last one was to avoid breaking exisitng
code, and should become an error, eventually.

Test Plan:
1. GHC can compile itself.
2. I compiled a number of large libraries, including `lens`.
    - I had to make some small changes:
      `unordered-containers` uses internals of `TypeReps`, so I had to do a 1 line fix
    - `lens` needed one instance changed, due to a poly-kinded `Typeble` instance

3. I also run some code that uses `syb` to traverse a largish datastrucutre.
I didn't notice any signifiant performance difference between the 7.8.3 version,
and this implementation.

Reviewers: simonpj, simonmar, austin, hvr

Reviewed By: austin, hvr

Subscribers: thomie

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

GHC Trac Issues: #9858

(cherry picked from commit b359c886cd7578ed083bcedcea05d315ecaeeb54)

29 files changed:
compiler/basicTypes/MkId.hs
compiler/deSugar/DsBinds.hs
compiler/main/DynFlags.hs
compiler/prelude/PrelNames.hs
compiler/typecheck/TcDeriv.hs
compiler/typecheck/TcEvidence.hs
compiler/typecheck/TcGenDeriv.hs
compiler/typecheck/TcHsSyn.hs
compiler/typecheck/TcInstDcls.hs
compiler/typecheck/TcInteract.hs
docs/users_guide/flags.xml
docs/users_guide/glasgow_exts.xml
libraries/base/Data/Typeable/Internal.hs
testsuite/tests/deriving/should_compile/all.T
testsuite/tests/deriving/should_fail/T2604.hs [deleted file]
testsuite/tests/deriving/should_fail/T2604.stderr [deleted file]
testsuite/tests/deriving/should_fail/T5863a.hs [deleted file]
testsuite/tests/deriving/should_fail/T5863a.stderr [deleted file]
testsuite/tests/deriving/should_fail/T7800.hs [deleted file]
testsuite/tests/deriving/should_fail/T7800.stderr [deleted file]
testsuite/tests/deriving/should_fail/T7800a.hs [deleted file]
testsuite/tests/deriving/should_fail/T9687.stderr
testsuite/tests/deriving/should_fail/all.T
testsuite/tests/ghci.debugger/scripts/print019.stderr
testsuite/tests/polykinds/T8132.stderr
testsuite/tests/typecheck/should_compile/T9999.hs [deleted file]
testsuite/tests/typecheck/should_compile/all.T
testsuite/tests/typecheck/should_fail/TcStaticPointersFail02.stderr
testsuite/tests/typecheck/should_fail/all.T

index a58400d..4d473d5 100644 (file)
@@ -32,6 +32,7 @@ module MkId (
         voidPrimId, voidArgId,
         nullAddrId, seqId, lazyId, lazyIdKey,
         coercionTokenId, magicDictId, coerceId,
+        proxyHashId,
 
         -- Re-export error Ids
         module PrelRules
index b512fbb..0031040 100644 (file)
@@ -36,17 +36,19 @@ import CoreArity ( etaExpand )
 import CoreUnfold
 import CoreFVs
 import UniqSupply
-import Unique( Unique )
 import Digraph
-
-
-import TyCon      ( isTupleTyCon, tyConDataCons_maybe )
+import Module
+import PrelNames
+import TysPrim ( mkProxyPrimTy )
+import TyCon      ( isTupleTyCon, tyConDataCons_maybe
+                  , tyConName, isPromotedTyCon, isPromotedDataCon )
 import TcEvidence
 import TcType
 import Type
 import Coercion hiding (substCo)
 import TysWiredIn ( eqBoxDataCon, coercibleDataCon, tupleCon )
 import Id
+import MkId(proxyHashId)
 import Class
 import DataCon  ( dataConWorkId )
 import Name
@@ -70,6 +72,7 @@ import Util
 import Control.Monad( when )
 import MonadUtils
 import Control.Monad(liftM)
+import Fingerprint(Fingerprint(..), fingerprintString)
 
 {-
 ************************************************************************
@@ -905,6 +908,124 @@ dsEvTerm (EvLit l) =
     EvNum n -> mkIntegerExpr n
     EvStr s -> mkStringExprFS s
 
+dsEvTerm (EvTypeable ev) = dsEvTypeable ev
+
+dsEvTypeable :: EvTypeable -> DsM CoreExpr
+dsEvTypeable ev =
+  do tyCl      <- dsLookupTyCon typeableClassName
+     typeRepTc <- dsLookupTyCon typeRepTyConName
+     let tyRepType = mkTyConApp typeRepTc []
+
+     (ty, rep) <-
+        case ev of
+
+          EvTypeableTyCon tc ks ts ->
+            do ctr       <- dsLookupGlobalId mkPolyTyConAppName
+               mkTyCon   <- dsLookupGlobalId mkTyConName
+               dflags    <- getDynFlags
+               let mkRep cRep kReps tReps =
+                     mkApps (Var ctr) [ cRep, mkListExpr tyRepType kReps
+                                            , mkListExpr tyRepType tReps ]
+
+               let kindRep k =
+                     case splitTyConApp_maybe k of
+                       Nothing -> panic "dsEvTypeable: not a kind constructor"
+                       Just (kc,ks) ->
+                         do kcRep <- tyConRep dflags mkTyCon kc
+                            reps  <- mapM kindRep ks
+                            return (mkRep kcRep [] reps)
+
+               tcRep     <- tyConRep dflags mkTyCon tc
+
+               kReps     <- mapM kindRep ks
+               tReps     <- mapM (getRep tyCl) ts
+
+               return ( mkTyConApp tc (ks ++ map snd ts)
+                      , mkRep tcRep kReps tReps
+                      )
+
+          EvTypeableTyApp t1 t2 ->
+            do e1  <- getRep tyCl t1
+               e2  <- getRep tyCl t2
+               ctr <- dsLookupGlobalId mkAppTyName
+
+               return ( mkAppTy (snd t1) (snd t2)
+                      , mkApps (Var ctr) [ e1, e2 ]
+                      )
+
+          EvTypeableTyLit ty ->
+            do str <- case (isNumLitTy ty, isStrLitTy ty) of
+                        (Just n, _) -> return (show n)
+                        (_, Just n) -> return (show n)
+                        _ -> panic "dsEvTypeable: malformed TyLit evidence"
+               ctr <- dsLookupGlobalId typeLitTypeRepName
+               tag <- mkStringExpr str
+               return (ty, mkApps (Var ctr) [ tag ])
+
+     -- TyRep -> Typeable t
+     -- see also: Note [Memoising typeOf]
+     repName <- newSysLocalDs tyRepType
+     let proxyT = mkProxyPrimTy (typeKind ty) ty
+         method = bindNonRec repName rep
+                $ mkLams [mkWildValBinder proxyT] (Var repName)
+
+     -- package up the method as `Typeable` dictionary
+     return $ mkCast method $ mkSymCo $ getTypeableCo tyCl ty
+
+  where
+  -- co: method -> Typeable k t
+  getTypeableCo tc t =
+    case instNewTyCon_maybe tc [typeKind t, t] of
+      Just (_,co) -> co
+      _           -> panic "Class `Typeable` is not a `newtype`."
+
+  -- Typeable t -> TyRep
+  getRep tc (ev,t) =
+    do typeableExpr <- dsEvTerm ev
+       let co     = getTypeableCo tc t
+           method = mkCast typeableExpr co
+           proxy  = mkTyApps (Var proxyHashId) [typeKind t, t]
+       return (mkApps method [proxy])
+
+  -- This part could be cached
+  tyConRep dflags mkTyCon tc =
+    do pkgStr  <- mkStringExprFS pkg_fs
+       modStr  <- mkStringExprFS modl_fs
+       nameStr <- mkStringExprFS name_fs
+       return (mkApps (Var mkTyCon) [ int64 high, int64 low
+                                    , pkgStr, modStr, nameStr
+                                    ])
+    where
+    tycon_name                = tyConName tc
+    modl                      = nameModule tycon_name
+    pkg                       = modulePackageKey modl
+
+    modl_fs                   = moduleNameFS (moduleName modl)
+    pkg_fs                    = packageKeyFS pkg
+    name_fs                   = occNameFS (nameOccName tycon_name)
+    hash_name_fs
+      | isPromotedTyCon tc    = appendFS (mkFastString "$k") name_fs
+      | isPromotedDataCon tc  = appendFS (mkFastString "$c") name_fs
+      | otherwise             = name_fs
+
+    hashThis = unwords $ map unpackFS [pkg_fs, modl_fs, hash_name_fs]
+    Fingerprint high low = fingerprintString hashThis
+
+    int64
+      | wORD_SIZE dflags == 4 = mkWord64LitWord64
+      | otherwise             = mkWordLit dflags . fromIntegral
+
+
+
+{- Note [Memoising typeOf]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+See #3245, #9203
+
+IMPORTANT: we don't want to recalculate the TypeRep once per call with
+the proxy argument.  This is what went wrong in #3245 and #9203. So we
+help GHC by manually keeping the 'rep' *outside* the lambda.
+-}
+
 ---------------------------------------
 dsTcCoercion :: TcCoercion -> (Coercion -> CoreExpr) -> DsM CoreExpr
 -- This is the crucial function that moves
index c373fdf..b974d72 100644 (file)
@@ -517,6 +517,7 @@ data WarningFlag =
    | Opt_WarnPartialTypeSignatures
    | Opt_WarnMissingExportedSigs
    | Opt_WarnUntickedPromotedConstructors
+   | Opt_WarnDerivingTypeable
    deriving (Eq, Show, Enum)
 
 data Language = Haskell98 | Haskell2010
@@ -2842,6 +2843,7 @@ fWarningFlags = [
   flagSpec "warn-auto-orphans"                Opt_WarnAutoOrphans,
   flagSpec "warn-deprecations"                Opt_WarnWarningsDeprecations,
   flagSpec "warn-deprecated-flags"            Opt_WarnDeprecatedFlags,
+  flagSpec "warn-deriving-typeable"           Opt_WarnDerivingTypeable,
   flagSpec "warn-dodgy-exports"               Opt_WarnDodgyExports,
   flagSpec "warn-dodgy-foreign-imports"       Opt_WarnDodgyForeignImports,
   flagSpec "warn-dodgy-imports"               Opt_WarnDodgyImports,
index 0964dd4..eb36f62 100644 (file)
@@ -213,7 +213,15 @@ basicKnownKeyNames
         alternativeClassName,
         foldableClassName,
         traversableClassName,
-        typeableClassName,              -- derivable
+
+        -- Typeable
+        typeableClassName,
+        typeRepTyConName,
+        mkTyConName,
+        mkPolyTyConAppName,
+        mkAppTyName,
+        typeLitTypeRepName,
+
 
         -- Numeric stuff
         negateName, minusName, geName, eqName,
@@ -1020,9 +1028,21 @@ rationalToDoubleName = varQual gHC_FLOAT (fsLit "rationalToDouble") rationalToDo
 ixClassName :: Name
 ixClassName = clsQual gHC_ARR (fsLit "Ix") ixClassKey
 
--- Class Typeable
-typeableClassName :: Name
-typeableClassName     = clsQual tYPEABLE_INTERNAL    (fsLit "Typeable")  typeableClassKey
+-- Class Typeable, and functions for constructing `Typeable` dictionaries
+typeableClassName
+  , typeRepTyConName
+  , mkTyConName
+  , mkPolyTyConAppName
+  , mkAppTyName
+  , typeLitTypeRepName
+  :: Name
+typeableClassName     = clsQual tYPEABLE_INTERNAL (fsLit "Typeable")       typeableClassKey
+typeRepTyConName      = tcQual  tYPEABLE_INTERNAL (fsLit "TypeRep")        typeRepTyConKey
+mkTyConName           = varQual tYPEABLE_INTERNAL (fsLit "mkTyCon")        mkTyConKey
+mkPolyTyConAppName    = varQual tYPEABLE_INTERNAL (fsLit "mkPolyTyConApp") mkPolyTyConAppKey
+mkAppTyName           = varQual tYPEABLE_INTERNAL (fsLit "mkAppTy")        mkAppTyKey
+typeLitTypeRepName    = varQual tYPEABLE_INTERNAL (fsLit "typeLitTypeRep") typeLitTypeRepKey
+
 
 
 -- Class Data
@@ -1517,6 +1537,9 @@ staticPtrTyConKey  = mkPreludeTyConUnique 180
 staticPtrInfoTyConKey :: Unique
 staticPtrInfoTyConKey = mkPreludeTyConUnique 181
 
+typeRepTyConKey :: Unique
+typeRepTyConKey = mkPreludeTyConUnique 183
+
 ---------------- Template Haskell -------------------
 --      USES TyConUniques 200-299
 -----------------------------------------------------
@@ -1844,6 +1867,18 @@ proxyHashKey = mkPreludeMiscIdUnique 502
 --      USES IdUniques 200-499
 -----------------------------------------------------
 
+-- Used to make `Typeable` dictionaries
+mkTyConKey
+  , mkPolyTyConAppKey
+  , mkAppTyKey
+  , typeLitTypeRepKey
+  :: Unique
+mkTyConKey        = mkPreludeMiscIdUnique 503
+mkPolyTyConAppKey = mkPreludeMiscIdUnique 504
+mkAppTyKey        = mkPreludeMiscIdUnique 505
+typeLitTypeRepKey = mkPreludeMiscIdUnique 506
+
+
 {-
 ************************************************************************
 *                                                                      *
index 488a076..06fbadf 100644 (file)
@@ -43,7 +43,6 @@ import Avail
 import Unify( tcUnifyTy )
 import Class
 import Type
-import Kind( isKind )
 import ErrUtils
 import DataCon
 import Maybes
@@ -150,18 +149,10 @@ forgetTheta :: EarlyDerivSpec -> DerivSpec ()
 forgetTheta (InferTheta spec) = spec { ds_theta = () }
 forgetTheta (GivenTheta spec) = spec { ds_theta = () }
 
-earlyDSTyCon :: EarlyDerivSpec -> TyCon
-earlyDSTyCon (InferTheta spec) = ds_tc spec
-earlyDSTyCon (GivenTheta spec) = ds_tc spec
-
 earlyDSLoc :: EarlyDerivSpec -> SrcSpan
 earlyDSLoc (InferTheta spec) = ds_loc spec
 earlyDSLoc (GivenTheta spec) = ds_loc spec
 
-earlyDSClass :: EarlyDerivSpec -> Class
-earlyDSClass (InferTheta spec) = ds_cls spec
-earlyDSClass (GivenTheta spec) = ds_cls spec
-
 splitEarlyDerivSpec :: [EarlyDerivSpec] -> ([DerivSpec ThetaOrigin], [DerivSpec ThetaType])
 splitEarlyDerivSpec [] = ([],[])
 splitEarlyDerivSpec (InferTheta spec : specs) =
@@ -382,10 +373,11 @@ tcDeriving tycl_decls inst_decls deriv_decls
         ; let (binds, newTyCons, famInsts, extraInstances) =
                 genAuxBinds loc (unionManyBags (auxDerivStuff : deriv_stuff))
 
+        ; dflags <- getDynFlags
+
         ; (inst_info, rn_binds, rn_dus) <-
             renameDeriv is_boot (inst_infos ++ (bagToList extraInstances)) binds
 
-        ; dflags <- getDynFlags
         ; unless (isEmptyBag inst_info) $
              liftIO (dumpIfSet_dyn dflags Opt_D_dump_deriv "Derived instances"
                         (ddump_deriving inst_info rn_binds newTyCons famInsts))
@@ -414,6 +406,73 @@ tcDeriving tycl_decls inst_decls deriv_decls
 
     hangP s x = text "" $$ hang (ptext (sLit s)) 2 x
 
+{-
+genTypeableTyConReps :: DynFlags ->
+                        [LTyClDecl Name] ->
+                        [LInstDecl Name] ->
+                        TcM (Bag (LHsBind RdrName, LSig RdrName))
+genTypeableTyConReps dflags decls insts =
+  do tcs1 <- mapM tyConsFromDecl decls
+     tcs2 <- mapM tyConsFromInst insts
+     return $ listToBag [ genTypeableTyConRep dflags loc tc
+                                          | (loc,tc) <- concat (tcs1 ++ tcs2) ]
+  where
+
+  tyConFromDataCon (L l n) = do dc <- tcLookupDataCon n
+                                return (do tc <- promoteDataCon_maybe dc
+                                           return (l,tc))
+
+  -- Promoted data constructors from a data declaration, or
+  -- a data-family instance.
+  tyConsFromDataRHS = fmap catMaybes
+                    . mapM tyConFromDataCon
+                    . concatMap (con_names . unLoc)
+                    . dd_cons
+
+  -- Tycons from a data-family declaration; not promotable.
+  tyConFromDataFamDecl FamilyDecl { fdLName = L loc name } =
+    do tc <- tcLookupTyCon name
+       return (loc,tc)
+
+
+  -- tycons from a type-level declaration
+  tyConsFromDecl (L _ d)
+
+    -- data or newtype declaration: promoted tycon, tycon, promoted ctrs.
+    | isDataDecl d =
+      do let L loc name = tcdLName d
+         tc           <- tcLookupTyCon name
+         promotedCtrs <- tyConsFromDataRHS (tcdDataDefn d)
+         let tyCons = (loc,tc) : promotedCtrs
+
+         return (case promotableTyCon_maybe tc of
+                   Nothing -> tyCons
+                   Just kc -> (loc,kc) : tyCons)
+
+    -- data family: just the type constructor;  these are not promotable.
+    | isDataFamilyDecl d =
+      do res <- tyConFromDataFamDecl (tcdFam d)
+         return [res]
+
+    -- class: the type constructors of associated data families
+    | isClassDecl d =
+      let isData FamilyDecl { fdInfo = DataFamily } = True
+          isData _ = False
+
+      in mapM tyConFromDataFamDecl (filter isData (map unLoc (tcdATs d)))
+
+    | otherwise = return []
+
+
+  tyConsFromInst (L _ d) =
+    case d of
+      ClsInstD ci      -> fmap concat
+                        $ mapM (tyConsFromDataRHS . dfid_defn . unLoc)
+                        $ cid_datafam_insts ci
+      DataFamInstD dfi -> tyConsFromDataRHS (dfid_defn dfi)
+      TyFamInstD {}    -> return []
+-}
+
 -- Prints the representable type family instance
 pprRepTy :: FamInst -> SDoc
 pprRepTy fi@(FamInst { fi_tys = lhs })
@@ -527,13 +586,7 @@ makeDerivSpecs is_boot tycl_decls inst_decls deriv_decls
   = do  { eqns1 <- concatMapM (recoverM (return []) . deriveTyDecl)     tycl_decls
         ; eqns2 <- concatMapM (recoverM (return []) . deriveInstDecl)   inst_decls
         ; eqns3 <- concatMapM (recoverM (return []) . deriveStandalone) deriv_decls
-
-        -- If AutoDeriveTypeable is set, we automatically add Typeable instances
-        -- for every data type and type class declared in the module
-        ; auto_typeable <- xoptM Opt_AutoDeriveTypeable
-        ; eqns4 <- deriveAutoTypeable auto_typeable (eqns1 ++ eqns3) tycl_decls
-
-        ; let eqns = eqns1 ++ eqns2 ++ eqns3 ++ eqns4
+        ; let eqns = eqns1 ++ eqns2 ++ eqns3
 
         ; if is_boot then   -- No 'deriving' at all in hs-boot files
               do { unless (null eqns) (add_deriv_err (head eqns))
@@ -545,33 +598,6 @@ makeDerivSpecs is_boot tycl_decls inst_decls deriv_decls
          addErr (hang (ptext (sLit "Deriving not permitted in hs-boot file"))
                     2 (ptext (sLit "Use an instance declaration instead")))
 
-deriveAutoTypeable :: Bool -> [EarlyDerivSpec] -> [LTyClDecl Name] -> TcM [EarlyDerivSpec]
--- Runs over *all* TyCl declarations, including classes and data families
--- i.e. not just data type decls
-deriveAutoTypeable auto_typeable done_specs tycl_decls
-  | not auto_typeable = return []
-  | otherwise         = do { cls <- tcLookupClass typeableClassName
-                           ; concatMapM (do_one cls) tycl_decls }
-  where
-    done_tcs = mkNameSet [ tyConName (earlyDSTyCon spec)
-                         | spec <- done_specs
-                         , className (earlyDSClass spec) == typeableClassName ]
-        -- Check if an automatically generated DS for deriving Typeable should be
-        -- omitted because the user had manually requested an instance
-
-    do_one cls (L _ decl)
-      = do { tc <- tcLookupTyCon (tcdName decl)
-           -- Traverse into class declarations to check if they have ATs (#9999)
-           ; ats <- if isClassDecl decl
-                    then concatMapM (do_one cls) (map (fmap FamDecl) (tcdATs decl))
-                    else return []
-           ; rest <- if (isTypeSynonymTyCon tc || isTypeFamilyTyCon tc
-                                       || tyConName tc `elemNameSet` done_tcs)
-                     -- Do not derive Typeable for type synonyms or type families
-                     then return []
-                     else mkPolyKindedTypeableEqn cls tc
-          ; return (ats ++ rest) }
-
 ------------------------------------------------------------------
 deriveTyDecl :: LTyClDecl Name -> TcM [EarlyDerivSpec]
 deriveTyDecl (L _ decl@(DataDecl { tcdLName = L _ tc_name
@@ -582,7 +608,7 @@ deriveTyDecl (L _ decl@(DataDecl { tcdLName = L _ tc_name
              tys  = mkTyVarTys tvs
 
        ; case preds of
-          Just (L _ preds') -> concatMapM (deriveTyData False tvs tc tys) preds'
+          Just (L _ preds') -> concatMapM (deriveTyData tvs tc tys) preds'
           Nothing           -> return [] }
 
 deriveTyDecl _ = return []
@@ -606,7 +632,7 @@ deriveFamInst decl@(DataFamInstDecl
        ; tcFamTyPats (famTyConShape fam_tc) pats (kcDataDefn defn) $
              -- kcDataDefn defn: see Note [Finding the LHS patterns]
          \ tvs' pats' _ ->
-           concatMapM (deriveTyData True tvs' fam_tc pats') preds }
+           concatMapM (deriveTyData tvs' fam_tc pats') preds }
 
 deriveFamInst _ = return []
 
@@ -640,8 +666,7 @@ deriveStandalone (L loc (DerivDecl deriv_ty overlap_mode))
   = setSrcSpan loc                   $
     addErrCtxt (standaloneCtxt deriv_ty)  $
     do { traceTc "Standalone deriving decl for" (ppr deriv_ty)
-       ; (tvs, theta, cls, inst_tys) <- setXOptM Opt_DataKinds $ -- for polykinded typeable
-                                        tcHsInstHead TcType.InstDeclCtxt deriv_ty
+       ; (tvs, theta, cls, inst_tys) <- tcHsInstHead TcType.InstDeclCtxt deriv_ty
        ; traceTc "Standalone deriving;" $ vcat
               [ text "tvs:" <+> ppr tvs
               , text "theta:" <+> ppr theta
@@ -659,10 +684,12 @@ deriveStandalone (L loc (DerivDecl deriv_ty overlap_mode))
 
        ; case tcSplitTyConApp_maybe inst_ty of
            Just (tc, tc_args)
-              | className cls == typeableClassName  -- Works for algebraic TyCons
-                                                    -- _and_ data families
-              -> do { check_standalone_typeable theta tc tc_args
-                    ; mkPolyKindedTypeableEqn cls tc }
+              | className cls == typeableClassName
+              -> do warn <- woptM Opt_WarnDerivingTypeable
+                    when warn
+                       $ addWarnTc
+                       $ text "Standalone deriving `Typeable` has no effect."
+                    return []
 
               | isAlgTyCon tc  -- All other classes
               -> do { spec <- mkEqnHelp (fmap unLoc overlap_mode)
@@ -670,59 +697,19 @@ deriveStandalone (L loc (DerivDecl deriv_ty overlap_mode))
                     ; return [spec] }
 
            _  -> -- Complain about functions, primitive types, etc,
-                 -- except for the Typeable class
                  failWithTc $ derivingThingErr False cls cls_tys inst_ty $
                  ptext (sLit "The last argument of the instance must be a data or newtype application")
         }
-  where
-    check_standalone_typeable theta tc tc_args
-             -- We expect to see
-             --       deriving Typeable <kind> T
-             -- for some tycon T.  But if S is kind-polymorphic,
-             -- say (S :: forall k. k -> *), we might see
-             --       deriving Typable <kind> (S k)
-             --
-             -- But we should NOT see
-             --       deriving Typeable <kind> (T Int)
-             -- or    deriving Typeable <kind> (S *)   where S is kind-polymorphic
-             --
-             -- So all the tc_args should be distinct kind variables
-      | null theta
-      , allDistinctTyVars tc_args
-      , all is_kind_var tc_args
-      = return ()
-
-      | otherwise
-      = do { polykinds <- xoptM Opt_PolyKinds
-           ; failWith (mk_msg polykinds theta tc tc_args) }
-
-    is_kind_var tc_arg = case tcGetTyVar_maybe tc_arg of
-                           Just v  -> isKindVar v
-                           Nothing -> False
-
-    mk_msg polykinds theta tc tc_args
-      | not polykinds
-      , all isKind tc_args   -- Non-empty, all kinds, at least one not a kind variable
-      , null theta
-      = hang (ptext (sLit "To make a Typeable instance of poly-kinded")
-               <+> quotes (ppr tc) <> comma)
-           2 (ptext (sLit "use XPolyKinds"))
-
-      | otherwise
-      = hang (ptext (sLit "Derived Typeable instance must be of form"))
-           2 (ptext (sLit "deriving instance Typeable") <+> ppr tc)
 
 
 ------------------------------------------------------------------
-deriveTyData :: Bool                         -- False <=> data/newtype
-                                             -- True  <=> data/newtype *instance*
-             -> [TyVar] -> TyCon -> [Type]   -- LHS of data or data instance
+deriveTyData :: [TyVar] -> TyCon -> [Type]   -- LHS of data or data instance
                                              --   Can be a data instance, hence [Type] args
              -> LHsType Name                 -- The deriving predicate
              -> TcM [EarlyDerivSpec]
 -- The deriving clause of a data or newtype declaration
 -- I.e. not standalone deriving
-deriveTyData is_instance tvs tc tc_args (L loc deriv_pred)
+deriveTyData tvs tc tc_args (L loc deriv_pred)
   = setSrcSpan loc     $        -- Use the location of the 'deriving' item
     do  { (deriv_tvs, cls, cls_tys, cls_arg_kind)
                 <- tcExtendTyVarEnv tvs $
@@ -736,7 +723,11 @@ deriveTyData is_instance tvs tc tc_args (L loc deriv_pred)
                 -- so the argument kind 'k' is not decomposable by splitKindFunTys
                 -- as is the case for all other derivable type classes
         ; if className cls == typeableClassName
-          then derivePolyKindedTypeable is_instance cls cls_tys tvs tc tc_args
+          then do warn <- woptM Opt_WarnDerivingTypeable
+                  when warn
+                     $ addWarnTc
+                     $ text "Deriving `Typeable` has no effect."
+                  return []
           else
 
      do {  -- Given data T a b c = ... deriving( C d ),
@@ -792,25 +783,6 @@ deriveTyData is_instance tvs tc tc_args (L loc deriv_pred)
                             cls final_cls_tys tc final_tc_args Nothing
         ; return [spec] } }
 
-derivePolyKindedTypeable :: Bool -> Class -> [Type]
-                         -> [TyVar] -> TyCon -> [Type]
-                         -> TcM [EarlyDerivSpec]
--- The deriving( Typeable ) clause of a data/newtype decl
--- I.e. not standalone deriving
-derivePolyKindedTypeable is_instance cls cls_tys _tvs tc tc_args
-  | is_instance
-  = failWith (sep [ ptext (sLit "Deriving Typeable is not allowed for family instances;")
-                  , ptext (sLit "derive Typeable for")
-                    <+> quotes (pprSourceTyCon tc)
-                    <+> ptext (sLit "alone") ])
-
-  | otherwise
-  = ASSERT( allDistinctTyVars tc_args )  -- Came from a data/newtype decl
-    do { checkTc (isSingleton cls_tys) $   -- Typeable k
-         derivingThingErr False cls cls_tys (mkTyConApp tc tc_args)
-                          (classArgsErr cls cls_tys)
-
-       ; mkPolyKindedTypeableEqn cls tc }
 
 {-
 Note [Unify kinds in deriving]
@@ -1046,38 +1018,6 @@ mk_data_eqn overlap_mode tvs cls tycon tc_args rep_tc rep_tc_args mtheta
 
 ----------------------
 
-mkPolyKindedTypeableEqn :: Class -> TyCon -> TcM [EarlyDerivSpec]
--- We can arrive here from a 'deriving' clause
--- or from standalone deriving
-mkPolyKindedTypeableEqn cls tc
-  = do { dflags <- getDynFlags   -- It's awkward to re-used checkFlag here,
-       ; checkTc(xopt Opt_DeriveDataTypeable dflags) -- so we do a DIY job
-                (hang (ptext (sLit "Can't make a Typeable instance of") <+> quotes (ppr tc))
-                    2 (ptext (sLit "You need DeriveDataTypeable to derive Typeable instances")))
-
-       ; loc <- getSrcSpanM
-       ; let prom_dcs = mapMaybe promoteDataCon_maybe (tyConDataCons tc)
-       ; mapM (mk_one loc) (tc : prom_dcs) }
-  where
-     mk_one loc tc = do { traceTc "mkPolyKindedTypeableEqn" (ppr tc)
-                        ; dfun_name <- new_dfun_name cls tc
-                        ; return $ GivenTheta $
-                          DS { ds_loc = loc, ds_name = dfun_name
-                             , ds_tvs = kvs, ds_cls = cls
-                             , ds_tys = [tc_app_kind, tc_app]
-                                 -- Remember, Typeable :: forall k. k -> *
-                                 -- so we must instantiate it appropiately
-                             , ds_tc = tc, ds_tc_args = tc_args
-                             , ds_theta = []  -- Context is empty for polykinded Typeable
-                             , ds_overlap = Nothing
-                               -- Perhaps this should be `Just NoOverlap`?
-
-                             , ds_newtype = False } }
-        where
-          (kvs,tc_app_kind) = splitForAllTys (tyConKind tc)
-          tc_args = mkTyVarTys kvs
-          tc_app  = mkTyConApp tc tc_args
-
 inferConstraints :: Class -> [TcType]
                  -> TyCon -> [TcType]
                  -> TcM ThetaOrigin
index 1f8f9b0..5bfd209 100644 (file)
@@ -15,6 +15,7 @@ module TcEvidence (
   EvBind(..), emptyTcEvBinds, isEmptyTcEvBinds,
   EvTerm(..), mkEvCast, evVarsOfTerm,
   EvLit(..), evTermCoercion,
+  EvTypeable(..),
 
   -- TcCoercion
   TcCoercion(..), LeftOrRight(..), pickLR,
@@ -704,8 +705,23 @@ data EvTerm
   | EvLit EvLit       -- Dictionary for KnownNat and KnownSymbol classes.
                       -- Note [KnownNat & KnownSymbol and EvLit]
 
-  deriving( Data.Data, Data.Typeable)
+  | EvTypeable EvTypeable   -- Dictionary for `Typeable`
 
+  deriving( Data.Data, Data.Typeable )
+
+-- | Instructions on how to make a 'Typeable' dictionary.
+data EvTypeable
+  = EvTypeableTyCon TyCon [Kind] [(EvTerm, Type)]
+    -- ^ Dicitionary for concrete type constructors.
+
+  | EvTypeableTyApp (EvTerm,Type) (EvTerm,Type)
+    -- ^ Dictionary for type applications;  this is used when we have
+    -- a type expression starting with a type variable (e.g., @Typeable (f a)@)
+
+  | EvTypeableTyLit Type
+    -- ^ Dictionary for a type literal.
+
+  deriving ( Data.Data, Data.Typeable )
 
 data EvLit
   = EvNum Integer
@@ -835,10 +851,18 @@ evVarsOfTerm (EvCast tm co)       = evVarsOfTerm tm `unionVarSet` coVarsOfTcCo c
 evVarsOfTerm (EvTupleMk evs)      = evVarsOfTerms evs
 evVarsOfTerm (EvDelayedError _ _) = emptyVarSet
 evVarsOfTerm (EvLit _)            = emptyVarSet
+evVarsOfTerm (EvTypeable ev)      = evVarsOfTypeable ev
 
 evVarsOfTerms :: [EvTerm] -> VarSet
 evVarsOfTerms = mapUnionVarSet evVarsOfTerm
 
+evVarsOfTypeable :: EvTypeable -> VarSet
+evVarsOfTypeable ev =
+  case ev of
+    EvTypeableTyCon _ _ es -> evVarsOfTerms (map fst es)
+    EvTypeableTyApp e1 e2  -> evVarsOfTerms (map fst [e1,e2])
+    EvTypeableTyLit _      -> emptyVarSet
+
 {-
 ************************************************************************
 *                                                                      *
@@ -900,7 +924,16 @@ instance Outputable EvTerm where
   ppr (EvLit l)          = ppr l
   ppr (EvDelayedError ty msg) =     ptext (sLit "error")
                                 <+> sep [ char '@' <> ppr ty, ppr msg ]
+  ppr (EvTypeable ev)    = ppr ev
 
 instance Outputable EvLit where
   ppr (EvNum n) = integer n
   ppr (EvStr s) = text (show s)
+
+instance Outputable EvTypeable where
+  ppr ev =
+    case ev of
+      EvTypeableTyCon tc ks ts -> parens (ppr tc <+> sep (map ppr ks) <+>
+                                                     sep (map (ppr . fst) ts))
+      EvTypeableTyApp t1 t2    -> parens (ppr (fst t1) <+> ppr (fst t2))
+      EvTypeableTyLit x        -> ppr x
index cdce739..279710d 100644 (file)
@@ -54,7 +54,6 @@ import Class
 import TypeRep
 import VarSet
 import VarEnv
-import Module
 import State
 import Util
 import Var
@@ -66,7 +65,6 @@ import Lexeme
 import FastString
 import Pair
 import Bag
-import Fingerprint
 import TcEnv (InstInfo)
 import StaticFlags( opt_PprStyle_Debug )
 
@@ -119,7 +117,6 @@ genDerivedBinds dflags fix_env clas loc tycon
   where
     gen_list :: [(Unique, SrcSpan -> TyCon -> (LHsBinds RdrName, BagDerivStuff))]
     gen_list = [ (eqClassKey,          gen_Eq_binds)
-               , (typeableClassKey,    gen_Typeable_binds dflags)
                , (ordClassKey,         gen_Ord_binds)
                , (enumClassKey,        gen_Enum_binds)
                , (boundedClassKey,     gen_Bounded_binds)
@@ -1233,55 +1230,6 @@ getPrecedence get_fixity nm
 {-
 ************************************************************************
 *                                                                      *
-\subsection{Typeable (new)}
-*                                                                      *
-************************************************************************
-
-From the data type
-
-        data T a b = ....
-
-we generate
-
-        instance Typeable2 T where
-                typeOf2 _ = mkTyConApp (mkTyCon <hash-high> <hash-low>
-                                                <pkg> <module> "T") []
-
-We are passed the Typeable2 class as well as T
--}
-
-gen_Typeable_binds :: DynFlags -> SrcSpan -> TyCon
-                   -> (LHsBinds RdrName, BagDerivStuff)
-gen_Typeable_binds dflags loc tycon
-  = ( unitBag $ mk_easy_FunBind loc typeRep_RDR [nlWildPat]
-                (nlHsApps mkTyConApp_RDR [tycon_rep, nlList []])
-    , emptyBag )
-  where
-    tycon_name = tyConName tycon
-    modl       = nameModule tycon_name
-    pkg        = modulePackageKey modl
-
-    modl_fs    = moduleNameFS (moduleName modl)
-    pkg_fs     = packageKeyFS pkg
-    name_fs    = occNameFS (nameOccName tycon_name)
-
-    tycon_rep = nlHsApps mkTyCon_RDR
-                    (map nlHsLit [int64 high,
-                                  int64 low,
-                                  HsString "" pkg_fs,
-                                  HsString "" modl_fs,
-                                  HsString "" name_fs])
-
-    hashThis = unwords $ map unpackFS [pkg_fs, modl_fs, name_fs]
-    Fingerprint high low = fingerprintString hashThis
-
-    int64
-      | wORD_SIZE dflags == 4 = HsWord64Prim "" . fromIntegral
-      | otherwise             = HsWordPrim "" . fromIntegral
-
-{-
-************************************************************************
-*                                                                      *
         Data instances
 *                                                                      *
 ************************************************************************
index 876ec2b..01b1cf7 100644 (file)
@@ -1246,6 +1246,20 @@ zonkEvTerm env (EvTupleSel tm n)  = do { tm' <- zonkEvTerm env tm
 zonkEvTerm env (EvTupleMk tms)    = do { tms' <- mapM (zonkEvTerm env) tms
                                        ; return (EvTupleMk tms') }
 zonkEvTerm _   (EvLit l)          = return (EvLit l)
+
+zonkEvTerm env (EvTypeable ev) =
+  fmap EvTypeable $
+  case ev of
+    EvTypeableTyCon tc ks ts -> EvTypeableTyCon tc ks `fmap` mapM zonk ts
+    EvTypeableTyApp t1 t2    -> do e1 <- zonk t1
+                                   e2 <- zonk t2
+                                   return (EvTypeableTyApp e1 e2)
+    EvTypeableTyLit t        -> EvTypeableTyLit `fmap` zonkTcTypeToType env t
+  where
+  zonk (ev,t) = do ev' <- zonkEvTerm env ev
+                   t'  <- zonkTcTypeToType env t
+                   return (ev',t')
+
 zonkEvTerm env (EvSuperClass d n) = do { d' <- zonkEvTerm env d
                                        ; return (EvSuperClass d' n) }
 zonkEvTerm env (EvDFunApp df tys tms)
index aba5be9..3aee02d 100644 (file)
@@ -43,7 +43,7 @@ import Class
 import Var
 import VarEnv
 import VarSet
-import PrelNames  ( tYPEABLE_INTERNAL, typeableClassName, genericClassNames )
+import PrelNames  ( typeableClassName, genericClassNames )
 import Bag
 import BasicTypes
 import DynFlags
@@ -371,7 +371,6 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
             -- round)
 
             -- Do class and family instance declarations
-       ; env <- getGblEnv
        ; stuff <- mapAndRecoverM tcLocalInstDecl inst_decls
        ; let (local_infos_s, fam_insts_s) = unzip stuff
              fam_insts    = concat fam_insts_s
@@ -379,7 +378,7 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
              -- Handwritten instances of the poly-kinded Typeable class are
              -- forbidden, so we handle those separately
              (typeable_instances, local_infos)
-                = partition (bad_typeable_instance env) local_infos'
+                = partition bad_typeable_instance local_infos'
 
        ; addClsInsts local_infos $
          addFamInsts fam_insts   $
@@ -423,14 +422,9 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
     }}
   where
     -- Separate the Typeable instances from the rest
-    bad_typeable_instance env i
-      =       -- Class name is Typeable
-         typeableClassName == is_cls_nm (iSpec i)
-              -- but not those that come from Data.Typeable.Internal
-      && tcg_mod env /= tYPEABLE_INTERNAL
-              -- nor those from an .hs-boot or .hsig file
-              -- (deriving can't be used there)
-      && not (isHsBootOrSig (tcg_src env))
+    bad_typeable_instance i
+      = typeableClassName == is_cls_nm (iSpec i)
+
 
     overlapCheck ty = case overlapMode (is_flag $ iSpec ty) of
                         NoOverlap _ -> False
@@ -441,18 +435,21 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
                          ptext (sLit "Replace the following instance:"))
                      2 (pprInstanceHdr (iSpec i))
 
-    typeable_err i
-      = setSrcSpan (getSrcSpan ispec) $
-        addErrTc $ hang (ptext (sLit "Typeable instances can only be derived"))
-                      2 (vcat [ ptext (sLit "Try") <+> quotes (ptext (sLit "deriving instance Typeable")
-                                                <+> pp_tc)
-                              , ptext (sLit "(requires StandaloneDeriving)") ])
-      where
-        ispec = iSpec i
-        pp_tc | [_kind, ty] <- is_tys ispec
-              , Just (tc,_) <- tcSplitTyConApp_maybe ty
-              = ppr tc
-              | otherwise = ptext (sLit "<tycon>")
+    -- Report an error or a warning for a `Typeable` instances.
+    -- If we are workikng on an .hs-boot file, we just report a warning,
+    -- and ignore the instance.  We do this, to give users a chance to fix
+    -- their code.
+    typeable_err i =
+      setSrcSpan (getSrcSpan (iSpec i)) $
+        do env <- getGblEnv
+           if isHsBootOrSig (tcg_src env)
+             then
+               do warn <- woptM Opt_WarnDerivingTypeable
+                  when warn $ addWarnTc $ vcat
+                    [ ptext (sLit "`Typeable` instances in .hs-boot files are ignored.")
+                    , ptext (sLit "This warning will become an error in future versions of the compiler.")
+                    ]
+             else addErrTc $ ptext (sLit "Class `Typeable` does not support user-specified instances.")
 
 addClsInsts :: [InstInfo Name] -> TcM a -> TcM a
 addClsInsts infos thing_inside
@@ -992,12 +989,6 @@ method in an instance declaration.  Here is an artificial example:
          compare :: a -> a -> Bool
          compare = error "You can't compare Ages"
 
-The instance signature can be *more* polymorphic than the instantiated
-class method (in this case: Age -> Age -> Bool), but it cannot be less
-polymorphic.  Moreover, if a signature is given, the implementation
-code should match the signature, and type variables bound in the
-singature should scope over the method body.
-
 We achieve this by building a TcSigInfo for the method, whether or not
 there is an instance method signature, and using that to typecheck
 the declaration (in tcInstanceMethodBody).  That means, conveniently,
index 1d0d8e4..9e7fe43 100644 (file)
@@ -12,13 +12,15 @@ import TcCanonical
 import TcFlatten
 import VarSet
 import Type
+import Kind (isKind)
 import Unify
 import InstEnv( lookupInstEnv, instanceDFunId )
 import CoAxiom(sfInteractTop, sfInteractInert)
 
 import Var
 import TcType
-import PrelNames (knownNatClassName, knownSymbolClassName, ipClassNameKey )
+import PrelNames ( knownNatClassName, knownSymbolClassName, ipClassNameKey
+                 , typeableClassName )
 import Id( idType )
 import Class
 import TyCon
@@ -1989,6 +1991,9 @@ matchClassInst _ clas [ ty ] _
     = panicTcS (text "Unexpected evidence for" <+> ppr (className clas)
                      $$ vcat (map (ppr . idType) (classMethods clas)))
 
+matchClassInst _ clas [k,t] loc
+  | className clas == typeableClassName = matchTypeableClass clas k t loc
+
 matchClassInst inerts clas tys loc
    = do { dflags <- getDynFlags
         ; tclvl <- getTcLevel
@@ -2110,3 +2115,58 @@ overlapping checks. There we are interested in validating the following principl
 But for the Given Overlap check our goal is just related to completeness of
 constraint solving.
 -}
+
+-- | Assumes that we've checked that this is the 'Typeable' class,
+-- and it was applied to the correc arugment.
+matchTypeableClass :: Class -> Kind -> Type -> CtLoc -> TcS LookupInstResult
+matchTypeableClass clas k t loc
+  | isForAllTy k                               = return NoInstance
+  | Just (tc, ks_tys) <- splitTyConApp_maybe t = doTyConApp tc ks_tys
+  | Just (f,kt)       <- splitAppTy_maybe t    = doTyApp f kt
+  | Just _            <- isNumLitTy t          = mkEv [] (EvTypeableTyLit t)
+  | Just _            <- isStrLitTy t          = mkEv [] (EvTypeableTyLit t)
+  | otherwise                                  = return NoInstance
+
+  where
+  -- Representation for type constructor applied to some kinds and some types.
+  doTyConApp tc ks_ts =
+    case mapM kindRep ks of
+      Nothing    -> return NoInstance      -- Not concrete kinds
+      Just kReps ->
+        do tCts <- mapM subGoal ts
+           mkEv tCts (EvTypeableTyCon tc kReps (map ctEvTerm tCts `zip` ts))
+    where
+    (ks,ts)    = span isKind ks_ts
+
+
+  {- Representation for an application of a type to a type-or-kind.
+  This may happen when the type expression starts with a type variable.
+  Example (ignoring kind parameter):
+    Typeable (f Int Char)                      -->
+    (Typeable (f Int), Typeable Char)          -->
+    (Typeable f, Typeable Int, Typeable Char)  --> (after some simp. steps)
+    Typeable f
+  -}
+  doTyApp f tk
+    | isKind tk = return NoInstance -- We can't solve until we know the ctr.
+    | otherwise =
+      do ct1 <- subGoal f
+         ct2 <- subGoal tk
+         mkEv [ct1,ct2] (EvTypeableTyApp (ctEvTerm ct1,f) (ctEvTerm ct2,tk))
+
+
+  -- Representation for concrete kinds.  We just use the kind itself,
+  -- but first check to make sure that it is "simple" (i.e., made entirely
+  -- out of kind constructors).
+  kindRep ki = do (_,ks) <- splitTyConApp_maybe ki
+                  mapM_ kindRep ks
+                  return ki
+
+
+  -- Emit a `Typeable` constraint for the given type.
+  subGoal ty = do let goal = mkClassPred clas [ typeKind ty, ty ]
+                  ev <- newWantedEvVarNC loc goal
+                  return ev
+
+
+  mkEv subs ev = return (GenInst subs (EvTypeable ev))
index 98c09bf..994a2c2 100644 (file)
           </row>
           <row>
             <entry><option>-XAutoDeriveTypeable</option></entry>
-            <entry>Automatically <link linkend="deriving-typeable">derive Typeable instances for every datatype and type class declaration</link>.
+            <entry>As of GHC 7.10, this option is not needed, and should
+                   not be used.  Automatically <link linkend="deriving-typeable">derive Typeable instances for every datatype and type class declaration</link>.
             Implies <option>-XDeriveDataTypeable</option>.</entry>
             <entry>dynamic</entry>
             <entry><option>-XNoAutoDeriveTypeable</option></entry>
           </row>
           <row>
             <entry><option>-XDeriveDataTypeable</option></entry>
-            <entry>Enable <link linkend="deriving-typeable">deriving for the Data and Typeable classes</link>.
+            <entry>Enable <link linkend="deriving-typeable">deriving for the Data class</link>.
               Implied by <option>-XAutoDeriveTypeable</option>.</entry>
             <entry>dynamic</entry>
             <entry><option>-XNoDeriveDataTypeable</option></entry>
             <entry><option>-fno-warn-partial-type-signatures</option></entry>
           </row>
 
+          <row>
+            <entry><option>-fwarn-deriving-typeable</option></entry>
+            <entry>
+              warn when encountering a request to derive an instance of
+              class <literal>Typeable</literal>. As of GHC 7.10, such
+              declarations are unnecessary and are ignored by the compiler
+              because GHC has a custom solver for discharging this type of
+              constraint.
+            </entry>
+            <entry>dynamic</entry>
+            <entry><option>-fno-warn-deriving-typeable</option></entry>
+          </row>
+
+
         </tbody>
       </tgroup>
     </informaltable>
index 0221421..9029c74 100644 (file)
@@ -4062,44 +4062,49 @@ can be mentioned in the <literal>deriving</literal> clause.
 </para></listitem>
 
 <listitem><para>
-Only derived instances of <literal>Typeable</literal> are allowed;
-i.e. handwritten instances are forbidden.  This ensures that the
-programmer cannot subert the type system by writing bogus instances.
+GHC has a custom solver for discharging constraints that involve
+class <literal>Typeable</literal>, and handwritten instances are forbidden.
+This ensures that the programmer cannot subert the type system by
+writing bogus instances.
 </para></listitem>
 
 <listitem><para>
-With <option>-XDeriveDataTypeable</option>
-GHC allows you to derive instances of <literal>Typeable</literal> for data types or newtypes,
-using a <literal>deriving</literal> clause, or using
-a standalone deriving declaration (<xref linkend="stand-alone-deriving"/>).
+Derived instances of <literal>Typeable</literal> are ignored,
+and may be reported as an error in a later version of the compiler.
 </para></listitem>
 
 <listitem><para>
-With <option>-XDataKinds</option>, deriving <literal>Typeable</literal> for a data
-type (whether via a deriving clause or standalone deriving)
-also derives <literal>Typeable</literal> for the promoted data constructors (<xref linkend="promotion"/>).
+The rules for solving `Typeable` constraints are as follows:
+<itemizedlist>
+<listitem><para>A concrete type constructor applied to some types.
+<programlisting>
+instance (Typeable t1, .., Typeable t_n) =>
+  Typeable (T t1 .. t_n)
+</programlisting>
+This rule works for any concrete type constructor, including type
+constructors with polymorhic kinds.   The only restriction is that
+if the type constructor has a polymorhic kind, then it has to be applied
+to all of its kinds parameters, and these kinds need to be concrete
+(i.e., they cannot mention kind variables).
 </para></listitem>
 
 <listitem><para>
-However, using standalone deriving, you can <emphasis>also</emphasis> derive
-a <literal>Typeable</literal> instance for a data family.
-You may not add a <literal>deriving(Typeable)</literal> clause to a
-<literal>data instance</literal> declaration; instead you must use a
-standalone deriving declaration for the data family.
+<programlisting>A type variable applied to some types.
+instance (Typeable f, Typeable t1, .., Typeable t_n) =>
+  Typeable (f t1 .. t_n)
+</programlisting>
 </para></listitem>
 
 <listitem><para>
-Using standalone deriving, you can <emphasis>also</emphasis> derive
-a <literal>Typeable</literal> instance for a type class.
+<programlisting>A concrete type literal.
+instance Typeable 0       -- Type natural literals
+instance Typeable "Hello" -- Type-level symbols
+</programlisting>
 </para></listitem>
-
-<listitem><para>
-The flag <option>-XAutoDeriveTypeable</option> triggers the generation
-of derived <literal>Typeable</literal> instances for every datatype, data family,
-and type class declaration in the module it is used, unless a manually-specified one is
-already provided.
-This flag implies <option>-XDeriveDataTypeable</option>.
+</itemizedlist>
 </para></listitem>
+
+
 </itemizedlist>
 
 </para>
index 8917833..4cdc57d 100644 (file)
@@ -27,6 +27,7 @@
 module Data.Typeable.Internal (
     Proxy (..),
     TypeRep(..),
+    KindRep,
     Fingerprint(..),
     typeOf, typeOf1, typeOf2, typeOf3, typeOf4, typeOf5, typeOf6, typeOf7,
     Typeable1, Typeable2, Typeable3, Typeable4, Typeable5, Typeable6, Typeable7,
@@ -35,11 +36,13 @@ module Data.Typeable.Internal (
     mkTyCon,
     mkTyCon3,
     mkTyConApp,
+    mkPolyTyConApp,
     mkAppTy,
     typeRepTyCon,
     Typeable(..),
     mkFunTy,
     splitTyConApp,
+    splitPolyTyConApp,
     funResultTy,
     typeRepArgs,
     typeRepHash,
@@ -47,33 +50,15 @@ module Data.Typeable.Internal (
     showsTypeRep,
     tyConString,
     rnfTyCon,
-    listTc, funTc
+    listTc, funTc,
+    typeRepKinds,
+    typeLitTypeRep
   ) where
 
 import GHC.Base
 import GHC.Word
 import GHC.Show
-import GHC.Read ( Read )
 import Data.Proxy
-import GHC.Num
-import GHC.Real
--- import GHC.IORef
--- import GHC.IOArray
--- import GHC.MVar
-import GHC.ST           ( ST, STret )
-import GHC.STRef        ( STRef )
-import GHC.Ptr          ( Ptr, FunPtr )
--- import GHC.Stable
-import GHC.Arr          ( Array, STArray, Ix )
-import GHC.TypeLits ( Nat, Symbol, KnownNat, KnownSymbol, natVal', symbolVal' )
-import Data.Type.Coercion
-import Data.Type.Equality
-import Text.ParserCombinators.ReadP ( ReadP )
-import Text.Read.Lex ( Lexeme, Number )
-import Text.ParserCombinators.ReadPrec ( ReadPrec )
-import GHC.Float ( FFFormat, RealFloat, Floating )
-import Data.Bits ( Bits, FiniteBits )
-import GHC.Enum ( Bounded, Enum )
 
 import GHC.Fingerprint.Type
 import {-# SOURCE #-} GHC.Fingerprint
@@ -84,14 +69,17 @@ import {-# SOURCE #-} GHC.Fingerprint
 
 -- | A concrete representation of a (monomorphic) type.  'TypeRep'
 -- supports reasonably efficient equality.
-data TypeRep = TypeRep {-# UNPACK #-} !Fingerprint TyCon [TypeRep]
+data TypeRep = TypeRep {-# UNPACK #-} !Fingerprint TyCon [KindRep] [TypeRep]
+
+type KindRep = TypeRep
 
 -- Compare keys for equality
 instance Eq TypeRep where
-  (TypeRep k1 _ _) == (TypeRep k2 _ _) = k1 == k2
+  TypeRep x _ _ _ == TypeRep y _ _ _ = x == y
 
 instance Ord TypeRep where
-  (TypeRep k1 _ _) <= (TypeRep k2 _ _) = k1 <= k2
+  TypeRep x _ _ _ <= TypeRep y _ _ _ = x <= y
+
 
 -- | An abstract representation of a type constructor.  'TyCon' objects can
 -- be built using 'mkTyCon'.
@@ -126,25 +114,33 @@ mkTyCon :: Word#   -> Word#   -> String -> String -> String -> TyCon
 mkTyCon high# low# pkg modl name
   = TyCon (Fingerprint (W64# high#) (W64# low#)) pkg modl name
 
--- | Applies a type constructor to a sequence of types
-mkTyConApp  :: TyCon -> [TypeRep] -> TypeRep
-mkTyConApp tc@(TyCon tc_k _ _ _) []
-  = TypeRep tc_k tc [] -- optimisation: all derived Typeable instances
-                       -- end up here, and it helps generate smaller
-                       -- code for derived Typeable.
-mkTyConApp tc@(TyCon tc_k _ _ _) args
-  = TypeRep (fingerprintFingerprints (tc_k : arg_ks)) tc args
+-- | Applies a polymorhic type constructor to a sequence of kinds and types
+mkPolyTyConApp :: TyCon -> [KindRep] -> [TypeRep] -> TypeRep
+mkPolyTyConApp tc@(TyCon tc_k _ _ _) [] [] = TypeRep tc_k tc [] []
+mkPolyTyConApp tc@(TyCon tc_k _ _ _) kinds types =
+  TypeRep (fingerprintFingerprints (tc_k : arg_ks)) tc kinds types
   where
-    arg_ks = [k | TypeRep k _ _ <- args]
+  arg_ks = [ k | TypeRep k _ _ _ <- kinds ++ types ]
+
+-- | Applies a monomorphic type constructor to a sequence of types
+mkTyConApp  :: TyCon -> [TypeRep] -> TypeRep
+mkTyConApp tc = mkPolyTyConApp tc []
 
 -- | A special case of 'mkTyConApp', which applies the function
 -- type constructor to a pair of types.
 mkFunTy  :: TypeRep -> TypeRep -> TypeRep
 mkFunTy f a = mkTyConApp funTc [f,a]
 
--- | Splits a type constructor application
+-- | Splits a type constructor application.
+-- Note that if the type construcotr is polymorphic, this will
+-- not return the kinds that were used.
+-- See 'splitPolyTyConApp' if you need all parts.
 splitTyConApp :: TypeRep -> (TyCon,[TypeRep])
-splitTyConApp (TypeRep _ tc trs) = (tc,trs)
+splitTyConApp (TypeRep _ tc _ trs) = (tc,trs)
+
+-- | Split a type constructor application
+splitPolyTyConApp :: TypeRep -> (TyCon,[KindRep],[TypeRep])
+splitPolyTyConApp (TypeRep _ tc ks trs) = (tc,ks,trs)
 
 -- | Applies a type to a function type.  Returns: @'Just' u@ if the
 -- first argument represents a function of type @t -> u@ and the
@@ -158,7 +154,7 @@ funResultTy trFun trArg
 
 -- | Adds a TypeRep argument to a TypeRep.
 mkAppTy :: TypeRep -> TypeRep -> TypeRep
-mkAppTy (TypeRep _ tc trs) arg_tr = mkTyConApp tc (trs ++ [arg_tr])
+mkAppTy (TypeRep _ tc ks trs) arg_tr = mkPolyTyConApp tc ks (trs ++ [arg_tr])
    -- Notice that we call mkTyConApp to construct the fingerprint from tc and
    -- the arg fingerprints.  Simply combining the current fingerprint with
    -- the new one won't give the same answer, but of course we want to
@@ -183,11 +179,15 @@ mkTyCon3 pkg modl name =
 
 -- | Observe the type constructor of a type representation
 typeRepTyCon :: TypeRep -> TyCon
-typeRepTyCon (TypeRep _ tc _) = tc
+typeRepTyCon (TypeRep _ tc _ _) = tc
 
 -- | Observe the argument types of a type representation
 typeRepArgs :: TypeRep -> [TypeRep]
-typeRepArgs (TypeRep _ _ args) = args
+typeRepArgs (TypeRep _ _ _ tys) = tys
+
+-- | Observe the argument kinds of a type representation
+typeRepKinds :: TypeRep -> [KindRep]
+typeRepKinds (TypeRep _ _ ks _) = ks
 
 -- | Observe string encoding of a type representation
 {-# DEPRECATED tyConString "renamed to 'tyConName'; 'tyConModule' and 'tyConPackage' are also available." #-} -- deprecated in 7.4
@@ -198,7 +198,7 @@ tyConString = tyConName
 --
 -- @since 4.8.0.0
 typeRepHash :: TypeRep -> Fingerprint
-typeRepHash (TypeRep fpr _ _) = fpr
+typeRepHash (TypeRep fpr _ _ _) = fpr
 
 -------------------------------------------------------------
 --
@@ -265,27 +265,11 @@ type Typeable7 (a :: * -> * -> * -> * -> * -> * -> * -> *) = Typeable a
 {-# DEPRECATED Typeable6 "renamed to 'Typeable'" #-} -- deprecated in 7.8
 {-# DEPRECATED Typeable7 "renamed to 'Typeable'" #-} -- deprecated in 7.8
 
--- | Kind-polymorphic Typeable instance for type application
-instance (Typeable s, Typeable a) => Typeable (s a) where
-         -- See Note [The apparent incoherence of Typable]
-  typeRep# = \_ -> rep                  -- Note [Memoising typeOf]
-    where !ty1 = typeRep# (proxy# :: Proxy# s)
-          !ty2 = typeRep# (proxy# :: Proxy# a)
-          !rep = ty1 `mkAppTy` ty2
-
-{- Note [Memoising typeOf]
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-See #3245, #9203
-
-IMPORTANT: we don't want to recalculate the TypeRep once per call with
-the proxy argument.  This is what went wrong in #3245 and #9203. So we
-help GHC by manually keeping the 'rep' *outside* the lambda.
--}
 
 ----------------- Showing TypeReps --------------------
 
 instance Show TypeRep where
-  showsPrec p (TypeRep _ tycon tys) =
+  showsPrec p (TypeRep _ tycon kinds tys) =
     case tys of
       [] -> showsPrec p tycon
       [x]   | tycon == listTc -> showChar '[' . shows x . showChar ']'
@@ -298,7 +282,7 @@ instance Show TypeRep where
             showParen (p > 9) $
             showsPrec p tycon .
             showChar ' '      .
-            showArgs (showChar ' ') tys
+            showArgs (showChar ' ') (kinds ++ tys)
 
 showsTypeRep :: TypeRep -> ShowS
 showsTypeRep = shows
@@ -314,7 +298,7 @@ isTupleTyCon _                         = False
 --
 -- @since 4.8.0.0
 rnfTypeRep :: TypeRep -> ()
-rnfTypeRep (TypeRep _ tyc tyrs) = rnfTyCon tyc `seq` go tyrs
+rnfTypeRep (TypeRep _ tyc krs tyrs) = rnfTyCon tyc `seq` go krs `seq` go tyrs
   where
     go [] = ()
     go (x:xs) = rnfTypeRep x `seq` go xs
@@ -346,147 +330,11 @@ listTc = typeRepTyCon (typeOf [()])
 funTc :: TyCon
 funTc = typeRepTyCon (typeRep (Proxy :: Proxy (->)))
 
--------------------------------------------------------------
---
---      Instances of the Typeable classes for Prelude types
---
--------------------------------------------------------------
-
-deriving instance Typeable ()
-deriving instance Typeable []
-deriving instance Typeable Maybe
-deriving instance Typeable Ratio
-deriving instance Typeable (->)
-deriving instance Typeable IO
-
-deriving instance Typeable Array
-
-deriving instance Typeable ST
-deriving instance Typeable STret
-deriving instance Typeable STRef
-deriving instance Typeable STArray
-
-deriving instance Typeable (,)
-deriving instance Typeable (,,)
-deriving instance Typeable (,,,)
-deriving instance Typeable (,,,,)
-deriving instance Typeable (,,,,,)
-deriving instance Typeable (,,,,,,)
 
-deriving instance Typeable Ptr
-deriving instance Typeable FunPtr
 
--------------------------------------------------------
---
--- Generate Typeable instances for standard datatypes
---
--------------------------------------------------------
-
-deriving instance Typeable Bool
-deriving instance Typeable Char
-deriving instance Typeable Float
-deriving instance Typeable Double
-deriving instance Typeable Int
-deriving instance Typeable Word
-deriving instance Typeable Integer
-deriving instance Typeable Ordering
-
-deriving instance Typeable Word8
-deriving instance Typeable Word16
-deriving instance Typeable Word32
-deriving instance Typeable Word64
-
-deriving instance Typeable TyCon
-deriving instance Typeable TypeRep
-deriving instance Typeable Fingerprint
-
-deriving instance Typeable RealWorld
-deriving instance Typeable Proxy
-deriving instance Typeable KProxy
-deriving instance Typeable (:~:)
-deriving instance Typeable Coercion
-
-deriving instance Typeable ReadP
-deriving instance Typeable Lexeme
-deriving instance Typeable Number
-deriving instance Typeable ReadPrec
-
-deriving instance Typeable FFFormat
-
--------------------------------------------------------
---
--- Generate Typeable instances for standard classes
---
--------------------------------------------------------
-
-deriving instance Typeable (~)
-deriving instance Typeable Coercible
-deriving instance Typeable TestEquality
-deriving instance Typeable TestCoercion
-
-deriving instance Typeable Eq
-deriving instance Typeable Ord
-
-deriving instance Typeable Bits
-deriving instance Typeable FiniteBits
-deriving instance Typeable Num
-deriving instance Typeable Real
-deriving instance Typeable Integral
-deriving instance Typeable Fractional
-deriving instance Typeable RealFrac
-deriving instance Typeable Floating
-deriving instance Typeable RealFloat
-
-deriving instance Typeable Bounded
-deriving instance Typeable Enum
-deriving instance Typeable Ix
-
-deriving instance Typeable Show
-deriving instance Typeable Read
-
-deriving instance Typeable Alternative
-deriving instance Typeable Applicative
-deriving instance Typeable Functor
-deriving instance Typeable Monad
-deriving instance Typeable MonadPlus
-deriving instance Typeable Monoid
-
-deriving instance Typeable Typeable
-
-
-
---------------------------------------------------------------------------------
--- Instances for type literals
-
-{- Note [Potential Collisions in `Nat` and `Symbol` instances]
-
-Kinds resulting from lifted types have finitely many type-constructors.
-This is not the case for `Nat` and `Symbol`, which both contain *infinitely*
-many type constructors (e.g., `Nat` has 0, 1, 2, 3, etc.).  One might think
-that this would increase the chance of hash-collisions in the type but this
-is not the case because the fingerprint stored in a `TypeRep` identifies
-the whole *type* and not just the type constructor.  This is why the chance
-of collisions for `Nat` and `Symbol` is not any worse than it is for other
-lifted types with infinitely many inhabitants.  Indeed, `Nat` is
-isomorphic to (lifted) `[()]`  and `Symbol` is isomorphic to `[Char]`.
--}
-
-{- Note [The apparent incoherence of Typable] See Trac #9242
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The reason we have INCOHERENT on Typeable (n:Nat) and Typeable (s:Symbol)
-because we also have an instance Typable (f a).  Now suppose we have
-  [Wanted] Typeable (a :: Nat)
-we should pick the (x::Nat) instance, even though the instance
-matching rules would worry that 'a' might later be instantiated to
-(f b), for some f and b. But we type theorists know that there are no
-type constructors f of kind blah -> Nat, so this can never happen and
-it's safe to pick the second instance. -}
-
-
-instance {-# INCOHERENT #-} KnownNat n => Typeable (n :: Nat) where
-  -- See Note [The apparent incoherence of Typable]
-  -- See #9203 for an explanation of why this is written as `\_ -> rep`.
-  typeRep# = \_ -> rep
+-- | An internal function, to make representations for type literals.
+typeLitTypeRep :: String -> TypeRep
+typeLitTypeRep nm = rep
     where
     rep = mkTyConApp tc []
     tc = TyCon
@@ -497,24 +345,6 @@ instance {-# INCOHERENT #-} KnownNat n => Typeable (n :: Nat) where
            }
     pack = "base"
     modu = "GHC.TypeLits"
-    nm   = show (natVal' (proxy# :: Proxy# n))
     mk a b c = a ++ " " ++ b ++ " " ++ c
 
 
-instance {-# INCOHERENT #-} KnownSymbol s => Typeable (s :: Symbol) where
-  -- See Note [The apparent incoherence of Typable]
-  -- See #9203 for an explanation of why this is written as `\_ -> rep`.
-  typeRep# = \_ -> rep
-    where
-    rep = mkTyConApp tc []
-    tc = TyCon
-           { tyConHash     = fingerprintString (mk pack modu nm)
-           , tyConPackage  = pack
-           , tyConModule   = modu
-           , tyConName     = nm
-           }
-    pack = "base"
-    modu = "GHC.TypeLits"
-    nm   = show (symbolVal' (proxy# :: Proxy# s))
-    mk a b c = a ++ " " ++ b ++ " " ++ c
-
index 8d90236..b56baed 100644 (file)
@@ -46,7 +46,7 @@ test('T8758', extra_clean(['T8758a.o', 'T8758a.hi']), multimod_compile, ['T8758a
 test('T8678', normal, compile, [''])
 test('T8865', normal, compile, [''])
 test('T8893', normal, compile, [''])
-test('T8950', expect_broken(8950), compile, [''])
+test('T8950', normal, compile, [''])
 test('T8963', normal, compile, [''])
 test('T7269', normal, compile, [''])
 test('T9069', normal, compile, [''])
diff --git a/testsuite/tests/deriving/should_fail/T2604.hs b/testsuite/tests/deriving/should_fail/T2604.hs
deleted file mode 100644 (file)
index 0f830d9..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-
-module Test where
-
-import Data.Typeable
-
-data DList a = DList [a] deriving(Typeable)
-
-newtype NList a = NList [a] deriving(Typeable)
diff --git a/testsuite/tests/deriving/should_fail/T2604.stderr b/testsuite/tests/deriving/should_fail/T2604.stderr
deleted file mode 100644 (file)
index 3000b50..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-
-T2604.hs:7:35:
-    Can't make a Typeable instance of ‘DList’
-      You need DeriveDataTypeable to derive Typeable instances
-    In the data declaration for ‘DList’
-
-T2604.hs:9:38:
-    Can't make a Typeable instance of ‘NList’
-      You need DeriveDataTypeable to derive Typeable instances
-    In the newtype declaration for ‘NList’
diff --git a/testsuite/tests/deriving/should_fail/T5863a.hs b/testsuite/tests/deriving/should_fail/T5863a.hs
deleted file mode 100644 (file)
index 3506dcc..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable, TypeFamilies #-}\r
-\r
-import Data.Typeable\r
-\r
-class C a where\r
-    data T a :: * \r
-\r
-instance C Int where\r
-    data T Int = A1 deriving (Typeable)\r
-\r
-instance C Bool where\r
-    data T Bool = A2 deriving (Typeable)\r
diff --git a/testsuite/tests/deriving/should_fail/T5863a.stderr b/testsuite/tests/deriving/should_fail/T5863a.stderr
deleted file mode 100644 (file)
index d64f1b2..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-
-T5863a.hs:9:31:
-    Deriving Typeable is not allowed for family instances;
-    derive Typeable for ‘T’ alone
-    In the data instance declaration for ‘T’
-
-T5863a.hs:12:32:
-    Deriving Typeable is not allowed for family instances;
-    derive Typeable for ‘T’ alone
-    In the data instance declaration for ‘T’
diff --git a/testsuite/tests/deriving/should_fail/T7800.hs b/testsuite/tests/deriving/should_fail/T7800.hs
deleted file mode 100644 (file)
index 9f190cf..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-{-# LANGUAGE StandaloneDeriving, DeriveDataTypeable #-}
-module T7800 where
-
-import T7800a
-import Data.Typeable
-
-deriving instance Typeable A
diff --git a/testsuite/tests/deriving/should_fail/T7800.stderr b/testsuite/tests/deriving/should_fail/T7800.stderr
deleted file mode 100644 (file)
index 8cd8533..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-[1 of 2] Compiling T7800a           ( T7800a.hs, T7800a.o )
-[2 of 2] Compiling T7800            ( T7800.hs, T7800.o )
-
-T7800.hs:7:1:
-    To make a Typeable instance of poly-kinded ‘A’, use XPolyKinds
-    In the stand-alone deriving instance for ‘Typeable A’
diff --git a/testsuite/tests/deriving/should_fail/T7800a.hs b/testsuite/tests/deriving/should_fail/T7800a.hs
deleted file mode 100644 (file)
index 22f1305..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-{-# LANGUAGE PolyKinds #-}
-module T7800a where
-
-data A a
\ No newline at end of file
index 10619a6..ad95393 100644 (file)
@@ -1,5 +1,3 @@
 
 T9687.hs:4:10:
-    Typeable instances can only be derived
-      Try ‘deriving instance Typeable (,,,,,,,)’
-      (requires StandaloneDeriving)
+    Class `Typeable` does not support user-specified instances.
index df7957d..60a4b7b 100644 (file)
@@ -17,7 +17,7 @@ test('drvfail016',
      run_command,
      ['$MAKE --no-print-directory -s drvfail016'])
 test('T2394', normal, compile_fail, [''])
-test('T2604', normal, compile_fail, [''])
+# T2604 was removed as it was out of date re: fixing #9858
 test('T2701', normal, compile_fail, [''])
 test('T2851', normal, compile_fail, [''])
 test('T2721', normal, compile_fail, [''])
@@ -38,14 +38,14 @@ test('T1133A',
      extra_clean(['T1133A.o-boot', 'T1133A.hi-boot']),
      run_command,
      ['$MAKE --no-print-directory -s T1133A'])
-test('T5863a', normal, compile_fail, [''])
+# 5863a was removed as it was out of date re: fixing #9858
 test('T7959', normal, compile_fail, [''])
 
 test('T1496', normal, compile_fail, [''])
 test('T4846', normal, compile_fail, [''])
 test('T7148', normal, compile_fail, [''])
 test('T7148a', normal, compile_fail, [''])
-test('T7800', normal, multimod_compile_fail, ['T7800',''])
+# T7800 was removed as it was out of date re: fixing #9858
 test('T5498', normal, compile_fail, [''])
 test('T6147', normal, compile_fail, [''])
 test('T8851', normal, compile_fail, [''])
index 139ce8d..0c92dba 100644 (file)
@@ -5,12 +5,8 @@
     Use :print or :force to determine these types
     Relevant bindings include it :: a1 (bound at <interactive>:11:1)
     Note: there are several potential instances:
-      instance forall (k :: BOX) (s :: k). Show (Proxy s)
-        -- Defined in ‘Data.Proxy’
-      instance forall (k :: BOX) (a :: k) (b :: k).
-               Show (Data.Type.Coercion.Coercion a b)
-        -- Defined in ‘Data.Type.Coercion’
-      instance forall (k :: BOX) (a :: k) (b :: k). Show (a :~: b)
-        -- Defined in ‘Data.Type.Equality’
-      ...plus 47 others
+      instance Show TyCon -- Defined in ‘Data.Typeable.Internal’
+      instance Show TypeRep -- Defined in ‘Data.Typeable.Internal’
+      instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
+      ...plus 30 others
     In a stmt of an interactive GHCi command: print it
index 6c567de..e4c4659 100644 (file)
@@ -1,5 +1,3 @@
 
 T8132.hs:6:10:
-    Typeable instances can only be derived
-      Try ‘deriving instance Typeable K’
-      (requires StandaloneDeriving)
+    Class `Typeable` does not support user-specified instances.
diff --git a/testsuite/tests/typecheck/should_compile/T9999.hs b/testsuite/tests/typecheck/should_compile/T9999.hs
deleted file mode 100644 (file)
index 656e913..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{-# LANGUAGE AutoDeriveTypeable, PolyKinds, TypeFamilies, StandaloneDeriving #-}
-
-module T9999 where
-
-import Data.Typeable
-
-data family F a
-
-class C a where
-  data F1 a
-  type F2 a
-
-main = typeRep (Proxy :: Proxy F) == typeRep (Proxy :: Proxy F1)
index 0b46cc6..87d217f 100644 (file)
@@ -438,6 +438,5 @@ test('T7643', normal, compile, [''])
 test('T9834', normal, compile, [''])
 test('T9892', normal, compile, [''])
 test('T9971', normal, compile, [''])
-test('T9999', normal, compile, [''])
 test('T10031', normal, compile, [''])
 test('T10072', normal, compile_fail, [''])
index f11ec28..8e37acf 100644 (file)
@@ -4,10 +4,10 @@ TcStaticPointersFail02.hs:9:6:
       arising from a static form
     In the expression: static (undefined :: (forall a. a -> a) -> b)
     In an equation for ‘f1’:
-       f1 = static (undefined :: (forall a. a -> a) -> b)
+        f1 = static (undefined :: (forall a. a -> a) -> b)
 
 TcStaticPointersFail02.hs:12:6:
-    No instance for (Data.Typeable.Internal.Typeable Monad)
+    No instance for (Data.Typeable.Internal.Typeable m)
       (maybe you haven't applied enough arguments to a function?)
       arising from a static form
     In the expression: static return
index 27dbef9..f5d4d0e 100644 (file)
@@ -353,3 +353,4 @@ test('T9497d', normal, compile_fail, ['-fdefer-type-errors -fno-defer-typed-hole
 test('T8044', normal, compile_fail, [''])
 test('T4921', normal, compile_fail, [''])
 test('T9605', normal, compile_fail, [''])
+test('T9999', normal, compile_fail, [''])