about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-12-07 21:05:49 +0000
committerbors <bors@rust-lang.org>2017-12-07 21:05:49 +0000
commitc8ddf28527119a06a9f5da9bd34c97ae97afe531 (patch)
tree458cdc07ce837e57058f2613e8e92e036d5251da
parent9c49f401fecd8c5ef42a33a070a61daa2b911b47 (diff)
parent29e268060209765e5a9efb4c0941765d064e13ea (diff)
downloadrust-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.rs16
-rw-r--r--src/libsyntax/parse/lexer/mod.rs14
-rw-r--r--src/libsyntax_pos/symbol.rs10
-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.rs14
-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() { }