diff options
| author | bors <bors@rust-lang.org> | 2017-12-07 21:05:49 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-12-07 21:05:49 +0000 |
| commit | c8ddf28527119a06a9f5da9bd34c97ae97afe531 (patch) | |
| tree | 458cdc07ce837e57058f2613e8e92e036d5251da | |
| parent | 9c49f401fecd8c5ef42a33a070a61daa2b911b47 (diff) | |
| parent | 29e268060209765e5a9efb4c0941765d064e13ea (diff) | |
| download | rust-c8ddf28527119a06a9f5da9bd34c97ae97afe531.tar.gz rust-c8ddf28527119a06a9f5da9bd34c97ae97afe531.zip | |
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.
| -rw-r--r-- | src/librustc_passes/ast_validation.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax_pos/symbol.rs | 10 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-10412.rs (renamed from src/test/parse-fail/issue-10412.rs) | 6 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-46311.rs | 14 | ||||
| -rw-r--r-- | src/test/compile-fail/lifetime-no-keyword.rs (renamed from src/test/parse-fail/lifetime-no-keyword.rs) | 9 |
6 files changed, 46 insertions, 23 deletions
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 97cea5c9d64..05ad1643619 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -21,6 +21,7 @@ use rustc::session::Session; use syntax::ast::*; use syntax::attr; use syntax::codemap::Spanned; +use syntax::parse::token; use syntax::symbol::keywords; use syntax::visit::{self, Visitor}; use syntax_pos::Span; @@ -35,8 +36,16 @@ impl<'a> AstValidator<'a> { &self.session.parse_sess.span_diagnostic } + fn check_lifetime(&self, lifetime: &Lifetime) { + let valid_names = [keywords::StaticLifetime.name(), keywords::Invalid.name()]; + if !valid_names.contains(&lifetime.ident.name) && + token::Ident(lifetime.ident.without_first_quote()).is_reserved_ident() { + self.err_handler().span_err(lifetime.span, "lifetimes cannot use keyword names"); + } + } + fn check_label(&self, label: Ident, span: Span) { - if label.name == keywords::StaticLifetime.name() || label.name == "'_" { + if token::Ident(label.without_first_quote()).is_reserved_ident() || label.name == "'_" { self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name)); } } @@ -200,6 +209,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_use_tree(self, use_tree, id); } + fn visit_lifetime(&mut self, lifetime: &'a Lifetime) { + self.check_lifetime(lifetime); + visit::walk_lifetime(self, lifetime); + } + fn visit_item(&mut self, item: &'a Item) { match item.node { ItemKind::Impl(.., Some(..), _, ref impl_items) => { diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 6f20104dda5..d9c33fa50bd 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -14,7 +14,7 @@ use codemap::{CodeMap, FilePathMapping}; use errors::{FatalError, DiagnosticBuilder}; use parse::{token, ParseSess}; use str::char_at; -use symbol::{Symbol, keywords}; +use symbol::Symbol; use std_unicode::property::Pattern_White_Space; use std::borrow::Cow; @@ -1296,18 +1296,6 @@ impl<'a> StringReader<'a> { self.mk_ident(&format!("'{}", lifetime_name)) }); - // Conjure up a "keyword checking ident" to make sure that - // the lifetime name is not a keyword. - let keyword_checking_ident = self.with_str_from(start, |lifetime_name| { - self.mk_ident(lifetime_name) - }); - let keyword_checking_token = &token::Ident(keyword_checking_ident); - let last_bpos = self.pos; - if keyword_checking_token.is_reserved_ident() && - !keyword_checking_token.is_keyword(keywords::Static) { - self.err_span_(start, last_bpos, "lifetimes cannot use keyword names"); - } - return Ok(token::Lifetime(ident)); } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 72760360711..aafdd696b74 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -35,6 +35,10 @@ impl Ident { Ident::with_empty_ctxt(Symbol::intern(string)) } + pub fn without_first_quote(&self) -> Ident { + Ident { name: Symbol::from(self.name.as_str().trim_left_matches('\'')), ctxt: self.ctxt } + } + pub fn modern(self) -> Ident { Ident { name: self.name, ctxt: self.ctxt.modern() } } @@ -437,4 +441,10 @@ mod tests { // gensym of *existing* string gets new number: assert_eq!(i.gensym("dog"), Symbol(4294967293)); } + + #[test] + fn without_first_quote_test() { + let i = Ident::from_str("'break"); + assert_eq!(i.without_first_quote().name, keywords::Break.name()); + } } diff --git a/src/test/parse-fail/issue-10412.rs b/src/test/compile-fail/issue-10412.rs index d723d94c02c..ee553730a35 100644 --- a/src/test/parse-fail/issue-10412.rs +++ b/src/test/compile-fail/issue-10412.rs @@ -8,16 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z parse-only -Z continue-parse-after-error - - trait Serializable<'self, T> { //~ ERROR lifetimes cannot use keyword names - fn serialize(val : &'self T) -> Vec<u8> ; //~ ERROR lifetimes cannot use keyword names + fn serialize(val : &'self T) -> Vec<u8>; //~ ERROR lifetimes cannot use keyword names fn deserialize(repr : &[u8]) -> &'self T; //~ ERROR lifetimes cannot use keyword names } impl<'self> Serializable<str> for &'self str { //~ ERROR lifetimes cannot use keyword names //~^ ERROR lifetimes cannot use keyword names + //~| ERROR missing lifetime specifier fn serialize(val : &'self str) -> Vec<u8> { //~ ERROR lifetimes cannot use keyword names vec![1] } diff --git a/src/test/compile-fail/issue-46311.rs b/src/test/compile-fail/issue-46311.rs new file mode 100644 index 00000000000..82f55f2c142 --- /dev/null +++ b/src/test/compile-fail/issue-46311.rs @@ -0,0 +1,14 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + 'break: loop { //~ ERROR invalid label name `'break` + } +} diff --git a/src/test/parse-fail/lifetime-no-keyword.rs b/src/test/compile-fail/lifetime-no-keyword.rs index a8771ae93af..d583c4fc6c6 100644 --- a/src/test/parse-fail/lifetime-no-keyword.rs +++ b/src/test/compile-fail/lifetime-no-keyword.rs @@ -8,11 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z parse-only -Z continue-parse-after-error - fn foo<'a>(a: &'a isize) { } fn bar(a: &'static isize) { } -fn baz(a: &'let isize) { } //~ ERROR lifetimes cannot use keyword names -fn zab(a: &'self isize) { } //~ ERROR lifetimes cannot use keyword names - +fn baz<'let>(a: &'let isize) { } //~ ERROR lifetimes cannot use keyword names +//~^ ERROR lifetimes cannot use keyword names +fn zab<'self>(a: &'self isize) { } //~ ERROR lifetimes cannot use keyword names +//~^ ERROR lifetimes cannot use keyword names fn main() { } |
