emacs-lsp / lsp-mode

Emacs client/library for the Language Server Protocol
https://emacs-lsp.github.io/lsp-mode
GNU General Public License v3.0
4.82k stars 895 forks source link

rust-analyzer's `fill_match_arms` code action is very slow #4085

Open hydrobeam opened 1 year ago

hydrobeam commented 1 year ago

Thank you for the bug report

Bug description

In a rust project, executing a code action to fill match arms where the match statement contains lots of subelements is very slow, taking upwards of 10 seconds (or much more, depending on the size of the match expr). This does not correlate with the number of match arms, just the size of the overall match block.

Steps to reproduce

the following snippet can be used to recreate the slowness. Hover the cursor over true and call the Fill match arms code action. The exact contents of the block aren't relevant, just that there's a lot of stuff.

fn main() {
    match true {
        false => {
            let q = 14;
            // this line^ repeated ~600+ times
        }
    }
}

Expected behavior

The change should be instant/near-instant. I checked the speed of the action in vscode and in eglot to make sure it's not because of rust-analyzer itself, and it was an instant action in both.

Which Language Server did you use?

I was using rust-analyzer:

➤ rust-analyzer --version
rust-analyzer 1.72.0-nightly (d59363a 2023-06-01)

OS

Linux

Error callstack

N/A

Anything else?

This probably isn't unique to rust-analyzer's fill_match_arms, but this is just where I happened to catch the bug.

This situation is pretty likely to happen in rust when matching on enums with a large number of variants (e.g. a language's AST).

yyoncho commented 1 year ago

lsp-mode is indenting the snippet using the rust-mode indent function which is slow. I will take a look what we can do.