Skip to content

Commit

Permalink
rustc_plugin: Remove support for plugin arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Dec 1, 2019
1 parent 4007d4e commit 55ba05b
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 156 deletions.
4 changes: 0 additions & 4 deletions src/doc/unstable-book/src/language-features/plugin.md
Expand Up @@ -21,10 +21,6 @@ the crate attribute `#![plugin(...)]`. See the
`rustc_driver::plugin` documentation for more about the
mechanics of defining and loading a plugin.

If present, arguments passed as `#![plugin(foo(... args ...))]` are not
interpreted by rustc itself. They are provided to the plugin through the
`Registry`'s `args` method.

In the vast majority of cases, a plugin should *only* be used through
`#![plugin]` and not through an `extern crate` item. Linking a plugin would
pull in all of libsyntax and librustc as dependencies of your crate. This is
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_feature/builtin_attrs.rs
Expand Up @@ -283,7 +283,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
)
),
(
sym::plugin, CrateLevel, template!(List: "name|name(args)"),
sym::plugin, CrateLevel, template!(List: "name"),
Gated(
Stability::Deprecated(
"https://github.com/rust-lang/rust/pull/64675",
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_interface/passes.rs
Expand Up @@ -229,8 +229,7 @@ pub fn register_plugins<'a>(

time(sess, "plugin registration", || {
for registrar in registrars {
registry.args_hidden = Some(registrar.args);
(registrar.fun)(&mut registry);
registrar(&mut registry);
}
});

Expand Down
165 changes: 68 additions & 97 deletions src/librustc_plugin_impl/load.rs
Expand Up @@ -9,27 +9,15 @@ use std::borrow::ToOwned;
use std::env;
use std::mem;
use std::path::PathBuf;
use syntax::ast;
use syntax::ast::{Crate, Ident};
use syntax::struct_span_err;
use syntax::symbol::{Symbol, kw, sym};
use syntax_pos::{Span, DUMMY_SP};
use syntax::symbol::sym;
use syntax_pos::Span;

use rustc_error_codes::*;

/// Pointer to a registrar function.
pub type PluginRegistrarFun =
fn(&mut Registry<'_>);

pub struct PluginRegistrar {
pub fun: PluginRegistrarFun,
pub args: Vec<ast::NestedMetaItem>,
}

struct PluginLoader<'a> {
sess: &'a Session,
metadata_loader: &'a dyn MetadataLoader,
plugins: Vec<PluginRegistrar>,
}
type PluginRegistrarFn = fn(&mut Registry<'_>);

fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
struct_span_err!(sess, span, E0498, "malformed `plugin` attribute")
Expand All @@ -40,98 +28,81 @@ fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
/// Read plugin metadata and dynamically load registrar functions.
pub fn load_plugins(sess: &Session,
metadata_loader: &dyn MetadataLoader,
krate: &ast::Crate,
addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
let mut loader = PluginLoader { sess, metadata_loader, plugins: Vec::new() };

// do not report any error now. since crate attributes are
// not touched by expansion, every use of plugin without
// the feature enabled will result in an error later...
if sess.features_untracked().plugin {
for attr in &krate.attrs {
if !attr.check_name(sym::plugin) {
continue;
}

let plugins = match attr.meta_item_list() {
Some(xs) => xs,
None => continue,
};
krate: &Crate,
addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrarFn> {
let mut plugins = Vec::new();
let mut load_plugin = |ident| load_plugin(&mut plugins, sess, metadata_loader, ident);

for attr in &krate.attrs {
if !attr.check_name(sym::plugin) {
continue;
}

for plugin in plugins {
// plugins must have a name and can't be key = value
let name = plugin.name_or_empty();
if name != kw::Invalid && !plugin.is_value_str() {
let args = plugin.meta_item_list().map(ToOwned::to_owned);
loader.load_plugin(plugin.span(), name, args.unwrap_or_default());
} else {
call_malformed_plugin_attribute(sess, attr.span);
}
for plugin in attr.meta_item_list().unwrap_or_default() {
match plugin.ident() {
Some(ident) if plugin.is_word() => load_plugin(ident),
_ => call_malformed_plugin_attribute(sess, plugin.span()),
}
}
}

if let Some(plugins) = addl_plugins {
for plugin in plugins {
loader.load_plugin(DUMMY_SP, Symbol::intern(&plugin), vec![]);
}
for plugin in addl_plugins.unwrap_or_default() {
load_plugin(Ident::from_str(&plugin));
}

loader.plugins
plugins
}

impl<'a> PluginLoader<'a> {
fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec<ast::NestedMetaItem>) {
let registrar = locator::find_plugin_registrar(self.sess, self.metadata_loader, span, name);

if let Some((lib, disambiguator)) = registrar {
let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator);
let fun = self.dylink_registrar(span, lib, symbol);
self.plugins.push(PluginRegistrar {
fun,
args,
});
}
fn load_plugin(plugins: &mut Vec<PluginRegistrarFn>,
sess: &Session,
metadata_loader: &dyn MetadataLoader,
ident: Ident) {
let registrar = locator::find_plugin_registrar(sess, metadata_loader, ident.span, ident.name);

if let Some((lib, disambiguator)) = registrar {
let symbol = sess.generate_plugin_registrar_symbol(disambiguator);
let fun = dylink_registrar(sess, ident.span, lib, symbol);
plugins.push(fun);
}
}

// Dynamically link a registrar function into the compiler process.
fn dylink_registrar(&mut self,
span: Span,
path: PathBuf,
symbol: String) -> PluginRegistrarFun {
use rustc_metadata::dynamic_lib::DynamicLibrary;

// Make sure the path contains a / or the linker will search for it.
let path = env::current_dir().unwrap().join(&path);

let lib = match DynamicLibrary::open(Some(&path)) {
Ok(lib) => lib,
// this is fatal: there are almost certainly macros we need
// inside this crate, so continue would spew "macro undefined"
// errors
Err(err) => {
self.sess.span_fatal(span, &err)
}
};

unsafe {
let registrar =
match lib.symbol(&symbol) {
Ok(registrar) => {
mem::transmute::<*mut u8,PluginRegistrarFun>(registrar)
}
// again fatal if we can't register macros
Err(err) => {
self.sess.span_fatal(span, &err)
}
};

// Intentionally leak the dynamic library. We can't ever unload it
// since the library can make things that will live arbitrarily long
// (e.g., an @-box cycle or a thread).
mem::forget(lib);

registrar
// Dynamically link a registrar function into the compiler process.
fn dylink_registrar(sess: &Session,
span: Span,
path: PathBuf,
symbol: String) -> PluginRegistrarFn {
use rustc_metadata::dynamic_lib::DynamicLibrary;

// Make sure the path contains a / or the linker will search for it.
let path = env::current_dir().unwrap().join(&path);

let lib = match DynamicLibrary::open(Some(&path)) {
Ok(lib) => lib,
// this is fatal: there are almost certainly macros we need
// inside this crate, so continue would spew "macro undefined"
// errors
Err(err) => {
sess.span_fatal(span, &err)
}
};

unsafe {
let registrar =
match lib.symbol(&symbol) {
Ok(registrar) => {
mem::transmute::<*mut u8, PluginRegistrarFn>(registrar)
}
// again fatal if we can't register macros
Err(err) => {
sess.span_fatal(span, &err)
}
};

// Intentionally leak the dynamic library. We can't ever unload it
// since the library can make things that will live arbitrarily long
// (e.g., an @-box cycle or a thread).
mem::forget(lib);

registrar
}
}
19 changes: 0 additions & 19 deletions src/librustc_plugin_impl/registry.rs
Expand Up @@ -2,7 +2,6 @@

use rustc::lint::LintStore;
use rustc::session::Session;
use syntax::ast;
use syntax_pos::Span;

use std::borrow::ToOwned;
Expand All @@ -23,9 +22,6 @@ pub struct Registry<'a> {
/// The `LintStore` allows plugins to register new lints.
pub lint_store: &'a mut LintStore,

#[doc(hidden)]
pub args_hidden: Option<Vec<ast::NestedMetaItem>>,

#[doc(hidden)]
pub krate_span: Span,

Expand All @@ -39,26 +35,11 @@ impl<'a> Registry<'a> {
Registry {
sess,
lint_store,
args_hidden: None,
krate_span,
llvm_passes: vec![],
}
}

/// Gets the plugin's arguments, if any.
///
/// These are specified inside the `plugin` crate attribute as
///
/// ```no_run
/// #![plugin(my_plugin_name(... args ...))]
/// ```
///
/// Returns empty slice in case the plugin was loaded
/// with `--extra-plugins`
pub fn args(&self) -> &[ast::NestedMetaItem] {
self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[])
}

/// Register an LLVM pass.
///
/// Registration with LLVM itself is handled through static C++ objects with
Expand Down
@@ -1,6 +1,7 @@
// Test that `#![plugin(...)]` attribute is gated by `plugin` feature gate
// aux-build:empty-plugin.rs
// ignore-stage1

#![plugin(foo)]
#![plugin(empty_plugin)]
//~^ ERROR compiler plugins are deprecated
//~| WARN use of deprecated attribute `plugin`: compiler plugins are deprecated

Expand Down
@@ -1,17 +1,17 @@
error[E0658]: compiler plugins are deprecated
--> $DIR/feature-gate-plugin.rs:3:1
--> $DIR/feature-gate-plugin.rs:4:1
|
LL | #![plugin(foo)]
| ^^^^^^^^^^^^^^^
LL | #![plugin(empty_plugin)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29597
= help: add `#![feature(plugin)]` to the crate attributes to enable

warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/feature-gate-plugin.rs:3:1
--> $DIR/feature-gate-plugin.rs:4:1
|
LL | #![plugin(foo)]
| ^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
LL | #![plugin(empty_plugin)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

Expand Down
5 changes: 3 additions & 2 deletions src/test/ui-fulldeps/plugin-args-2.rs
@@ -1,8 +1,9 @@
// check-pass
// aux-build:empty-plugin.rs
// ignore-stage1

#![feature(plugin)]
#![plugin(empty_plugin())] //~ WARNING compiler plugins are deprecated
#![plugin(empty_plugin(args))]
//~^ ERROR malformed `plugin` attribute
//~| WARNING compiler plugins are deprecated

fn main() {}
14 changes: 11 additions & 3 deletions src/test/ui-fulldeps/plugin-args-2.stderr
@@ -1,8 +1,16 @@
error[E0498]: malformed `plugin` attribute
--> $DIR/plugin-args-2.rs:5:11
|
LL | #![plugin(empty_plugin(args))]
| ^^^^^^^^^^^^^^^^^^ malformed attribute

warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/plugin-args-2.rs:6:1
--> $DIR/plugin-args-2.rs:5:1
|
LL | #![plugin(empty_plugin())]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
LL | #![plugin(empty_plugin(args))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

error: aborting due to previous error

8 changes: 0 additions & 8 deletions src/test/ui-fulldeps/plugin-args-3.rs

This file was deleted.

8 changes: 0 additions & 8 deletions src/test/ui-fulldeps/plugin-args-3.stderr

This file was deleted.

2 changes: 1 addition & 1 deletion src/test/ui/malformed/malformed-plugin-1.stderr
Expand Up @@ -2,7 +2,7 @@ error: malformed `plugin` attribute input
--> $DIR/malformed-plugin-1.rs:2:1
|
LL | #![plugin]
| ^^^^^^^^^^ help: must be of the form: `#[plugin(name|name(args))]`
| ^^^^^^^^^^ help: must be of the form: `#[plugin(name)]`

warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/malformed-plugin-1.rs:2:1
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/malformed/malformed-plugin-2.stderr
Expand Up @@ -2,7 +2,7 @@ error: malformed `plugin` attribute input
--> $DIR/malformed-plugin-2.rs:2:1
|
LL | #![plugin="bleh"]
| ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[plugin(name|name(args))]`
| ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[plugin(name)]`

warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/malformed-plugin-2.rs:2:1
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/malformed/malformed-plugin-3.stderr
@@ -1,8 +1,8 @@
error[E0498]: malformed `plugin` attribute
--> $DIR/malformed-plugin-3.rs:2:1
--> $DIR/malformed-plugin-3.rs:2:11
|
LL | #![plugin(foo="bleh")]
| ^^^^^^^^^^^^^^^^^^^^^^ malformed attribute
| ^^^^^^^^^^ malformed attribute

warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/malformed-plugin-3.rs:2:1
Expand Down

0 comments on commit 55ba05b

Please sign in to comment.