Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syntax: Support modern attribute syntax in the meta matcher #63674

Merged
merged 3 commits into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
syntax: Support modern attribute syntax in the meta matcher
  • Loading branch information
petrochenkov committed Sep 30, 2019
commit 957986d05620238799ae7053d505f742a0c7d640
16 changes: 11 additions & 5 deletions src/libsyntax/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,8 @@ impl MetaItem {
}
}

impl Attribute {
/// Extracts the `MetaItem` from inside this `Attribute`.
pub fn meta(&self) -> Option<MetaItem> {
impl AttrItem {
crate fn meta(&self, span: Span) -> Option<MetaItem> {
let mut tokens = self.tokens.trees().peekable();
Some(MetaItem {
path: self.path.clone(),
Expand All @@ -269,9 +268,16 @@ impl Attribute {
} else {
return None;
},
span: self.span,
span,
})
}
}

impl Attribute {
/// Extracts the MetaItem from inside this Attribute.
pub fn meta(&self) -> Option<MetaItem> {
self.item.meta(self.span)
}

pub fn parse<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, T>
where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
Expand Down Expand Up @@ -524,7 +530,7 @@ impl MetaItem {
}
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
token::Nonterminal::NtIdent(ident, _) => Path::from_ident(ident),
token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()),
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
token::Nonterminal::NtPath(ref path) => path.clone(),
_ => return None,
},
Expand Down
8 changes: 4 additions & 4 deletions src/libsyntax/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ impl<'a> StripUnconfigured<'a> {

while !parser.check(&token::CloseDelim(token::Paren)) {
let lo = parser.token.span.lo();
let (path, tokens) = parser.parse_meta_item_unrestricted()?;
expanded_attrs.push((path, tokens, parser.prev_span.with_lo(lo)));
let item = parser.parse_attr_item()?;
expanded_attrs.push((item, parser.prev_span.with_lo(lo)));
parser.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Paren)])?;
}

Expand All @@ -150,8 +150,8 @@ impl<'a> StripUnconfigured<'a> {
// `cfg_attr` inside of another `cfg_attr`. E.g.
// `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
expanded_attrs.into_iter()
.flat_map(|(path, tokens, span)| self.process_cfg_attr(ast::Attribute {
item: ast::AttrItem { path, tokens },
.flat_map(|(item, span)| self.process_cfg_attr(ast::Attribute {
item,
id: attr::mk_attr_id(),
style: attr.style,
is_sugared_doc: false,
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/mbe/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Nonterminal {
FatalError.raise()
}
sym::path => token::NtPath(panictry!(p.parse_path(PathStyle::Type))),
sym::meta => token::NtMeta(panictry!(p.parse_meta_item())),
sym::meta => token::NtMeta(panictry!(p.parse_attr_item())),
sym::vis => token::NtVis(panictry!(p.parse_visibility(true))),
sym::lifetime => if p.check_lifetime() {
token::NtLifetime(p.expect_lifetime().ident)
Expand Down
5 changes: 4 additions & 1 deletion src/libsyntax/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,10 @@ pub fn noop_visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis:
token::NtIdent(ident, _is_raw) => vis.visit_ident(ident),
token::NtLifetime(ident) => vis.visit_ident(ident),
token::NtLiteral(expr) => vis.visit_expr(expr),
token::NtMeta(meta) => vis.visit_meta_item(meta),
token::NtMeta(AttrItem { path, tokens }) => {
vis.visit_path(path);
vis.visit_tts(tokens);
}
token::NtPath(path) => vis.visit_path(path),
token::NtTT(tt) => vis.visit_tt(tt),
token::NtImplItem(item) =>
Expand Down
31 changes: 18 additions & 13 deletions src/libsyntax/parse/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl<'a> Parser<'a> {
debug!("parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}",
inner_parse_policy,
self.token);
let (span, path, tokens, style) = match self.token.kind {
let (span, item, style) = match self.token.kind {
token::Pound => {
let lo = self.token.span;
self.bump();
Expand All @@ -107,7 +107,7 @@ impl<'a> Parser<'a> {
};

self.expect(&token::OpenDelim(token::Bracket))?;
let (path, tokens) = self.parse_meta_item_unrestricted()?;
let item = self.parse_attr_item()?;
self.expect(&token::CloseDelim(token::Bracket))?;
let hi = self.prev_span;

Expand Down Expand Up @@ -142,7 +142,7 @@ impl<'a> Parser<'a> {
}
}

(attr_sp, path, tokens, style)
(attr_sp, item, style)
}
_ => {
let token_str = self.this_token_to_string();
Expand All @@ -151,7 +151,7 @@ impl<'a> Parser<'a> {
};

Ok(ast::Attribute {
item: ast::AttrItem { path, tokens },
item,
id: attr::mk_attr_id(),
style,
is_sugared_doc: false,
Expand All @@ -168,17 +168,17 @@ impl<'a> Parser<'a> {
/// PATH
/// PATH `=` TOKEN_TREE
/// The delimiters or `=` are still put into the resulting token stream.
pub fn parse_meta_item_unrestricted(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
let meta = match self.token.kind {
pub fn parse_attr_item(&mut self) -> PResult<'a, ast::AttrItem> {
let item = match self.token.kind {
token::Interpolated(ref nt) => match **nt {
Nonterminal::NtMeta(ref meta) => Some(meta.clone()),
Nonterminal::NtMeta(ref item) => Some(item.clone()),
_ => None,
},
_ => None,
};
Ok(if let Some(meta) = meta {
Ok(if let Some(item) = item {
self.bump();
(meta.path, meta.kind.tokens(meta.span))
item
} else {
let path = self.parse_path(PathStyle::Mod)?;
let tokens = if self.check(&token::OpenDelim(DelimToken::Paren)) ||
Expand All @@ -205,7 +205,7 @@ impl<'a> Parser<'a> {
} else {
TokenStream::empty()
};
(path, tokens)
ast::AttrItem { path, tokens }
})
}

Expand Down Expand Up @@ -273,9 +273,14 @@ impl<'a> Parser<'a> {
_ => None,
};

if let Some(meta) = nt_meta {
self.bump();
return Ok(meta);
if let Some(item) = nt_meta {
return match item.meta(item.path.span) {
Some(meta) => {
self.bump();
Ok(meta)
}
None => self.unexpected(),
}
}

let lo = self.token.span;
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/parse/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ impl<'a> Parser<'a> {
pub fn parse_path_allowing_meta(&mut self, style: PathStyle) -> PResult<'a, Path> {
let meta_ident = match self.token.kind {
token::Interpolated(ref nt) => match **nt {
token::NtMeta(ref meta) => match meta.kind {
ast::MetaItemKind::Word => Some(meta.path.clone()),
_ => None,
token::NtMeta(ref item) => match item.tokens.is_empty() {
true => Some(item.path.clone()),
false => None,
},
_ => None,
},
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ pub enum Nonterminal {
NtLifetime(ast::Ident),
NtLiteral(P<ast::Expr>),
/// Stuff inside brackets for attributes
NtMeta(ast::MetaItem),
NtMeta(ast::AttrItem),
NtPath(ast::Path),
NtVis(ast::Visibility),
NtTT(TokenTree),
Expand Down
40 changes: 22 additions & 18 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String {
crate fn nonterminal_to_string(nt: &Nonterminal) -> String {
match *nt {
token::NtExpr(ref e) => expr_to_string(e),
token::NtMeta(ref e) => meta_item_to_string(e),
token::NtMeta(ref e) => attr_item_to_string(e),
token::NtTy(ref e) => ty_to_string(e),
token::NtPath(ref e) => path_to_string(e),
token::NtItem(ref e) => item_to_string(e),
Expand Down Expand Up @@ -412,8 +412,8 @@ pub fn meta_list_item_to_string(li: &ast::NestedMetaItem) -> String {
to_string(|s| s.print_meta_list_item(li))
}

pub fn meta_item_to_string(mi: &ast::MetaItem) -> String {
to_string(|s| s.print_meta_item(mi))
fn attr_item_to_string(ai: &ast::AttrItem) -> String {
to_string(|s| s.print_attr_item(ai, ai.path.span))
}

pub fn attribute_to_string(attr: &ast::Attribute) -> String {
Expand Down Expand Up @@ -629,24 +629,28 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
ast::AttrStyle::Inner => self.word("#!["),
ast::AttrStyle::Outer => self.word("#["),
}
self.ibox(0);
match attr.tokens.trees().next() {
Some(TokenTree::Delimited(_, delim, tts)) => {
self.print_mac_common(
Some(MacHeader::Path(&attr.path)), false, None, delim, tts, true, attr.span
);
}
tree => {
self.print_path(&attr.path, false, 0);
if tree.is_some() {
self.space();
self.print_tts(attr.tokens.clone(), true);
}
self.print_attr_item(&attr.item, attr.span);
self.word("]");
}
}

fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
self.ibox(0);
match item.tokens.trees().next() {
Some(TokenTree::Delimited(_, delim, tts)) => {
self.print_mac_common(
Some(MacHeader::Path(&item.path)), false, None, delim, tts, true, span
);
}
tree => {
self.print_path(&item.path, false, 0);
if tree.is_some() {
self.space();
self.print_tts(item.tokens.clone(), true);
}
}
self.end();
self.word("]");
}
self.end();
}

fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) {
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax_ext/cmdline_attrs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Attributes injected into the crate root from command line using `-Z crate-attr`.

use syntax::ast::{self, AttrStyle};
use syntax::ast::{self, AttrItem, AttrStyle};
use syntax::attr::mk_attr;
use syntax::panictry;
use syntax::parse::{self, token, ParseSess};
Expand All @@ -15,7 +15,7 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
);

let start_span = parser.token.span;
let (path, tokens) = panictry!(parser.parse_meta_item_unrestricted());
let AttrItem { path, tokens } = panictry!(parser.parse_attr_item());
let end_span = parser.token.span;
if parser.token != token::Eof {
parse_sess.span_diagnostic
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/cfg/cfg_stmt_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fn main() {
// check that macro expanded code works

macro_rules! if_cfg {
($cfg:meta $ib:block else $eb:block) => {
($cfg:meta? $ib:block else $eb:block) => {
{
let r;
#[cfg($cfg)]
Expand All @@ -69,7 +69,7 @@ fn main() {
}
}

let n = if_cfg!(unset {
let n = if_cfg!(unset? {
413
} else {
612
Expand Down
6 changes: 0 additions & 6 deletions src/test/ui/macros/macro-first-set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,6 @@ test_path!(::std);
test_path!(std::u8,);
test_path!(any, super, super::super::self::path, X<Y>::Z<'a, T=U>);

macro_rules! test_meta_block {
($($m:meta)* $b:block) => {};
}

test_meta_block!(windows {});

macro_rules! test_lifetime {
(1. $($l:lifetime)* $($b:block)*) => {};
(2. $($b:block)* $($l:lifetime)*) => {};
Expand Down