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

Avoid parse error occurred when the field name generated by TH matches any of Haskell keywords #1476

Merged
merged 6 commits into from Mar 3, 2023

Conversation

ccycle
Copy link
Contributor

@ccycle ccycle commented Mar 2, 2023

To avoid the problem that GHC fails compiling due to parse error when the field name generated by Template Haskell matches any of Haskell keywords, this PR fixes mkRecordName to suffix _ if the field name matches any of keywords.

Before submitting your PR, check that you've:

  • Documented new APIs with Haddock markup
  • Added @since declarations to the Haddock
  • Ran stylish-haskell on any changed files.
  • Adhered to the code style (see the .editorconfig file for details)

After submitting your PR:

  • Update the Changelog.md file with a link to your PR
  • Bumped the version number if there isn't an (unreleased) on the Changelog
  • Check that CI passes (or if it fails, for reasons unrelated to your change, like CI timeouts)

Copy link
Collaborator

@parsonsmatt parsonsmatt left a comment

Choose a reason for hiding this comment

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

Thanks for writing this up! One minor performance quibble.

At a future point, it would be nice to customize this behavior.

Since anyone writing type as a field name currently will receive GHC error, I think we can safely call this a bugfix. Mind doing a patch version bump and adding a changelog notice?

Comment on lines 3119 to 3127
avoidKeyword name = if name `elem` keywords then name ++ "_" else name

keywords :: [Text]
keywords =
["case","class","data","default","deriving","do","else"
,"if","import","in","infix","infixl","infixr","instance","let","module"
,"newtype","of","then","type","where","_"
,"foreign"
]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Lots of list lookups like this is pretty inefficient - would prefer to see a Set lookup

Suggested change
avoidKeyword name = if name `elem` keywords then name ++ "_" else name
keywords :: [Text]
keywords =
["case","class","data","default","deriving","do","else"
,"if","import","in","infix","infixl","infixr","instance","let","module"
,"newtype","of","then","type","where","_"
,"foreign"
]
avoidKeyword name = if name `Set.member` haskellKeywords then name ++ "_" else name
haskellKeywords :: Set Text
haskellKeywords = Set.fromList
["case","class","data","default","deriving","do","else"
,"if","import","in","infix","infixl","infixr","instance","let","module"
,"newtype","of","then","type","where","_"
,"foreign"
]

Floating it to the top-level ensures we aren't constructing the Set for each call to mkRecordName, though I would guess GHC is capable of performing that optimization on it's own

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for your review, I changed the suggested part and added a notice to bump up a patch version in ChangeLog.

Copy link
Collaborator

@parsonsmatt parsonsmatt left a comment

Choose a reason for hiding this comment

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

awesome, thanks! I'll release this today.

@parsonsmatt parsonsmatt merged commit 23773f2 into yesodweb:master Mar 3, 2023
7 checks passed
@ccycle ccycle deleted the fix-mkRecordName branch March 13, 2023 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants