-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
x/tools/gopls: file corruption on case-insensitive filesystems #57081
Comments
Hi, I'm not aware of anything in the extension or language server that would cause the behavior you describe. I'm not saying it's impossible, but given the frequency with which you describe encountering this problem, it seems likely that there is something else going on (perhaps a bad interaction with another extension?). If you are able to reliably repro, we would be very interested to get to the bottom of this. The easiest way for us to see what is going on is to look at LSP logs, which you can collect as described here: Could you try to collect those logs for a minimal repro? |
Seems like the issue is occurring due to this extension itself, as I disabled all other extensions and this still occurs. You can view the logs here. EDIT: This is only occurring with one file, as all other files don't seem to face this. Even tried creating a new VSCode workspace to try and troubleshoot but does not seem to make any difference. This is the exact file. |
Aha, I stared at this for a bit and believe that I have found a likely related issue. Look at these two logs:
I noticed that we apparently have two different representations for this file: one with a capital 'S' for 'Server', and another with a lower-case 's' for 'server'. It looks like the 'didChangeWatchedFile' notification (arriving from the file watcher) has a lower-case 's', but notifications related to the open file have upper-case 'S'. Clearly gopls is confused about the identity of this file, because it sent different diagnostics for the two files. I'm not yet sure how this causes the corruption you observe, but it seems likely that either the editor is confused about file identity, gopls is confused, or both. Can you tell me more about your environment? What does the filesystem say about this path? Do you know where the capital 'S' originated? I'll do more digging to try to understand how this could cause problems in gopls. |
It would also be incredibly helpful if you could include a full set of logs for a session that repros the problem, starting from the beginning. That would let us see when and how the two different casings were communicated. |
Hi, I believe I understand this now. The key is in the following logs:
These show that gopls got a request for But it looks like content invalidation does not canonicalize URIs. So a didOpen or didChange of the same URI will NOT invalidate on-disk contents inside of gopls. This is simply a bug. In other words, I think the bug goes as follows:
Now to find a case-insensitive filesystem to reproduce... |
This seems correct. I did a bit of digging too, and attempted to copy and paste the contents of the file into another. This does not repro the issue, but if I directly copy the file itself (and not just its contents), the issue does reoccur, no matter where I store it. |
I created a new workspace in the same folder and opened the |
Thanks, while we haven't yet reproduced locally, I think we have enough information about the nature of the bug. I have transferred this to the Go issue tracker. |
@findleyr Any updates? |
@CompeyDev unfortunately this is going to take a little while to fix. We have ideas, but it is a rather low level bug. We will try to fix this for the next minor release, which is slated for ~February, but there is no guarantee. |
Understood, is there at least a way I can mitigate this? It is quite disruptive at the moment. |
@CompeyDev sorry for missing your last comment. If you can get your editor to agree about file casing that would avoid the problem. I'm working on a fix now, but as I said it will not arrive this month. I will ping here when there is something ready for testing. |
How exactly can I achieve this in VSCode? I'm not really sure what kind of casing VSCode on Windows follows. |
Change https://go.dev/cl/462819 mentions this issue: |
Sorry, I'm not sure why VS Code is choosing a different spelling of this file. The CL above (not yet submitted) fixes the file corruption, but there is more work yet as other features won't work in this file: we need to identify that this is the same file as returned to us from the |
Fix the bug that gopls finds the wrong content when formatting an open URI whose spelling does not match the spelling on disk (i.e. because of case insensitivity). Remove the whole View.filesByBase mechanism: it is problematic as we can't generally know whether or not we want to associate two different spellings of the same file: for the purposes of finding packages we may want to treat Foo.go as foo.go, but we don't want to treat a symlink of foo.go in another directory the same. Instead, use robustio.FileID to de-duplicate content in the cache, and otherwise treat URIs as we receive them. This fixes the formatting corruption, but means that we don't find packages for the corresponding file (because go/packages.Load("file=foo.go") fails). A failing test is added for the latter bug. Also: use a seenFiles map in the view to satisfy the concern of tracking relevant files, with a TODO to delete this problematic map. Along the way, refactor somewhat to separate and normalize the implementations of source.FileSource. For golang/go#57081 Change-Id: I02971a1702f057b644fa18a873790e8f0d98a323 Reviewed-on: https://go-review.googlesource.com/c/tools/+/462819 gopls-CI: kokoro <noreply+kokoro@google.com> Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Alan Donovan <adonovan@google.com>
Heya, it's been a while now - any new updates, @findleyr? |
@CompeyDev sorry, missed your ping. We have been busy with the v0.12.0 release, but this is one of the largest issues we hope to fix for v0.13.0, as we believe it is the largest outstanding gopls bug. |
Alright, as for now I've switched my environment to Linux & everything seems to work as expected. Thanks for the update! |
I am facing the same issue right now... can i at least somehow restart/clear gopls completely so it stops doing it? it happened when i renamed User.go to user.go on windows... I guess it has User.go stored somewhere, so some sort of clearing would help, how do i do that? edit clearing c:/Users/%USER%/AppData/Local/gopls/ helped |
@alesji are you experiencing corruption, or just a broken LSP server? Your files should no longer be corrupted. |
What version of Go, VS Code & VS Code Go extension are you using?
Version Information
go version
to get version of Go from the VS Code integrated terminal.gopls -v version
to get version of Gopls from the VS Code integrated terminal.code -v
orcode-insiders -v
to get version of VS Code or VS Code Insiders.Go: Locate Configured Go Tools
command.Share the Go related settings you have added/edited
None, all default.
Describe the bug
The lint process of the extension is extremely bugged, and ends up deleting random bunches of code. If you save it during this process, the file's contents get discarded entirely.
Steps to reproduce the behavior:
Screenshots or recordings
Following are screenshots of before and after saving a file with changes made. Notice how the
fmt.Sprint(instanceCheckingErr)
I added magically disappears once saved.Before:
After:
The text was updated successfully, but these errors were encountered: