) -> Plugins {
let mut loader = PluginLoader::new(sess);
+
+ // We need to error on `#[macro_use] extern crate` when it isn't at the
+ // crate root, because `$crate` won't work properly. Identify these by
+ // spans, because the crate map isn't set up yet.
+ for vi in krate.module.view_items.iter() {
+ loader.span_whitelist.insert(vi.span);
+ }
+
visit::walk_crate(&mut loader, krate);
let mut plugins = loader.plugins;
@@ -89,41 +97,112 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
// note that macros aren't expanded yet, and therefore macros can't add plugins.
impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
fn visit_view_item(&mut self, vi: &ast::ViewItem) {
+ // We're only interested in `extern crate`.
match vi.node {
- ast::ViewItemExternCrate(name, _, _) => {
- let mut plugin_phase = false;
+ ast::ViewItemExternCrate(..) => (),
+ _ => return,
+ }
- for attr in vi.attrs.iter().filter(|a| a.check_name("phase")) {
- let phases = attr.meta_item_list().unwrap_or(&[]);
- if attr::contains_name(phases, "plugin") {
- plugin_phase = true;
+ // 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 reexport = HashSet::new();
+ for attr in vi.attrs.iter() {
+ let mut used = true;
+ match attr.name().get() {
+ "phase" => {
+ self.sess.span_err(attr.span, "#[phase] is deprecated; use \
+ #[macro_use], #[plugin], and/or #[no_link]");
+ }
+ "plugin" => {
+ if plugin_attr.is_some() {
+ self.sess.span_err(attr.span, "#[plugin] specified multiple times");
+ }
+ plugin_attr = Some(attr.node.value.clone());
+ }
+ "macro_use" => {
+ let names = attr.meta_item_list();
+ if names.is_none() {
+ // no names => load all
+ macro_selection = None;
+ }
+ if let (Some(sel), Some(names)) = (macro_selection.as_mut(), names) {
+ for name in names.iter() {
+ if let ast::MetaWord(ref name) = name.node {
+ sel.insert(name.clone());
+ } else {
+ self.sess.span_err(name.span, "bad macro import");
+ }
+ }
}
- if attr::contains_name(phases, "syntax") {
- plugin_phase = true;
- self.sess.span_warn(attr.span,
- "phase(syntax) is a deprecated synonym for phase(plugin)");
+ }
+ "macro_reexport" => {
+ let names = match attr.meta_item_list() {
+ Some(names) => names,
+ None => {
+ self.sess.span_err(attr.span, "bad macro reexport");
+ continue;
+ }
+ };
+
+ for name in names.iter() {
+ if let ast::MetaWord(ref name) = name.node {
+ reexport.insert(name.clone());
+ } else {
+ self.sess.span_err(name.span, "bad macro reexport");
+ }
}
}
+ _ => used = false,
+ }
+ if used {
+ attr::mark_used(attr);
+ }
+ }
- if !plugin_phase { return; }
+ let mut macros = vec![];
+ let mut registrar = None;
- let PluginMetadata { macros, lib, registrar_symbol } =
- self.reader.read_plugin_metadata(vi);
+ let load_macros = match macro_selection.as_ref() {
+ Some(sel) => sel.len() != 0 || reexport.len() != 0,
+ None => true,
+ };
+ let load_registrar = plugin_attr.is_some();
- self.plugins.macros.push(ExportedMacros {
- crate_name: name,
- macros: macros,
- });
+ if load_macros && !self.span_whitelist.contains(&vi.span) {
+ self.sess.span_err(vi.span, "an `extern crate` loading macros must be at \
+ the crate root");
+ }
- match (lib, registrar_symbol) {
- (Some(lib), Some(symbol))
- => self.dylink_registrar(vi, lib, symbol),
- _ => (),
- }
+ if load_macros || load_registrar {
+ let pmd = self.reader.read_plugin_metadata(vi);
+ if load_macros {
+ macros = pmd.exported_macros();
+ }
+ if load_registrar {
+ registrar = pmd.plugin_registrar();
}
- _ => (),
+ }
+
+ for mut def in macros.into_iter() {
+ let name = token::get_ident(def.ident);
+ def.use_locally = match macro_selection.as_ref() {
+ None => true,
+ Some(sel) => sel.contains(&name),
+ };
+ def.export = reexport.contains(&name);
+ self.plugins.macros.push(def);
+ }
+
+ if let Some((lib, symbol)) = registrar {
+ let fun = self.dylink_registrar(vi, lib, symbol);
+ self.plugins.registrars.push(PluginRegistrar {
+ fun: fun,
+ args: plugin_attr.unwrap(),
+ });
}
}
+
fn visit_mac(&mut self, _: &ast::Mac) {
// bummer... can't see plugins inside macros.
// do nothing.
@@ -132,7 +211,10 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
impl<'a> PluginLoader<'a> {
// Dynamically link a registrar function into the compiler process.
- fn dylink_registrar(&mut self, vi: &ast::ViewItem, path: Path, symbol: String) {
+ fn dylink_registrar(&mut self,
+ vi: &ast::ViewItem,
+ path: Path,
+ symbol: String) -> PluginRegistrarFun {
// Make sure the path contains a / or the linker will search for it.
let path = os::make_absolute(&path).unwrap();
@@ -154,13 +236,12 @@ impl<'a> PluginLoader<'a> {
Err(err) => self.sess.span_fatal(vi.span, err[])
};
- self.plugins.registrars.push(registrar);
-
// 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 task).
mem::forget(lib);
+ registrar
}
}
}
diff --git a/src/librustc/plugin/mod.rs b/src/librustc/plugin/mod.rs
index 8dd60880cdd56..fd8873454b4d9 100644
--- a/src/librustc/plugin/mod.rs
+++ b/src/librustc/plugin/mod.rs
@@ -43,14 +43,14 @@
//! To use a plugin while compiling another crate:
//!
//! ```rust
-//! #![feature(phase)]
+//! #![feature(plugin)]
//!
-//! #[phase(plugin)]
+//! #[plugin]
//! extern crate myplugin;
//! ```
//!
-//! If you also need the plugin crate available at runtime, use
-//! `phase(plugin, link)`.
+//! If you don't need the plugin crate available at runtime, use
+//! `#[no_link]` as well.
//!
//! See [the compiler plugin guide](../../guide-plugin.html)
//! for more examples.
diff --git a/src/librustc/plugin/registry.rs b/src/librustc/plugin/registry.rs
index 99e870a901e08..feec97f02da55 100644
--- a/src/librustc/plugin/registry.rs
+++ b/src/librustc/plugin/registry.rs
@@ -11,12 +11,14 @@
//! Used by plugin crates to tell `rustc` about the plugins they provide.
use lint::{LintPassObject, LintId, Lint};
+use session::Session;
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
-use syntax::ext::base::{IdentTT, LetSyntaxTT, Decorator, Modifier};
+use syntax::ext::base::{IdentTT, Decorator, Modifier, MacroRulesTT};
use syntax::ext::base::{MacroExpanderFn};
use syntax::codemap::Span;
use syntax::parse::token;
+use syntax::ptr::P;
use syntax::ast;
use std::collections::HashMap;
@@ -29,7 +31,14 @@ use std::collections::HashMap;
/// This struct has public fields and other methods for use by `rustc`
/// itself. They are not documented here, and plugin authors should
/// not use them.
-pub struct Registry {
+pub struct Registry<'a> {
+ /// Compiler session. Useful if you want to emit diagnostic messages
+ /// from the plugin registrar.
+ pub sess: &'a Session,
+
+ #[doc(hidden)]
+ pub args_hidden: Option>,
+
#[doc(hidden)]
pub krate_span: Span,
@@ -43,10 +52,12 @@ pub struct Registry {
pub lint_groups: HashMap<&'static str, Vec>,
}
-impl Registry {
+impl<'a> Registry<'a> {
#[doc(hidden)]
- pub fn new(krate: &ast::Crate) -> Registry {
+ pub fn new(sess: &'a Session, krate: &ast::Crate) -> Registry<'a> {
Registry {
+ sess: sess,
+ args_hidden: None,
krate_span: krate.span,
syntax_exts: vec!(),
lint_passes: vec!(),
@@ -54,6 +65,14 @@ impl Registry {
}
}
+ /// Get the `#[plugin]` attribute used to load this plugin.
+ ///
+ /// This gives access to arguments passed via `#[plugin=...]` or
+ /// `#[plugin(...)]`.
+ pub fn args<'b>(&'b self) -> &'b P {
+ self.args_hidden.as_ref().expect("args not set")
+ }
+
/// Register a syntax extension of any kind.
///
/// This is the most general hook into `libsyntax`'s expansion behavior.
@@ -63,8 +82,11 @@ impl Registry {
IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)),
Decorator(ext) => Decorator(ext),
Modifier(ext) => Modifier(ext),
- // there's probably a nicer way to signal this:
- LetSyntaxTT(_, _) => panic!("can't register a new LetSyntax!"),
+
+ MacroRulesTT => {
+ self.sess.err("plugin tried to register a new MacroRulesTT");
+ return;
+ }
}));
}
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
index 2bb99a7141f70..238c84e88a9e0 100644
--- a/src/librustc_back/lib.rs
+++ b/src/librustc_back/lib.rs
@@ -34,8 +34,14 @@
#![feature(unboxed_closures)]
#![feature(old_orphan_check)]
+#[cfg(stage0)]
#[phase(plugin, link)]
extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
extern crate syntax;
extern crate serialize;
diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs
index 1e55f442fb9ac..d606c5158d0f7 100644
--- a/src/librustc_back/sha2.rs
+++ b/src/librustc_back/sha2.rs
@@ -346,12 +346,12 @@ impl Engine256State {
// Sha-512 and Sha-256 use basically the same calculations which are implemented
// by these macros. Inlining the calculations seems to result in better generated code.
- macro_rules! schedule_round( ($t:expr) => (
+ macro_rules! schedule_round { ($t:expr) => (
w[$t] = sigma1(w[$t - 2]) + w[$t - 7] + sigma0(w[$t - 15]) + w[$t - 16];
)
- );
+ }
- macro_rules! sha2_round(
+ macro_rules! sha2_round {
($A:ident, $B:ident, $C:ident, $D:ident,
$E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
{
@@ -360,7 +360,7 @@ impl Engine256State {
$H += sum0($A) + maj($A, $B, $C);
}
)
- );
+ }
read_u32v_be(w.slice_mut(0, 16), data);
diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs
index 2ae88aa4476f7..86bd74d3f85e5 100644
--- a/src/librustc_back/svh.rs
+++ b/src/librustc_back/svh.rs
@@ -327,11 +327,11 @@ mod svh_visitor {
impl<'a, 'v> Visitor<'v> for StrictVersionHashVisitor<'a> {
- fn visit_mac(&mut self, macro: &Mac) {
+ fn visit_mac(&mut self, mac: &Mac) {
// macro invocations, namely macro_rules definitions,
// *can* appear as items, even in the expanded crate AST.
- if macro_name(macro).get() == "macro_rules" {
+ if macro_name(mac).get() == "macro_rules" {
// Pretty-printing definition to a string strips out
// surface artifacts (currently), such as the span
// information, yielding a content-based hash.
@@ -341,7 +341,7 @@ mod svh_visitor {
// trees might be faster. Implementing this is far
// easier in short term.
let macro_defn_as_string = pprust::to_string(|pp_state| {
- pp_state.print_mac(macro, token::Paren)
+ pp_state.print_mac(mac, token::Paren)
});
macro_defn_as_string.hash(self.st);
} else {
@@ -349,14 +349,14 @@ mod svh_visitor {
// invocation at this stage except `macro_rules!`.
panic!("reached macro somehow: {}",
pprust::to_string(|pp_state| {
- pp_state.print_mac(macro, token::Paren)
+ pp_state.print_mac(mac, token::Paren)
}));
}
- visit::walk_mac(self, macro);
+ visit::walk_mac(self, mac);
- fn macro_name(macro: &Mac) -> token::InternedString {
- match ¯o.node {
+ fn macro_name(mac: &Mac) -> token::InternedString {
+ match &mac.node {
&MacInvocTT(ref path, ref _tts, ref _stx_ctxt) => {
let s = path.segments[];
assert_eq!(s.len(), 1);
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index d53f97c3a0423..f14583bb9aa81 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -239,7 +239,7 @@ impl Target {
options: Default::default(),
};
- macro_rules! key (
+ macro_rules! key {
($key_name:ident) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(name[]).map(|o| o.as_string()
@@ -257,7 +257,7 @@ impl Target {
)
);
} );
- );
+ }
key!(cpu);
key!(linker);
@@ -305,7 +305,7 @@ impl Target {
}
// this would use a match if stringify! were allowed in pattern position
- macro_rules! load_specific (
+ macro_rules! load_specific {
( $($name:ident),+ ) => (
{
let target = target.replace("-", "_");
@@ -326,7 +326,7 @@ impl Target {
}
}
)
- );
+ }
load_specific!(
x86_64_unknown_linux_gnu,
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 75545634b40cf..fd46a03553771 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -39,15 +39,6 @@ use syntax::visit;
use syntax::visit::{Visitor, FnKind};
use syntax::ast::{FnDecl, Block, NodeId};
-macro_rules! if_ok {
- ($inp: expr) => (
- match $inp {
- Ok(v) => { v }
- Err(e) => { return Err(e); }
- }
- )
-}
-
pub mod doc;
pub mod check_loans;
diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs
index b886883c73ad2..0600ddba01897 100644
--- a/src/librustc_borrowck/lib.rs
+++ b/src/librustc_borrowck/lib.rs
@@ -24,8 +24,21 @@
#![feature(old_orphan_check)]
#![allow(non_camel_case_types)]
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
// for "clarity", rename the graphviz crate to dot; graphviz within `borrowck`
// refers to the borrowck-specific graphviz adapter traits.
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 1455aa3c99bb3..c88ffffecc32d 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -12,7 +12,7 @@ use rustc::session::Session;
use rustc::session::config::{self, Input, OutputFilenames};
use rustc::session::search_paths::PathKind;
use rustc::lint;
-use rustc::metadata::creader;
+use rustc::metadata::creader::CrateReader;
use rustc::middle::{stability, ty, reachable};
use rustc::middle::dependency_format;
use rustc::middle;
@@ -182,7 +182,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
// strip before expansion to allow macros to depend on
// configuration variables e.g/ in
//
- // #[macro_escape] #[cfg(foo)]
+ // #[macro_use] #[cfg(foo)]
// mod bar { macro_rules! baz!(() => {{}}) }
//
// baz! should not use this definition unless foo is enabled.
@@ -216,9 +216,9 @@ pub fn phase_2_configure_and_expand(sess: &Session,
= time(time_passes, "plugin loading", (), |_|
plugin::load::load_plugins(sess, &krate, addl_plugins.take().unwrap()));
- let mut registry = Registry::new(&krate);
+ let mut registry = Registry::new(sess, &krate);
- time(time_passes, "plugin registration", (), |_| {
+ time(time_passes, "plugin registration", registrars, |registrars| {
if sess.features.borrow().rustc_diagnostic_macros {
registry.register_macro("__diagnostic_used",
diagnostics::plugin::expand_diagnostic_used);
@@ -228,8 +228,9 @@ pub fn phase_2_configure_and_expand(sess: &Session,
diagnostics::plugin::expand_build_diagnostic_array);
}
- for ®istrar in registrars.iter() {
- registrar(&mut registry);
+ for registrar in registrars.into_iter() {
+ registry.args_hidden = Some(registrar.args);
+ (registrar.fun)(&mut registry);
}
});
@@ -352,7 +353,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
let krate = ast_map.krate();
time(time_passes, "external crate/lib resolution", (), |_|
- creader::read_crates(&sess, krate));
+ CrateReader::new(&sess).read_crates(krate));
let lang_items = time(time_passes, "language item collection", (), |_|
middle::lang_items::collect_language_items(krate, &sess));
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 983188c709000..a43ee3e6d338d 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -39,11 +39,25 @@ extern crate rustc_borrowck;
extern crate rustc_resolve;
extern crate rustc_trans;
extern crate rustc_typeck;
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
extern crate serialize;
extern crate "rustc_llvm" as llvm;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
+
pub use syntax::diagnostic;
use rustc_trans::back::link;
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index d972229e7c75b..61fd7d16ab7dd 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -484,8 +484,8 @@ impl fold::Folder for ReplaceBodyWithLoop {
// in general the pretty printer processes unexpanded code, so
// we override the default `fold_mac` method which panics.
- fn fold_mac(&mut self, _macro: ast::Mac) -> ast::Mac {
- fold::noop_fold_mac(_macro, self)
+ fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+ fold::noop_fold_mac(mac, self)
}
}
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 2c2678c8dc68e..2237ec53ea177 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -20,8 +20,21 @@
#![feature(rustc_diagnostic_macros)]
#![feature(associated_types)]
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
extern crate rustc;
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 9dbff66aba286..705fecf4d198e 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -37,11 +37,25 @@ extern crate graphviz;
extern crate libc;
extern crate rustc;
extern crate rustc_back;
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
extern crate serialize;
extern crate "rustc_llvm" as llvm;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
+
pub use rustc::session;
pub use rustc::metadata;
pub use rustc::middle;
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index e5a0e2e9234d5..b121dbec011c9 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -741,7 +741,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
}
fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option {
- macro_rules! ifn (
+ macro_rules! ifn {
($name:expr fn() -> $ret:expr) => (
if *key == $name {
let f = base::decl_cdecl_fn(
@@ -759,10 +759,10 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option (Type::struct_(ccx, &[$($field_ty),*], false))
- );
+ }
let i8p = Type::i8p(ccx);
let void = Type::void(ccx);
@@ -883,7 +883,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option $ret:expr) => (
if unsafe { llvm::LLVMVersionMinor() >= 4 } {
// The `if key == $name` is already in ifn!
@@ -896,7 +896,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option t_f32);
compatible_ifn!("llvm.copysign.f64", copysign(t_f64, t_f64) -> t_f64);
diff --git a/src/librustc_trans/trans/macros.rs b/src/librustc_trans/trans/macros.rs
index ab202975bfc15..77efcc6fb0030 100644
--- a/src/librustc_trans/trans/macros.rs
+++ b/src/librustc_trans/trans/macros.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![macro_escape]
-
macro_rules! unpack_datum {
($bcx: ident, $inp: expr) => (
{
diff --git a/src/librustc_trans/trans/mod.rs b/src/librustc_trans/trans/mod.rs
index 72c4def15a215..fa9cd5a698bbe 100644
--- a/src/librustc_trans/trans/mod.rs
+++ b/src/librustc_trans/trans/mod.rs
@@ -16,8 +16,11 @@ pub use self::base::trans_crate;
pub use self::context::CrateContext;
pub use self::common::gensym_name;
-mod doc;
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
mod macros;
+
+mod doc;
mod inline;
mod monomorphize;
mod controlflow;
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 48f9b12971971..7206a71001be2 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -77,8 +77,21 @@ This API is completely unstable and subject to change.
#![feature(unboxed_closures)]
#![allow(non_camel_case_types)]
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
extern crate arena;
extern crate rustc;
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index cfaae1a9f80fd..30b9d6c63c5bb 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -166,6 +166,9 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
}
}
+ // Special macro vars are like keywords
+ token::SpecialVarNt(_) => "kw-2",
+
token::Lifetime(..) => "lifetime",
token::DocComment(..) => "doccomment",
token::Underscore | token::Eof | token::Interpolated(..) |
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 106fe452f46a6..6e42c50f974c5 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -32,7 +32,14 @@ extern crate rustc_driver;
extern crate serialize;
extern crate syntax;
extern crate "test" as testing;
-#[phase(plugin, link)] extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
extern crate "serialize" as rustc_serialize; // used by deriving
@@ -49,11 +56,13 @@ use rustc::session::search_paths::SearchPaths;
// reexported from `clean` so it can be easily updated with the mod itself
pub use clean::SCHEMA_VERSION;
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+pub mod externalfiles;
+
pub mod clean;
pub mod core;
pub mod doctree;
-#[macro_escape]
-pub mod externalfiles;
pub mod fold;
pub mod html {
pub mod highlight;
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index c98ec97ab87f0..ad67672ea6ea7 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -73,7 +73,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
None);
// attach the crate's exported macros to the top-level module:
self.module.macros = krate.exported_macros.iter()
- .map(|it| self.visit_macro(&**it)).collect();
+ .map(|def| self.visit_macro(def)).collect();
self.module.is_crate = true;
}
@@ -363,13 +363,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
// convert each exported_macro into a doc item
- fn visit_macro(&self, item: &ast::Item) -> Macro {
+ fn visit_macro(&self, def: &ast::MacroDef) -> Macro {
Macro {
- id: item.id,
- attrs: item.attrs.clone(),
- name: item.ident,
- whence: item.span,
- stab: self.stability(item.id),
+ id: def.id,
+ attrs: def.attrs.clone(),
+ name: def.ident,
+ whence: def.span,
+ stab: self.stability(def.id),
}
}
}
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 8ad2013f9368f..8fe15f00ded73 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -31,8 +31,14 @@ Core encoding and decoding interfaces.
#[cfg(test)]
extern crate test;
+#[cfg(stage0)]
#[phase(plugin, link)]
extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
extern crate unicode;
extern crate collections;
diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs
index 65cbce08543cc..ed3f2cbe1a1da 100644
--- a/src/libstd/bitflags.rs
+++ b/src/libstd/bitflags.rs
@@ -9,7 +9,6 @@
// except according to those terms.
#![experimental]
-#![macro_escape]
//! A typesafe bitmask flag generator.
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index b1824db93aad1..b1906da43558f 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -21,7 +21,9 @@ use hash::{Hash, Hasher, RandomSipHasher};
use iter::{Iterator, IteratorExt, IteratorCloneExt, FromIterator, Map, Chain, Extend};
use ops::{BitOr, BitAnd, BitXor, Sub};
use option::Option::{Some, None, self};
-use result::Result::{Ok, Err};
+
+// NOTE: for old macros; remove after the next snapshot
+#[cfg(stage0)] use result::Result::{Ok, Err};
use super::map::{self, HashMap, Keys, INITIAL_CAPACITY};
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index c56acd38e810f..0882efde232fe 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -18,11 +18,14 @@ use iter::ExactSizeIterator;
use ops::Drop;
use option::Option;
use option::Option::{Some, None};
-use result::Result::{Ok, Err};
+use result::Result::Ok;
use slice::{SliceExt};
use slice;
use vec::Vec;
+// NOTE: for old macros; remove after the next snapshot
+#[cfg(stage0)] use result::Result::Err;
+
/// Wraps a Reader and buffers input from it
///
/// It can be excessively inefficient to work directly with a `Reader`. For
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 3fa0b5645c528..e9386c30a6dad 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -282,10 +282,13 @@ pub mod net;
pub mod pipe;
pub mod process;
pub mod stdio;
-pub mod test;
pub mod timer;
pub mod util;
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+pub mod test;
+
/// The default buffer size for various I/O operations
// libuv recommends 64k buffers to maximize throughput
// https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
diff --git a/src/libstd/io/test.rs b/src/libstd/io/test.rs
index 3ce56c907b33d..6eeef175f73d5 100644
--- a/src/libstd/io/test.rs
+++ b/src/libstd/io/test.rs
@@ -10,8 +10,6 @@
//! Various utility functions useful for writing I/O tests
-#![macro_escape]
-
use prelude::v1::*;
use libc;
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 608ad9882b977..65c36d813f478 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -117,13 +117,36 @@
#![reexport_test_harness_main = "test_main"]
-#[cfg(test)] #[phase(plugin, link)] extern crate log;
+#[cfg(all(test, stage0))]
+#[phase(plugin, link)]
+extern crate log;
-extern crate alloc;
-extern crate unicode;
+#[cfg(all(test, not(stage0)))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate core;
+
+#[cfg(not(stage0))]
+#[macro_use]
+#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
+ unreachable, unimplemented, write, writeln)]
extern crate core;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate "collections" as core_collections;
+
+#[cfg(not(stage0))]
+#[macro_use]
+#[macro_reexport(vec)]
extern crate "collections" as core_collections;
+
extern crate "rand" as core_rand;
+extern crate alloc;
+extern crate unicode;
extern crate libc;
// Make std testable by not duplicating lang items. See #2912
@@ -167,7 +190,18 @@ pub use unicode::char;
/* Exported macros */
+#[cfg(stage0)]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+pub mod macros_stage0;
+
+#[cfg(not(stage0))]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
pub mod macros;
+
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
pub mod bitflags;
mod rtdeps;
@@ -179,9 +213,20 @@ pub mod prelude;
/* Primitive types */
-#[path = "num/float_macros.rs"] mod float_macros;
-#[path = "num/int_macros.rs"] mod int_macros;
-#[path = "num/uint_macros.rs"] mod uint_macros;
+#[path = "num/float_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod float_macros;
+
+#[path = "num/int_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod int_macros;
+
+#[path = "num/uint_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod uint_macros;
#[path = "num/int.rs"] pub mod int;
#[path = "num/i8.rs"] pub mod i8;
@@ -208,7 +253,10 @@ pub mod num;
/* Runtime and platform support */
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
pub mod thread_local;
+
pub mod c_str;
pub mod c_vec;
pub mod dynamic_lib;
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 63fd3209cc019..6bf1ba2355f8d 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -15,7 +15,6 @@
//! library.
#![experimental]
-#![macro_escape]
/// The entry point for panic of Rust tasks.
///
@@ -57,179 +56,6 @@ macro_rules! panic {
});
}
-/// Ensure that a boolean expression is `true` at runtime.
-///
-/// This will invoke the `panic!` macro if the provided expression cannot be
-/// evaluated to `true` at runtime.
-///
-/// # Example
-///
-/// ```
-/// // the panic message for these assertions is the stringified value of the
-/// // expression given.
-/// assert!(true);
-/// # fn some_computation() -> bool { true }
-/// assert!(some_computation());
-///
-/// // assert with a custom message
-/// # let x = true;
-/// assert!(x, "x wasn't true!");
-/// # let a = 3i; let b = 27i;
-/// assert!(a + b == 30, "a = {}, b = {}", a, b);
-/// ```
-#[macro_export]
-macro_rules! assert {
- ($cond:expr) => (
- if !$cond {
- panic!(concat!("assertion failed: ", stringify!($cond)))
- }
- );
- ($cond:expr, $($arg:expr),+) => (
- if !$cond {
- panic!($($arg),+)
- }
- );
-}
-
-/// Asserts that two expressions are equal to each other, testing equality in
-/// both directions.
-///
-/// On panic, this macro will print the values of the expressions.
-///
-/// # Example
-///
-/// ```
-/// let a = 3i;
-/// let b = 1i + 2i;
-/// assert_eq!(a, b);
-/// ```
-#[macro_export]
-macro_rules! assert_eq {
- ($left:expr , $right:expr) => ({
- match (&($left), &($right)) {
- (left_val, right_val) => {
- // check both directions of equality....
- if !((*left_val == *right_val) &&
- (*right_val == *left_val)) {
- panic!("assertion failed: `(left == right) && (right == left)` \
- (left: `{}`, right: `{}`)", *left_val, *right_val)
- }
- }
- }
- })
-}
-
-/// Ensure that a boolean expression is `true` at runtime.
-///
-/// This will invoke the `panic!` macro if the provided expression cannot be
-/// evaluated to `true` at runtime.
-///
-/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
-/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for
-/// checks that are too expensive to be present in a release build but may be
-/// helpful during development.
-///
-/// # Example
-///
-/// ```
-/// // the panic message for these assertions is the stringified value of the
-/// // expression given.
-/// debug_assert!(true);
-/// # fn some_expensive_computation() -> bool { true }
-/// debug_assert!(some_expensive_computation());
-///
-/// // assert with a custom message
-/// # let x = true;
-/// debug_assert!(x, "x wasn't true!");
-/// # let a = 3i; let b = 27i;
-/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
-/// ```
-#[macro_export]
-macro_rules! debug_assert {
- ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
-}
-
-/// Asserts that two expressions are equal to each other, testing equality in
-/// both directions.
-///
-/// On panic, this macro will print the values of the expressions.
-///
-/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
-/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
-/// useful for checks that are too expensive to be present in a release build
-/// but may be helpful during development.
-///
-/// # Example
-///
-/// ```
-/// let a = 3i;
-/// let b = 1i + 2i;
-/// debug_assert_eq!(a, b);
-/// ```
-#[macro_export]
-macro_rules! debug_assert_eq {
- ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
-}
-
-/// A utility macro for indicating unreachable code.
-///
-/// This is useful any time that the compiler can't determine that some code is unreachable. For
-/// example:
-///
-/// * Match arms with guard conditions.
-/// * Loops that dynamically terminate.
-/// * Iterators that dynamically terminate.
-///
-/// # Panics
-///
-/// This will always panic.
-///
-/// # Examples
-///
-/// Match arms:
-///
-/// ```rust
-/// fn foo(x: Option) {
-/// match x {
-/// Some(n) if n >= 0 => println!("Some(Non-negative)"),
-/// Some(n) if n < 0 => println!("Some(Negative)"),
-/// Some(_) => unreachable!(), // compile error if commented out
-/// None => println!("None")
-/// }
-/// }
-/// ```
-///
-/// Iterators:
-///
-/// ```rust
-/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
-/// for i in std::iter::count(0_u32, 1) {
-/// if 3*i < i { panic!("u32 overflow"); }
-/// if x < 3*i { return i-1; }
-/// }
-/// unreachable!();
-/// }
-/// ```
-#[macro_export]
-macro_rules! unreachable {
- () => ({
- panic!("internal error: entered unreachable code")
- });
- ($msg:expr) => ({
- unreachable!("{}", $msg)
- });
- ($fmt:expr, $($arg:tt)*) => ({
- panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
- });
-}
-
-/// A standardised placeholder for marking unfinished code. It panics with the
-/// message `"not yet implemented"` when executed.
-#[macro_export]
-macro_rules! unimplemented {
- () => (panic!("not yet implemented"))
-}
-
/// Use the syntax described in `std::fmt` to create a value of type `String`.
/// See `std::fmt` for more information.
///
@@ -246,34 +72,6 @@ macro_rules! format {
($($arg:tt)*) => (::std::fmt::format(format_args!($($arg)*)))
}
-/// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
-/// See `std::fmt` for more information.
-///
-/// # Example
-///
-/// ```
-/// # #![allow(unused_must_use)]
-///
-/// let mut w = Vec::new();
-/// write!(&mut w, "test");
-/// write!(&mut w, "formatted {}", "arguments");
-/// ```
-#[macro_export]
-#[stable]
-macro_rules! write {
- ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*)))
-}
-
-/// Equivalent to the `write!` macro, except that a newline is appended after
-/// the message is written.
-#[macro_export]
-#[stable]
-macro_rules! writeln {
- ($dst:expr, $fmt:expr $($arg:tt)*) => (
- write!($dst, concat!($fmt, "\n") $($arg)*)
- )
-}
-
/// Equivalent to the `println!` macro except that a newline is not printed at
/// the end of the message.
#[macro_export]
@@ -306,23 +104,15 @@ macro_rules! println {
#[macro_export]
macro_rules! try {
($expr:expr) => ({
+ use $crate::result::Result::{Ok, Err};
+
match $expr {
Ok(val) => val,
- Err(err) => return Err(::std::error::FromError::from_error(err))
+ Err(err) => return Err($crate::error::FromError::from_error(err)),
}
})
}
-/// Create a `std::vec::Vec` containing the arguments.
-#[macro_export]
-macro_rules! vec {
- ($($x:expr),*) => ({
- let xs: ::std::boxed::Box<[_]> = box [$($x),*];
- ::std::slice::SliceExt::into_vec(xs)
- });
- ($($x:expr,)*) => (vec![$($x),*])
-}
-
/// A macro to select an event from a number of receivers.
///
/// This macro is used to wait for the first event to occur on a number of
@@ -358,7 +148,7 @@ macro_rules! select {
(
$($name:pat = $rx:ident.$meth:ident() => $code:expr),+
) => ({
- use std::sync::mpsc::Select;
+ use $crate::sync::mpsc::Select;
let sel = Select::new();
$( let mut $rx = sel.handle(&$rx); )+
unsafe {
diff --git a/src/libstd/macros_stage0.rs b/src/libstd/macros_stage0.rs
new file mode 100644
index 0000000000000..48d62e73e13ed
--- /dev/null
+++ b/src/libstd/macros_stage0.rs
@@ -0,0 +1,648 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Standard library macros
+//!
+//! This modules contains a set of macros which are exported from the standard
+//! library. Each macro is available for use when linking against the standard
+//! library.
+
+#![experimental]
+
+/// The entry point for panic of Rust tasks.
+///
+/// This macro is used to inject panic into a Rust task, causing the task to
+/// unwind and panic entirely. Each task's panic can be reaped as the
+/// `Box` type, and the single-argument form of the `panic!` macro will be
+/// the value which is transmitted.
+///
+/// The multi-argument form of this macro panics with a string and has the
+/// `format!` syntax for building a string.
+///
+/// # Example
+///
+/// ```should_fail
+/// # #![allow(unreachable_code)]
+/// panic!();
+/// panic!("this is a terrible mistake!");
+/// panic!(4i); // panic with the value of 4 to be collected elsewhere
+/// panic!("this is a {} {message}", "fancy", message = "message");
+/// ```
+#[macro_export]
+macro_rules! panic {
+ () => ({
+ panic!("explicit panic")
+ });
+ ($msg:expr) => ({
+ // static requires less code at runtime, more constant data
+ static _FILE_LINE: (&'static str, uint) = (file!(), line!());
+ ::std::rt::begin_unwind($msg, &_FILE_LINE)
+ });
+ ($fmt:expr, $($arg:tt)*) => ({
+ // The leading _'s are to avoid dead code warnings if this is
+ // used inside a dead function. Just `#[allow(dead_code)]` is
+ // insufficient, since the user may have
+ // `#[forbid(dead_code)]` and which cannot be overridden.
+ static _FILE_LINE: (&'static str, uint) = (file!(), line!());
+ ::std::rt::begin_unwind_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE)
+
+ });
+}
+
+/// Ensure that a boolean expression is `true` at runtime.
+///
+/// This will invoke the `panic!` macro if the provided expression cannot be
+/// evaluated to `true` at runtime.
+///
+/// # Example
+///
+/// ```
+/// // the panic message for these assertions is the stringified value of the
+/// // expression given.
+/// assert!(true);
+/// # fn some_computation() -> bool { true }
+/// assert!(some_computation());
+///
+/// // assert with a custom message
+/// # let x = true;
+/// assert!(x, "x wasn't true!");
+/// # let a = 3i; let b = 27i;
+/// assert!(a + b == 30, "a = {}, b = {}", a, b);
+/// ```
+#[macro_export]
+macro_rules! assert {
+ ($cond:expr) => (
+ if !$cond {
+ panic!(concat!("assertion failed: ", stringify!($cond)))
+ }
+ );
+ ($cond:expr, $($arg:expr),+) => (
+ if !$cond {
+ panic!($($arg),+)
+ }
+ );
+}
+
+/// Asserts that two expressions are equal to each other, testing equality in
+/// both directions.
+///
+/// On panic, this macro will print the values of the expressions.
+///
+/// # Example
+///
+/// ```
+/// let a = 3i;
+/// let b = 1i + 2i;
+/// assert_eq!(a, b);
+/// ```
+#[macro_export]
+macro_rules! assert_eq {
+ ($left:expr , $right:expr) => ({
+ match (&($left), &($right)) {
+ (left_val, right_val) => {
+ // check both directions of equality....
+ if !((*left_val == *right_val) &&
+ (*right_val == *left_val)) {
+ panic!("assertion failed: `(left == right) && (right == left)` \
+ (left: `{}`, right: `{}`)", *left_val, *right_val)
+ }
+ }
+ }
+ })
+}
+
+/// Ensure that a boolean expression is `true` at runtime.
+///
+/// This will invoke the `panic!` macro if the provided expression cannot be
+/// evaluated to `true` at runtime.
+///
+/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
+/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for
+/// checks that are too expensive to be present in a release build but may be
+/// helpful during development.
+///
+/// # Example
+///
+/// ```
+/// // the panic message for these assertions is the stringified value of the
+/// // expression given.
+/// debug_assert!(true);
+/// # fn some_expensive_computation() -> bool { true }
+/// debug_assert!(some_expensive_computation());
+///
+/// // assert with a custom message
+/// # let x = true;
+/// debug_assert!(x, "x wasn't true!");
+/// # let a = 3i; let b = 27i;
+/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
+/// ```
+#[macro_export]
+macro_rules! debug_assert {
+ ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
+}
+
+/// Asserts that two expressions are equal to each other, testing equality in
+/// both directions.
+///
+/// On panic, this macro will print the values of the expressions.
+///
+/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
+/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
+/// useful for checks that are too expensive to be present in a release build
+/// but may be helpful during development.
+///
+/// # Example
+///
+/// ```
+/// let a = 3i;
+/// let b = 1i + 2i;
+/// debug_assert_eq!(a, b);
+/// ```
+#[macro_export]
+macro_rules! debug_assert_eq {
+ ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
+}
+
+/// A utility macro for indicating unreachable code.
+///
+/// This is useful any time that the compiler can't determine that some code is unreachable. For
+/// example:
+///
+/// * Match arms with guard conditions.
+/// * Loops that dynamically terminate.
+/// * Iterators that dynamically terminate.
+///
+/// # Panics
+///
+/// This will always panic.
+///
+/// # Examples
+///
+/// Match arms:
+///
+/// ```rust
+/// fn foo(x: Option) {
+/// match x {
+/// Some(n) if n >= 0 => println!("Some(Non-negative)"),
+/// Some(n) if n < 0 => println!("Some(Negative)"),
+/// Some(_) => unreachable!(), // compile error if commented out
+/// None => println!("None")
+/// }
+/// }
+/// ```
+///
+/// Iterators:
+///
+/// ```rust
+/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
+/// for i in std::iter::count(0_u32, 1) {
+/// if 3*i < i { panic!("u32 overflow"); }
+/// if x < 3*i { return i-1; }
+/// }
+/// unreachable!();
+/// }
+/// ```
+#[macro_export]
+macro_rules! unreachable {
+ () => ({
+ panic!("internal error: entered unreachable code")
+ });
+ ($msg:expr) => ({
+ unreachable!("{}", $msg)
+ });
+ ($fmt:expr, $($arg:tt)*) => ({
+ panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
+ });
+}
+
+/// A standardised placeholder for marking unfinished code. It panics with the
+/// message `"not yet implemented"` when executed.
+#[macro_export]
+macro_rules! unimplemented {
+ () => (panic!("not yet implemented"))
+}
+
+/// Use the syntax described in `std::fmt` to create a value of type `String`.
+/// See `std::fmt` for more information.
+///
+/// # Example
+///
+/// ```
+/// format!("test");
+/// format!("hello {}", "world!");
+/// format!("x = {}, y = {y}", 10i, y = 30i);
+/// ```
+#[macro_export]
+#[stable]
+macro_rules! format {
+ ($($arg:tt)*) => (::std::fmt::format(format_args!($($arg)*)))
+}
+
+/// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
+/// See `std::fmt` for more information.
+///
+/// # Example
+///
+/// ```
+/// # #![allow(unused_must_use)]
+///
+/// let mut w = Vec::new();
+/// write!(&mut w, "test");
+/// write!(&mut w, "formatted {}", "arguments");
+/// ```
+#[macro_export]
+#[stable]
+macro_rules! write {
+ ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*)))
+}
+
+/// Equivalent to the `write!` macro, except that a newline is appended after
+/// the message is written.
+#[macro_export]
+#[stable]
+macro_rules! writeln {
+ ($dst:expr, $fmt:expr $($arg:tt)*) => (
+ write!($dst, concat!($fmt, "\n") $($arg)*)
+ )
+}
+
+/// Equivalent to the `println!` macro except that a newline is not printed at
+/// the end of the message.
+#[macro_export]
+#[stable]
+macro_rules! print {
+ ($($arg:tt)*) => (::std::io::stdio::print_args(format_args!($($arg)*)))
+}
+
+/// Macro for printing to a task's stdout handle.
+///
+/// Each task can override its stdout handle via `std::io::stdio::set_stdout`.
+/// The syntax of this macro is the same as that used for `format!`. For more
+/// information, see `std::fmt` and `std::io::stdio`.
+///
+/// # Example
+///
+/// ```
+/// println!("hello there!");
+/// println!("format {} arguments", "some");
+/// ```
+#[macro_export]
+#[stable]
+macro_rules! println {
+ ($($arg:tt)*) => (::std::io::stdio::println_args(format_args!($($arg)*)))
+}
+
+/// Helper macro for unwrapping `Result` values while returning early with an
+/// error if the value of the expression is `Err`. For more information, see
+/// `std::io`.
+#[macro_export]
+macro_rules! try {
+ ($expr:expr) => ({
+ match $expr {
+ Ok(val) => val,
+ Err(err) => return Err(::std::error::FromError::from_error(err))
+ }
+ })
+}
+
+/// Create a `std::vec::Vec` containing the arguments.
+#[macro_export]
+macro_rules! vec {
+ ($($x:expr),*) => ({
+ let xs: ::std::boxed::Box<[_]> = box [$($x),*];
+ ::std::slice::SliceExt::into_vec(xs)
+ });
+ ($($x:expr,)*) => (vec![$($x),*])
+}
+
+/// A macro to select an event from a number of receivers.
+///
+/// This macro is used to wait for the first event to occur on a number of
+/// receivers. It places no restrictions on the types of receivers given to
+/// this macro, this can be viewed as a heterogeneous select.
+///
+/// # Example
+///
+/// ```
+/// use std::thread::Thread;
+/// use std::sync::mpsc::channel;
+///
+/// let (tx1, rx1) = channel();
+/// let (tx2, rx2) = channel();
+/// # fn long_running_task() {}
+/// # fn calculate_the_answer() -> int { 42i }
+///
+/// Thread::spawn(move|| { long_running_task(); tx1.send(()) }).detach();
+/// Thread::spawn(move|| { tx2.send(calculate_the_answer()) }).detach();
+///
+/// select! (
+/// _ = rx1.recv() => println!("the long running task finished first"),
+/// answer = rx2.recv() => {
+/// println!("the answer was: {}", answer.unwrap());
+/// }
+/// )
+/// ```
+///
+/// For more information about select, see the `std::sync::mpsc::Select` structure.
+#[macro_export]
+#[experimental]
+macro_rules! select {
+ (
+ $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
+ ) => ({
+ use std::sync::mpsc::Select;
+ let sel = Select::new();
+ $( let mut $rx = sel.handle(&$rx); )+
+ unsafe {
+ $( $rx.add(); )+
+ }
+ let ret = sel.wait();
+ $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
+ { unreachable!() }
+ })
+}
+
+// When testing the standard library, we link to the liblog crate to get the
+// logging macros. In doing so, the liblog crate was linked against the real
+// version of libstd, and uses a different std::fmt module than the test crate
+// uses. To get around this difference, we redefine the log!() macro here to be
+// just a dumb version of what it should be.
+#[cfg(test)]
+macro_rules! log {
+ ($lvl:expr, $($args:tt)*) => (
+ if log_enabled!($lvl) { println!($($args)*) }
+ )
+}
+
+/// Built-in macros to the compiler itself.
+///
+/// These macros do not have any corresponding definition with a `macro_rules!`
+/// macro, but are documented here. Their implementations can be found hardcoded
+/// into libsyntax itself.
+#[cfg(dox)]
+pub mod builtin {
+ /// The core macro for formatted string creation & output.
+ ///
+ /// This macro produces a value of type `fmt::Arguments`. This value can be
+ /// passed to the functions in `std::fmt` for performing useful functions.
+ /// All other formatting macros (`format!`, `write!`, `println!`, etc) are
+ /// proxied through this one.
+ ///
+ /// For more information, see the documentation in `std::fmt`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::fmt;
+ ///
+ /// let s = fmt::format(format_args!("hello {}", "world"));
+ /// assert_eq!(s, format!("hello {}", "world"));
+ ///
+ /// ```
+ #[macro_export]
+ macro_rules! format_args { ($fmt:expr $($args:tt)*) => ({
+ /* compiler built-in */
+ }) }
+
+ /// Inspect an environment variable at compile time.
+ ///
+ /// This macro will expand to the value of the named environment variable at
+ /// compile time, yielding an expression of type `&'static str`.
+ ///
+ /// If the environment variable is not defined, then a compilation error
+ /// will be emitted. To not emit a compile error, use the `option_env!`
+ /// macro instead.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let path: &'static str = env!("PATH");
+ /// println!("the $PATH variable at the time of compiling was: {}", path);
+ /// ```
+ #[macro_export]
+ macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }) }
+
+ /// Optionally inspect an environment variable at compile time.
+ ///
+ /// If the named environment variable is present at compile time, this will
+ /// expand into an expression of type `Option<&'static str>` whose value is
+ /// `Some` of the value of the environment variable. If the environment
+ /// variable is not present, then this will expand to `None`.
+ ///
+ /// A compile time error is never emitted when using this macro regardless
+ /// of whether the environment variable is present or not.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let key: Option<&'static str> = option_env!("SECRET_KEY");
+ /// println!("the secret key might be: {}", key);
+ /// ```
+ #[macro_export]
+ macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }) }
+
+ /// Concatenate literals into a static byte slice.
+ ///
+ /// This macro takes any number of comma-separated literal expressions,
+ /// yielding an expression of type `&'static [u8]` which is the
+ /// concatenation (left to right) of all the literals in their byte format.
+ ///
+ /// This extension currently only supports string literals, character
+ /// literals, and integers less than 256. The byte slice returned is the
+ /// utf8-encoding of strings and characters.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let rust = bytes!("r", 'u', "st", 255);
+ /// assert_eq!(rust[1], b'u');
+ /// assert_eq!(rust[4], 255);
+ /// ```
+ #[macro_export]
+ macro_rules! bytes { ($($e:expr),*) => ({ /* compiler built-in */ }) }
+
+ /// Concatenate identifiers into one identifier.
+ ///
+ /// This macro takes any number of comma-separated identifiers, and
+ /// concatenates them all into one, yielding an expression which is a new
+ /// identifier. Note that hygiene makes it such that this macro cannot
+ /// capture local variables, and macros are only allowed in item,
+ /// statement or expression position, meaning this macro may be difficult to
+ /// use in some situations.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// #![feature(concat_idents)]
+ ///
+ /// # fn main() {
+ /// fn foobar() -> int { 23 }
+ ///
+ /// let f = concat_idents!(foo, bar);
+ /// println!("{}", f());
+ /// # }
+ /// ```
+ #[macro_export]
+ macro_rules! concat_idents {
+ ($($e:ident),*) => ({ /* compiler built-in */ })
+ }
+
+ /// Concatenates literals into a static string slice.
+ ///
+ /// This macro takes any number of comma-separated literals, yielding an
+ /// expression of type `&'static str` which represents all of the literals
+ /// concatenated left-to-right.
+ ///
+ /// Integer and floating point literals are stringified in order to be
+ /// concatenated.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let s = concat!("test", 10i, 'b', true);
+ /// assert_eq!(s, "test10btrue");
+ /// ```
+ #[macro_export]
+ macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }) }
+
+ /// A macro which expands to the line number on which it was invoked.
+ ///
+ /// The expanded expression has type `uint`, and the returned line is not
+ /// the invocation of the `line!()` macro itself, but rather the first macro
+ /// invocation leading up to the invocation of the `line!()` macro.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let current_line = line!();
+ /// println!("defined on line: {}", current_line);
+ /// ```
+ #[macro_export]
+ macro_rules! line { () => ({ /* compiler built-in */ }) }
+
+ /// A macro which expands to the column number on which it was invoked.
+ ///
+ /// The expanded expression has type `uint`, and the returned column is not
+ /// the invocation of the `column!()` macro itself, but rather the first macro
+ /// invocation leading up to the invocation of the `column!()` macro.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let current_col = column!();
+ /// println!("defined on column: {}", current_col);
+ /// ```
+ #[macro_export]
+ macro_rules! column { () => ({ /* compiler built-in */ }) }
+
+ /// A macro which expands to the file name from which it was invoked.
+ ///
+ /// The expanded expression has type `&'static str`, and the returned file
+ /// is not the invocation of the `file!()` macro itself, but rather the
+ /// first macro invocation leading up to the invocation of the `file!()`
+ /// macro.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let this_file = file!();
+ /// println!("defined in file: {}", this_file);
+ /// ```
+ #[macro_export]
+ macro_rules! file { () => ({ /* compiler built-in */ }) }
+
+ /// A macro which stringifies its argument.
+ ///
+ /// This macro will yield an expression of type `&'static str` which is the
+ /// stringification of all the tokens passed to the macro. No restrictions
+ /// are placed on the syntax of the macro invocation itself.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let one_plus_one = stringify!(1 + 1);
+ /// assert_eq!(one_plus_one, "1 + 1");
+ /// ```
+ #[macro_export]
+ macro_rules! stringify { ($t:tt) => ({ /* compiler built-in */ }) }
+
+ /// Includes a utf8-encoded file as a string.
+ ///
+ /// This macro will yield an expression of type `&'static str` which is the
+ /// contents of the filename specified. The file is located relative to the
+ /// current file (similarly to how modules are found),
+ ///
+ /// # Example
+ ///
+ /// ```rust,ignore
+ /// let secret_key = include_str!("secret-key.ascii");
+ /// ```
+ #[macro_export]
+ macro_rules! include_str { ($file:expr) => ({ /* compiler built-in */ }) }
+
+ /// Includes a file as a byte slice.
+ ///
+ /// This macro will yield an expression of type `&'static [u8]` which is
+ /// the contents of the filename specified. The file is located relative to
+ /// the current file (similarly to how modules are found),
+ ///
+ /// # Example
+ ///
+ /// ```rust,ignore
+ /// let secret_key = include_bytes!("secret-key.bin");
+ /// ```
+ #[macro_export]
+ macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }) }
+
+ /// Deprecated alias for `include_bytes!()`.
+ #[macro_export]
+ macro_rules! include_bin { ($file:expr) => ({ /* compiler built-in */}) }
+
+ /// Expands to a string that represents the current module path.
+ ///
+ /// The current module path can be thought of as the hierarchy of modules
+ /// leading back up to the crate root. The first component of the path
+ /// returned is the name of the crate currently being compiled.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// mod test {
+ /// pub fn foo() {
+ /// assert!(module_path!().ends_with("test"));
+ /// }
+ /// }
+ ///
+ /// test::foo();
+ /// ```
+ #[macro_export]
+ macro_rules! module_path { () => ({ /* compiler built-in */ }) }
+
+ /// Boolean evaluation of configuration flags.
+ ///
+ /// In addition to the `#[cfg]` attribute, this macro is provided to allow
+ /// boolean expression evaluation of configuration flags. This frequently
+ /// leads to less duplicated code.
+ ///
+ /// The syntax given to this macro is the same syntax as the `cfg`
+ /// attribute.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let my_directory = if cfg!(windows) {
+ /// "windows-specific-directory"
+ /// } else {
+ /// "unix-directory"
+ /// };
+ /// ```
+ #[macro_export]
+ macro_rules! cfg { ($cfg:tt) => ({ /* compiler built-in */ }) }
+}
diff --git a/src/libstd/num/float_macros.rs b/src/libstd/num/float_macros.rs
index fd00f15662a72..4c52f29b12d76 100644
--- a/src/libstd/num/float_macros.rs
+++ b/src/libstd/num/float_macros.rs
@@ -9,7 +9,6 @@
// except according to those terms.
#![experimental]
-#![macro_escape]
#![doc(hidden)]
macro_rules! assert_approx_eq {
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index fce150c4ad1e3..ebcb20861879c 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -9,7 +9,6 @@
// except according to those terms.
#![experimental]
-#![macro_escape]
#![doc(hidden)]
macro_rules! int_module { ($T:ty) => (
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index 7818f4a053497..08ea1b024c993 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -9,7 +9,6 @@
// except according to those terms.
#![experimental]
-#![macro_escape]
#![doc(hidden)]
#![allow(unsigned_negation)]
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index ae82e201cb855..a78dfe3edceda 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -558,7 +558,7 @@ mod tests {
t!(b"foo/\xFFbar", filename_display, "\u{FFFD}bar");
t!(b"/", filename_display, "");
- macro_rules! t(
+ macro_rules! t {
($path:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -573,7 +573,7 @@ mod tests {
assert!(mo.as_slice() == $exp);
}
)
- );
+ }
t!("foo", "foo");
t!(b"foo\x80", "foo\u{FFFD}");
@@ -585,7 +585,7 @@ mod tests {
#[test]
fn test_display() {
- macro_rules! t(
+ macro_rules! t {
($path:expr, $exp:expr, $expf:expr) => (
{
let path = Path::new($path);
@@ -595,7 +595,7 @@ mod tests {
assert!(f == $expf);
}
)
- );
+ }
t!(b"foo", "foo", "foo");
t!(b"foo/bar", "foo/bar", "bar");
@@ -608,7 +608,7 @@ mod tests {
#[test]
fn test_components() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $op:ident, $exp:expr) => (
{
let path = Path::new($path);
@@ -629,7 +629,7 @@ mod tests {
assert!(path.$op() == $exp);
}
);
- );
+ }
t!(v: b"a/b/c", filename, Some(b"c"));
t!(v: b"a/b/c\xFF", filename, Some(b"c\xFF"));
@@ -692,7 +692,7 @@ mod tests {
#[test]
fn test_push() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $join:expr) => (
{
let path = $path;
@@ -703,7 +703,7 @@ mod tests {
assert!(p1 == p2.join(join));
}
)
- );
+ }
t!(s: "a/b/c", "..");
t!(s: "/a/b/c", "d");
@@ -713,7 +713,7 @@ mod tests {
#[test]
fn test_push_path() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $push:expr, $exp:expr) => (
{
let mut p = Path::new($path);
@@ -722,7 +722,7 @@ mod tests {
assert!(p.as_str() == Some($exp));
}
)
- );
+ }
t!(s: "a/b/c", "d", "a/b/c/d");
t!(s: "/a/b/c", "d", "/a/b/c/d");
@@ -734,7 +734,7 @@ mod tests {
#[test]
fn test_push_many() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $push:expr, $exp:expr) => (
{
let mut p = Path::new($path);
@@ -749,7 +749,7 @@ mod tests {
assert!(p.as_vec() == $exp);
}
)
- );
+ }
t!(s: "a/b/c", ["d", "e"], "a/b/c/d/e");
t!(s: "a/b/c", ["d", "/e"], "/e");
@@ -762,7 +762,7 @@ mod tests {
#[test]
fn test_pop() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $left:expr, $right:expr) => (
{
let mut p = Path::new($path);
@@ -779,7 +779,7 @@ mod tests {
assert!(result == $right);
}
)
- );
+ }
t!(b: b"a/b/c", b"a/b", true);
t!(b: b"a", b".", true);
@@ -818,7 +818,7 @@ mod tests {
#[test]
fn test_join_path() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $join:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -827,7 +827,7 @@ mod tests {
assert!(res.as_str() == Some($exp));
}
)
- );
+ }
t!(s: "a/b/c", "..", "a/b");
t!(s: "/a/b/c", "d", "/a/b/c/d");
@@ -839,7 +839,7 @@ mod tests {
#[test]
fn test_join_many() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $join:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -854,7 +854,7 @@ mod tests {
assert!(res.as_vec() == $exp);
}
)
- );
+ }
t!(s: "a/b/c", ["d", "e"], "a/b/c/d/e");
t!(s: "a/b/c", ["..", "d"], "a/b/d");
@@ -917,7 +917,7 @@ mod tests {
#[test]
fn test_setters() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $set:ident, $with:ident, $arg:expr) => (
{
let path = $path;
@@ -938,7 +938,7 @@ mod tests {
assert!(p1 == p2.$with(arg));
}
)
- );
+ }
t!(v: b"a/b/c", set_filename, with_filename, b"d");
t!(v: b"/", set_filename, with_filename, b"foo");
@@ -961,7 +961,7 @@ mod tests {
#[test]
fn test_getters() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
{
let path = $path;
@@ -992,7 +992,7 @@ mod tests {
assert!(path.extension() == $ext);
}
)
- );
+ }
t!(v: Path::new(b"a/b/c"), Some(b"c"), b"a/b", Some(b"c"), None);
t!(v: Path::new(b"a/b/\xFF"), Some(b"\xFF"), b"a/b", Some(b"\xFF"), None);
@@ -1031,7 +1031,7 @@ mod tests {
#[test]
fn test_is_absolute() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $abs:expr, $rel:expr) => (
{
let path = Path::new($path);
@@ -1039,7 +1039,7 @@ mod tests {
assert_eq!(path.is_relative(), $rel);
}
)
- );
+ }
t!(s: "a/b/c", false, true);
t!(s: "/a/b/c", true, false);
t!(s: "a", false, true);
@@ -1052,7 +1052,7 @@ mod tests {
#[test]
fn test_is_ancestor_of() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $dest:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -1060,7 +1060,7 @@ mod tests {
assert_eq!(path.is_ancestor_of(&dest), $exp);
}
)
- );
+ }
t!(s: "a/b/c", "a/b/c/d", true);
t!(s: "a/b/c", "a/b/c", true);
@@ -1086,7 +1086,7 @@ mod tests {
#[test]
fn test_ends_with_path() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $child:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -1101,7 +1101,7 @@ mod tests {
assert_eq!(path.ends_with_path(&child), $exp);
}
)
- );
+ }
t!(s: "a/b/c", "c", true);
t!(s: "a/b/c", "d", false);
@@ -1125,7 +1125,7 @@ mod tests {
#[test]
fn test_path_relative_from() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $other:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -1134,7 +1134,7 @@ mod tests {
assert_eq!(res.as_ref().and_then(|x| x.as_str()), $exp);
}
)
- );
+ }
t!(s: "a/b/c", "a/b", Some("c"));
t!(s: "a/b/c", "a/b/d", Some("../c"));
@@ -1170,7 +1170,7 @@ mod tests {
#[test]
fn test_components_iter() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -1196,7 +1196,7 @@ mod tests {
assert_eq!(comps, exp)
}
)
- );
+ }
t!(b: b"a/b/c", [b"a", b"b", b"c"]);
t!(b: b"/\xFF/a/\x80", [b"\xFF", b"a", b"\x80"]);
@@ -1216,7 +1216,7 @@ mod tests {
#[test]
fn test_str_components() {
- macro_rules! t(
+ macro_rules! t {
(b: $arg:expr, $exp:expr) => (
{
let path = Path::new($arg);
@@ -1228,7 +1228,7 @@ mod tests {
assert_eq!(comps, exp);
}
)
- );
+ }
t!(b: b"a/b/c", [Some("a"), Some("b"), Some("c")]);
t!(b: b"/\xFF/a/\x80", [None, Some("a"), None]);
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index cf8bc0e6242b3..30ed07446a400 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -1149,7 +1149,7 @@ mod tests {
#[test]
fn test_parse_prefix() {
- macro_rules! t(
+ macro_rules! t {
($path:expr, $exp:expr) => (
{
let path = $path;
@@ -1159,7 +1159,7 @@ mod tests {
"parse_prefix(\"{}\"): expected {}, found {}", path, exp, res);
}
)
- );
+ }
t!("\\\\SERVER\\share\\foo", Some(UNCPrefix(6,5)));
t!("\\\\", None);
@@ -1348,7 +1348,7 @@ mod tests {
#[test]
fn test_display() {
- macro_rules! t(
+ macro_rules! t {
($path:expr, $exp:expr, $expf:expr) => (
{
let path = Path::new($path);
@@ -1358,7 +1358,7 @@ mod tests {
assert_eq!(f, $expf);
}
)
- );
+ }
t!("foo", "foo", "foo");
t!("foo\\bar", "foo\\bar", "bar");
@@ -1367,7 +1367,7 @@ mod tests {
#[test]
fn test_components() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $op:ident, $exp:expr) => (
{
let path = $path;
@@ -1390,7 +1390,7 @@ mod tests {
assert!(path.$op() == $exp);
}
)
- );
+ }
t!(v: b"a\\b\\c", filename, Some(b"c"));
t!(s: "a\\b\\c", filename_str, "c");
@@ -1490,7 +1490,7 @@ mod tests {
#[test]
fn test_push() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $join:expr) => (
{
let path = $path;
@@ -1501,7 +1501,7 @@ mod tests {
assert!(p1 == p2.join(join));
}
)
- );
+ }
t!(s: "a\\b\\c", "..");
t!(s: "\\a\\b\\c", "d");
@@ -1525,7 +1525,7 @@ mod tests {
#[test]
fn test_push_path() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $push:expr, $exp:expr) => (
{
let mut p = Path::new($path);
@@ -1534,7 +1534,7 @@ mod tests {
assert_eq!(p.as_str(), Some($exp));
}
)
- );
+ }
t!(s: "a\\b\\c", "d", "a\\b\\c\\d");
t!(s: "\\a\\b\\c", "d", "\\a\\b\\c\\d");
@@ -1577,7 +1577,7 @@ mod tests {
#[test]
fn test_push_many() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $push:expr, $exp:expr) => (
{
let mut p = Path::new($path);
@@ -1592,7 +1592,7 @@ mod tests {
assert_eq!(p.as_vec(), $exp);
}
)
- );
+ }
t!(s: "a\\b\\c", ["d", "e"], "a\\b\\c\\d\\e");
t!(s: "a\\b\\c", ["d", "\\e"], "\\e");
@@ -1606,7 +1606,7 @@ mod tests {
#[test]
fn test_pop() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $left:expr, $right:expr) => (
{
let pstr = $path;
@@ -1627,7 +1627,7 @@ mod tests {
assert!(result == $right);
}
)
- );
+ }
t!(s: "a\\b\\c", "a\\b", true);
t!(s: "a", ".", true);
@@ -1695,7 +1695,7 @@ mod tests {
#[test]
fn test_join_path() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $join:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -1704,7 +1704,7 @@ mod tests {
assert_eq!(res.as_str(), Some($exp));
}
)
- );
+ }
t!(s: "a\\b\\c", "..", "a\\b");
t!(s: "\\a\\b\\c", "d", "\\a\\b\\c\\d");
@@ -1718,7 +1718,7 @@ mod tests {
#[test]
fn test_join_many() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $join:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -1733,7 +1733,7 @@ mod tests {
assert_eq!(res.as_vec(), $exp);
}
)
- );
+ }
t!(s: "a\\b\\c", ["d", "e"], "a\\b\\c\\d\\e");
t!(s: "a\\b\\c", ["..", "d"], "a\\b\\d");
@@ -1746,7 +1746,7 @@ mod tests {
#[test]
fn test_with_helpers() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $op:ident, $arg:expr, $res:expr) => (
{
let pstr = $path;
@@ -1759,7 +1759,7 @@ mod tests {
pstr, stringify!($op), arg, exp, res.as_str().unwrap());
}
)
- );
+ }
t!(s: "a\\b\\c", with_filename, "d", "a\\b\\d");
t!(s: ".", with_filename, "foo", "foo");
@@ -1831,7 +1831,7 @@ mod tests {
#[test]
fn test_setters() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $set:ident, $with:ident, $arg:expr) => (
{
let path = $path;
@@ -1852,7 +1852,7 @@ mod tests {
assert!(p1 == p2.$with(arg));
}
)
- );
+ }
t!(v: b"a\\b\\c", set_filename, with_filename, b"d");
t!(v: b"\\", set_filename, with_filename, b"foo");
@@ -1876,7 +1876,7 @@ mod tests {
#[test]
fn test_getters() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
{
let path = $path;
@@ -1907,7 +1907,7 @@ mod tests {
assert!(path.extension() == $ext);
}
)
- );
+ }
t!(v: Path::new(b"a\\b\\c"), Some(b"c"), b"a\\b", Some(b"c"), None);
t!(s: Path::new("a\\b\\c"), Some("c"), Some("a\\b"), Some("c"), None);
@@ -1942,7 +1942,7 @@ mod tests {
#[test]
fn test_is_absolute() {
- macro_rules! t(
+ macro_rules! t {
($path:expr, $abs:expr, $vol:expr, $cwd:expr, $rel:expr) => (
{
let path = Path::new($path);
@@ -1961,7 +1961,7 @@ mod tests {
path.as_str().unwrap(), rel, b);
}
)
- );
+ }
t!("a\\b\\c", false, false, false, true);
t!("\\a\\b\\c", false, true, false, false);
t!("a", false, false, false, true);
@@ -1982,7 +1982,7 @@ mod tests {
#[test]
fn test_is_ancestor_of() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $dest:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -1994,7 +1994,7 @@ mod tests {
path.as_str().unwrap(), dest.as_str().unwrap(), exp, res);
}
)
- );
+ }
t!(s: "a\\b\\c", "a\\b\\c\\d", true);
t!(s: "a\\b\\c", "a\\b\\c", true);
@@ -2085,7 +2085,7 @@ mod tests {
#[test]
fn test_ends_with_path() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $child:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -2093,7 +2093,7 @@ mod tests {
assert_eq!(path.ends_with_path(&child), $exp);
}
);
- );
+ }
t!(s: "a\\b\\c", "c", true);
t!(s: "a\\b\\c", "d", false);
@@ -2117,7 +2117,7 @@ mod tests {
#[test]
fn test_path_relative_from() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $other:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -2130,7 +2130,7 @@ mod tests {
res.as_ref().and_then(|x| x.as_str()));
}
)
- );
+ }
t!(s: "a\\b\\c", "a\\b", Some("c"));
t!(s: "a\\b\\c", "a\\b\\d", Some("..\\c"));
@@ -2251,7 +2251,7 @@ mod tests {
#[test]
fn test_str_components() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -2265,7 +2265,7 @@ mod tests {
assert_eq!(comps, exp);
}
);
- );
+ }
t!(s: b"a\\b\\c", ["a", "b", "c"]);
t!(s: "a\\b\\c", ["a", "b", "c"]);
@@ -2309,7 +2309,7 @@ mod tests {
#[test]
fn test_components_iter() {
- macro_rules! t(
+ macro_rules! t {
(s: $path:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -2321,7 +2321,7 @@ mod tests {
assert_eq!(comps, exp);
}
)
- );
+ }
t!(s: "a\\b\\c", [b"a", b"b", b"c"]);
t!(s: ".", [b"."]);
@@ -2330,7 +2330,7 @@ mod tests {
#[test]
fn test_make_non_verbatim() {
- macro_rules! t(
+ macro_rules! t {
($path:expr, $exp:expr) => (
{
let path = Path::new($path);
@@ -2339,7 +2339,7 @@ mod tests {
assert!(make_non_verbatim(&path) == exp);
}
)
- );
+ }
t!(r"\a\b\c", Some(r"\a\b\c"));
t!(r"a\b\c", Some(r"a\b\c"));
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index 6ae6a238c952a..a79a6e35ebcfd 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -23,11 +23,14 @@ mod imp {
use path::Path;
use rand::Rng;
use rand::reader::ReaderRng;
- use result::Result::{Ok, Err};
+ use result::Result::Ok;
use slice::SliceExt;
use mem;
use os::errno;
+ // NOTE: for old macros; remove after the next snapshot
+ #[cfg(stage0)] use result::Result::Err;
+
#[cfg(all(target_os = "linux",
any(target_arch = "x86_64",
target_arch = "x86",
diff --git a/src/libstd/rt/macros.rs b/src/libstd/rt/macros.rs
index 0f35500a04a73..bbc96d0b19f12 100644
--- a/src/libstd/rt/macros.rs
+++ b/src/libstd/rt/macros.rs
@@ -13,8 +13,6 @@
//! These macros call functions which are only accessible in the `rt` module, so
//! they aren't defined anywhere outside of the `rt` module.
-#![macro_escape]
-
macro_rules! rterrln {
($fmt:expr $($arg:tt)*) => ( {
::rt::util::dumb_print(format_args!(concat!($fmt, "\n") $($arg)*))
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 2b0639c570537..e556888a470a2 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -39,6 +39,8 @@ pub use alloc::heap;
pub mod backtrace;
// Internals
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
mod macros;
// These should be refactored/moved/made private over time
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index d3b4fab96810b..e0cbaa8ca50ed 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -34,13 +34,14 @@
//! will want to make use of some form of **interior mutability** through the
//! `Cell` or `RefCell` types.
-#![macro_escape]
#![stable]
use prelude::v1::*;
use cell::UnsafeCell;
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
pub mod scoped;
// Sure wish we had macro hygiene, no?
diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs
index dc36fda3a020e..714b71d5dbd4e 100644
--- a/src/libstd/thread_local/scoped.rs
+++ b/src/libstd/thread_local/scoped.rs
@@ -38,7 +38,6 @@
//! });
//! ```
-#![macro_escape]
#![unstable = "scoped TLS has yet to have wide enough use to fully consider \
stabilizing its interface"]
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index d48b0342b3bf7..ac1f0c5d803ac 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -17,8 +17,10 @@ use ops::{Add, Sub, Mul, Div, Neg, FnOnce};
use option::Option;
use option::Option::{Some, None};
use num::Int;
-use result::Result;
-use result::Result::{Ok, Err};
+use result::Result::Ok;
+
+// NOTE: for old macros; remove after the next snapshot
+#[cfg(stage0)] use result::Result::Err;
/// The number of nanoseconds in a microsecond.
const NANOS_PER_MICRO: i32 = 1000;
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index c9d27e304ff15..0f90e31c17eee 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -476,7 +476,7 @@ pub struct Crate {
pub attrs: Vec,
pub config: CrateConfig,
pub span: Span,
- pub exported_macros: Vec>
+ pub exported_macros: Vec,
}
pub type MetaItem = Spanned;
@@ -884,6 +884,7 @@ impl TokenTree {
match *self {
TtToken(_, token::DocComment(_)) => 2,
TtToken(_, token::SubstNt(..)) => 2,
+ TtToken(_, token::SpecialVarNt(..)) => 2,
TtToken(_, token::MatchNt(..)) => 3,
TtDelimited(_, ref delimed) => {
delimed.tts.len() + 2
@@ -925,6 +926,12 @@ impl TokenTree {
TtToken(sp, token::Ident(name, name_st))];
v[index]
}
+ (&TtToken(sp, token::SpecialVarNt(var)), _) => {
+ let v = [TtToken(sp, token::Dollar),
+ TtToken(sp, token::Ident(token::str_to_ident(var.as_str()),
+ token::Plain))];
+ v[index]
+ }
(&TtToken(sp, token::MatchNt(name, kind, name_st, kind_st)), _) => {
let v = [TtToken(sp, token::SubstNt(name, name_st)),
TtToken(sp, token::Colon),
@@ -1691,6 +1698,21 @@ pub enum InlinedItem {
IIForeign(P),
}
+/// A macro definition, in this crate or imported from another.
+///
+/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
+pub struct MacroDef {
+ pub ident: Ident,
+ pub attrs: Vec,
+ pub id: NodeId,
+ pub span: Span,
+ pub imported_from: Option,
+ pub export: bool,
+ pub use_locally: bool,
+ pub body: Vec,
+}
+
#[cfg(test)]
mod test {
use serialize::json;
diff --git a/src/libsyntax/diagnostics/macros.rs b/src/libsyntax/diagnostics/macros.rs
index 3107508a96a5c..34a193dffd3db 100644
--- a/src/libsyntax/diagnostics/macros.rs
+++ b/src/libsyntax/diagnostics/macros.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![macro_escape]
-
#[macro_export]
macro_rules! register_diagnostic {
($code:tt, $description:tt) => (__register_diagnostic! { $code, $description });
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 91cc8a2462205..91ae7396ea469 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -16,6 +16,7 @@ use codemap;
use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
use ext;
use ext::expand;
+use ext::tt::macro_rules;
use parse;
use parse::parser;
use parse::token;
@@ -28,19 +29,6 @@ use fold::Folder;
use std::collections::HashMap;
use std::rc::Rc;
-// new-style macro! tt code:
-//
-// MacResult, NormalTT, IdentTT
-//
-// also note that ast::Mac used to have a bunch of extraneous cases and
-// is now probably a redundant AST node, can be merged with
-// ast::MacInvocTT.
-
-pub struct MacroDef {
- pub name: String,
- pub ext: SyntaxExtension
-}
-
pub trait ItemDecorator {
fn expand(&self,
ecx: &mut ExtCtxt,
@@ -140,13 +128,6 @@ impl IdentMacroExpander for F
/// methods are spliced into the AST at the callsite of the macro (or
/// just into the compiler's internal macro table, for `make_def`).
pub trait MacResult {
- /// Attempt to define a new macro.
- // this should go away; the idea that a macro might expand into
- // either a macro definition or an expression, depending on what
- // the context wants, is kind of silly.
- fn make_def(&mut self) -> Option {
- None
- }
/// Create an expression.
fn make_expr(self: Box) -> Option> {
None
@@ -328,13 +309,8 @@ pub enum SyntaxExtension {
///
IdentTT(Box, Option),
- /// An ident macro that has two properties:
- /// - it adds a macro definition to the environment, and
- /// - the definition it adds doesn't introduce any new
- /// identifiers.
- ///
- /// `macro_rules!` is a LetSyntaxTT
- LetSyntaxTT(Box, Option),
+ /// Represents `macro_rules!` itself.
+ MacroRulesTT,
}
pub type NamedSyntaxExtension = (Name, SyntaxExtension);
@@ -364,8 +340,7 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
}
let mut syntax_expanders = SyntaxEnv::new();
- syntax_expanders.insert(intern("macro_rules"),
- LetSyntaxTT(box ext::tt::macro_rules::add_new_extension, None));
+ syntax_expanders.insert(intern("macro_rules"), MacroRulesTT);
syntax_expanders.insert(intern("fmt"),
builtin_normal_expander(
ext::fmt::expand_syntax_ext));
@@ -475,7 +450,7 @@ pub struct ExtCtxt<'a> {
pub mod_path: Vec ,
pub trace_mac: bool,
- pub exported_macros: Vec>,
+ pub exported_macros: Vec,
pub syntax_env: SyntaxEnv,
pub recursion_count: uint,
@@ -594,6 +569,17 @@ impl<'a> ExtCtxt<'a> {
}
}
}
+
+ pub fn insert_macro(&mut self, def: ast::MacroDef) {
+ if def.export {
+ self.exported_macros.push(def.clone());
+ }
+ if def.use_locally {
+ let ext = macro_rules::compile(self, &def);
+ self.syntax_env.insert(def.ident.name, ext);
+ }
+ }
+
/// Emit `msg` attached to `sp`, and stop compilation immediately.
///
/// `span_err` should be strongly preferred where-ever possible:
diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs
index 7a67fab820de5..1b1bc6d281a2f 100644
--- a/src/libsyntax/ext/deriving/cmp/eq.rs
+++ b/src/libsyntax/ext/deriving/cmp/eq.rs
@@ -61,7 +61,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt,
cx, span, substr)
}
- macro_rules! md (
+ macro_rules! md {
($name:expr, $f:ident) => { {
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
@@ -77,7 +77,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt,
})
}
} }
- );
+ }
let trait_def = TraitDef {
span: span,
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index c02416bfbea3a..7353ddc172015 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -27,7 +27,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
push: F) where
F: FnOnce(P- ),
{
- macro_rules! md (
+ macro_rules! md {
($name:expr, $op:expr, $equal:expr) => { {
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
@@ -43,7 +43,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
})
}
} }
- );
+ }
let ordering_ty = Literal(Path::new(vec!["std", "cmp", "Ordering"]));
let ret_ty = Literal(Path::new_(vec!["std", "option", "Option"],
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 14b19fee3df5e..e72c83b67c89b 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -71,9 +71,11 @@ pub fn expand_meta_derive(cx: &mut ExtCtxt,
MetaNameValue(ref tname, _) |
MetaList(ref tname, _) |
MetaWord(ref tname) => {
- macro_rules! expand(($func:path) => ($func(cx, titem.span,
- &**titem, item,
- |i| push.call_mut((i,)))));
+ macro_rules! expand {
+ ($func:path) => ($func(cx, titem.span, &**titem, item,
+ |i| push.call_mut((i,))))
+ }
+
match tname.get() {
"Clone" => expand!(clone::expand_deriving_clone),
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index b3f30dd4581c9..8decedf289af3 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -7,7 +7,6 @@
// , at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use self::Either::*;
use ast::{Block, Crate, DeclLocal, ExprMac, PatMac};
use ast::{Local, Ident, MacInvocTT};
@@ -33,11 +32,6 @@ use util::small_vector::SmallVector;
use visit;
use visit::Visitor;
-enum Either {
- Left(L),
- Right(R)
-}
-
pub fn expand_type(t: P,
fld: &mut MacroExpander,
impl_ty: Option
>)
@@ -445,9 +439,9 @@ pub fn expand_item(it: P, fld: &mut MacroExpander)
if valid_ident {
fld.cx.mod_push(it.ident);
}
- let macro_escape = contains_macro_escape(new_attrs[]);
+ let macro_use = contains_macro_use(fld, new_attrs[]);
let result = with_exts_frame!(fld.cx.syntax_env,
- macro_escape,
+ macro_use,
noop_fold_item(it, fld));
if valid_ident {
fld.cx.mod_pop();
@@ -527,15 +521,34 @@ fn expand_item_underscore(item: ast::Item_, fld: &mut MacroExpander) -> ast::Ite
}
}
-// does this attribute list contain "macro_escape" ?
-fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
- attr::contains_name(attrs, "macro_escape")
+// does this attribute list contain "macro_use" ?
+fn contains_macro_use(fld: &mut MacroExpander, attrs: &[ast::Attribute]) -> bool {
+ for attr in attrs.iter() {
+ let mut is_use = attr.check_name("macro_use");
+ if attr.check_name("macro_escape") {
+ fld.cx.span_warn(attr.span, "macro_escape is a deprecated synonym for macro_use");
+ is_use = true;
+ if let ast::AttrInner = attr.node.style {
+ fld.cx.span_help(attr.span, "consider an outer attribute, \
+ #[macro_use] mod ...");
+ }
+ };
+
+ if is_use {
+ match attr.node.value.node {
+ ast::MetaWord(..) => (),
+ _ => fld.cx.span_err(attr.span, "arguments to macro_use are not allowed here"),
+ }
+ return true;
+ }
+ }
+ false
}
// Support for item-position macro invocations, exactly the same
// logic as for expression-position macro invocations.
-pub fn expand_item_mac(it: P, fld: &mut MacroExpander)
- -> SmallVector> {
+pub fn expand_item_mac(it: P,
+ fld: &mut MacroExpander) -> SmallVector> {
let (extname, path_span, tts) = match it.node {
ItemMac(codemap::Spanned {
node: MacInvocTT(ref pth, ref tts, _),
@@ -548,8 +561,8 @@ pub fn expand_item_mac(it: P, fld: &mut MacroExpander)
let extnamestr = token::get_ident(extname);
let fm = fresh_mark();
- let def_or_items = {
- let mut expanded = match fld.cx.syntax_env.find(&extname.name) {
+ let items = {
+ let expanded = match fld.cx.syntax_env.find(&extname.name) {
None => {
fld.cx.span_err(path_span,
format!("macro undefined: '{}!'",
@@ -600,11 +613,10 @@ pub fn expand_item_mac(it: P, fld: &mut MacroExpander)
let marked_tts = mark_tts(tts[], fm);
expander.expand(fld.cx, it.span, it.ident, marked_tts)
}
- LetSyntaxTT(ref expander, span) => {
+ MacroRulesTT => {
if it.ident.name == parse::token::special_idents::invalid.name {
fld.cx.span_err(path_span,
- format!("macro {}! expects an ident argument",
- extnamestr.get())[]);
+ format!("macro_rules! expects an ident argument")[]);
return SmallVector::zero();
}
fld.cx.bt_push(ExpnInfo {
@@ -612,11 +624,26 @@ pub fn expand_item_mac(it: P, fld: &mut MacroExpander)
callee: NameAndSpan {
name: extnamestr.get().to_string(),
format: MacroBang,
- span: span
+ span: None,
}
});
- // DON'T mark before expansion:
- expander.expand(fld.cx, it.span, it.ident, tts)
+ // DON'T mark before expansion.
+
+ let def = ast::MacroDef {
+ ident: it.ident,
+ attrs: it.attrs.clone(),
+ id: ast::DUMMY_NODE_ID,
+ span: it.span,
+ imported_from: None,
+ export: attr::contains_name(it.attrs.as_slice(), "macro_export"),
+ use_locally: true,
+ body: tts,
+ };
+ fld.cx.insert_macro(def);
+
+ // macro_rules! has a side effect but expands to nothing.
+ fld.cx.bt_pop();
+ return SmallVector::zero();
}
_ => {
fld.cx.span_err(it.span,
@@ -627,31 +654,17 @@ pub fn expand_item_mac(it: P, fld: &mut MacroExpander)
}
};
- match expanded.make_def() {
- Some(def) => Left(def),
- None => Right(expanded.make_items())
- }
+ expanded.make_items()
};
- let items = match def_or_items {
- Left(MacroDef { name, ext }) => {
- // hidden invariant: this should only be possible as the
- // result of expanding a LetSyntaxTT, and thus doesn't
- // need to be marked. Not that it could be marked anyway.
- // create issue to recommend refactoring here?
- fld.cx.syntax_env.insert(intern(name[]), ext);
- if attr::contains_name(it.attrs[], "macro_export") {
- fld.cx.exported_macros.push(it);
- }
- SmallVector::zero()
- }
- Right(Some(items)) => {
+ let items = match items {
+ Some(items) => {
items.into_iter()
.map(|i| mark_item(i, fm))
.flat_map(|i| fld.fold_item(i).into_iter())
.collect()
}
- Right(None) => {
+ None => {
fld.cx.span_err(path_span,
format!("non-item macro in item position: {}",
extnamestr.get())[]);
@@ -664,9 +677,6 @@ pub fn expand_item_mac(it: P, fld: &mut MacroExpander)
}
/// Expand a stmt
-//
-// I don't understand why this returns a vector... it looks like we're
-// half done adding machinery to allow macros to expand into multiple statements.
fn expand_stmt(s: Stmt, fld: &mut MacroExpander) -> SmallVector> {
let (mac, style) = match s.node {
StmtMac(mac, style) => (mac, style),
@@ -976,8 +986,8 @@ impl<'a> Folder for IdentRenamer<'a> {
ctxt: mtwt::apply_renames(self.renames, id.ctxt),
}
}
- fn fold_mac(&mut self, macro: ast::Mac) -> ast::Mac {
- fold::noop_fold_mac(macro, self)
+ fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+ fold::noop_fold_mac(mac, self)
}
}
@@ -1013,8 +1023,8 @@ impl<'a> Folder for PatIdentRenamer<'a> {
_ => unreachable!()
})
}
- fn fold_mac(&mut self, macro: ast::Mac) -> ast::Mac {
- fold::noop_fold_mac(macro, self)
+ fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+ fold::noop_fold_mac(mac, self)
}
}
@@ -1177,31 +1187,17 @@ impl ExpansionConfig {
}
}
-pub struct ExportedMacros {
- pub crate_name: Ident,
- pub macros: Vec,
-}
-
pub fn expand_crate(parse_sess: &parse::ParseSess,
cfg: ExpansionConfig,
// these are the macros being imported to this crate:
- imported_macros: Vec,
+ imported_macros: Vec,
user_exts: Vec,
c: Crate) -> Crate {
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
let mut expander = MacroExpander::new(&mut cx);
- for ExportedMacros { crate_name, macros } in imported_macros.into_iter() {
- let name = format!("<{} macros>", token::get_ident(crate_name));
-
- for source in macros.into_iter() {
- let item = parse::parse_item_from_source_str(name.clone(),
- source,
- expander.cx.cfg(),
- expander.cx.parse_sess())
- .expect("expected a serialized item");
- expand_item_mac(item, &mut expander);
- }
+ for def in imported_macros.into_iter() {
+ expander.cx.insert_macro(def);
}
for (name, extension) in user_exts.into_iter() {
@@ -1290,8 +1286,8 @@ struct MacroExterminator<'a>{
}
impl<'a, 'v> Visitor<'v> for MacroExterminator<'a> {
- fn visit_mac(&mut self, macro: &ast::Mac) {
- self.sess.span_diagnostic.span_bug(macro.span,
+ fn visit_mac(&mut self, mac: &ast::Mac) {
+ self.sess.span_diagnostic.span_bug(mac.span,
"macro exterminator: expected AST \
with no macro invocations");
}
@@ -1300,7 +1296,7 @@ impl<'a, 'v> Visitor<'v> for MacroExterminator<'a> {
#[cfg(test)]
mod test {
- use super::{pattern_bindings, expand_crate, contains_macro_escape};
+ use super::{pattern_bindings, expand_crate, contains_macro_use};
use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig};
use ast;
use ast::{Attribute_, AttrOuter, MetaWord, Name};
@@ -1397,9 +1393,9 @@ mod test {
expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast);
}
- // macro_escape modules should allow macros to escape
+ // macro_use modules should allow macros to escape
#[test] fn macros_can_escape_flattened_mods_test () {
- let src = "#[macro_escape] mod foo {macro_rules! z (() => (3+4));}\
+ let src = "#[macro_use] mod foo {macro_rules! z (() => (3+4));}\
fn inty() -> int { z!() }".to_string();
let sess = parse::new_parse_sess();
let crate_ast = parse::parse_crate_from_source_str(
@@ -1409,16 +1405,6 @@ mod test {
expand_crate(&sess, test_ecfg(), vec!(), vec!(), crate_ast);
}
- #[test] fn test_contains_flatten (){
- let attr1 = make_dummy_attr ("foo");
- let attr2 = make_dummy_attr ("bar");
- let escape_attr = make_dummy_attr ("macro_escape");
- let attrs1 = vec!(attr1.clone(), escape_attr, attr2.clone());
- assert_eq!(contains_macro_escape(attrs1[]),true);
- let attrs2 = vec!(attr1,attr2);
- assert_eq!(contains_macro_escape(attrs2[]),false);
- }
-
// make a MetaWord outer attribute with the given name
fn make_dummy_attr(s: &str) -> ast::Attribute {
Spanned {
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 08014dc13383f..9837c8088fa45 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -11,7 +11,7 @@
use ast::{Ident, TtDelimited, TtSequence, TtToken};
use ast;
use codemap::{Span, DUMMY_SP};
-use ext::base::{ExtCtxt, MacResult, MacroDef};
+use ext::base::{ExtCtxt, MacResult, SyntaxExtension};
use ext::base::{NormalTT, TTMacroExpander};
use ext::tt::macro_parser::{Success, Error, Failure};
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
@@ -38,8 +38,8 @@ impl<'a> ParserAnyMacro<'a> {
/// Make sure we don't have any tokens left to parse, so we don't
/// silently drop anything. `allow_semi` is so that "optional"
/// semicolons at the end of normal expressions aren't complained
- /// about e.g. the semicolon in `macro_rules! kapow( () => {
- /// panic!(); } )` doesn't get picked up by .parse_expr(), but it's
+ /// about e.g. the semicolon in `macro_rules! kapow { () => {
+ /// panic!(); } }` doesn't get picked up by .parse_expr(), but it's
/// allowed to be there.
fn ensure_complete_parse(&self, allow_semi: bool) {
let mut parser = self.parser.borrow_mut();
@@ -110,6 +110,7 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
struct MacroRulesMacroExpander {
name: Ident,
+ imported_from: Option,
lhses: Vec>,
rhses: Vec>,
}
@@ -123,25 +124,18 @@ impl TTMacroExpander for MacroRulesMacroExpander {
generic_extension(cx,
sp,
self.name,
+ self.imported_from,
arg,
self.lhses[],
self.rhses[])
}
}
-struct MacroRulesDefiner {
- def: Option
-}
-impl MacResult for MacroRulesDefiner {
- fn make_def(&mut self) -> Option {
- Some(self.def.take().expect("empty MacroRulesDefiner"))
- }
-}
-
/// Given `lhses` and `rhses`, this is the new macro we create
fn generic_extension<'cx>(cx: &'cx ExtCtxt,
sp: Span,
name: Ident,
+ imported_from: Option,
arg: &[ast::TokenTree],
lhses: &[Rc],
rhses: &[Rc])
@@ -165,6 +159,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
};
// `None` is because we're not interpolating
let mut arg_rdr = new_tt_reader(&cx.parse_sess().span_diagnostic,
+ None,
None,
arg.iter()
.map(|x| (*x).clone())
@@ -186,6 +181,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
// rhs has holes ( `$id` and `$(...)` that need filled)
let trncbr = new_tt_reader(&cx.parse_sess().span_diagnostic,
Some(named_matches),
+ imported_from,
rhs);
let p = Parser::new(cx.parse_sess(), cx.cfg(), box trncbr);
// Let the context choose how to interpret the result.
@@ -212,14 +208,9 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
//
// Holy self-referential!
-/// This procedure performs the expansion of the
-/// macro_rules! macro. It parses the RHS and adds
-/// an extension to the current context.
-pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt,
- sp: Span,
- name: Ident,
- arg: Vec )
- -> Box {
+/// Converts a `macro_rules!` invocation into a syntax extension.
+pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
+ def: &ast::MacroDef) -> SyntaxExtension {
let lhs_nm = gensym_ident("lhs");
let rhs_nm = gensym_ident("rhs");
@@ -256,7 +247,8 @@ pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt,
// Parse the macro_rules! invocation (`none` is for no interpolations):
let arg_reader = new_tt_reader(&cx.parse_sess().span_diagnostic,
None,
- arg.clone());
+ None,
+ def.body.clone());
let argument_map = parse_or_else(cx.parse_sess(),
cx.cfg(),
arg_reader,
@@ -265,24 +257,20 @@ pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt,
// Extract the arguments:
let lhses = match *argument_map[lhs_nm] {
MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(),
- _ => cx.span_bug(sp, "wrong-structured lhs")
+ _ => cx.span_bug(def.span, "wrong-structured lhs")
};
let rhses = match *argument_map[rhs_nm] {
MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(),
- _ => cx.span_bug(sp, "wrong-structured rhs")
+ _ => cx.span_bug(def.span, "wrong-structured rhs")
};
let exp = box MacroRulesMacroExpander {
- name: name,
+ name: def.ident,
+ imported_from: def.imported_from,
lhses: lhses,
rhses: rhses,
};
- box MacroRulesDefiner {
- def: Some(MacroDef {
- name: token::get_ident(name).to_string(),
- ext: NormalTT(exp, Some(sp))
- })
- } as Box
+ NormalTT(exp, Some(def.span))
}
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 86e81ede8b0fe..e4e6f5ac6b0f0 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -15,7 +15,7 @@ use codemap::{Span, DUMMY_SP};
use diagnostic::SpanHandler;
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
use parse::token::{Eof, DocComment, Interpolated, MatchNt, SubstNt};
-use parse::token::{Token, NtIdent};
+use parse::token::{Token, NtIdent, SpecialMacroVar};
use parse::token;
use parse::lexer::TokenAndSpan;
@@ -39,6 +39,10 @@ pub struct TtReader<'a> {
stack: Vec,
/* for MBE-style macro transcription */
interpolations: HashMap>,
+ imported_from: Option,
+
+ // Some => return imported_from as the next token
+ crate_name_next: Option,
repeat_idx: Vec,
repeat_len: Vec,
/* cached: */
@@ -53,6 +57,7 @@ pub struct TtReader<'a> {
/// should) be none.
pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
interp: Option>>,
+ imported_from: Option,
src: Vec )
-> TtReader<'a> {
let mut r = TtReader {
@@ -71,6 +76,8 @@ pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
None => HashMap::new(),
Some(x) => x,
},
+ imported_from: imported_from,
+ crate_name_next: None,
repeat_idx: Vec::new(),
repeat_len: Vec::new(),
desugar_doc_comments: false,
@@ -162,6 +169,14 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
sp: r.cur_span.clone(),
};
loop {
+ match r.crate_name_next.take() {
+ None => (),
+ Some(sp) => {
+ r.cur_span = sp;
+ r.cur_tok = token::Ident(r.imported_from.unwrap(), token::Plain);
+ return ret_val;
+ },
+ }
let should_pop = match r.stack.last() {
None => {
assert_eq!(ret_val.tok, token::Eof);
@@ -307,6 +322,18 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
sep: None
});
}
+ TtToken(sp, token::SpecialVarNt(SpecialMacroVar::CrateMacroVar)) => {
+ r.stack.last_mut().unwrap().idx += 1;
+
+ if r.imported_from.is_some() {
+ r.cur_span = sp;
+ r.cur_tok = token::ModSep;
+ r.crate_name_next = Some(sp);
+ return ret_val;
+ }
+
+ // otherwise emit nothing and proceed to the next token
+ }
TtToken(sp, tok) => {
r.cur_span = sp;
r.cur_tok = tok;
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index f8ac34cfe2920..fe6e28f23a355 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -37,14 +37,14 @@ use std::ascii::AsciiExt;
// if you change this list without updating src/doc/reference.md, @cmr will be sad
static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
("globs", Active),
- ("macro_rules", Active),
+ ("macro_rules", Accepted),
("struct_variant", Accepted),
("asm", Active),
("managed_boxes", Removed),
("non_ascii_idents", Active),
("thread_local", Active),
("link_args", Active),
- ("phase", Active),
+ ("phase", Active), // NOTE(stage0): switch to Removed after next snapshot
("plugin_registrar", Active),
("log_syntax", Active),
("trace_macros", Active),
@@ -74,6 +74,8 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
("if_let", Accepted),
("while_let", Accepted),
+ ("plugin", Active),
+
// A temporary feature gate used to enable parser extensions needed
// to bootstrap fix for #5723.
("issue_5723_bootstrap", Accepted),
@@ -163,32 +165,11 @@ struct MacroVisitor<'a> {
}
impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
- fn visit_view_item(&mut self, i: &ast::ViewItem) {
- match i.node {
- ast::ViewItemExternCrate(..) => {
- for attr in i.attrs.iter() {
- if attr.name().get() == "phase"{
- self.context.gate_feature("phase", attr.span,
- "compile time crate loading is \
- experimental and possibly buggy");
- }
- }
- },
- _ => { }
- }
- visit::walk_view_item(self, i)
- }
-
- fn visit_mac(&mut self, macro: &ast::Mac) {
- let ast::MacInvocTT(ref path, _, _) = macro.node;
+ fn visit_mac(&mut self, mac: &ast::Mac) {
+ let ast::MacInvocTT(ref path, _, _) = mac.node;
let id = path.segments.last().unwrap().identifier;
- if id == token::str_to_ident("macro_rules") {
- self.context.gate_feature("macro_rules", path.span, "macro definitions are \
- not stable enough for use and are subject to change");
- }
-
- else if id == token::str_to_ident("asm") {
+ if id == token::str_to_ident("asm") {
self.context.gate_feature("asm", path.span, "inline assembly is not \
stable enough for use and is subject to change");
}
@@ -241,10 +222,10 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
}
ast::ViewItemExternCrate(..) => {
for attr in i.attrs.iter() {
- if attr.name().get() == "phase"{
- self.gate_feature("phase", attr.span,
- "compile time crate loading is \
- experimental and possibly buggy");
+ if attr.check_name("plugin") {
+ self.gate_feature("plugin", attr.span,
+ "compiler plugins are experimental \
+ and possibly buggy");
}
}
}
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 35b2e5dbc5381..aa4b04b28799a 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -194,13 +194,13 @@ pub trait Folder : Sized {
noop_fold_local(l, self)
}
- fn fold_mac(&mut self, _macro: Mac) -> Mac {
+ fn fold_mac(&mut self, _mac: Mac) -> Mac {
panic!("fold_mac disabled by default");
// NB: see note about macros above.
// if you really want a folder that
// works on macros, use this
// definition in your trait impl:
- // fold::noop_fold_mac(_macro, self)
+ // fold::noop_fold_mac(_mac, self)
}
fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf {
@@ -1115,7 +1115,7 @@ pub fn noop_fold_mod(Mod {inner, view_items, items}: Mod, folder: &mu
}
}
-pub fn noop_fold_crate(Crate {module, attrs, config, exported_macros, span}: Crate,
+pub fn noop_fold_crate(Crate {module, attrs, config, mut exported_macros, span}: Crate,
folder: &mut T) -> Crate {
let config = folder.fold_meta_items(config);
@@ -1146,6 +1146,10 @@ pub fn noop_fold_crate(Crate {module, attrs, config, exported_macros,
}, Vec::new(), span)
};
+ for def in exported_macros.iter_mut() {
+ def.id = folder.new_id(def.id);
+ }
+
Crate {
module: module,
attrs: attrs,
@@ -1483,8 +1487,8 @@ mod test {
fn fold_ident(&mut self, _: ast::Ident) -> ast::Ident {
token::str_to_ident("zz")
}
- fn fold_mac(&mut self, macro: ast::Mac) -> ast::Mac {
- fold::noop_fold_mac(macro, self)
+ fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+ fold::noop_fold_mac(mac, self)
}
}
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 18cdb3fc64789..b7bfd346d506b 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -31,11 +31,18 @@
extern crate arena;
extern crate fmt_macros;
-#[phase(plugin, link)] extern crate log;
extern crate serialize;
extern crate term;
extern crate libc;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
extern crate "serialize" as rustc_serialize; // used by deriving
pub mod util {
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 8598571e5c37a..b0969a573e66b 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -24,8 +24,11 @@ use std::num::Int;
use std::str;
use std::iter;
-pub mod lexer;
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
pub mod parser;
+
+pub mod lexer;
pub mod token;
pub mod attr;
@@ -166,6 +169,8 @@ pub fn parse_stmt_from_source_str(name: String,
// Note: keep in sync with `with_hygiene::parse_tts_from_source_str`
// until #16472 is resolved.
+//
+// Warning: This parses with quote_depth > 0, which is not the default.
pub fn parse_tts_from_source_str(name: String,
source: String,
cfg: ast::CrateConfig,
@@ -291,7 +296,7 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc)
pub fn tts_to_parser<'a>(sess: &'a ParseSess,
tts: Vec,
cfg: ast::CrateConfig) -> Parser<'a> {
- let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts);
+ let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, None, tts);
Parser::new(sess, cfg, box trdr)
}
@@ -307,6 +312,8 @@ pub mod with_hygiene {
// Note: keep this in sync with `super::parse_tts_from_source_str` until
// #16472 is resolved.
+ //
+ // Warning: This parses with quote_depth > 0, which is not the default.
pub fn parse_tts_from_source_str(name: String,
source: String,
cfg: ast::CrateConfig,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index cc67079e53879..24011df7acb9b 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![macro_escape]
-
pub use self::PathParsingMode::*;
use self::ItemOrViewItem::*;
@@ -75,8 +73,8 @@ use parse::classify;
use parse::common::{SeqSep, seq_sep_none, seq_sep_trailing_allowed};
use parse::lexer::{Reader, TokenAndSpan};
use parse::obsolete::*;
-use parse::token::{self, MatchNt, SubstNt, InternedString};
-use parse::token::{keywords, special_idents};
+use parse::token::{self, MatchNt, SubstNt, SpecialVarNt, InternedString};
+use parse::token::{keywords, special_idents, SpecialMacroVar};
use parse::{new_sub_parser_from_file, ParseSess};
use print::pprust;
use ptr::P;
@@ -2747,6 +2745,9 @@ impl<'a> Parser<'a> {
op: repeat,
num_captures: name_num
}))
+ } else if p.token.is_keyword_allow_following_colon(keywords::Crate) {
+ p.bump();
+ TtToken(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar))
} else {
// A nonterminal that matches or not
let namep = match p.token { token::Ident(_, p) => p, _ => token::Plain };
@@ -3880,13 +3881,13 @@ impl<'a> Parser<'a> {
&mut stmts,
&mut expr);
}
- StmtMac(macro, MacStmtWithoutBraces) => {
+ StmtMac(mac, MacStmtWithoutBraces) => {
// statement macro without braces; might be an
// expr depending on whether a semicolon follows
match self.token {
token::Semi => {
stmts.push(P(Spanned {
- node: StmtMac(macro,
+ node: StmtMac(mac,
MacStmtWithSemicolon),
span: span,
}));
@@ -3895,7 +3896,7 @@ impl<'a> Parser<'a> {
_ => {
let e = self.mk_mac_expr(span.lo,
span.hi,
- macro.and_then(|m| m.node));
+ mac.and_then(|m| m.node));
let e =
self.parse_dot_or_call_expr_with(e);
self.handle_expression_like_statement(
@@ -5970,6 +5971,10 @@ impl<'a> Parser<'a> {
fn parse_view_path(&mut self) -> P {
let lo = self.span.lo;
+ // Allow a leading :: because the paths are absolute either way.
+ // This occurs with "use $crate::..." in macros.
+ self.eat(&token::ModSep);
+
if self.check(&token::OpenDelim(token::Brace)) {
// use {foo,bar}
let idents = self.parse_unspanned_seq(
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index b7e89b32b709e..094aacf3207fc 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -61,6 +61,21 @@ pub enum IdentStyle {
Plain,
}
+#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Show, Copy)]
+pub enum SpecialMacroVar {
+ /// `$crate` will be filled in with the name of the crate a macro was
+ /// imported from, if any.
+ CrateMacroVar,
+}
+
+impl SpecialMacroVar {
+ pub fn as_str(self) -> &'static str {
+ match self {
+ SpecialMacroVar::CrateMacroVar => "crate",
+ }
+ }
+}
+
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Show, Copy)]
pub enum Lit {
Byte(ast::Name),
@@ -143,6 +158,8 @@ pub enum Token {
// In right-hand-sides of MBE macros:
/// A syntactic variable that will be filled in by macro expansion.
SubstNt(ast::Ident, IdentStyle),
+ /// A macro variable with special meaning.
+ SpecialVarNt(SpecialMacroVar),
// Junk. These carry no data because we don't really care about the data
// they *would* carry, and don't really want to allocate a new ident for
@@ -265,6 +282,13 @@ impl Token {
}
}
+ pub fn is_keyword_allow_following_colon(&self, kw: keywords::Keyword) -> bool {
+ match *self {
+ Ident(sid, _) => { kw.to_name() == sid.name }
+ _ => { false }
+ }
+ }
+
/// Returns `true` if the token is either a special identifier, or a strict
/// or reserved keyword.
#[allow(non_upper_case_globals)]
@@ -550,6 +574,7 @@ declare_special_idents_and_keywords! {
(56, Abstract, "abstract");
(57, Final, "final");
(58, Override, "override");
+ (59, Macro, "macro");
}
}
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 61b7aa408a8d5..27db49b65ce19 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -272,6 +272,8 @@ pub fn token_to_string(tok: &Token) -> String {
token::Comment => "/* */".to_string(),
token::Shebang(s) => format!("/* shebang: {}*/", s.as_str()),
+ token::SpecialVarNt(var) => format!("${}", var.as_str()),
+
token::Interpolated(ref nt) => match *nt {
token::NtExpr(ref e) => expr_to_string(&**e),
token::NtMeta(ref e) => meta_item_to_string(&**e),
diff --git a/src/libsyntax/show_span.rs b/src/libsyntax/show_span.rs
index 354ba854b101a..e7c9101ebc657 100644
--- a/src/libsyntax/show_span.rs
+++ b/src/libsyntax/show_span.rs
@@ -28,8 +28,8 @@ impl<'a, 'v> Visitor<'v> for ShowSpanVisitor<'a> {
visit::walk_expr(self, e);
}
- fn visit_mac(&mut self, macro: &ast::Mac) {
- visit::walk_mac(self, macro);
+ fn visit_mac(&mut self, mac: &ast::Mac) {
+ visit::walk_mac(self, mac);
}
}
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index 5a4d0cc3bd896..4ef7eb97a2189 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -65,12 +65,8 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
Some((actual_crate_name, ast::CookedStr)),
ast::DUMMY_NODE_ID),
attrs: vec!(
- attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
- InternedString::new("phase"),
- vec!(
- attr::mk_word_item(InternedString::new("plugin")),
- attr::mk_word_item(InternedString::new("link")
- ))))),
+ attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
+ InternedString::new("macro_use")))),
vis: ast::Inherited,
span: DUMMY_SP
});
@@ -82,16 +78,6 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
// don't add #![no_std] here, that will block the prelude injection later.
// Add it during the prelude injection instead.
- // Add #![feature(phase)] here, because we use #[phase] on extern crate std.
- let feat_phase_attr = attr::mk_attr_inner(attr::mk_attr_id(),
- attr::mk_list_item(
- InternedString::new("feature"),
- vec![attr::mk_word_item(InternedString::new("phase"))],
- ));
- // std_inject runs after feature checking so manually mark this attr
- attr::mark_used(&feat_phase_attr);
- krate.attrs.push(feat_phase_attr);
-
krate
}
}
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 054a288a69e6d..888c0251d7652 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -115,13 +115,13 @@ pub trait Visitor<'v> : Sized {
fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
walk_explicit_self(self, es)
}
- fn visit_mac(&mut self, _macro: &'v Mac) {
+ fn visit_mac(&mut self, _mac: &'v Mac) {
panic!("visit_mac disabled by default");
// NB: see note about macros above.
// if you really want a visitor that
// works on macros, use this
// definition in your trait impl:
- // visit::walk_mac(self, _macro)
+ // visit::walk_mac(self, _mac)
}
fn visit_path(&mut self, path: &'v Path, _id: ast::NodeId) {
walk_path(self, path)
@@ -334,7 +334,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_trait_item(method)
}
}
- ItemMac(ref macro) => visitor.visit_mac(macro),
+ ItemMac(ref mac) => visitor.visit_mac(mac),
}
for attr in item.attrs.iter() {
visitor.visit_attribute(attr);
@@ -546,7 +546,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
visitor.visit_pat(&**postpattern)
}
}
- PatMac(ref macro) => visitor.visit_mac(macro),
+ PatMac(ref mac) => visitor.visit_mac(mac),
}
}
@@ -746,7 +746,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
StmtExpr(ref expression, _) | StmtSemi(ref expression, _) => {
visitor.visit_expr(&**expression)
}
- StmtMac(ref macro, _) => visitor.visit_mac(&**macro),
+ StmtMac(ref mac, _) => visitor.visit_mac(&**mac),
}
}
@@ -893,7 +893,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
ExprRet(ref optional_expression) => {
walk_expr_opt(visitor, optional_expression)
}
- ExprMac(ref macro) => visitor.visit_mac(macro),
+ ExprMac(ref mac) => visitor.visit_mac(mac),
ExprParen(ref subexpression) => {
visitor.visit_expr(&**subexpression)
}
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 3a442080077f3..dd42bede13ac3 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -52,7 +52,13 @@
#![deny(missing_docs)]
-#[phase(plugin, link)] extern crate log;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
pub use terminfo::TerminfoTerminal;
#[cfg(windows)]
diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs
index fe96d7b8b7d01..5f0111c7d7a84 100644
--- a/src/libterm/terminfo/parser/compiled.rs
+++ b/src/libterm/terminfo/parser/compiled.rs
@@ -160,12 +160,12 @@ pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tb
/// Parse a compiled terminfo entry, using long capability names if `longnames` is true
pub fn parse(file: &mut io::Reader, longnames: bool)
-> Result, String> {
- macro_rules! try( ($e:expr) => (
+ macro_rules! try { ($e:expr) => (
match $e {
Ok(e) => e,
Err(e) => return Err(format!("{}", e))
}
- ) );
+ ) }
let bnames;
let snames;
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 3fb2211eff23a..0419d85d3914e 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -32,7 +32,7 @@
html_root_url = "http://doc.rust-lang.org/nightly/")]
#![allow(unknown_features)]
-#![feature(asm, macro_rules, phase, globs, slicing_syntax)]
+#![feature(asm, globs, slicing_syntax)]
#![feature(unboxed_closures, default_type_params)]
#![feature(old_orphan_check)]
diff --git a/src/test/auxiliary/issue-13560-3.rs b/src/test/auxiliary/issue-13560-3.rs
index c80a7643e01ac..5510d3e2e0df1 100644
--- a/src/test/auxiliary/issue-13560-3.rs
+++ b/src/test/auxiliary/issue-13560-3.rs
@@ -11,8 +11,7 @@
// no-prefer-dynamic
#![crate_type = "rlib"]
-#![feature(phase)]
-#[phase(plugin)] extern crate "issue-13560-1" as t1;
-#[phase(plugin, link)] extern crate "issue-13560-2" as t2;
+#[macro_use] #[no_link] extern crate "issue-13560-1" as t1;
+#[macro_use] extern crate "issue-13560-2" as t2;
diff --git a/src/test/auxiliary/lint_group_plugin_test.rs b/src/test/auxiliary/lint_group_plugin_test.rs
index add54ed01e00e..097a5827fc4be 100644
--- a/src/test/auxiliary/lint_group_plugin_test.rs
+++ b/src/test/auxiliary/lint_group_plugin_test.rs
@@ -10,12 +10,12 @@
// force-host
-#![feature(phase, plugin_registrar)]
+#![feature(plugin_registrar)]
extern crate syntax;
// Load rustc as a plugin to get macros
-#[phase(plugin, link)]
+#[macro_use]
extern crate rustc;
use syntax::ast;
diff --git a/src/test/auxiliary/lint_plugin_test.rs b/src/test/auxiliary/lint_plugin_test.rs
index 6c78cdce28ac4..01ef08c475234 100644
--- a/src/test/auxiliary/lint_plugin_test.rs
+++ b/src/test/auxiliary/lint_plugin_test.rs
@@ -10,12 +10,12 @@
// force-host
-#![feature(phase, plugin_registrar)]
+#![feature(plugin_registrar)]
extern crate syntax;
// Load rustc as a plugin to get macros
-#[phase(plugin, link)]
+#[macro_use]
extern crate rustc;
use syntax::ast;
diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs
index 82af18b189b68..708830d025986 100644
--- a/src/test/auxiliary/lint_stability.rs
+++ b/src/test/auxiliary/lint_stability.rs
@@ -10,9 +10,6 @@
#![crate_name="lint_stability"]
#![crate_type = "lib"]
-#![feature(macro_rules)]
-#![macro_escape]
-
#[deprecated]
pub fn deprecated() {}
#[deprecated="text"]
@@ -181,16 +178,16 @@ pub struct FrozenTupleStruct(pub int);
pub struct LockedTupleStruct(pub int);
#[macro_export]
-macro_rules! macro_test(
+macro_rules! macro_test {
() => (deprecated());
-);
+}
#[macro_export]
-macro_rules! macro_test_arg(
+macro_rules! macro_test_arg {
($func:expr) => ($func);
-);
+}
#[macro_export]
-macro_rules! macro_test_arg_nested(
+macro_rules! macro_test_arg_nested {
($func:ident) => (macro_test_arg!($func()));
-);
+}
diff --git a/src/test/auxiliary/logging_right_crate.rs b/src/test/auxiliary/logging_right_crate.rs
index fad70a917980d..bf4ab975cedd8 100644
--- a/src/test/auxiliary/logging_right_crate.rs
+++ b/src/test/auxiliary/logging_right_crate.rs
@@ -8,8 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(phase)]
-#[phase(plugin, link)] extern crate log;
+#[macro_use] extern crate log;
pub fn foo() {
fn death() -> int { panic!() }
diff --git a/src/test/auxiliary/macro_crate_MacroRulesTT.rs b/src/test/auxiliary/macro_crate_MacroRulesTT.rs
new file mode 100644
index 0000000000000..d50c27a4e75bb
--- /dev/null
+++ b/src/test/auxiliary/macro_crate_MacroRulesTT.rs
@@ -0,0 +1,25 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// force-host
+
+#![feature(plugin_registrar)]
+
+extern crate syntax;
+extern crate rustc;
+
+use syntax::parse::token;
+use syntax::ext::base::MacroRulesTT;
+use rustc::plugin::Registry;
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+ reg.register_syntax_extension(token::intern("bogus"), MacroRulesTT);
+}
diff --git a/src/test/auxiliary/macro_crate_def_only.rs b/src/test/auxiliary/macro_crate_def_only.rs
index ad3e72f5fa221..4f55ac4f65fd4 100644
--- a/src/test/auxiliary/macro_crate_def_only.rs
+++ b/src/test/auxiliary/macro_crate_def_only.rs
@@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
#[macro_export]
-macro_rules! make_a_5(
+macro_rules! make_a_5 {
() => (5)
-);
+}
diff --git a/src/test/auxiliary/macro_crate_nonterminal.rs b/src/test/auxiliary/macro_crate_nonterminal.rs
new file mode 100644
index 0000000000000..922efc1aec38f
--- /dev/null
+++ b/src/test/auxiliary/macro_crate_nonterminal.rs
@@ -0,0 +1,22 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn increment(x: uint) -> uint {
+ x + 1
+}
+
+#[macro_export]
+macro_rules! increment {
+ ($x:expr) => ($crate::increment($x))
+}
+
+pub fn check_local() {
+ assert_eq!(increment!(3), 4);
+}
diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs
index b82cfcbc8fcb2..ce66cad213d0e 100644
--- a/src/test/auxiliary/macro_crate_test.rs
+++ b/src/test/auxiliary/macro_crate_test.rs
@@ -10,7 +10,7 @@
// force-host
-#![feature(globs, plugin_registrar, macro_rules, quote)]
+#![feature(globs, plugin_registrar, quote)]
extern crate syntax;
extern crate rustc;
@@ -24,9 +24,9 @@ use syntax::ptr::P;
use rustc::plugin::Registry;
#[macro_export]
-macro_rules! exported_macro (() => (2i));
+macro_rules! exported_macro { () => (2i) }
-macro_rules! unexported_macro (() => (3i));
+macro_rules! unexported_macro { () => (3i) }
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
diff --git a/src/test/auxiliary/macro_export_inner_module.rs b/src/test/auxiliary/macro_export_inner_module.rs
index 9b4b1ceb5c1e7..84e944f69b98e 100644
--- a/src/test/auxiliary/macro_export_inner_module.rs
+++ b/src/test/auxiliary/macro_export_inner_module.rs
@@ -8,11 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
pub mod inner {
#[macro_export]
- macro_rules! foo(
+ macro_rules! foo {
() => (1)
- );
+ }
}
diff --git a/src/test/auxiliary/macro_non_reexport_2.rs b/src/test/auxiliary/macro_non_reexport_2.rs
new file mode 100644
index 0000000000000..910fcd2e3671d
--- /dev/null
+++ b/src/test/auxiliary/macro_non_reexport_2.rs
@@ -0,0 +1,19 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "dylib"]
+
+// Since we load a serialized macro with all its attributes, accidentally
+// re-exporting a `#[macro_export] macro_rules!` is something of a concern!
+//
+// We avoid it at the moment only because of the order in which we do things.
+
+#[macro_use] #[no_link]
+extern crate macro_reexport_1;
diff --git a/src/test/auxiliary/macro_reexport_1.rs b/src/test/auxiliary/macro_reexport_1.rs
new file mode 100644
index 0000000000000..a913749bc66a9
--- /dev/null
+++ b/src/test/auxiliary/macro_reexport_1.rs
@@ -0,0 +1,15 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "dylib"]
+#[macro_export]
+macro_rules! reexported {
+ () => ( 3u )
+}
diff --git a/src/test/auxiliary/macro_reexport_2.rs b/src/test/auxiliary/macro_reexport_2.rs
new file mode 100644
index 0000000000000..15d9f9cc9146d
--- /dev/null
+++ b/src/test/auxiliary/macro_reexport_2.rs
@@ -0,0 +1,15 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "dylib"]
+
+#[macro_reexport(reexported)]
+#[macro_use] #[no_link]
+extern crate macro_reexport_1;
diff --git a/src/test/auxiliary/macro_reexport_2_no_use.rs b/src/test/auxiliary/macro_reexport_2_no_use.rs
new file mode 100644
index 0000000000000..63142b0a69935
--- /dev/null
+++ b/src/test/auxiliary/macro_reexport_2_no_use.rs
@@ -0,0 +1,15 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "dylib"]
+
+#[macro_reexport(reexported)]
+#[no_link]
+extern crate macro_reexport_1;
diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/auxiliary/plugin_args.rs
new file mode 100644
index 0000000000000..b90c3f1d727bf
--- /dev/null
+++ b/src/test/auxiliary/plugin_args.rs
@@ -0,0 +1,50 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// force-host
+
+#![feature(plugin_registrar)]
+
+extern crate syntax;
+extern crate rustc;
+
+use std::borrow::ToOwned;
+use syntax::ast;
+use syntax::codemap::Span;
+use syntax::ext::build::AstBuilder;
+use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacExpr, NormalTT};
+use syntax::parse::token;
+use syntax::print::pprust;
+use syntax::ptr::P;
+use rustc::plugin::Registry;
+
+struct Expander {
+ args: P,
+}
+
+impl TTMacroExpander for Expander {
+ fn expand<'cx>(&self,
+ ecx: &'cx mut ExtCtxt,
+ sp: Span,
+ _: &[ast::TokenTree]) -> Box {
+
+ let attr = ecx.attribute(sp, self.args.clone());
+ let src = pprust::attribute_to_string(&attr);
+ let interned = token::intern_and_get_ident(src.as_slice());
+ MacExpr::new(ecx.expr_str(sp, interned))
+ }
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+ let args = reg.args().clone();
+ reg.register_syntax_extension(token::intern("plugin_args"),
+ NormalTT(box Expander { args: args, }, None));
+}
diff --git a/src/test/auxiliary/svh-a-base.rs b/src/test/auxiliary/svh-a-base.rs
index c035f1203f8e3..12833daf60458 100644
--- a/src/test/auxiliary/svh-a-base.rs
+++ b/src/test/auxiliary/svh-a-base.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-change-lit.rs b/src/test/auxiliary/svh-a-change-lit.rs
index 614487c981713..9e74bf281358f 100644
--- a/src/test/auxiliary/svh-a-change-lit.rs
+++ b/src/test/auxiliary/svh-a-change-lit.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-change-significant-cfg.rs b/src/test/auxiliary/svh-a-change-significant-cfg.rs
index 99506309a592e..c900550041b5c 100644
--- a/src/test/auxiliary/svh-a-change-significant-cfg.rs
+++ b/src/test/auxiliary/svh-a-change-significant-cfg.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-change-trait-bound.rs b/src/test/auxiliary/svh-a-change-trait-bound.rs
index 8ec4eaebbe8df..04f8eb3cf9bc0 100644
--- a/src/test/auxiliary/svh-a-change-trait-bound.rs
+++ b/src/test/auxiliary/svh-a-change-trait-bound.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-change-type-arg.rs b/src/test/auxiliary/svh-a-change-type-arg.rs
index ad120e12f86fb..c7e0a18768a3d 100644
--- a/src/test/auxiliary/svh-a-change-type-arg.rs
+++ b/src/test/auxiliary/svh-a-change-type-arg.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-change-type-ret.rs b/src/test/auxiliary/svh-a-change-type-ret.rs
index c68c13c0991f2..5100af323183b 100644
--- a/src/test/auxiliary/svh-a-change-type-ret.rs
+++ b/src/test/auxiliary/svh-a-change-type-ret.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-change-type-static.rs b/src/test/auxiliary/svh-a-change-type-static.rs
index 6c13e84a7febe..077c33cb90d75 100644
--- a/src/test/auxiliary/svh-a-change-type-static.rs
+++ b/src/test/auxiliary/svh-a-change-type-static.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-comment.rs b/src/test/auxiliary/svh-a-comment.rs
index 3d0973cb7ba13..d481fa5a1fa3b 100644
--- a/src/test/auxiliary/svh-a-comment.rs
+++ b/src/test/auxiliary/svh-a-comment.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-doc.rs b/src/test/auxiliary/svh-a-doc.rs
index 1ad9e5e1c0e3a..9e99a355ac1ee 100644
--- a/src/test/auxiliary/svh-a-doc.rs
+++ b/src/test/auxiliary/svh-a-doc.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-macro.rs b/src/test/auxiliary/svh-a-macro.rs
index 6bd36b5a9b1c4..b8dd497ac99c8 100644
--- a/src/test/auxiliary/svh-a-macro.rs
+++ b/src/test/auxiliary/svh-a-macro.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-no-change.rs b/src/test/auxiliary/svh-a-no-change.rs
index c035f1203f8e3..12833daf60458 100644
--- a/src/test/auxiliary/svh-a-no-change.rs
+++ b/src/test/auxiliary/svh-a-no-change.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-redundant-cfg.rs b/src/test/auxiliary/svh-a-redundant-cfg.rs
index d67c8f4c18179..690ddc670f5fa 100644
--- a/src/test/auxiliary/svh-a-redundant-cfg.rs
+++ b/src/test/auxiliary/svh-a-redundant-cfg.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/svh-a-whitespace.rs b/src/test/auxiliary/svh-a-whitespace.rs
index 73798f3787558..216e8e997f22d 100644
--- a/src/test/auxiliary/svh-a-whitespace.rs
+++ b/src/test/auxiliary/svh-a-whitespace.rs
@@ -13,8 +13,6 @@
//! should not affect the strict version hash (SVH) computation
//! (#14132).
-#![feature(macro_rules)]
-
#![crate_name = "a"]
macro_rules! three {
diff --git a/src/test/auxiliary/two_macros.rs b/src/test/auxiliary/two_macros.rs
new file mode 100644
index 0000000000000..11b6108b99ed9
--- /dev/null
+++ b/src/test/auxiliary/two_macros.rs
@@ -0,0 +1,17 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// force-host
+
+#[macro_export]
+macro_rules! macro_one { () => ("one") }
+
+#[macro_export]
+macro_rules! macro_two { () => ("two") }
diff --git a/src/test/auxiliary/weak-lang-items.rs b/src/test/auxiliary/weak-lang-items.rs
index 6a1f8588b60d7..39462fdc1e528 100644
--- a/src/test/auxiliary/weak-lang-items.rs
+++ b/src/test/auxiliary/weak-lang-items.rs
@@ -14,10 +14,9 @@
// it hasn't been defined just yet. Make sure we don't explode.
#![no_std]
-#![feature(phase)]
#![crate_type = "rlib"]
-#[phase(plugin, link)]
+#[macro_use]
extern crate core;
struct A;
diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs
index ee7c442da195c..9007b4fd64c43 100644
--- a/src/test/bench/core-std.rs
+++ b/src/test/bench/core-std.rs
@@ -11,7 +11,6 @@
// ignore-lexer-test FIXME #15679
// Microbenchmarks for various functions in std and extra
-#![feature(macro_rules)]
#![feature(unboxed_closures)]
use std::io::File;
@@ -28,11 +27,12 @@ fn main() {
let argv = os::args();
let _tests = argv.slice(1, argv.len());
- macro_rules! bench (
+ macro_rules! bench {
($id:ident) =>
(maybe_run_test(argv.as_slice(),
stringify!($id).to_string(),
- $id)));
+ $id))
+ }
bench!(shift_push);
bench!(read_line);
diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs
index 4e8e0d64d52ce..16d6036d4c40f 100644
--- a/src/test/bench/shootout-mandelbrot.rs
+++ b/src/test/bench/shootout-mandelbrot.rs
@@ -38,7 +38,6 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
-#![feature(macro_rules)]
#![feature(simd)]
#![allow(experimental)]
diff --git a/src/test/bench/shootout-regex-dna.rs b/src/test/bench/shootout-regex-dna.rs
index 4f87171f5d3fa..ef538eb699189 100644
--- a/src/test/bench/shootout-regex-dna.rs
+++ b/src/test/bench/shootout-regex-dna.rs
@@ -41,7 +41,7 @@
// ignore-stage1
// ignore-cross-compile #12102
-#![feature(macro_rules, phase, slicing_syntax)]
+#![feature(plugin, slicing_syntax)]
extern crate regex;
diff --git a/src/test/compile-fail-fulldeps/gated-phase.rs b/src/test/compile-fail-fulldeps/gated-plugin.rs
similarity index 86%
rename from src/test/compile-fail-fulldeps/gated-phase.rs
rename to src/test/compile-fail-fulldeps/gated-plugin.rs
index 1f384b856334c..89090d5f38abe 100644
--- a/src/test/compile-fail-fulldeps/gated-phase.rs
+++ b/src/test/compile-fail-fulldeps/gated-plugin.rs
@@ -11,8 +11,8 @@
// aux-build:macro_crate_test.rs
// ignore-stage1
-#[phase(plugin)]
-//~^ ERROR compile time crate loading is experimental and possibly buggy
+#[plugin] #[no_link]
+//~^ ERROR compiler plugins are experimental and possibly buggy
extern crate macro_crate_test;
fn main() {}
diff --git a/src/test/compile-fail-fulldeps/lint-group-plugin-deny-cmdline.rs b/src/test/compile-fail-fulldeps/lint-group-plugin-deny-cmdline.rs
index 5edaa78eeea38..11ae556395962 100644
--- a/src/test/compile-fail-fulldeps/lint-group-plugin-deny-cmdline.rs
+++ b/src/test/compile-fail-fulldeps/lint-group-plugin-deny-cmdline.rs
@@ -12,9 +12,9 @@
// ignore-stage1
// compile-flags: -D lint-me
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate lint_group_plugin_test;
fn lintme() { } //~ ERROR item is named 'lintme'
diff --git a/src/test/compile-fail-fulldeps/lint-plugin-deny-attr.rs b/src/test/compile-fail-fulldeps/lint-plugin-deny-attr.rs
index 9eb39a9178c02..62007d6575a8d 100644
--- a/src/test/compile-fail-fulldeps/lint-plugin-deny-attr.rs
+++ b/src/test/compile-fail-fulldeps/lint-plugin-deny-attr.rs
@@ -11,10 +11,10 @@
// aux-build:lint_plugin_test.rs
// ignore-stage1
-#![feature(phase)]
+#![feature(plugin)]
#![deny(test_lint)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } //~ ERROR item is named 'lintme'
diff --git a/src/test/compile-fail-fulldeps/lint-plugin-deny-cmdline.rs b/src/test/compile-fail-fulldeps/lint-plugin-deny-cmdline.rs
index 46aa4b6b5b741..da51c047f57e1 100644
--- a/src/test/compile-fail-fulldeps/lint-plugin-deny-cmdline.rs
+++ b/src/test/compile-fail-fulldeps/lint-plugin-deny-cmdline.rs
@@ -12,9 +12,9 @@
// ignore-stage1
// compile-flags: -D test-lint
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } //~ ERROR item is named 'lintme'
diff --git a/src/test/compile-fail-fulldeps/lint-plugin-forbid-attrs.rs b/src/test/compile-fail-fulldeps/lint-plugin-forbid-attrs.rs
index 329d3e86c052e..cf51958b53d8b 100644
--- a/src/test/compile-fail-fulldeps/lint-plugin-forbid-attrs.rs
+++ b/src/test/compile-fail-fulldeps/lint-plugin-forbid-attrs.rs
@@ -11,10 +11,10 @@
// aux-build:lint_plugin_test.rs
// ignore-stage1
-#![feature(phase)]
+#![feature(plugin)]
#![forbid(test_lint)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } //~ ERROR item is named 'lintme'
diff --git a/src/test/compile-fail-fulldeps/lint-plugin-forbid-cmdline.rs b/src/test/compile-fail-fulldeps/lint-plugin-forbid-cmdline.rs
index 601faa22d77a0..9a36143f65c6a 100644
--- a/src/test/compile-fail-fulldeps/lint-plugin-forbid-cmdline.rs
+++ b/src/test/compile-fail-fulldeps/lint-plugin-forbid-cmdline.rs
@@ -12,9 +12,9 @@
// ignore-stage1
// compile-flags: -F test-lint
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } //~ ERROR item is named 'lintme'
diff --git a/src/test/compile-fail-fulldeps/macro-crate-cannot-read-embedded-ident.rs b/src/test/compile-fail-fulldeps/macro-crate-cannot-read-embedded-ident.rs
index fc7664c480fdb..46eb4d4b2eff1 100644
--- a/src/test/compile-fail-fulldeps/macro-crate-cannot-read-embedded-ident.rs
+++ b/src/test/compile-fail-fulldeps/macro-crate-cannot-read-embedded-ident.rs
@@ -20,9 +20,9 @@
// editors, so instead he made a macro that expands into the embedded
// ident form.
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate macro_crate_test;
fn main() {
diff --git a/src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs b/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs
similarity index 95%
rename from src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs
rename to src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs
index 00aeb1c1bae8f..adcdba04cc782 100644
--- a/src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs
+++ b/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs
@@ -12,9 +12,7 @@
// ignore-stage1
// ignore-android
-#![feature(phase)]
-
-#[phase(plugin)]
+#[macro_use] #[no_link]
extern crate macro_crate_test;
fn main() {
diff --git a/src/test/compile-fail-fulldeps/macro-crate-rlib.rs b/src/test/compile-fail-fulldeps/macro-crate-rlib.rs
index d4f286f20e8f7..1f44ac7cf9cae 100644
--- a/src/test/compile-fail-fulldeps/macro-crate-rlib.rs
+++ b/src/test/compile-fail-fulldeps/macro-crate-rlib.rs
@@ -14,8 +14,8 @@
// ignore-android
// ignore-cross-compile gives a different error message
-#![feature(phase)]
-#[phase(plugin)] extern crate rlib_crate_test;
+#![feature(plugin)]
+#[plugin] #[no_link] extern crate rlib_crate_test;
//~^ ERROR: plugin crate `rlib_crate_test` only found in rlib format, but must be available in dylib format
fn main() {}
diff --git a/src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs b/src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs
index 6a3b0b91ffe29..b5ff8b7155632 100644
--- a/src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs
+++ b/src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs
@@ -12,9 +12,7 @@
// ignore-stage1
// ignore-android
-#![feature(phase)]
-
-#[phase(plugin)]
+#[macro_use] #[no_link]
extern crate macro_crate_test;
fn main() {
diff --git a/src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs b/src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs
index 7a7eac7b70925..65657eea1efb0 100644
--- a/src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs
+++ b/src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs
@@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(phase)]
-
-#[phase(plugin)]
+#[macro_use] #[no_link]
extern crate doesnt_exist; //~ ERROR can't find crate
fn main() {}
diff --git a/src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs b/src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs
new file mode 100644
index 0000000000000..cff2e5eaf8786
--- /dev/null
+++ b/src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs
@@ -0,0 +1,21 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_crate_MacroRulesTT.rs
+// ignore-stage1
+// ignore-android
+// error-pattern: plugin tried to register a new MacroRulesTT
+
+#![feature(plugin)]
+
+#[plugin] #[no_link]
+extern crate macro_crate_MacroRulesTT;
+
+fn main() { }
diff --git a/src/test/compile-fail/asm-src-loc-codegen-units.rs b/src/test/compile-fail/asm-src-loc-codegen-units.rs
index 1b8fb32a808dc..5ebcdb20b1952 100644
--- a/src/test/compile-fail/asm-src-loc-codegen-units.rs
+++ b/src/test/compile-fail/asm-src-loc-codegen-units.rs
@@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
+// ignore-stage1 (#20184)
// compile-flags: -C codegen-units=2
// error-pattern: build without -C codegen-units for more exact errors
diff --git a/src/test/compile-fail/cleanup-rvalue-scopes-cf.rs b/src/test/compile-fail/cleanup-rvalue-scopes-cf.rs
index b79f4507d4673..dcbb25ba5a95f 100644
--- a/src/test/compile-fail/cleanup-rvalue-scopes-cf.rs
+++ b/src/test/compile-fail/cleanup-rvalue-scopes-cf.rs
@@ -11,8 +11,6 @@
// Test that the borrow checker prevents pointers to temporaries
// with statement lifetimes from escaping.
-#![feature(macro_rules)]
-
use std::ops::Drop;
static mut FLAGS: u64 = 0;
diff --git a/src/test/compile-fail/const-block-non-item-statement.rs b/src/test/compile-fail/const-block-non-item-statement.rs
index 0a004c101ee4f..1814b1cd544ef 100644
--- a/src/test/compile-fail/const-block-non-item-statement.rs
+++ b/src/test/compile-fail/const-block-non-item-statement.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
static A: uint = { 1u; 2 };
//~^ ERROR: blocks in constants are limited to items and tail expressions
diff --git a/src/test/run-pass/phase-use-ignored.rs b/src/test/compile-fail/deprecated-phase.rs
similarity index 87%
rename from src/test/run-pass/phase-use-ignored.rs
rename to src/test/compile-fail/deprecated-phase.rs
index 5015e43fa3f34..1401494d987a2 100644
--- a/src/test/run-pass/phase-use-ignored.rs
+++ b/src/test/compile-fail/deprecated-phase.rs
@@ -8,11 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-
-#![feature(phase)]
-
-#[phase(plugin)]
-use std::mem;
+#[phase(blah)]
+//~^ ERROR #[phase] is deprecated
+extern crate foo;
fn main() {}
-
diff --git a/src/test/compile-fail/empty-macro-use.rs b/src/test/compile-fail/empty-macro-use.rs
new file mode 100644
index 0000000000000..fbf6287db9444
--- /dev/null
+++ b/src/test/compile-fail/empty-macro-use.rs
@@ -0,0 +1,19 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use()]
+extern crate two_macros;
+
+pub fn main() {
+ macro_two!(); //~ ERROR macro undefined
+}
diff --git a/src/test/compile-fail/fail-no-dead-code-core.rs b/src/test/compile-fail/fail-no-dead-code-core.rs
index 49a927b9879e4..6f75181c31cbc 100644
--- a/src/test/compile-fail/fail-no-dead-code-core.rs
+++ b/src/test/compile-fail/fail-no-dead-code-core.rs
@@ -8,11 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(phase)]
#![deny(dead_code)]
#![allow(unreachable_code)]
-#[phase(link, plugin)] extern crate core;
+#[macro_use] extern crate core;
fn foo() { //~ ERROR function is never used
diff --git a/src/test/compile-fail/hygienic-label-1.rs b/src/test/compile-fail/hygienic-label-1.rs
index 0e87dc97c2631..dd6682a6f4282 100644
--- a/src/test/compile-fail/hygienic-label-1.rs
+++ b/src/test/compile-fail/hygienic-label-1.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! foo {
() => { break 'x; }
}
diff --git a/src/test/compile-fail/hygienic-label-2.rs b/src/test/compile-fail/hygienic-label-2.rs
index fe87e32459bb1..24194d7bbe970 100644
--- a/src/test/compile-fail/hygienic-label-2.rs
+++ b/src/test/compile-fail/hygienic-label-2.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! foo {
($e: expr) => { 'x: loop { $e } }
}
diff --git a/src/test/compile-fail/hygienic-label-3.rs b/src/test/compile-fail/hygienic-label-3.rs
index b5954ac99303b..4ff3bec3c6459 100644
--- a/src/test/compile-fail/hygienic-label-3.rs
+++ b/src/test/compile-fail/hygienic-label-3.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! foo {
() => { break 'x; }
}
diff --git a/src/test/compile-fail/hygienic-label-4.rs b/src/test/compile-fail/hygienic-label-4.rs
index 67fa56b130677..174e8a2834f4b 100644
--- a/src/test/compile-fail/hygienic-label-4.rs
+++ b/src/test/compile-fail/hygienic-label-4.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! foo {
($e: expr) => { 'x: for _ in range(0,1) { $e } }
}
diff --git a/src/test/compile-fail/if-let.rs b/src/test/compile-fail/if-let.rs
index 88b6854bb1d2c..971f643c0fe91 100644
--- a/src/test/compile-fail/if-let.rs
+++ b/src/test/compile-fail/if-let.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
fn macros() {
macro_rules! foo{
($p:pat, $e:expr, $b:block) => {{
diff --git a/src/test/compile-fail/infinite-macro-expansion.rs b/src/test/compile-fail/infinite-macro-expansion.rs
index 22ac2eb1f7d5d..74835f4bf22ca 100644
--- a/src/test/compile-fail/infinite-macro-expansion.rs
+++ b/src/test/compile-fail/infinite-macro-expansion.rs
@@ -8,13 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! recursive(
- () => (
- recursive!() //~ ERROR recursion limit reached while expanding the macro `recursive`
- )
- );
+macro_rules! recursive {
+ () => (recursive!()) //~ ERROR recursion limit reached while expanding the macro `recursive`
+}
fn main() {
recursive!()
diff --git a/src/test/compile-fail/issue-10536.rs b/src/test/compile-fail/issue-10536.rs
index 36afc729de959..370a6228db6ac 100644
--- a/src/test/compile-fail/issue-10536.rs
+++ b/src/test/compile-fail/issue-10536.rs
@@ -13,8 +13,6 @@
// error-pattern:
-#![feature(macro_rules)]
-
macro_rules! foo{
() => {{
macro_rules! bar{() => (())}
diff --git a/src/test/compile-fail/issue-15167.rs b/src/test/compile-fail/issue-15167.rs
index 300831b100773..d4de4e177f026 100644
--- a/src/test/compile-fail/issue-15167.rs
+++ b/src/test/compile-fail/issue-15167.rs
@@ -15,9 +15,7 @@
// ignore-test
-#![feature(macro_rules)]
-
-macro_rules! f(() => (n))
+macro_rules! f { () => (n) }
fn main() -> (){
for n in range(0i, 1) {
diff --git a/src/test/compile-fail/issue-16098.rs b/src/test/compile-fail/issue-16098.rs
index 5adcd7c2bb6d7..68ac19b383f5a 100644
--- a/src/test/compile-fail/issue-16098.rs
+++ b/src/test/compile-fail/issue-16098.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! prob1 {
(0) => {
0
diff --git a/src/test/compile-fail/issue-6596.rs b/src/test/compile-fail/issue-6596.rs
index 3222b2cd53719..c5be0da5f4b2a 100644
--- a/src/test/compile-fail/issue-6596.rs
+++ b/src/test/compile-fail/issue-6596.rs
@@ -8,15 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
// error-pattern: unexpected token
-macro_rules! e(
+macro_rules! e {
($inp:ident) => (
$nonexistent
);
-);
+}
fn main() {
e!(foo);
diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs
index 8e1723ddab24c..63dc8d692bacd 100644
--- a/src/test/compile-fail/lint-stability.rs
+++ b/src/test/compile-fail/lint-stability.rs
@@ -13,19 +13,20 @@
// aux-build:stability_cfg1.rs
// aux-build:stability_cfg2.rs
-#![feature(globs, phase)]
+#![feature(globs)]
#![deny(unstable)]
#![deny(deprecated)]
#![deny(experimental)]
#![allow(dead_code)]
+#[macro_use]
+extern crate lint_stability; //~ ERROR: use of unmarked item
+
mod cross_crate {
extern crate stability_cfg1;
extern crate stability_cfg2; //~ ERROR: use of experimental item
- #[phase(plugin, link)]
- extern crate lint_stability; //~ ERROR: use of unmarked item
- use self::lint_stability::*;
+ use lint_stability::*;
fn test() {
let foo = MethodTester;
diff --git a/src/test/compile-fail/lint-unsafe-block.rs b/src/test/compile-fail/lint-unsafe-block.rs
index 8899d06804f1e..56d2b2cd6c084 100644
--- a/src/test/compile-fail/lint-unsafe-block.rs
+++ b/src/test/compile-fail/lint-unsafe-block.rs
@@ -11,8 +11,6 @@
#![allow(unused_unsafe)]
#![allow(dead_code)]
#![deny(unsafe_blocks)]
-#![feature(macro_rules)]
-
unsafe fn allowed() {}
#[allow(unsafe_blocks)] fn also_allowed() { unsafe {} }
diff --git a/src/test/compile-fail/liveness-return-last-stmt-semi.rs b/src/test/compile-fail/liveness-return-last-stmt-semi.rs
index e92faa6bdaf6e..9cfffb5fa6b62 100644
--- a/src/test/compile-fail/liveness-return-last-stmt-semi.rs
+++ b/src/test/compile-fail/liveness-return-last-stmt-semi.rs
@@ -10,9 +10,7 @@
//
// regression test for #8005
-#![feature(macro_rules)]
-
-macro_rules! test ( () => { fn foo() -> int { 1i; } } );
+macro_rules! test { () => { fn foo() -> int { 1i; } } }
//~^ ERROR not all control paths return a value
//~^^ HELP consider removing this semicolon
diff --git a/src/test/compile-fail/macro-crate-nonterminal-non-root.rs b/src/test/compile-fail/macro-crate-nonterminal-non-root.rs
new file mode 100644
index 0000000000000..67aaf05c3101b
--- /dev/null
+++ b/src/test/compile-fail/macro-crate-nonterminal-non-root.rs
@@ -0,0 +1,20 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_crate_nonterminal.rs
+// ignore-stage1
+
+mod foo {
+ #[macro_use]
+ extern crate macro_crate_nonterminal; //~ ERROR must be at the crate root
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/macro-incomplete-parse.rs b/src/test/compile-fail/macro-incomplete-parse.rs
index 71b656d0bbb57..53b29ccb0c0c7 100644
--- a/src/test/compile-fail/macro-incomplete-parse.rs
+++ b/src/test/compile-fail/macro-incomplete-parse.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! ignored_item {
() => {
fn foo() {}
diff --git a/src/test/compile-fail/macro-inner-attributes.rs b/src/test/compile-fail/macro-inner-attributes.rs
index f64b7be50e307..e4fc5bb462700 100644
--- a/src/test/compile-fail/macro-inner-attributes.rs
+++ b/src/test/compile-fail/macro-inner-attributes.rs
@@ -8,11 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! test ( ($nm:ident,
+macro_rules! test { ($nm:ident,
#[$a:meta],
- $i:item) => (mod $nm { #![$a] $i }); );
+ $i:item) => (mod $nm { #![$a] $i }); }
test!(a,
#[cfg(qux)],
diff --git a/src/test/compile-fail/macro-keyword.rs b/src/test/compile-fail/macro-keyword.rs
new file mode 100644
index 0000000000000..9d4ec9c176cce
--- /dev/null
+++ b/src/test/compile-fail/macro-keyword.rs
@@ -0,0 +1,15 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn macro() { //~ ERROR `macro` is a reserved keyword
+}
+
+pub fn main() {
+}
diff --git a/src/test/compile-fail/macro-match-nonterminal.rs b/src/test/compile-fail/macro-match-nonterminal.rs
index 150187aa07d3c..a66b638701436 100644
--- a/src/test/compile-fail/macro-match-nonterminal.rs
+++ b/src/test/compile-fail/macro-match-nonterminal.rs
@@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! test ( ($a, $b) => (()); ); //~ ERROR Cannot transcribe
+macro_rules! test { ($a, $b) => (()); } //~ ERROR Cannot transcribe
fn main() {
test!()
diff --git a/src/test/compile-fail/macro-no-implicit-reexport.rs b/src/test/compile-fail/macro-no-implicit-reexport.rs
new file mode 100644
index 0000000000000..4a427f121fcab
--- /dev/null
+++ b/src/test/compile-fail/macro-no-implicit-reexport.rs
@@ -0,0 +1,20 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_reexport_1.rs
+// aux-build:macro_non_reexport_2.rs
+// ignore-stage1
+
+#[macro_use] #[no_link]
+extern crate macro_non_reexport_2;
+
+fn main() {
+ assert_eq!(reexported!(), 3u); //~ ERROR macro undefined
+}
diff --git a/src/test/compile-fail/macro-outer-attributes.rs b/src/test/compile-fail/macro-outer-attributes.rs
index 6d59c203d14bd..a0f23c72bc41e 100644
--- a/src/test/compile-fail/macro-outer-attributes.rs
+++ b/src/test/compile-fail/macro-outer-attributes.rs
@@ -8,11 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! test ( ($nm:ident,
+macro_rules! test { ($nm:ident,
#[$a:meta],
- $i:item) => (mod $nm { #[$a] $i }); );
+ $i:item) => (mod $nm { #[$a] $i }); }
test!(a,
#[cfg(qux)],
diff --git a/src/test/compile-fail/macro-reexport-malformed-1.rs b/src/test/compile-fail/macro-reexport-malformed-1.rs
new file mode 100644
index 0000000000000..b9f754b2778bc
--- /dev/null
+++ b/src/test/compile-fail/macro-reexport-malformed-1.rs
@@ -0,0 +1,14 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_reexport] //~ ERROR bad macro reexport
+extern crate std;
+
+fn main() { }
diff --git a/src/test/compile-fail/macro-reexport-malformed-2.rs b/src/test/compile-fail/macro-reexport-malformed-2.rs
new file mode 100644
index 0000000000000..9ced5be8479ba
--- /dev/null
+++ b/src/test/compile-fail/macro-reexport-malformed-2.rs
@@ -0,0 +1,14 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_reexport="foo"] //~ ERROR bad macro reexport
+extern crate std;
+
+fn main() { }
diff --git a/src/test/compile-fail/macro-reexport-malformed-3.rs b/src/test/compile-fail/macro-reexport-malformed-3.rs
new file mode 100644
index 0000000000000..c8bd0a0509cdc
--- /dev/null
+++ b/src/test/compile-fail/macro-reexport-malformed-3.rs
@@ -0,0 +1,14 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_reexport(foo="bar")] //~ ERROR bad macro reexport
+extern crate std;
+
+fn main() { }
diff --git a/src/test/compile-fail/macro-reexport-not-locally-visible.rs b/src/test/compile-fail/macro-reexport-not-locally-visible.rs
new file mode 100644
index 0000000000000..c8e59f98d3cea
--- /dev/null
+++ b/src/test/compile-fail/macro-reexport-not-locally-visible.rs
@@ -0,0 +1,20 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_reexport_1.rs
+// ignore-stage1
+
+#[macro_reexport(reexported)]
+#[no_link]
+extern crate macro_reexport_1;
+
+fn main() {
+ assert_eq!(reexported!(), 3u); //~ ERROR macro undefined
+}
diff --git a/src/test/compile-fail/macro-use-bad-args-1.rs b/src/test/compile-fail/macro-use-bad-args-1.rs
new file mode 100644
index 0000000000000..a73c4adb71f9f
--- /dev/null
+++ b/src/test/compile-fail/macro-use-bad-args-1.rs
@@ -0,0 +1,15 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_use(foo(bar))] //~ ERROR bad macro import
+extern crate std;
+
+fn main() {
+}
diff --git a/src/test/compile-fail/macro-use-bad-args-2.rs b/src/test/compile-fail/macro-use-bad-args-2.rs
new file mode 100644
index 0000000000000..31efe857605b4
--- /dev/null
+++ b/src/test/compile-fail/macro-use-bad-args-2.rs
@@ -0,0 +1,15 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_use(foo="bar")] //~ ERROR bad macro import
+extern crate std;
+
+fn main() {
+}
diff --git a/src/test/compile-fail/macro-use-wrong-name.rs b/src/test/compile-fail/macro-use-wrong-name.rs
new file mode 100644
index 0000000000000..4e0486f0db7e9
--- /dev/null
+++ b/src/test/compile-fail/macro-use-wrong-name.rs
@@ -0,0 +1,19 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_one)]
+extern crate two_macros;
+
+pub fn main() {
+ macro_two!(); //~ ERROR macro undefined
+}
diff --git a/src/test/compile-fail/macros-no-semicolon-items.rs b/src/test/compile-fail/macros-no-semicolon-items.rs
index f1f31a99e970a..314292085dfe6 100644
--- a/src/test/compile-fail/macros-no-semicolon-items.rs
+++ b/src/test/compile-fail/macros-no-semicolon-items.rs
@@ -12,4 +12,3 @@ macro_rules! foo() //~ ERROR semicolon
fn main() {
}
-
diff --git a/src/test/compile-fail/method-macro-backtrace.rs b/src/test/compile-fail/method-macro-backtrace.rs
index 747b4815ac2ae..f4740492651ae 100644
--- a/src/test/compile-fail/method-macro-backtrace.rs
+++ b/src/test/compile-fail/method-macro-backtrace.rs
@@ -10,11 +10,9 @@
// forbid-output: in expansion of
-#![feature(macro_rules)]
-
-macro_rules! make_method ( ($name:ident) => (
- fn $name(&self) { }
-));
+macro_rules! make_method {
+ ($name:ident) => ( fn $name(&self) { } )
+}
struct S;
diff --git a/src/test/compile-fail/missing-macro-use.rs b/src/test/compile-fail/missing-macro-use.rs
new file mode 100644
index 0000000000000..0153d71fb268f
--- /dev/null
+++ b/src/test/compile-fail/missing-macro-use.rs
@@ -0,0 +1,18 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+extern crate two_macros;
+
+pub fn main() {
+ macro_two!(); //~ ERROR macro undefined
+}
diff --git a/src/test/compile-fail/module-macro_use-arguments.rs b/src/test/compile-fail/module-macro_use-arguments.rs
new file mode 100644
index 0000000000000..6d3038b4820d6
--- /dev/null
+++ b/src/test/compile-fail/module-macro_use-arguments.rs
@@ -0,0 +1,16 @@
+// Copyright 2013-2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_use(foo, bar)] //~ ERROR arguments to macro_use are not allowed here
+mod foo {
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/gated-macro-rules.rs b/src/test/compile-fail/multi-plugin-attr.rs
similarity index 73%
rename from src/test/compile-fail/gated-macro-rules.rs
rename to src/test/compile-fail/multi-plugin-attr.rs
index ae2f03fd5f798..1d98cd26a38f5 100644
--- a/src/test/compile-fail/gated-macro-rules.rs
+++ b/src/test/compile-fail/multi-plugin-attr.rs
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// 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.
//
@@ -8,7 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-macro_rules! foo(() => ());
-//~^ ERROR: macro definitions are not stable enough for use
+#[plugin]
+#[plugin] //~ ERROR #[plugin] specified multiple times
+extern crate std;
fn main() {}
diff --git a/src/test/compile-fail/no-link.rs b/src/test/compile-fail/no-link.rs
new file mode 100644
index 0000000000000..a9c2b6a942c65
--- /dev/null
+++ b/src/test/compile-fail/no-link.rs
@@ -0,0 +1,19 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[no_link]
+extern crate libc;
+
+fn main() {
+ unsafe {
+ libc::abs(0); //~ ERROR Use of undeclared type or module `libc`
+ //~^ ERROR unresolved name `libc::abs`
+ }
+}
diff --git a/src/test/compile-fail/pattern-macro-hygiene.rs b/src/test/compile-fail/pattern-macro-hygiene.rs
index 3322fecf950c1..1c79c9a2293a0 100644
--- a/src/test/compile-fail/pattern-macro-hygiene.rs
+++ b/src/test/compile-fail/pattern-macro-hygiene.rs
@@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! foo ( () => ( x ) );
+macro_rules! foo { () => ( x ) }
fn main() {
let foo!() = 2;
diff --git a/src/test/compile-fail/recursion_limit.rs b/src/test/compile-fail/recursion_limit.rs
index de0d5c90fdd4b..6e1ecb10e3a2a 100644
--- a/src/test/compile-fail/recursion_limit.rs
+++ b/src/test/compile-fail/recursion_limit.rs
@@ -12,7 +12,6 @@
// deeply nested types that will fail the `Send` check by overflow
// when the recursion limit is set very low.
-#![feature(macro_rules)]
#![allow(dead_code)]
#![recursion_limit="10"]
diff --git a/src/test/compile-fail/svh-change-lit.rs b/src/test/compile-fail/svh-change-lit.rs
index 179fb11d5fe5b..c839ade75cf29 100644
--- a/src/test/compile-fail/svh-change-lit.rs
+++ b/src/test/compile-fail/svh-change-lit.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-change-lit.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
//~^ NOTE: perhaps this crate needs to be recompiled
diff --git a/src/test/compile-fail/svh-change-significant-cfg.rs b/src/test/compile-fail/svh-change-significant-cfg.rs
index 1f65f3873a94d..df0adf36ce2e6 100644
--- a/src/test/compile-fail/svh-change-significant-cfg.rs
+++ b/src/test/compile-fail/svh-change-significant-cfg.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-change-significant-cfg.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
//~^ NOTE: perhaps this crate needs to be recompiled
diff --git a/src/test/compile-fail/svh-change-trait-bound.rs b/src/test/compile-fail/svh-change-trait-bound.rs
index 4e4f7b232f469..4774384fecd49 100644
--- a/src/test/compile-fail/svh-change-trait-bound.rs
+++ b/src/test/compile-fail/svh-change-trait-bound.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-change-trait-bound.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
//~^ NOTE: perhaps this crate needs to be recompiled
diff --git a/src/test/compile-fail/svh-change-type-arg.rs b/src/test/compile-fail/svh-change-type-arg.rs
index 77b0a9211cafd..51d3fd0a73a12 100644
--- a/src/test/compile-fail/svh-change-type-arg.rs
+++ b/src/test/compile-fail/svh-change-type-arg.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-change-type-arg.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
//~^ NOTE: perhaps this crate needs to be recompiled
diff --git a/src/test/compile-fail/svh-change-type-ret.rs b/src/test/compile-fail/svh-change-type-ret.rs
index 13dcfa3b5da58..609e0f3689e5d 100644
--- a/src/test/compile-fail/svh-change-type-ret.rs
+++ b/src/test/compile-fail/svh-change-type-ret.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-change-type-ret.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
//~^ NOTE: perhaps this crate needs to be recompiled
diff --git a/src/test/compile-fail/svh-change-type-static.rs b/src/test/compile-fail/svh-change-type-static.rs
index 7d26bdd15fb28..c42714609b6f8 100644
--- a/src/test/compile-fail/svh-change-type-static.rs
+++ b/src/test/compile-fail/svh-change-type-static.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-change-type-static.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
//~^ NOTE: perhaps this crate needs to be recompiled
diff --git a/src/test/compile-fail/trace_macros-format.rs b/src/test/compile-fail/trace_macros-format.rs
index 8e0000246757d..95cb17c215b7b 100644
--- a/src/test/compile-fail/trace_macros-format.rs
+++ b/src/test/compile-fail/trace_macros-format.rs
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules, trace_macros)]
+#![feature(trace_macros)]
fn main() {
trace_macros!(); //~ ERROR trace_macros! accepts only `true` or `false`
diff --git a/src/test/compile-fail/while-let.rs b/src/test/compile-fail/while-let.rs
index ccf3d2dd75076..adb8ee6940d3b 100644
--- a/src/test/compile-fail/while-let.rs
+++ b/src/test/compile-fail/while-let.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
fn macros() {
macro_rules! foo{
($p:pat, $e:expr, $b:block) => {{
diff --git a/src/test/debuginfo/lexical-scope-with-macro.rs b/src/test/debuginfo/lexical-scope-with-macro.rs
index be52ffff1b45e..2aa31969a46ad 100644
--- a/src/test/debuginfo/lexical-scope-with-macro.rs
+++ b/src/test/debuginfo/lexical-scope-with-macro.rs
@@ -111,7 +111,6 @@
// lldb-command:continue
-#![feature(macro_rules)]
#![omit_gdb_pretty_printer_section]
macro_rules! trivial {
diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp
index 35bd22880cef7..500305f597075 100644
--- a/src/test/pretty/issue-4264.pp
+++ b/src/test/pretty/issue-4264.pp
@@ -1,7 +1,6 @@
-#![feature(phase)]
#![no_std]
#![feature(globs)]
-#[phase(plugin, link)]
+#[macro_use]
extern crate "std" as std;
#[prelude_import]
use std::prelude::v1::*;
diff --git a/src/test/run-fail/rt-set-exit-status-panic.rs b/src/test/run-fail/rt-set-exit-status-panic.rs
index e524a2432ac4e..fd7c3f8cc0e4b 100644
--- a/src/test/run-fail/rt-set-exit-status-panic.rs
+++ b/src/test/run-fail/rt-set-exit-status-panic.rs
@@ -10,8 +10,7 @@
// error-pattern:whatever
-#![feature(phase)]
-#[phase(plugin, link)] extern crate log;
+#[macro_use] extern crate log;
use std::os;
fn main() {
diff --git a/src/test/run-fail/rt-set-exit-status-panic2.rs b/src/test/run-fail/rt-set-exit-status-panic2.rs
index 972c85e376e51..446ef6f97e297 100644
--- a/src/test/run-fail/rt-set-exit-status-panic2.rs
+++ b/src/test/run-fail/rt-set-exit-status-panic2.rs
@@ -10,8 +10,7 @@
// error-pattern:whatever
-#![feature(phase)]
-#[phase(plugin, link)] extern crate log;
+#[macro_use] extern crate log;
use std::os;
use std::thread::Thread;
diff --git a/src/test/run-fail/rt-set-exit-status.rs b/src/test/run-fail/rt-set-exit-status.rs
index bddf9b5a7ea59..39ece8a464a6f 100644
--- a/src/test/run-fail/rt-set-exit-status.rs
+++ b/src/test/run-fail/rt-set-exit-status.rs
@@ -10,8 +10,7 @@
// error-pattern:whatever
-#![feature(phase)]
-#[phase(plugin, link)] extern crate log;
+#[macro_use] extern crate log;
use std::os;
fn main() {
diff --git a/src/test/run-make/extern-diff-internal-name/test.rs b/src/test/run-make/extern-diff-internal-name/test.rs
index ab1cf96999dce..11e042c8c4a06 100644
--- a/src/test/run-make/extern-diff-internal-name/test.rs
+++ b/src/test/run-make/extern-diff-internal-name/test.rs
@@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(phase)]
-
-#[phase(plugin, link)]
+#[macro_use]
extern crate foo;
fn main() {
diff --git a/src/test/run-make/lto-syntax-extension/main.rs b/src/test/run-make/lto-syntax-extension/main.rs
index 2028710cbd2bc..a38b2cfb96287 100644
--- a/src/test/run-make/lto-syntax-extension/main.rs
+++ b/src/test/run-make/lto-syntax-extension/main.rs
@@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(phase)]
-
extern crate lib;
-#[phase(plugin, link)] extern crate log;
+#[macro_use] extern crate log;
fn main() {}
diff --git a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs b/src/test/run-make/pretty-expanded-hygiene/input.pp.rs
index bf60784ab58b9..6febe2ff7c1d3 100755
--- a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs
+++ b/src/test/run-make/pretty-expanded-hygiene/input.pp.rs
@@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
// minimal junk
#![no_std]
diff --git a/src/test/run-make/pretty-expanded-hygiene/input.rs b/src/test/run-make/pretty-expanded-hygiene/input.rs
index c9d603c2e1cfb..c31b67b8043ae 100755
--- a/src/test/run-make/pretty-expanded-hygiene/input.rs
+++ b/src/test/run-make/pretty-expanded-hygiene/input.rs
@@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
// minimal junk
#![no_std]
diff --git a/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs b/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs
index 08c9f8b4aa7d5..11e7da770291a 100644
--- a/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs
+++ b/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs
@@ -11,9 +11,9 @@
// ignore-stage1
// ignore-android
// aux-build:issue_16723_multiple_items_syntax_ext.rs
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)] extern crate issue_16723_multiple_items_syntax_ext;
+#[plugin] #[no_link] extern crate issue_16723_multiple_items_syntax_ext;
multiple_items!();
diff --git a/src/test/run-pass-fulldeps/lint-group-plugin.rs b/src/test/run-pass-fulldeps/lint-group-plugin.rs
index 726670b5d7f93..7615b25f9e40c 100644
--- a/src/test/run-pass-fulldeps/lint-group-plugin.rs
+++ b/src/test/run-pass-fulldeps/lint-group-plugin.rs
@@ -12,9 +12,9 @@
// ignore-stage1
// ignore-pretty
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate lint_group_plugin_test;
fn lintme() { } //~ WARNING item is named 'lintme'
diff --git a/src/test/run-pass-fulldeps/lint-plugin-cmdline.rs b/src/test/run-pass-fulldeps/lint-plugin-cmdline.rs
index d3d1f1ea565a3..7144d2b0f1e71 100644
--- a/src/test/run-pass-fulldeps/lint-plugin-cmdline.rs
+++ b/src/test/run-pass-fulldeps/lint-plugin-cmdline.rs
@@ -12,9 +12,9 @@
// ignore-stage1
// compile-flags: -A test-lint
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { }
diff --git a/src/test/run-pass-fulldeps/lint-plugin.rs b/src/test/run-pass-fulldeps/lint-plugin.rs
index 8c5269e227410..d11242f4fe643 100644
--- a/src/test/run-pass-fulldeps/lint-plugin.rs
+++ b/src/test/run-pass-fulldeps/lint-plugin.rs
@@ -12,9 +12,9 @@
// ignore-stage1
// ignore-pretty
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate lint_plugin_test;
fn lintme() { } //~ WARNING item is named 'lintme'
diff --git a/src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs b/src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs
index 0afd76e1659c4..a8762234ad996 100644
--- a/src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs
+++ b/src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs
@@ -14,9 +14,9 @@
// Issue #15750: a macro that internally parses its input and then
// uses `quote_expr!` to rearrange it should be hygiene-preserving.
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate macro_crate_test;
fn main() {
diff --git a/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs b/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs
index dd585ea979408..d943cf0457b4f 100644
--- a/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs
+++ b/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs
@@ -11,9 +11,9 @@
// aux-build:plugin_crate_outlive_expansion_phase.rs
// ignore-stage1
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate plugin_crate_outlive_expansion_phase;
pub fn main() {}
diff --git a/src/test/run-pass-fulldeps/macro-crate.rs b/src/test/run-pass-fulldeps/macro-crate.rs
index 0f5e2cb3b6b46..4ffb8a3f74d4f 100644
--- a/src/test/run-pass-fulldeps/macro-crate.rs
+++ b/src/test/run-pass-fulldeps/macro-crate.rs
@@ -11,9 +11,9 @@
// aux-build:macro_crate_test.rs
// ignore-stage1
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[macro_use] #[plugin] #[no_link]
extern crate macro_crate_test;
#[into_foo]
diff --git a/src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs b/src/test/run-pass-fulldeps/plugin-link-does-resolve.rs
similarity index 94%
rename from src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs
rename to src/test/run-pass-fulldeps/plugin-link-does-resolve.rs
index 47ff7d31df5f3..518d02e3d75bb 100644
--- a/src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs
+++ b/src/test/run-pass-fulldeps/plugin-link-does-resolve.rs
@@ -15,9 +15,9 @@
// macro_crate_test will not compile on a cross-compiled target because
// libsyntax is not compiled for it.
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin, link)]
+#[plugin]
extern crate macro_crate_test;
fn main() {
diff --git a/src/test/run-pass-fulldeps/roman-numerals-macro.rs b/src/test/run-pass-fulldeps/roman-numerals-macro.rs
index 73a4a51f31c4e..d76766094ed77 100644
--- a/src/test/run-pass-fulldeps/roman-numerals-macro.rs
+++ b/src/test/run-pass-fulldeps/roman-numerals-macro.rs
@@ -11,9 +11,9 @@
// aux-build:roman_numerals.rs
// ignore-stage1
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate roman_numerals;
pub fn main() {
diff --git a/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs b/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs
index b3fae671c5266..1c74c8ad08eec 100644
--- a/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs
+++ b/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs
@@ -12,9 +12,9 @@
// aux-build:syntax-extension-with-dll-deps-2.rs
// ignore-stage1
-#![feature(phase)]
+#![feature(plugin)]
-#[phase(plugin)]
+#[plugin] #[no_link]
extern crate "syntax-extension-with-dll-deps-2" as extension;
fn main() {
diff --git a/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs b/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
index 822db63971e21..28db3953a0021 100644
--- a/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
+++ b/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
@@ -11,8 +11,6 @@
// Check that we do not ICE when compiling this
// macro, which reuses the expression `$id`
-#![feature(macro_rules)]
-
struct Foo {
a: int
@@ -24,12 +22,12 @@ pub enum Bar {
impl Foo {
fn elaborate_stm(&mut self, s: Box) -> Box {
- macro_rules! declare(
+ macro_rules! declare {
($id:expr, $rest:expr) => ({
self.check_id($id);
box Bar::Bar2($id, $rest)
})
- );
+ }
match s {
box Bar::Bar2(id, rest) => declare!(id, self.elaborate_stm(rest)),
_ => panic!()
diff --git a/src/test/run-pass/capturing-logging.rs b/src/test/run-pass/capturing-logging.rs
index 3f6d6a02c7926..e3e0041050762 100644
--- a/src/test/run-pass/capturing-logging.rs
+++ b/src/test/run-pass/capturing-logging.rs
@@ -11,9 +11,7 @@
// ignore-android (FIXME #11419)
// exec-env:RUST_LOG=info
-#![feature(phase)]
-
-#[phase(plugin, link)]
+#[macro_use]
extern crate log;
use log::{set_logger, Logger, LogRecord};
diff --git a/src/test/run-pass/cfg-macros-foo.rs b/src/test/run-pass/cfg-macros-foo.rs
index ec9ef38150136..aeb6fcbbc0f01 100644
--- a/src/test/run-pass/cfg-macros-foo.rs
+++ b/src/test/run-pass/cfg-macros-foo.rs
@@ -13,10 +13,8 @@
// check that cfg correctly chooses between the macro impls (see also
// cfg-macros-notfoo.rs)
-#![feature(macro_rules)]
-
#[cfg(foo)]
-#[macro_escape]
+#[macro_use]
mod foo {
macro_rules! bar {
() => { true }
@@ -24,7 +22,7 @@ mod foo {
}
#[cfg(not(foo))]
-#[macro_escape]
+#[macro_use]
mod foo {
macro_rules! bar {
() => { false }
diff --git a/src/test/run-pass/cfg-macros-notfoo.rs b/src/test/run-pass/cfg-macros-notfoo.rs
index fb44176ec2212..adc27d556227e 100644
--- a/src/test/run-pass/cfg-macros-notfoo.rs
+++ b/src/test/run-pass/cfg-macros-notfoo.rs
@@ -13,10 +13,8 @@
// check that cfg correctly chooses between the macro impls (see also
// cfg-macros-foo.rs)
-#![feature(macro_rules)]
-
#[cfg(foo)]
-#[macro_escape]
+#[macro_use]
mod foo {
macro_rules! bar {
() => { true }
@@ -24,7 +22,7 @@ mod foo {
}
#[cfg(not(foo))]
-#[macro_escape]
+#[macro_use]
mod foo {
macro_rules! bar {
() => { false }
diff --git a/src/test/run-pass/cleanup-rvalue-for-scope.rs b/src/test/run-pass/cleanup-rvalue-for-scope.rs
index 932a5a044ad3e..8969cca2610ea 100644
--- a/src/test/run-pass/cleanup-rvalue-for-scope.rs
+++ b/src/test/run-pass/cleanup-rvalue-for-scope.rs
@@ -11,8 +11,6 @@
// Test that the lifetime of rvalues in for loops is extended
// to the for loop itself.
-#![feature(macro_rules)]
-
use std::ops::Drop;
static mut FLAGS: u64 = 0;
diff --git a/src/test/run-pass/cleanup-rvalue-scopes.rs b/src/test/run-pass/cleanup-rvalue-scopes.rs
index 42f6914e081a3..59763e417a258 100644
--- a/src/test/run-pass/cleanup-rvalue-scopes.rs
+++ b/src/test/run-pass/cleanup-rvalue-scopes.rs
@@ -12,8 +12,6 @@
// statement or end of block, as appropriate given the temporary
// lifetime rules.
-#![feature(macro_rules)]
-
use std::ops::Drop;
static mut FLAGS: u64 = 0;
@@ -61,7 +59,7 @@ impl Drop for AddFlags {
}
}
-macro_rules! end_of_block(
+macro_rules! end_of_block {
($pat:pat, $expr:expr) => (
{
println!("end_of_block({})", stringify!({let $pat = $expr;}));
@@ -74,9 +72,9 @@ macro_rules! end_of_block(
check_flags(1);
}
)
-);
+}
-macro_rules! end_of_stmt(
+macro_rules! end_of_stmt {
($pat:pat, $expr:expr) => (
{
println!("end_of_stmt({})", stringify!($expr));
@@ -91,7 +89,7 @@ macro_rules! end_of_stmt(
check_flags(0);
}
)
-);
+}
pub fn main() {
diff --git a/src/test/run-pass/colorful-write-macros.rs b/src/test/run-pass/colorful-write-macros.rs
index d2caecdf05be2..ca7f761b80d31 100644
--- a/src/test/run-pass/colorful-write-macros.rs
+++ b/src/test/run-pass/colorful-write-macros.rs
@@ -11,8 +11,6 @@
// no-pretty-expanded
#![allow(unused_must_use, dead_code, deprecated)]
-#![feature(macro_rules)]
-
use std::io::MemWriter;
use std::fmt;
diff --git a/src/test/run-pass/conditional-debug-macro-off.rs b/src/test/run-pass/conditional-debug-macro-off.rs
index f87d92dc16f7f..e3bdbeb169295 100644
--- a/src/test/run-pass/conditional-debug-macro-off.rs
+++ b/src/test/run-pass/conditional-debug-macro-off.rs
@@ -11,8 +11,7 @@
// compile-flags: --cfg ndebug
// exec-env:RUST_LOG=conditional-debug-macro-off=4
-#![feature(phase)]
-#[phase(plugin, link)]
+#[macro_use]
extern crate log;
pub fn main() {
diff --git a/src/test/run-pass/const-binops.rs b/src/test/run-pass/const-binops.rs
index cac805189b82e..11590ceb19d48 100644
--- a/src/test/run-pass/const-binops.rs
+++ b/src/test/run-pass/const-binops.rs
@@ -8,16 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! assert_approx_eq(
+macro_rules! assert_approx_eq {
($a:expr, $b:expr) => ({
use std::num::Float;
let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b);
})
-);
+}
static A: int = -4 + 3;
static A2: uint = 3 + 3;
diff --git a/src/test/run-pass/const-block-item-macro-codegen.rs b/src/test/run-pass/const-block-item-macro-codegen.rs
index 09f26b15734ff..03afe798954d5 100644
--- a/src/test/run-pass/const-block-item-macro-codegen.rs
+++ b/src/test/run-pass/const-block-item-macro-codegen.rs
@@ -11,8 +11,6 @@
// General test that function items in static blocks
// can be generated with a macro.
-#![feature(macro_rules)]
-
struct MyType {
desc: &'static str,
data: uint,
diff --git a/src/test/run-pass/const-block-item.rs b/src/test/run-pass/const-block-item.rs
index 3365f09cd80ab..d55b420db083e 100644
--- a/src/test/run-pass/const-block-item.rs
+++ b/src/test/run-pass/const-block-item.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
mod foo {
pub trait Value {
fn value(&self) -> uint;
diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs
index c1db8a6eb13f4..3298976de6ce3 100644
--- a/src/test/run-pass/core-run-destroy.rs
+++ b/src/test/run-pass/core-run-destroy.rs
@@ -15,7 +15,6 @@
// memory, which makes for some *confusing* logs. That's why these are here
// instead of in std.
-#![feature(macro_rules)]
#![reexport_test_harness_main = "test_main"]
extern crate libc;
@@ -26,9 +25,9 @@ use std::str;
use std::sync::mpsc::channel;
use std::thread::Thread;
-macro_rules! succeed( ($e:expr) => (
+macro_rules! succeed { ($e:expr) => (
match $e { Ok(..) => {}, Err(e) => panic!("panic: {}", e) }
-) );
+) }
fn test_destroy_once() {
let mut p = sleeper();
diff --git a/src/test/run-pass/crate-leading-sep.rs b/src/test/run-pass/crate-leading-sep.rs
new file mode 100644
index 0000000000000..b2956f4e229b6
--- /dev/null
+++ b/src/test/run-pass/crate-leading-sep.rs
@@ -0,0 +1,14 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ use ::std::mem;
+ mem::drop(2u);
+}
diff --git a/src/test/run-pass/deprecated-macro_escape-inner.rs b/src/test/run-pass/deprecated-macro_escape-inner.rs
new file mode 100644
index 0000000000000..7960a91bdc4fc
--- /dev/null
+++ b/src/test/run-pass/deprecated-macro_escape-inner.rs
@@ -0,0 +1,19 @@
+// Copyright 2013-2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty
+
+mod foo {
+ #![macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use
+ //~^ HELP consider an outer attribute
+}
+
+fn main() {
+}
diff --git a/src/test/run-pass/deprecated-phase-syntax.rs b/src/test/run-pass/deprecated-macro_escape.rs
similarity index 76%
rename from src/test/run-pass/deprecated-phase-syntax.rs
rename to src/test/run-pass/deprecated-macro_escape.rs
index df835dab4d4e0..b03905e1a0d63 100644
--- a/src/test/run-pass/deprecated-phase-syntax.rs
+++ b/src/test/run-pass/deprecated-macro_escape.rs
@@ -8,12 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(phase)]
+// ignore-pretty
-//~ WARNING phase(syntax) is a deprecated synonym for phase(plugin)
-#[phase(syntax, link)]
-extern crate log;
+#[macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use
+mod foo {
+}
fn main() {
- debug!("foo");
}
diff --git a/src/test/run-pass/deriving-in-macro.rs b/src/test/run-pass/deriving-in-macro.rs
index 97f6ee341a71f..c9b60d22ecb7b 100644
--- a/src/test/run-pass/deriving-in-macro.rs
+++ b/src/test/run-pass/deriving-in-macro.rs
@@ -8,16 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! define_vec (
+macro_rules! define_vec {
() => (
mod foo {
#[derive(PartialEq)]
pub struct bar;
}
)
-);
+}
define_vec!();
diff --git a/src/test/run-pass/deriving-show.rs b/src/test/run-pass/deriving-show.rs
index f619c824d5e68..e8086b8b7c6b2 100644
--- a/src/test/run-pass/deriving-show.rs
+++ b/src/test/run-pass/deriving-show.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
#[derive(Show)]
struct Unit;
diff --git a/src/test/run-pass/enum-discrim-width-stuff.rs b/src/test/run-pass/enum-discrim-width-stuff.rs
index 73abec89a2df9..07941eca2243e 100644
--- a/src/test/run-pass/enum-discrim-width-stuff.rs
+++ b/src/test/run-pass/enum-discrim-width-stuff.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! check {
($m:ident, $t:ty, $v:expr) => {{
mod $m {
diff --git a/src/test/run-pass/exponential-notation.rs b/src/test/run-pass/exponential-notation.rs
index 38d1093762432..1fb434f7d7619 100644
--- a/src/test/run-pass/exponential-notation.rs
+++ b/src/test/run-pass/exponential-notation.rs
@@ -8,14 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
use std::num::strconv::ExponentFormat::{ExpBin, ExpDec};
use std::num::strconv::SignificantDigits::DigMax;
use std::num::strconv::SignFormat::{SignAll, SignNeg};
use std::num::strconv::float_to_str_common as to_string;
-macro_rules! t(($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()); } });
+macro_rules! t {
+ ($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()); } }
+}
pub fn main() {
// Basic usage
diff --git a/src/test/run-pass/html-literals.rs b/src/test/run-pass/html-literals.rs
index 0d56f28e8fae7..fbaeb1753f41d 100644
--- a/src/test/run-pass/html-literals.rs
+++ b/src/test/run-pass/html-literals.rs
@@ -10,8 +10,6 @@
// A test of the macro system. Can we do HTML literals?
-#![feature(macro_rules)]
-
/*
@@ -27,13 +25,13 @@ left.
*/
use HTMLFragment::{tag, text};
-macro_rules! html (
+macro_rules! html {
( $($body:tt)* ) => (
parse_node!( []; []; $($body)* )
)
-);
+}
-macro_rules! parse_node (
+macro_rules! parse_node {
(
[:$head:ident ($(:$head_nodes:expr),*)
$(:$tags:ident ($(:$tag_nodes:expr),*))*];
@@ -85,7 +83,7 @@ macro_rules! parse_node (
);
( []; [:$e:expr]; ) => ( $e );
-);
+}
pub fn main() {
let _page = html! (
diff --git a/src/test/run-pass/hygienic-labels-in-let.rs b/src/test/run-pass/hygienic-labels-in-let.rs
index 397ce75b6b93e..17c0299cf4dd7 100644
--- a/src/test/run-pass/hygienic-labels-in-let.rs
+++ b/src/test/run-pass/hygienic-labels-in-let.rs
@@ -10,8 +10,6 @@
// ignore-pretty: pprust doesn't print hygiene output
-#![feature(macro_rules)]
-
macro_rules! loop_x {
($e: expr) => {
// $e shouldn't be able to interact with this 'x
diff --git a/src/test/run-pass/hygienic-labels.rs b/src/test/run-pass/hygienic-labels.rs
index 53c081ff83e0e..e899a1adb794f 100644
--- a/src/test/run-pass/hygienic-labels.rs
+++ b/src/test/run-pass/hygienic-labels.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! loop_x {
($e: expr) => {
// $e shouldn't be able to interact with this 'x
diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs
index 1efae89f66563..d38b0ea274765 100644
--- a/src/test/run-pass/ifmt.rs
+++ b/src/test/run-pass/ifmt.rs
@@ -11,7 +11,6 @@
// no-pretty-expanded unnecessary unsafe block generated
// ignore-lexer-test FIXME #15679
-#![feature(macro_rules)]
#![deny(warnings)]
#![allow(unused_must_use)]
@@ -37,7 +36,9 @@ impl fmt::Show for C {
}
}
-macro_rules! t(($a:expr, $b:expr) => { assert_eq!($a.as_slice(), $b) });
+macro_rules! t {
+ ($a:expr, $b:expr) => { assert_eq!($a.as_slice(), $b) }
+}
pub fn main() {
// Various edge cases without formats
diff --git a/src/test/run-pass/intrinsics-math.rs b/src/test/run-pass/intrinsics-math.rs
index 9f2fe155cdf95..efb2ecfe875df 100644
--- a/src/test/run-pass/intrinsics-math.rs
+++ b/src/test/run-pass/intrinsics-math.rs
@@ -9,16 +9,16 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(globs, macro_rules, intrinsics)]
+#![feature(globs, intrinsics)]
-macro_rules! assert_approx_eq(
+macro_rules! assert_approx_eq {
($a:expr, $b:expr) => ({
use std::num::Float;
let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b);
})
-);
+}
mod rusti {
extern "rust-intrinsic" {
diff --git a/src/test/run-pass/issue-14330.rs b/src/test/run-pass/issue-14330.rs
index bac846dfa203b..f983f233ee356 100644
--- a/src/test/run-pass/issue-14330.rs
+++ b/src/test/run-pass/issue-14330.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(phase)]
-
-#[phase(plugin, link)] extern crate "std" as std2;
+#[macro_use] extern crate "std" as std2;
fn main() {}
diff --git a/src/test/run-pass/issue-14936.rs b/src/test/run-pass/issue-14936.rs
index 960dae8b7043c..a441729e2d0ba 100644
--- a/src/test/run-pass/issue-14936.rs
+++ b/src/test/run-pass/issue-14936.rs
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(asm, macro_rules)]
+#![feature(asm)]
type History = Vec<&'static str>;
diff --git a/src/test/run-pass/issue-15189.rs b/src/test/run-pass/issue-15189.rs
index 01c96b7563a75..6d1813f8aa437 100644
--- a/src/test/run-pass/issue-15189.rs
+++ b/src/test/run-pass/issue-15189.rs
@@ -10,9 +10,9 @@
// ignore-pretty
-#![feature(macro_rules)]
-
-macro_rules! third(($e:expr)=>({let x = 2; $e[x]}));
+macro_rules! third {
+ ($e:expr) => ({let x = 2; $e[x]})
+}
fn main() {
let x = vec!(10u,11u,12u,13u);
diff --git a/src/test/run-pass/issue-15221.rs b/src/test/run-pass/issue-15221.rs
index a11b34e476275..e3c102e01ec5e 100644
--- a/src/test/run-pass/issue-15221.rs
+++ b/src/test/run-pass/issue-15221.rs
@@ -8,13 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! inner (
- ($e:pat ) => ($e));
+macro_rules! inner {
+ ($e:pat ) => ($e)
+}
-macro_rules! outer (
- ($e:pat ) => (inner!($e)));
+macro_rules! outer {
+ ($e:pat ) => (inner!($e))
+}
fn main() {
let outer!(g1) = 13i;
diff --git a/src/test/run-pass/issue-5060.rs b/src/test/run-pass/issue-5060.rs
index 0cd25bc2c719b..7c3b0a5f1f014 100644
--- a/src/test/run-pass/issue-5060.rs
+++ b/src/test/run-pass/issue-5060.rs
@@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! print_hd_tl (
+macro_rules! print_hd_tl {
($field_hd:ident, $($field_tl:ident),+) => ({
print!("{}", stringify!($field_hd));
print!("::[");
@@ -21,7 +19,7 @@ macro_rules! print_hd_tl (
// FIXME: #9970
print!("{}", "]\n");
})
-);
+}
pub fn main() {
print_hd_tl!(x, y, z, w)
diff --git a/src/test/run-pass/issue-5554.rs b/src/test/run-pass/issue-5554.rs
index 24dcc3838c5fc..32fca7a182c1b 100644
--- a/src/test/run-pass/issue-5554.rs
+++ b/src/test/run-pass/issue-5554.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
use std::default::Default;
pub struct X {
diff --git a/src/test/run-pass/issue-5718.rs b/src/test/run-pass/issue-5718.rs
index f2167da31fc2b..589ccefd9ea28 100644
--- a/src/test/run-pass/issue-5718.rs
+++ b/src/test/run-pass/issue-5718.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
struct Element;
macro_rules! foo {
diff --git a/src/test/run-pass/issue-7911.rs b/src/test/run-pass/issue-7911.rs
index c69b66f4dbd76..86948ebcb91e0 100644
--- a/src/test/run-pass/issue-7911.rs
+++ b/src/test/run-pass/issue-7911.rs
@@ -14,8 +14,6 @@
// with different mutability in macro in two methods
#![allow(unused_variable)] // unused foobar_immut + foobar_mut
-#![feature(macro_rules)]
-
trait FooBar {}
struct Bar(i32);
struct Foo { bar: Bar }
@@ -27,7 +25,7 @@ trait Test {
fn get_mut(&mut self) -> &mut FooBar;
}
-macro_rules! generate_test(($type_:path, $slf:ident, $field:expr) => (
+macro_rules! generate_test { ($type_:path, $slf:ident, $field:expr) => (
impl Test for $type_ {
fn get_immut(&$slf) -> &FooBar {
&$field as &FooBar
@@ -37,7 +35,7 @@ macro_rules! generate_test(($type_:path, $slf:ident, $field:expr) => (
&mut $field as &mut FooBar
}
}
-));
+)}
generate_test!(Foo, self, self.bar);
diff --git a/src/test/run-pass/issue-8709.rs b/src/test/run-pass/issue-8709.rs
index d4ea05004a064..865905bf50441 100644
--- a/src/test/run-pass/issue-8709.rs
+++ b/src/test/run-pass/issue-8709.rs
@@ -8,15 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! sty(
+macro_rules! sty {
($t:ty) => (stringify!($t))
-);
+}
-macro_rules! spath(
+macro_rules! spath {
($t:path) => (stringify!($t))
-);
+}
fn main() {
assert_eq!(sty!(int), "int");
diff --git a/src/test/run-pass/issue-8851.rs b/src/test/run-pass/issue-8851.rs
index 5826a5f9919f4..b70711f9f39e2 100644
--- a/src/test/run-pass/issue-8851.rs
+++ b/src/test/run-pass/issue-8851.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
// after fixing #9384 and implementing hygiene for match bindings,
// this now fails because the insertion of the 'y' into the match
// doesn't cause capture. Making this macro hygienic (as I've done)
@@ -20,7 +18,7 @@ enum T {
B(uint)
}
-macro_rules! test(
+macro_rules! test {
($id:ident, $e:expr) => (
fn foo(t: T) -> int {
match t {
@@ -29,7 +27,7 @@ macro_rules! test(
}
}
)
-);
+}
test!(y, 10 + (y as int));
diff --git a/src/test/run-pass/issue-9110.rs b/src/test/run-pass/issue-9110.rs
index 60011281d425e..09d0f20c96d6c 100644
--- a/src/test/run-pass/issue-9110.rs
+++ b/src/test/run-pass/issue-9110.rs
@@ -8,16 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! silly_macro(
+macro_rules! silly_macro {
() => (
pub mod Qux {
pub struct Foo { x : u8 }
pub fn bar(_foo : Foo) {}
}
);
-);
+}
silly_macro!();
diff --git a/src/test/run-pass/issue-9129.rs b/src/test/run-pass/issue-9129.rs
index a6746f452065d..2e089d30bab02 100644
--- a/src/test/run-pass/issue-9129.rs
+++ b/src/test/run-pass/issue-9129.rs
@@ -10,8 +10,6 @@
// ignore-pretty
-#![feature(macro_rules)]
-
pub trait bomb { fn boom(&self, Ident); }
pub struct S;
@@ -19,8 +17,8 @@ impl bomb for S { fn boom(&self, _: Ident) { } }
pub struct Ident { name: uint }
-// macro_rules! int3( () => ( unsafe { asm!( "int3" ); } ) )
-macro_rules! int3( () => ( { } ) );
+// macro_rules! int3 { () => ( unsafe { asm!( "int3" ); } ) }
+macro_rules! int3 { () => ( { } ) }
fn Ident_new() -> Ident {
int3!();
diff --git a/src/test/run-pass/issue-9737.rs b/src/test/run-pass/issue-9737.rs
index 1f385b2fb1589..e5a287d014919 100644
--- a/src/test/run-pass/issue-9737.rs
+++ b/src/test/run-pass/issue-9737.rs
@@ -10,9 +10,9 @@
// ignore-test #9737
-#![feature(macro_rules)]
-
-macro_rules! f((v: $x:expr) => ( println!("{}", $x) ))
+macro_rules! f {
+ (v: $x:expr) => ( println!("{}", $x) )
+}
fn main () {
let v = 5;
diff --git a/src/test/run-pass/lambda-var-hygiene.rs b/src/test/run-pass/lambda-var-hygiene.rs
index 5dfc4208554b1..a6060bebbc5cd 100644
--- a/src/test/run-pass/lambda-var-hygiene.rs
+++ b/src/test/run-pass/lambda-var-hygiene.rs
@@ -10,10 +10,10 @@
// ignore-test #9383
-#![feature(macro_rules)]
-
// shouldn't affect evaluation of $ex:
-macro_rules! bad_macro (($ex:expr) => ({(|_x| { $ex }) (9) }))
+macro_rules! bad_macro {
+ ($ex:expr) => ({(|_x| { $ex }) (9) })
+}
fn takes_x(_x : int) {
assert_eq!(bad_macro!(_x),8);
diff --git a/src/test/run-pass/let-var-hygiene.rs b/src/test/run-pass/let-var-hygiene.rs
index 5eed791e0582d..2287cc48b66ce 100644
--- a/src/test/run-pass/let-var-hygiene.rs
+++ b/src/test/run-pass/let-var-hygiene.rs
@@ -8,10 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
// shouldn't affect evaluation of $ex:
-macro_rules! bad_macro (($ex:expr) => ({let _x = 9i; $ex}));
+macro_rules! bad_macro {
+ ($ex:expr) => ({let _x = 9i; $ex})
+}
+
pub fn main() {
let _x = 8i;
assert_eq!(bad_macro!(_x),8i)
diff --git a/src/test/run-pass/logging-enabled-debug.rs b/src/test/run-pass/logging-enabled-debug.rs
index 4b97d274fbae4..262d9b21eb48b 100644
--- a/src/test/run-pass/logging-enabled-debug.rs
+++ b/src/test/run-pass/logging-enabled-debug.rs
@@ -11,8 +11,7 @@
// compile-flags:--cfg ndebug
// exec-env:RUST_LOG=logging-enabled-debug=debug
-#![feature(phase)]
-#[phase(plugin, link)]
+#[macro_use]
extern crate log;
pub fn main() {
diff --git a/src/test/run-pass/logging-enabled.rs b/src/test/run-pass/logging-enabled.rs
index c4f7b1492ab57..372cdc401b549 100644
--- a/src/test/run-pass/logging-enabled.rs
+++ b/src/test/run-pass/logging-enabled.rs
@@ -10,8 +10,7 @@
// exec-env:RUST_LOG=logging-enabled=info
-#![feature(phase)]
-#[phase(plugin, link)]
+#[macro_use]
extern crate log;
pub fn main() {
diff --git a/src/test/run-pass/logging-separate-lines.rs b/src/test/run-pass/logging-separate-lines.rs
index ebbe7fa65cdf8..0f13df644a1f7 100644
--- a/src/test/run-pass/logging-separate-lines.rs
+++ b/src/test/run-pass/logging-separate-lines.rs
@@ -12,9 +12,7 @@
// ignore-windows
// exec-env:RUST_LOG=debug
-#![feature(phase)]
-
-#[phase(plugin, link)]
+#[macro_use]
extern crate log;
use std::io::Command;
diff --git a/src/test/run-pass/macro-2.rs b/src/test/run-pass/macro-2.rs
index 7b4d376993aa9..80b2f408c1915 100644
--- a/src/test/run-pass/macro-2.rs
+++ b/src/test/run-pass/macro-2.rs
@@ -10,16 +10,14 @@
// ignore-pretty - token trees can't pretty print
-#![feature(macro_rules)]
-
pub fn main() {
- macro_rules! mylambda_tt(
+ macro_rules! mylambda_tt {
($x:ident, $body:expr) => ({
fn f($x: int) -> int { return $body; };
f
})
- );
+ }
assert!(mylambda_tt!(y, y * 2)(8) == 16);
}
diff --git a/src/test/run-pass/macro-attribute-expansion.rs b/src/test/run-pass/macro-attribute-expansion.rs
index 3c170634c2231..60217139cd778 100644
--- a/src/test/run-pass/macro-attribute-expansion.rs
+++ b/src/test/run-pass/macro-attribute-expansion.rs
@@ -10,8 +10,6 @@
// ignore-pretty - token trees can't pretty print
-#![feature(macro_rules)]
-
macro_rules! descriptions {
($name:ident is $desc:expr) => {
// Check that we will correctly expand attributes
diff --git a/src/test/run-pass/macro-attributes.rs b/src/test/run-pass/macro-attributes.rs
index 4df3b94c1c9d1..521aef4b5ba5b 100644
--- a/src/test/run-pass/macro-attributes.rs
+++ b/src/test/run-pass/macro-attributes.rs
@@ -10,8 +10,6 @@
// ignore-pretty - token trees can't pretty print
-#![feature(macro_rules)]
-
macro_rules! compiles_fine {
(#[$at:meta]) => {
// test that the different types of attributes work
diff --git a/src/test/run-pass/macro-block-nonterminal.rs b/src/test/run-pass/macro-block-nonterminal.rs
index 8a9fbbe284864..6c568d6d493ca 100644
--- a/src/test/run-pass/macro-block-nonterminal.rs
+++ b/src/test/run-pass/macro-block-nonterminal.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! do_block{
($val:block) => {$val}
}
diff --git a/src/test/run-pass/macro-crate-def-only.rs b/src/test/run-pass/macro-crate-def-only.rs
index 70080fcc3c91d..7505fa6e6841a 100644
--- a/src/test/run-pass/macro-crate-def-only.rs
+++ b/src/test/run-pass/macro-crate-def-only.rs
@@ -10,9 +10,7 @@
// aux-build:macro_crate_def_only.rs
-#![feature(phase)]
-
-#[phase(plugin)]
+#[macro_use] #[no_link]
extern crate macro_crate_def_only;
pub fn main() {
diff --git a/src/test/run-pass/macro-crate-nonterminal-renamed.rs b/src/test/run-pass/macro-crate-nonterminal-renamed.rs
new file mode 100644
index 0000000000000..cb919297b0406
--- /dev/null
+++ b/src/test/run-pass/macro-crate-nonterminal-renamed.rs
@@ -0,0 +1,20 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_crate_nonterminal.rs
+// ignore-stage1
+
+#[macro_use]
+extern crate "macro_crate_nonterminal" as new_name;
+
+pub fn main() {
+ new_name::check_local();
+ assert_eq!(increment!(5), 6);
+}
diff --git a/src/test/run-pass/macro-crate-nonterminal.rs b/src/test/run-pass/macro-crate-nonterminal.rs
new file mode 100644
index 0000000000000..9882f806a9eea
--- /dev/null
+++ b/src/test/run-pass/macro-crate-nonterminal.rs
@@ -0,0 +1,20 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_crate_nonterminal.rs
+// ignore-stage1
+
+#[macro_use]
+extern crate macro_crate_nonterminal;
+
+pub fn main() {
+ macro_crate_nonterminal::check_local();
+ assert_eq!(increment!(5), 6);
+}
diff --git a/src/test/run-pass/macro-crate-use.rs b/src/test/run-pass/macro-crate-use.rs
new file mode 100644
index 0000000000000..fbbe0105cf4fe
--- /dev/null
+++ b/src/test/run-pass/macro-crate-use.rs
@@ -0,0 +1,25 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn increment(x: uint) -> uint {
+ x + 1
+}
+
+#[macro_export]
+macro_rules! increment {
+ ($x:expr) => ({
+ use $crate::increment;
+ increment($x)
+ })
+}
+
+fn main() {
+ assert_eq!(increment!(3), 4);
+}
diff --git a/src/test/run-pass/macro-deep_expansion.rs b/src/test/run-pass/macro-deep_expansion.rs
index f85c6f1fc9349..c4012e2cf3c7e 100644
--- a/src/test/run-pass/macro-deep_expansion.rs
+++ b/src/test/run-pass/macro-deep_expansion.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! foo2 {
() => {
"foo"
diff --git a/src/test/run-pass/macro-export-inner-module.rs b/src/test/run-pass/macro-export-inner-module.rs
index 88ca466b4afdf..ef22410751c0c 100644
--- a/src/test/run-pass/macro-export-inner-module.rs
+++ b/src/test/run-pass/macro-export-inner-module.rs
@@ -11,9 +11,7 @@
//aux-build:macro_export_inner_module.rs
//ignore-stage1
-#![feature(phase)]
-
-#[phase(plugin)]
+#[macro_use] #[no_link]
extern crate macro_export_inner_module;
pub fn main() {
diff --git a/src/test/run-pass/macro-interpolation.rs b/src/test/run-pass/macro-interpolation.rs
index 45712f5c62a6e..ff5b29d6ac88b 100644
--- a/src/test/run-pass/macro-interpolation.rs
+++ b/src/test/run-pass/macro-interpolation.rs
@@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! overly_complicated (
+macro_rules! overly_complicated {
($fnname:ident, $arg:ident, $ty:ty, $body:block, $val:expr, $pat:pat, $res:path) =>
({
fn $fnname($arg: $ty) -> Option<$ty> $body
@@ -22,7 +20,7 @@ macro_rules! overly_complicated (
}
})
-);
+}
pub fn main() {
assert!(overly_complicated!(f, x, Option, { return Some(x); },
diff --git a/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs b/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs
index ecd7c0458f701..ce74896749838 100644
--- a/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs
+++ b/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs
@@ -8,11 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! four (
+macro_rules! four {
() => (4)
-);
+}
fn main() {
let _x: [u16; four!()];
diff --git a/src/test/run-pass/macro-meta-items.rs b/src/test/run-pass/macro-meta-items.rs
index 4b01fdf816216..47e3a0723993e 100644
--- a/src/test/run-pass/macro-meta-items.rs
+++ b/src/test/run-pass/macro-meta-items.rs
@@ -11,8 +11,6 @@
// ignore-pretty - token trees can't pretty print
// compile-flags: --cfg foo
-#![feature(macro_rules)]
-
macro_rules! compiles_fine {
($at:meta) => {
#[cfg($at)]
diff --git a/src/test/run-pass/macro-method-issue-4621.rs b/src/test/run-pass/macro-method-issue-4621.rs
index aa6de9acf6b88..fd16958d8964b 100644
--- a/src/test/run-pass/macro-method-issue-4621.rs
+++ b/src/test/run-pass/macro-method-issue-4621.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
struct A;
macro_rules! make_thirteen_method {() => (fn thirteen(&self)->int {13})}
diff --git a/src/test/run-pass/macro-multiple-items.rs b/src/test/run-pass/macro-multiple-items.rs
index 4fb130f0e1314..f78f93e84810c 100644
--- a/src/test/run-pass/macro-multiple-items.rs
+++ b/src/test/run-pass/macro-multiple-items.rs
@@ -10,9 +10,7 @@
// ignore-pretty - token trees can't pretty print
-#![feature(macro_rules)]
-
-macro_rules! make_foo(
+macro_rules! make_foo {
() => (
struct Foo;
@@ -20,7 +18,7 @@ macro_rules! make_foo(
fn bar(&self) {}
}
)
-);
+}
make_foo!();
diff --git a/src/test/run-pass/macro-nt-list.rs b/src/test/run-pass/macro-nt-list.rs
index 9367a231d4f65..c6efc2f2bc83b 100644
--- a/src/test/run-pass/macro-nt-list.rs
+++ b/src/test/run-pass/macro-nt-list.rs
@@ -8,17 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! list (
+macro_rules! list {
( ($($id:ident),*) ) => (());
( [$($id:ident),*] ) => (());
( {$($id:ident),*} ) => (());
-);
+}
-macro_rules! tt_list (
+macro_rules! tt_list {
( ($($tt:tt),*) ) => (());
-);
+}
pub fn main() {
list!( () );
diff --git a/src/test/run-pass/macro-of-higher-order.rs b/src/test/run-pass/macro-of-higher-order.rs
index c47b5e1108901..3276aa0265f70 100644
--- a/src/test/run-pass/macro-of-higher-order.rs
+++ b/src/test/run-pass/macro-of-higher-order.rs
@@ -8,14 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! higher_order (
+macro_rules! higher_order {
(subst $lhs:tt => $rhs:tt) => ({
- macro_rules! anon ( $lhs => $rhs );
+ macro_rules! anon { $lhs => $rhs }
anon!(1u, 2u, "foo")
});
-);
+}
fn main() {
let val = higher_order!(subst ($x:expr, $y:expr, $foo:expr) => (($x + $y, $foo)));
diff --git a/src/test/run-pass/macro-pat.rs b/src/test/run-pass/macro-pat.rs
index 496cef9d644e2..07b75389cf4ff 100644
--- a/src/test/run-pass/macro-pat.rs
+++ b/src/test/run-pass/macro-pat.rs
@@ -8,37 +8,35 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! mypat(
+macro_rules! mypat {
() => (
Some('y')
)
-);
+}
-macro_rules! char_x(
+macro_rules! char_x {
() => (
'x'
)
-);
+}
-macro_rules! some(
+macro_rules! some {
($x:pat) => (
Some($x)
)
-);
+}
-macro_rules! indirect(
+macro_rules! indirect {
() => (
some!(char_x!())
)
-);
+}
-macro_rules! ident_pat(
+macro_rules! ident_pat {
($x:ident) => (
$x
)
-);
+}
fn f(c: Option) -> uint {
match c {
diff --git a/src/test/run-pass/macro-path.rs b/src/test/run-pass/macro-path.rs
index 97f6e2b50d7c8..4aa1587943413 100644
--- a/src/test/run-pass/macro-path.rs
+++ b/src/test/run-pass/macro-path.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
mod m {
pub type t = int;
}
diff --git a/src/test/run-pass/macro-reexport-no-intermediate-use.rs b/src/test/run-pass/macro-reexport-no-intermediate-use.rs
new file mode 100644
index 0000000000000..77ef9421273ef
--- /dev/null
+++ b/src/test/run-pass/macro-reexport-no-intermediate-use.rs
@@ -0,0 +1,20 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_reexport_1.rs
+// aux-build:macro_reexport_2_no_use.rs
+// ignore-stage1
+
+#[macro_use] #[no_link]
+extern crate macro_reexport_2_no_use;
+
+fn main() {
+ assert_eq!(reexported!(), 3u);
+}
diff --git a/src/test/run-pass/macro-reexport.rs b/src/test/run-pass/macro-reexport.rs
new file mode 100644
index 0000000000000..9701610cbd964
--- /dev/null
+++ b/src/test/run-pass/macro-reexport.rs
@@ -0,0 +1,20 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_reexport_1.rs
+// aux-build:macro_reexport_2.rs
+// ignore-stage1
+
+#[macro_use] #[no_link]
+extern crate macro_reexport_2;
+
+fn main() {
+ assert_eq!(reexported!(), 3u);
+}
diff --git a/src/test/run-pass/macro-stmt.rs b/src/test/run-pass/macro-stmt.rs
index 7be49e1acd844..cb5370c8bcba1 100644
--- a/src/test/run-pass/macro-stmt.rs
+++ b/src/test/run-pass/macro-stmt.rs
@@ -10,23 +10,21 @@
// ignore-pretty - token trees can't pretty print
-#![feature(macro_rules)]
-
-macro_rules! myfn(
+macro_rules! myfn {
( $f:ident, ( $( $x:ident ),* ), $body:block ) => (
fn $f( $( $x : int),* ) -> int $body
)
-);
+}
myfn!(add, (a,b), { return a+b; } );
pub fn main() {
- macro_rules! mylet(
+ macro_rules! mylet {
($x:ident, $val:expr) => (
let $x = $val;
)
- );
+ }
mylet!(y, 8i*2);
assert_eq!(y, 16i);
@@ -35,9 +33,9 @@ pub fn main() {
assert_eq!(mult(2, add(4,4)), 16);
- macro_rules! actually_an_expr_macro (
+ macro_rules! actually_an_expr_macro {
() => ( 16i )
- );
+ }
assert_eq!({ actually_an_expr_macro!() }, 16i);
diff --git a/src/test/run-pass/macro-use-all-and-none.rs b/src/test/run-pass/macro-use-all-and-none.rs
new file mode 100644
index 0000000000000..e93d1c106a2ce
--- /dev/null
+++ b/src/test/run-pass/macro-use-all-and-none.rs
@@ -0,0 +1,22 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use]
+#[macro_use()]
+#[no_link]
+extern crate two_macros;
+
+pub fn main() {
+ macro_one!();
+ macro_two!();
+}
diff --git a/src/test/run-pass/macro-use-all.rs b/src/test/run-pass/macro-use-all.rs
new file mode 100644
index 0000000000000..56d942a33a3ae
--- /dev/null
+++ b/src/test/run-pass/macro-use-all.rs
@@ -0,0 +1,21 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use]
+#[no_link]
+extern crate two_macros;
+
+pub fn main() {
+ macro_one!();
+ macro_two!();
+}
diff --git a/src/test/run-pass/macro-use-both.rs b/src/test/run-pass/macro-use-both.rs
new file mode 100644
index 0000000000000..7b7ee6a51bfa3
--- /dev/null
+++ b/src/test/run-pass/macro-use-both.rs
@@ -0,0 +1,21 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_one, macro_two)]
+#[no_link]
+extern crate two_macros;
+
+pub fn main() {
+ macro_one!();
+ macro_two!();
+}
diff --git a/src/test/run-pass/macro-use-one.rs b/src/test/run-pass/macro-use-one.rs
new file mode 100644
index 0000000000000..a4fcd7ba2a49a
--- /dev/null
+++ b/src/test/run-pass/macro-use-one.rs
@@ -0,0 +1,20 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_two)]
+#[no_link]
+extern crate two_macros;
+
+pub fn main() {
+ macro_two!();
+}
diff --git a/src/test/run-pass/macro-with-attrs1.rs b/src/test/run-pass/macro-with-attrs1.rs
index 631fc8666713d..3f9d07466cc81 100644
--- a/src/test/run-pass/macro-with-attrs1.rs
+++ b/src/test/run-pass/macro-with-attrs1.rs
@@ -10,13 +10,11 @@
// compile-flags: --cfg foo
-#![feature(macro_rules)]
-
#[cfg(foo)]
-macro_rules! foo( () => (1i) );
+macro_rules! foo { () => (1i) }
#[cfg(not(foo))]
-macro_rules! foo( () => (2i) );
+macro_rules! foo { () => (2i) }
pub fn main() {
assert_eq!(foo!(), 1i);
diff --git a/src/test/run-pass/macro-with-attrs2.rs b/src/test/run-pass/macro-with-attrs2.rs
index 3ac0d47e61a63..f90a0dfa6b31e 100644
--- a/src/test/run-pass/macro-with-attrs2.rs
+++ b/src/test/run-pass/macro-with-attrs2.rs
@@ -8,13 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
#[cfg(foo)]
-macro_rules! foo( () => (1i) );
+macro_rules! foo { () => (1i) }
#[cfg(not(foo))]
-macro_rules! foo( () => (2i) );
+macro_rules! foo { () => (2i) }
pub fn main() {
assert_eq!(foo!(), 2i);
diff --git a/src/test/run-pass/macro-with-braces-in-expr-position.rs b/src/test/run-pass/macro-with-braces-in-expr-position.rs
index a6e579ddff304..93bb9557604c4 100644
--- a/src/test/run-pass/macro-with-braces-in-expr-position.rs
+++ b/src/test/run-pass/macro-with-braces-in-expr-position.rs
@@ -8,11 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
use std::thread::Thread;
-macro_rules! expr (($e: expr) => { $e });
+macro_rules! expr { ($e: expr) => { $e } }
macro_rules! spawn {
($($code: tt)*) => {
diff --git a/src/test/run-pass/match-in-macro.rs b/src/test/run-pass/match-in-macro.rs
index a776999ec8a00..e4886ddaa0ed3 100644
--- a/src/test/run-pass/match-in-macro.rs
+++ b/src/test/run-pass/match-in-macro.rs
@@ -8,19 +8,17 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
enum Foo {
B { b1: int, bb1: int},
}
-macro_rules! match_inside_expansion(
+macro_rules! match_inside_expansion {
() => (
match (Foo::B { b1:29 , bb1: 100}) {
Foo::B { b1:b2 , bb1:bb2 } => b2+bb2
}
)
-);
+}
pub fn main() {
assert_eq!(match_inside_expansion!(),129);
diff --git a/src/test/run-pass/match-var-hygiene.rs b/src/test/run-pass/match-var-hygiene.rs
index 482fdf5b1d040..984f675b4dc7d 100644
--- a/src/test/run-pass/match-var-hygiene.rs
+++ b/src/test/run-pass/match-var-hygiene.rs
@@ -10,12 +10,10 @@
// ignore-test #9384
-#![feature(macro_rules)]
-
// shouldn't affect evaluation of $ex.
-macro_rules! bad_macro (($ex:expr) => (
+macro_rules! bad_macro { ($ex:expr) => (
{match 9 {_x => $ex}}
-))
+)}
fn main() {
match 8 {
diff --git a/src/test/run-pass/non-built-in-quote.rs b/src/test/run-pass/non-built-in-quote.rs
index 9151564b3407b..8b41670734f95 100644
--- a/src/test/run-pass/non-built-in-quote.rs
+++ b/src/test/run-pass/non-built-in-quote.rs
@@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
-macro_rules! quote_tokens ( () => (()) );
+macro_rules! quote_tokens { () => (()) }
pub fn main() {
quote_tokens!();
diff --git a/src/test/run-pass/nullable-pointer-iotareduction.rs b/src/test/run-pass/nullable-pointer-iotareduction.rs
index 2660de619e9c7..9b9a7f68995f7 100644
--- a/src/test/run-pass/nullable-pointer-iotareduction.rs
+++ b/src/test/run-pass/nullable-pointer-iotareduction.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
use std::{option, mem};
// Iota-reduction is a rule in the Calculus of (Co-)Inductive Constructions,
diff --git a/src/test/run-pass/nullable-pointer-size.rs b/src/test/run-pass/nullable-pointer-size.rs
index afc22be38b8a4..02fc0cf0291d4 100644
--- a/src/test/run-pass/nullable-pointer-size.rs
+++ b/src/test/run-pass/nullable-pointer-size.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
use std::mem;
enum E { Thing(int, T), Nothing((), ((), ()), [i8; 0]) }
diff --git a/src/test/run-pass/plugin-args-1.rs b/src/test/run-pass/plugin-args-1.rs
new file mode 100644
index 0000000000000..5a91f603f9681
--- /dev/null
+++ b/src/test/run-pass/plugin-args-1.rs
@@ -0,0 +1,22 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:plugin_args.rs
+// ignore-stage1
+
+#![feature(plugin)]
+
+#[no_link]
+#[plugin]
+extern crate plugin_args;
+
+fn main() {
+ assert_eq!(plugin_args!(), "#[plugin]");
+}
diff --git a/src/test/run-pass/plugin-args-2.rs b/src/test/run-pass/plugin-args-2.rs
new file mode 100644
index 0000000000000..d0ac22a529021
--- /dev/null
+++ b/src/test/run-pass/plugin-args-2.rs
@@ -0,0 +1,22 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:plugin_args.rs
+// ignore-stage1
+
+#![feature(plugin)]
+
+#[no_link]
+#[plugin()]
+extern crate plugin_args;
+
+fn main() {
+ assert_eq!(plugin_args!(), "#[plugin()]");
+}
diff --git a/src/test/run-pass/plugin-args-3.rs b/src/test/run-pass/plugin-args-3.rs
new file mode 100644
index 0000000000000..7cac8ac57e55c
--- /dev/null
+++ b/src/test/run-pass/plugin-args-3.rs
@@ -0,0 +1,22 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:plugin_args.rs
+// ignore-stage1
+
+#![feature(plugin)]
+
+#[no_link]
+#[plugin(hello(there), how(are="you"))]
+extern crate plugin_args;
+
+fn main() {
+ assert_eq!(plugin_args!(), "#[plugin(hello(there), how(are = \"you\"))]");
+}
diff --git a/src/test/run-pass/plugin-args-4.rs b/src/test/run-pass/plugin-args-4.rs
new file mode 100644
index 0000000000000..8563c8c178ff8
--- /dev/null
+++ b/src/test/run-pass/plugin-args-4.rs
@@ -0,0 +1,22 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:plugin_args.rs
+// ignore-stage1
+
+#![feature(plugin)]
+
+#[no_link]
+#[plugin="foobar"]
+extern crate plugin_args;
+
+fn main() {
+ assert_eq!(plugin_args!(), "#[plugin = \"foobar\"]");
+}
diff --git a/src/test/run-pass/rust-log-filter.rs b/src/test/run-pass/rust-log-filter.rs
index 2612483ded486..95f90ebbf8edf 100644
--- a/src/test/run-pass/rust-log-filter.rs
+++ b/src/test/run-pass/rust-log-filter.rs
@@ -10,8 +10,7 @@
// exec-env:RUST_LOG=rust-log-filter/f.o
-#![feature(phase)]
-#[phase(plugin,link)]
+#[macro_use]
extern crate log;
use std::sync::mpsc::{channel, Sender, Receiver};
diff --git a/src/test/run-pass/small-enums-with-fields.rs b/src/test/run-pass/small-enums-with-fields.rs
index 247fa6453b831..46daa6594303c 100644
--- a/src/test/run-pass/small-enums-with-fields.rs
+++ b/src/test/run-pass/small-enums-with-fields.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
use std::mem::size_of;
#[derive(PartialEq, Show)]
diff --git a/src/test/run-pass/svh-add-comment.rs b/src/test/run-pass/svh-add-comment.rs
index bc9a371edf7ce..235c4e74d0857 100644
--- a/src/test/run-pass/svh-add-comment.rs
+++ b/src/test/run-pass/svh-add-comment.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-comment.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b;
diff --git a/src/test/run-pass/svh-add-doc.rs b/src/test/run-pass/svh-add-doc.rs
index 6599e493d25a1..365960b96e4e9 100644
--- a/src/test/run-pass/svh-add-doc.rs
+++ b/src/test/run-pass/svh-add-doc.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-doc.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b;
diff --git a/src/test/run-pass/svh-add-macro.rs b/src/test/run-pass/svh-add-macro.rs
index f4bfe3d8c7c98..a0dbc96cdb02a 100644
--- a/src/test/run-pass/svh-add-macro.rs
+++ b/src/test/run-pass/svh-add-macro.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-macro.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b;
diff --git a/src/test/run-pass/svh-add-nothing.rs b/src/test/run-pass/svh-add-nothing.rs
index 7f702bd7ab553..98b7663c58ebb 100644
--- a/src/test/run-pass/svh-add-nothing.rs
+++ b/src/test/run-pass/svh-add-nothing.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-no-change.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b;
diff --git a/src/test/run-pass/svh-add-redundant-cfg.rs b/src/test/run-pass/svh-add-redundant-cfg.rs
index b5a84843a545b..650f76d729a54 100644
--- a/src/test/run-pass/svh-add-redundant-cfg.rs
+++ b/src/test/run-pass/svh-add-redundant-cfg.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-redundant-cfg.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b;
diff --git a/src/test/run-pass/svh-add-whitespace.rs b/src/test/run-pass/svh-add-whitespace.rs
index 4a8058c96643e..6612c93e90bc5 100644
--- a/src/test/run-pass/svh-add-whitespace.rs
+++ b/src/test/run-pass/svh-add-whitespace.rs
@@ -13,8 +13,6 @@
// aux-build:svh-b.rs
// aux-build:svh-a-whitespace.rs
-#![feature(macro_rules)]
-
extern crate a;
extern crate b;
diff --git a/src/test/run-pass/syntax-extension-source-utils.rs b/src/test/run-pass/syntax-extension-source-utils.rs
index f6708536a9d99..f85305cf31926 100644
--- a/src/test/run-pass/syntax-extension-source-utils.rs
+++ b/src/test/run-pass/syntax-extension-source-utils.rs
@@ -11,8 +11,6 @@
// This test is brittle!
// ignore-pretty - the pretty tests lose path information, breaking include!
-#![feature(macro_rules)]
-
pub mod m1 {
pub mod m2 {
pub fn where_am_i() -> String {
@@ -21,12 +19,12 @@ pub mod m1 {
}
}
-macro_rules! indirect_line( () => ( line!() ) );
+macro_rules! indirect_line { () => ( line!() ) }
pub fn main() {
- assert_eq!(line!(), 27);
+ assert_eq!(line!(), 25);
//assert!((column!() == 11));
- assert_eq!(indirect_line!(), 29);
+ assert_eq!(indirect_line!(), 27);
assert!((file!().ends_with("syntax-extension-source-utils.rs")));
assert_eq!(stringify!((2*3) + 5).to_string(), "( 2 * 3 ) + 5".to_string());
assert!(include!("syntax-extension-source-utils-files/includeme.\
@@ -44,7 +42,7 @@ pub fn main() {
// The Windows tests are wrapped in an extra module for some reason
assert!((m1::m2::where_am_i().as_slice().ends_with("m1::m2")));
- assert!(match (47, "( 2 * 3 ) + 5") {
+ assert!(match (45, "( 2 * 3 ) + 5") {
(line!(), stringify!((2*3) + 5)) => true,
_ => false
})
diff --git a/src/test/run-pass/tcp-connect-timeouts.rs b/src/test/run-pass/tcp-connect-timeouts.rs
index 6812255d82ca0..adbc16f5c2918 100644
--- a/src/test/run-pass/tcp-connect-timeouts.rs
+++ b/src/test/run-pass/tcp-connect-timeouts.rs
@@ -16,7 +16,7 @@
// one test task to ensure that errors are timeouts, not file descriptor
// exhaustion.
-#![feature(macro_rules, globs)]
+#![feature(globs)]
#![allow(experimental)]
#![reexport_test_harness_main = "test_main"]
diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs
index 62b61c153c707..7d226aa942032 100644
--- a/src/test/run-pass/tcp-stress.rs
+++ b/src/test/run-pass/tcp-stress.rs
@@ -12,8 +12,7 @@
// ignore-android needs extra network permissions
// exec-env:RUST_LOG=debug
-#![feature(phase)]
-#[phase(plugin, link)]
+#[macro_use]
extern crate log;
extern crate libc;
diff --git a/src/test/run-pass/two-macro-use.rs b/src/test/run-pass/two-macro-use.rs
new file mode 100644
index 0000000000000..0826190bb5c45
--- /dev/null
+++ b/src/test/run-pass/two-macro-use.rs
@@ -0,0 +1,22 @@
+// 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_one)]
+#[macro_use(macro_two)]
+#[no_link]
+extern crate two_macros;
+
+pub fn main() {
+ macro_one!();
+ macro_two!();
+}
diff --git a/src/test/run-pass/typeck-macro-interaction-issue-8852.rs b/src/test/run-pass/typeck-macro-interaction-issue-8852.rs
index 4dec227d52020..673e852356266 100644
--- a/src/test/run-pass/typeck-macro-interaction-issue-8852.rs
+++ b/src/test/run-pass/typeck-macro-interaction-issue-8852.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
enum T {
A(int),
B(f64)
@@ -20,7 +18,7 @@ enum T {
// doesn't cause capture. Making this macro hygienic (as I've done)
// could very well make this test case completely pointless....
-macro_rules! test(
+macro_rules! test {
($id1:ident, $id2:ident, $e:expr) => (
fn foo(a:T, b:T) -> T {
match (a, b) {
@@ -30,7 +28,7 @@ macro_rules! test(
}
}
)
-);
+}
test!(x,y,x + y);
diff --git a/src/test/run-pass/vec-macro-no-std.rs b/src/test/run-pass/vec-macro-no-std.rs
new file mode 100644
index 0000000000000..c04afffb12037
--- /dev/null
+++ b/src/test/run-pass/vec-macro-no-std.rs
@@ -0,0 +1,39 @@
+// Copyright 2014 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(lang_items)]
+#![no_std]
+
+#[macro_use]
+extern crate core;
+extern crate libc;
+
+#[macro_use]
+extern crate collections;
+
+use core::option::Option::Some;
+use core::slice::SliceExt;
+use collections::vec::Vec;
+
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+
+// Issue #16806
+
+#[start]
+fn start(_argc: int, _argv: *const *const u8) -> int {
+ let x: Vec = vec![0, 1, 2];
+ match x.last() {
+ Some(&2) => (),
+ _ => panic!(),
+ }
+ 0
+}
diff --git a/src/test/run-pass/vec-macro-with-brackets.rs b/src/test/run-pass/vec-macro-with-brackets.rs
index 2c784dade5711..a263501f8fe71 100644
--- a/src/test/run-pass/vec-macro-with-brackets.rs
+++ b/src/test/run-pass/vec-macro-with-brackets.rs
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(macro_rules)]
-
macro_rules! vec [
($($e:expr),*) => ({
let mut _temp = ::std::vec::Vec::new();