Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix a name shadowing warning (#1406) #1407

Merged
merged 3 commits into from
Jun 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions persistent/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog for persistent

## 2.14.0.2

* [#1407](https://github.com/yesodweb/persistent/pull/1407)
* Fix a name shadowing warning.

## 2.14.0.1

* [#1392](https://github.com/yesodweb/persistent/pull/1392)
Expand Down
44 changes: 27 additions & 17 deletions persistent/Database/Persist/TH.hs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ import Language.Haskell.TH.Syntax
import Web.HttpApiData (FromHttpApiData(..), ToHttpApiData(..))
import Web.PathPieces (PathPiece(..))

import Database.Persist.Class.PersistEntity
import Database.Persist
import Database.Persist.Class.PersistEntity
import Database.Persist.Quasi
import Database.Persist.Quasi.Internal
import Database.Persist.Sql
Expand Down Expand Up @@ -1462,9 +1462,15 @@ fieldUpd :: Name -- ^ constructor name
-> Exp -- ^ record value
-> Name -- ^ field name to update
-> Exp -- ^ new value
-> Exp
fieldUpd con names record name new = CaseE record
[ Match (RecP con pats) (NormalB body) []]
-> Q Exp
fieldUpd con names record name new = do
pats <-
fmap mconcat $ forM names $ \k -> do
varName <- VarP <$> newName (nameBase k)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, this line is the real fix. By creating a newName, we're guaranteeing that the variable is fresh and uncapturable and isn't shadowing anything.

@fumieval This is one of those tricky things about TemplateHaskell - it's so easy to use and make names that can cause warnings and bugs! I do it all the time and I really ought to write up a lil' how to on the matter.

pure [(k, varName) | k /= name]

pure $ CaseE record
[ Match (RecP con pats) (NormalB body) []]
Comment on lines +1466 to +1473
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the function that was introducing the problem.

where
body = RecConE con
[ if k == name then (name, new) else (k, VarE k)
Expand All @@ -1486,23 +1492,26 @@ mkLensClauses mps entDef genDataType = do
let idClause = normalClause
[conp (keyIdName entDef) []]
(lens' `AppE` getId `AppE` setId)
return $ idClause : if unboundEntitySum entDef
then fmap (toSumClause lens' keyVar valName xName) (getUnboundFieldDefs entDef)
else zipWith (toClause lens' getVal dot keyVar valName xName) (getUnboundFieldDefs entDef) fieldNames
(idClause :) <$> if unboundEntitySum entDef
then pure $ fmap (toSumClause lens' keyVar valName xName) (getUnboundFieldDefs entDef)
else zipWithM (toClause lens' getVal dot keyVar valName xName) (getUnboundFieldDefs entDef) fieldNames
where
fieldNames = fieldDefToRecordName mps entDef <$> getUnboundFieldDefs entDef
toClause lens' getVal dot keyVar valName xName fieldDef fieldName = normalClause
[conp (filterConName mps entDef fieldDef) []]
(lens' `AppE` getter `AppE` setter)
toClause lens' getVal dot keyVar valName xName fieldDef fieldName = do
setter <- mkSetter
pure $ normalClause
[conp (filterConName mps entDef fieldDef) []]
(lens' `AppE` getter `AppE` setter)
where
defName = mkEntityDefName entDef
getter = InfixE (Just $ fieldSel defName fieldName) dot (Just getVal)
setter = LamE
[ conp 'Entity [VarP keyVar, VarP valName]
, VarP xName
]
$ ConE 'Entity `AppE` VarE keyVar
`AppE` fieldUpd defName fieldNames (VarE valName) fieldName (VarE xName)
mkSetter = do
updExpr <- fieldUpd defName fieldNames (VarE valName) fieldName (VarE xName)
pure $ LamE
[ conp 'Entity [VarP keyVar, VarP valName]
, VarP xName
]
$ ConE 'Entity `AppE` VarE keyVar `AppE` updExpr

toSumClause lens' keyVar valName xName fieldDef = normalClause
[conp (filterConName mps entDef fieldDef) []]
Expand Down Expand Up @@ -2167,6 +2176,7 @@ mkLenses mps entityMap ent = fmap mconcat $ forM (getUnboundFieldDefs ent `zip`
t1 `arrow` t2 = ArrowT `AppT` t1 `AppT` t2
vars = mkForallTV fT
: (if mpsGeneric mps then [mkForallTV backend1{-, PlainTV backend2-}] else [])
fieldUpdClause <- fieldUpd (mkEntityDefName ent) fieldNames a fieldName y
return
[ SigD lensName $ ForallT vars [mkClassP ''Functor [VarT fT]] $
(aT `arrow` (VarT fT `AppT` bT)) `arrow`
Expand All @@ -2179,7 +2189,7 @@ mkLenses mps entityMap ent = fmap mconcat $ forM (getUnboundFieldDefs ent `zip`
[ FunD needleN [normalClause [] (fieldSel (mkEntityDefName ent) fieldName `AppE` a)]
, FunD setterN $ return $ normalClause
[VarP yN]
(fieldUpd (mkEntityDefName ent) fieldNames a fieldName y)
fieldUpdClause
]
]
where
Expand Down
2 changes: 1 addition & 1 deletion persistent/persistent.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: persistent
version: 2.14.0.1
version: 2.14.0.2
license: MIT
license-file: LICENSE
author: Michael Snoyman <michael@snoyman.com>
Expand Down
6 changes: 3 additions & 3 deletions persistent/test/Database/Persist/TH/NoFieldSelectorsSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ spec = it "compiles" True

#else

spec :: Spec
spec :: Spec
spec = do
it "only works with GHC 9.2 or greater" $ do
pendingWith "only works with GHC 9.2 or greater"
pendingWith "only works with GHC 9.2 or greater"

#endif
#endif
2 changes: 2 additions & 0 deletions persistent/test/Database/Persist/TH/OverloadedLabelSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

{-# OPTIONS_GHC -Wname-shadowing -Werror=name-shadowing #-}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warning is the 'test' for the feature.


module Database.Persist.TH.OverloadedLabelSpec where

import TemplateTestImports
Expand Down
6 changes: 3 additions & 3 deletions stack.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
resolver: nightly-2022-01-14
resolver: nightly-2022-06-10

packages:
- ./persistent
Expand All @@ -14,7 +14,7 @@ extra-deps:
- lift-type-0.1.0.0
- mysql-0.2.1
- mysql-simple-0.4.7
- aeson-2.0.2.0
# - aeson-2.0.2.0
# https://github.com/yesodweb/shakespeare/pull/260
# https://github.com/commercialhaskell/stackage/issues/6294
- happy-1.20.0
# - happy-1.20.0