-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Generalize #[macro_registrar] to #[plugin_registrar] #14554
Conversation
Having syntax extensions forcibly depend on librustc seems to go against one of the major goals of refactoring syntax out of rustc, as well as the current design. I didn't see any wording about this in the RFC, can you explain why this dependency has been picked up? |
This was discussed mainly in @kballard's comment and then on IRC (linked on the RFC thread too). The issue is that we want to register all plugins through a single interface, so that interface needs to use types from both It makes sense to me that syntax extensions are Metadata is defined within I'm not against moving plugin stuff to its own crate (along with metadata reading?) and implementing something like @kballard's type-keyed map to break the unconditional dependency on |
By introducing a dependency on librustc, we're essentially exposing the entire compiler as the interface that syntax extensions have to work with. It's bad enough exposing all of libsyntax where it itself doesn't have a stable interface. I don't think I understand the use case for depending on librustc to have a unified interface for registering plugins. Does this patch currently have examples of how a syntax extension now depends on librustc? The cited example is lints, but I can imagine a world where pluggable lints work without librustc. I think the idea of moving the syntax extension interface to its own crate is a great one because it can be a concrete stable API for future syntax extensions. That said, it probably won't happen for some time. Also, while I agree that this is all feature gated and everything, it doesn't mean that we should throw caution to the wind and accidentally take steps backwards. We should always consider the future direction to go in, regardless of whether it is a large guiding presence at this time or not. I'm not saying that this should block for the perfect design, but "we want this now, not later" doesn't mean that we should basically accept anything that works. |
I don't think so. It's already the case that syntax extension crates can link If you think that convention should be documented more explicitly, I can certainly do that.
Yeah, that's part of why I don't think this is much of a regression. We're not currently getting some huge benefit from a stable, clean
Take a look at my Nothing in this branch requires
Maybe some of them, but a lot of the existing lints talk to the typechecker, for example. The lint I want to write for Servo will need to know the inferred types of
This isn't accidental; it was discussed on the RFC thread and on IRC and again by us here.
Sure, and of course I agree in general. We're just disagreeing on whether this particular tradeoff is acceptable or not. I think it is, because we're not losing any major capability that we have today. Getting those capabilities would require a stable |
if cfg!(windows) { | ||
sess.host_filesearch().add_dylib_search_paths(); | ||
let Plugins { macros, registrars } | ||
= time(time_passes, "plugin loading", (), |_| |
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.
Running at this phase implies that a macro cannot load new plugins internally, right?
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.
Ah, do you mean something like
#[macro_export]
macro_rules! foo ( () => (
#[phase(plugin)] extern crate log;
));
That's true, this wouldn't work as an exported macro. I hadn't thought of that.
Do you think there is a compelling use case for this pattern or is it an acceptable limitation? The alternative I guess is to alternate between expansion and plugin loading until a fixed point is reached.
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.
We could just have three passes: load, expand, load again, meaning macros can introduce lints etc., but not other macros.
(I think this is actually close to the only thing that works, since any macro that's defined in a crate loaded from another macro will be undefined on the first expansion run... unless additional plugins are loaded while expanding.)
The approach you have here is certainly the most conservative, and should work for now. I guess other approaches should go through an RFC.
Rebased. |
See RFC 22. [breaking-change]
Do this to avoid warnings on post-stage0 builds.
Sorry about the repeated breakage. I was having trouble running |
This implements the design in rust-lang/rfcs#86. It shouldn't be merged until that RFC is accepted, but it would be great if somebody has time to review the code before then.
This implements the design in rust-lang/rfcs#86. It shouldn't be merged until that RFC is accepted, but it would be great if somebody has time to review the code before then.