Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit fca91bc

Browse files
authored
Merge pull request rust-lang#3333 from topecongiro/macro-arg-single-keyword
Handle a macro argument with a single keyword
2 parents c4611a0 + 9a7ea6a commit fca91bc

File tree

5 files changed

+110
-9
lines changed

5 files changed

+110
-9
lines changed

src/macros.rs

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use syntax::parse::parser::Parser;
2626
use syntax::parse::token::{BinOpToken, DelimToken, Token};
2727
use syntax::print::pprust;
2828
use syntax::source_map::{BytePos, Span};
29-
use syntax::symbol;
29+
use syntax::symbol::keywords;
3030
use syntax::tokenstream::{Cursor, TokenStream, TokenTree};
3131
use syntax::ThinVec;
3232
use syntax::{ast, parse, ptr};
@@ -64,6 +64,7 @@ pub enum MacroArg {
6464
Ty(ptr::P<ast::Ty>),
6565
Pat(ptr::P<ast::Pat>),
6666
Item(ptr::P<ast::Item>),
67+
Keyword(ast::Ident, Span),
6768
}
6869

6970
impl MacroArg {
@@ -92,6 +93,7 @@ impl Rewrite for MacroArg {
9293
MacroArg::Ty(ref ty) => ty.rewrite(context, shape),
9394
MacroArg::Pat(ref pat) => pat.rewrite(context, shape),
9495
MacroArg::Item(ref item) => item.rewrite(context, shape),
96+
MacroArg::Keyword(ident, _) => Some(ident.to_string()),
9597
}
9698
}
9799
}
@@ -156,7 +158,7 @@ fn rewrite_macro_name(
156158
format!("{}!", path)
157159
};
158160
match extra_ident {
159-
Some(ident) if ident != symbol::keywords::Invalid.ident() => format!("{} {}", name, ident),
161+
Some(ident) if ident != keywords::Invalid.ident() => format!("{} {}", name, ident),
160162
_ => name,
161163
}
162164
}
@@ -224,6 +226,23 @@ pub fn rewrite_macro(
224226
result
225227
}
226228

