Skip to content

Commit ed5ea5c

Browse files
committed
Reject _ in ident matcher
1 parent 5d06c89 commit ed5ea5c

File tree

4 files changed

+46
-19
lines changed

4 files changed

+46
-19
lines changed

Diff for: src/libsyntax/ext/tt/macro_parser.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ use self::TokenTreeOrTokenTreeVec::*;
8686

8787
use ast::Ident;
8888
use syntax_pos::{self, BytePos, Span};
89-
use codemap::Spanned;
89+
use codemap::respan;
9090
use errors::FatalError;
9191
use ext::tt::quoted::{self, TokenTree};
9292
use parse::{Directory, ParseSess};
@@ -709,6 +709,15 @@ pub fn parse(
709709
}
710710
}
711711

712+
/// The token is an identifier, but not `_`.
713+
/// We prohibit passing `_` to macros expecting `ident` for now.
714+
fn get_macro_ident(token: &Token) -> Option<Ident> {
715+
match *token {
716+
token::Ident(ident) if ident.name != keywords::Underscore.name() => Some(ident),
717+
_ => None,
718+
}
719+
}
720+
712721
/// Checks whether a non-terminal may begin with a particular token.
713722
///
714723
/// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that
@@ -725,7 +734,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
725734
match name {
726735
"expr" => token.can_begin_expr(),
727736
"ty" => token.can_begin_type(),
728-
"ident" => token.is_ident(),
737+
"ident" => get_macro_ident(token).is_some(),
729738
"vis" => match *token {
730739
// The follow-set of :vis + "priv" keyword + interpolated
731740
Token::Comma | Token::Ident(_) | Token::Interpolated(_) => true,
@@ -814,21 +823,14 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
814823
"expr" => token::NtExpr(panictry!(p.parse_expr())),
815824
"ty" => token::NtTy(panictry!(p.parse_ty())),
816825
// this could be handled like a token, since it is one
817-
"ident" => match p.token {
818-
token::Ident(sn) => {
819-
p.bump();
820-
token::NtIdent(Spanned::<Ident> {
821-
node: sn,
822-
span: p.prev_span,
823-
})
824-
}
825-
_ => {
826-
let token_str = pprust::token_to_string(&p.token);
827-
p.fatal(&format!("expected ident, found {}", &token_str[..]))
828-
.emit();
829-
FatalError.raise()
830-
}
831-
},
826+
"ident" => if let Some(ident) = get_macro_ident(&p.token) {
827+
p.bump();
828+
token::NtIdent(respan(p.prev_span, ident))
829+
} else {
830+
let token_str = pprust::token_to_string(&p.token);
831+
p.fatal(&format!("expected ident, found {}", &token_str)).emit();
832+
FatalError.raise()
833+
}
832834
"path" => token::NtPath(panictry!(p.parse_path_common(PathStyle::Type, false))),
833835
"meta" => token::NtMeta(panictry!(p.parse_meta_item())),
834836
"vis" => token::NtVis(panictry!(p.parse_visibility(true))),

Diff for: src/test/run-pass/macro-pat.rs

-2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,4 @@ pub fn main() {
7171
let ident_pat!(x) = 2;
7272
x+1
7373
});
74-
75-
let ident_pat!(_) = 2; // OK
7674
}

Diff for: src/test/ui/underscore-ident-matcher.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2018 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! identity {
12+
($i: ident) => (
13+
$i
14+
)
15+
}
16+
17+
fn main() {
18+
let identity!(_) = 10; //~ ERROR no rules expected the token `_`
19+
}

Diff for: src/test/ui/underscore-ident-matcher.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: no rules expected the token `_`
2+
--> $DIR/underscore-ident-matcher.rs:18:19
3+
|
4+
LL | let identity!(_) = 10; //~ ERROR no rules expected the token `_`
5+
| ^
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)