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

autocompletion results occasionally fail to show if one types too fast #12153

Closed
kevinushey opened this issue May 4, 2022 · 7 comments · Fixed by #12431
Closed

autocompletion results occasionally fail to show if one types too fast #12153

kevinushey opened this issue May 4, 2022 · 7 comments · Fixed by #12431

Comments

@kevinushey
Copy link
Contributor

kevinushey commented May 4, 2022

rust-analyzer version: rust-analyzer version: 5dce1ff 2022-05-02 stable

rustc version: rustc 1.60.0 (7737e0b5c 2022-04-04)

relevant settings: (not sure if anything relevant here?)


The following uses VSCode For example, with the code:

pub fn test() {
  let x = Some(42);
  x.

If you type un quickly (e.g. to trigger completions for unwrap() and friends), on occasion, relevant completion results will fail to show:

Screen.Recording.2022-05-04.at.12.30.34.PM.mov

It's not clear to me if this is an issue in rust-analyzer, VSCode, or something else -- please let me know.


From what I can see in the trace logs, it seems like the language server is receiving a textDocument/didChange notification just after the completion request, and that's causing the language server to give up when producing completion results:

[Trace - 12:37:09 PM] Sending request 'textDocument/completion - (61)'.
Params: {
    "textDocument": {
        "uri": "file:///Users/kevin/rust/walkdir/src/util.rs"
    },
    "position": {
        "line": 28,
        "character": 7
    },
    "context": {
        "triggerKind": 1
    }
}


[Trace - 12:37:09 PM] Sending notification 'textDocument/didChange'.
Params: {
    "textDocument": {
        "uri": "file:///Users/kevin/rust/walkdir/src/util.rs",
        "version": 422
    },
    "contentChanges": [
        {
            "range": {
                "start": {
                    "line": 28,
                    "character": 7
                },
                "end": {
                    "line": 28,
                    "character": 7
                }
            },
            "rangeLength": 0,
            "text": "n"
        }
    ]
}



[Trace - 12:37:09 PM] Received response 'textDocument/completion - (61)' in 3ms. Request failed: content modified (-32801).

I'm not sure what the best option here is, but the user experience is a little unfortunate. Could rust-analyzer provide completion results relevant for x. regardless, and rely on the front-end to filter the completion results as appropriate?

For what it's worth, it seems like the completion results in x.u produced by rust-analyzer include all relevant methods on the x object; not just those with a u prefix. So presumedly, VSCode is responsible for filtering the completion results produced by rust-analyzer anyhow, so it could still feel comfortable producing completion results even if the document were modified after the request was received?


VSCode version:

Version: 1.66.2
Commit: dfd34e8260c270da74b5c2d86d61aee4b6d56977
Date: 2022-04-11T07:47:29.396Z (3 wks ago)
Electron: 17.2.0
Chromium: 98.0.4758.109
Node.js: 16.13.0
V8: 9.8.177.11-electron.0
OS: Darwin arm64 21.4.0
@flodiebold
Copy link
Member

Presumably this is #7560; you could try the settings mentioned in #7560 (comment).

@kevinushey
Copy link
Contributor Author

The suggestions help, but are not a total panacea. For example:

Screen.Recording.2022-05-05.at.10.26.49.AM.mov

That is, if a completion list is already being shown as via a trigger character (.) here, and then the user types quickly after, the completion list may no longer display. Presumedly, this is because "editor.quickSuggestionsDelay" does not apply to completions displayed following a trigger character, or following subsequent completion requests (when the completion list is already displaying).

In this case, I again see that completions were canceled, e.g.

[Trace - 10:31:34 AM] Received response 'textDocument/completion - (1249)' in 10ms. Request failed: content modified (-32801).

Do you know if this is a limitation of rust-analyzer, or is it in VSCode's LSP implementation? (Who is cancelling the request here?)

@lnicola
Copy link
Member

lnicola commented May 6, 2022

Who is cancelling the request here?

We are, there's a related discussion here.

@kevinushey
Copy link
Contributor Author

kevinushey commented May 6, 2022

Is that discussion public? It looks like it just brings me to the set of recent topics. (It's my first time using Zulip; forgive me if I'm missing something)

For this particular context, I think it should be okay to serve the completion request if the only document changes are insertions of "identifier" characters at the cursor position (ie: it looks like the user is typing the name of a method / symbol).

@lnicola
Copy link
Member

lnicola commented May 6, 2022

@kevinushey
Copy link
Contributor Author

Following up from the discussion, some other things to note:

The issue reproduces quite a bit more readily in debug builds of rust-analyzer; presumedly, because the language server is now quite a bit slower. That is, it's a lot easier to modify the document while rust-analyzer is servicing a completion request, and so trigger the behavior described here.

It seems like completions are normally requested on every keystroke -- but only if there isn't already a pending completion request. In other words, the following sequence of events is pretty common:

  1. Perform an action that triggers a completion request,
  2. Type a letter,
  3. The completion request is cancelled,
  4. The completion request is never restarted / retried in response to the user typing.

This gives the following trace:

[Trace - 4:36:31 PM] Sending notification 'textDocument/didChange'.
[Trace - 4:36:31 PM] Sending request 'textDocument/completion - (177)'.
[Trace - 4:36:32 PM] Sending notification 'textDocument/didChange'.
[Trace - 4:36:32 PM] Received response 'textDocument/completion - (177)' in 379ms. Request failed: content modified (-32801).

(Note: sometimes, I also see an interleaving $/cancelRequest as well, but not always?)

The fact that VSCode never asks for new completions following the document modification makes me think (assuming the behavior is intentional) VSCode would've been happy with a response from the original completion request, and expects the language server to handle or recover from the case where there are some interleaving document edits.

@kevinushey
Copy link
Contributor Author

Awesome!! Thank you @Veykril :-)

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 a pull request may close this issue.

3 participants