Skip to content

Fix locate in let punnings#2066

Open
panglesd wants to merge 3 commits into
ocaml:mainfrom
panglesd:locate-in-punning
Open

Fix locate in let punnings#2066
panglesd wants to merge 3 commits into
ocaml:mainfrom
panglesd:locate-in-punning

Conversation

@panglesd
Copy link
Copy Markdown
Contributor

This fixes an issue with the locate query reported in #1796.

(Sorry this is quite verbose for such a small PR but it is also here to help me be corrected if I have assumed something wrong)

In a punned let binding, both the pattern and the expression have the same location. None of them is ghost. I think that somehow breaks the assumption that "sibling nodes have disjoint locations".

During a locate query, the first thing is to load the environment at the point of the cursor. The lookup of "nodes at cursor position" will suppose the invariant mentioned above to return a list all nodes the cursor is in (of which we take the first one, the "deepest").

Since two siblings (the pattern and expression) have the same location, the order in which they are considered matter: when the first one is found, we never look at the other siblings, and "enter" it to continue the search.

In the current implementation, patterns are looked first, and we end up with the environment at the pattern to do our "locate". And so, the unhelpful "Already at definition point".

This PR fixes this by folding let operators in a different order, making the expressions side be entered first.

Having the behaviour depend on the order of the fold is slightly brittle, but I think this PR is still fine to solve #1796 without refactoring a huge part to solve a bigger underlying issue ("siblings might have the same location"). But I'm new to the codebase so I might miss something!
(I'm happy to implement a better fix, but then I'd like to discuss with more experienced Merlin disciple first)

panglesd added a commit to panglesd/merlin that referenced this pull request May 11, 2026
Copy link
Copy Markdown
Collaborator

@xvw xvw left a comment

Choose a reason for hiding this comment

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

Neat!

panglesd added 3 commits May 22, 2026 15:53
Include let punnings, named argument punnings and fields punning
Change the order in which we fold the let operators, to give priority to the
expression in the "locate" query
@voodoos voodoos force-pushed the locate-in-punning branch from 22e7942 to 31b48aa Compare May 22, 2026 13:53
Copy link
Copy Markdown
Collaborator

@voodoos voodoos left a comment

Choose a reason for hiding this comment

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

I have mixed feeling because this makes the behavior of occurrences (and maybe other queries? we should think about it!) less intuitive. I do think locate is the most important of them so this is an improvement, just one that is not entirely satisfying.

Comment thread tests/test-dirs/punning.t
> x
> EOF

FIXME: Should locate to the `x` in `f x`, not say that we are at the definition
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is not a fixme anymore, tight ?

Suggested change
FIXME: Should locate to the `x` in `f x`, not say that we are at the definition
Should locate to the `x` in `f x`, not say that we are at the definition

Comment thread tests/test-dirs/punning.t
"col": 6
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Of course this change impacts other queries too, and some might expect the new value to be considered, not the punned one. I can think of occurrences, but maybe others too ?

Fixing Locate at that costs feels like a fair payment, but ideally we could fix one without breaking the other.

Suggested change
FIXME Since #2066 this shows the occurrences of the punned value (lines 3 and
4), not of the pattern (lines 4 and 5). Unlike for the locate query this does
not feel like the more natural choice. We should think of a more flexible fix at
some point.
$ $MERLIN single occurrences -identifier-at 4:7 -filename let_punning.ml < let_punning.ml | jq .value
[
{
"start": {
"line": 3,
"col": 6
},
"end": {
"line": 3,
"col": 7
},
"stale": false
},
{
"start": {
"line": 4,
"col": 7
},
"end": {
"line": 4,
"col": 8
},
"stale": false
}
]

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.

3 participants