Skip to content

Commit 28937be

Browse files
committed
rollup merge of #21429: GuillaumeGomez/macro-fix
This is little clean code of this PR: #21366. I patched the same thing as aochagavia but too slowly obviously. This is a merge of our two codes, more "rust-like".
2 parents 9ef5484 + 3c37a95 commit 28937be

File tree

2 files changed

+68
-53
lines changed

2 files changed

+68
-53
lines changed

src/libsyntax/ext/tt/macro_rules.rs

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use ast::{TokenTree, TtDelimited, TtSequence, TtToken};
12-
use ast;
11+
use ast::{self, TokenTree, TtDelimited, TtSequence, TtToken};
1312
use codemap::{Span, DUMMY_SP};
1413
use ext::base::{ExtCtxt, MacResult, SyntaxExtension};
1514
use ext::base::{NormalTT, TTMacroExpander};
@@ -19,9 +18,8 @@ use ext::tt::macro_parser::{parse, parse_or_else};
1918
use parse::lexer::{new_tt_reader, new_tt_reader_with_doc_flag};
2019
use parse::parser::Parser;
2120
use parse::attr::ParserAttr;
22-
use parse::token::{special_idents, gensym_ident, NtTT, Token};
21+
use parse::token::{self, special_idents, gensym_ident, NtTT, Token};
2322
use parse::token::Token::*;
24-
use parse::token;
2523
use print;
2624
use ptr::P;
2725

@@ -336,16 +334,20 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
336334

337335
let tok = if let TtToken(_, ref tok) = *token { tok } else { unreachable!() };
338336
// If T' is in the set FOLLOW(NT), continue. Else, reject.
339-
match &next_token {
340-
&Eof => return Some((sp, tok.clone())),
341-
_ if is_in_follow(cx, &next_token, frag_spec.as_str()) => continue,
342-
next => {
337+
match (&next_token, is_in_follow(cx, &next_token, frag_spec.as_str())) {
338+
(&Eof, _) => return Some((sp, tok.clone())),
339+
(_, Ok(true)) => continue,
340+
(next, Ok(false)) => {
343341
cx.span_err(sp, format!("`${0}:{1}` is followed by `{2}`, which \
344342
is not allowed for `{1}` fragments",
345343
name.as_str(), frag_spec.as_str(),
346344
token_to_string(next)).as_slice());
347345
continue
348346
},
347+
(_, Err(msg)) => {
348+
cx.span_err(sp, msg.as_slice());
349+
continue
350+
}
349351
}
350352
},
351353
TtSequence(sp, ref seq) => {
@@ -412,51 +414,50 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
412414
last
413415
}
414416

415-
fn is_in_follow(cx: &ExtCtxt, tok: &Token, frag: &str) -> bool {
417+
fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> {
416418
if let &CloseDelim(_) = tok {
417-
return true;
418-
}
419-
420-
match frag {
421-
"item" => {
422-
// since items *must* be followed by either a `;` or a `}`, we can
423-
// accept anything after them
424-
true
425-
},
426-
"block" => {
427-
// anything can follow block, the braces provide a easy boundary to
428-
// maintain
429-
true
430-
},
431-
"stmt" | "expr" => {
432-
match *tok {
433-
FatArrow | Comma | Semi => true,
434-
_ => false
435-
}
436-
},
437-
"pat" => {
438-
match *tok {
439-
FatArrow | Comma | Eq => true,
440-
_ => false
441-
}
442-
},
443-
"path" | "ty" => {
444-
match *tok {
445-
Comma | FatArrow | Colon | Eq | Gt => true,
446-
Ident(i, _) if i.as_str() == "as" => true,
447-
_ => false
448-
}
449-
},
450-
"ident" => {
451-
// being a single token, idents are harmless
452-
true
453-
},
454-
"meta" | "tt" => {
455-
// being either a single token or a delimited sequence, tt is
456-
// harmless
457-
true
458-
},
459-
_ => cx.bug(format!("unrecognized builtin nonterminal {}",
460-
frag).as_slice()),
419+
Ok(true)
420+
} else {
421+
match frag {
422+
"item" => {
423+
// since items *must* be followed by either a `;` or a `}`, we can
424+
// accept anything after them
425+
Ok(true)
426+
},
427+
"block" => {
428+
// anything can follow block, the braces provide a easy boundary to
429+
// maintain
430+
Ok(true)
431+
},
432+
"stmt" | "expr" => {
433+
match *tok {
434+
FatArrow | Comma | Semi => Ok(true),
435+
_ => Ok(false)
436+
}
437+
},
438+
"pat" => {
439+
match *tok {
440+
FatArrow | Comma | Eq => Ok(true),
441+
_ => Ok(false)
442+
}
443+
},
444+
"path" | "ty" => {
445+
match *tok {
446+
Comma | FatArrow | Colon | Eq | Gt => Ok(true),
447+
Ident(i, _) if i.as_str() == "as" => Ok(true),
448+
_ => Ok(false)
449+
}
450+
},
451+
"ident" => {
452+
// being a single token, idents are harmless
453+
Ok(true)
454+
},
455+
"meta" | "tt" => {
456+
// being either a single token or a delimited sequence, tt is
457+
// harmless
458+
Ok(true)
459+
},
460+
_ => Err(format!("unrecognized builtin nonterminal `{}`", frag))
461+
}
461462
}
462463
}

src/test/compile-fail/issue-21356.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
macro_rules! test { ($wrong:t_ty ..) => () }
12+
//~^ ERROR: unrecognized builtin nonterminal `t_ty`
13+
14+
fn main() {}

0 commit comments

Comments
 (0)