Merge pull request #3333 from topecongiro/macro-arg-single-keyword

Handle a macro argument with a single keyword
This commit is contained in:
Seiichi Uchida 2019-02-11 00:45:13 +09:00 committed by GitHub
commit fca91bc22f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 110 additions and 9 deletions

View File

@ -26,7 +26,7 @@ use syntax::parse::parser::Parser;
use syntax::parse::token::{BinOpToken, DelimToken, Token}; use syntax::parse::token::{BinOpToken, DelimToken, Token};
use syntax::print::pprust; use syntax::print::pprust;
use syntax::source_map::{BytePos, Span}; use syntax::source_map::{BytePos, Span};
use syntax::symbol; use syntax::symbol::keywords;
use syntax::tokenstream::{Cursor, TokenStream, TokenTree}; use syntax::tokenstream::{Cursor, TokenStream, TokenTree};
use syntax::ThinVec; use syntax::ThinVec;
use syntax::{ast, parse, ptr}; use syntax::{ast, parse, ptr};
@ -64,6 +64,7 @@ pub enum MacroArg {
Ty(ptr::P<ast::Ty>), Ty(ptr::P<ast::Ty>),
Pat(ptr::P<ast::Pat>), Pat(ptr::P<ast::Pat>),
Item(ptr::P<ast::Item>), Item(ptr::P<ast::Item>),
Keyword(ast::Ident, Span),
} }
impl MacroArg { impl MacroArg {
@ -92,6 +93,7 @@ impl Rewrite for MacroArg {
MacroArg::Ty(ref ty) => ty.rewrite(context, shape), MacroArg::Ty(ref ty) => ty.rewrite(context, shape),
MacroArg::Pat(ref pat) => pat.rewrite(context, shape), MacroArg::Pat(ref pat) => pat.rewrite(context, shape),
MacroArg::Item(ref item) => item.rewrite(context, shape), MacroArg::Item(ref item) => item.rewrite(context, shape),
MacroArg::Keyword(ident, _) => Some(ident.to_string()),
} }
} }
} }
@ -156,7 +158,7 @@ fn rewrite_macro_name(
format!("{}!", path) format!("{}!", path)
}; };
match extra_ident { match extra_ident {
Some(ident) if ident != symbol::keywords::Invalid.ident() => format!("{} {}", name, ident), Some(ident) if ident != keywords::Invalid.ident() => format!("{} {}", name, ident),
_ => name, _ => name,
} }
} }
@ -224,6 +226,23 @@ pub fn rewrite_macro(
result result
} }
fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> {
for &keyword in RUST_KEYWORDS.iter() {
if parser.token.is_keyword(keyword)
&& parser.look_ahead(1, |t| {
*t == Token::Eof
|| *t == Token::Comma
|| *t == Token::CloseDelim(DelimToken::NoDelim)
})
{
let macro_arg = MacroArg::Keyword(keyword.ident(), parser.span);
parser.bump();
return Some(macro_arg);
}
}
None
}
pub fn rewrite_macro_inner( pub fn rewrite_macro_inner(
mac: &ast::Mac, mac: &ast::Mac,
extra_ident: Option<ast::Ident>, extra_ident: Option<ast::Ident>,
@ -276,11 +295,12 @@ pub fn rewrite_macro_inner(
if DelimToken::Brace != style { if DelimToken::Brace != style {
loop { loop {
match parse_macro_arg(&mut parser) { if let Some(arg) = parse_macro_arg(&mut parser) {
Some(arg) => arg_vec.push(arg), arg_vec.push(arg);
None => { } else if let Some(arg) = check_keyword(&mut parser) {
return return_macro_parse_failure_fallback(context, shape.indent, mac.span); arg_vec.push(arg);
} } else {
return return_macro_parse_failure_fallback(context, shape.indent, mac.span);
} }
match parser.token { match parser.token {
@ -1373,8 +1393,8 @@ fn format_lazy_static(context: &RewriteContext, shape: Shape, ts: &TokenStream)
while parser.token != Token::Eof { while parser.token != Token::Eof {
// Parse a `lazy_static!` item. // Parse a `lazy_static!` item.
let vis = crate::utils::format_visibility(context, &parse_or!(parse_visibility, false)); let vis = crate::utils::format_visibility(context, &parse_or!(parse_visibility, false));
parser.eat_keyword(symbol::keywords::Static); parser.eat_keyword(keywords::Static);
parser.eat_keyword(symbol::keywords::Ref); parser.eat_keyword(keywords::Ref);
let id = parse_or!(parse_ident); let id = parse_or!(parse_ident);
parser.eat(&Token::Colon); parser.eat(&Token::Colon);
let ty = parse_or!(parse_ty); let ty = parse_or!(parse_ty);
@ -1449,3 +1469,66 @@ fn rewrite_macro_with_items(
result.push_str(trailing_semicolon); result.push_str(trailing_semicolon);
Some(result) Some(result)
} }
const RUST_KEYWORDS: [keywords::Keyword; 60] = [
keywords::PathRoot,
keywords::DollarCrate,
keywords::Underscore,
keywords::As,
keywords::Box,
keywords::Break,
keywords::Const,
keywords::Continue,
keywords::Crate,
keywords::Else,
keywords::Enum,
keywords::Extern,
keywords::False,
keywords::Fn,
keywords::For,
keywords::If,
keywords::Impl,
keywords::In,
keywords::Let,
keywords::Loop,
keywords::Match,
keywords::Mod,
keywords::Move,
keywords::Mut,
keywords::Pub,
keywords::Ref,
keywords::Return,
keywords::SelfLower,
keywords::SelfUpper,
keywords::Static,
keywords::Struct,
keywords::Super,
keywords::Trait,
keywords::True,
keywords::Type,
keywords::Unsafe,
keywords::Use,
keywords::Where,
keywords::While,
keywords::Abstract,
keywords::Become,
keywords::Do,
keywords::Final,
keywords::Macro,
keywords::Override,
keywords::Priv,
keywords::Typeof,
keywords::Unsized,
keywords::Virtual,
keywords::Yield,
keywords::Dyn,
keywords::Async,
keywords::Try,
keywords::UnderscoreLifetime,
keywords::StaticLifetime,
keywords::Auto,
keywords::Catch,
keywords::Default,
keywords::Existential,
keywords::Union,
];

View File

@ -167,6 +167,7 @@ impl<'a> OverflowableItem<'a> {
MacroArg::Ty(ref ty) => can_be_overflowed_type(context, ty, len), MacroArg::Ty(ref ty) => can_be_overflowed_type(context, ty, len),
MacroArg::Pat(..) => false, MacroArg::Pat(..) => false,
MacroArg::Item(..) => len == 1, MacroArg::Item(..) => len == 1,
MacroArg::Keyword(..) => false,
}, },
OverflowableItem::NestedMetaItem(nested_meta_item) if len == 1 => { OverflowableItem::NestedMetaItem(nested_meta_item) if len == 1 => {
match nested_meta_item.node { match nested_meta_item.node {

View File

@ -198,6 +198,7 @@ impl Spanned for MacroArg {
MacroArg::Ty(ref ty) => ty.span(), MacroArg::Ty(ref ty) => ty.span(),
MacroArg::Pat(ref pat) => pat.span(), MacroArg::Pat(ref pat) => pat.span(),
MacroArg::Item(ref item) => item.span(), MacroArg::Item(ref item) => item.span(),
MacroArg::Keyword(_, span) => span,
} }
} }
} }

View File

@ -463,3 +463,11 @@ fn issue3004() {
foo!(|_| { ( ) }); foo!(|_| { ( ) });
stringify!(( foo+ )); stringify!(( foo+ ));
} }
// #3331
pub fn fold_abi<V: Fold + ?Sized>(_visitor: &mut V, _i: Abi) -> Abi {
Abi {
extern_token: Token ! [ extern ](tokens_helper(_visitor, &_i.extern_token.span)),
name: (_i.name).map(|it| _visitor.fold_lit_str(it)),
}
}

View File

@ -1040,3 +1040,11 @@ fn issue3004() {
foo!(|_| { () }); foo!(|_| { () });
stringify!((foo+)); stringify!((foo+));
} }
// #3331
pub fn fold_abi<V: Fold + ?Sized>(_visitor: &mut V, _i: Abi) -> Abi {
Abi {
extern_token: Token![extern](tokens_helper(_visitor, &_i.extern_token.span)),
name: (_i.name).map(|it| _visitor.fold_lit_str(it)),
}
}