Skip to content

Option to use the rustup-provided proc-macro-srv #12855

Closed
@fasterthanlime

Description

@fasterthanlime

Since RA as a subtree looks like it's gonna land soon, I'm looking at next steps.

I'm already happily using it locally with a rust-toolchain of:

[toolchain]
channel = "nightly-2022-07-23"

Having installed RA like so:

cargo +nightly-2022-07-23 install --path crates/rust-analyzer --locked --force --features force-always-assert --features proc-macro-srv/sysroot-abi

And having VSCode workspace settings (.vscode/settings.json) of:

{
  "rust-analyzer.server.path": "rust-analyzer"
}

This is very close to something I can tell others to do.

The issue is, as soon as "RA as a subtree" lands and that we have the "rust-analyzer proc-macro always works with the rustc from the same toolchain+channel" guarantee, what I want instead is this:

{
  "rust-analyzer.procMacro.server": "/home/amos/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu/bin/rust-analyzer"
}

There's several issues with that:

  • It doesn't even work as-is: rust-analyzer.procMacro.server wants a path relative to the workspace for some reason, so the actual path it tries to execute is /home/amos/bearcove/some-project/home/amos/.rustup/...
  • I obviously can't commit an absolute path starting with /home/amos to a shared Git repository
  • Having to re-state the channel here when it's in rust-toolchain.toml already is.. not very DRY. rust-analyzer already has code to discover the toolchain / various tools, I'd expect it to do the right thing here too.

But what is the right thing?

The dream scenario

In my dreams, when expanding a proc-macro, rust-analyzer:

  • Finds out which toolchain it's been compiled with
  • If it's provided by rustup, it adds the rust-analyzer component as needed
  • Then it spawns that toolchain's rust-analyzer proc-macro subcommand and uses that, for this proc macro
  • Repeat with any proc macros that need expanding (which may spawn several toolchains, if different cargo workspaces are opened in the same vscode window)

There's a bunch of moving pieces there - I don't know how hard the current codebase assumes that we have "a single proc-macro-srv binary" (and then that binary is responsible for handling all possible ABIs).

The short-term win

Because this is all relatively new, we might not want to mess with defaults just yet. Instead, we could add another option, say maybe:

  "rust-analyzer.procMacro.serverFromRustup": true

Under the hood, this executes rustup which rust-analyzer at the top of the workspace:

❯ rustup +nightly-2022-07-23 which rust-analyzer
/home/amos/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu/bin/rust-analyzer

And attempts rustup component add rust-analyzer once if that fails.

One alternative is to have a special value for rust-analyzer.procMacro.server that's just the "rustup" string, but using an in-band value / picking "rustup" as a niche feels odd.

The downside of having an option like rust-analyzer.procMacro.serverFromRustup is that we need to decide if it takes precedence over rust-analyzer.procMacro.server (I think it should).

Later on, if we're happy with that behavior, we can change the default to true (and folks can still opt out of it by setting it to false explicitly).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions