diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs index 94e3d5ce2d3..ef8894a258c 100644 --- a/src/libstd/comm/mod.rs +++ b/src/libstd/comm/mod.rs @@ -252,7 +252,7 @@ use sync::arc::UnsafeArc; pub use comm::select::{Select, Handle}; macro_rules! test ( - { fn $name:ident() $b:block $($a:attr)*} => ( + { fn $name:ident() $b:block $(#[$a:meta])*} => ( mod $name { #[allow(unused_imports)]; @@ -265,8 +265,8 @@ macro_rules! test ( fn f() $b - $($a)* #[test] fn uv() { f() } - $($a)* #[test] fn native() { + $(#[$a])* #[test] fn uv() { f() } + $(#[$a])* #[test] fn native() { use native; let (tx, rx) = channel(); native::task::spawn(proc() { tx.send(f()) }); diff --git a/src/libstd/io/test.rs b/src/libstd/io/test.rs index 9eeaf4635a4..6e987869238 100644 --- a/src/libstd/io/test.rs +++ b/src/libstd/io/test.rs @@ -19,7 +19,7 @@ use std::io::net::ip::*; use sync::atomics::{AtomicUint, INIT_ATOMIC_UINT, Relaxed}; macro_rules! iotest ( - { fn $name:ident() $b:block $($a:attr)* } => ( + { fn $name:ident() $b:block $(#[$a:meta])* } => ( mod $name { #[allow(unused_imports)]; @@ -43,8 +43,8 @@ macro_rules! iotest ( fn f() $b - $($a)* #[test] fn green() { f() } - $($a)* #[test] fn native() { + $(#[$a])* #[test] fn green() { f() } + $(#[$a])* #[test] fn native() { use native; let (tx, rx) = channel(); native::task::spawn(proc() { tx.send(f()) }); diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index aa4f192f779..0d90093a40f 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -441,7 +441,7 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal { "path" => { token::NtPath(~p.parse_path(LifetimeAndTypesWithoutColons).path) } - "attr" => token::NtAttr(@p.parse_attribute(false)), + "meta" => token::NtMeta(p.parse_meta_item()), "tt" => { p.quote_depth += 1u; //but in theory, non-quoted tts might be useful let res = token::NtTT(@p.parse_token_tree()); diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 8f7fb5749a1..b569bb28a7d 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -34,9 +34,6 @@ impl<'a> ParserAttr for Parser<'a> { debug!("parse_outer_attributes: self.token={:?}", self.token); match self.token { - token::INTERPOLATED(token::NtAttr(..)) => { - attrs.push(self.parse_attribute(false)); - } token::POUND => { attrs.push(self.parse_attribute(false)); } @@ -66,11 +63,6 @@ impl<'a> ParserAttr for Parser<'a> { debug!("parse_attributes: permit_inner={:?} self.token={:?}", permit_inner, self.token); let (span, value, mut style) = match self.token { - INTERPOLATED(token::NtAttr(attr)) => { - assert!(attr.node.style == ast::AttrOuter); - self.bump(); - (attr.span, attr.node.value, ast::AttrOuter) - } token::POUND => { let lo = self.span.lo; self.bump(); @@ -133,9 +125,6 @@ impl<'a> ParserAttr for Parser<'a> { let mut next_outer_attrs: Vec = Vec::new(); loop { let attr = match self.token { - token::INTERPOLATED(token::NtAttr(..)) => { - self.parse_attribute(true) - } token::POUND => { self.parse_attribute(true) } @@ -163,6 +152,14 @@ impl<'a> ParserAttr for Parser<'a> { // | IDENT = lit // | IDENT meta_seq fn parse_meta_item(&mut self) -> @ast::MetaItem { + match self.token { + token::INTERPOLATED(token::NtMeta(e)) => { + self.bump(); + return e + } + _ => {} + } + let lo = self.span.lo; let ident = self.parse_ident(); let name = self.id_to_interned_str(ident); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 7bb920bdf56..e3eb1f1f711 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -113,7 +113,7 @@ pub enum Nonterminal { NtExpr(@ast::Expr), NtTy( P), NtIdent(~ast::Ident, bool), - NtAttr(@ast::Attribute), // #[foo] + NtMeta(@ast::MetaItem), // stuff inside brackets for attributes NtPath(~ast::Path), NtTT( @ast::TokenTree), // needs @ed to break a circularity NtMatchers(Vec ) @@ -129,7 +129,7 @@ impl fmt::Show for Nonterminal { NtExpr(..) => f.pad("NtExpr(..)"), NtTy(..) => f.pad("NtTy(..)"), NtIdent(..) => f.pad("NtIdent(..)"), - NtAttr(..) => f.pad("NtAttr(..)"), + NtMeta(..) => f.pad("NtMeta(..)"), NtPath(..) => f.pad("NtPath(..)"), NtTT(..) => f.pad("NtTT(..)"), NtMatchers(..) => f.pad("NtMatchers(..)"), @@ -241,7 +241,7 @@ pub fn to_str(t: &Token) -> ~str { INTERPOLATED(ref nt) => { match nt { &NtExpr(e) => ::print::pprust::expr_to_str(e), - &NtAttr(e) => ::print::pprust::attribute_to_str(e), + &NtMeta(e) => ::print::pprust::meta_item_to_str(e), _ => { ~"an interpolated " + match *nt { @@ -249,7 +249,7 @@ pub fn to_str(t: &Token) -> ~str { NtBlock(..) => ~"block", NtStmt(..) => ~"statement", NtPat(..) => ~"pattern", - NtAttr(..) => fail!("should have been handled"), + NtMeta(..) => fail!("should have been handled"), NtExpr(..) => fail!("should have been handled above"), NtTy(..) => ~"type", NtIdent(..) => ~"identifier", diff --git a/src/test/compile-fail/macro-inner-attributes.rs b/src/test/compile-fail/macro-inner-attributes.rs index 104438848c4..753ab3d0368 100644 --- a/src/test/compile-fail/macro-inner-attributes.rs +++ b/src/test/compile-fail/macro-inner-attributes.rs @@ -11,8 +11,8 @@ #[feature(macro_rules)]; macro_rules! test ( ($nm:ident, - $a:attr, - $i:item) => (mod $nm { $a; $i }); ) + #[$a:meta], + $i:item) => (mod $nm { #![$a] $i }); ) test!(a, #[cfg(qux)], diff --git a/src/test/compile-fail/macro-outer-attributes.rs b/src/test/compile-fail/macro-outer-attributes.rs index 6bd184ce6a6..a4ded8e20b9 100644 --- a/src/test/compile-fail/macro-outer-attributes.rs +++ b/src/test/compile-fail/macro-outer-attributes.rs @@ -11,8 +11,8 @@ #[feature(macro_rules)]; macro_rules! test ( ($nm:ident, - $a:attr, - $i:item) => (mod $nm { $a $i }); ) + #[$a:meta], + $i:item) => (mod $nm { #[$a] $i }); ) test!(a, #[cfg(qux)], diff --git a/src/test/run-pass/macro-attributes.rs b/src/test/run-pass/macro-attributes.rs index 58095137428..076305002e4 100644 --- a/src/test/run-pass/macro-attributes.rs +++ b/src/test/run-pass/macro-attributes.rs @@ -13,11 +13,11 @@ #[feature(macro_rules)]; macro_rules! compiles_fine { - ($at:attr) => { + (#[$at:meta]) => { // test that the different types of attributes work #[attribute] /// Documentation! - $at + #[$at] // check that the attributes are recognised by requiring this // to be removed to avoid a compile error diff --git a/src/test/run-pass/macro-meta-items.rs b/src/test/run-pass/macro-meta-items.rs new file mode 100644 index 00000000000..e92685f3e58 --- /dev/null +++ b/src/test/run-pass/macro-meta-items.rs @@ -0,0 +1,43 @@ +// 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 - token trees can't pretty print +// compile-flags: --cfg foo + +#[feature(macro_rules)]; + +macro_rules! compiles_fine { + ($at:meta) => { + #[cfg($at)] + static MISTYPED: () = "foo"; + } +} +macro_rules! emit { + ($at:meta) => { + #[cfg($at)] + static MISTYPED: &'static str = "foo"; + } +} + +// item +compiles_fine!(bar) +emit!(foo) + +fn foo() { + println!("{}", MISTYPED); +} + +pub fn main() { + // statement + compiles_fine!(baz); + emit!(baz); + println!("{}", MISTYPED); +} +