diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+### 0.5.10 [2020.09.30]
+* Allow building with `template-haskell-2.17.0.0` (GHC 9.0).
+
 ### 0.5.9 [2019.06.08]
 * Have `deriveFunctor` and `deriveFoldable` derive implementations of `(<$)`
   and `null`, which GHC starting doing in 8.2 and 8.4, respectively.
diff --git a/deriving-compat.cabal b/deriving-compat.cabal
--- a/deriving-compat.cabal
+++ b/deriving-compat.cabal
@@ -1,5 +1,5 @@
 name:                deriving-compat
-version:             0.5.9
+version:             0.5.10
 synopsis:            Backports of GHC deriving extensions
 description:         Provides Template Haskell functions that mimic deriving
                      extensions that were introduced or modified in recent versions
@@ -122,7 +122,7 @@
   other-modules:       Paths_deriving_compat
   build-depends:       containers          >= 0.1   && < 0.7
                      , ghc-prim
-                     , th-abstraction      >= 0.3   && < 0.4
+                     , th-abstraction      >= 0.4   && < 0.5
 
   if flag(base-4-9)
     build-depends:     base                >= 4.9   && < 5
@@ -131,7 +131,7 @@
     build-depends:     base                >= 4.3   && < 4.9
 
   if flag(template-haskell-2-11)
-    build-depends:     template-haskell    >= 2.11  && < 2.17
+    build-depends:     template-haskell    >= 2.11  && < 2.18
                      , ghc-boot-th
   else
     build-depends:     template-haskell    >= 2.5   && < 2.11
@@ -170,7 +170,7 @@
                      , hspec               >= 1.8
                      , QuickCheck          >= 2      && < 3
                      , tagged              >= 0.7    && < 1
-                     , template-haskell    >= 2.5    && < 2.17
+                     , template-haskell    >= 2.5    && < 2.18
                      , void                >= 0.5.10 && < 1
   build-tool-depends:  hspec-discover:hspec-discover >= 1.8
 
@@ -190,3 +190,5 @@
   hs-source-dirs:      tests
   default-language:    Haskell2010
   ghc-options:         -Wall -threaded -rtsopts
+  if impl(ghc >= 8.6)
+    ghc-options:       -Wno-star-is-type
diff --git a/src/Data/Deriving/Internal.hs b/src/Data/Deriving/Internal.hs
--- a/src/Data/Deriving/Internal.hs
+++ b/src/Data/Deriving/Internal.hs
@@ -66,6 +66,7 @@
 #endif
 
 import           Language.Haskell.TH.Datatype
+import           Language.Haskell.TH.Datatype.TyVarBndr
 import           Language.Haskell.TH.Lib
 import           Language.Haskell.TH.Ppr (pprint)
 import           Language.Haskell.TH.Syntax
@@ -813,14 +814,12 @@
 newNameList prefix n = mapM (newName . (prefix ++) . show) [1..n]
 
 -- | Extracts the kind from a TyVarBndr.
-tvbKind :: TyVarBndr -> Kind
-tvbKind (PlainTV  _)   = starK
-tvbKind (KindedTV _ k) = k
+tvbKind :: TyVarBndr_ flag -> Kind
+tvbKind = elimTV (\_ -> starK) (\_ k -> k)
 
 -- | Convert a TyVarBndr to a Type.
-tvbToType :: TyVarBndr -> Type
-tvbToType (PlainTV n)    = VarT n
-tvbToType (KindedTV n k) = SigT (VarT n) k
+tvbToType :: TyVarBndr_ flag -> Type
+tvbToType = elimTV VarT (\n k -> SigT (VarT n) k)
 
 -- | Applies a typeclass constraint to a type.
 applyClass :: Name -> Name -> Pred
