]> git.lizzy.rs Git - rust.git/commitdiff
Generalize `async_idents` to all new keywords
authorAlex Crichton <alex@alexcrichton.com>
Fri, 24 Aug 2018 20:48:20 +0000 (13:48 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 29 Aug 2018 16:34:53 +0000 (09:34 -0700)
This commit generalizes the existing `async_idents` lint to easily encompass
other identifiers that will be keywords in future editions. The new lint is
called `keyword_idents` and the old `async_idents` lint is registered as renamed
to this new lint.

As a proof of concept the `try` keyword was added to this list as it looks to be
listed as a keyword in the 2018 edition only. The `await` keyword was not added
as it's not listed as a keyword yet.

Closes #53077

14 files changed:
src/librustc/lint/context.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/test/ui/editions/auxiliary/edition-kw-macro-2015.rs
src/test/ui/editions/auxiliary/edition-kw-macro-2018.rs
src/test/ui/editions/edition-keywords-2015-2015-expansion.rs
src/test/ui/editions/edition-keywords-2018-2015-expansion.rs
src/test/ui/rust-2018/async-ident-allowed.stderr
src/test/ui/rust-2018/async-ident.fixed
src/test/ui/rust-2018/async-ident.rs
src/test/ui/rust-2018/async-ident.stderr
src/test/ui/rust-2018/try-ident.fixed [new file with mode: 0644]
src/test/ui/rust-2018/try-ident.rs [new file with mode: 0644]
src/test/ui/rust-2018/try-ident.stderr [new file with mode: 0644]

index 315ed38ad07703fc14566a3efe808490d6253826..5cc862a58d35a3496875452086b834902c33409b 100644 (file)
@@ -1046,7 +1046,7 @@ fn visit_mac_def(&mut self, mac: &'a ast::MacroDef, id: ast::NodeId) {
         self.check_id(id);
     }
 
-    fn visit_mac(&mut self, mac: &'ast ast::Mac) {
+    fn visit_mac(&mut self, mac: &'a ast::Mac) {
         run_lints!(self, check_mac, mac);
     }
 }
index c497627415f1ac3abde1a981ec437911f926b076..16aa80c34cc1bcad120bc5307bc46ba2893f2e7a 100644 (file)
@@ -46,6 +46,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map::Spanned;
+use syntax::edition::Edition;
 use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes};
 use syntax_pos::{BytePos, Span, SyntaxContext};
 use syntax::symbol::keywords;
@@ -1876,30 +1877,33 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
 }
 
 declare_lint! {
-    pub ASYNC_IDENTS,
+    pub KEYWORD_IDENTS,
     Allow,
-    "detects `async` being used as an identifier"
+    "detects edition keywords being used as an identifier"
 }
 
-/// Checks for uses of `async` as an identifier
+/// Checks for uses of edtion keywords used as an identifier
 #[derive(Clone)]
-pub struct Async2018;
+pub struct KeywordIdents;
 
