Decouple proc_macro from the rest of the compiler.#49219
Decouple proc_macro from the rest of the compiler.#49219bors merged 16 commits intorust-lang:masterfrom
Conversation
|
@bors try |
|
🔒 Merge conflict |
67f317e to
6e63e8d
Compare
|
@bors try |
Decouple proc_macro from the rest of the compiler.
This PR removes all dependencies of `proc_macro` on compiler crates and allows multiple copies of `proc_macro`, built even by different compilers (but from the same source), to interoperate.
On the compiler (aka "frontend") side:
* `Registry` is implemented (as until now)
* instead of function pointers, the `Expand{1,2}` wrapper types are received
* `FrontendInterface` is implemented to provide the concrete type and methods
* the concrete types are completely separated from the `proc_macro` public API
* the only use of the implementer is to be passed to `Expand{1,2}::run`
On the proc macro side (potentially using a different `proc_macro` instance):
* `&mut Registry` is passed to the registrar (as until now)
* `Expand{1,2}` wrappers are created to be passed to the `Registry`
* they encapsulate the `proc_macro` instance used by the macro crate
* their `run` method will set up the "current frontend" of that instance
`proc_macro` public APIs call into the "current frontend" via the internal `bridge`:
* only a currently running proc macro can interact with those APIs
* the frontend itself might not be able to (if it uses a different `proc_macro` instance)
* the `bridge` uses C ABI to avoid Rust ABI instability and "generation tagging" for safety
* each invocation of a proc macro results in a different "generation"
* specifically, opaque `proc_macro` types wrapping concrete frontend types are tagged
* this prevents using values of those types across invocations (even if they can be kept)
* an ABI mismatch between two versions of `proc_macro` is only possible during stage1
* specifically, rustc compiled by stage0 but proc macros compiled by stage1
* can only affect running tests at stage1 or the compiler using proc macros
* defficiencies in the `bridge` can be addressed without waiting for a release cycle
r? @alexcrichton cc @jseyfried @nikomatsakis @Zoxc @thepowersgang
|
cc @rust-lang/infra We shouldn't merge this without a crater run, although you might want to wait on a review as well (then again, the results could inform the review, so whichever comes first). |
|
☀️ Test successful - status-travis |
src/libproc_macro/lib.rs
Outdated
|
|
||
| #[unstable(feature = "proc_macro_internals", issue = "27812")] | ||
| #[doc(hidden)] | ||
| pub contents: Term, |
There was a problem hiding this comment.
Do we want to commit to using interning for literals? I'm not sure interning it terrible useful for that.
There was a problem hiding this comment.
Wait, I can make these fields private again. Definitely not considering stabilizing any of this.
| term = { path = "../libterm" } | ||
|
|
||
| # not actually used but needed to always have proc_macro in the sysroot | ||
| proc_macro = { path = "../libproc_macro" } |
There was a problem hiding this comment.
This should probably be a rustbuild change.
|
Could you use something like bincode for data bridging, instead of 800 lines of own code? |
|
@bjorn3 I'm not serializing the data (but rather using handles), and I am going to look into simplifying the bridge code, removing most |
|
I get it. |
This comment has been minimized.
This comment has been minimized.
6e63e8d to
cd9ac21
Compare
This comment has been minimized.
This comment has been minimized.
|
Not sure if you wanted perf, or whether this is even helpful, but http://perf.rust-lang.org/compare.html?start=75af15ee6ca0c12b699a17984b033363cd25e9c3&end=c4a77e121949c30306dbbf48259a49c3aeb55028&stat=instructions%3Au |
|
@Mark-Simulacrum It doesn't look bad, that's for sure, thanks! If we switch to spawning a thread (or even a process) per invocation it'd warrant another perf run. |
cd9ac21 to
76590d8
Compare
A few tests related to proc-macros fail when performing stage-1 testing. This PR adds // ignore-stage1 to them, along with a FIXME. Original issue: rust-lang#49352 This should (hopefully) be fixed when rust-lang#49219 is merged.
|
Crater run started |
|
Hi @eddyb (crater requester), @Zoxc (PR reviewer)! Crater results are at: http://cargobomb-reports.s3.amazonaws.com/pr-49219/index.html. 'Blacklisted' crates (spurious failures etc) can be found here. If you see any spurious failures not on the list, please make a PR against that file. (interested observers: Crater is a tool for testing the impact of changes on the crates.io ecosystem. You can find out more at the repo if you're curious) |
|
I can't believe you've done this! |
This PR removes all dependencies of
proc_macroon compiler crates and allows multiple copies ofproc_macro, built even by different compilers (but from the same source), to interoperate.Practically, it allows:
-fulldepsto the regular suites)On the server (i.e. compiler front-end) side:
server::*traits are implemented to provide the concrete types and methodsproc_macropublic APIServeris to be passed toClient::runOn the client (i.e. proc macro) side (potentially using a different
proc_macroinstance!):client::Clientwraps around client-side (expansion) function pointersproc_macroinstance used by the clientrunmethod can be called by a server, to execute the client-side functioncurrently a thread is spawned, could use process isolation in the future(not the case anymore, see Run proc macro invocations in separate threads. #56058)
staticholding a&[ProcMacro]ProcMacrocontains an appropriately typedClient<fn(...) -> ...>proc_macropublic APIs call into the server via an internal "bridge":Clientcan interact with those APIsproc_macroinstance)runits ownClient, but that may be inefficientbridgeuses serialization, C ABI and integer handles to avoid Rust ABI instabilityproc_macrohandlesr? @alexcrichton cc @jseyfried @nikomatsakis @Zoxc @thepowersgang