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

Incorrect textDocument/rename response when multiple edits on same document. #4901

Closed
martskins opened this issue Jun 15, 2020 · 10 comments · Fixed by #7251
Closed

Incorrect textDocument/rename response when multiple edits on same document. #4901

martskins opened this issue Jun 15, 2020 · 10 comments · Fixed by #7251
Labels
E-has-instructions Issue has some instructions and pointers to code to get started E-medium

Comments

@martskins
Copy link
Contributor

I just noticed that when issuing a textDocument/rename request on a file that has N occurrences of the symbol to be renamed, rust-analyzer replies with N TextDocumentEdits with a single TextEdit in it, whereas other servers reply with a single TextDocumentEdit with N TextEdits.

A TextDocumentEdit describes all changes on a version Si and after they are applied move the document to version Si+1.

This, according to the specification (above), seems incorrect to me, as applying a TextDocumentEdit effectively changes the version of the document, and any subsequent applies to the older version are potentially not valid anymore. More importantly it states that a TextDocumentEdit describes all changes on a version.

This is affecting LanguageClient-neovim right now, as filed in autozimu/LanguageClient-neovim#1055, when there are two occurrences of that symbol in the same line. If the leftmost edit is applied first, then the range for the rightmost edit is invalid, as the document has changed. When all the edits for a document are listed in a single TextDocumentEdit, LanguageClient-neovim sorts those edits by character and applies them from right to left, but given the current response this is not possible, as there is a single edit for each text document (except all text documents are really the same).

For what it's worth, we could potentially fix this in LanguageClient-neovim by grouping the TextDocumentEdits by text document URI, but I feel like this is just a misinterpretation of the specification.

@memoryruins
Copy link
Contributor

I'm also able to recreate the issue with coc-rust-analyzer --

ra-rename

rust-analyzer 017331a

@lnicola
Copy link
Member

lnicola commented Jun 16, 2020

CC #4831.

@matklad
Copy link
Member

matklad commented Jun 16, 2020

Hm, yup, that's definitely a bug, and I think even the design one. The fix is to change find_usages API to return references, groupped by the file:

https://github.com/rust-analyzer/rust-analyzer/blob/83a16e825da2767aaee1d62447eb94f4d7de8881/crates/ra_ide_db/src/search.rs#L181-L185

Ie, I'd imagine something like:

struct FileReferences {
  file_id: FIleId,
  refs: Vec<FileReference> // stores only `TextRange`
}

After this refactor, changing all the call-sites should should automagicaly fix all the issues (I belive we have a similar problem in the new extract enum variant assist).

@kjeremy
Copy link
Contributor

kjeremy commented Aug 31, 2020

I don't think this is quite true anymore. SourceChange still traffics in SourceFileEdits. Maybe SourceChange should keep it's edits in a map by FileId as well.

@koopa1338
Copy link

Im not sure if I have a similar issue. I'm using neovim lsp and tried to rename a variable that has multiple occurences in the same file but getting an error like buffer <filepath> newer than edits. I also tried this with a python language server, where it works as expected.
I've looked into the response from the servers:

  • python groups the edits in one documentChange by file uri and version
  • rust-analyzer has individual documentChanges per occurence with the same version

I've changed many settings in my vim config but with the same results and as it works with other languages, this might seem an issue in the rust-analyzer.

used:

  • NVIM v0.5.0-681-g7ba28b1ae
  • rust-analyzer latest commit

@sharksforarms
Copy link
Contributor

Im not sure if I have a similar issue. I'm using neovim lsp and tried to rename a variable that has multiple occurences in the same file but getting an error like buffer <filepath> newer than edits.

@koopa1338, see neovim/neovim#12970

@Xuyuanp
Copy link

Xuyuanp commented Sep 24, 2020

@martskins
Copy link
Contributor Author

It has been a while since the suggestion for how to fix this was given, do you still think that's the way to go here?

@matklad
Copy link
Member

matklad commented Dec 10, 2020

@martskins yup, I still think that it makes sense to first refactor the reference search API to return results grouped per file. The relevatn entry point is FindUsages::all method now.

@matklad
Copy link
Member

matklad commented Dec 24, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E-has-instructions Issue has some instructions and pointers to code to get started E-medium
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants