diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Revision history for large-records
 
+## 0.3 -- 2022-07-22
+
+* Support ghc 9.2 (#117)
+* Support for field strictness annotations (#107)
+
 ## 0.2.1.0 -- 2022-04-06
 
 * Update for `large-generics` 0.2
diff --git a/large-records.cabal b/large-records.cabal
--- a/large-records.cabal
+++ b/large-records.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               large-records
-version:            0.2.1.0
+version:            0.3
 synopsis:           Efficient compilation for large records, linear in the size of the record
 description:        For many reasons, the internal code generated for modules
                     that contain records is quadratic in the number of record
@@ -16,7 +16,7 @@
 maintainer:         edsko@well-typed.com
 category:           Generics
 extra-source-files: CHANGELOG.md
-tested-with:        GHC ==8.8.4 || ==8.10.7 || ==9.0.2
+tested-with:        GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.2
 
 source-repository head
   type:     git
@@ -99,6 +99,7 @@
       Test.Record.Sanity.RDP.SplitModule.RecordDef
       Test.Record.Sanity.RecordConstruction
       Test.Record.Sanity.Strictness
+      Test.Record.Sanity.StrictnessStrictData
       Test.Record.Sanity.GhcGenerics
       Test.Record.Util
 
diff --git a/src/Data/Record/Internal/GHC/Shim.hs b/src/Data/Record/Internal/GHC/Shim.hs
--- a/src/Data/Record/Internal/GHC/Shim.hs
+++ b/src/Data/Record/Internal/GHC/Shim.hs
@@ -7,6 +7,7 @@
 {-# LANGUAGE RankNTypes             #-}
 {-# LANGUAGE TypeApplications       #-}
 {-# LANGUAGE UndecidableInstances   #-}
+{-# LANGUAGE ViewPatterns           #-}
 
 -- | Thin compatibility layer around GHC
 --
@@ -21,10 +22,17 @@
   , LHsModule
   , LRdrName
   , pattern GHC.HsModule
-  , putLogMsg
 
+    -- * Annotations
+#if __GLASGOW_HASKELL__ < 902
+  , reLoc
+  , reLocA
+  , noLocA
+#endif
+
     -- * Extensions
   , HasDefaultExt(..)
+  , withDefExt
 
     -- * Generalized @forall@
 #if __GLASGOW_HASKELL__ >= 900
@@ -39,7 +47,9 @@
 
     -- * New functionality
   , compareHs
-  , InheritLoc(..)
+  , inheritLoc
+  , inheritLoc'
+  , inheritLocPat
 
     -- * Re-exports
 
@@ -60,10 +70,13 @@
   , module GHC.Hs
   , module GHC.Plugins
   , module GHC.Tc.Types.Evidence
-  , module GHC.Types.Basic
   , module GHC.Types.Name.Cache
   , module GHC.Utils.Error
+#if __GLASGOW_HASKELL__ >= 902
+  , module GHC.Types.SourceText
+  , module GHC.Types.Fixity
 #endif
+#endif
   ) where
 
 import Data.List.NonEmpty (NonEmpty(..))
@@ -73,12 +86,12 @@
 
 #if __GLASGOW_HASKELL__ < 900
 
+import BasicTypes (SourceText (NoSourceText))
 import Bag (listToBag, emptyBag)
-import BasicTypes (SourceText(NoSourceText))
 import ConLike (ConLike)
 import ErrUtils (mkErrMsg, mkWarnMsg)
 import GHC hiding (AnnKeywordId(..), HsModule, exprType, typeKind, mkFunBind)
-import GhcPlugins hiding ((<>), getHscEnv, putLogMsg)
+import GhcPlugins hiding ((<>), getHscEnv,)
 import HscMain (getHscEnv)
 import NameCache (NameCache(nsUniqs))
 import PatSyn (PatSyn)
@@ -89,21 +102,33 @@
 
 #else
 
+import GHC.Hs hiding (LHsTyVarBndr, HsTyVarBndr, HsModule, mkFunBind)
+
 import GHC.Core.Class (Class)
 import GHC.Core.ConLike (ConLike)
 import GHC.Core.PatSyn (PatSyn)
 import GHC.Data.Bag (listToBag, emptyBag)
 import GHC.Driver.Main (getHscEnv)
-import GHC.Hs hiding (LHsTyVarBndr, HsTyVarBndr, HsModule, mkFunBind)
-import GHC.Parser.Annotation (IsUnicodeSyntax(NormalSyntax))
-import GHC.Plugins hiding ((<>), getHscEnv, putLogMsg)
 import GHC.Tc.Types.Evidence (HsWrapper(WpHole))
-import GHC.Types.Basic (SourceText(NoSourceText))
 import GHC.Types.Name.Cache (NameCache(nsUniqs))
-import GHC.Utils.Error (Severity(SevError, SevWarning), mkErrMsg, mkWarnMsg)
+import GHC.Utils.Error (Severity(SevError, SevWarning))
 
+import GHC.Plugins hiding ((<>), getHscEnv
+#if __GLASGOW_HASKELL__ >=902
+    , AnnType, AnnLet, AnnRec, AnnLam, AnnCase
+    , Exception
+#endif
+    )
+
+#if __GLASGOW_HASKELL__ < 902
+import GHC.Utils.Error (mkErrMsg, mkWarnMsg)
+import GHC.Parser.Annotation (IsUnicodeSyntax(NormalSyntax))
+#else
+import GHC.Types.SourceText (SourceText(NoSourceText), mkIntegralLit)
+import GHC.Types.Fixity
+#endif
+
 import qualified GHC.Hs      as GHC
-import qualified GHC.Plugins as GHC
 
 #endif
 
@@ -113,10 +138,10 @@
 
 -- | Optionally @qualified@ import declaration
 importDecl :: ModuleName -> Bool -> LImportDecl GhcPs
-importDecl name qualified = noLoc $ ImportDecl {
+importDecl name qualified = noLocA $ ImportDecl {
       ideclExt       = defExt
     , ideclSourceSrc = NoSourceText
-    , ideclName      = noLoc name
+    , ideclName      = noLocA name
     , ideclPkgQual   = Nothing
     , ideclSafe      = False
     , ideclImplicit  = False
@@ -138,14 +163,14 @@
 #if __GLASGOW_HASKELL__ < 900
 conPat x y = ConPatIn x y
 #else
-conPat x y = ConPat noExtField x y
+conPat x y = ConPat defExt (reLocA x) y
 #endif
 
 mkFunBind :: Located RdrName -> [LMatch GhcPs (LHsExpr GhcPs)] -> HsBind GhcPs
 #if __GLASGOW_HASKELL__ < 810
 mkFunBind = GHC.mkFunBind
 #else
-mkFunBind = GHC.mkFunBind Generated
+mkFunBind (reLocA -> n) = GHC.mkFunBind Generated n
 #endif
 
 #if __GLASGOW_HASKELL__ < 900
@@ -157,13 +182,25 @@
 type LHsModule = Located HsModule
 type LRdrName  = Located RdrName
 
-putLogMsg :: DynFlags -> WarnReason -> Severity -> SrcSpan -> SDoc -> IO ()
-#if __GLASGOW_HASKELL__ < 900
-putLogMsg flags reason sev srcspan =
-    GHC.putLogMsg flags reason sev srcspan (defaultErrStyle flags)
-#else
-putLogMsg = GHC.putLogMsg
+{-------------------------------------------------------------------------------
+  Exact-print annotations
+-------------------------------------------------------------------------------}
+
+#if __GLASGOW_HASKELL__ < 902
+reLoc :: Located a -> Located a
+reLoc = id
+
+reLocA :: Located a -> Located a
+reLocA = id
+
+noLocA :: e -> Located e
+noLocA = noLoc
+
+#if __GLASGOW_HASKELL__ >= 900
+mapXRec :: forall pass f g l. (f pass -> g pass) -> GenLocated l (f pass) -> GenLocated l (g pass)
+mapXRec = fmap
 #endif
+#endif
 
 {-------------------------------------------------------------------------------
   Extensions
@@ -185,6 +222,32 @@
   defExt = NoLayoutInfo
 #endif
 
+instance (HasDefaultExt a, HasDefaultExt b) => HasDefaultExt (a, b) where
+  defExt = (defExt, defExt)
+
+instance (HasDefaultExt a, HasDefaultExt b, HasDefaultExt c) => HasDefaultExt (a, b, c) where
+  defExt = (defExt, defExt, defExt)
+
+#if __GLASGOW_HASKELL__ >= 902
+instance HasDefaultExt (EpAnn ann) where
+  defExt = noAnn
+
+instance HasDefaultExt AnnSortKey where
+  defExt = NoAnnSortKey
+
+instance HasDefaultExt EpAnnComments where
+  defExt = epAnnComments noAnn
+#endif
+
+-- In GHC-9.2 some things have extension fields.
+#if __GLASGOW_HASKELL__ >= 902
+withDefExt :: HasDefaultExt a => (a -> b) -> b
+withDefExt f = f defExt 
+#else
+withDefExt :: a -> a
+withDefExt a = a
+#endif
+
 {-------------------------------------------------------------------------------
   Generalized @forall@ in 9.0
 -------------------------------------------------------------------------------}
@@ -202,24 +265,24 @@
 #endif
 
 userTyVar ::
-     XUserTyVar pass
-  -> Located (IdP pass)
-  -> HsTyVarBndr pass
+     XUserTyVar GhcPs
+  -> Located (IdP GhcPs)
+  -> HsTyVarBndr GhcPs
 #if __GLASGOW_HASKELL__ < 900
 userTyVar = UserTyVar
 #else
-userTyVar ext = UserTyVar ext ()
+userTyVar ext x = UserTyVar ext () (reLocA x)
 #endif
 
 kindedTyVar ::
-     XKindedTyVar pass
-  -> Located (IdP pass)
-  -> LHsKind pass
-  -> HsTyVarBndr pass
+     XKindedTyVar GhcPs
+  -> Located (IdP GhcPs)
+  -> LHsKind GhcPs
+  -> HsTyVarBndr GhcPs
 #if __GLASGOW_HASKELL__ < 900
 kindedTyVar = KindedTyVar
 #else
-kindedTyVar ext = KindedTyVar ext ()
+kindedTyVar ext k = KindedTyVar ext () (reLocA k)
 #endif
 
 -- | Like 'hsTyVarName', but don't throw away the location information
@@ -229,20 +292,22 @@
 hsTyVarLName (KindedTyVar _ n _) = n
 hsTyVarLName _ = panic "hsTyVarLName"
 #else
-hsTyVarLName (UserTyVar   _ _ n  ) = n
-hsTyVarLName (KindedTyVar _ _ n _) = n
+hsTyVarLName (UserTyVar   _ _ n  ) = reLoc n
+hsTyVarLName (KindedTyVar _ _ n _) = reLoc n
 #endif
 
 #if __GLASGOW_HASKELL__ < 900
 setDefaultSpecificity :: LHsTyVarBndr pass -> GHC.LHsTyVarBndr pass
 setDefaultSpecificity = id
 #else
-setDefaultSpecificity :: LHsTyVarBndr pass -> GHC.LHsTyVarBndr Specificity pass
-setDefaultSpecificity (L l v) = L l $ case v of
+setDefaultSpecificity :: LHsTyVarBndr GhcPs -> GHC.LHsTyVarBndr Specificity GhcPs
+setDefaultSpecificity = mapXRec @GhcPs $ \v -> case v of
     UserTyVar   ext () name      -> UserTyVar   ext SpecifiedSpec name
     KindedTyVar ext () name kind -> KindedTyVar ext SpecifiedSpec name kind
+#if __GLASGOW_HASKELL__ < 900
     XTyVarBndr  ext              -> XTyVarBndr  ext
 #endif
+#endif
 
 {-------------------------------------------------------------------------------
   New functionality
@@ -294,26 +359,57 @@
   Working with locations
 -------------------------------------------------------------------------------}
 
-class InheritLoc a b lb | lb -> b where
-  inheritLoc :: a -> b -> lb
+class FromSrcSpan l where
+  fromSrcSpan :: SrcSpan -> l
 
-instance InheritLoc (Located a) b (Located b) where
-  inheritLoc (L l _) = L l
+instance FromSrcSpan SrcSpan where
+  fromSrcSpan = id
 
-instance InheritLoc a b lb => InheritLoc (NonEmpty a) b lb where
+#if __GLASGOW_HASKELL__ >= 902
+instance HasDefaultExt ann => FromSrcSpan (SrcSpanAnn' ann) where
+  fromSrcSpan = SrcSpanAnn defExt
+#endif
+
+class InheritLoc a where
+  inheritLoc :: FromSrcSpan l => a -> b -> GenLocated l b
+
+#if __GLASGOW_HASKELL__ >= 902
+-- GHC-9.2 may not require annotation
+inheritLoc' :: a -> b -> b
+inheritLoc' _ = id
+#else
+inheritLoc' :: InheritLoc a => a -> b -> Located b
+inheritLoc' = inheritLoc
+#endif
+
+instance InheritLoc a => InheritLoc (NonEmpty a) where
   inheritLoc = inheritLoc . NE.head
 
--- | The instance for @[]@ is not ideal: we use 'noLoc' if the list is empty
+instance InheritLoc l => InheritLoc (GenLocated l a) where
+  inheritLoc (L l _) = inheritLoc l
+
+instance InheritLoc SrcSpan where
+  inheritLoc l x = L (fromSrcSpan l) x
+
+#if __GLASGOW_HASKELL__ >= 902
+instance InheritLoc (SrcSpanAnn' ann) where
+  inheritLoc (SrcSpanAnn _ l) = inheritLoc l
+#endif
+
 --
--- For the use cases in this library, this is acceptable: typically these are
--- lists with elements for the record fields, and having slightly poorer error
--- messages for highly unusual "empty large" records is fine.
-instance InheritLoc a b (Located b) => InheritLoc [a] b (Located b) where
-  inheritLoc (a:_) = inheritLoc a
-  inheritLoc []    = noLoc
+-- -- | The instance for @[]@ is not ideal: we use 'noLoc' if the list is empty
+-- --
+-- -- For the use cases in this library, this is acceptable: typically these are
+-- -- lists with elements for the record fields, and having slightly poorer error
+-- -- messages for highly unusual "empty large" records is fine.
+instance InheritLoc a => InheritLoc [a] where
+   inheritLoc (a:_) = inheritLoc a
+   inheritLoc []    = inheritLoc noSrcSpan
 
 #if __GLASGOW_HASKELL__ < 810
--- In 8.8, 'LPat' is a synonym for 'Pat'
-instance InheritLoc a (Pat p) (LPat p) where
-  inheritLoc _ = id
+inheritLocPat :: a -> Pat p -> LPat p
+inheritLocPat _ = id -- In 8.8, 'LPat' is a synonym for 'Pat'
+#else
+inheritLocPat :: InheritLoc a => a -> Pat (GhcPass p) -> LPat (GhcPass p)
+inheritLocPat = inheritLoc
 #endif
diff --git a/src/Data/Record/Internal/GHC/TemplateHaskellStyle.hs b/src/Data/Record/Internal/GHC/TemplateHaskellStyle.hs
--- a/src/Data/Record/Internal/GHC/TemplateHaskellStyle.hs
+++ b/src/Data/Record/Internal/GHC/TemplateHaskellStyle.hs
@@ -179,13 +179,13 @@
 -- | Equivalent of 'Language.Haskell.TH.Lib.varE'
 varE :: HasCallStack => LRdrName -> LHsExpr GhcPs
 varE name
-  | isTermVar name = inheritLoc name $ HsVar defExt name
+  | isTermVar name = inheritLoc name $ HsVar defExt (reLocA name)
   | otherwise      = error "varE: incorrect name type"
 
 -- | Inverse to 'varE'
 viewVarE :: LHsExpr GhcPs -> Maybe LRdrName
-viewVarE (L _ (HsVar _ name)) | isTermVar name = Just name
-viewVarE _                                     = Nothing
+viewVarE (reLoc -> L _ (HsVar _ (reLoc -> name))) | isTermVar name = Just name
+viewVarE _ = Nothing
 
 pattern VarE :: HasCallStack => () => LRdrName -> LHsExpr GhcPs
 pattern VarE name <- (viewVarE -> Just name)
@@ -195,12 +195,12 @@
 -- | Equivalent of 'Language.Haskell.TH.Lib.conE'
 conE :: HasCallStack => LRdrName -> LHsExpr GhcPs
 conE name
-  | isTermCon name = inheritLoc name $ HsVar defExt name
+  | isTermCon name = inheritLoc name $ HsVar defExt (reLocA name)
   | otherwise      = error "conE: incorrect name type"
 
 -- | Inverse to 'conE'
 viewConE :: LHsExpr GhcPs -> Maybe LRdrName
-viewConE (L _ (HsVar _ name)) | isTermCon name = Just name
+viewConE (reLoc -> L _ (HsVar _ (reLoc -> name))) | isTermCon name = Just name
 viewConE _ = Nothing
 
 pattern ConE :: HasCallStack => () => LRdrName -> LHsExpr GhcPs
@@ -210,7 +210,7 @@
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.litE'
 litE :: HsLit GhcPs -> LHsExpr GhcPs
-litE = noLoc . HsLit defExt
+litE = noLocA . HsLit defExt
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.stringE'
 stringE :: String -> LHsExpr GhcPs
@@ -222,11 +222,15 @@
   where
     mkRec :: LRdrName -> [LHsRecField GhcPs (LHsExpr GhcPs)] -> LHsExpr GhcPs
     mkRec name fields = inheritLoc name $
-        RecordCon defExt name (HsRecFields fields Nothing)
+        RecordCon defExt (reLocA name) (HsRecFields fields Nothing)
 
     mkFld :: LRdrName -> LHsExpr GhcPs -> LHsRecField GhcPs (LHsExpr GhcPs)
     mkFld name val = inheritLoc name $
-        HsRecField (inheritLoc name (mkFieldOcc name)) val False
+        HsRecField
+#if __GLASGOW_HASKELL__ >= 902
+          defExt
+#endif
+          (reLoc (inheritLoc name (mkFieldOcc (reLocA name)))) val False
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.recUpdE'
 recUpdE :: LHsExpr GhcPs -> [(LRdrName, LHsExpr GhcPs)] -> LHsExpr GhcPs
@@ -234,21 +238,33 @@
   where
     updRec :: LHsExpr GhcPs -> [LHsRecUpdField GhcPs] -> LHsExpr GhcPs
     updRec expr fields = inheritLoc expr $
-        RecordUpd defExt expr fields
+        RecordUpd defExt expr
+#if __GLASGOW_HASKELL__ >= 902
+          $ Left
+#endif
+            fields
 
     updFld :: LRdrName -> LHsExpr GhcPs -> LHsRecUpdField GhcPs
     updFld name val = inheritLoc name $
-        HsRecField (inheritLoc name (mkAmbiguousFieldOcc name)) val False
+        HsRecField
+#if __GLASGOW_HASKELL__ >= 902
+          defExt
+#endif
+         (reLoc (inheritLoc name (mkAmbiguousFieldOcc (reLocA name)))) val False
 
 viewRecUpdE ::
      LHsExpr GhcPs
   -> Maybe (LHsExpr GhcPs, [(LRdrName, LHsExpr GhcPs)])
+#if __GLASGOW_HASKELL__ >= 902
+viewRecUpdE (L _ (RecordUpd _ recExpr (Left fields))) =
+#else
 viewRecUpdE (L _ (RecordUpd _ recExpr fields)) =
+#endif
     (recExpr,) <$> mapM viewFieldUpd fields
   where
     viewFieldUpd :: LHsRecUpdField GhcPs -> Maybe (LRdrName, LHsExpr GhcPs)
-    viewFieldUpd (L _ (HsRecField (L _ (Unambiguous _ name)) val False)) =
-        Just (name, val)
+    viewFieldUpd (L _ (HsRecField { hsRecFieldLbl = L _ (Unambiguous _ name), hsRecFieldArg = val, hsRecPun = False })) =
+        Just (reLoc name, val)
     viewFieldUpd _otherwise =
         Nothing
 viewRecUpdE _otherwise = Nothing
@@ -264,7 +280,11 @@
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.listE'
 listE :: [LHsExpr GhcPs] -> LHsExpr GhcPs
-listE es = inheritLoc es $ ExplicitList defExt Nothing es
+listE es = inheritLoc es $ ExplicitList defExt
+#if __GLASGOW_HASKELL__ < 902
+    Nothing
+#endif
+    es
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.lamE'
 lamE :: NonEmpty (LPat GhcPs) -> LHsExpr GhcPs -> LHsExpr GhcPs
@@ -297,7 +317,7 @@
 tupE xs = inheritLoc xs $
     ExplicitTuple
       defExt
-      [inheritLoc xs (Present defExt x) | x <- NE.toList xs]
+      [inheritLoc' xs (Present defExt x) | x <- NE.toList xs]
       Boxed
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.sigE'
@@ -319,18 +339,18 @@
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.litT'
 litT :: HsTyLit -> LHsType GhcPs
-litT = noLoc . HsTyLit defExt
+litT = noLocA . HsTyLit defExt
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.varT'
 varT :: HasCallStack => LRdrName -> LHsType GhcPs
 varT name
-  | isTypeVar name = inheritLoc name (HsTyVar defExt NotPromoted name)
+  | isTypeVar name = inheritLoc name (HsTyVar defExt NotPromoted (reLocA name))
   | otherwise      = error "varT: incorrect name type"
 
 -- | Inverse to 'varT'
 viewVarT :: LHsType GhcPs -> Maybe LRdrName
-viewVarT (L _ (HsTyVar _ _ name)) | isTypeVar name = Just name
-viewVarT _otherwise                                = Nothing
+viewVarT (reLoc -> L _ (HsTyVar _ _ (reLoc -> name))) | isTypeVar name = Just name
+viewVarT _otherwise = Nothing
 
 pattern VarT :: HasCallStack => () => LRdrName -> LHsType GhcPs
 pattern VarT name <- (viewVarT -> Just name)
@@ -340,13 +360,13 @@
 -- | Equivalent of 'Language.Haskell.TH.Lib.conT'
 conT :: HasCallStack => LRdrName -> LHsType GhcPs
 conT name
-  | isTypeCon name = inheritLoc name (HsTyVar defExt NotPromoted name)
+  | isTypeCon name = inheritLoc name (HsTyVar defExt NotPromoted (reLocA name))
   | otherwise      = error "varT: incorrect name type"
 
 -- | Inverse to 'conT'
 viewConT :: LHsType GhcPs -> Maybe LRdrName
-viewConT (L _ (HsTyVar _ _ name)) | isTypeCon name = Just name
-viewConT _otherwise                                = Nothing
+viewConT (reLoc -> L _ (HsTyVar _ _ (reLoc -> name))) | isTypeCon name = Just name
+viewConT _otherwise = Nothing
 
 pattern ConT :: HasCallStack => () => LRdrName -> LHsType GhcPs
 pattern ConT name <- (viewConT -> Just name)
@@ -394,23 +414,27 @@
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.varP'
 varP :: LRdrName -> LPat GhcPs
-varP name = inheritLoc name (VarPat defExt name)
+varP name = inheritLocPat name (VarPat defExt (reLocA name))
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.conP'
 conP :: LRdrName -> [LPat GhcPs] -> LPat GhcPs
-conP con args = inheritLoc con (conPat con (PrefixCon args))
+#if __GLASGOW_HASKELL__ >= 902
+conP con args = inheritLocPat con (conPat con (PrefixCon [] args))
+#else
+conP con args = inheritLocPat con (conPat con (PrefixCon args))
+#endif
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.bangP'
 bangP :: LPat GhcPs -> LPat GhcPs
-bangP p = inheritLoc p $ BangPat defExt p
+bangP p = inheritLocPat p $ BangPat defExt p
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.listP'
 listP :: [LPat GhcPs] -> LPat GhcPs
-listP xs = inheritLoc xs $ ListPat defExt xs
+listP xs = inheritLocPat xs $ ListPat defExt xs
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.wildP'
 wildP :: LPat GhcPs
-wildP = noLoc (WildPat defExt)
+wildP = inheritLocPat noSrcSpan (WildPat defExt)
 
 {-------------------------------------------------------------------------------
   Strictness
@@ -448,12 +472,16 @@
     (L _
        ConDeclH98 {
            con_name   = conName
+#if __GLASGOW_HASKELL__ >= 902
+         , con_forall = False
+#else
          , con_forall = L _ False
+#endif
          , con_ex_tvs = []
          , con_mb_cxt = Nothing
          , con_args   = RecCon (L _ fields)
          }
-    ) = (conName,) <$> mapM viewRecField fields
+    ) = (reLoc conName ,) <$> mapM viewRecField fields
   where
     viewRecField :: LConDeclField GhcPs -> Maybe (LRdrName, LHsType GhcPs)
     viewRecField
@@ -466,7 +494,7 @@
     viewRecField _otherwise = Nothing
 
     viewFieldOcc :: FieldOcc GhcPs -> LRdrName
-    viewFieldOcc (FieldOcc _ name) = name
+    viewFieldOcc (FieldOcc _ (reLoc -> name)) = name
 #if __GLASGOW_HASKELL__ < 900
     viewFieldOcc _ = panic "viewFieldOcc"
 #endif
@@ -487,8 +515,8 @@
   -> LConDecl GhcPs
 forallRecC vars ctxt conName args = inheritLoc conName $ ConDeclH98 {
       con_ext    = defExt
-    , con_name   = conName
-    , con_forall = inheritLoc conName True
+    , con_name   = reLocA conName
+    , con_forall = inheritLoc' conName True
     , con_ex_tvs = map (setDefaultSpecificity . mkBndr) vars
     , con_mb_cxt = Just (inheritLoc conName ctxt)
     , con_args   = RecCon (inheritLoc conName $ map (uncurry mkRecField) args)
@@ -501,7 +529,7 @@
     mkRecField :: LRdrName -> LHsType GhcPs -> LConDeclField GhcPs
     mkRecField name ty = inheritLoc name $ ConDeclField {
           cd_fld_ext   = defExt
-        , cd_fld_names = [inheritLoc name $ mkFieldOcc name]
+        , cd_fld_names = [inheritLoc name $ mkFieldOcc $ reLocA name]
         , cd_fld_type  = ty
         , cd_fld_doc   = Nothing
         }
@@ -530,7 +558,7 @@
 sigD name ty = inheritLoc name $ SigD defExt sig
   where
     sig :: Sig GhcPs
-    sig = TypeSig defExt [name] $ HsWC defExt (implicitBndrs ty)
+    sig = TypeSig defExt [reLocA name] $ HsWC defExt (implicitBndrs ty)
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.valD'
 --
@@ -549,17 +577,21 @@
 dataD typeName tyVars cons derivs = inheritLoc typeName $
     TyClD defExt $ DataDecl {
         tcdDExt     = defExt
-      , tcdLName    = typeName
+      , tcdLName    = reLocA typeName
       , tcdTyVars   = mkHsQTvs tyVars
       , tcdFixity   = Prefix
       , tcdDataDefn = HsDataDefn {
             dd_ext     = defExt
           , dd_ND      = DataType
+#if __GLASGOW_HASKELL__ >= 902
+          , dd_ctxt    = Nothing
+#else
           , dd_ctxt    = inheritLoc typeName []
+#endif
           , dd_cType   = Nothing
           , dd_kindSig = Nothing
           , dd_cons    = cons
-          , dd_derivs  = inheritLoc typeName derivs
+          , dd_derivs  = inheritLoc' typeName derivs
           }
       }
 
@@ -582,15 +614,23 @@
            , tcdFixity   = Prefix
            , tcdDataDefn = HsDataDefn {
                    dd_ND      = DataType
+#if __GLASGOW_HASKELL__ >= 902
+                 , dd_ctxt    = Nothing
+#else
                  , dd_ctxt    = L _ []
+#endif
                  , dd_cType   = Nothing
                  , dd_kindSig = Nothing
                  , dd_cons    = cons
+#if __GLASGOW_HASKELL__ >= 902
+                 , dd_derivs  = derivs
+#else
                  , dd_derivs  = L _ derivs
+#endif
                  }
            }
        )
-    ) = Just (typeName, tyVars, cons, derivs)
+    ) = Just (reLoc typeName, tyVars, cons, derivs)
 viewDataD _otherwise = Nothing
 
 pattern DataD ::
@@ -610,15 +650,25 @@
   -> NonEmpty (LHsType GhcPs)
   -> LHsDerivingClause GhcPs
 derivClause strat tys = inheritLoc tys $
-    HsDerivingClause defExt strat $
-      inheritLoc tys $ map implicitBndrs (NE.toList tys)
+    HsDerivingClause defExt strat $ inheritLoc tys $
+#if __GLASGOW_HASKELL__ >= 902
+      DctMulti defExt $
+#endif
+      map implicitBndrs (NE.toList tys)
 
 -- | Inverse of 'derivClause'
 viewDerivClause ::
      LHsDerivingClause GhcPs
   -> (Maybe (LDerivStrategy GhcPs), [LHsType GhcPs])
+#if __GLASGOW_HASKELL__ >= 902
+viewDerivClause (L _ (HsDerivingClause _ mStrat (L _ (DctMulti _ tys)))) =
+    (mStrat, map viewImplicitBndrs tys)
+viewDerivClause (L _ (HsDerivingClause _ mStrat (L _ (DctSingle _ ty)))) =
+    (mStrat, map viewImplicitBndrs [ty])
+#else
 viewDerivClause (L _ (HsDerivingClause _ mStrat (L _ tys))) =
     (mStrat, map viewImplicitBndrs tys)
+#endif
 #if __GLASGOW_HASKELL__ < 900
 viewDerivClause _ = panic "viewDerivClause"
 #endif
@@ -654,8 +704,13 @@
   where
     qualT :: [LHsType GhcPs] -> LHsType GhcPs -> LHsType GhcPs
     qualT []        a = a
-    qualT ctx@(c:_) a = inheritLoc c $
-                          HsQualTy defExt (inheritLoc c ctx) a
+    qualT ctx@(c:_) a = inheritLoc c $ HsQualTy defExt
+#if __GLASGOW_HASKELL__ >= 902
+        (Just (inheritLoc c ctx))
+#else
+        (inheritLoc c ctx)
+#endif
+        a
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.classD'
 classD ::
@@ -667,8 +722,12 @@
 classD = \ctx name clsVars sigs -> inheritLoc name $
     TyClD defExt $ ClassDecl {
         tcdCExt   = defExt
+#if __GLASGOW_HASKELL__ >= 902
+      , tcdCtxt   = Just (inheritLoc name ctx)
+#else
       , tcdCtxt   = inheritLoc name ctx
-      , tcdLName  = name
+#endif
+      , tcdLName  = reLocA name
       , tcdTyVars = mkHsQTvs clsVars
       , tcdFixity = Prefix
       , tcdFDs    = []
@@ -681,7 +740,7 @@
   where
     classOpSig :: LRdrName -> LHsType GhcPs -> LSig GhcPs
     classOpSig name ty = inheritLoc name $
-        ClassOpSig defExt False [name] (implicitBndrs ty)
+        ClassOpSig defExt False [reLocA name] (implicitBndrs ty)
 
 -- | Approximate equivalent of 'Language.Haskell.TH.Lib.tySynEqn'
 tySynEqn ::
@@ -690,11 +749,19 @@
   -> LHsType GhcPs   -- ^ Equation RHS
   -> LTyFamInstDecl GhcPs
 tySynEqn name pats val = inheritLoc val $
-    TyFamInstDecl $
-      implicitBndrs $
+    TyFamInstDecl
+#if __GLASGOW_HASKELL__ >= 902
+      defExt $
+#else
+      $ implicitBndrs $
+#endif
         FamEqn defExt
-               name
+               (reLocA name)
+#if __GLASGOW_HASKELL__ >= 902
+               (HsOuterImplicit defExt)
+#else
                Nothing
+#endif
                (map HsValArg pats)
                Prefix
                val
@@ -706,22 +773,29 @@
   the @name@ type in @Located@.
 -------------------------------------------------------------------------------}
 
+type AnnProvenancePs = AnnProvenance
+#if __GLASGOW_HASKELL__ >= 902
+    GhcPs
+#else
+    RdrName
+#endif
+
 -- | Equivalent of 'Language.Haskell.TH.Lib.typeAnnotation'
-typeAnnotation :: LRdrName -> AnnProvenance RdrName
-typeAnnotation name = TypeAnnProvenance name
+typeAnnotation :: LRdrName -> AnnProvenancePs
+typeAnnotation name = TypeAnnProvenance (reLocA name)
 
 -- | Inverse to 'typeAnnotation'
-viewTypeAnnotation :: AnnProvenance RdrName -> Maybe LRdrName
-viewTypeAnnotation (TypeAnnProvenance name) = Just name
+viewTypeAnnotation :: AnnProvenancePs -> Maybe LRdrName
+viewTypeAnnotation (TypeAnnProvenance name) = Just (reLoc name)
 viewTypeAnnotation _otherwise               = Nothing
 
-pattern TypeAnnotation :: LRdrName -> AnnProvenance RdrName
+pattern TypeAnnotation :: LRdrName -> AnnProvenancePs
 pattern TypeAnnotation name <- (viewTypeAnnotation -> Just name)
   where
     TypeAnnotation = typeAnnotation
 
 -- | Equivalent of 'Language.Haskell.TH.Lib.pragAnnD'
-pragAnnD :: AnnProvenance RdrName -> LHsExpr GhcPs -> AnnDecl GhcPs
+pragAnnD :: AnnProvenancePs -> LHsExpr GhcPs -> AnnDecl GhcPs
 pragAnnD prov value =
     HsAnnotation
       defExt
@@ -729,13 +803,13 @@
       prov
       value
 
-viewPragAnnD :: AnnDecl GhcPs -> (AnnProvenance RdrName, LHsExpr GhcPs)
+viewPragAnnD :: AnnDecl GhcPs -> (AnnProvenancePs, LHsExpr GhcPs)
 viewPragAnnD (HsAnnotation _ _ prov value) = (prov, value)
 #if __GLASGOW_HASKELL__ < 900
 viewPragAnnD _ = panic "viewPragAnnD"
 #endif
 
-pattern PragAnnD :: AnnProvenance RdrName -> LHsExpr GhcPs -> AnnDecl GhcPs
+pattern PragAnnD :: AnnProvenancePs -> LHsExpr GhcPs -> AnnDecl GhcPs
 pattern PragAnnD prov value <- (viewPragAnnD -> (prov, value))
   where
     PragAnnD = pragAnnD
@@ -744,6 +818,14 @@
   Internal auxiliary
 -------------------------------------------------------------------------------}
 
+#if __GLASGOW_HASKELL__ >= 902
+implicitBndrs :: LHsType GhcPs -> LHsSigType GhcPs
+implicitBndrs t = inheritLoc t (HsSig defExt (HsOuterImplicit defExt) t)
+
+viewImplicitBndrs :: LHsSigType GhcPs -> LHsType GhcPs
+viewImplicitBndrs (L _ (HsSig _ _ ty)) = ty
+
+#else
 implicitBndrs :: a -> HsImplicitBndrs GhcPs a
 implicitBndrs a = HsIB defExt a
 
@@ -752,6 +834,7 @@
 #if __GLASGOW_HASKELL__ < 900
 viewImplicitBndrs _ = panic "viewImplicitBndrs"
 #endif
+#endif
 
 -- | Simple binding (without patterns)
 simpleBinding :: LRdrName -> LHsExpr GhcPs -> LHsBind GhcPs
@@ -764,7 +847,7 @@
     match :: LMatch GhcPs (LHsExpr GhcPs)
     match = inheritLoc fnName $
         Match defExt
-              (FunRhs fnName Prefix NoSrcStrict)
+              (FunRhs (reLocA fnName) Prefix NoSrcStrict)
               []
               grhs
 
@@ -773,6 +856,6 @@
 simpleGHRSs body =
     GRHSs defExt
           [inheritLoc body $ GRHS defExt [] body]
-          (inheritLoc body $ EmptyLocalBinds defExt)
+          (inheritLoc' body $ EmptyLocalBinds defExt)
 
 
diff --git a/src/Data/Record/Internal/Plugin/CodeGen.hs b/src/Data/Record/Internal/Plugin/CodeGen.hs
--- a/src/Data/Record/Internal/Plugin/CodeGen.hs
+++ b/src/Data/Record/Internal/Plugin/CodeGen.hs
@@ -8,12 +8,13 @@
 import Data.List (nubBy)
 import Data.List.NonEmpty (NonEmpty(..))
 
+import Language.Haskell.TH (Extension(StrictData))
+
 import qualified Data.Generics as SYB
 
 import Data.Record.Internal.GHC.Fresh
 import Data.Record.Internal.GHC.Shim hiding (mkTyVar)
 import Data.Record.Internal.GHC.TemplateHaskellStyle
-import Data.Record.Internal.Plugin.Options
 import Data.Record.Internal.Plugin.Record
 
 import qualified Data.Record.Internal.Plugin.Names.GhcGenerics as GHC
@@ -24,8 +25,8 @@
 -------------------------------------------------------------------------------}
 
 -- | Generate all large-records definitions for a record.
-genLargeRecord :: MonadFresh m => Record -> m [LHsDecl GhcPs]
-genLargeRecord r@Record{..} = concatM [
+genLargeRecord :: MonadFresh m => Record -> DynFlags -> m [LHsDecl GhcPs]
+genLargeRecord r@Record{..} dynFlags = concatM [
       (:[]) <$> genDatatype r
     , genVectorConversions  r
     , genIndexedAccessor    r
@@ -35,7 +36,7 @@
     , sequence [
           genConstraintsClass    r
         , genConstraintsInstance r
-        , genGenericInstance     r
+        , genGenericInstance     r dynFlags
         , genGHCGeneric          r
       ]
     ]
@@ -101,7 +102,7 @@
           (zipWith fieldExistentialType vars recordFields)
 
       ]
-      [ DerivClause (Just (noLoc AnyclassStrategy)) (c :| [])
+      [ DerivClause (Just (noLoc (withDefExt AnyclassStrategy))) (c :| [])
       | DeriveAnyClass c <- recordDerivings
       ]
   where
@@ -113,14 +114,14 @@
         | (i, _) <- zip [1 :: Int ..] recordFields
         ]
 
-    optionalBang :: LHsType GhcPs -> LHsType GhcPs
-    optionalBang = if allFieldsStrict recordOptions then bangType else id
+    optionalBang :: HsSrcBang -> LHsType GhcPs -> LHsType GhcPs
+    optionalBang bang = noLocA . HsBangTy defExt bang
 
     fieldContext :: LRdrName -> Field -> LHsType GhcPs
     fieldContext var fld = equalP (VarT var) (fieldType fld)
 
     fieldExistentialType :: LRdrName -> Field -> (LRdrName, LHsType GhcPs)
-    fieldExistentialType var fld = (fieldName fld, optionalBang $ VarT var)
+    fieldExistentialType var fld = (fieldName fld, optionalBang (fieldStrictness fld) $ VarT var)
 
 -- | Generate conversion to and from an array
 --
@@ -467,8 +468,8 @@
 -- >       , FieldMetadata (Proxy :: Proxy "tListB")) FieldLazy
 -- >       ]
 -- >   }
-genMetadata :: MonadFresh m => Record -> m (LHsExpr GhcPs)
-genMetadata r@Record{..} = do
+genMetadata :: MonadFresh m => Record -> DynFlags -> m (LHsExpr GhcPs)
+genMetadata r@Record{..} dynFlags = do
     p <- freshName $ mkExpVar recordAnnLoc "p"
     return $
       lamE1 (varP p) $
@@ -498,11 +499,26 @@
         appsE
           (ConE RT.con_FieldMetadata)
           [ proxyE (stringT (nameBase fieldName))
-          , ConE $ if allFieldsStrict recordOptions
-                     then RT.con_FieldStrict
-                     else RT.con_FieldLazy
+          , ConE $ case decideStrictness dynFlags fieldStrictness of
+              HsStrict                  -> RT.con_FieldStrict
+              HsLazy                    -> RT.con_FieldLazy
+              HsUnpack _                -> RT.con_FieldStrict
           ]
 
+-- | Implementation of https://hackage.haskell.org/package/base-4.16.1.0/docs/GHC-Generics.html#t:DecidedStrictness
+decideStrictness :: DynFlags -> HsSrcBang -> HsImplBang
+decideStrictness dynFlags (HsSrcBang _ unpackedness strictness) =
+  case (unpackedness, srcToImpl strictness) of
+    (SrcUnpack, HsStrict) | optimizations -> HsUnpack Nothing
+    (_, strictness') -> strictness'
+  where
+    strictData = xopt StrictData dynFlags
+    optimizations = optLevel dynFlags >= 1
+    srcToImpl = \case
+      SrcStrict -> HsStrict
+      SrcLazy -> HsLazy
+      NoSrcStrict -> if strictData then HsStrict else HsLazy
+
 -- | Generate definition for `from` in the `Generic` instance
 --
 -- Generates something like
@@ -545,9 +561,9 @@
 -- >   to       = ..
 -- >   dict     = dictConstraints_T
 -- >   metadata = ..
-genGenericInstance :: MonadFresh m => Record -> m (LHsDecl GhcPs)
-genGenericInstance r@Record{..} = do
-    metadata <- genMetadata r
+genGenericInstance :: MonadFresh m => Record -> DynFlags -> m (LHsDecl GhcPs)
+genGenericInstance r@Record{..} dynFlags  = do
+    metadata <- genMetadata r dynFlags
     from     <- genFrom     r
     to       <- genTo       r
     return $
diff --git a/src/Data/Record/Internal/Plugin/Exception.hs b/src/Data/Record/Internal/Plugin/Exception.hs
--- a/src/Data/Record/Internal/Plugin/Exception.hs
+++ b/src/Data/Record/Internal/Plugin/Exception.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ViewPatterns      #-}
 
 -- | Exceptions that may be thrown by the large-records plugin.
 module Data.Record.Internal.Plugin.Exception (
@@ -17,9 +18,9 @@
 
 exceptionLoc :: Exception -> SrcSpan
 exceptionLoc = \case
-    UnsupportedStockDeriving (L l _) -> l
-    UnsupportedStrategy      (L l _) -> l
-    InvalidDeclaration       (L l _) -> l
+    UnsupportedStockDeriving (reLoc -> L l _) -> l
+    UnsupportedStrategy      (id    -> L l _) -> l
+    InvalidDeclaration       (reLoc -> L l _) -> l
 
 exceptionToSDoc :: Exception -> SDoc
 exceptionToSDoc = hsep . \case
diff --git a/src/Data/Record/Internal/Plugin/Options.hs b/src/Data/Record/Internal/Plugin/Options.hs
--- a/src/Data/Record/Internal/Plugin/Options.hs
+++ b/src/Data/Record/Internal/Plugin/Options.hs
@@ -7,8 +7,7 @@
 module Data.Record.Internal.Plugin.Options (
     -- * Definition
     LargeRecordOptions(..)
-  , largeRecordStrict
-  , largeRecordLazy
+  , largeRecord
     -- * Extract options from source module
   , getLargeRecordOptions
   ) where
@@ -32,34 +31,21 @@
 --
 -- The default for Haskell code should probably be:
 --
--- > {-# ANN type T largeRecordLazy #-}
--- > data T = ..
---
--- For records with strict fields, you can use:
---
--- > {-# ANN type T largeRecordStrict #-}
+-- > {-# ANN type T largeRecord #-}
 -- > data T = ..
 --
 -- To see the definitions generated by @large-records@:
 --
--- > {-# ANN type T largeRecordLazy {debugLargeRecords = True} #-}
+-- > {-# ANN type T largeRecord {debugLargeRecords = True} #-}
 -- > data T = ..
 data LargeRecordOptions = LargeRecordOptions {
-      allFieldsStrict   :: Bool
-    , debugLargeRecords :: Bool
+      debugLargeRecords :: Bool
     }
   deriving stock (Data)
 
-largeRecordStrict :: LargeRecordOptions
-largeRecordStrict = LargeRecordOptions {
-      allFieldsStrict   = True
-    , debugLargeRecords = False
-    }
-
-largeRecordLazy :: LargeRecordOptions
-largeRecordLazy = LargeRecordOptions {
-      allFieldsStrict   = False
-    , debugLargeRecords = False
+largeRecord :: LargeRecordOptions
+largeRecord = LargeRecordOptions {
+      debugLargeRecords = False
     }
 
 {-------------------------------------------------------------------------------
@@ -94,10 +80,8 @@
 -------------------------------------------------------------------------------}
 
 intOptions :: LHsExpr GhcPs -> Maybe LargeRecordOptions
-intOptions (VarE (nameBase -> "largeRecordStrict")) =
-    Just largeRecordStrict
-intOptions (VarE (nameBase -> "largeRecordLazy")) =
-    Just largeRecordLazy
+intOptions (VarE (nameBase -> "largeRecord")) =
+    Just largeRecord
 intOptions (RecUpdE expr fields) = do
     opts    <- intOptions expr
     updates <- mapM intUpdate fields
diff --git a/src/Data/Record/Internal/Plugin/Record.hs b/src/Data/Record/Internal/Plugin/Record.hs
--- a/src/Data/Record/Internal/Plugin/Record.hs
+++ b/src/Data/Record/Internal/Plugin/Record.hs
@@ -43,9 +43,10 @@
     }
 
 data Field = Field {
-      fieldName  :: LRdrName
-    , fieldType  :: LHsType GhcPs
-    , fieldIndex :: Int
+      fieldName       :: LRdrName
+    , fieldType       :: LHsType GhcPs
+    , fieldStrictness :: HsSrcBang
+    , fieldIndex      :: Int
     }
 
 -- | Derived classes that we can support.
@@ -97,8 +98,9 @@
 
 viewField ::
      MonadError Exception m
-  => (LRdrName, LHsType GhcPs) -> m (Int -> Field)
-viewField (name, typ) = return $ Field name typ
+  => (LRdrName, LHsType GhcPs) -> m (Int -> Field)  
+viewField (name, typ) =
+  return $ Field name (getBangType typ) (getBangStrictness typ)
 
 viewRecordDerivings ::
      MonadError Exception m
@@ -111,9 +113,9 @@
 viewRecordDeriving = \case
     DerivClause Nothing tys ->
       goStock tys
-    DerivClause (Just (L _ StockStrategy)) tys ->
+    DerivClause (Just (L _ StockStrategy {})) tys ->
       goStock tys
-    DerivClause (Just (L _ AnyclassStrategy)) tys ->
+    DerivClause (Just (L _ AnyclassStrategy {})) tys ->
       pure $ fmap DeriveAnyClass (NE.toList tys)
     DerivClause (Just strategy) _ ->
       throwError (UnsupportedStrategy strategy)
diff --git a/src/Data/Record/Plugin.hs b/src/Data/Record/Plugin.hs
--- a/src/Data/Record/Plugin.hs
+++ b/src/Data/Record/Plugin.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP            #-}
 {-# LANGUAGE NamedFieldPuns #-}
 {-# LANGUAGE ViewPatterns   #-}
 
@@ -7,7 +8,7 @@
 --
 -- > {-# OPTIONS_GHC -fplugin=Data.Record.Plugin #-}
 -- >
--- > {-# ANN type B LargeRecordStrict #-}
+-- > {-# ANN type B largeRecord #-}
 -- > data B a = B {a :: a, b :: String}
 -- >   deriving stock (Show, Eq, Ord)
 --
@@ -43,6 +44,12 @@
 import Data.Record.Internal.Plugin.Options
 import Data.Record.Internal.Plugin.Record
 
+#if __GLASGOW_HASKELL__ >= 902
+import GHC.Driver.Errors
+import GHC.Types.Error (mkWarnMsg, mkErr, mkDecorated)
+import GHC.Utils.Logger (getLogger)
+#endif
+
 {-------------------------------------------------------------------------------
   Top-level: the plugin proper
 -------------------------------------------------------------------------------}
@@ -103,7 +110,7 @@
      Map String [(SrcSpan, LargeRecordOptions)]
   -> LHsDecl GhcPs
   -> WriterT (Set String) Hsc [LHsDecl GhcPs]
-transformDecl largeRecords decl@(L l _) =
+transformDecl largeRecords decl@(reLoc -> L l _) =
     case decl of
       DataD (nameBase -> name) _ _ _  ->
         case Map.findWithDefault [] name largeRecords of
@@ -121,7 +128,8 @@
                 -- Return the declaration unchanged if we cannot parse it
                 return [decl]
               Right r -> do
-                newDecls <- lift $ runFreshHsc $ genLargeRecord r
+                dynFlags <- lift getDynFlags
+                newDecls <- lift $ runFreshHsc $ genLargeRecord r dynFlags
                 when (debugLargeRecords opts) $
                   lift $ issueWarning l (debugMsg newDecls)
                 pure newDecls
@@ -185,12 +193,23 @@
 
 issueError :: SrcSpan -> SDoc -> Hsc ()
 issueError l errMsg = do
+#if __GLASGOW_HASKELL__ >= 902
+    throwOneError $
+      mkErr l neverQualify (mkDecorated [errMsg])
+#else
     dynFlags <- getDynFlags
     throwOneError $
       mkErrMsg dynFlags l neverQualify errMsg
+#endif
 
 issueWarning :: SrcSpan -> SDoc -> Hsc ()
 issueWarning l errMsg = do
     dynFlags <- getDynFlags
+#if __GLASGOW_HASKELL__ >= 902
+    logger <- getLogger
+    liftIO $ printOrThrowWarnings logger dynFlags . listToBag . (:[]) $
+      mkWarnMsg l neverQualify errMsg
+#else
     liftIO $ printOrThrowWarnings dynFlags . listToBag . (:[]) $
       mkWarnMsg dynFlags l neverQualify errMsg
+#endif
diff --git a/src/Data/Record/Plugin/Options.hs b/src/Data/Record/Plugin/Options.hs
--- a/src/Data/Record/Plugin/Options.hs
+++ b/src/Data/Record/Plugin/Options.hs
@@ -3,8 +3,7 @@
 -- This module is added as an export to user code by the plugin.
 module Data.Record.Plugin.Options (
     LargeRecordOptions(..)
-  , largeRecordStrict
-  , largeRecordLazy
+  , largeRecord
   ) where
 
 import Data.Record.Internal.Plugin.Options
diff --git a/test/Test/Record/Sanity/CodeGen.hs b/test/Test/Record/Sanity/CodeGen.hs
--- a/test/Test/Record/Sanity/CodeGen.hs
+++ b/test/Test/Record/Sanity/CodeGen.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE ConstraintKinds           #-}
 {-# LANGUAGE DataKinds                 #-}
 {-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleContexts          #-}
 {-# LANGUAGE FlexibleInstances         #-}
 {-# LANGUAGE MultiParamTypeClasses     #-}
 {-# LANGUAGE RecordWildCards           #-}
@@ -24,7 +25,7 @@
   This is the example record we use throughout the comments in TH codegen.
 -------------------------------------------------------------------------------}
 
-{-# ANN type T largeRecordStrict #-}
+{-# ANN type T largeRecord #-}
 data T a b = MkT {
       tInt   :: Word
     , tBool  :: Bool
diff --git a/test/Test/Record/Sanity/Derive.hs b/test/Test/Record/Sanity/Derive.hs
--- a/test/Test/Record/Sanity/Derive.hs
+++ b/test/Test/Record/Sanity/Derive.hs
@@ -33,7 +33,7 @@
 
 -- Type of kind @Type@
 
-{-# ANN type LA1 largeRecordStrict #-}
+{-# ANN type LA1 largeRecord #-}
 data LA1 = MkLA1 { la1_f1 :: Int }
   deriving anyclass C1
 
@@ -42,7 +42,7 @@
 data RA2 a = MkRA1 { ra2_f1 :: a }
   deriving anyclass C1
 
-{-# ANN type LA2 largeRecordStrict #-}
+{-# ANN type LA2 largeRecord #-}
 data LA2 a = MkLA2 { la2_f1 :: a }
   deriving anyclass C1
 
@@ -59,7 +59,7 @@
   really is a newtype around a record).
 -------------------------------------------------------------------------------}
 
-{-# ANN type LB largeRecordStrict #-}
+{-# ANN type LB largeRecord #-}
 data LB = MkLB { lb1 :: Int, lb2 :: Int }
     deriving anyclass (Newtype LB)
 
@@ -80,7 +80,7 @@
 data RC a = MkRC { rc1 :: a, rc2 :: Int }
   deriving anyclass C3
 
-{-# ANN type LC largeRecordStrict #-}
+{-# ANN type LC largeRecord #-}
 data LC (a :: Type) = MkLC { lc1 :: a, lc2 :: Int }
   deriving anyclass C3
 
@@ -96,7 +96,7 @@
 data RD f = MkRD { rd1 :: f Int, rd2 :: Int }
   deriving anyclass C4
 
-{-# ANN type LD largeRecordStrict #-}
+{-# ANN type LD largeRecord #-}
 data LD (f :: Type -> Type) = MkLD { ld1 :: f Int, ld2 :: Int }
   deriving anyclass C4
 
@@ -113,7 +113,7 @@
   deriving stock Show
   deriving anyclass C5
 
-{-# ANN type LE largeRecordStrict #-}
+{-# ANN type LE largeRecord #-}
 data LE = MkLE { le1 :: Int, le2 :: Bool }
   deriving stock Show
   deriving anyclass C5
diff --git a/test/Test/Record/Sanity/EqualFieldTypes.hs b/test/Test/Record/Sanity/EqualFieldTypes.hs
--- a/test/Test/Record/Sanity/EqualFieldTypes.hs
+++ b/test/Test/Record/Sanity/EqualFieldTypes.hs
@@ -20,7 +20,7 @@
 import Test.Tasty
 import Test.Tasty.HUnit
 
-{-# ANN type R largeRecordStrict #-}
+{-# ANN type R largeRecord #-}
 data R a = MkR {
       field1 :: a
     , field2 :: a
diff --git a/test/Test/Record/Sanity/GhcGenerics.hs b/test/Test/Record/Sanity/GhcGenerics.hs
--- a/test/Test/Record/Sanity/GhcGenerics.hs
+++ b/test/Test/Record/Sanity/GhcGenerics.hs
@@ -21,7 +21,7 @@
 import Test.Tasty
 import Test.Tasty.HUnit
 
-{-# ANN type R largeRecordStrict #-}
+{-# ANN type R largeRecord #-}
 data R = MkR { a :: Int }
   deriving (Show)
 
diff --git a/test/Test/Record/Sanity/HKD.hs b/test/Test/Record/Sanity/HKD.hs
--- a/test/Test/Record/Sanity/HKD.hs
+++ b/test/Test/Record/Sanity/HKD.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE ConstraintKinds           #-}
 {-# LANGUAGE DataKinds                 #-}
 {-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleContexts          #-}
 {-# LANGUAGE FlexibleInstances         #-}
 {-# LANGUAGE KindSignatures            #-}
 {-# LANGUAGE MultiParamTypeClasses     #-}
@@ -29,7 +30,7 @@
   HKD (Const b) a = b
 
 -- | Test record with fields whose types are given by type families
-{-# ANN type T largeRecordStrict #-}
+{-# ANN type T largeRecord #-}
 data T (f :: Type -> Type) = MkT {
       field1 :: HKD f Int
     , field2 :: HKD f Bool
diff --git a/test/Test/Record/Sanity/HigherKinded.hs b/test/Test/Record/Sanity/HigherKinded.hs
--- a/test/Test/Record/Sanity/HigherKinded.hs
+++ b/test/Test/Record/Sanity/HigherKinded.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE ConstraintKinds           #-}
 {-# LANGUAGE DataKinds                 #-}
 {-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleContexts          #-}
 {-# LANGUAGE FlexibleInstances         #-}
 {-# LANGUAGE KindSignatures            #-}
 {-# LANGUAGE MultiParamTypeClasses     #-}
@@ -35,7 +36,7 @@
 
 -- We need an explicit kind annotation on @f@ for @large-records@ to generate
 -- correct code (either that, or use @PolyKinds@).
-{-# ANN type MyRecord largeRecordStrict #-}
+{-# ANN type MyRecord largeRecord #-}
 data MyRecord (f :: Type -> Type) = MyRecord {
       field0 :: T 0 f
     , field1 :: T 1 f
diff --git a/test/Test/Record/Sanity/OverloadingNoDRF.hs b/test/Test/Record/Sanity/OverloadingNoDRF.hs
--- a/test/Test/Record/Sanity/OverloadingNoDRF.hs
+++ b/test/Test/Record/Sanity/OverloadingNoDRF.hs
@@ -29,10 +29,10 @@
   through DRF.
 --------------------------------------s-----------------------------------------}
 
-{-# ANN type X largeRecordStrict #-}
+{-# ANN type X largeRecord #-}
 data X = MkX { a :: Int }
 
-{-# ANN type Y largeRecordStrict #-}
+{-# ANN type Y largeRecord #-}
 data Y = MkY { a :: String }
 
 testOverloading :: Assertion
diff --git a/test/Test/Record/Sanity/PatternMatch.hs b/test/Test/Record/Sanity/PatternMatch.hs
--- a/test/Test/Record/Sanity/PatternMatch.hs
+++ b/test/Test/Record/Sanity/PatternMatch.hs
@@ -28,10 +28,10 @@
   Basic pattern matching tests
 -------------------------------------------------------------------------------}
 
-{-# ANN type T largeRecordStrict #-}
+{-# ANN type T largeRecord #-}
 data T a = MkT { x :: Int,  y :: [a], z :: Double }
 
-{-# ANN type S largeRecordStrict #-}
+{-# ANN type S largeRecord #-}
 data S a = MkS { x :: Char, y :: T a }
 
 projectOne :: T Bool -> Int
@@ -75,7 +75,7 @@
   type errors iff 'noSigEmpty' and 'noSigNonEmpty' are suffciently monomorphic.
 -------------------------------------------------------------------------------}
 
-{-# ANN type T2 largeRecordStrict #-}
+{-# ANN type T2 largeRecord #-}
 data T2 = MkT2 { x :: Int }
 
 noSigEmpty MkT {} = ()
diff --git a/test/Test/Record/Sanity/QualifiedImports/A.hs b/test/Test/Record/Sanity/QualifiedImports/A.hs
--- a/test/Test/Record/Sanity/QualifiedImports/A.hs
+++ b/test/Test/Record/Sanity/QualifiedImports/A.hs
@@ -11,5 +11,5 @@
 
 module Test.Record.Sanity.QualifiedImports.A (T(..)) where
 
-{-# ANN type T largeRecordStrict #-}
+{-# ANN type T largeRecord #-}
 data T a = MkT { x :: Int, y :: [a] }
diff --git a/test/Test/Record/Sanity/QualifiedImports/B.hs b/test/Test/Record/Sanity/QualifiedImports/B.hs
--- a/test/Test/Record/Sanity/QualifiedImports/B.hs
+++ b/test/Test/Record/Sanity/QualifiedImports/B.hs
@@ -14,5 +14,5 @@
 
 import qualified Test.Record.Sanity.QualifiedImports.A as A
 
-{-# ANN type T largeRecordStrict #-}
+{-# ANN type T largeRecord #-}
 data T a = MkT { x :: Char, y :: A.T a }
diff --git a/test/Test/Record/Sanity/RDP/SingleModule.hs b/test/Test/Record/Sanity/RDP/SingleModule.hs
--- a/test/Test/Record/Sanity/RDP/SingleModule.hs
+++ b/test/Test/Record/Sanity/RDP/SingleModule.hs
@@ -22,7 +22,7 @@
   Simple field selection and override
 -------------------------------------------------------------------------------}
 
-{-# ANN type R1 largeRecordStrict #-}
+{-# ANN type R1 largeRecord #-}
 data R1 = MkR1 { r1_x :: Int, r1_y :: Bool }
   deriving (Show, Eq)
 
@@ -44,11 +44,11 @@
   Field selection and override when there are overloaded fields
 -------------------------------------------------------------------------------}
 
-{-# ANN type R2 largeRecordStrict #-}
+{-# ANN type R2 largeRecord #-}
 data R2 = MkR2 { a :: Int, b :: Bool }
   deriving (Show, Eq)
 
-{-# ANN type R3 largeRecordStrict #-}
+{-# ANN type R3 largeRecord #-}
 data R3 = MkR3 { a :: Int, b :: Char }
   deriving (Show, Eq)
 
@@ -81,11 +81,11 @@
 data R5_WOutLR = MkR5_WOutLR { r5_woutLR_x :: Char, r5_woutLR_y :: Double }
   deriving (Show, Eq)
 
-{-# ANN type R4_WithLR largeRecordStrict #-}
+{-# ANN type R4_WithLR largeRecord #-}
 data R4_WithLR = MkR4_WithLR { r4_withLR_x :: Int, r4_withLR_y :: R5_WithLR }
   deriving (Show, Eq)
 
-{-# ANN type R5_WithLR largeRecordStrict #-}
+{-# ANN type R5_WithLR largeRecord #-}
 data R5_WithLR = MkR5_WithLR { r5_withLR_x :: Char, r5_withLR_y :: Double }
   deriving (Show, Eq)
 
diff --git a/test/Test/Record/Sanity/RDP/SplitModule/RecordDef.hs b/test/Test/Record/Sanity/RDP/SplitModule/RecordDef.hs
--- a/test/Test/Record/Sanity/RDP/SplitModule/RecordDef.hs
+++ b/test/Test/Record/Sanity/RDP/SplitModule/RecordDef.hs
@@ -22,23 +22,23 @@
   , R5_WithLR(..)
   ) where
 
-{-# ANN type R1 largeRecordStrict #-}
+{-# ANN type R1 largeRecord #-}
 data R1 = MkR1 { r1_x :: Int, r1_y :: Bool }
   deriving (Show, Eq)
 
-{-# ANN type R2 largeRecordStrict #-}
+{-# ANN type R2 largeRecord #-}
 data R2 = MkR2 { a :: Int, b :: Bool }
   deriving (Show, Eq)
 
-{-# ANN type R3 largeRecordStrict #-}
+{-# ANN type R3 largeRecord #-}
 data R3 = MkR3 { a :: Int, b :: Char }
   deriving (Show, Eq)
 
-{-# ANN type R4_WithLR largeRecordStrict #-}
+{-# ANN type R4_WithLR largeRecord #-}
 data R4_WithLR = MkR4_WithLR { r4_withLR_x :: Int, r4_withLR_y :: R5_WithLR }
   deriving (Show, Eq)
 
-{-# ANN type R5_WithLR largeRecordStrict #-}
+{-# ANN type R5_WithLR largeRecord #-}
 data R5_WithLR = MkR5_WithLR { r5_withLR_x :: Char, r5_withLR_y :: Double }
   deriving (Show, Eq)
 
diff --git a/test/Test/Record/Sanity/RecordConstruction.hs b/test/Test/Record/Sanity/RecordConstruction.hs
--- a/test/Test/Record/Sanity/RecordConstruction.hs
+++ b/test/Test/Record/Sanity/RecordConstruction.hs
@@ -2,6 +2,7 @@
 {-# LANGUAGE DataKinds                 #-}
 {-# LANGUAGE DuplicateRecordFields     #-}
 {-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleContexts          #-}
 {-# LANGUAGE FlexibleInstances         #-}
 {-# LANGUAGE KindSignatures            #-}
 {-# LANGUAGE MultiParamTypeClasses     #-}
@@ -27,10 +28,10 @@
 -- Test both the case where the name of the type and the name of the constructor
 -- are the same and where they are different.
 
-{-# ANN type R largeRecordLazy #-}
+{-# ANN type R largeRecord #-}
 data R a = MkR { x :: Int, y :: [a] } deriving (Eq, Show)
 
-{-# ANN type S largeRecordLazy #-}
+{-# ANN type S largeRecord #-}
 data S a = S { x :: Int, y :: [a] } deriving (Eq, Show)
 
 inOrder :: R Bool
@@ -56,7 +57,7 @@
 data RegularRecord = RR { a :: Int }
   deriving (Show, Eq)
 
-{-# ANN type T largeRecordStrict #-}
+{-# ANN type T largeRecord #-}
 data T = T { x :: Int, y :: S Bool, z :: RegularRecord }
 
 valueOfT :: T
diff --git a/test/Test/Record/Sanity/Strictness.hs b/test/Test/Record/Sanity/Strictness.hs
--- a/test/Test/Record/Sanity/Strictness.hs
+++ b/test/Test/Record/Sanity/Strictness.hs
@@ -27,11 +27,11 @@
 import Test.Tasty
 import Test.Tasty.HUnit
 
-{-# ANN type Lazy largeRecordLazy #-}
+{-# ANN type Lazy largeRecord #-}
 data Lazy = MkLazy { lazyField :: Word }
 
-{-# ANN type Strict largeRecordStrict #-}
-data Strict = MkStrict { strictField :: Word }
+{-# ANN type Strict largeRecord #-}
+data Strict = MkStrict { strictField :: !Word }
 
 _silenceWarnings :: Lazy -> Strict -> ()
 _silenceWarnings MkLazy{..} MkStrict{..} = const () $ (
diff --git a/test/Test/Record/Sanity/StrictnessStrictData.hs b/test/Test/Record/Sanity/StrictnessStrictData.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Record/Sanity/StrictnessStrictData.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE ConstraintKinds           #-}
+{-# LANGUAGE DataKinds                 #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE MultiParamTypeClasses     #-}
+{-# LANGUAGE RecordWildCards           #-}
+{-# LANGUAGE ScopedTypeVariables       #-}
+{-# LANGUAGE TemplateHaskell           #-}
+{-# LANGUAGE TemplateHaskell           #-}
+{-# LANGUAGE TypeApplications          #-}
+{-# LANGUAGE TypeFamilies              #-}
+{-# LANGUAGE UndecidableInstances      #-}
+{-# LANGUAGE StrictData                #-}
+
+{-# OPTIONS_GHC -fplugin=Data.Record.Plugin #-}
+
+module Test.Record.Sanity.StrictnessStrictData (tests) where
+
+import Control.Exception
+import GHC.Records.Compat
+
+import Data.Record.Generic
+import Data.Record.Generic.LowerBound
+
+import qualified Data.Record.Generic.Rep as Rep
+
+import Test.Tasty
+import Test.Tasty.HUnit
+
+{-# ANN type Lazy largeRecord #-}
+data Lazy = MkLazy { lazyField :: ~Word }
+
+{-# ANN type Strict largeRecord #-}
+data Strict = MkStrict { strictField :: Word }
+
+_silenceWarnings :: Lazy -> Strict -> ()
+_silenceWarnings MkLazy{..} MkStrict{..} = const () $ (
+      lazyField
+    , strictField
+    )
+
+tests :: TestTree
+tests = testGroup "Test.Record.Sanity.Strictness" [
+      testCase "initValueLazy"   test_initValueLazy
+    , testCase "initValueStrict" test_initValueStrict
+    , testCase "setValueLazy"    test_setValueLazy
+    , testCase "setValueStrict"  test_setValueStrict
+    ]
+
+test_initValueLazy :: Assertion
+test_initValueLazy =
+    initValue `seq` return ()
+  where
+    initValue :: Lazy
+    initValue = to $ Rep.pure undefined
+
+test_initValueStrict :: Assertion
+test_initValueStrict =
+    expectBoom (initValue `seq` return ())
+  where
+    initValue :: Strict
+    initValue = to $ Rep.pure boom
+
+test_setValueLazy :: Assertion
+test_setValueLazy =
+    setField @"lazyField" initValue boom `seq` return ()
+  where
+    initValue :: Lazy
+    initValue = glowerBound
+
+test_setValueStrict :: Assertion
+test_setValueStrict =
+    expectBoom (setField @"strictField" initValue boom `seq` return ())
+  where
+    initValue :: Strict
+    initValue = glowerBound
+
+{-------------------------------------------------------------------------------
+  Auxiliary
+-------------------------------------------------------------------------------}
+
+data Boom = Boom
+  deriving (Show)
+
+boom :: a
+boom = throw Boom
+
+instance Exception Boom
+
+expectBoom :: IO () -> Assertion
+expectBoom act = do
+    mErr <- try act
+    case mErr of
+      Left Boom -> return ()
+      Right ()  -> assertFailure "Expected boom"
diff --git a/test/TestLargeRecords.hs b/test/TestLargeRecords.hs
--- a/test/TestLargeRecords.hs
+++ b/test/TestLargeRecords.hs
@@ -14,6 +14,7 @@
 import qualified Test.Record.Sanity.RDP.SingleModule
 import qualified Test.Record.Sanity.RecordConstruction
 import qualified Test.Record.Sanity.Strictness
+import qualified Test.Record.Sanity.StrictnessStrictData
 import qualified Test.Record.Sanity.GhcGenerics
 
 main :: IO ()
@@ -34,6 +35,7 @@
         , Test.Record.Sanity.RDP.SingleModule.tests
         , Test.Record.Sanity.RecordConstruction.tests
         , Test.Record.Sanity.Strictness.tests
+        , Test.Record.Sanity.StrictnessStrictData.tests
         , Test.Record.Sanity.GhcGenerics.tests
         ]
     ]
