1
Fork 0

Use a crate attribute to load plugins

#[plugin] #[no_link] extern crate bleh;

becomes a crate attribute

    #![plugin(bleh)]

The feature gate is still required.

It's almost never correct to link a plugin into the resulting library /
executable, because it will bring all of libsyntax and librustc with it.
However if you really want this behavior, you can get it with a separate
`extern crate` item in addition to the `plugin` attribute.

Fixes #21043.
Fixes #20769.

[breaking-change]
This commit is contained in:
Keegan McAllister 2015-02-06 13:56:38 -08:00
parent 0ba9e1fa52
commit 93b642d974
37 changed files with 152 additions and 165 deletions

View file

@ -2014,6 +2014,11 @@ type int8_t = i8;
- `no_start` - disable linking to the `native` crate, which specifies the - `no_start` - disable linking to the `native` crate, which specifies the
"start" language item. "start" language item.
- `no_std` - disable linking to the `std` crate. - `no_std` - disable linking to the `std` crate.
- `plugin` — load a list of named crates as compiler plugins, e.g.
`#![plugin(foo, bar)]`. Optional arguments for each plugin,
i.e. `#![plugin(foo(... args ...))]`, are provided to the plugin's
registrar function. The `plugin` feature gate is required to use
this attribute.
### Module-only attributes ### Module-only attributes
@ -2082,7 +2087,7 @@ On `struct`s:
remove any padding between fields (note that this is very fragile and may remove any padding between fields (note that this is very fragile and may
break platforms which require aligned access). break platforms which require aligned access).
### Macro- and plugin-related attributes ### Macro-related attributes
- `macro_use` on a `mod` — macros defined in this module will be visible in the - `macro_use` on a `mod` — macros defined in this module will be visible in the
module's parent, after this module has been included. module's parent, after this module has been included.
@ -2097,13 +2102,8 @@ On `struct`s:
- `macro_export` - export a macro for cross-crate usage. - `macro_export` - export a macro for cross-crate usage.
- `plugin` on an `extern crate` — load this crate as a [compiler - `no_link` on an `extern crate` — even if we load this crate for macros, don't
plugin][plugin]. The `plugin` feature gate is required. Any arguments to link it into the output.
the attribute, e.g. `#[plugin=...]` or `#[plugin(...)]`, are provided to the
plugin.
- `no_link` on an `extern crate` — even if we load this crate for macros or
compiler plugins, don't link it into the output.
See the [macros section of the See the [macros section of the
book](book/macros.html#scoping-and-macro-import/export) for more information on book](book/macros.html#scoping-and-macro-import/export) for more information on

View file

@ -30,14 +30,14 @@ information.
extend the compiler's behavior with new syntax extensions, lint checks, etc. extend the compiler's behavior with new syntax extensions, lint checks, etc.
A plugin is a dynamic library crate with a designated *registrar* function that A plugin is a dynamic library crate with a designated *registrar* function that
registers extensions with `rustc`. Other crates can use these extensions by registers extensions with `rustc`. Other crates can load these extensions using
loading the plugin crate with `#[plugin] extern crate`. See the the crate attribute `#![plugin(...)]`. See the
[`rustc::plugin`](../rustc/plugin/index.html) documentation for more about the [`rustc::plugin`](../rustc/plugin/index.html) documentation for more about the
mechanics of defining and loading a plugin. mechanics of defining and loading a plugin.
Arguments passed as `#[plugin=...]` or `#[plugin(...)]` are not interpreted by If present, arguments passed as `#![plugin(foo(... args ...))]` are not
rustc itself. They are provided to the plugin through the `Registry`'s [`args` interpreted by rustc itself. They are provided to the plugin through the
method](../rustc/plugin/registry/struct.Registry.html#method.args). `Registry`'s [`args` method](../rustc/plugin/registry/struct.Registry.html#method.args).
# Syntax extensions # Syntax extensions
@ -110,8 +110,7 @@ Then we can use `rn!()` like any other macro:
```ignore ```ignore
#![feature(plugin)] #![feature(plugin)]
#![plugin(roman_numerals)]
#[plugin] extern crate roman_numerals;
fn main() { fn main() {
assert_eq!(rn!(MMXV), 2015); assert_eq!(rn!(MMXV), 2015);
@ -219,7 +218,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
Then code like Then code like
```ignore ```ignore
#[plugin] extern crate lint_plugin_test; #![plugin(lint_plugin_test)]
fn lintme() { } fn lintme() { }
``` ```

View file

@ -26,7 +26,7 @@ use syntax::ast;
use syntax::abi; use syntax::abi;
use syntax::attr; use syntax::attr;
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
use syntax::codemap::{COMMAND_LINE_SP, Span, mk_sp}; use syntax::codemap::{Span, mk_sp};
use syntax::parse; use syntax::parse;
use syntax::parse::token::InternedString; use syntax::parse::token::InternedString;
use syntax::parse::token; use syntax::parse::token;
@ -457,13 +457,13 @@ impl<'a> CrateReader<'a> {
CrateOrString::Krate(c) => { CrateOrString::Krate(c) => {
(self.extract_crate_info(c).unwrap(), c.span) (self.extract_crate_info(c).unwrap(), c.span)
} }
CrateOrString::Str(s) => { CrateOrString::Str(sp, s) => {
(CrateInfo { (CrateInfo {
name: s.to_string(), name: s.to_string(),
ident: s.to_string(), ident: s.to_string(),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
should_link: true, should_link: true,
}, COMMAND_LINE_SP) }, sp)
} }
}; };
let target_triple = &self.sess.opts.target_triple[]; let target_triple = &self.sess.opts.target_triple[];
@ -531,7 +531,7 @@ impl<'a> CrateReader<'a> {
#[derive(Copy)] #[derive(Copy)]
pub enum CrateOrString<'a> { pub enum CrateOrString<'a> {
Krate(&'a ast::Item), Krate(&'a ast::Item),
Str(&'a str) Str(Span, &'a str)
} }
impl<'a> PluginMetadata<'a> { impl<'a> PluginMetadata<'a> {

View file

@ -18,9 +18,10 @@ use std::mem;
use std::env; use std::env;
use std::dynamic_lib::DynamicLibrary; use std::dynamic_lib::DynamicLibrary;
use std::collections::HashSet; use std::collections::HashSet;
use std::borrow::ToOwned;
use syntax::ast; use syntax::ast;
use syntax::attr; use syntax::attr;
use syntax::codemap::Span; use syntax::codemap::{Span, COMMAND_LINE_SP};
use syntax::parse::token; use syntax::parse::token;
use syntax::ptr::P; use syntax::ptr::P;
use syntax::visit; use syntax::visit;
@ -33,7 +34,7 @@ pub type PluginRegistrarFun =
pub struct PluginRegistrar { pub struct PluginRegistrar {
pub fun: PluginRegistrarFun, pub fun: PluginRegistrarFun,
pub args: P<ast::MetaItem>, pub args: Vec<P<ast::MetaItem>>,
} }
/// Information about loaded plugins. /// Information about loaded plugins.
@ -81,10 +82,34 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
visit::walk_crate(&mut loader, krate); visit::walk_crate(&mut loader, krate);
for attr in &krate.attrs {
if !attr.check_name("plugin") {
continue;
}
let plugins = match attr.meta_item_list() {
Some(xs) => xs,
None => {
sess.span_err(attr.span, "malformed plugin attribute");
continue;
}
};
for plugin in plugins {
if plugin.value_str().is_some() {
sess.span_err(attr.span, "malformed plugin attribute");
continue;
}
let args = plugin.meta_item_list().map(ToOwned::to_owned).unwrap_or_default();
loader.load_plugin(CrateOrString::Str(plugin.span, &*plugin.name()),
args);
}
}
if let Some(plugins) = addl_plugins { if let Some(plugins) = addl_plugins {
for plugin in plugins { for plugin in plugins {
loader.load_plugin(CrateOrString::Str(&plugin), loader.load_plugin(CrateOrString::Str(COMMAND_LINE_SP, &plugin), vec![]);
None, None, None)
} }
} }
@ -104,21 +129,16 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
} }
// Parse the attributes relating to macro / plugin loading. // Parse the attributes relating to macro / plugin loading.
let mut plugin_attr = None;
let mut macro_selection = Some(HashSet::new()); // None => load all let mut macro_selection = Some(HashSet::new()); // None => load all
let mut reexport = HashSet::new(); let mut reexport = HashSet::new();
for attr in &item.attrs { for attr in &item.attrs {
let mut used = true; let mut used = true;
match &attr.name()[] { match &attr.name()[] {
"phase" => { "phase" => {
self.sess.span_err(attr.span, "#[phase] is deprecated; use \ self.sess.span_err(attr.span, "#[phase] is deprecated");
#[macro_use], #[plugin], and/or #[no_link]");
} }
"plugin" => { "plugin" => {
if plugin_attr.is_some() { self.sess.span_err(attr.span, "#[plugin] on `extern crate` is deprecated");
self.sess.span_err(attr.span, "#[plugin] specified multiple times");
}
plugin_attr = Some(attr.node.value.clone());
} }
"macro_use" => { "macro_use" => {
let names = attr.meta_item_list(); let names = attr.meta_item_list();
@ -160,10 +180,7 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
} }
} }
self.load_plugin(CrateOrString::Krate(item), self.load_macros(item, macro_selection, Some(reexport))
plugin_attr,
macro_selection,
Some(reexport))
} }
fn visit_mac(&mut self, _: &ast::Mac) { fn visit_mac(&mut self, _: &ast::Mac) {
@ -173,38 +190,25 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
} }
impl<'a> PluginLoader<'a> { impl<'a> PluginLoader<'a> {
pub fn load_plugin<'b>(&mut self, pub fn load_macros<'b>(&mut self,
c: CrateOrString<'b>, vi: &ast::Item,
plugin_attr: Option<P<ast::MetaItem>>,
macro_selection: Option<HashSet<token::InternedString>>, macro_selection: Option<HashSet<token::InternedString>>,
reexport: Option<HashSet<token::InternedString>>) { reexport: Option<HashSet<token::InternedString>>) {
let mut macros = vec![]; if let (Some(sel), Some(re)) = (macro_selection.as_ref(), reexport.as_ref()) {
let mut registrar = None; if sel.is_empty() && re.is_empty() {
return;
}
}
let load_macros = match (macro_selection.as_ref(), reexport.as_ref()) { if !self.span_whitelist.contains(&vi.span) {
(Some(sel), Some(re)) => sel.len() != 0 || re.len() != 0,
_ => true,
};
let load_registrar = plugin_attr.is_some();
if let CrateOrString::Krate(vi) = c {
if load_macros && !self.span_whitelist.contains(&vi.span) {
self.sess.span_err(vi.span, "an `extern crate` loading macros must be at \ self.sess.span_err(vi.span, "an `extern crate` loading macros must be at \
the crate root"); the crate root");
} return;
} }
if load_macros || load_registrar { let pmd = self.reader.read_plugin_metadata(CrateOrString::Krate(vi));
let pmd = self.reader.read_plugin_metadata(c);
if load_macros {
macros = pmd.exported_macros();
}
if load_registrar {
registrar = pmd.plugin_registrar();
}
}
for mut def in macros { for mut def in pmd.exported_macros() {
let name = token::get_ident(def.ident); let name = token::get_ident(def.ident);
def.use_locally = match macro_selection.as_ref() { def.use_locally = match macro_selection.as_ref() {
None => true, None => true,
@ -217,12 +221,21 @@ impl<'a> PluginLoader<'a> {
}; };
self.plugins.macros.push(def); self.plugins.macros.push(def);
} }
}
pub fn load_plugin<'b>(&mut self,
c: CrateOrString<'b>,
args: Vec<P<ast::MetaItem>>) {
let registrar = {
let pmd = self.reader.read_plugin_metadata(c);
pmd.plugin_registrar()
};
if let Some((lib, symbol)) = registrar { if let Some((lib, symbol)) = registrar {
let fun = self.dylink_registrar(c, lib, symbol); let fun = self.dylink_registrar(c, lib, symbol);
self.plugins.registrars.push(PluginRegistrar { self.plugins.registrars.push(PluginRegistrar {
fun: fun, fun: fun,
args: plugin_attr.unwrap(), args: args,
}); });
} }
} }

View file

@ -44,14 +44,9 @@
//! //!
//! ```rust //! ```rust
//! #![feature(plugin)] //! #![feature(plugin)]
//! //! #![plugin(myplugin)]
//! #[plugin]
//! extern crate myplugin;
//! ``` //! ```
//! //!
//! If you don't need the plugin crate available at runtime, use
//! `#[no_link]` as well.
//!
//! See [the compiler plugin guide](../../guide-plugin.html) //! See [the compiler plugin guide](../../guide-plugin.html)
//! for more examples. //! for more examples.

View file

@ -37,7 +37,7 @@ pub struct Registry<'a> {
pub sess: &'a Session, pub sess: &'a Session,
#[doc(hidden)] #[doc(hidden)]
pub args_hidden: Option<P<ast::MetaItem>>, pub args_hidden: Option<Vec<P<ast::MetaItem>>>,
#[doc(hidden)] #[doc(hidden)]
pub krate_span: Span, pub krate_span: Span,
@ -65,11 +65,14 @@ impl<'a> Registry<'a> {
} }
} }
/// Get the `#[plugin]` attribute used to load this plugin. /// Get the plugin's arguments, if any.
/// ///
/// This gives access to arguments passed via `#[plugin=...]` or /// These are specified inside the `plugin` crate attribute as
/// `#[plugin(...)]`. ///
pub fn args<'b>(&'b self) -> &'b P<ast::MetaItem> { /// ```no_run
/// #![plugin(my_plugin_name(... args ...))]
/// ```
pub fn args<'b>(&'b self) -> &'b Vec<P<ast::MetaItem>> {
self.args_hidden.as_ref().expect("args not set") self.args_hidden.as_ref().expect("args not set")
} }

View file

@ -69,7 +69,6 @@ use rustc::session::config::{Input, PrintRequest, UnstableFeatures};
use rustc::lint::Lint; use rustc::lint::Lint;
use rustc::lint; use rustc::lint;
use rustc::metadata; use rustc::metadata;
use rustc::metadata::creader::CrateOrString::Str;
use rustc::util::common::time; use rustc::util::common::time;
use std::cmp::Ordering::Equal; use std::cmp::Ordering::Equal;

View file

@ -284,11 +284,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
} }
match i.node { match i.node {
ast::ItemExternCrate(_) => { ast::ItemExternCrate(_) => {
if attr::contains_name(&i.attrs[], "plugin") { if attr::contains_name(&i.attrs[], "macro_reexport") {
self.gate_feature("plugin", i.span,
"compiler plugins are experimental \
and possibly buggy");
} else if attr::contains_name(&i.attrs[], "macro_reexport") {
self.gate_feature("macro_reexport", i.span, self.gate_feature("macro_reexport", i.span,
"macros reexports are experimental \ "macros reexports are experimental \
and possibly buggy"); and possibly buggy");
@ -462,6 +458,10 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
if attr.check_name("staged_api") { if attr.check_name("staged_api") {
self.gate_feature("staged_api", attr.span, self.gate_feature("staged_api", attr.span,
"staged_api is for use by rustc only"); "staged_api is for use by rustc only");
} else if attr.check_name("plugin") {
self.gate_feature("plugin", attr.span,
"compiler plugins are experimental \
and possibly buggy");
} }
if attr::contains_name(slice::ref_slice(attr), "lang") { if attr::contains_name(slice::ref_slice(attr), "lang") {

View file

@ -27,7 +27,7 @@ use syntax::ptr::P;
use rustc::plugin::Registry; use rustc::plugin::Registry;
struct Expander { struct Expander {
args: P<ast::MetaItem>, args: Vec<P<ast::MetaItem>>,
} }
impl TTMacroExpander for Expander { impl TTMacroExpander for Expander {
@ -35,10 +35,9 @@ impl TTMacroExpander for Expander {
ecx: &'cx mut ExtCtxt, ecx: &'cx mut ExtCtxt,
sp: Span, sp: Span,
_: &[ast::TokenTree]) -> Box<MacResult+'cx> { _: &[ast::TokenTree]) -> Box<MacResult+'cx> {
let args = self.args.iter().map(|i| pprust::meta_item_to_string(&*i))
let attr = ecx.attribute(sp, self.args.clone()); .collect::<Vec<_>>().connect(", ");
let src = pprust::attribute_to_string(&attr); let interned = token::intern_and_get_ident(&args[]);
let interned = token::intern_and_get_ident(&src);
MacExpr::new(ecx.expr_str(sp, interned)) MacExpr::new(ecx.expr_str(sp, interned))
} }
} }

View file

@ -13,7 +13,7 @@
#![crate_type = "dylib"] #![crate_type = "dylib"]
#![feature(plugin_registrar, quote)] #![feature(plugin_registrar, quote)]
extern crate "syntax-extension-with-dll-deps-1" as other; extern crate "syntax_extension_with_dll_deps_1" as other;
extern crate syntax; extern crate syntax;
extern crate rustc; extern crate rustc;

View file

@ -11,7 +11,7 @@
// aux-build:macro_crate_test.rs // aux-build:macro_crate_test.rs
// ignore-stage1 // ignore-stage1
#[plugin] #[no_link] extern crate macro_crate_test; #![plugin(macro_crate_test)]
//~^ ERROR compiler plugins are experimental and possibly buggy //~^ ERROR compiler plugins are experimental and possibly buggy
fn main() {} fn main() {}

View file

@ -13,9 +13,7 @@
// compile-flags: -D lint-me // compile-flags: -D lint-me
#![feature(plugin)] #![feature(plugin)]
#![plugin(lint_group_plugin_test)]
#[plugin] #[no_link]
extern crate lint_group_plugin_test;
fn lintme() { } //~ ERROR item is named 'lintme' fn lintme() { } //~ ERROR item is named 'lintme'

View file

@ -12,11 +12,9 @@
// ignore-stage1 // ignore-stage1
#![feature(plugin)] #![feature(plugin)]
#![plugin(lint_plugin_test)]
#![deny(test_lint)] #![deny(test_lint)]
#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } //~ ERROR item is named 'lintme' fn lintme() { } //~ ERROR item is named 'lintme'
pub fn main() { pub fn main() {

View file

@ -13,9 +13,7 @@
// compile-flags: -D test-lint // compile-flags: -D test-lint
#![feature(plugin)] #![feature(plugin)]
#![plugin(lint_plugin_test)]
#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } //~ ERROR item is named 'lintme' fn lintme() { } //~ ERROR item is named 'lintme'

View file

@ -12,11 +12,9 @@
// ignore-stage1 // ignore-stage1
#![feature(plugin)] #![feature(plugin)]
#![plugin(lint_plugin_test)]
#![forbid(test_lint)] #![forbid(test_lint)]
#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } //~ ERROR item is named 'lintme' fn lintme() { } //~ ERROR item is named 'lintme'
#[allow(test_lint)] //~ ERROR allow(test_lint) overruled by outer forbid(test_lint) #[allow(test_lint)] //~ ERROR allow(test_lint) overruled by outer forbid(test_lint)

View file

@ -13,9 +13,7 @@
// compile-flags: -F test-lint // compile-flags: -F test-lint
#![feature(plugin)] #![feature(plugin)]
#![plugin(lint_plugin_test)]
#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } //~ ERROR item is named 'lintme' fn lintme() { } //~ ERROR item is named 'lintme'

View file

@ -21,9 +21,7 @@
// ident form. // ident form.
#![feature(plugin)] #![feature(plugin)]
#![plugin(macro_crate_test)]
#[plugin] #[no_link]
extern crate macro_crate_test;
fn main() { fn main() {
let x = 0; let x = 0;

View file

@ -15,7 +15,7 @@
// ignore-cross-compile gives a different error message // ignore-cross-compile gives a different error message
#![feature(plugin)] #![feature(plugin)]
#[plugin] #[no_link] extern crate rlib_crate_test; #![plugin(rlib_crate_test)]
//~^ ERROR: plugin crate `rlib_crate_test` only found in rlib format, but must be available in dylib format //~^ ERROR: plugin crate `rlib_crate_test` only found in rlib format, but must be available in dylib format
fn main() {} fn main() {}

View file

@ -14,8 +14,6 @@
// error-pattern: plugin tried to register a new MacroRulesTT // error-pattern: plugin tried to register a new MacroRulesTT
#![feature(plugin)] #![feature(plugin)]
#![plugin(macro_crate_MacroRulesTT)]
#[plugin] #[no_link]
extern crate macro_crate_MacroRulesTT;
fn main() { } fn main() { }

View file

@ -8,15 +8,6 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// aux-build:plugin_args.rs #![plugin] //~ ERROR malformed plugin attribute
// ignore-stage1
#![feature(plugin)] fn main() {}
#[no_link]
#[plugin="foobar"]
extern crate plugin_args;
fn main() {
assert_eq!(plugin_args!(), "#[plugin = \"foobar\"]");
}

View file

@ -0,0 +1,13 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![plugin="bleh"] //~ ERROR malformed plugin attribute
fn main() {}

View file

@ -0,0 +1,13 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![plugin(foo="bleh")] //~ ERROR malformed plugin attribute
fn main() {}

View file

@ -8,8 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#[plugin] #[plugin] //~ ERROR #[plugin] on `extern crate` is deprecated
#[plugin] //~ ERROR #[plugin] specified multiple times
extern crate std; extern crate std;
fn main() {} fn main() {}

View file

@ -12,8 +12,7 @@
// ignore-android // ignore-android
// aux-build:issue_16723_multiple_items_syntax_ext.rs // aux-build:issue_16723_multiple_items_syntax_ext.rs
#![feature(plugin)] #![feature(plugin)]
#![plugin(issue_16723_multiple_items_syntax_ext)]
#[plugin] #[no_link] extern crate issue_16723_multiple_items_syntax_ext;
multiple_items!(); multiple_items!();

View file

@ -13,9 +13,7 @@
// ignore-pretty // ignore-pretty
#![feature(plugin)] #![feature(plugin)]
#![plugin(lint_group_plugin_test)]
#[plugin] #[no_link]
extern crate lint_group_plugin_test;
fn lintme() { } //~ WARNING item is named 'lintme' fn lintme() { } //~ WARNING item is named 'lintme'
fn pleaselintme() { } //~ WARNING item is named 'pleaselintme' fn pleaselintme() { } //~ WARNING item is named 'pleaselintme'

View file

@ -13,9 +13,7 @@
// compile-flags: -A test-lint // compile-flags: -A test-lint
#![feature(plugin)] #![feature(plugin)]
#![plugin(lint_plugin_test)]
#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } fn lintme() { }

View file

@ -13,9 +13,7 @@
// ignore-pretty // ignore-pretty
#![feature(plugin)] #![feature(plugin)]
#![plugin(lint_plugin_test)]
#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } //~ WARNING item is named 'lintme' fn lintme() { } //~ WARNING item is named 'lintme'

View file

@ -15,9 +15,7 @@
// uses `quote_expr!` to rearrange it should be hygiene-preserving. // uses `quote_expr!` to rearrange it should be hygiene-preserving.
#![feature(plugin)] #![feature(plugin)]
#![plugin(macro_crate_test)]
#[plugin] #[no_link]
extern crate macro_crate_test;
fn main() { fn main() {
let x = 3; let x = 3;

View file

@ -12,8 +12,6 @@
// ignore-stage1 // ignore-stage1
#![feature(plugin)] #![feature(plugin)]
#![plugin(plugin_crate_outlive_expansion_phase)]
#[plugin] #[no_link]
extern crate plugin_crate_outlive_expansion_phase;
pub fn main() {} pub fn main() {}

View file

@ -12,8 +12,9 @@
// ignore-stage1 // ignore-stage1
#![feature(plugin)] #![feature(plugin)]
#![plugin(macro_crate_test)]
#[macro_use] #[plugin] #[no_link] #[macro_use] #[no_link]
extern crate macro_crate_test; extern crate macro_crate_test;
#[into_foo] #[into_foo]

View file

@ -12,11 +12,8 @@
// ignore-stage1 // ignore-stage1
#![feature(plugin)] #![feature(plugin)]
#![plugin(plugin_args)]
#[no_link]
#[plugin]
extern crate plugin_args;
fn main() { fn main() {
assert_eq!(plugin_args!(), "#[plugin]"); assert_eq!(plugin_args!(), "");
} }

View file

@ -12,11 +12,8 @@
// ignore-stage1 // ignore-stage1
#![feature(plugin)] #![feature(plugin)]
#![plugin(plugin_args())]
#[no_link]
#[plugin()]
extern crate plugin_args;
fn main() { fn main() {
assert_eq!(plugin_args!(), "#[plugin()]"); assert_eq!(plugin_args!(), "");
} }

View file

@ -12,11 +12,8 @@
// ignore-stage1 // ignore-stage1
#![feature(plugin)] #![feature(plugin)]
#![plugin(plugin_args(hello(there), how(are="you")))]
#[no_link]
#[plugin(hello(there), how(are="you"))]
extern crate plugin_args;
fn main() { fn main() {
assert_eq!(plugin_args!(), "#[plugin(hello(there), how(are = \"you\"))]"); assert_eq!(plugin_args!(), "hello(there), how(are = \"you\")");
} }

View file

@ -1,4 +1,4 @@
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at // file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT. // http://rust-lang.org/COPYRIGHT.
// //
@ -16,8 +16,8 @@
// libsyntax is not compiled for it. // libsyntax is not compiled for it.
#![feature(plugin)] #![feature(plugin)]
#![plugin(macro_crate_test)]
#[plugin]
extern crate macro_crate_test; extern crate macro_crate_test;
fn main() { fn main() {

View file

@ -12,9 +12,7 @@
// ignore-stage1 // ignore-stage1
#![feature(plugin)] #![feature(plugin)]
#![plugin(roman_numerals)]
#[plugin] #[no_link]
extern crate roman_numerals;
pub fn main() { pub fn main() {
assert_eq!(rn!(MMXV), 2015); assert_eq!(rn!(MMXV), 2015);

View file

@ -8,14 +8,12 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// aux-build:syntax-extension-with-dll-deps-1.rs // aux-build:syntax_extension_with_dll_deps_1.rs
// aux-build:syntax-extension-with-dll-deps-2.rs // aux-build:syntax_extension_with_dll_deps_2.rs
// ignore-stage1 // ignore-stage1
#![feature(plugin)] #![feature(plugin)]
#![plugin(syntax_extension_with_dll_deps_2)]
#[plugin] #[no_link]
extern crate "syntax-extension-with-dll-deps-2" as extension;
fn main() { fn main() {
foo!(); foo!();