rust-analyzer: Typing `let c = '🐰` causes immediate rust-analyzer crash (before I can type the close quote)
Using rust-analyzer 1.65.0 (897e375 2022-11-02) with emacs lsp-mode and rustic.
Open a brand new .rs file and type
pub fn test () {
let c = '🐰
rust-analyzer crashes immediately upon being notified of insertion of the rabbit emoji. If I add the missing close quote and then restart rust-analyzer, it continues running fine. If I type first
pub fn test () {
let c = '';
}
and then go back and insert the rabbit emoji between the quotes, it doesn’t crash.
I have this backtrace in the *rust-analyzer::stderr* buffer:
Panic context:
>
version: 1.65.0 (897e375 2022-11-02)
notification: textDocument/didChange
thread 'LspServer' panicked at 'assertion failed: self.is_char_boundary(n)', /rustc/897e37553bba8b42751c67658967889d11ecd120/library/alloc/src/string.rs:1820:29
stack backtrace:
0: rust_begin_unwind
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:584:5
1: core::panicking::panic_fmt
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/panicking.rs:142:14
2: core::panicking::panic
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/panicking.rs:48:5
3: <alloc::string::String>::replace_range::<core::ops::range::Range<usize>>
4: rust_analyzer::lsp_utils::apply_document_changes
5: <<rust_analyzer::global_state::GlobalState>::on_notification::{closure#3} as core::ops::function::FnOnce<(&mut rust_analyzer::global_state::GlobalState, lsp_types::DidChangeTextDocumentParams)>>::call_once
6: <rust_analyzer::dispatch::NotificationDispatcher>::on::<lsp_types::notification::DidChangeTextDocument>
7: <rust_analyzer::global_state::GlobalState>::handle_event
8: <rust_analyzer::global_state::GlobalState>::run
9: rust_analyzer::main_loop::main_loop
10: rust_analyzer::run_server
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: "SendError(..)"', lib/lsp-server/src/stdio.rs:29:37
stack backtrace:
0: rust_begin_unwind
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/panicking.rs:584:5
1: core::panicking::panic_fmt
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/panicking.rs:142:14
2: core::result::unwrap_failed
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/result.rs:1785:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
rustc version: rustc 1.65.0 (897e37553 2022-11-02)
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 3
- Comments: 29 (19 by maintainers)
I believe vscode shows InvalidParams using an error popup and does not attempt to recover from it in any way. While for crashes it will attempt to restart it and I believe it doesn’t show any popup in that case. It does give an error popup if it crashed 5 times in the last 3 minutes though. Restarting can recover from the error in some cases. Rust-analyzer can’t distinguish between cases where restarting would fix the issue and cases where it doesn’t so choosing the option of crashing unconditionally has the best UX as you don’t have to manually restart rust-analyzer (at least in vscode).
Particular issue at hand should be fixed by this pair of PRs
My earlier comment
was inaccurate. While the fix on the lsp-mode side is indeed a couple of lines, turns out I was wrong that utf8 is native position encoding for Emacs. It seems like it uses utf32 in the end (would appreciate double-checking from anyone more knowlegable in Emacs ways). So, this also required support for utf32 on rust-analyzer side, which the second PR implements.
I still think it is incorrect for rust-analyzer to panic in this case. Panic is exclusively for when your program detects a bug in itself. It should never be used to report anything else. In this case, everyone agrees that emacs lsp-mode sent a bogus protocol message, so the error should be reported in a way that makes it clear that emacs lsp-mode is the program with the bug.
Granted that the lsp protocol is badly designed on multiple levels such that (a) we have this problem in the first place, and (b) there’s no good way to report the error besides terminating the server, that still leaves the possibility of, say,
If you made this change people would at least stop reporting this as a bug in rust-analyzer. (Ideally it would be made everywhere there is currently a panic whose root cause is a protocol error.)