-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RA should use the toolchain's proc_macro
instead of copying library/proc-macro
.
#12579
Comments
I don't think I quite understand the points here so I'll ask some questions to clarify for myself.
Do you mean we should be building rust-analyzer with the rustc proc-macro server src on the users machine?
This is technically fine, we rely on this var for querying cargo on stable 🤐 Though it would be nice if we didn't have to resort to this.
If I understand this right, this is solely talking about rustup shipped builds or custom builds by the user. But there are also the VSCode published builds which won't work with this approach. |
Could we instead just build and distribute the rust-analyzer proc macro server together with rustc (maybe even in rustc)? This would require keeping the interface between rust-analyzer and the proc macro server somewhat stable, but I think that should be easier than adapting to ABI changes, considering it's just a JSON interface. ("somewhat stable" would mean being backwards- and forwards-compatible over a few rustc versions, since rust-analyzer doesn't guarantee compatibility with more than that.) (That would incidentally also fix the M1 Mac architecture confusion problems that have shown up recently.) |
If the proc macro bridge is put in a crate separate from the user facing proc_macro crate, I think it wouldn't be too hard to make the proc macro bridge compile on stable. I believe I already removed almost all uses of unstable features from it. The proc_macro crate still needs unstable features for making api's unstable and for performance, but this shouldn't be the case for the bridge. |
@Veykril Sorry, I should've been more specific, I'm saying RA would be built and shipped as normal, but @flodiebold The (I don't think it should be in @bjorn3 The bridge is inherently an unstable API, I don't really understand this point. The reason to use |
Yes, I'm suggesting that it would be a separate binary that is always built with rustc. That would solve the problem for all rust-analyzer builds, not just the rustup ones. So I'd want it to be in the rustc component, so that we can rely on it always being there.
I don't quite understand what you mean here, why would it read rmeta and why would that be a problem? |
We'd need to store the binary somewhere then though since we don't want to rebuild this per project. I like the idea of shipping the proc-macro server as a rustup component tbh, that way we could also get around having to build it ourselves. (IntelliJ could just use it as a rustup component as well then instead of copying our thing) |
Assuming it's nestled in the same Presumably someone would have to open a compiler-team MCP to get this going. However, I should note that experimenting with external RA using the
Currently, when If IOW, with access to |
bootstrap itself falls under T-infra, but libproc_macro is in kind of a weird place because it integrates libs, compiler, and also has to deal with bootstrapping ... I think bringing it up in T-compiler is reasonable since people there know more about proc-macros. If you want to ship more files in the I haven't read through this whole issue, but I'm one of the current maintainers of bootstrap, happy to answer questions. |
(just skimmed the issue - +1 to not exposing any rustc_private functionality to the proc macro server, it should only be able to access stuff in |
OK, I can see that.
It would require people to suddenly install the rust-analyzer component even though they get RA through e.g. VSCode. Also, I don't think there's any reason for the proc-macro server to be tied to rust-analyzer at all in this setup (except for saying "this is intended for rust-analyzer and we don't provide any stability guarantees for the protocol outside of that"). We could even put the code into the rust repo? The only reason against that I see is that we'd have the definitions of the JSON protocol in two places. |
doesn't rust-lang/rust already have rust-analyzer as a submodule? I don't see why we'd need to also duplicate proc-macro-srv in-tree. |
We wouldn't duplicate it; it would live in rust-lang/rust because it's independent (code-wise) from rust-analyzer. The reason why I'm slightly against keeping it in rust-analyzer is that it might give the impression that the rust-analyzer binary and the proc-macro-server binary would be matched (built from the same revision), which would not be the case -- they'd have to be compatible with older versions in both directions. The only code that would have to be duplicated would be the struct definitions for the JSON protocol, and I feel having these duplicated would actually reflect the fact that changing the protocol definition in the server doesn't affect what code runs in rust-analyzer. (That's still a big improvement over the current situation, where we have duplicated the proc-macro bridge multiple times!) (As an analogy, consider the cargo metadata format.) Also, if the server is part of the rustc component, it makes sense to me that the code would live in the rustc repo, but 🤷♂️ Anyway, we could also start with the code in the rust-analyzer repo and move it later if we want, so I don't think this question is blocking 🤷♂️ We should make the server an actual separate binary and not a subcommand of rust-analyzer though, since otherwise we'll have to build the full rust-analyzer as part of the rustc component... |
(I guess there is an alternative future where rust-analyzer is always distributed over rustup, and the extension runs the RA version matching the compiler version configured for each project, e.g. in rust-toolchain.toml. In that future, we could indeed rely on the RA and proc-macro server always matching. The problem with that though is that a VSCode workspace can potentially contain multiple Cargo workspaces with differing rust-toolchain.tomls. Also, people will want to use newer rust-analyzer versions with stable rustc.) |
hmm, that gives me an idea - can we make a rust crate that parses the JSON and have both rust-analyzer and proc-macro-srv depend on that? that avoids duplication but still allows you to have different versions in RA and rust-lang/rust. |
I don't think that the JSON interface being unstable is problematic as long as it's versioned; the previous breakages of r-a were generally because of abi breaks and us not updating our side yet. As in, a versioned-but-can-change-arbitrarily API is basically what we have today, just with more unfortunate copying of code. |
Also, if the code for the server lives in the rust-analyzer repo, it could be broken on nightly by changes in the proc macro bridge, right? In which case either there's no nightly, or there is a nightly but no server, which kind of defeats the purpose. |
@flodiebold the "standard" way we've been fixing this genre of issue in I believe |
the latter. |
#12835 (partially) closes this. The steps after that are:
|
So I'm not sure how to share this, but I was wondering about what it would take to long-term not need certain usecases to even touch EDIT (after sleeping on it): to be perfectly clear, this is an useless demo:
The bridge does remain the only way to reliably provide all of the |
This PR just landed to Here's what it means: #12803 (comment) I think this issue can be closed — although we can wait for monday, too :) |
Thank you so much for working on this! Sounds like we got what was being discussed back in e.g. the first half of #12579 (comment), which I would've expected to take much longer, so that's a welcome surprise 🚀 |
I've brought this up elsewhere in the past, but it should've probably been a GH issue from the start. (I also regret not getting in touch with any RA devs when I heard they were working around the internal APIs of
proc_macro
, instead of with them - ideally we would streamline the aspects RA needs)Right now, RA contains (slightly modified IIUC) copies of
rust-lang/rust
'slibrary/proc-macro
for various versions, and when the proc-macro ABI breaks on nightly, RA's proc macro support starts crashing.However, this is far from the intended usage of the unstable
proc_macro::bridge
implementation details.Instead, RA's proc macro support should be built against specific toolchains, and there's two scenarios:
include_str!("proc-macro-srv/.../foo.rs")
) to build on user's machineRUSTC_BOOTSTRAP=1
would need to be used (this is not IMO philosophically different from the second scenario, it's just that the build doesn't happen onrust-lang
CI)rustup
is used, it could be cached in the toolchain itself, with the appropriate invalidation based on toolchain version etc.)rustup
rustc
)rustc
doesFor stable versions, pre-building the proc macro support in RA CI is also possible, but I don't see that scaling up to individual nightlies.
The text was updated successfully, but these errors were encountered: