Skip to content

Commit 412f43a

Browse files
committed
Auto merge of #66647 - petrochenkov:nosynt, r=Centril
rustc_plugin: Remove support for syntactic plugins This part of the plugin interface was successfully replaced by token-based procedural macros in theory and in practice. cc #29597 cc #64675 r? @Centril
2 parents 5a1d028 + f89e6c8 commit 412f43a

31 files changed

+56
-523
lines changed

Cargo.lock

-1
Original file line numberDiff line numberDiff line change
@@ -3802,7 +3802,6 @@ dependencies = [
38023802
"rustc_error_codes",
38033803
"rustc_metadata",
38043804
"syntax",
3805-
"syntax_expand",
38063805
"syntax_pos",
38073806
]
38083807

src/doc/unstable-book/src/language-features/plugin.md

+1-129
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ This feature is part of "compiler plugins." It will often be used with the
1313
------------------------
1414

1515
`rustc` can load compiler plugins, which are user-provided libraries that
16-
extend the compiler's behavior with new syntax extensions, lint checks, etc.
16+
extend the compiler's behavior with new lint checks, etc.
1717

1818
A plugin is a dynamic library crate with a designated *registrar* function that
1919
registers extensions with `rustc`. Other crates can load these extensions using
@@ -35,134 +35,6 @@ The usual practice is to put compiler plugins in their own crate, separate from
3535
any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
3636
of a library.
3737

38-
# Syntax extensions
39-
40-
Plugins can extend Rust's syntax in various ways. One kind of syntax extension
41-
is the procedural macro. These are invoked the same way as [ordinary
42-
macros](../../book/macros.md), but the expansion is performed by arbitrary Rust
43-
code that manipulates syntax trees at
44-
compile time.
45-
46-
Let's write a plugin
47-
[`roman_numerals.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/roman_numerals.rs)
48-
that implements Roman numeral integer literals.
49-
50-
```rust,ignore
51-
#![crate_type="dylib"]
52-
#![feature(plugin_registrar, rustc_private)]
53-
54-
extern crate syntax;
55-
extern crate syntax_pos;
56-
extern crate rustc;
57-
extern crate rustc_driver;
58-
59-
use syntax::parse::token::{self, Token};
60-
use syntax::tokenstream::{TokenTree, TokenStream};
61-
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
62-
use syntax_pos::Span;
63-
use rustc_driver::plugin::Registry;
64-
65-
fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: TokenStream)
66-
-> Box<dyn MacResult + 'static> {
67-
68-
static NUMERALS: &'static [(&'static str, usize)] = &[
69-
("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
70-
("C", 100), ("XC", 90), ("L", 50), ("XL", 40),
71-
("X", 10), ("IX", 9), ("V", 5), ("IV", 4),
72-
("I", 1)];
73-
74-
if args.len() != 1 {
75-
cx.span_err(
76-
sp,
77-
&format!("argument should be a single identifier, but got {} arguments", args.len()));
78-
return DummyResult::any(sp);
79-
}
80-
81-
let text = match args.into_trees().next().unwrap() {
82-
TokenTree::Token(Token { kind: token::Ident(s, _), .. }) => s.to_string(),
83-
_ => {
84-
cx.span_err(sp, "argument should be a single identifier");
85-
return DummyResult::any(sp);
86-
}
87-
};
88-
89-
let mut text = &*text;
90-
let mut total = 0;
91-
while !text.is_empty() {
92-
match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
93-
Some(&(rn, val)) => {
94-
total += val;
95-
text = &text[rn.len()..];
96-
}
97-
None => {
98-
cx.span_err(sp, "invalid Roman numeral");
99-
return DummyResult::any(sp);
100-
}
101-
}
102-
}
103-
104-
MacEager::expr(cx.expr_usize(sp, total))
105-
}
106-
107-
#[plugin_registrar]
108-
pub fn plugin_registrar(reg: &mut Registry) {
109-
reg.register_macro("rn", expand_rn);
110-
}
111-
```
112-
113-
Then we can use `rn!()` like any other macro:
114-
115-
```rust,ignore
116-
#![feature(plugin)]
117-
#![plugin(roman_numerals)]
118-
119-
fn main() {
120-
assert_eq!(rn!(MMXV), 2015);
121-
}
122-
```
123-
124-
The advantages over a simple `fn(&str) -> u32` are:
125-
126-
* The (arbitrarily complex) conversion is done at compile time.
127-
* Input validation is also performed at compile time.
128-
* It can be extended to allow use in patterns, which effectively gives
129-
a way to define new literal syntax for any data type.
130-
131-
In addition to procedural macros, you can define new
132-
[`derive`](../../reference/attributes/derive.md)-like attributes and other kinds
133-
of extensions. See `Registry::register_syntax_extension` and the
134-
`SyntaxExtension` struct. For a more involved macro example, see
135-
[`regex_macros`](https://github.com/rust-lang/regex/blob/master/regex_macros/src/lib.rs).
136-
137-
138-
## Tips and tricks
139-
140-
You can use `syntax::parse` to turn token trees into
141-
higher-level syntax elements like expressions:
142-
143-
```rust,ignore
144-
fn expand_foo(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
145-
-> Box<MacResult+'static> {
146-
147-
let mut parser = cx.new_parser_from_tts(args);
148-
149-
let expr: P<Expr> = parser.parse_expr();
150-
```
151-
152-
Looking through [`libsyntax` parser
153-
code](https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs)
154-
will give you a feel for how the parsing infrastructure works.
155-
156-
Keep the `Span`s of everything you parse, for better error reporting. You can
157-
wrap `Spanned` around your custom data structures.
158-
159-
Calling `ExtCtxt::span_fatal` will immediately abort compilation. It's better to
160-
instead call `ExtCtxt::span_err` and return `DummyResult` so that the compiler
161-
can continue and find further errors.
162-
163-
To print syntax fragments for debugging, you can use `span_note` together with
164-
`syntax::print::pprust::*_to_string`.
165-
16638
# Lint plugins
16739

16840
Plugins can extend [Rust's lint

src/librustc_driver/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ pub fn run_compiler(
322322
}
323323

324324
{
325-
let (_, _, lint_store) = &*compiler.register_plugins()?.peek();
325+
let (_, lint_store) = &*compiler.register_plugins()?.peek();
326326

327327
// Lint plugins are registered; now we can process command line flags.
328328
if sess.opts.describe_lints {

src/librustc_interface/passes.rs

+4-16
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use rustc_traits;
3737
use rustc_typeck as typeck;
3838
use syntax::{self, ast, visit};
3939
use syntax::early_buffered_lints::BufferedEarlyLint;
40-
use syntax_expand::base::{NamedSyntaxExtension, ExtCtxt};
40+
use syntax_expand::base::ExtCtxt;
4141
use syntax::mut_visit::MutVisitor;
4242
use syntax::util::node_count::NodeCounter;
4343
use syntax::symbol::Symbol;
@@ -119,7 +119,6 @@ pub fn configure_and_expand(
119119
metadata_loader: Box<MetadataLoaderDyn>,
120120
krate: ast::Crate,
121121
crate_name: &str,
122-
plugin_info: PluginInfo,
123122
) -> Result<(ast::Crate, BoxedResolver)> {
124123
// Currently, we ignore the name resolution data structures for the purposes of dependency
125124
// tracking. Instead we will run name resolution and include its output in the hash of each
@@ -137,7 +136,6 @@ pub fn configure_and_expand(
137136
&crate_name,
138137
&resolver_arenas,
139138
&*metadata_loader,
140-
plugin_info,
141139
);
142140
let mut resolver = match res {
143141
Err(v) => {
@@ -164,17 +162,13 @@ impl BoxedResolver {
164162
}
165163
}
166164

167-
pub struct PluginInfo {
168-
syntax_exts: Vec<NamedSyntaxExtension>,
169-
}
170-
171165
pub fn register_plugins<'a>(
172166
sess: &'a Session,
173167
metadata_loader: &'a dyn MetadataLoader,
174168
register_lints: impl Fn(&Session, &mut lint::LintStore),
175169
mut krate: ast::Crate,
176170
crate_name: &str,
177-
) -> Result<(ast::Crate, PluginInfo, Lrc<lint::LintStore>)> {
171+
) -> Result<(ast::Crate, Lrc<lint::LintStore>)> {
178172
krate = time(sess, "attributes injection", || {
179173
syntax_ext::cmdline_attrs::inject(
180174
krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr
@@ -240,10 +234,9 @@ pub fn register_plugins<'a>(
240234
}
241235
});
242236

243-
let Registry { syntax_exts, llvm_passes, .. } = registry;
244-
*sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
237+
*sess.plugin_llvm_passes.borrow_mut() = registry.llvm_passes;
245238

246-
Ok((krate, PluginInfo { syntax_exts }, Lrc::new(lint_store)))
239+
Ok((krate, Lrc::new(lint_store)))
247240
}
248241

249242
fn configure_and_expand_inner<'a>(
@@ -253,7 +246,6 @@ fn configure_and_expand_inner<'a>(
253246
crate_name: &str,
254247
resolver_arenas: &'a ResolverArenas<'a>,
255248
metadata_loader: &'a MetadataLoaderDyn,
256-
plugin_info: PluginInfo,
257249
) -> Result<(ast::Crate, Resolver<'a>)> {
258250
time(sess, "pre-AST-expansion lint checks", || {
259251
lint::check_ast_crate(
@@ -290,10 +282,6 @@ fn configure_and_expand_inner<'a>(
290282

291283
util::check_attr_crate_type(&krate.attrs, &mut resolver.lint_buffer());
292284

293-
syntax_ext::plugin_macro_defs::inject(
294-
&mut krate, &mut resolver, plugin_info.syntax_exts, sess.edition()
295-
);
296-
297285
// Expand all macros
298286
krate = time(sess, "expansion", || {
299287
let _prof_timer = sess.prof.generic_activity("macro_expand_crate");

src/librustc_interface/queries.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::interface::{Compiler, Result};
2-
use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt, PluginInfo};
2+
use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt};
33

44
use rustc_incremental::DepGraphFuture;
55
use rustc_data_structures::sync::Lrc;
@@ -79,7 +79,7 @@ pub(crate) struct Queries {
7979
dep_graph_future: Query<Option<DepGraphFuture>>,
8080
parse: Query<ast::Crate>,
8181
crate_name: Query<String>,
82-
register_plugins: Query<(ast::Crate, PluginInfo, Lrc<LintStore>)>,
82+
register_plugins: Query<(ast::Crate, Lrc<LintStore>)>,
8383
expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>,
8484
dep_graph: Query<DepGraph>,
8585
lower_to_hir: Query<(Steal<hir::map::Forest>, Steal<ResolverOutputs>)>,
@@ -111,7 +111,7 @@ impl Compiler {
111111
})
112112
}
113113

114-
pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo, Lrc<LintStore>)>> {
114+
pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, Lrc<LintStore>)>> {
115115
self.queries.register_plugins.compute(|| {
116116
let crate_name = self.crate_name()?.peek().clone();
117117
let krate = self.parse()?.take();
@@ -161,14 +161,13 @@ impl Compiler {
161161
) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>> {
162162
self.queries.expansion.compute(|| {
163163
let crate_name = self.crate_name()?.peek().clone();
164-
let (krate, plugin_info, lint_store) = self.register_plugins()?.take();
164+
let (krate, lint_store) = self.register_plugins()?.take();
165165
passes::configure_and_expand(
166166
self.sess.clone(),
167167
lint_store.clone(),
168168
self.codegen_backend().metadata_loader(),
169169
krate,
170170
&crate_name,
171-
plugin_info,
172171
).map(|(krate, resolver)| {
173172
(krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store)
174173
})

src/librustc_plugin_impl/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,5 @@ doctest = false
1414
rustc = { path = "../librustc" }
1515
rustc_metadata = { path = "../librustc_metadata" }
1616
syntax = { path = "../libsyntax" }
17-
syntax_expand = { path = "../libsyntax_expand" }
1817
syntax_pos = { path = "../libsyntax_pos" }
1918
rustc_error_codes = { path = "../librustc_error_codes" }

src/librustc_plugin_impl/lib.rs

+2-47
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,10 @@
11
//! Infrastructure for compiler plugins.
22
//!
3-
//! Plugins are Rust libraries which extend the behavior of `rustc`
4-
//! in various ways.
5-
//!
6-
//! Plugin authors will use the `Registry` type re-exported by
7-
//! this module, along with its methods. The rest of the module
8-
//! is for use by `rustc` itself.
9-
//!
10-
//! To define a plugin, build a dylib crate with a
11-
//! `#[plugin_registrar]` function:
12-
//!
13-
//! ```no_run
14-
//! #![crate_name = "myplugin"]
15-
//! #![crate_type = "dylib"]
16-
//! #![feature(plugin_registrar)]
17-
//! #![feature(rustc_private)]
18-
//!
19-
//! extern crate rustc_driver;
20-
//! extern crate syntax;
21-
//! extern crate syntax_pos;
22-
//!
23-
//! use rustc_driver::plugin::Registry;
24-
//! use syntax_expand::base::{ExtCtxt, MacResult};
25-
//! use syntax_pos::Span;
26-
//! use syntax::tokenstream::TokenTree;
27-
//!
28-
//! #[plugin_registrar]
29-
//! pub fn plugin_registrar(reg: &mut Registry) {
30-
//! reg.register_macro("mymacro", expand_mymacro);
31-
//! }
32-
//!
33-
//! fn expand_mymacro(cx: &mut ExtCtxt, span: Span, tt: &[TokenTree]) -> Box<MacResult> {
34-
//! unimplemented!()
35-
//! }
36-
//!
37-
//! # fn main() {}
38-
//! ```
39-
//!
40-
//! WARNING: We currently don't check that the registrar function
41-
//! has the appropriate type!
42-
//!
43-
//! To use a plugin while compiling another crate:
44-
//!
45-
//! ```rust
46-
//! #![feature(plugin)]
47-
//! #![plugin(myplugin)]
48-
//! ```
3+
//! Plugins are a deprecated way to extend the behavior of `rustc` in various ways.
494
//!
505
//! See the [`plugin`
516
//! feature](https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html)
52-
//! of the Unstable Book for more examples.
7+
//! of the Unstable Book for some examples.
538
549
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
5510

src/librustc_plugin_impl/registry.rs

-26
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
33
use rustc::lint::LintStore;
44
use rustc::session::Session;
5-
6-
use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension};
7-
use syntax_expand::base::MacroExpanderFn;
8-
use syntax::symbol::Symbol;
95
use syntax::ast;
106
use syntax_pos::Span;
117

@@ -33,9 +29,6 @@ pub struct Registry<'a> {
3329
#[doc(hidden)]
3430
pub krate_span: Span,
3531

36-
#[doc(hidden)]
37-
pub syntax_exts: Vec<NamedSyntaxExtension>,
38-
3932
#[doc(hidden)]
4033
pub llvm_passes: Vec<String>,
4134
}
@@ -48,7 +41,6 @@ impl<'a> Registry<'a> {
4841
lint_store,
4942
args_hidden: None,
5043
krate_span,
51-
syntax_exts: vec![],
5244
llvm_passes: vec![],
5345
}
5446
}
@@ -67,24 +59,6 @@ impl<'a> Registry<'a> {
6759
self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[])
6860
}
6961

70-
/// Register a syntax extension of any kind.
71-
///
72-
/// This is the most general hook into `libsyntax`'s expansion behavior.
73-
pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
74-
self.syntax_exts.push((name, extension));
75-
}
76-
77-
/// Register a macro of the usual kind.
78-
///
79-
/// This is a convenience wrapper for `register_syntax_extension`.
80-
/// It builds for you a `SyntaxExtensionKind::LegacyBang` that calls `expander`,
81-
/// and also takes care of interning the macro's name.
82-
pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
83-
let kind = SyntaxExtensionKind::LegacyBang(Box::new(expander));
84-
let ext = SyntaxExtension::default(kind, self.sess.edition());
85-
self.register_syntax_extension(Symbol::intern(name), ext);
86-
}
87-
8862
/// Register an LLVM pass.
8963
///
9064
/// Registration with LLVM itself is handled through static C++ objects with

0 commit comments

Comments
 (0)