229+
fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> {
230+
for &keyword in RUST_KEYWORDS.iter() {
231+
if parser.token.is_keyword(keyword)
232+
&& parser.look_ahead(1, |t| {
233+
*t == Token::Eof
234+
|| *t == Token::Comma
235+
|| *t == Token::CloseDelim(DelimToken::NoDelim)
236+
})
237+
{
238+
let macro_arg = MacroArg::Keyword(keyword.ident(), parser.span);
239+
parser.bump();
240+
return Some(macro_arg);
241+
}
242+
}
243+
None
244+
}
245+
227246
pub fn rewrite_macro_inner(
228247
mac: &ast::Mac,
229248
extra_ident: Option<ast::Ident>,
@@ -276,11 +295,12 @@ pub fn rewrite_macro_inner(
276295

277296
if DelimToken::Brace != style {
278297
loop {
279-
match parse_macro_arg(&mut parser) {
280-
Some(arg) => arg_vec.push(arg),
281-
None => {
282-
return return_macro_parse_failure_fallback(context, shape.indent, mac.span);
283-
}
298+
if let Some(arg) = parse_macro_arg(&mut parser) {
299+
arg_vec.push(arg);
300+
} else if let Some(arg) = check_keyword(&mut parser) {
301+
arg_vec.push(arg);
302+
} else {
303+
return return_macro_parse_failure_fallback(context, shape.indent, mac.span);
284304
}
285305

286306
match parser.token {
@@ -1373,8 +1393,8 @@ fn format_lazy_static(context: &RewriteContext, shape: Shape, ts: &TokenStream)
13731393
while parser.token != Token::Eof {
13741394
// Parse a `lazy_static!` item.
13751395
let vis = crate::utils::format_visibility(context, &parse_or!(parse_visibility, false));
1376-
parser.eat_keyword(symbol::keywords::Static);
1377-
parser.eat_keyword(symbol::keywords::Ref);
1396+
parser.eat_keyword(keywords::Static);
1397+
parser.eat_keyword(keywords::Ref);
13781398
let id = parse_or!(parse_ident);
13791399
parser.eat(&Token::Colon);
13801400
let ty = parse_or!(parse_ty);
@@ -1449,3 +1469,66 @@ fn rewrite_macro_with_items(
14491469
result.push_str(trailing_semicolon);
14501470
Some(result)
14511471
}
1472+
1473+
const RUST_KEYWORDS: [keywords::Keyword; 60] = [
1474+
keywords::PathRoot,
1475+
keywords::DollarCrate,
1476+
keywords::Underscore,
1477+
keywords::As,
1478+
keywords::Box,
1479+
keywords::Break,
1480+
keywords::Const,
1481+
keywords::Continue,
1482+
keywords::Crate,
1483+
keywords::Else,
1484+
keywords::Enum,
1485+
keywords::Extern,
1486+
keywords::False,
1487+
keywords::Fn,
1488+
keywords::For,
1489+
keywords::If,
1490+
keywords::Impl,
1491+
keywords::In,
1492+
keywords::Let,
1493+
keywords::Loop,
1494+
keywords::Match,
1495+
keywords::Mod,
1496+
keywords::Move,
1497+
keywords::Mut,
1498+
keywords::Pub,
1499+
keywords::Ref,
1500+
keywords::Return,
1501+
keywords::SelfLower,
1502+
keywords::SelfUpper,
1503+
keywords::Static,
1504+
keywords::Struct,
1505+
keywords::Super,
1506+
keywords::Trait,
1507+
keywords::True,
1508+
keywords::Type,
1509+
keywords::Unsafe,
1510+
keywords::Use,
1511+
keywords::Where,
1512+
keywords::While,
1513+
keywords::Abstract,
1514+
keywords::Become,
1515+
keywords::Do,
1516+
keywords::Final,
1517+
keywords::Macro,
1518+
keywords::Override,
1519+
keywords::Priv,
1520+
keywords::Typeof,
1521+
keywords::Unsized,
1522+
keywords::Virtual,
1523+
keywords::Yield,
1524+
keywords::Dyn,
1525+
keywords::Async,
1526+
keywords::Try,
1527+
keywords::UnderscoreLifetime,
1528+
keywords::StaticLifetime,
1529+
keywords::Auto,
1530+
keywords::Catch,
1531+
keywords::Default,
1532+
keywords::Existential,
1533+
keywords::Union,
1534+
];

src/overflow.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ impl<'a> OverflowableItem<'a> {
167167
MacroArg::Ty(ref ty) => can_be_overflowed_type(context, ty, len),
168168
MacroArg::Pat(..) => false,
169169
MacroArg::Item(..) => len == 1,
170+
MacroArg::Keyword(..) => false,
170171
},
171172
OverflowableItem::NestedMetaItem(nested_meta_item) if len == 1 => {
172173
match nested_meta_item.node {

src/spanned.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ impl Spanned for MacroArg {
198198
MacroArg::Ty(ref ty) => ty.span(),
199199
MacroArg::Pat(ref pat) => pat.span(),
200200
MacroArg::Item(ref item) => item.span(),
201+
MacroArg::Keyword(_, span) => span,
201202
}
202203
}
203204
}

tests/source/macros.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,3 +463,11 @@ fn issue3004() {
463463
foo!(|_| { ( ) });
464464
stringify!(( foo+ ));
465465
}
466+
467+
// #3331
468+
pub fn fold_abi<V: Fold + ?Sized>(_visitor: &mut V, _i: Abi) -> Abi {
469+
Abi {
470+
extern_token: Token ! [ extern ](tokens_helper(_visitor, &_i.extern_token.span)),
471+
name: (_i.name).map(|it| _visitor.fold_lit_str(it)),
472+
}
473+
}

tests/target/macros.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,3 +1040,11 @@ fn issue3004() {
10401040
foo!(|_| { () });
10411041
stringify!((foo+));
10421042
}
1043+
1044+
// #3331
1045+
pub fn fold_abi<V: Fold + ?Sized>(_visitor: &mut V, _i: Abi) -> Abi {
1046+
Abi {
1047+
extern_token: Token![extern](tokens_helper(_visitor, &_i.extern_token.span)),
1048+
name: (_i.name).map(|it| _visitor.fold_lit_str(it)),
1049+
}
1050+
}

0 commit comments

Comments
 (0)