Skip to content

`OverloadedRecordDot` and `COLUMN`-pragmas don't play nice together

Summary

foo.foo is accepted while foo{-# COLUMN 23 #-}.foo results in a parse error.

This is surprising from a users perspective and can break OverloadedRecordDot with source-to-source transformations / pre-processors (as it does for me).

Steps to reproduce

{-# LANGUAGE NoFieldSelectors #-}
{-# LANGUAGE OverloadedRecordDot #-}

data Foo = Foo { foo :: String }

foo :: Foo
foo = Foo "foo"

main :: IO ()
main = do
  putStrLn foo.foo                        -- works
  putStrLn foo{-# COLUMN 23 #-}.foo       -- parse error

Expected behavior

Both foo.foo and foo{-# COLUMN 23 #-}.foo should be accepted.

Investigation

foo.foo is tokenized to:

[ITvarid "foo", ITproj False, ITvarid "bar"]

However, foo{-# COLUMN 23 #-}.foo is tokenized to:

[ITvarid "foo", ITproj True, ITvarid "bar"]

So from what I understand, even though this manifests as a parse error, the bug is actually in the lexer.

Environment

  • GHC version used: 9.6.0.20230111

Optional:

  • Operating System: Linux
  • System Architecture: x86_64
Edited by Simon Hengel
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information