Skip to content

the syntax highlighting of a field name used as a function and a field used with -XOverloadedRecordDot should look the same #4501

Open
@MangoIV

Description

@MangoIV
Contributor

Is your enhancement request related to a problem? Please describe.

  • for some reason, fields when used as functions get highlighted as fields, but when used as accessors using overloaded record dot, get highlighted as functions

Describe the solution you'd like

  • both get highlighted as record accessors (distinct from function highlighting)

Describe alternatives you've considered

n/a

Additional context

  • I'm using semantic highlighting

Activity

soulomoon

soulomoon commented on Feb 17, 2025

@soulomoon
Collaborator

Should be related to how hie present the node. I'll take a look.

soulomoon

soulomoon commented on Feb 17, 2025

@soulomoon
Collaborator

For

{-# LANGUAGE OverloadedRecordDot #-}

module Hello where

data Foo = Foo { foo :: Int }

myFoo = Foo { foo = 1 }

main :: IO ()
main = do
    let x = myFoo.foo
    print x

The related HieAst node does not show information about .foo.

              Node@hello.hs:11:9: Source: From source
                                  {(annotations: {}),  (types: []), 
                                   (identifier info: {(name x,  Details:  Just 0 {LHS of a match group,
                                                                                  regular value bound with scope: LocalScope hello.hs:(11,9)-(12,11) bound at: hello.hs:11:9-21})})}
                                  
              Node@hello.hs:11:11-21: Source: From source
                                      {(annotations: {(GRHS, GRHS)}),  (types: []), 
                                       (identifier info: {})}
                                      
                Node@hello.hs:11:13-21: Source: From source
                                        {(annotations: {(HsApp, HsExpr), (XExpr, HsExpr)}), 
                                         (types: [0]),  (identifier info: {})}
                                        
                  Node@hello.hs:11:13-17: Source: From source
                                          {(annotations: {(HsVar, HsExpr)}),  (types: [2]), 
                                           (identifier info: {(name myFoo,  Details:  Just 2 {usage})})}

But for typechecked source, the FieldLabelString is there. likely it does not convert to the node in hieast

                                                (XExpr
                                                 (ExpandedThingTc
                                                  (OrigExpr
                                                   (HsGetField
                                                    (NoExtField)
                                                    (L
                                                     (EpAnn
                                                      (EpaSpan { hello.hs:11:13-17 })
                                                      (AnnListItem
                                                       [])
                                                      (EpaComments
                                                       []))
                                                     (HsVar
                                                      (NoExtField)
                                                      (L
                                                       (EpAnn
                                                        (EpaSpan { hello.hs:11:13-17 })
                                                        (NameAnnTrailing
                                                         [])
                                                        (EpaComments
                                                         []))
                                                       {Name: myFoo})))
                                                    (L
                                                     (EpAnn
                                                      (EpaSpan { hello.hs:11:18-21 })
                                                      (NoEpAnns)
                                                      (EpaComments
                                                       []))
                                                     (DotFieldOcc
                                                      (AnnFieldLabel
                                                       (Just
                                                        (EpaSpan { hello.hs:11:18 })))
                                                      (L
                                                       (EpAnn
                                                        (EpaSpan { hello.hs:11:19-21 })
                                                        (NameAnnTrailing
                                                         [])
                                                        (EpaComments
                                                         []))
                                                       (FieldLabelString
                                                        {FastString: "foo"}))))))
soulomoon

soulomoon commented on Feb 17, 2025

@soulomoon
Collaborator

To fix this, we need to modify the hieast generation in ghc. More specifically at ghc source code.
We can see the OrigExpr is omited all togather.
I would be helpful to see Note [Overview of record dot syntax]

================ update ===========

After looking into the ghc code, I think it might not be easy. The main problem is the ".foo" remains to be just FieldLabelString in the artifact ghc generated and does not resolve to the actual field Name.

For overloadedDot, ghc make a serious of trasformation from the source code through HasField type class,
And the field existency checking occur in the solver during typechecking through matchGlobalInst.
But it does not add (a reference to the actual field) in typecheckedSource nor renamedSource for us to relate the FieldLabelString back to the actual field Name.

Possible solutions:

  1. update the GHC TTG with this additional bit of information, maybe add it back when renaming.
  2. A possible easier ad-hoc workaround after the landing of new entity map in the HieFile,
    That is to assign a new name in the generation of HieAst and add it as a field Entity in the entity map just for the sake of semantic highlighting. But we would still be lacking the type information and jump over feature a like for this symbol.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    component: semantic-tokenstype: bugSomething isn't right: doesn't work as intended, documentation is missing/outdated, etc..type: enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @soulomoon@MangoIV

      Issue actions

        the syntax highlighting of a field name used as a function and a field used with `-XOverloadedRecordDot` should look the same · Issue #4501 · haskell/haskell-language-server