Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

rust-analyzer initializes again when jumping to code outside of current workspace #421

Open
GuillaumeLagrange opened this issue Sep 4, 2023 · 7 comments

Comments

@GuillaumeLagrange
Copy link

Hello,

Whenever I am jumping to definition outside of current workspace, rust-analyzer seems to start a new instance on the jumped file's location, while leaving the current instance hanging until it has started.

This is an issue because rust-analyzer is extremely slow to start on large code bases, and I sometimes lose the LSP for ~1 minute.

It happens when I jump to definition of something in std (Default, or Vec for example), or whenever I jump to a dependency (inside or outside my monorepo workspace)

In VSCode, I do not have the issue. I am not sure how to troubleshoot the problem, maybe I am missing some config file ?

Is it possible to have RA run as single file mode for any code that is outside the scope of the initial root directory ?
Or to blacklist some paths (std lib and cargo deps mainly) and prevent them from starting a full steam rust-analyzer ?

@NicolasGB
Copy link

Yeah i noticed the same, Even when setting the LSP to standalone=true, it launches a full new instance. I don't know either if its lsp or plugin related issue, but if you say that this does not happen with VSCode i guess it's the plugin?

@mrcjkb
Copy link

mrcjkb commented Oct 22, 2023

I can't reproduce this with jump-to-definition (using my fork), but it does happen when I'm in a project with multiple subpackages, and I open files from more than one of them.
I think that is because the plugin searches upward for the first directory containing a Cargo.toml, and uses that as the workspace root.

@mrcjkb
Copy link

mrcjkb commented Oct 22, 2023

So, the solution in my fork was to call workspace/didChangeWorkspaceFolders.

This plugin uses lspconfig, which should call that method, too. But it also supports a "standalone" client that doesn't use lspconfig.

Also, support for it in rust-analyzer is fairly recent (since February, see rust-lang/rust-analyzer#14098).
Maybe the version you're using with Neovim is an older one?

@GuillaumeLagrange
Copy link
Author

Thanks for your input.

lspconfig indeed seems to send the didChangeWorkspaceFolders and it adds the new folder ot the workspaces, as shown by

lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))

{ "/home/guillaume/${initialWorkspace}", "/home/guillaume/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc" }

The behavior I find irritating is therefore not a restart, but a sort of unresponsiveness after this for a short while.
rust-analyzer seems to re initialize, and tries to build all proc macros and re indexes everything. It is especially weird since adding a package from the monorepo cargo workspace does not trigger this, it just addes the new package as a lsp workspace folder and does not trigger re-indexing and rebuilding proc macros whatsoever.

It is not really noticeable on small repos, but on large monorepos with tons of packages, it takes a good minute to be operational again, which painful.

Disabling cachePriming in rust-analyzer shortens this time, but does not make it disappear.

I will try with your plugin when I get some time, maybe reducing the number of actors in play by getting rid of lspconfig could help troubleshoot. Thanks anyway for trying to help ❤️

For anyone interested, my current workaround is preventing ra to start whenever a new workspace is to be added and its root contains a path that looks like a dependency

if string.find(new_root_dir, ".cargo/") or string.find(new_root_dir, ".rustup/toolchain") then
    return nil
end

It is not clean and I use a fork of a plugin used for local config to do so (neoconf), but it works on my machine️️ ™️

@GuillaumeLagrange GuillaumeLagrange changed the title rust-analyzer restarts when jumping to code outside of current workspace rust-analyzer initializes again when jumping to code outside of current workspace Oct 23, 2023
@mrcjkb
Copy link

mrcjkb commented Oct 23, 2023

rust-analyzer seems to re initialize, and tries to build all proc macros and re indexes everything.

Interesting 🤔.

I don't have a second rust-analyzer process spawning, but it does spawn a second rust-analyzer-proc-macro-srv (but there's only one LSP client in Neovim).

rust-analyzer-proc-macro-srv

And you say this doesn't happen in VSCode?
Maybe there's a server configuration option...

For anyone interested, my current workaround is preventing ra to start whenever a new workspace is to be added and its root contains a path that looks like a dependency

This might also work if you set rust-analyzer.files.excludeDirs.
In rust-tools, that would be the server["rust-analyzer"].files.excludeDirs config.

@mrcjkb
Copy link

mrcjkb commented Oct 23, 2023

Ha!

> rust-analyzer --help
# <...>
rust-analyzer diagnostics

  ARGS:
    <path>
      Directory with Cargo.toml.

  OPTIONS:
    --disable-build-scripts
      Don't run build scripts or load `OUT_DIR` values by running `cargo check` before analysis.

    --disable-proc-macros
      Don't use expand proc macros.

    --proc-macro-srv <path>
      Run a custom proc-macro-srv binary.

... maybe we're onto something.

Update:

I have tried

  server = {
    ['rust-analyzer'] = {
      procMacro = {
        enable = false,
      },
    },
  },

to no avail 😞

@GuillaumeLagrange
Copy link
Author

I will try and bisect the exact differences between rust analyzer behavior in vs code and nvim for this and will update if I find anything significant.

In the meantime, preventing ra from spawning in dependencies/std has been wroking fine for a few weeks with very few downsides

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants