rust-lang / rust-analyzer

A Rust compiler front-end for IDEs
https://rust-analyzer.github.io/
Apache License 2.0
14.06k stars 1.56k forks source link

inlay_hint serialization crash #17778

Open kleinesfilmroellchen opened 1 month ago

kleinesfilmroellchen commented 1 month ago

While analyzing cmp, which involves the (traditionally very heavy) bevy crate graph, rust-analyzer seems to consistently crash while (apparently, as far as I can tell) serializing an inlay hint.

Server output ``` thread 'VfsLoader' panicked at crates\vfs-notify\src\lib.rs:82:92: called `Result::unwrap()` on an `Err` value: RecvError stack backtrace: thread 'notify-rs windows loop' panicked at crates\vfs-notify\src\lib.rs:97:64: called `Result::unwrap()` on an `Err` value: "SendError(..)" 0: std::panicking::begin_panic_handler at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\panicking.rs:652 1: core::panicking::panic_fmt at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\panicking.rs:72 2: core::result::unwrap_failed at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\result.rs:1679 3: vfs_notify::NotifyActor::run note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. stack backtrace: thread 'LspServer' panicked at crates\rust-analyzer\src\main_loop.rs:249:38: called `Result::unwrap()` on an `Err` value: RecvError 0: std::panicking::begin_panic_handler at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\panicking.rs:652 1: core::panicking::panic_fmt at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\panicking.rs:72 2: core::result::unwrap_failed at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\result.rs:1679 3: ::handle_event 4: notify::windows::ReadDirectoryChangesServer::run 5: notify::windows::ReadDirectoryChangesServer::run 6: KiUserApcDispatcher 7: NtTestAlert 8: RtlInterlockedPushListSList 9: _chkstk 10: RtlUnwindEx 11: _C_specific_handler 12: _chkstk 13: RtlRaiseException 14: KiUserExceptionDispatcher 15: notify::windows::ReadDirectoryChangesServer::run 16: notify::windows::ReadDirectoryChangesServer::run 17: KiUserApcDispatcher 18: ZwWaitForSingleObject 19: WaitForSingleObjectEx 20: notify::windows::ReadDirectoryChangesServer::run note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. stack backtrace: 0: std::panicking::begin_panic_handler at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\panicking.rs:652 1: core::panicking::panic_fmt at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\panicking.rs:72 2: core::result::unwrap_failed at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\result.rs:1679 3: rust_analyzer::main_loop::::run 4: rust_analyzer::main_loop::main_loop 5: rust_analyzer::run_server note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. thread 'main' panicked at C:\Users\runneradmin\.cargo\registry\src\index.crates.io-6f17d22bba15001f\jod-thread-0.1.2\src\lib.rs:33:22: called `Result::unwrap()` on an `Err` value: Any { .. } stack backtrace: 0: std::panicking::begin_panic_handler at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\panicking.rs:652 1: core::panicking::panic_fmt at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\panicking.rs:72 2: core::result::unwrap_failed at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\result.rs:1679 3: stdx::thread::JoinHandle::join 4: lsp_types::inlay_hint::_::::serialize 5: lsp_types::inlay_hint::_::::serialize note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. ```

The "trace" ends with a few normal notifications received, which do not seem related. The last requested inlay hint was:

[Trace - 12:44:54 PM] Sending request 'textDocument/inlayHint - (13)'.
Params: {
    "textDocument": {
        "uri": "file://cmp/cmp/src/input.rs"
    },
    "range": {
        "start": {
            "line": 0,
            "character": 0
        },
        "end": {
            "line": 100,
            "character": 0
        }
    }
}

However, the same exact crash also happens if I close the corresponding file and the inlay hint is not requested at all. Cleaning the build directory has no effect. This bug appeared suddenly and does not seem to be correlated to either a Rust or rust-analyzer update.

rust-analyzer version: 0.4.2059-standalone (aa00ddcf6 2024-08-02) [c:\Users\%USER%.vscode\extensions\rust-lang.rust-analyzer-0.4.2059-win32-x64\server\rust-analyzer.exe]

rustc version: rustc 1.82.0-nightly (612a33f20 2024-07-29)

editor or extension: VSCode

relevant settings: none as far as I know

repository link (if public, optional): cmp

kleinesfilmroellchen commented 1 month ago

Doesn't happen on rust-analyzer 1.82.0-nightly (612a33f2 2024-07-29), so that might be helpful for bisecting.

Veykril commented 1 month ago

the backtrace funnily enough does not contain the relevant panic message 😅 All the panic messages there are just cascades of channel sender/receiver halfs being dropped (we should clean that up so we exit gracefully when that happens)

kleinesfilmroellchen commented 1 month ago

the backtrace funnily enough does not contain the relevant panic message 😅

I did realize that, and I went looking in all the logs I could find for something more useful, but came up with nothing, so I rather pasted everything the server said.

Veykril commented 1 month ago

What i assume happened is that we panicked while computing diagnostics which will tear down a worker thread currently which then cascades into other channels

yebei199 commented 1 week ago

me too, like this #15957 , this is my code Can reproduce this bug :Request textDocument/inlayHint failed.

use futures::future;
use futures::select;
fn main() {
    let mut a_fut = future::ready(4);
    let mut b_fut = future::ready(6);
    let mut total = 0;

    loop {
        select! {
            a = a_fut => total += a,
            b = b_fut => total += b,
            complete => break,
            default => panic!(), // 该分支永远不会运行,因为 `Future` 会先运行,然后是 `complete`
        };
    }
    assert_eq!(total, 10);
    println!("total = {}", total)
}