Skip to content

Commit 5d06c89

Browse files
committed
syntax: Make _ an identifier
1 parent 61b6bf5 commit 5d06c89

File tree

20 files changed

+109
-119
lines changed

20 files changed

+109
-119
lines changed

Diff for: src/libproc_macro/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,6 @@ impl TokenTree {
680680
Pound => op!('#'),
681681
Dollar => op!('$'),
682682
Question => op!('?'),
683-
Underscore => op!('_'),
684683

685684
Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)),
686685
Literal(..) | DocComment(..) => TokenNode::Literal(self::Literal(token)),
@@ -743,7 +742,6 @@ impl TokenTree {
743742
'#' => Pound,
744743
'$' => Dollar,
745744
'?' => Question,
746-
'_' => Underscore,
747745
_ => panic!("unsupported character {}", op),
748746
};
749747

Diff for: src/librustc/hir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ impl LifetimeName {
214214
use self::LifetimeName::*;
215215
match *self {
216216
Implicit => keywords::Invalid.name(),
217-
Underscore => Symbol::intern("'_"),
217+
Underscore => keywords::UnderscoreLifetime.name(),
218218
Static => keywords::StaticLifetime.name(),
219219
Name(name) => name,
220220
}

Diff for: src/librustc/ich/impls_syntax.rs

-1
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,6 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
287287
token::Token::Pound |
288288
token::Token::Dollar |
289289
token::Token::Question |
290-
token::Token::Underscore |
291290
token::Token::Whitespace |
292291
token::Token::Comment |
293292
token::Token::Eof => {}

Diff for: src/librustc_passes/ast_validation.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,17 @@ impl<'a> AstValidator<'a> {
3737
}
3838

3939
fn check_lifetime(&self, lifetime: &Lifetime) {
40-
let valid_names = [keywords::StaticLifetime.name(), keywords::Invalid.name()];
40+
let valid_names = [keywords::UnderscoreLifetime.name(),
41+
keywords::StaticLifetime.name(),
42+
keywords::Invalid.name()];
4143
if !valid_names.contains(&lifetime.ident.name) &&
4244
token::Ident(lifetime.ident.without_first_quote()).is_reserved_ident() {
4345
self.err_handler().span_err(lifetime.span, "lifetimes cannot use keyword names");
4446
}
4547
}
4648

4749
fn check_label(&self, label: Ident, span: Span) {
48-
if token::Ident(label.without_first_quote()).is_reserved_ident() || label.name == "'_" {
50+
if token::Ident(label.without_first_quote()).is_reserved_ident() {
4951
self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name));
5052
}
5153
}

Diff for: src/librustdoc/html/highlight.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ impl<'a> Classifier<'a> {
352352

353353
token::Lifetime(..) => Class::Lifetime,
354354

355-
token::Underscore | token::Eof | token::Interpolated(..) |
355+
token::Eof | token::Interpolated(..) |
356356
token::Tilde | token::At | token::DotEq => Class::None,
357357
};
358358

Diff for: src/libsyntax/diagnostics/plugin.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use ext::base::{ExtCtxt, MacEager, MacResult};
1919
use ext::build::AstBuilder;
2020
use parse::token;
2121
use ptr::P;
22-
use symbol::Symbol;
22+
use symbol::{keywords, Symbol};
2323
use tokenstream::{TokenTree};
2424
use util::small_vector::SmallVector;
2525

@@ -192,7 +192,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
192192
(descriptions.len(), ecx.expr_vec(span, descriptions))
193193
});
194194

195-
let static_ = ecx.lifetime(span, Ident::from_str("'static"));
195+
let static_ = ecx.lifetime(span, keywords::StaticLifetime.ident());
196196
let ty_str = ecx.ty_rptr(
197197
span,
198198
ecx.ty_ident(span, ecx.ident_of("str")),

Diff for: src/libsyntax/ext/quote.rs

-1
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,6 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
709709
token::Pound => "Pound",
710710
token::Dollar => "Dollar",
711711
token::Question => "Question",
712-
token::Underscore => "Underscore",
713712
token::Eof => "Eof",
714713

715714
token::Whitespace | token::Comment | token::Shebang(_) => {

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -765,8 +765,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
765765
Token::DotDotDot | // range pattern (future compat)
766766
Token::ModSep | // path
767767
Token::Lt | // path (UFCS constant)
768-
Token::BinOp(token::Shl) | // path (double UFCS)
769-
Token::Underscore => true, // placeholder
768+
Token::BinOp(token::Shl) => true, // path (double UFCS)
770769
Token::Interpolated(ref nt) => may_be_ident(&nt.0),
771770
_ => false,
772771
},

Diff for: src/libsyntax/feature_gate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1790,7 +1790,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
17901790
}
17911791

