-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat: Use oldest rustup rust-analyzer when toolchain override is present #17705
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
editors/code/src/bootstrap.ts
Outdated
}); | ||
if (!res.error && res.status === 0) { | ||
toolchainServerPath = earliestToolchainPath(toolchainServerPath, res.stdout.trim(), function (path) { | ||
const res = spawnSync(path, ["version"], { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it make more sense to query the rustup version for the workspace here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a lambda where the path
comes from within evaluating the toolchain path. It is invoked conditionally depending on the type of path to the RA it is i.e. if the RA isn't pointing to a nightly or stable one, then the path is deemed to be an explicit version of RA. In that instance we'll query its version for a date.
Also, this is a lambda for two reasons:
- other
spawnSync
calls are made within thisgetServer
function; and - so that I can write unit tests easily for
earliestToolchainPath
andorderFromPath
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused, rustup which rust-analyzer
should only yield a rust toolchain version (if installed in the toolchain) or error no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears to yield paths with stable, nightly and [some-version] in them. At least in my workspace. I’ll create some unit tests with sample paths to illustrate as I move forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or may be I don’t understand what you’re asking… if we are talking about the lambda still, that path can be a path to a nightly, stable or versioned RA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see, we can return a manual (non-toolchain component) rust-analyzer install from this. Okay then this handling does make sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or actually, what is being invoked here, path/to/rust-analyzer version
? That wouldn't make sense as that is not valid command for r-a. The flag is --version
. Can you add a comment above that explaining roughly whats being executed for visibility? Also for the regex part a comment showing an example input and what we disassemble that to via the regexes(regices?) would be helpful for readability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely, I’ll get on to some unit tests tomorrow which should make things a bit more obvious Also, the test infra is there already (npm test).
I just wanted to make sure I was on the right track etc. Thanks for the initial review.
@Veykril Can you please direct me to some doco in your to conveniently test our the extension? |
I don't think we can easily test this. We generally don't have a good testing infra setup for the vscode extension unfortunately. |
Sorry, I meant, how do I test this manually and locally? I can see an option to install the VSIX file, but I'm unsure if it updates an existing one. |
OK, this is working, although I think we need to go a bit further... At the moment, the code will identify RA's for each rust-toolchain.toml file found. This isn't exactly what we want though. We should only select an RA with a toolchain if it is explicitly set via |
BTW I figured this out by installing the extension from its VSIX. I realised that |
This PR has now been tested in my environment that has a couple of projects pinned to old toolchains. Having added RA as a component to the relevant toolchain files causes the corresponding version of RA to be used. I can confirm this by using the "show RA version" command. I am getting the following warnings reported and don't quite understand why:
Do we need to do something with the proc-macro server as well? |
Selects a rust-toolchain declared RA based on its date. The earliest (oldest) RA wins and becomes the one that the workspace uses as a whole. In terms of precedence: nightly > stable-with-version > stable With stable-with-version, we invoke the RA with a `--version` arg and attempt to extract a date. Given the same date as a nightly, the nightly RA will win.
export const _private = { | ||
earliestToolchainPath, | ||
orderFromPath, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This appears to be the TS way of "hiding" things that need to be exported purely for testing.
That is a problem we can't work around unfortunately. The problem here is that the rust-analyzer is too old for one of the newer toolchains in the project being used, so it doesn't speak the proc-macro servers protocol anymore. We can't use a different proc-macro server though as it is required for the proc-macro server to built with the same toolchain as the proc-macros that are being loaded. |
Ok. I guess we must live with that then. At least the changes here avoid broken development experiences. |
Regexen, of course 🙃. |
// nightly - /Users/myuser/.rustup/toolchains/nightly-2022-11-22-aarch64-apple-darwin/bin/rust-analyzer | ||
// versioned - /Users/myuser/.rustup/toolchains/1.72.1-aarch64-apple-darwin/bin/rust-analyzer | ||
// stable - /Users/myuser/.rustup/toolchains/stable-aarch64-apple-darwin/bin/rust-analyzer | ||
function orderFromPath( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will not handle non-versioned toolchains correctly. stable
/beta
/nightly
can refer to some arbitrary old or new version.
For those we should invoke rustup show active-toolchain -v
which yields
nightly-x86_64-pc-windows-msvc (default)
rustc 1.81.0-nightly (9c3bc805d 2024-06-27)
where we can fetch the date
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please note that we're not actually checking the path itself, but the RA that resides at that path is being asked for its version.
However, I've now actually enhanced the logic to always ask the RA for its version info, even if is stable, beta etc. The logic now stands that given the same date, nightly will take precedence over anything else. This actually simplifies the code.
Looks great, thank you for implementing this! |
☀️ Test successful - checks-actions |
My pleasure. Thanks for the guidance also. |
Selects a rust-toolchain declared RA based on its date. The earliest (oldest) RA wins and becomes the one that the workspace uses as a whole.
In terms of precedence:
nightly > stable-with-version > stable
With stable-with-version, we invoke the RA with a
--version
arg and attempt to extract a date. Given the same date as a nightly, the nightly RA will win.Fixes #17663