diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,7 @@
+4.0.4
+-----
+* Made `declareFields` work again.
+
 4.0.3
 -----
 * Fixed random segfaulting when using `foldMapBy`.
@@ -25,7 +29,7 @@
   * Replaced the use of `Mutator` with `Identity`.
   * Replaced the use of `Reviewed` with `Tagged`.
 * Removed the deprecated `Control.Lens.Simple` module.
-* Repurposed `Control.Lens.Combinators` to reëxport `Control.Lens` sans any operators; previous residents rehomed to `Control.Lens.Lens`.
+* Repurposed `Control.Lens.Combinators` to re-export `Control.Lens` sans any operators; previous residents rehomed to `Control.Lens.Lens`.
 * Added `Control.Lens.Operators` to export just the operators. Varying your import styles between these supports many qualified usage scenarios.
 * Simplified `Cons` and `Snoc`. Now they must be a `Prism`.
 * Simplified `Contains`. This necessitated losing many instancs of `Contains`, but makes it much easier and more consistent to use and instantiate.
diff --git a/lens.cabal b/lens.cabal
--- a/lens.cabal
+++ b/lens.cabal
@@ -1,6 +1,6 @@
 name:          lens
 category:      Data, Lenses, Generics
-version:       4.0.3
+version:       4.0.4
 license:       BSD3
 cabal-version: >= 1.8
 license-file:  LICENSE
@@ -71,7 +71,7 @@
   > bar :: Functor f => (Int -> f Int) -> Foo a -> f (Foo a)
   > bar f (Foo a b c) = fmap (\a' -> Foo a' b c) (f a)
   .
-  > -- baz :: Lens (Foo a) (Foo b) a b
+  > -- quux :: Lens (Foo a) (Foo b) a b
   > quux :: Functor f => (a -> f b) -> Foo a -> f (Foo b)
   > quux f (Foo a b c) = fmap (Foo a b) (f c)
   .
diff --git a/src/Control/Lens/TH.hs b/src/Control/Lens/TH.hs
--- a/src/Control/Lens/TH.hs
+++ b/src/Control/Lens/TH.hs
@@ -28,7 +28,7 @@
   , makePrisms
   , makeWrapped
   , makeFields
-  -- * Constructing Lenses Given a Declaretion Quote
+  -- * Constructing Lenses Given a Declaration Quote
   , declareLenses, declareLensesFor
   , declareClassy, declareClassyFor
   , declareIso
@@ -1154,6 +1154,7 @@
     , _fieldLensName      :: Name
     , _fieldClassName     :: Name
     , _fieldClassLensName :: Name
+    , _fieldNameType      :: Type
     }
 
 overHead :: (a -> a) -> [a] -> [a]
@@ -1197,11 +1198,10 @@
 
 
 collectRecords :: [Con] -> [VarStrictType]
-collectRecords cons = rs
+collectRecords cons = nubBy varEq allRecordFields
   where
-    recs = filter (\r -> case r of RecC{} -> True; _ -> False) cons
-    rs' = List.concatMap (\(RecC _ _rs) -> _rs) recs
-    rs = nubBy ((==) `on` (^._1)) rs'
+    varEq (name1,_,_) (name2,_,_) = name1 == name2
+    allRecordFields = [ field | RecC _ fields <- cons , field <- fields ]
 
 verboseLenses :: FieldRules -> Dec -> Q [Dec]
 verboseLenses c decl = do
@@ -1214,7 +1214,7 @@
     then fail "verboseLenses: Expected the name of a record type"
     else flip makeLenses' decl
             $ mkFields c rs
-            & map (\(Field n _ l _ _) -> (show n, show l))
+            & map (\(Field n _ l _ _ _) -> (show n, show l))
   where
     makeLenses' fields' =
         makeLensesForDec $ lensRules
@@ -1224,20 +1224,21 @@
 
 mkFields :: FieldRules -> [VarStrictType] -> [Field]
 mkFields (FieldRules prefix' raw' nice' clas') rs
-    = Maybe.mapMaybe namer fields
+    = Maybe.mapMaybe namer fieldNamesAndTypes
     & List.groupBy (on (==) _fieldLensPrefix)
     & (\ gs -> case gs of
         x:_ -> x
         _   -> [])
   where
-    fields = map (nameBase . fst3) rs
-    fst3 (x,_,_) = x
-    namer field = do
+    fieldNamesAndTypes = [(nameBase n, t) | (n,_,t) <- rs]
+    fieldNames = map fst fieldNamesAndTypes
+
+    namer (field, fieldType) = do
         let rawlens = mkName (raw' field)
-        prefix <- prefix' fields field
+        prefix <- prefix' fieldNames field
         nice   <- mkName <$> nice' field
         clas   <- mkName <$> clas' field
-        return (Field (mkName field) prefix rawlens clas nice)
+        return (Field (mkName field) prefix rawlens clas nice fieldType)
 
 hasClassAndInstance :: FieldRules -> Dec -> Q [Dec]
 hasClassAndInstance cfg decl = do
@@ -1249,19 +1250,13 @@
     let rs = collectRecords $ constructors dataDecl
     when (List.null rs) $
       fail "hasClassAndInstance: Expected the name of a record type"
-    fmap concat . forM (mkFields cfg rs) $ \(Field field _ fullLensName className lensName) -> do
+    fmap concat . forM (mkFields cfg rs) $ \(Field _ _ fullLensName className lensName fieldType) -> do
         classHas <- classD
             (return [])
             className
             [ PlainTV c, PlainTV e ]
             [ FunDep [c] [e] ]
             [ sigD lensName (conT ''Lens' `appsT` [varT c, varT e])]
-        fieldType <- do
-            VarI _ t _ _ <- reify field
-            case t of
-                AppT    _    fieldType          -> return fieldType
-                ForallT _ [] (AppT _ fieldType) -> return fieldType
-                _                               -> error "Cannot get fieldType"
         instanceHas <- instanceD
             (return [])
             (return $ ConT className `apps`
@@ -1328,7 +1323,7 @@
 defaultFieldRules :: FieldRules
 defaultFieldRules = camelCaseFields
 
--- Declaretion quote stuff
+-- Declaration quote stuff
 
 declareWith :: (Dec -> Declare Dec) -> Q [Dec] -> Q [Dec]
 declareWith fun = (runDeclare . traverseDataAndNewtype fun =<<)
