summaryrefslogtreecommitdiff
path: root/libraries/template-haskell
diff options
context:
space:
mode:
authorRyanGlScott <ryan.gl.scott@gmail.com>2015-12-22 11:25:59 +0100
committerBen Gamari <ben@smart-cactus.org>2015-12-22 13:22:29 +0100
commitf975b0b10b2971d00b6e1986e0a2af2bf759a4f4 (patch)
tree8b890f6e8058bb0a625a409de70f107101048d8d /libraries/template-haskell
parentb407bd775d9241023b4694b3142a756df0082ea2 (diff)
downloadhaskell-f975b0b10b2971d00b6e1986e0a2af2bf759a4f4.tar.gz
Rework Template Haskell's handling of strictness
Currently, Template Haskell's treatment of strictness is not enough to cover all possible combinations of unpackedness and strictness. In addition, it isn't equipped to deal with new features (such as `-XStrictData`) which can change a datatype's fields' strictness during compilation. To address this, I replaced TH's `Strict` datatype with `SourceUnpackedness` and `SourceStrictness` (which give the programmer a more complete toolkit to configure a datatype field's strictness than just `IsStrict`, `IsLazy`, and `Unpack`). I also added the ability to reify a constructor fields' strictness post-compilation through the `reifyConStrictness` function. Fixes #10697. Test Plan: ./validate Reviewers: simonpj, goldfire, bgamari, austin Reviewed By: goldfire, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1603 GHC Trac Issues: #10697
Diffstat (limited to 'libraries/template-haskell')
-rw-r--r--libraries/template-haskell/Language/Haskell/TH.hs16
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Lib.hs97
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Ppr.hs66
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Syntax.hs162
-rw-r--r--libraries/template-haskell/changelog.md12
5 files changed, 245 insertions, 108 deletions
diff --git a/libraries/template-haskell/Language/Haskell/TH.hs b/libraries/template-haskell/Language/Haskell/TH.hs
index 66d507cf9d..19882868b0 100644
--- a/libraries/template-haskell/Language/Haskell/TH.hs
+++ b/libraries/template-haskell/Language/Haskell/TH.hs
@@ -41,6 +41,8 @@ module Language.Haskell.TH(
reifyRoles,
-- *** Annotation lookup
reifyAnnotations, AnnLookup(..),
+ -- *** Constructor strictness lookup
+ reifyConStrictness,
-- * Typed expressions
TExp, unType,
@@ -66,7 +68,8 @@ module Language.Haskell.TH(
-- ** Declarations
Dec(..), Con(..), Clause(..),
- Strict(..), Foreign(..), Callconv(..), Safety(..), Pragma(..),
+ SourceUnpackedness(..), SourceStrictness(..), DecidedStrictness(..),
+ Bang(..), Strict, Foreign(..), Callconv(..), Safety(..), Pragma(..),
Inline(..), RuleMatch(..), Phases(..), RuleBndr(..), AnnTarget(..),
FunDep(..), FamFlavour(..), TySynEqn(..), TypeFamilyHead(..),
Fixity(..), FixityDirection(..), defaultFixity, maxPrecedence,
@@ -80,9 +83,10 @@ module Language.Haskell.TH(
-- * Library functions
-- ** Abbreviations
- InfoQ, ExpQ, DecQ, DecsQ, ConQ, TypeQ, TyLitQ, CxtQ, PredQ, MatchQ, ClauseQ,
- BodyQ, GuardQ, StmtQ, RangeQ, StrictTypeQ, VarStrictTypeQ, PatQ, FieldPatQ,
- RuleBndrQ, TySynEqnQ,
+ InfoQ, ExpQ, DecQ, DecsQ, ConQ, TypeQ, TyLitQ, CxtQ, PredQ, MatchQ,
+ ClauseQ, BodyQ, GuardQ, StmtQ, RangeQ, SourceStrictnessQ,
+ SourceUnpackednessQ, BangTypeQ, VarBangTypeQ, StrictTypeQ,
+ VarStrictTypeQ, PatQ, FieldPatQ, RuleBndrQ, TySynEqnQ,
-- ** Constructors lifted to 'Q'
-- *** Literals
@@ -119,7 +123,9 @@ module Language.Haskell.TH(
-- **** Type literals
numTyLit, strTyLit,
-- **** Strictness
- isStrict, notStrict, strictType, varStrictType,
+ noSourceUnpackedness, sourceNoUnpack, sourceUnpack,
+ noSourceStrictness, sourceLazy, sourceStrict,
+ bang, bangType, varBangType, strictType, varStrictType,
-- **** Class Contexts
cxt, classP, equalP,
-- **** Constructors
diff --git a/libraries/template-haskell/Language/Haskell/TH/Lib.hs b/libraries/template-haskell/Language/Haskell/TH/Lib.hs
index 737b9d42c7..ef928e8a36 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Lib.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Lib.hs
@@ -18,31 +18,38 @@ import Data.Word( Word8 )
-- * Type synonyms
----------------------------------------------------------
-type InfoQ = Q Info
-type PatQ = Q Pat
-type FieldPatQ = Q FieldPat
-type ExpQ = Q Exp
-type TExpQ a = Q (TExp a)
-type DecQ = Q Dec
-type DecsQ = Q [Dec]
-type ConQ = Q Con
-type TypeQ = Q Type
-type TyLitQ = Q TyLit
-type CxtQ = Q Cxt
-type PredQ = Q Pred
-type MatchQ = Q Match
-type ClauseQ = Q Clause
-type BodyQ = Q Body
-type GuardQ = Q Guard
-type StmtQ = Q Stmt
-type RangeQ = Q Range
-type StrictTypeQ = Q StrictType
-type VarStrictTypeQ = Q VarStrictType
-type FieldExpQ = Q FieldExp
-type RuleBndrQ = Q RuleBndr
-type TySynEqnQ = Q TySynEqn
-type Role = TH.Role -- must be defined here for DsMeta to find it
-type InjectivityAnn = TH.InjectivityAnn
+type InfoQ = Q Info
+type PatQ = Q Pat
+type FieldPatQ = Q FieldPat
+type ExpQ = Q Exp
+type TExpQ a = Q (TExp a)
+type DecQ = Q Dec
+type DecsQ = Q [Dec]
+type ConQ = Q Con
+type TypeQ = Q Type
+type TyLitQ = Q TyLit
+type CxtQ = Q Cxt
+type PredQ = Q Pred
+type MatchQ = Q Match
+type ClauseQ = Q Clause
+type BodyQ = Q Body
+type GuardQ = Q Guard
+type StmtQ = Q Stmt
+type RangeQ = Q Range
+type SourceStrictnessQ = Q SourceStrictness
+type SourceUnpackednessQ = Q SourceUnpackedness
+type BangQ = Q Bang
+type BangTypeQ = Q BangType
+type VarBangTypeQ = Q VarBangType
+type StrictTypeQ = Q StrictType
+type VarStrictTypeQ = Q VarStrictType
+type FieldExpQ = Q FieldExp
+type RuleBndrQ = Q RuleBndr
+type TySynEqnQ = Q TySynEqn
+
+-- must be defined here for DsMeta to find it
+type Role = TH.Role
+type InjectivityAnn = TH.InjectivityAnn
----------------------------------------------------------
-- * Lowercase pattern syntax functions
@@ -529,13 +536,13 @@ tySynEqn lhs rhs =
cxt :: [PredQ] -> CxtQ
cxt = sequence
-normalC :: Name -> [StrictTypeQ] -> ConQ
+normalC :: Name -> [BangTypeQ] -> ConQ
normalC con strtys = liftM (NormalC con) $ sequence strtys
-recC :: Name -> [VarStrictTypeQ] -> ConQ
+recC :: Name -> [VarBangTypeQ] -> ConQ
recC con varstrtys = liftM (RecC con) $ sequence varstrtys
-infixC :: Q (Strict, Type) -> Name -> Q (Strict, Type) -> ConQ
+infixC :: Q (Bang, Type) -> Name -> Q (Bang, Type) -> ConQ
infixC st1 con st2 = do st1' <- st1
st2' <- st2
return $ InfixC st1' con st2'
@@ -644,17 +651,37 @@ promotedNilT = return PromotedNilT
promotedConsT :: TypeQ
promotedConsT = return PromotedConsT
-isStrict, notStrict, unpacked :: Q Strict
-isStrict = return $ IsStrict
-notStrict = return $ NotStrict
-unpacked = return Unpacked
+noSourceUnpackedness, sourceNoUnpack, sourceUnpack :: SourceUnpackednessQ
+noSourceUnpackedness = return NoSourceUnpackedness
+sourceNoUnpack = return SourceNoUnpack
+sourceUnpack = return SourceUnpack
+noSourceStrictness, sourceLazy, sourceStrict :: SourceStrictnessQ
+noSourceStrictness = return NoSourceStrictness
+sourceLazy = return SourceLazy
+sourceStrict = return SourceStrict
+
+bang :: SourceUnpackednessQ -> SourceStrictnessQ -> BangQ
+bang u s = do u' <- u
+ s' <- s
+ return (Bang u' s')
+
+bangType :: BangQ -> TypeQ -> BangTypeQ
+bangType = liftM2 (,)
+
+varBangType :: Name -> BangTypeQ -> VarBangTypeQ
+varBangType v bt = do (b, t) <- bt
+ return (v, b, t)
+
+{-# DEPRECATED strictType
+ "As of @template-haskell-2.11.0.0@, 'StrictType' has been replaced by 'BangType'. Please use 'bangType' instead." #-}
strictType :: Q Strict -> TypeQ -> StrictTypeQ
-strictType = liftM2 (,)
+strictType = bangType
+{-# DEPRECATED varStrictType
+ "As of @template-haskell-2.11.0.0@, 'VarStrictType' has been replaced by 'VarBangType'. Please use 'varBangType' instead." #-}
varStrictType :: Name -> StrictTypeQ -> VarStrictTypeQ
-varStrictType v st = do (s, t) <- st
- return (v, s, t)
+varStrictType = varBangType
-- * Type Literals
diff --git a/libraries/template-haskell/Language/Haskell/TH/Ppr.hs b/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
index bf240f4ec5..d02ad0a30a 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Ppr.hs
@@ -497,14 +497,14 @@ instance Ppr Clause where
------------------------------
instance Ppr Con where
- ppr (NormalC c sts) = ppr c <+> sep (map pprStrictType sts)
+ ppr (NormalC c sts) = ppr c <+> sep (map pprBangType sts)
ppr (RecC c vsts)
- = ppr c <+> braces (sep (punctuate comma $ map pprVarStrictType vsts))
+ = ppr c <+> braces (sep (punctuate comma $ map pprVarBangType vsts))
- ppr (InfixC st1 c st2) = pprStrictType st1
+ ppr (InfixC st1 c st2) = pprBangType st1
<+> pprName' Infix c
- <+> pprStrictType st2
+ <+> pprBangType st2
ppr (ForallC ns ctxt (GadtC c sts ty idx))
= commaSep c <+> dcolon <+> pprForall ns ctxt <+> pprGadtRHS sts ty idx
@@ -529,27 +529,69 @@ pprForall ns ctxt
pprRecFields :: [(Name, Strict, Type)] -> Name -> [Type] -> Doc
pprRecFields vsts ty idx
- = braces (sep (punctuate comma $ map pprVarStrictType vsts))
+ = braces (sep (punctuate comma $ map pprVarBangType vsts))
<+> arrow <+> ppr ty <+> sep (map ppr idx)
pprGadtRHS :: [(Strict, Type)] -> Name -> [Type] -> Doc
pprGadtRHS [] ty idx
= ppr ty <+> sep (map ppr idx)
pprGadtRHS sts ty idx
- = sep (punctuate (space <> arrow) (map pprStrictType sts))
+ = sep (punctuate (space <> arrow) (map pprBangType sts))
<+> arrow <+> ppr ty <+> sep (map ppr idx)
------------------------------
-pprVarStrictType :: (Name, Strict, Type) -> Doc
+pprVarBangType :: VarBangType -> Doc
-- Slight infelicity: with print non-atomic type with parens
-pprVarStrictType (v, str, t) = ppr v <+> dcolon <+> pprStrictType (str, t)
+pprVarBangType (v, bang, t) = ppr v <+> dcolon <+> pprBangType (bang, t)
+
+------------------------------
+pprBangType :: BangType -> Doc
+-- Make sure we print
+--
+-- Con {-# UNPACK #-} a
+--
+-- rather than
+--
+-- Con {-# UNPACK #-}a
+--
+-- when there's no strictness annotation. If there is a strictness annotation,
+-- it's okay to not put a space between it and the type.
+pprBangType (bt@(Bang _ NoSourceStrictness), t) = ppr bt <+> pprParendType t
+pprBangType (bt, t) = ppr bt <> pprParendType t
+
+------------------------------
+instance Ppr Bang where
+ ppr (Bang su ss) = ppr su <+> ppr ss
+
+------------------------------
+instance Ppr SourceUnpackedness where
+ ppr NoSourceUnpackedness = empty
+ ppr SourceNoUnpack = text "{-# NOUNPACK #-}"
+ ppr SourceUnpack = text "{-# UNPACK #-}"
+
+------------------------------
+instance Ppr SourceStrictness where
+ ppr NoSourceStrictness = empty
+ ppr SourceLazy = char '~'
+ ppr SourceStrict = char '!'
+
+------------------------------
+instance Ppr DecidedStrictness where
+ ppr DecidedLazy = empty
+ ppr DecidedStrict = char '!'
+ ppr DecidedUnpack = text "{-# UNPACK #-} !"
+
+------------------------------
+{-# DEPRECATED pprVarStrictType
+ "As of @template-haskell-2.11.0.0@, 'VarStrictType' has been replaced by 'VarBangType'. Please use 'pprVarBangType' instead." #-}
+pprVarStrictType :: (Name, Strict, Type) -> Doc
+pprVarStrictType = pprVarBangType
------------------------------
+{-# DEPRECATED pprStrictType
+ "As of @template-haskell-2.11.0.0@, 'StrictType' has been replaced by 'BangType'. Please use 'pprBangType' instead." #-}
pprStrictType :: (Strict, Type) -> Doc
--- Prints with parens if not already atomic
-pprStrictType (IsStrict, t) = char '!' <> pprParendType t
-pprStrictType (NotStrict, t) = pprParendType t
-pprStrictType (Unpacked, t) = text "{-# UNPACK #-} !" <> pprParendType t
+pprStrictType = pprBangType
------------------------------
pprParendType :: Type -> Doc
diff --git a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
index b333b006b6..d10fb3c0a5 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
@@ -76,9 +76,10 @@ class (Applicative m, Monad m) => Quasi m where
-- Returns list of matching instance Decs
-- (with empty sub-Decs)
-- Works for classes and type functions
- qReifyRoles :: Name -> m [Role]
- qReifyAnnotations :: Data a => AnnLookup -> m [a]
- qReifyModule :: Module -> m ModuleInfo
+ qReifyRoles :: Name -> m [Role]
+ qReifyAnnotations :: Data a => AnnLookup -> m [a]
+ qReifyModule :: Module -> m ModuleInfo
+ qReifyConStrictness :: Name -> m [DecidedStrictness]
qLocation :: m Loc
@@ -117,22 +118,23 @@ instance Quasi IO where
qReport True msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
qReport False msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
- qLookupName _ _ = badIO "lookupName"
- qReify _ = badIO "reify"
- qReifyFixity _ = badIO "reifyFixity"
- qReifyInstances _ _ = badIO "reifyInstances"
- qReifyRoles _ = badIO "reifyRoles"
- qReifyAnnotations _ = badIO "reifyAnnotations"
- qReifyModule _ = badIO "reifyModule"
- qLocation = badIO "currentLocation"
- qRecover _ _ = badIO "recover" -- Maybe we could fix this?
- qAddDependentFile _ = badIO "addDependentFile"
- qAddTopDecls _ = badIO "addTopDecls"
- qAddModFinalizer _ = badIO "addModFinalizer"
- qGetQ = badIO "getQ"
- qPutQ _ = badIO "putQ"
- qIsExtEnabled _ = badIO "isExtEnabled"
- qExtsEnabled = badIO "extsEnabled"
+ qLookupName _ _ = badIO "lookupName"
+ qReify _ = badIO "reify"
+ qReifyFixity _ = badIO "reifyFixity"
+ qReifyInstances _ _ = badIO "reifyInstances"
+ qReifyRoles _ = badIO "reifyRoles"
+ qReifyAnnotations _ = badIO "reifyAnnotations"
+ qReifyModule _ = badIO "reifyModule"
+ qReifyConStrictness _ = badIO "reifyConStrictness"
+ qLocation = badIO "currentLocation"
+ qRecover _ _ = badIO "recover" -- Maybe we could fix this?
+ qAddDependentFile _ = badIO "addDependentFile"
+ qAddTopDecls _ = badIO "addTopDecls"
+ qAddModFinalizer _ = badIO "addModFinalizer"
+ qGetQ = badIO "getQ"
+ qPutQ _ = badIO "putQ"
+ qIsExtEnabled _ = badIO "isExtEnabled"
+ qExtsEnabled = badIO "extsEnabled"
qRunIO m = m
@@ -391,6 +393,21 @@ reifyAnnotations an = Q (qReifyAnnotations an)
reifyModule :: Module -> Q ModuleInfo
reifyModule m = Q (qReifyModule m)
+-- | @reifyConStrictness nm@ looks up the strictness information for the fields
+-- of the constructor with the name @nm@. Note that the strictness information
+-- that 'reifyConStrictness' returns may not correspond to what is written in
+-- the source code. For example, in the following data declaration:
+--
+-- @
+-- data Pair a = Pair a a
+-- @
+--
+-- 'reifyConStrictness' would return @['DecidedLazy', DecidedLazy]@ under most
+-- circumstances, but it would return @['DecidedStrict', DecidedStrict]@ if the
+-- @-XStrictData@ language extension was enabled.
+reifyConStrictness :: Name -> Q [DecidedStrictness]
+reifyConStrictness n = Q (qReifyConStrictness n)
+
-- | Is the list of instances returned by 'reifyInstances' nonempty?
isInstance :: Name -> [Type] -> Q Bool
isInstance nm tys = do { decs <- reifyInstances nm tys
@@ -451,25 +468,26 @@ extsEnabled :: Q [Extension]
extsEnabled = Q qExtsEnabled
instance Quasi Q where
- qNewName = newName
- qReport = report
- qRecover = recover
- qReify = reify
- qReifyFixity = reifyFixity
- qReifyInstances = reifyInstances
- qReifyRoles = reifyRoles
- qReifyAnnotations = reifyAnnotations
- qReifyModule = reifyModule
- qLookupName = lookupName
- qLocation = location
- qRunIO = runIO
- qAddDependentFile = addDependentFile
- qAddTopDecls = addTopDecls
- qAddModFinalizer = addModFinalizer
- qGetQ = getQ
- qPutQ = putQ
- qIsExtEnabled = isExtEnabled
- qExtsEnabled = extsEnabled
+ qNewName = newName
+ qReport = report
+ qRecover = recover
+ qReify = reify
+ qReifyFixity = reifyFixity
+ qReifyInstances = reifyInstances
+ qReifyRoles = reifyRoles
+ qReifyAnnotations = reifyAnnotations
+ qReifyModule = reifyModule
+ qReifyConStrictness = reifyConStrictness
+ qLookupName = lookupName
+ qLocation = location
+ qRunIO = runIO
+ qAddDependentFile = addDependentFile
+ qAddTopDecls = addTopDecls
+ qAddModFinalizer = addModFinalizer
+ qGetQ = getQ
+ qPutQ = putQ
+ qIsExtEnabled = isExtEnabled
+ qExtsEnabled = extsEnabled
----------------------------------------------------
@@ -1593,22 +1611,39 @@ type Cxt = [Pred] -- ^ @(Eq a, Ord b)@
-- be tuples of other constraints.
type Pred = Type
-data Strict = IsStrict | NotStrict | Unpacked
- deriving( Show, Eq, Ord, Data, Typeable, Generic )
-
-data Con = NormalC Name [StrictType] -- ^ @C Int a@
- | RecC Name [VarStrictType] -- ^ @C { v :: Int, w :: a }@
- | InfixC StrictType Name StrictType -- ^ @Int :+ a@
- | ForallC [TyVarBndr] Cxt Con -- ^ @forall a. Eq a => C [a]@
- | GadtC [Name] [StrictType]
- Name -- See Note [GADT return type]
- [Type] -- Indices of the type constructor
- -- ^ @C :: a -> b -> T b Int@
- | RecGadtC [Name] [VarStrictType]
- Name -- See Note [GADT return type]
- [Type] -- Indices of the type constructor
- -- ^ @C :: { v :: Int } -> T b Int@
- deriving( Show, Eq, Ord, Data, Typeable, Generic )
+data SourceUnpackedness
+ = NoSourceUnpackedness -- ^ @C a@
+ | SourceNoUnpack -- ^ @C { {\-\# NOUNPACK \#-\} } a@
+ | SourceUnpack -- ^ @C { {\-\# UNPACK \#-\} } a@
+ deriving (Show, Eq, Ord, Data, Typeable, Generic)
+
+data SourceStrictness = NoSourceStrictness -- ^ @C a@
+ | SourceLazy -- ^ @C {~}a@
+ | SourceStrict -- ^ @C {!}a@
+ deriving (Show, Eq, Ord, Data, Typeable, Generic)
+
+-- | Unlike 'SourceStrictness' and 'SourceUnpackedness', 'DecidedStrictness'
+-- refers to the strictness that the compiler chooses for a data constructor
+-- field, which may be different from what is written in source code. See
+-- 'reifyConStrictness' for more information.
+data DecidedStrictness = DecidedLazy
+ | DecidedStrict
+ | DecidedUnpack
+ deriving (Show, Eq, Ord, Data, Typeable, Generic)
+
+data Con = NormalC Name [BangType] -- ^ @C Int a@
+ | RecC Name [VarBangType] -- ^ @C { v :: Int, w :: a }@
+ | InfixC BangType Name BangType -- ^ @Int :+ a@
+ | ForallC [TyVarBndr] Cxt Con -- ^ @forall a. Eq a => C [a]@
+ | GadtC [Name] [BangType]
+ Name -- See Note [GADT return type]
+ [Type] -- Indices of the type constructor
+ -- ^ @C :: a -> b -> T b Int@
+ | RecGadtC [Name] [VarBangType]
+ Name -- See Note [GADT return type]
+ [Type] -- Indices of the type constructor
+ -- ^ @C :: { v :: Int } -> T b Int@
+ deriving (Show, Eq, Ord, Data, Typeable, Generic)
-- Note [GADT return type]
-- ~~~~~~~~~~~~~~~~~~~~~~~
@@ -1621,8 +1656,23 @@ data Con = NormalC Name [StrictType] -- ^ @C Int a@
-- data T a where
-- MkT :: S Int
-type StrictType = (Strict, Type)
-type VarStrictType = (Name, Strict, Type)
+data Bang = Bang SourceUnpackedness SourceStrictness
+ -- ^ @C { {\-\# UNPACK \#-\} !}a@
+ deriving (Show, Eq, Ord, Data, Typeable, Generic)
+
+type BangType = (Bang, Type)
+type VarBangType = (Name, Bang, Type)
+
+-- | As of @template-haskell-2.11.0.0@, 'Strict' has been replaced by 'Bang'.
+type Strict = Bang
+
+-- | As of @template-haskell-2.11.0.0@, 'StrictType' has been replaced by
+-- 'BangType'.
+type StrictType = BangType
+
+-- | As of @template-haskell-2.11.0.0@, 'VarStrictType' has been replaced by
+-- 'VarBangType'.
+type VarStrictType = VarBangType
data Type = ForallT [TyVarBndr] Cxt Type -- ^ @forall \<vars\>. \<ctxt\> -> \<type\>@
| AppT Type Type -- ^ @T a b@
diff --git a/libraries/template-haskell/changelog.md b/libraries/template-haskell/changelog.md
index 33419b34ec..9564e95678 100644
--- a/libraries/template-haskell/changelog.md
+++ b/libraries/template-haskell/changelog.md
@@ -25,6 +25,18 @@
* Add `TypeFamilyHead` for common elements of `OpenTypeFamilyD` and
`ClosedTypeFamilyD` (#10902)
+ * The `Strict` datatype was split among different datatypes: three for
+ writing the strictness information of data constructors' fields as denoted
+ in Haskell source code (`SourceUnpackedness` and `SourceStrictness`, as
+ well as `Bang`), and one for strictness information after a constructor is
+ compiled (`DecidedStrictness`). `Strict`, `StrictType` and `VarStrictType`
+ have been deprecated in favor of `Bang`, `BangType` and `VarBangType`, and
+ three functions (`isStrict`, `isLazy`, and `unpack`) were removed because
+ they no longer serve any use in this new design. (#10697)
+
+ * Add `reifyConStrictness` to query a data constructor's `DecidedStrictness`
+ values for its fields (#10697)
+
* TODO: document API changes and important bugfixes