17921792
fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) {
1793-
if lt.ident.name == "'_" {
1793+
if lt.ident.name == keywords::UnderscoreLifetime.name() {
17941794
gate_feature_post!(&self, underscore_lifetimes, lt.span,
17951795
"underscore lifetimes are unstable");
17961796
}

Diff for: src/libsyntax/parse/lexer/mod.rs

+4-10
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub struct TokenAndSpan {
3434

3535
impl Default for TokenAndSpan {
3636
fn default() -> Self {
37-
TokenAndSpan { tok: token::Underscore, sp: syntax_pos::DUMMY_SP }
37+
TokenAndSpan { tok: token::Whitespace, sp: syntax_pos::DUMMY_SP }
3838
}
3939
}
4040

@@ -126,7 +126,7 @@ impl<'a> StringReader<'a> {
126126
pub fn try_next_token(&mut self) -> Result<TokenAndSpan, ()> {
127127
assert!(self.fatal_errs.is_empty());
128128
let ret_val = TokenAndSpan {
129-
tok: replace(&mut self.peek_tok, token::Underscore),
129+
tok: replace(&mut self.peek_tok, token::Whitespace),
130130
sp: self.peek_span,
131131
};
132132
self.advance_token()?;
@@ -1133,14 +1133,8 @@ impl<'a> StringReader<'a> {
11331133
self.bump();
11341134
}
11351135

1136-
return Ok(self.with_str_from(start, |string| {
1137-
if string == "_" {
1138-
token::Underscore
1139-
} else {
1140-
// FIXME: perform NFKC normalization here. (Issue #2253)
1141-
token::Ident(self.mk_ident(string))
1142-
}
1143-
}));
1136+
// FIXME: perform NFKC normalization here. (Issue #2253)
1137+
return Ok(self.with_str_from(start, |string| token::Ident(self.mk_ident(string))));
11441138
}
11451139

11461140
if is_dec_digit(c) {

Diff for: src/libsyntax/parse/parser.rs

+16-20
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ impl<'a> Parser<'a> {
549549
-> Self {
550550
let mut parser = Parser {
551551
sess,
552-
token: token::Underscore,
552+
token: token::Whitespace,
553553
span: syntax_pos::DUMMY_SP,
554554
prev_span: syntax_pos::DUMMY_SP,
555555
meta_var_span: None,
@@ -800,11 +800,7 @@ impl<'a> Parser<'a> {
800800
Err(if self.prev_token_kind == PrevTokenKind::DocComment {
801801
self.span_fatal_err(self.prev_span, Error::UselessDocComment)
802802
} else {
803-
let mut err = self.expected_ident_found();
804-
if self.token == token::Underscore {
805-
err.note("`_` is a wildcard pattern, not an identifier");
806-
}
807-
err
803+
self.expected_ident_found()
808804
})
809805
}
810806
}
@@ -1602,7 +1598,7 @@ impl<'a> Parser<'a> {
16021598
let e = self.parse_expr()?;
16031599
self.expect(&token::CloseDelim(token::Paren))?;
16041600
TyKind::Typeof(e)
1605-
} else if self.eat(&token::Underscore) {
1601+
} else if self.eat_keyword(keywords::Underscore) {
16061602
// A type to be inferred `_`
16071603
TyKind::Infer
16081604
} else if self.token_is_bare_fn_keyword() {
@@ -1796,7 +1792,7 @@ impl<'a> Parser<'a> {
17961792
_ => 0,
17971793
};
17981794

1799-
self.look_ahead(offset, |t| t.is_ident() || t == &token::Underscore) &&
1795+
self.look_ahead(offset, |t| t.is_ident()) &&
18001796
self.look_ahead(offset + 1, |t| t == &token::Colon)
18011797
}
18021798

@@ -2782,7 +2778,7 @@ impl<'a> Parser<'a> {
27822778
},
27832779
token::CloseDelim(_) | token::Eof => unreachable!(),
27842780
_ => {
2785-
let (token, span) = (mem::replace(&mut self.token, token::Underscore), self.span);
2781+
let (token, span) = (mem::replace(&mut self.token, token::Whitespace), self.span);
27862782
self.bump();
27872783
TokenTree::Token(span, token)
27882784
}
@@ -3815,11 +3811,6 @@ impl<'a> Parser<'a> {
38153811
let lo = self.span;
38163812
let pat;
38173813
match self.token {
3818-
token::Underscore => {
3819-
// Parse _
3820-
self.bump();
3821-
pat = PatKind::Wild;
3822-
}
38233814
token::BinOp(token::And) | token::AndAnd => {
38243815
// Parse &pat / &mut pat
38253816
self.expect_and()?;
@@ -3849,8 +3840,11 @@ impl<'a> Parser<'a> {
38493840
self.expect(&token::CloseDelim(token::Bracket))?;
38503841
pat = PatKind::Slice(before, slice, after);
38513842
}
3852-
// At this point, token != _, &, &&, (, [
3853-
_ => if self.eat_keyword(keywords::Mut) {
3843+
// At this point, token != &, &&, (, [
3844+
_ => if self.eat_keyword(keywords::Underscore) {
3845+
// Parse _
3846+
pat = PatKind::Wild;
3847+
} else if self.eat_keyword(keywords::Mut) {
38543848
// Parse mut ident @ pat / mut ref ident @ pat
38553849
let mutref_span = self.prev_span.to(self.span);
38563850
let binding_mode = if self.eat_keyword(keywords::Ref) {
@@ -7065,10 +7059,12 @@ impl<'a> Parser<'a> {
70657059

70667060
fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
70677061
if self.eat_keyword(keywords::As) {
7068-
if self.eat(&token::Underscore) {
7069-
Ok(Some(Ident::with_empty_ctxt(Symbol::gensym("_"))))
7070-
} else {
7071-
self.parse_ident().map(Some)
7062+
match self.token {
7063+
token::Ident(ident) if ident.name == keywords::Underscore.name() => {
7064+
self.bump(); // `_`
7065+
Ok(Some(Ident { name: ident.name.gensymed(), ..ident }))
7066+
}
7067+
_ => self.parse_ident().map(Some),
70727068
}
70737069
} else {
70747070
Ok(None)

Diff for: src/libsyntax/parse/token.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ fn ident_can_begin_type(ident: ast::Ident) -> bool {
122122
!ident_token.is_reserved_ident() ||
123123
ident_token.is_path_segment_keyword() ||
124124
[
125+
keywords::Underscore.name(),
125126
keywords::For.name(),
126127
keywords::Impl.name(),
127128
keywords::Fn.name(),
@@ -175,7 +176,6 @@ pub enum Token {
175176

176177
/* Name components */
177178
Ident(ast::Ident),
178-
Underscore,
179179
Lifetime(ast::Ident),
180180

181181
// The `LazyTokenStream` is a pure function of the `Nonterminal`,
@@ -242,7 +242,6 @@ impl Token {
242242
Ident(ident) => ident_can_begin_type(ident), // type name or keyword
243243
OpenDelim(Paren) | // tuple
244244
OpenDelim(Bracket) | // array
245-
Underscore | // placeholder
246245
Not | // never
247246
BinOp(Star) | // raw pointer
248247
BinOp(And) | // reference
@@ -371,7 +370,7 @@ impl Token {
371370
// unnamed method parameters, crate root module, error recovery etc.
372371
pub fn is_special_ident(&self) -> bool {
373372
match self.ident() {
374-
Some(id) => id.name <= keywords::DollarCrate.name(),
373+
Some(id) => id.name <= keywords::Underscore.name(),
375374
_ => false,
376375
}
377376
}
@@ -441,7 +440,7 @@ impl Token {
441440

442441
Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotEq |
443442
DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar |
444-
Question | OpenDelim(..) | CloseDelim(..) | Underscore => return None,
443+
Question | OpenDelim(..) | CloseDelim(..) => return None,
445444

446445
Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) |
447446
Whitespace | Comment | Shebang(..) | Eof => return None,
@@ -573,7 +572,7 @@ impl fmt::Debug for Nonterminal {
573572
pub fn is_op(tok: &Token) -> bool {
574573
match *tok {
575574
OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) |
576-
Ident(..) | Underscore | Lifetime(..) | Interpolated(..) |
575+
Ident(..) | Lifetime(..) | Interpolated(..) |
577576
Whitespace | Comment | Shebang(..) | Eof => false,
578577
_ => true,
579578
}

Diff for: src/libsyntax/print/pprust.rs

-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,6 @@ pub fn token_to_string(tok: &Token) -> String {
252252
/* Name components */
253253
token::Ident(s) => s.to_string(),
254254
token::Lifetime(s) => s.to_string(),
255-
token::Underscore => "_".to_string(),
256255

257256
/* Other */
258257
token::DocComment(s) => s.to_string(),

Diff for: src/libsyntax_ext/env.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use syntax::ast::{self, Ident};
1717
use syntax::ext::base::*;
1818
use syntax::ext::base;
1919
use syntax::ext::build::AstBuilder;
20-
use syntax::symbol::Symbol;
20+
use syntax::symbol::{keywords, Symbol};
2121
use syntax_pos::Span;
2222
use syntax::tokenstream;
2323

@@ -35,14 +35,14 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
3535
let sp = sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark));
3636
let e = match env::var(&*var.as_str()) {
3737
Err(..) => {
38+
let lt = cx.lifetime(sp, keywords::StaticLifetime.ident());
3839
cx.expr_path(cx.path_all(sp,
3940
true,
4041
cx.std_path(&["option", "Option", "None"]),
4142
Vec::new(),
4243
vec![cx.ty_rptr(sp,
4344
cx.ty_ident(sp, Ident::from_str("str")),
44-
Some(cx.lifetime(sp,
45-
Ident::from_str("'static"))),
45+
Some(lt),
4646
ast::Mutability::Immutable)],
4747
Vec::new()))
4848
}

0 commit comments

Comments
 (0)