@@ -1045,7 +1044,7 @@
     let tvbs = avoidTypeInType $ freeVariablesWellScoped [ty']
     lam1E (conP iHashDataName [varP iHash]) $
         varE tagToEnumHashValName `appE` varE iHash
-            `sigE` return (ForallT tvbs [] ty')
+            `sigE` return (ForallT (changeTVFlags SpecifiedSpec tvbs) [] ty')
             -- tagToEnum# is a hack, and won't typecheck unless it's in the
             -- immediate presence of a type ascription like so:
             --
@@ -1072,16 +1071,16 @@
     -- a breaking change, so I decided against it at the time. If we ever make
     -- some breaking change in the future, however, this would be at the top
     -- of the list of things that I'd rip out.
-    avoidTypeInType :: [TyVarBndr] -> [TyVarBndr]
+    avoidTypeInType :: [TyVarBndrUnit] -> [TyVarBndrUnit]
 #if __GLASGOW_HASKELL__ >= 806
     avoidTypeInType = id
 #else
     avoidTypeInType = go . map attachFreeKindVars
       where
-        attachFreeKindVars :: TyVarBndr -> (TyVarBndr, [Name])
+        attachFreeKindVars :: TyVarBndrUnit -> (TyVarBndrUnit, [Name])
         attachFreeKindVars tvb = (tvb, freeVariables (tvKind tvb))
 
-        go :: [(TyVarBndr, [Name])] -> [TyVarBndr]
+        go :: [(TyVarBndrUnit, [Name])] -> [TyVarBndrUnit]
         go [] = []
         go ((tvb, _):tvbsAndFVs)
           | any (\(_, kindVars) -> tvName tvb `elem` kindVars) tvbsAndFVs
diff --git a/src/Data/Deriving/Via/Internal.hs b/src/Data/Deriving/Via/Internal.hs
--- a/src/Data/Deriving/Via/Internal.hs
+++ b/src/Data/Deriving/Via/Internal.hs
@@ -29,6 +29,7 @@
 
 import           Language.Haskell.TH
 import           Language.Haskell.TH.Datatype
+import           Language.Haskell.TH.Datatype.TyVarBndr
 
 -------------------------------------------------------------------------------
 -- Code generation
@@ -133,7 +134,7 @@
         _ -> fail $ "Not a type class: " ++ pprint clsTy
     _ -> fail $ "Malformed instance: " ++ pprint instanceTy
 
-deriveViaDecs' :: Name -> [TyVarBndr] -> [Type] -> Type -> Dec -> Q (Maybe [Dec])
+deriveViaDecs' :: Name -> [TyVarBndrUnit] -> [Type] -> Type -> Dec -> Q (Maybe [Dec])
 deriveViaDecs' clsName clsTvbs clsArgs repTy dec = do
     let numExpectedArgs = length clsTvbs
         numActualArgs   = length clsArgs
@@ -172,7 +173,7 @@
 
     go _ = return Nothing
 
-mkCoerceClassMethEqn :: [TyVarBndr] -> [Type] -> Type -> Type -> (Type, Type)
+mkCoerceClassMethEqn :: [TyVarBndrUnit] -> [Type] -> Type -> Type -> (Type, Type)
 mkCoerceClassMethEqn clsTvbs clsArgs repTy methTy
   = ( applySubstitution rhsSubst methTy
     , applySubstitution lhsSubst methTy
@@ -181,7 +182,7 @@
     lhsSubst = zipTvbSubst clsTvbs clsArgs
     rhsSubst = zipTvbSubst clsTvbs $ changeLast clsArgs repTy
 
-zipTvbSubst :: [TyVarBndr] -> [Type] -> Map Name Type
+zipTvbSubst :: [TyVarBndr_ flag] -> [Type] -> Map Name Type
 zipTvbSubst tvbs = M.fromList . zipWith (\tvb ty -> (tvName tvb, ty)) tvbs
 
 -- | Replace the last element of a list with another element.
@@ -199,7 +200,7 @@
 #endif
 stripOuterForallT ty               = ty
 
-decomposeType :: Type -> ([TyVarBndr], Cxt, Type)
+decomposeType :: Type -> ([TyVarBndrSpec], Cxt, Type)
 decomposeType (ForallT tvbs ctxt ty) = (tvbs, ctxt, ty)
 decomposeType ty                     = ([],   [],   ty)
 
diff --git a/src/Data/Functor/Deriving/Internal.hs b/src/Data/Functor/Deriving/Internal.hs
--- a/src/Data/Functor/Deriving/Internal.hs
+++ b/src/Data/Functor/Deriving/Internal.hs
@@ -61,6 +61,7 @@
 import           Data.Maybe
 
 import           Language.Haskell.TH.Datatype
+import           Language.Haskell.TH.Datatype.TyVarBndr
 import           Language.Haskell.TH.Lib
 import           Language.Haskell.TH.Syntax
 
@@ -727,7 +728,7 @@
           --   @arg_ty@ in @fun_ty arg_ty@.
         , ft_bad_app :: a
           -- ^ Type app, variable other than in last argument
-        , ft_forall  :: [TyVarBndr] -> a -> a
+        , ft_forall  :: [TyVarBndrSpec] -> a -> a
           -- ^ Forall type
      }
 
