Skip to content

Commit c8ddf28

Browse files
committed
Auto merge of #46497 - AgustinCB:issue-46311, r=petrochenkov
Modify message for keyword as identifier name This is a temporary solution to #46311. The message is generic enough to cover both cases and is probably a fine enough solution to the specific problem described in the task. However, the underlying reason for this to be wrong is that `next_token_inner` returns `Lifetime` even if the token is a label. That's not simple, as the syntax for both can be quite similar and it may need to take a look to the next token to make a decision. I'm not sure I have enough knowledge about the project to be able to solve that (yet!), so I thought I'll fix the immediate problem first.
2 parents 9c49f40 + 29e2680 commit c8ddf28

File tree

6 files changed

+46
-23
lines changed

6 files changed

+46
-23
lines changed

src/librustc_passes/ast_validation.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc::session::Session;
2121
use syntax::ast::*;
2222
use syntax::attr;
2323
use syntax::codemap::Spanned;
24+
use syntax::parse::token;
2425
use syntax::symbol::keywords;
2526
use syntax::visit::{self, Visitor};
2627
use syntax_pos::Span;
@@ -35,8 +36,16 @@ impl<'a> AstValidator<'a> {
3536
&self.session.parse_sess.span_diagnostic
3637
}
3738

39+
fn check_lifetime(&self, lifetime: &Lifetime) {
40+
let valid_names = [keywords::StaticLifetime.name(), keywords::Invalid.name()];
41+
if !valid_names.contains(&lifetime.ident.name) &&
42+
token::Ident(lifetime.ident.without_first_quote()).is_reserved_ident() {
43+
self.err_handler().span_err(lifetime.span, "lifetimes cannot use keyword names");
44+
}
45+
}
46+
3847
fn check_label(&self, label: Ident, span: Span) {
39-
if label.name == keywords::StaticLifetime.name() || label.name == "'_" {
48+
if token::Ident(label.without_first_quote()).is_reserved_ident() || label.name == "'_" {
4049
self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name));
4150
}
4251
}
@@ -200,6 +209,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
200209
visit::walk_use_tree(self, use_tree, id);
201210
}
202211

212+
fn visit_lifetime(&mut self, lifetime: &'a Lifetime) {
213+
self.check_lifetime(lifetime);
214+
visit::walk_lifetime(self, lifetime);
215+
}
216+
203217
fn visit_item(&mut self, item: &'a Item) {
204218
match item.node {
205219
ItemKind::Impl(.., Some(..), _, ref impl_items) => {

src/libsyntax/parse/lexer/mod.rs

+1-13
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use codemap::{CodeMap, FilePathMapping};
1414
use errors::{FatalError, DiagnosticBuilder};
1515
use parse::{token, ParseSess};
1616
use str::char_at;
17-
use symbol::{Symbol, keywords};
17+
use symbol::Symbol;
1818
use std_unicode::property::Pattern_White_Space;
1919

2020
use std::borrow::Cow;
@@ -1296,18 +1296,6 @@ impl<'a> StringReader<'a> {
12961296
self.mk_ident(&format!("'{}", lifetime_name))
12971297
});
12981298

1299-
// Conjure up a "keyword checking ident" to make sure that
1300-
// the lifetime name is not a keyword.
1301-
let keyword_checking_ident = self.with_str_from(start, |lifetime_name| {
1302-
self.mk_ident(lifetime_name)
1303-
});
1304-
let keyword_checking_token = &token::Ident(keyword_checking_ident);
1305-
let last_bpos = self.pos;
1306-
if keyword_checking_token.is_reserved_ident() &&
1307-
!keyword_checking_token.is_keyword(keywords::Static) {
1308-
self.err_span_(start, last_bpos, "lifetimes cannot use keyword names");
1309-
}
1310-
13111299
return Ok(token::Lifetime(ident));
13121300
}
13131301

src/libsyntax_pos/symbol.rs

+10
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ impl Ident {
3535
Ident::with_empty_ctxt(Symbol::intern(string))
3636
}
3737

38+
pub fn without_first_quote(&self) -> Ident {
39+
Ident { name: Symbol::from(self.name.as_str().trim_left_matches('\'')), ctxt: self.ctxt }
40+
}
41+
3842
pub fn modern(self) -> Ident {
3943
Ident { name: self.name, ctxt: self.ctxt.modern() }
4044
}
@@ -437,4 +441,10 @@ mod tests {
437441
// gensym of *existing* string gets new number:
438442
assert_eq!(i.gensym("dog"), Symbol(4294967293));
439443
}
444+
445+
#[test]
446+
fn without_first_quote_test() {
447+
let i = Ident::from_str("'break");
448+
assert_eq!(i.without_first_quote().name, keywords::Break.name());
449+
}
440450
}

src/test/parse-fail/issue-10412.rs renamed to src/test/compile-fail/issue-10412.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,14 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// compile-flags: -Z parse-only -Z continue-parse-after-error
12-
13-
1411
trait Serializable<'self, T> { //~ ERROR lifetimes cannot use keyword names
15-
fn serialize(val : &'self T) -> Vec<u8> ; //~ ERROR lifetimes cannot use keyword names
12+
fn serialize(val : &'self T) -> Vec<u8>; //~ ERROR lifetimes cannot use keyword names
1613
fn deserialize(repr : &[u8]) -> &'self T; //~ ERROR lifetimes cannot use keyword names
1714
}
1815

1916
impl<'self> Serializable<str> for &'self str { //~ ERROR lifetimes cannot use keyword names
2017
//~^ ERROR lifetimes cannot use keyword names
18+
//~| ERROR missing lifetime specifier
2119
fn serialize(val : &'self str) -> Vec<u8> { //~ ERROR lifetimes cannot use keyword names
2220
vec![1]
2321
}

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

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2012-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+
fn main() {
12+
'break: loop { //~ ERROR invalid label name `'break`
13+
}
14+
}

src/test/parse-fail/lifetime-no-keyword.rs renamed to src/test/compile-fail/lifetime-no-keyword.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// compile-flags: -Z parse-only -Z continue-parse-after-error
12-
1311
fn foo<'a>(a: &'a isize) { }
1412
fn bar(a: &'static isize) { }
15-
fn baz(a: &'let isize) { } //~ ERROR lifetimes cannot use keyword names
16-
fn zab(a: &'self isize) { } //~ ERROR lifetimes cannot use keyword names
17-
13+
fn baz<'let>(a: &'let isize) { } //~ ERROR lifetimes cannot use keyword names
14+
//~^ ERROR lifetimes cannot use keyword names
15+
fn zab<'self>(a: &'self isize) { } //~ ERROR lifetimes cannot use keyword names
16+
//~^ ERROR lifetimes cannot use keyword names
1817
fn main() { }

0 commit comments

Comments
 (0)