Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ghc-optics-th for openSUSE:Factory 
checked in at 2021-03-10 08:55:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-optics-th (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-optics-th.new.2378 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-optics-th"

Wed Mar 10 08:55:17 2021 rev:4 rq:877660 version:0.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-optics-th/ghc-optics-th.changes      
2020-12-22 11:43:47.089733253 +0100
+++ /work/SRC/openSUSE:Factory/.ghc-optics-th.new.2378/ghc-optics-th.changes    
2021-03-10 08:57:22.822896729 +0100
@@ -1,0 +2,21 @@
+Tue Feb 23 18:11:41 UTC 2021 - psim...@suse.com
+
+- Update optics-th to version 0.4.
+  # optics-th-0.4 (2021-02-22)
+  * Add support for GHC-9.0
+  * Print missing language extensions during TH generation of labels if there 
are
+    any ([#352](https://github.com/well-typed/optics/pull/352))
+  * Add support for getters of rank1 polymorphic fields to optics generated 
with
+    the `makeFieldLabels` family of functions
+    ([#365](https://github.com/well-typed/optics/pull/365))
+  * Extend support of type-changing optics generated with the `makeFieldLabels`
+    family to type parameters that are phantom and applied to non-injective 
type
+    families
+    ([#365](https://github.com/well-typed/optics/pull/365))
+  * Fix TH generation of optics for poly-kinded data families
+    ([#378](https://github.com/well-typed/optics/pull/378))
+  * Fix `declareFieldLabels` when a field type refers to a type defined in the
+    same quote
+    ([#380](https://github.com/well-typed/optics/pull/380))
+
+-------------------------------------------------------------------

Old:
----
  optics-th-0.3.0.2.tar.gz
  optics-th.cabal

New:
----
  optics-th-0.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-optics-th.spec ++++++
--- /var/tmp/diff_new_pack.Nq50Ne/_old  2021-03-10 08:57:23.426897353 +0100
+++ /var/tmp/diff_new_pack.Nq50Ne/_new  2021-03-10 08:57:23.426897353 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package ghc-optics-th
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,13 +19,12 @@
 %global pkg_name optics-th
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        0.3.0.2
+Version:        0.4
 Release:        0
 Summary:        Optics construction using TemplateHaskell
 License:        BSD-3-Clause
 URL:            https://hackage.haskell.org/package/%{pkg_name}
 Source0:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
-Source1:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/revision/1.cabal#/%{pkg_name}.cabal
 BuildRequires:  ghc-Cabal-devel
 BuildRequires:  ghc-containers-devel
 BuildRequires:  ghc-mtl-devel
@@ -59,7 +58,6 @@
 
 %prep
 %autosetup -n %{pkg_name}-%{version}
-cp -p %{SOURCE1} %{pkg_name}.cabal
 
 %build
 %ghc_lib_build

++++++ optics-th-0.3.0.2.tar.gz -> optics-th-0.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/optics-th-0.3.0.2/CHANGELOG.md 
new/optics-th-0.4/CHANGELOG.md
--- old/optics-th-0.3.0.2/CHANGELOG.md  2001-09-09 03:46:40.000000000 +0200
+++ new/optics-th-0.4/CHANGELOG.md      2001-09-09 03:46:40.000000000 +0200
@@ -1,3 +1,20 @@
+# optics-th-0.4 (2021-02-22)
+* Add support for GHC-9.0
+* Print missing language extensions during TH generation of labels if there are
+  any ([#352](https://github.com/well-typed/optics/pull/352))
+* Add support for getters of rank1 polymorphic fields to optics generated with
+  the `makeFieldLabels` family of functions
+  ([#365](https://github.com/well-typed/optics/pull/365))
+* Extend support of type-changing optics generated with the `makeFieldLabels`
+  family to type parameters that are phantom and applied to non-injective type
+  families
+  ([#365](https://github.com/well-typed/optics/pull/365))
+* Fix TH generation of optics for poly-kinded data families
+  ([#378](https://github.com/well-typed/optics/pull/378))
+* Fix `declareFieldLabels` when a field type refers to a type defined in the
+  same quote
+  ([#380](https://github.com/well-typed/optics/pull/380))
+
 # optics-th-0.3.0.2 (2020-08-20)
 * Fix tests on GHC 8.10.2
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/optics-th-0.3.0.2/optics-th.cabal 
new/optics-th-0.4/optics-th.cabal
--- old/optics-th-0.3.0.2/optics-th.cabal       2001-09-09 03:46:40.000000000 
+0200
+++ new/optics-th-0.4/optics-th.cabal   2001-09-09 03:46:40.000000000 +0200
@@ -1,12 +1,12 @@
 name:          optics-th
-version:       0.3.0.2
+version:       0.4
 license:       BSD3
 license-file:  LICENSE
 build-type:    Simple
 maintainer:    opt...@well-typed.com
 author:        Andrzej Rybczak
 cabal-version: 1.24
-tested-with:   ghc ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.4 || 
==8.10.2, GHCJS ==8.4
+tested-with:   ghc ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.4 || ==8.10.3, GHCJS 
==8.4
 synopsis:      Optics construction using TemplateHaskell
 category:      Data, Optics, Lenses
 description:
@@ -29,12 +29,12 @@
   hs-source-dirs:   src
   ghc-options:      -Wall
 
-  build-depends: base                   >= 4.9       && <5
-               , containers             >= 0.5.7.1   && <0.7
+  build-depends: base                   >= 4.10      && <5
+               , containers             >= 0.5.10.2  && <0.7
                , mtl                    >= 2.2.2     && <2.3
-               , optics-core            >= 0.3       && <0.4
-               , template-haskell       >= 2.11      && <2.17
-               , th-abstraction         >= 0.2.1     && <0.4
+               , optics-core            >= 0.4       && <0.5
+               , template-haskell       >= 2.12      && <2.18
+               , th-abstraction         >= 0.4       && <0.5
                , transformers           >= 0.5       && <0.6
 
   exposed-modules: Optics.TH
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/optics-th-0.3.0.2/src/Language/Haskell/TH/Optics/Internal.hs 
new/optics-th-0.4/src/Language/Haskell/TH/Optics/Internal.hs
--- old/optics-th-0.3.0.2/src/Language/Haskell/TH/Optics/Internal.hs    
2001-09-09 03:46:40.000000000 +0200
+++ new/optics-th-0.4/src/Language/Haskell/TH/Optics/Internal.hs        
2001-09-09 03:46:40.000000000 +0200
@@ -1,5 +1,6 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE TypeSynonymInstances #-}
 module Language.Haskell.TH.Optics.Internal
   (
   -- * Traversals
@@ -14,6 +15,9 @@
   , _ClosedTypeFamilyD
   , _OpenTypeFamilyD
   , _ForallT
+
+  -- * TyVarBndr compatiblity
+  , TyVarBndrSpec
   ) where
 
 import Data.Map as Map hiding (map, toList)
@@ -21,6 +25,7 @@
 import Data.Foldable (traverse_)
 import Data.Set as Set hiding (map, toList)
 import Language.Haskell.TH
+import Language.Haskell.TH.Datatype.TyVarBndr
 
 import Data.Set.Optics
 import Optics.Core
@@ -30,10 +35,15 @@
   -- | Extract (or modify) the 'Name' of something
   name :: Lens' t Name
 
-instance HasName TyVarBndr where
+instance HasName (TyVarBndr_ flag) where
   name = lensVL $ \f -> \case
+#if MIN_VERSION_template_haskell(2,17,0)
+    PlainTV n flag    -> (\n' -> PlainTV n' flag) <$> f n
+    KindedTV n flag k -> (\n' -> KindedTV n' flag k ) <$> f n
+#else
     PlainTV n    -> PlainTV <$> f n
     KindedTV n k -> (`KindedTV` k) <$> f n
+#endif
 
 -- | Provides for the extraction of free type variables, and alpha renaming.
 class HasTypeVars t where
@@ -42,7 +52,7 @@
   -- 'Traversal' laws, when in doubt generate your names with 'newName'.
   typeVarsEx :: Set Name -> Traversal' t Name
 
-instance HasTypeVars TyVarBndr where
+instance HasTypeVars (TyVarBndr_ flag) where
   typeVarsEx s = traversalVL $ \f b ->
     if view name b `Set.member` s
     then pure b
@@ -159,7 +169,7 @@
       remitter (OpenTypeFamilyD x) = Just x
       remitter _ = Nothing
 
-_ForallT :: Prism' Type ([TyVarBndr], Cxt, Type)
+_ForallT :: Prism' Type ([TyVarBndrSpec], Cxt, Type)
 _ForallT
   = prism' reviewer remitter
   where
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/optics-th-0.3.0.2/src/Optics/TH/Internal/Product.hs 
new/optics-th-0.4/src/Optics/TH/Internal/Product.hs
--- old/optics-th-0.3.0.2/src/Optics/TH/Internal/Product.hs     2001-09-09 
03:46:40.000000000 +0200
+++ new/optics-th-0.4/src/Optics/TH/Internal/Product.hs 2001-09-09 
03:46:40.000000000 +0200
@@ -1,4 +1,5 @@
 {-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE LambdaCase #-}
@@ -35,6 +36,7 @@
 import Data.Set.Optics
 import Language.Haskell.TH.Optics.Internal
 import Optics.Core hiding (cons)
+import Optics.Internal.Magic
 import Optics.TH.Internal.Utils
 
 ------------------------------------------------------------------------
@@ -44,8 +46,13 @@
 typeSelf :: Traversal' Type Type
 typeSelf = traversalVL $ \f -> \case
   ForallT tyVarBndrs ctx ty ->
+#if MIN_VERSION_template_haskell(2,17,0)
+    let go (KindedTV nam flag kind) = KindedTV <$> pure nam <*> pure flag <*> 
f kind
+        go (PlainTV nam flag)       = pure (PlainTV nam flag)
+#else
     let go (KindedTV nam kind) = KindedTV <$> pure nam <*> f kind
         go (PlainTV nam)       = pure (PlainTV nam)
+#endif
     in ForallT <$> traverse go tyVarBndrs <*> traverse f ctx <*> f ty
   AppT ty1 ty2              -> AppT <$> f ty1 <*> f ty2
   SigT ty kind              -> SigT <$> f ty <*> f kind
@@ -84,12 +91,15 @@
      case _classyLenses rules tyName of
        Just (className, methodName) ->
          makeClassyDriver rules className methodName s defs
-       Nothing -> do decss <- traverse (makeFieldOptic rules) defs
-                     return (concat decss)
+       Nothing -> do
+         when (has (traversed % _1 % _MethodName) defs) $ do
+           lift requireExtensionsForFields
+         decss <- traverse (makeFieldOptic rules) defs
+         return (concat decss)
 
   where
   tyName = D.datatypeName info
-  s      = addKindVars info $ D.datatypeType info
+  s      = addKindInfo info $ D.datatypeType info
   cons   = D.datatypeCons info
 
   -- Traverse the field labels of a normalized constructor
@@ -135,26 +145,19 @@
 -- | Compute the field optics for a deconstructed datatype Dec
 -- When possible build an Iso otherwise build one optic per field.
 makeFieldLabelsForDatatype :: LensRules -> D.DatatypeInfo -> Q [Dec]
-makeFieldLabelsForDatatype rules info =
-  do perDef <- do
-       fieldCons <- traverse (normalizeConstructor info) cons
-       let allFields  = toListOf (folded % _2 % folded % _1 % folded) fieldCons
-       let defCons    = over normFieldLabels (expandName rules tyName cons 
allFields) fieldCons
-           allDefs    = setOf (normFieldLabels % folded) defCons
-       T.sequenceA (M.fromSet (buildScaffold True rules s defCons) allDefs)
-
-     let defs = filter isRank1 $ M.toList perDef
-     traverse (makeFieldLabel rules) defs
-
+makeFieldLabelsForDatatype rules info = do
+  requireExtensionsForLabels
+  perDef <- do
+    fieldCons <- traverse (normalizeConstructor info) cons
+    let allFields  = toListOf (folded % _2 % folded % _1 % folded) fieldCons
+    let defCons    = over normFieldLabels (expandName rules tyName cons 
allFields) fieldCons
+        allDefs    = setOf (normFieldLabels % folded) defCons
+    T.sequenceA (M.fromSet (buildScaffold True rules s defCons) allDefs)
+  let defs = M.toList perDef
+  traverse (makeFieldLabel info rules) defs
   where
-    -- LabelOptic doesn't support higher rank fields because of functional
-    -- dependencies (s -> a, t -> b), so just skip them.
-    isRank1 = \case
-      (_, (OpticSa vs _ _ _ _, _)) -> null vs
-      _                            -> True
-
     tyName = D.datatypeName info
-    s      = addKindVars info $ D.datatypeType info
+    s      = addKindInfo info $ D.datatypeType info
     cons   = D.datatypeCons info
 
     -- Traverse the field labels of a normalized constructor
@@ -162,23 +165,38 @@
     normFieldLabels = traversed % _2 % traversed % _1
 
 makeFieldLabel
-  :: LensRules
+  :: D.DatatypeInfo
+  -> LensRules
   -> (DefName, (OpticStab, [(Name, Int, [Int])]))
   -> Q Dec
-makeFieldLabel rules (defName, (defType, cons)) = do
+makeFieldLabel info rules (defName, (defType, cons)) = do
   (context, instHead) <- case defType of
-    OpticSa _ _ otype s a -> do
+    OpticSa vs cx otype s a0 -> do
+      -- 'tv' might have info about type variables of 'a' that need filling in.
+      let a = addKindInfo' (map tyVarBndrToType vs) info a0
       (k,  cxtK) <- eqSubst (ConT $ opticTypeToTag otype) "k"
       (a', cxtA) <- eqSubst a "a"
       (b', cxtB) <- eqSubst a "b"
-      pure (pure [cxtK, cxtA, cxtB], pure $ conAppsT ''LabelOptic
-        [LitT (StrTyLit fieldName), k, s, s, a', b'])
-    OpticStab otype s t a b -> do
+      let tyArgs = [LitT (StrTyLit fieldName), k, s, s, a', b']
+          context = concat
+            [ -- If the field is polymorphic, the instance is dysfunctional.
+              if null vs then [] else [conAppsT ''Dysfunctional tyArgs]
+            , [cxtK, cxtA, cxtB]
+            , cx
+            ]
+      pure (pure context, pure $ conAppsT ''LabelOptic tyArgs)
+    OpticStab tvsCovered otype s t a b -> do
       (k,  cxtK) <- eqSubst (ConT $ opticTypeToTag otype) "k"
       (a', cxtA) <- eqSubst a "a"
       (b', cxtB) <- eqSubst b "b"
-      pure (pure [cxtK, cxtA, cxtB], pure $ conAppsT ''LabelOptic
-        [LitT (StrTyLit fieldName), k, s, t, a', b'])
+      let tyArgs = [LitT (StrTyLit fieldName), k, s, t, a', b']
+          context = concat
+            [ -- If some of the type variables are not covered, the instance is
+              -- dysfunctional.
+              if tvsCovered then [] else [conAppsT ''Dysfunctional tyArgs]
+            , [cxtK, cxtA, cxtB]
+            ]
+      pure (pure context, pure $ conAppsT ''LabelOptic tyArgs)
   instanceD context instHead (fun 'labelOptic)
   where
     opticTypeToTag AffineFoldType      = ''An_AffineFold
@@ -221,11 +239,11 @@
     -- elligible for TH generated optics.
     checkForExistentials _ fieldtype
       | any (\tv -> D.tvName tv `S.member` used) unallowable
-      = (Nothing, addKindVars info fieldtype)
+      = (Nothing, addKindInfo info fieldtype)
       where
         used        = setOf typeVars fieldtype
         unallowable = D.constructorVars con
-    checkForExistentials fieldname fieldtype = (fieldname, addKindVars info 
fieldtype)
+    checkForExistentials fieldname fieldtype = (fieldname, addKindInfo info 
fieldtype)
 
 -- | Compute the positional location of the fields involved in
 -- each constructor for a given optic definition as well as the
@@ -241,29 +259,30 @@
               {- ^ optic type, definition type, field count, target fields -}
 buildScaffold forClassInstance rules s cons defName =
 
-  do (s',t,a,b) <- buildStab forClassInstance s (concatMap snd consForDef)
+  do (t,a,b, tvsCovered) <- buildTab forClassInstance s $
+       concatMap snd consForDef
 
      let defType
            | Just (tyvars, cx, a') <- preview _ForallT a =
                let optic | lensCase   = GetterType
                          | affineCase = AffineFoldType
                          | otherwise  = FoldType
-               in OpticSa tyvars cx optic s' a'
+               in OpticSa tyvars cx optic s a'
 
            -- Getter and Fold are always simple
            | not (_allowUpdates rules) =
                let optic | lensCase   = GetterType
                          | affineCase = AffineFoldType
                          | otherwise  = FoldType
-               in OpticSa [] [] optic s' a
+               in OpticSa [] [] optic s a
 
            -- Generate simple Lens and Traversal where possible
-           | _simpleLenses rules || s' == t && a == b =
+           | _simpleLenses rules || s == t && a == b =
                let optic | isoCase && _allowIsos rules = IsoType
                          | lensCase                    = LensType
                          | affineCase                  = AffineTraversalType
                          | otherwise                   = TraversalType
-               in OpticSa [] [] optic s' a
+               in OpticSa [] [] optic s a
 
            -- Generate type-changing Lens and Traversal otherwise
            | otherwise =
@@ -271,7 +290,7 @@
                          | lensCase                    = LensType
                          | affineCase                  = AffineTraversalType
                          | otherwise                   = TraversalType
-               in OpticStab optic s' t a b
+               in OpticStab tvsCovered optic s t a b
 
      return (defType, scaffolds)
   where
@@ -333,12 +352,12 @@
                                                   else ''Traversal'
 
 data OpticStab
-  = OpticStab               OpticType Type Type Type Type
-  | OpticSa [TyVarBndr] Cxt OpticType Type Type
+  = OpticStab Bool              OpticType Type Type Type Type
+  | OpticSa [TyVarBndrSpec] Cxt OpticType Type Type
   deriving Show
 
 stabToType :: OpticStab -> Type
-stabToType (OpticStab c s t a b) =
+stabToType (OpticStab _ c s t a b) =
   quantifyType [] [] (opticTypeName True c `conAppsT` [s,t,a,b])
 stabToType (OpticSa vs cx c s a) =
   quantifyType vs cx (opticTypeName False c `conAppsT` [s,a])
@@ -348,31 +367,33 @@
 stabToContext (OpticSa _ cx _ _ _) = cx
 
 stabToOpticType :: OpticStab -> OpticType
-stabToOpticType (OpticStab c _ _ _ _) = c
+stabToOpticType (OpticStab _ c _ _ _ _) = c
 stabToOpticType (OpticSa _ _ c _ _) = c
 
 stabToOptic :: OpticStab -> Name
-stabToOptic (OpticStab c _ _ _ _) = opticTypeName True c
+stabToOptic (OpticStab _ c _ _ _ _) = opticTypeName True c
 stabToOptic (OpticSa _ _ c _ _) = opticTypeName False c
 
 stabToS :: OpticStab -> Type
-stabToS (OpticStab _ s _ _ _) = s
+stabToS (OpticStab _ _ s _ _ _) = s
 stabToS (OpticSa _ _ _ s _) = s
 
 stabToA :: OpticStab -> Type
-stabToA (OpticStab _ _ _ a _) = a
+stabToA (OpticStab _ _ _ _ a _) = a
 stabToA (OpticSa _ _ _ _ a) = a
 
--- | Compute the s t a b types given the outer type 's' and the
+-- | Compute the t a b types given the outer type 's' and the
 -- categorized field types. Left for fixed and Right for visited.
 -- These types are "raw" and will be packaged into an 'OpticStab'
 -- shortly after creation.
-buildStab :: Bool -> Type -> [Either Type Type] -> Q (Type,Type,Type,Type)
-buildStab forClassInstance s categorizedFields = do
-  -- compute possible type changes
-  sub <- T.sequenceA . M.fromSet (newName . nameBase) =<< unfixedTypeVars
+buildTab :: Bool -> Type -> [Either Type Type] -> Q (Type,Type,Type,Bool)
+buildTab forClassInstance s categorizedFields = do
+  -- Compute possible type changes and check whether we have to lift the
+  -- coverage condition in case we're generating a class instance.
+  (unfixedTypeVars, tvsCovered) <- mkUnfixedTypeVars
+  sub <- T.sequenceA $ M.fromSet (newName . nameBase) unfixedTypeVars
   let (t, b) = over each (substTypeVars sub) (s, a)
-  pure (s, t, a, b)
+  pure (t, a, b, tvsCovered)
   where
     -- Just take the type of the first field and let GHC do the unification.
     a = fromMaybe
@@ -385,7 +406,11 @@
 
     (fixedFields, targetFields) = partitionEithers categorizedFields
 
-    unfixedTypeVars
+    mkUnfixedTypeVars
+      | S.null freeTypeVars =
+        -- If there are no free type vars, don't bother searching for ambiguous
+        -- type family applications because there are none.
+        pure (S.empty, True)
       | forClassInstance = do
           ambiguousTypeVars <- getAmbiguousTypeFamilyTypeVars
           --runIO $ do
@@ -395,10 +420,10 @@
           --  putStrLn $ "FIXED:     " ++ show fixedTypeVars
           --  putStrLn $ "PHANTOM:   " ++ show phantomTypeVars
           --  putStrLn $ "AMBIGUOUS: " ++ show ambiguousTypeVars
-          pure $ freeTypeVars S.\\ fixedTypeVars
-                              S.\\ phantomTypeVars
-                              S.\\ ambiguousTypeVars
-      | otherwise = pure $ freeTypeVars S.\\ fixedTypeVars
+          pure ( freeTypeVars S.\\ fixedTypeVars
+               , S.null phantomTypeVars && S.null ambiguousTypeVars
+               )
+      | otherwise = pure (freeTypeVars S.\\ fixedTypeVars, True)
       where
         freeTypeVars  = setOf typeVars s
         fixedTypeVars = setOf typeVars fixedFields
@@ -421,7 +446,7 @@
         go (ConT nm) = do
           let getVarLen = afolding $ \tf@(TypeFamilyHead _ varBndrs _ _) ->
                 if null varBndrs then Nothing else Just (length varBndrs, tf, 
[])
-          preview (_FamilyI % _1 % typeFamilyHead % getVarLen) <$> lift (reify 
nm)
+          tryReify (preview $ _FamilyI % _1 % typeFamilyHead % getVarLen) nm
 
         go (AppT ty1 ty2) = go ty1 >>= \case
           Just (n, tf, !args)
@@ -433,18 +458,23 @@
         go _ = pure Nothing
 
         procInfix ty1 nm ty2 = do
-          mtf <- preview (_FamilyI % _1 % typeFamilyHead) <$> lift (reify nm)
+          mtf <- tryReify (preview $ _FamilyI % _1 % typeFamilyHead) nm
           case mtf of
             Just tf -> procTF tf [ty1, ty2]
             Nothing -> go ty1 *> go ty2 *> pure ()
 
+        -- If reification fails (e.g. because the type contains local names),
+        -- assume there are no type families (the best we can do really).
+        tryReify :: (Info -> Maybe a) -> Name -> StateT (S.Set Name) Q (Maybe 
a)
+        tryReify f nm = lift $ recover (pure Nothing) (f <$> reify nm)
+
         -- Once fully applied type family is collected, the only arguments that
         -- should be traversed further are these with injectivity annotation.
         procTF :: TypeFamilyHead -> [Type] -> StateT (S.Set Name) Q ()
         procTF tf args = case tf of
           TypeFamilyHead _ varBndrs _ (Just (InjectivityAnn _ ins)) -> do
             let insSet = S.fromList ins
-                vars   = map bndrName varBndrs
+                vars   = map D.tvName varBndrs
             --lift . runIO $ do
             --  putStrLn $ "INS:  " ++ show ins
             --  putStrLn $ "VARS: " ++ show vars
@@ -528,7 +558,7 @@
            | otherwise = [FunDep [c] vars]
 
 
-  classD (cxt[]) className (map PlainTV (c:vars)) fd
+  classD (cxt[]) className (map plainTV (c:vars)) fd
     $ sigD methodName (return (''Lens' `conAppsT` [VarT c, s]))
     : concat
       [ [sigD defName (return ty)
@@ -572,7 +602,7 @@
 
 makeFieldClass :: OpticStab -> Name -> Name -> DecQ
 makeFieldClass defType className methodName =
-  classD (cxt []) className [PlainTV s, PlainTV a] [FunDep [s] [a]]
+  classD (cxt []) className [plainTV s, plainTV a] [FunDep [s] [a]]
          [sigD methodName (return methodType)]
   where
   methodType = quantifyType' (S.fromList [s,a])
@@ -879,6 +909,11 @@
   | MethodName Name Name -- ^ makeFields-style class name and method name
   deriving (Show, Eq, Ord)
 
+_MethodName :: Prism' DefName (Name, Name)
+_MethodName = prism' (uncurry MethodName) $ \case
+  TopName{}      -> Nothing
+  MethodName c n -> Just (c, n)
+
 -- | The optional rule to create a class and method around a
 -- monomorphic data type. If this naming convention is provided, it
 -- generates a "classy" lens.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/optics-th-0.3.0.2/src/Optics/TH/Internal/Sum.hs 
new/optics-th-0.4/src/Optics/TH/Internal/Sum.hs
--- old/optics-th-0.3.0.2/src/Optics/TH/Internal/Sum.hs 2001-09-09 
03:46:40.000000000 +0200
+++ new/optics-th-0.4/src/Optics/TH/Internal/Sum.hs     2001-09-09 
03:46:40.000000000 +0200
@@ -11,6 +11,7 @@
 import Data.Maybe
 import Data.Traversable
 import Language.Haskell.TH
+import Language.Haskell.TH.Datatype.TyVarBndr
 import qualified Data.Map as M
 import qualified Data.Set as S
 import qualified Language.Haskell.TH.Datatype as D
@@ -18,6 +19,7 @@
 import Data.Set.Optics
 import Language.Haskell.TH.Optics.Internal
 import Optics.Core hiding (cons)
+import Optics.Internal.Magic
 import Optics.TH.Internal.Utils
 
 -- | Generate a 'Prism' for each constructor of a data type. Isos generated 
when
@@ -82,29 +84,31 @@
 
 makePrismLabels :: Name -> DecsQ
 makePrismLabels typeName = do
+  requireExtensionsForLabels
   info <- D.reifyDatatype typeName
   let cons = map (normalizeCon info) $ D.datatypeCons info
   catMaybes <$> traverse (makeLabel info cons) cons
   where
     makeLabel :: D.DatatypeInfo -> [NCon] -> NCon -> Q (Maybe Dec)
     makeLabel info cons con = do
-      stab@(Stab cx otype s t a b) <- computeOpticType labelConfig ty cons con
-      case otype of
-        -- Reviews are for existentially quantified types and these don't fit
-        -- into OpticLabel because of functional dependencies, just skip them.
-        ReviewType -> pure Nothing
-        _ -> do
-          (k,  cxtK) <- eqSubst (ConT $ opticTypeToTag otype) "k"
-          (a', cxtA) <- eqSubst a "a"
-          (b', cxtB) <- eqSubst b "b"
-          let label = nameBase . prismName $ view nconName con
-              instHead = pure $ conAppsT ''LabelOptic
-                [LitT (StrTyLit label), k, s, t, a', b']
-          Just <$> instanceD (pure $ cx ++ [cxtK, cxtA, cxtB])
-                             instHead
-                             (fun stab 'labelOptic)
+      stab@(Stab tvsCovered cx otype s t a b) <- computeOpticType labelConfig 
ty cons con
+      (k,  cxtK) <- eqSubst (ConT $ opticTypeToTag otype) "k"
+      (a', cxtA) <- eqSubst a "a"
+      (b', cxtB) <- eqSubst b "b"
+      let label = nameBase . prismName $ view nconName con
+          tyArgs = [LitT (StrTyLit label), k, s, t, a', b']
+          context = concat
+            [ -- If some of the type variables are not covered, instance is
+              -- dysfunctional.
+              if tvsCovered then [] else [conAppsT ''Dysfunctional tyArgs]
+            , [cxtK, cxtA, cxtB]
+            , cx
+            ]
+      Just <$> instanceD (pure context)
+                         (pure $ conAppsT ''LabelOptic tyArgs)
+                         (fun stab 'labelOptic)
       where
-        ty        = addKindVars info $ D.datatypeType info
+        ty        = addKindInfo info $ D.datatypeType info
         isNewtype = D.datatypeVariant info == D.Newtype
 
         opticTypeToTag IsoType    = ''An_Iso
@@ -156,7 +160,7 @@
     , valD (varP n) (normalB body) []
     ] ++ inlinePragma n
   where
-    ty        = addKindVars info $ D.datatypeType info
+    ty        = addKindInfo info $ D.datatypeType info
     isNewtype = D.datatypeVariant info == D.Newtype
 
 -- classy prism class and instance
@@ -173,41 +177,42 @@
 ----------------------------------------
 
 data StabConfig = StabConfig
-  { scAllowPhantomsChange :: Bool
-  , scAllowIsos           :: Bool
+  { scForLabelInstance :: Bool
+  , scAllowIsos        :: Bool
   }
 
 defaultConfig :: StabConfig
 defaultConfig = StabConfig
-  { scAllowPhantomsChange = True
-  , scAllowIsos           = True
+  { scForLabelInstance = False
+  , scAllowIsos        = True
   }
 
 classyConfig :: StabConfig
 classyConfig = StabConfig
-  { scAllowPhantomsChange = True
-  , scAllowIsos           = False
+  { scForLabelInstance = False
+  , scAllowIsos        = False
   }
 
 labelConfig :: StabConfig
 labelConfig = StabConfig
-  { scAllowPhantomsChange = False
-  , scAllowIsos           = True
+  { scForLabelInstance = True
+  , scAllowIsos        = True
   }
 
 data OpticType = IsoType | PrismType | ReviewType
-data Stab  = Stab Cxt OpticType Type Type Type Type
+  deriving Eq
+data Stab  = Stab Bool Cxt OpticType Type Type Type Type
 
 simplifyStab :: Stab -> Stab
-simplifyStab (Stab cx ty _ t _ b) = Stab cx ty t t b b
+simplifyStab (Stab tvsCovered cx ty _ t _ b) = Stab tvsCovered cx ty t t b b
   -- simplification uses t and b because those types
   -- are interesting in the Review case
 
 stabSimple :: Stab -> Bool
-stabSimple (Stab _ _ s t a b) = s == t && a == b
+stabSimple (Stab _ _ _ s t a b) = s == t && a == b
 
 stabToType :: Stab -> Type
-stabToType stab@(Stab cx ty s t a b) = ForallT vs cx $
+stabToType stab@(Stab _ cx ty s t a b) = ForallT vs cx $
   case ty of
     IsoType    | stabSimple stab -> ''Iso'    `conAppsT` [s,a]
                | otherwise       -> ''Iso     `conAppsT` [s,t,a,b]
@@ -216,12 +221,13 @@
     ReviewType                   -> ''Review  `conAppsT` [t,b]
 
   where
-    vs = D.freeVariablesWellScoped
+    vs = changeTVFlags SpecifiedSpec
+       . D.freeVariablesWellScoped
        . S.toList
        $ setOf (folded % typeVarsKinded) cx
 
 stabType :: Stab -> OpticType
-stabType (Stab _ o _ _ _ _) = o
+stabType (Stab _ _ o _ _ _ _) = o
 
 computeOpticType :: StabConfig -> Type -> [NCon] -> NCon -> Q Stab
 computeOpticType conf t cons con =
@@ -230,11 +236,10 @@
          then computePrismType conf t (view nconCxt con) cons' con
          else computeReviewType t (view nconCxt con) (view nconTypes con)
 
-
 computeReviewType :: Type -> Cxt -> [Type] -> Q Stab
 computeReviewType t cx tys = do
   b <- toTupleT (map return tys)
-  return (Stab cx ReviewType t t b b)
+  return (Stab False cx ReviewType t t b b)
 
 -- | Compute the full type-changing Prism type given an outer type, list of
 -- constructors, and target constructor name.
@@ -244,9 +249,11 @@
       free     = setOf typeVars s
       fixed    = setOf typeVars cons
       phantoms = free S.\\ setOf (folded % nconTypes % typeVars) (con : cons)
-      unbound  = if scAllowPhantomsChange conf
-                 then free S.\\ fixed
-                 else free S.\\ fixed S.\\ phantoms
+
+      unbound    = free S.\\ fixed
+      tvsCovered = if scForLabelInstance conf
+                   then S.null phantoms
+                   else True
   sub <- sequenceA (M.fromSet (newName . nameBase) unbound)
   a   <- toTupleT (map return ts)
   b   <- toTupleT (map return (substTypeVars sub ts))
@@ -262,7 +269,7 @@
       otype = if null cons && scAllowIsos conf
               then IsoType
               else PrismType
-  return (Stab cx' otype s t a b)
+  return (Stab tvsCovered cx' otype s t a b)
 
 -- | Construct either a Review or Prism as appropriate
 makeConOpticExp :: Stab -> [NCon] -> NCon -> ExpQ
@@ -403,15 +410,15 @@
   do r <- newName "r"
      let methodType = appsT (conT ''Prism') [varT r,return t]
      methodss <- traverse (mkMethod (VarT r)) cons'
-     classD (cxt[]) className (map PlainTV (r : vs)) (fds r)
+     classD (cxt[]) className (map plainTV (r : vs)) (fds r)
        ( sigD methodName methodType
        : map return (concat methodss)
        )
 
   where
   mkMethod r con =
-    do Stab cx o _ _ _ b <- computeOpticType classyConfig t cons con
-       let stab' = Stab cx o r r b b
+    do Stab tvsCovered cx o _ _ _ b <- computeOpticType classyConfig t cons con
+       let stab' = Stab tvsCovered cx o r r b b
            defName = view nconName con
            body    = appsE [varE '(%), varE methodName, varE defName]
        sequenceA
@@ -467,7 +474,7 @@
   , _nconCxt  :: Cxt
   , _nconTypes :: [Type]
   }
-  deriving (Eq)
+  deriving (Eq, Show)
 
 instance HasTypeVars NCon where
   typeVarsEx s = traversalVL $ \f (NCon x vars y z) ->
@@ -487,10 +494,13 @@
 
 -- | Normalize a single 'Con' to its constructor name and field types.
 normalizeCon :: D.DatatypeInfo -> D.ConstructorInfo -> NCon
-normalizeCon di info = NCon (D.constructorName info)
-                            (D.tvName <$> D.constructorVars info)
-                            (D.constructorContext info)
-                            (map (addKindVars di) $ D.constructorFields info)
+normalizeCon di info = NCon
+  { _nconName  = D.constructorName info
+  , _nconVars  = D.tvName <$> D.constructorVars info
+  , _nconCxt   = D.constructorContext info
+  , _nconTypes = let tyVars = map tyVarBndrToType (D.constructorVars info)
+                 in addKindInfo' tyVars di <$> D.constructorFields info
+  }
 
 
 -- | Compute a prism's name by prefixing an underscore for normal
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/optics-th-0.3.0.2/src/Optics/TH/Internal/Utils.hs 
new/optics-th-0.4/src/Optics/TH/Internal/Utils.hs
--- old/optics-th-0.3.0.2/src/Optics/TH/Internal/Utils.hs       2001-09-09 
03:46:40.000000000 +0200
+++ new/optics-th-0.4/src/Optics/TH/Internal/Utils.hs   2001-09-09 
03:46:40.000000000 +0200
@@ -1,7 +1,10 @@
 module Optics.TH.Internal.Utils where
 
+import Control.Monad
 import Data.Maybe
+import Data.List
 import Language.Haskell.TH
+import Language.Haskell.TH.Datatype.TyVarBndr
 import qualified Data.Map as M
 import qualified Data.Set as S
 import qualified Language.Haskell.TH.Datatype as D
@@ -37,11 +40,6 @@
 conAppsT :: Name -> [Type] -> Type
 conAppsT conName = foldl AppT (ConT conName)
 
--- | Return 'Name' contained in a 'TyVarBndr'.
-bndrName :: TyVarBndr -> Name
-bndrName (PlainTV  n  ) = n
-bndrName (KindedTV n _) = n
-
 -- | Generate many new names from a given base name.
 newNames :: String {- ^ base name -} -> Int {- ^ count -} -> Q [Name]
 newNames base n = sequence [ newName (base++show i) | i <- [1..n] ]
@@ -55,31 +53,101 @@
   placeholder <- VarT <$> newName n
   pure (placeholder, D.equalPred placeholder ty)
 
+addKindInfo :: D.DatatypeInfo -> Type -> Type
+addKindInfo = addKindInfo' []
+
 -- | Fill in kind variables using info from datatype type parameters.
-addKindVars :: D.DatatypeInfo -> Type -> Type
-addKindVars = substType . M.fromList . mapMaybe var . D.datatypeInstTypes
+addKindInfo' :: [Type] -> D.DatatypeInfo -> Type -> Type
+addKindInfo' additionalInfo di =
+  substType . M.fromList . mapMaybe var $ additionalInfo ++ 
D.datatypeInstTypes di
   where
+    -- If the type is a data/newtype family instance, we need to fill in all of
+    -- the kinds for weird cases such as:
+    --
+    -- data family KDF (a :: k)
+    -- data instance KDF (a :: Type) = Kinded3 { _kdf :: Proxy a }
+    --
+    -- Otherwise we only need info about kind variables.
+    --
+    -- More info at https://github.com/ekmett/lens/pull/945.
+    isDataFamily = D.datatypeVariant di == D.DataInstance
+                || D.datatypeVariant di == D.NewtypeInstance
+
     var t@(SigT (VarT n) k)
+      | isDataFamily   = Just (n, t)
       | has typeVars k = Just (n, t)
       | otherwise      = Nothing
     var _              = Nothing
 
 -- | Template Haskell wants type variables declared in a forall, so
 -- we find all free type variables in a given type and declare them.
-quantifyType :: [TyVarBndr] -> Cxt -> Type -> Type
+quantifyType :: [TyVarBndrSpec] -> Cxt -> Type -> Type
 quantifyType = quantifyType' S.empty
 
 -- | This function works like 'quantifyType' except that it takes
 -- a list of variables to exclude from quantification.
-quantifyType' :: S.Set Name -> [TyVarBndr] -> Cxt -> Type -> Type
+quantifyType' :: S.Set Name -> [TyVarBndrSpec] -> Cxt -> Type -> Type
 quantifyType' exclude vars cx t = ForallT vs cx t
   where
-    vs = filter (\v -> bndrName v `S.notMember` exclude)
+    vs = filter (\v -> D.tvName v `S.notMember` exclude)
+       . changeTVFlags SpecifiedSpec
        . D.freeVariablesWellScoped
-       $ map bndrToType vars ++ S.toList (setOf typeVarsKinded t)
+       $ map tyVarBndrToType vars ++ S.toList (setOf typeVarsKinded t)
+
+-- | Transform 'TyVarBndr' into a 'Type' so it's suitable e.g. for
+-- freeVariablesWellScoped or type substitution.
+tyVarBndrToType :: TyVarBndr_ flag -> Type
+tyVarBndrToType = elimTV VarT (\n k -> SigT (VarT n) k)
+
+-- | Pass in a list of lists of extensions, where any of the given extensions
+-- will satisfy it. For example, you might need either GADTs or
+-- ExistentialQuantification, so you'd write:
+--
+-- > requireExtensions [[GADTs, ExistentialQuantification]]
+--
+-- But if you need TypeFamilies and MultiParamTypeClasses, then you'd write:
+--
+-- > requireExtensions [[TypeFamilies], [MultiParamTypeClasses]]
+--
+requireExtensions :: String -> [[Extension]] -> Q ()
+requireExtensions what extLists = do
+  -- Taken from the persistent library
+  required <- filterM (fmap (not . or) . traverse isExtEnabled) extLists
+  case mapMaybe listToMaybe required of
+    [] -> pure ()
+    [extension] -> fail $ mconcat
+      [ "Generating " ++ what ++ " requires the "
+      , show extension
+      , " language extension. Please enable it by copy/pasting this line to 
the top of your file:\n\n"
+      , extensionToPragma extension
+      , "\n\nTo enable it in a GHCi session, use the following command:\n\n"
+      , ":seti -X" ++ show extension
+      ]
+    extensions -> fail $ mconcat
+      [ "Generating " ++ what ++ " requires the following language 
extensions:\n\n"
+      , intercalate "\n" (map (("- " ++) . show) extensions)
+      , "\n\nPlease enable the extensions by copy/pasting these lines into the 
top of your file:\n\n"
+      , intercalate "\n" (map extensionToPragma extensions)
+      , "\n\nTo enable them in a GHCi session, use the following command:\n\n"
+      , ":seti " ++ unwords (map (("-X" ++) . show) extensions)
+      ]
+  where
+    extensionToPragma ext = "{-# LANGUAGE " ++ show ext ++ " #-}"
 
-    bndrToType (PlainTV n)    = VarT n
-    bndrToType (KindedTV n k) = SigT (VarT n) k
+requireExtensionsForLabels :: Q ()
+requireExtensionsForLabels = requireExtensions "LabelOptic instances"
+  [ [DataKinds]
+  , [FlexibleInstances]
+  , [MultiParamTypeClasses]
+  , [TypeFamilies, GADTs]
+  , [UndecidableInstances]
+  ]
+
+requireExtensionsForFields :: Q ()
+requireExtensionsForFields = requireExtensions "field optics"
+  [ [FlexibleInstances]
+  , [FunctionalDependencies]
+  ]
 
 ------------------------------------------------------------------------
 -- Support for generating inline pragmas
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/optics-th-0.3.0.2/src/Optics/TH.hs 
new/optics-th-0.4/src/Optics/TH.hs
--- old/optics-th-0.3.0.2/src/Optics/TH.hs      2001-09-09 03:46:40.000000000 
+0200
+++ new/optics-th-0.4/src/Optics/TH.hs  2001-09-09 03:46:40.000000000 +0200
@@ -3,6 +3,7 @@
   -- * Generation of field optics
   -- ** Labels
     makeFieldLabels
+  , makeFieldLabelsNoPrefix
   , makeFieldLabelsFor
   , makeFieldLabelsWith
   , declareFieldLabels
@@ -124,13 +125,21 @@
 --   labelOptic = atraversalVL $ \\point f s -> case s of
 --     Cat x1 x2 -> fmap (\\y -> Cat x1 y) (f x2)
 --     Dog x1 x2 -> point (Dog x1 x2)
+--
+-- instance
+--   ( Dysfunctional "absurd" k Animal Animal a b
+--   , k ~ An_AffineFold, a ~ (x -> y), b ~ (x -> y)
+--   ) => LabelOptic "absurd" k Animal Animal a b where
+--   labelOptic = afolding $ \\s -> case s of
+--     Cat _ _  -> Nothing
+--     Dog _ f  -> Just f
 -- @
 --
--- which can be used as @#age@ and @#name@ with the @OverloadedLabels@ language
--- extension.
+-- which can be used as @#age@, @#name@ and @#absurd@ with the
+-- @OverloadedLabels@ language extension.
 --
--- /Note:/ if you wonder about the form of instances or why there is no label 
for
--- @animalAbsurd@, see "Optics.Label#limitations".
+-- /Note:/ if you wonder about the structure of instances, see
+-- "Optics.Label#structure".
 --
 -- @
 -- 'makeFieldOptics' = 'makeFieldLabelsWith' 'fieldLabelsRules'
@@ -138,6 +147,10 @@
 makeFieldLabels :: Name -> DecsQ
 makeFieldLabels = makeFieldLabelsWith fieldLabelsRules
 
+-- | An alias for @makeFieldLabels noPrefixFieldLabels@.
+makeFieldLabelsNoPrefix :: Name -> DecsQ
+makeFieldLabelsNoPrefix = makeFieldLabelsWith noPrefixFieldLabels
+
 -- | Derive field optics as labels, specifying explicit pairings of 
@(fieldName,
 -- labelName)@.
 --
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/optics-th-0.3.0.2/tests/Optics/TH/Tests.hs 
new/optics-th-0.4/tests/Optics/TH/Tests.hs
--- old/optics-th-0.3.0.2/tests/Optics/TH/Tests.hs      2001-09-09 
03:46:40.000000000 +0200
+++ new/optics-th-0.4/tests/Optics/TH/Tests.hs  2001-09-09 03:46:40.000000000 
+0200
@@ -1,4 +1,5 @@
 {-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE GADTs #-}
@@ -67,7 +68,7 @@
 
 checkPairEq_
   :: (Eq a', Eq b')
-  => Iso (PairEq a b c) (PairEq a' b' c) (a, b) (a', b')
+  => Iso (PairEq a b c) (PairEq a' b' c') (a, b) (a', b')
 checkPairEq_ = #_PairEq
 
 data Brr a where
@@ -97,15 +98,13 @@
 checkBzztShow :: Show a => Prism (Bzzt a b c) (Bzzt a b c') a a
 checkBzztShow = _BzztShow
 
--- We can't change b because of LabelOptic fundeps.
-checkBzztShow_ :: Show a => Prism' (Bzzt a b c) a
+checkBzztShow_ :: Show a => Prism (Bzzt a b c) (Bzzt a b c') a a
 checkBzztShow_ = #_BzztShow
 
 checkBzztRead :: Read b => Prism (Bzzt a b c) (Bzzt a b c') b b
 checkBzztRead = _BzztRead
 
--- We can't change b because of LabelOptic fundeps.
-checkBzztRead_ :: Read b => Prism' (Bzzt a b c) b
+checkBzztRead_ :: Read b => Prism (Bzzt a b c) (Bzzt a b c') b b
 checkBzztRead_ = #_BzztRead
 
 data FooX a where
@@ -116,15 +115,13 @@
 checkFooX1 :: Prism (FooX a) (FooX b) (Int, Int) (Int, Int)
 checkFooX1 = _FooX1
 
--- We can't change a because of LabelOptic fundeps.
-checkFooX1_ :: Prism' (FooX a) (Int, Int)
+checkFooX1_ :: Prism (FooX a) (FooX b) (Int, Int) (Int, Int)
 checkFooX1_ = #_FooX1
 
 checkFooX2 :: Prism (FooX a) (FooX b) (Int, Int) (Int, Int)
 checkFooX2 = _FooX2
 
--- We can't change a because of LabelOptic fundeps.
-checkFooX2_ :: Prism' (FooX a) (Int, Int)
+checkFooX2_ :: Prism (FooX a) (FooX b) (Int, Int) (Int, Int)
 checkFooX2_ = #_FooX2
 
 data ClassyTest = ClassyT1 Int | ClassyT2 String | ClassyT3 Char
@@ -173,9 +170,11 @@
 checkWeird2 = _Weird2
 
 checkWeird2_
-  :: forall (a  :: Type -> Type)
-            (b  :: Type -> Type)
-   . Iso (Weird2 a b) (Weird2 a b) () ()
+  :: forall k (a  :: k    -> Type)
+              (b  :: k    -> Type)
+              (a' :: Type -> Type)
+              (b' :: Type -> Type)
+   . Iso (Weird2 a b) (Weird2 a' b') () ()
 checkWeird2_ = #_Weird2
 
 data Weird3 (a :: k) where
@@ -186,7 +185,7 @@
 checkWeird3 :: forall k (a :: k) (b :: Type). Iso (Weird3 a) (Weird3 b) () ()
 checkWeird3 = _Weird3
 
-checkWeird3_ :: forall (a :: Type). Iso (Weird3 a) (Weird3 a) () ()
+checkWeird3_ :: forall k (a :: k) (b :: Type). Iso (Weird3 a) (Weird3 b) () ()
 checkWeird3_ = #_Weird3
 
 ----------------------------------------
@@ -198,8 +197,7 @@
 checkBaz :: Iso (Bar a b c) (Bar a' b' c') (a, b) (a', b')
 checkBaz = baz
 
--- We can't change c because of LabelOptic fundeps.
-checkBaz_ :: Iso (Bar a b c) (Bar a' b' c) (a, b) (a', b')
+checkBaz_ :: Iso (Bar a b c) (Bar a' b' c') (a, b) (a', b')
 checkBaz_ = #baz
 
 data Quux a b = Quux { _quaffle :: Int, _quartz :: Double }
@@ -209,15 +207,13 @@
 checkQuaffle :: Lens (Quux a b) (Quux a' b') Int Int
 checkQuaffle = quaffle
 
--- We can't change a and b because of LabelOptic fundeps.
-checkQuaffle_ :: Lens (Quux a b) (Quux a b) Int Int
+checkQuaffle_ :: Lens (Quux a b) (Quux a' b') Int Int
 checkQuaffle_ = #quaffle
 
 checkQuartz :: Lens (Quux a b) (Quux a' b') Double Double
 checkQuartz = quartz
 
--- We can't change a and b because of LabelOptic fundeps.
-checkQuartz_ :: Lens (Quux a b) (Quux a b) Double Double
+checkQuartz_ :: Lens (Quux a b) (Quux a' b') Double Double
 checkQuartz_ = #quartz
 
 data Quark a = Qualified   { _gaffer :: a }
@@ -289,9 +285,15 @@
 checkAbsurdity1 :: Eq x => Getter (Perambulation a b) (x -> y)
 checkAbsurdity1 = absurdity1
 
+checkAbsurdity1_ :: Eq x => Getter (Perambulation a b) (x -> y)
+checkAbsurdity1_ = #absurdity1
+
 checkAbsurdity2 :: Eq x => AffineFold (Perambulation a b) (x -> y)
 checkAbsurdity2 = absurdity2
 
+checkAbsurdity2_ :: Eq x => AffineFold (Perambulation a b) (x -> y)
+checkAbsurdity2_ = #absurdity2
+
 checkDunes :: AffineTraversal' (Perambulation a b) a
 checkDunes = dunes
 
@@ -507,10 +509,14 @@
   { _kinded0Thing :: forall a. Proxy (a :: k)
   }
 makeLenses ''Kinded0
+makeFieldLabelsWith lensRules ''Kinded0
 
 checkKinded0Thing :: Getter (Kinded0 k) (Proxy (a :: k))
 checkKinded0Thing = kinded0Thing
 
+checkKinded0Thing_ :: Getter (Kinded0 k) (Proxy (a :: k))
+checkKinded0Thing_ = #kinded0Thing
+
 data Kinded1 (a :: k1) (b :: k2) = Kinded
   { _kinded1Thing :: Tagged '(a, b) Int
   }
@@ -533,6 +539,17 @@
                          (Proxy (a' :: k'))
 checkKinded2Thing = #thing
 
+data family KDF (a :: k)
+data instance KDF (a :: Type) = Kinded3 { _kdf :: Proxy a }
+makeLenses 'Kinded3
+makeFieldLabelsWith lensRules 'Kinded3
+
+checkKdf :: forall (a :: Type) (b :: Type). Iso (KDF a) (KDF b) (Proxy a) 
(Proxy b)
+checkKdf = kdf
+
+checkKdf_ :: forall (a :: Type) (b :: Type). Iso (KDF a) (KDF b) (Proxy a) 
(Proxy b)
+checkKdf_ = #kdf
+
 type family Fam0
 
 type family Fam (a :: k)
@@ -554,7 +571,7 @@
 data FamRec2 a b = FamRec2 { _famRec2Thing :: FamInj1 a b }
 makeFieldLabels ''FamRec2
 
-checkFamRec2Thing :: Iso (FamRec2 a b) (FamRec2 a' b) (FamInj1 a b) (FamInj1 
a' b)
+checkFamRec2Thing :: Iso (FamRec2 a b) (FamRec2 a' b') (FamInj1 a b) (FamInj1 
a' b')
 checkFamRec2Thing = #thing
 
 type family a :#: b = r | r -> b
@@ -563,15 +580,14 @@
 data FamRec3 a b = FamRec3 { _famRec3Thing :: a :#: b }
 makeFieldLabels ''FamRec3
 
-checkFamRec3Thing :: Iso (FamRec3 a b) (FamRec3 a b') (a :#: b) (a :#: b')
+checkFamRec3Thing :: Iso (FamRec3 a b) (FamRec3 a' b') (a :#: b) (a' :#: b')
 checkFamRec3Thing = #thing
 
 -- ambiguous type family application, type-preserving optic
 data FamRec4 a = FamRec4 { _famRec4Thing :: FamInj1 (Fam a) a }
 makeFieldLabels ''FamRec4 -- no error
 
--- no type changing optic here
-checkFamRec4Thing :: Iso' (FamRec4 a) (FamInj1 (Fam a) a)
+checkFamRec4Thing :: Iso (FamRec4 a) (FamRec4 b) (FamInj1 (Fam a) a) (FamInj1 
(Fam b) b)
 checkFamRec4Thing = #thing
 
 type family FamInj2 a b (c :: k) = r | r -> a b c
@@ -601,10 +617,10 @@
   }
 makeFieldLabels ''FamRec7
 
-checkFamRec7Thing :: Iso (FamRec7 a b  (c  :: [k ]))
-                         (FamRec7 a' b (c' :: [k']))
+checkFamRec7Thing :: Iso (FamRec7 a  b  (c  :: [k ]))
+                         (FamRec7 a' b' (c' :: [k']))
                          (FamInj1 (b :#: (a -> FamInj1 c b)) b)
-                         (FamInj1 (b :#: (a' -> FamInj1 c' b)) b)
+                         (FamInj1 (b' :#: (a' -> FamInj1 c' b')) b')
 checkFamRec7Thing = #thing
 
 data FamRec a = FamRec
@@ -687,6 +703,13 @@
   data Quark2 a = Qualified2   { gaffer2 :: a }
                 | Unqualified2 { gaffer2 :: a, tape2 :: a }
   |]
+makePrismLabels ''Quark2 -- after declareFieldLabels
+
+checkQualified2 :: Prism' (Quark2 a) a
+checkQualified2 = #_Qualified2
+
+checkUnqualified2 :: Prism' (Quark2 a) (a, a)
+checkUnqualified2 = #_Unqualified2
 
 checkGaffer2 :: Lens' (Quark2 a) a
 checkGaffer2 = #gaffer2
@@ -781,6 +804,24 @@
 checkCoffee :: Iso' (Associated Double) Double
 checkCoffee = #coffee
 
+declareFieldLabels
+  [d| data User a = User
+        { user_name :: Name -- local type
+        , user_age  :: a
+        }
+
+      newtype Name = Name { name_unwrap :: String }
+    |]
+
+checkUserName :: Lens' (User a) Name
+checkUserName = #user_name
+
+checkUserAge :: Lens (User a) (User b) a b
+checkUserAge = #user_age
+
+checkNameUnwrap :: Iso' Name String
+checkNameUnwrap = #name_unwrap
+
 declareFields [d|
   data DeclaredFields f a
     = DeclaredField1 { declaredFieldsA0 :: f a    , declaredFieldsB0 :: Int }
@@ -824,26 +865,35 @@
   | C2 { _r2length :: forall a. [a] -> Int }
 
 makeLenses ''Rank2Tests
-makeFieldLabelsWith lensRules ''Rank2Tests -- doesn't generate anything
+makeFieldLabelsWith lensRules ''Rank2Tests
 
 checkR2length :: Getter Rank2Tests ([a] -> Int)
 checkR2length = r2length
 
+checkR2length_ :: Getter Rank2Tests ([a] -> Int)
+checkR2length_ = #r2length
+
 checkR2nub :: Eq a => AffineFold Rank2Tests ([a] -> [a])
 checkR2nub = r2nub
 
+checkR2nub_ :: Eq a => AffineFold Rank2Tests ([a] -> [a])
+checkR2nub_ = #r2nub
+
 data PureNoFields = PureNoFieldsA | PureNoFieldsB { _pureNoFields :: Int }
 makeLenses ''PureNoFields
 makeFieldLabels ''PureNoFields
 
-data ReviewTest where
-  ReviewTest :: (Typeable a, Typeable b) => a -> b -> ReviewTest
+data ReviewTest k where
+  ReviewTest :: Typeable t => t -> Proxy (a :: k) -> ReviewTest k
 makePrisms ''ReviewTest
-makePrismLabels ''ReviewTest -- doesn't generate anything
+makePrismLabels ''ReviewTest
 
-checkReviewTest :: (Typeable a, Typeable b) => Review ReviewTest (a, b)
+checkReviewTest :: Typeable t => Review (ReviewTest k) (t, Proxy (a :: k))
 checkReviewTest = _ReviewTest
 
+checkReviewTest_ :: Typeable t => Review (ReviewTest k) (t, Proxy (a :: k))
+checkReviewTest_ = #_ReviewTest
+
 -- test FieldNamers
 
 data CheckUnderscoreNoPrefixNamer = CheckUnderscoreNoPrefixNamer

Reply via email to