-impl LintPass for Async2018 {
+impl LintPass for KeywordIdents {
     fn get_lints(&self) -> LintArray {
-        lint_array!(ASYNC_IDENTS)
+        lint_array!(KEYWORD_IDENTS)
     }
 }
 
-impl Async2018 {
+impl KeywordIdents {
     fn check_tokens(&mut self, cx: &EarlyContext, tokens: TokenStream) {
         for tt in tokens.into_trees() {
             match tt {
                 TokenTree::Token(span, tok) => match tok.ident() {
                     // only report non-raw idents
-                    Some((ident, false)) if ident.as_str() == "async" => {
-                        self.report(cx, span.substitute_dummy(ident.span))
-                    },
+                    Some((ident, false)) => {
+                        self.check_ident(cx, ast::Ident {
+                            span: span.substitute_dummy(ident.span),
+                            ..ident
+                        });
+                    }
                     _ => {},
                 }
                 TokenTree::Delimited(_, ref delim) => {
@@ -1908,29 +1912,9 @@ fn check_tokens(&mut self, cx: &EarlyContext, tokens: TokenStream) {
             }
         }
     }
-    fn report(&mut self, cx: &EarlyContext, span: Span) {
-        // don't lint `r#async`
-        if cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&span) {
-            return;
-        }
-        let mut lint = cx.struct_span_lint(
-            ASYNC_IDENTS,
-            span,
-            "`async` is a keyword in the 2018 edition",
-        );
-
-        // Don't suggest about raw identifiers if the feature isn't active
-        lint.span_suggestion_with_applicability(
-            span,
-            "you can use a raw identifier to stay compatible",
-            "r#async".to_string(),
-            Applicability::MachineApplicable,
-        );
-        lint.emit()
-    }
 }
 
-impl EarlyLintPass for Async2018 {
+impl EarlyLintPass for KeywordIdents {
     fn check_mac_def(&mut self, cx: &EarlyContext, mac_def: &ast::MacroDef, _id: ast::NodeId) {
         self.check_tokens(cx, mac_def.stream());
     }
@@ -1938,8 +1922,37 @@ fn check_mac(&mut self, cx: &EarlyContext, mac: &ast::Mac) {
         self.check_tokens(cx, mac.node.tts.clone().into());
     }
     fn check_ident(&mut self, cx: &EarlyContext, ident: ast::Ident) {
-        if ident.as_str() == "async" {
-            self.report(cx, ident.span);
+        let next_edition = match cx.sess.edition() {
+            Edition::Edition2015 => {
+                match &ident.as_str()[..] {
+                    "async" |
+                    "try" => Edition::Edition2018,
+                    _ => return,
+                }
+            }
+
+            // no new keywords yet for 2018 edition and beyond
+            _ => return,
+        };
+
+        // don't lint `r#foo`
+        if cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&ident.span) {
+            return;
         }
+
+        let mut lint = cx.struct_span_lint(
+            KEYWORD_IDENTS,
+            ident.span,
+            &format!("`{}` is a keyword in the {} edition",
+                     ident.as_str(),
+                     next_edition),
+        );
+        lint.span_suggestion_with_applicability(
+            ident.span,
+            "you can use a raw identifier to stay compatible",
+            format!("r#{}", ident.as_str()),
+            Applicability::MachineApplicable,
+        );
+        lint.emit()
     }
 }
index 05b11e3ba3a4c82a2de48a483a2795b091a36f7a..39abfee5fb9ec851c9d99f23817256857c303262 100644 (file)
@@ -110,7 +110,7 @@ macro_rules! add_lint_group {
     }
 
     add_pre_expansion_builtin!(sess,
-        Async2018,
+        KeywordIdents,
     );
 
     add_early_builtin!(sess,
@@ -240,7 +240,7 @@ macro_rules! add_lint_group {
             edition: Some(Edition::Edition2018),
         },
         FutureIncompatibleInfo {
-            id: LintId::of(ASYNC_IDENTS),
+            id: LintId::of(KEYWORD_IDENTS),
             reference: "issue #49716 <https://github.com/rust-lang/rust/issues/49716>",
             edition: Some(Edition::Edition2018),
         },
@@ -349,6 +349,7 @@ macro_rules! add_lint_group {
     store.register_renamed("bare_trait_object", "bare_trait_objects");
     store.register_renamed("unstable_name_collision", "unstable_name_collisions");
     store.register_renamed("unused_doc_comment", "unused_doc_comments");
+    store.register_renamed("async_idents", "keyword_idents");
     store.register_removed("unknown_features", "replaced by an error");
     store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate");
     store.register_removed("negate_unsigned", "cast a signed value instead");
index 5b8832ddaf27ca4496335a43e3f400b367965ae2..9343312fdd84f91953475818cb627f318d1b79ab 100644 (file)
@@ -10,7 +10,7 @@
 
 // edition:2015
 
-#![allow(async_idents)]
+#![allow(keyword_idents)]
 
 #[macro_export]
 macro_rules! produces_async {
index 85ef15858fe912a02e3ae906f6a9ea4c6708d482..19a7b91624fe339b6b8791060ea21fd06fa8bb2d 100644 (file)
@@ -10,7 +10,7 @@
 
 // edition:2018
 
-#![allow(async_idents)]
+#![allow(keyword_idents)]
 
 #[macro_export]
 macro_rules! produces_async {
index a9037a50ecb6b94c6f87b9d6494854f7693230cc..382c7c1f325a3bf5b8acbbd5bf3d698096bda345 100644 (file)
@@ -12,7 +12,7 @@
 // aux-build:edition-kw-macro-2015.rs
 // compile-pass
 
-#![allow(async_idents)]
+#![allow(keyword_idents)]
 
 #[macro_use]
 extern crate edition_kw_macro_2015;
index 911dcd855aad6c2fb21e68161e24fc2368558f55..46434daaab9244c12cce7dad984684c326cd8f8f 100644 (file)
@@ -12,7 +12,7 @@
 // aux-build:edition-kw-macro-2015.rs
 // compile-pass
 
-#![allow(async_idents)]
+#![allow(keyword_idents)]
 
 #[macro_use]
 extern crate edition_kw_macro_2015;
index 741c1c70209bc91f60d9703bbc8e4d0daa112297..68d7930e0434af4eb2cfbcabd0f1ff39cae27469 100644 (file)
@@ -9,7 +9,7 @@ note: lint level defined here
    |
 LL | #![deny(rust_2018_compatibility)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
-   = note: #[deny(async_idents)] implied by #[deny(rust_2018_compatibility)]
+   = note: #[deny(keyword_idents)] implied by #[deny(rust_2018_compatibility)]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
index 15b8eec3bea99071182c90165c9b98726682d97a..ef88f835fc83d1fc454d2903c81fc39b1fde44ab 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![allow(dead_code, unused_variables, non_camel_case_types, non_upper_case_globals)]
-#![deny(async_idents)]
+#![deny(keyword_idents)]
 
 // edition:2015
 // run-rustfix
index 6087d2c16423ea7c537299e8acfcb4361ba97a66..069da7ffcdd4dd4ecd8f594d0994d7dcf7182ff6 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![allow(dead_code, unused_variables, non_camel_case_types, non_upper_case_globals)]
-#![deny(async_idents)]
+#![deny(keyword_idents)]
 
 // edition:2015
 // run-rustfix
index 06d68a38c5f381769660947e68890b095603596e..b9bb2e254b44e0fa008efd0e3325382156aa91bf 100644 (file)
@@ -7,8 +7,8 @@ LL | fn async() {} //~ ERROR async
 note: lint level defined here
   --> $DIR/async-ident.rs:12:9
    |
-LL | #![deny(async_idents)]
-   |         ^^^^^^^^^^^^
+LL | #![deny(keyword_idents)]
+   |         ^^^^^^^^^^^^^^
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
diff --git a/src/test/ui/rust-2018/try-ident.fixed b/src/test/ui/rust-2018/try-ident.fixed
new file mode 100644 (file)
index 0000000..96a0cd0
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+// run-rustfix
+// compile-pass
+
+#![warn(rust_2018_compatibility)]
+
+fn main() {
+    r#try();
+}
+
+fn r#try() {
+}
diff --git a/src/test/ui/rust-2018/try-ident.rs b/src/test/ui/rust-2018/try-ident.rs
new file mode 100644 (file)
index 0000000..ade2e03
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+// run-rustfix
+// compile-pass
+
+#![warn(rust_2018_compatibility)]
+
+fn main() {
+    try();
+}
+
+fn try() {
+}
diff --git a/src/test/ui/rust-2018/try-ident.stderr b/src/test/ui/rust-2018/try-ident.stderr
new file mode 100644 (file)
index 0000000..72bd815
--- /dev/null
@@ -0,0 +1,24 @@
+warning: `try` is a keyword in the 2018 edition
+  --> $DIR/try-ident.rs:17:5
+   |
+LL |     try();
+   |     ^^^ help: you can use a raw identifier to stay compatible: `r#try`
+   |
+note: lint level defined here
+  --> $DIR/try-ident.rs:14:9
+   |
+LL | #![warn(rust_2018_compatibility)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   = note: #[warn(keyword_idents)] implied by #[warn(rust_2018_compatibility)]
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+warning: `try` is a keyword in the 2018 edition
+  --> $DIR/try-ident.rs:20:4
+   |
+LL | fn try() {
+   |    ^^^ help: you can use a raw identifier to stay compatible: `r#try`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+