about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-09-25 15:20:10 +0000
committerbors <bors@rust-lang.org>2018-09-25 15:20:10 +0000
commit31789a658bb6b6c78da1f2b99a5f169e4e8b983b (patch)
tree4cf36212dc830154f9c581e3b196652bd82b62c4
parentae366637fedf6f34185e54fc7b2d725b1a458ff6 (diff)
parentfb14662e74d6fb2e99d73525bf46931a05ce974a (diff)
downloadrust-31789a658bb6b6c78da1f2b99a5f169e4e8b983b.tar.gz
rust-31789a658bb6b6c78da1f2b99a5f169e4e8b983b.zip
Auto merge of #54411 - cramertj:await-keyword-error, r=nikomatsakis
Make "await" a pseudo-edition keyword

This change makes "await" ident an error in 2018 edition without async_await
feature and adds "await" to the 2018 edition keyword lint group that
suggest migration on the 2015 edition.

cc https://github.com/rust-lang/rust/issues/53834

r? @nikomatsakis
-rw-r--r--src/librustc_lint/builtin.rs40
-rw-r--r--src/librustc_lint/diagnostics.rs13
-rw-r--r--src/librustc_lint/lib.rs2
-rw-r--r--src/test/ui/await-keyword/2015-edition-no-warnings-with-feature-gate.rs16
-rw-r--r--src/test/ui/await-keyword/2015-edition-warning.fixed15
-rw-r--r--src/test/ui/await-keyword/2015-edition-warning.rs15
-rw-r--r--src/test/ui/await-keyword/2015-edition-warning.stderr61
-rw-r--r--src/test/ui/await-keyword/2018-edition-error.rs13
-rw-r--r--src/test/ui/await-keyword/2018-edition-error.stderr39
-rw-r--r--src/test/ui/await-keyword/2018-edition-no-error-with-feature-gate.rs16
-rw-r--r--src/test/ui/await-keyword/post_expansion_error.rs9
-rw-r--r--src/test/ui/await-keyword/post_expansion_error.stderr9
12 files changed, 244 insertions, 4 deletions
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index a169736d853..adf23a5cf2c 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1934,20 +1934,52 @@ impl EarlyLintPass for KeywordIdents {
         self.check_tokens(cx, mac.node.tts.clone().into());
     }
     fn check_ident(&mut self, cx: &EarlyContext, ident: ast::Ident) {
-        let next_edition = match cx.sess.edition() {
+        let ident_str = &ident.as_str()[..];
+        let cur_edition = cx.sess.edition();
+        let is_raw_ident = |ident: ast::Ident| {
+            cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&ident.span)
+        };
+        let next_edition = match cur_edition {
             Edition::Edition2015 => {
-                match &ident.as_str()[..] {
+                match ident_str {
                     "async" | "try" | "dyn" => Edition::Edition2018,
+                    // Only issue warnings for `await` if the `async_await`
+                    // feature isn't being used. Otherwise, users need
+                    // to keep using `await` for the macro exposed by std.
+                    "await" if !cx.sess.features_untracked().async_await => Edition::Edition2018,
                     _ => return,
                 }
             }
 
             // no new keywords yet for 2018 edition and beyond
-            _ => return,
+            // However, `await` is a "false" keyword in the 2018 edition,
+            // and can only be used if the `async_await` feature is enabled.
+            // Otherwise, we emit an error.
+            _ => {
+                if "await" == ident_str
+                    && !cx.sess.features_untracked().async_await
+                    && !is_raw_ident(ident)
+                {
+                    let mut err = struct_span_err!(
+                        cx.sess,
+                        ident.span,
+                        E0721,
+                        "`await` is a keyword in the {} edition", cur_edition,
+                    );
+                    err.span_suggestion_with_applicability(
+                        ident.span,
+                        "you can use a raw identifier to stay compatible",
+                        "r#await".to_string(),
+                        Applicability::MachineApplicable,
+                    );
+                    err.emit();
+                }
+                return
+            },
         };
 
         // don't lint `r#foo`
-        if cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&ident.span) {
+        if is_raw_ident(ident) {
             return;
         }
 
diff --git a/src/librustc_lint/diagnostics.rs b/src/librustc_lint/diagnostics.rs
new file mode 100644
index 00000000000..59f005a5de8
--- /dev/null
+++ b/src/librustc_lint/diagnostics.rs
@@ -0,0 +1,13 @@
+// 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.
+
+register_diagnostics! {
+    E0721, // `await` keyword
+}
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 9ed69a2dc9b..9e2e3435bd9 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -32,6 +32,7 @@
 #![feature(rustc_diagnostic_macros)]
 #![feature(macro_at_most_once_rep)]
 
+#[macro_use]
 extern crate syntax;
 #[macro_use]
 extern crate rustc;
@@ -61,6 +62,7 @@ use syntax::edition::Edition;
 use lint::LintId;
 use lint::FutureIncompatibleInfo;
 
+mod diagnostics;
 mod nonstandard_style;
 pub mod builtin;
 mod types;
diff --git a/src/test/ui/await-keyword/2015-edition-no-warnings-with-feature-gate.rs b/src/test/ui/await-keyword/2015-edition-no-warnings-with-feature-gate.rs
new file mode 100644
index 00000000000..92c60e7d6ee
--- /dev/null
+++ b/src/test/ui/await-keyword/2015-edition-no-warnings-with-feature-gate.rs
@@ -0,0 +1,16 @@
+// compile-pass
+
+#![feature(async_await)]
+#![allow(non_camel_case_types)]
+#![deny(keyword_idents)]
+
+mod outer_mod {
+    pub mod await {
+        pub struct await;
+    }
+}
+use outer_mod::await::await;
+
+fn main() {
+    match await { await => {} }
+}
diff --git a/src/test/ui/await-keyword/2015-edition-warning.fixed b/src/test/ui/await-keyword/2015-edition-warning.fixed
new file mode 100644
index 00000000000..c2c40cd11a6
--- /dev/null
+++ b/src/test/ui/await-keyword/2015-edition-warning.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+
+#![allow(non_camel_case_types)]
+#![deny(keyword_idents)]
+
+mod outer_mod {
+    pub mod r#await {
+        pub struct r#await;
+    }
+}
+use outer_mod::r#await::r#await;
+
+fn main() {
+    match r#await { r#await => {} }
+}
diff --git a/src/test/ui/await-keyword/2015-edition-warning.rs b/src/test/ui/await-keyword/2015-edition-warning.rs
new file mode 100644
index 00000000000..95539ab29dc
--- /dev/null
+++ b/src/test/ui/await-keyword/2015-edition-warning.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+
+#![allow(non_camel_case_types)]
+#![deny(keyword_idents)]
+
+mod outer_mod {
+    pub mod await {
+        pub struct await;
+    }
+}
+use outer_mod::await::await;
+
+fn main() {
+    match await { await => {} }
+}
diff --git a/src/test/ui/await-keyword/2015-edition-warning.stderr b/src/test/ui/await-keyword/2015-edition-warning.stderr
new file mode 100644
index 00000000000..073e9d7e6d0
--- /dev/null
+++ b/src/test/ui/await-keyword/2015-edition-warning.stderr
@@ -0,0 +1,61 @@
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:7:13
+   |
+LL |     pub mod await {
+   |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+note: lint level defined here
+  --> $DIR/2015-edition-warning.rs:4:9
+   |
+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>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:8:20
+   |
+LL |         pub struct await;
+   |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = 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>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:11:16
+   |
+LL | use outer_mod::await::await;
+   |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = 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>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:11:23
+   |
+LL | use outer_mod::await::await;
+   |                       ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = 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>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:14:11
+   |
+LL |     match await { await => {} }
+   |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = 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>
+
+error: `await` is a keyword in the 2018 edition
+  --> $DIR/2015-edition-warning.rs:14:19
+   |
+LL |     match await { await => {} }
+   |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+   |
+   = 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>
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/await-keyword/2018-edition-error.rs b/src/test/ui/await-keyword/2018-edition-error.rs
new file mode 100644
index 00000000000..a9e2e3f79ee
--- /dev/null
+++ b/src/test/ui/await-keyword/2018-edition-error.rs
@@ -0,0 +1,13 @@
+// edition:2018
+#![allow(non_camel_case_types)]
+
+mod outer_mod {
+    pub mod await {
+        pub struct await;
+    }
+}
+use self::outer_mod::await::await;
+
+fn main() {
+    match await { await => () }
+}
diff --git a/src/test/ui/await-keyword/2018-edition-error.stderr b/src/test/ui/await-keyword/2018-edition-error.stderr
new file mode 100644
index 00000000000..d5727b8db37
--- /dev/null
+++ b/src/test/ui/await-keyword/2018-edition-error.stderr
@@ -0,0 +1,39 @@
+error[E0721]: `await` is a keyword in the 2018 edition
+  --> $DIR/2018-edition-error.rs:5:13
+   |
+LL |     pub mod await {
+   |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+
+error[E0721]: `await` is a keyword in the 2018 edition
+  --> $DIR/2018-edition-error.rs:6:20
+   |
+LL |         pub struct await;
+   |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+
+error[E0721]: `await` is a keyword in the 2018 edition
+  --> $DIR/2018-edition-error.rs:9:22
+   |
+LL | use self::outer_mod::await::await;
+   |                      ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+
+error[E0721]: `await` is a keyword in the 2018 edition
+  --> $DIR/2018-edition-error.rs:9:29
+   |
+LL | use self::outer_mod::await::await;
+   |                             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+
+error[E0721]: `await` is a keyword in the 2018 edition
+  --> $DIR/2018-edition-error.rs:12:11
+   |
+LL |     match await { await => () }
+   |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+
+error[E0721]: `await` is a keyword in the 2018 edition
+  --> $DIR/2018-edition-error.rs:12:19
+   |
+LL |     match await { await => () }
+   |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0721`.
diff --git a/src/test/ui/await-keyword/2018-edition-no-error-with-feature-gate.rs b/src/test/ui/await-keyword/2018-edition-no-error-with-feature-gate.rs
new file mode 100644
index 00000000000..52d32c83510
--- /dev/null
+++ b/src/test/ui/await-keyword/2018-edition-no-error-with-feature-gate.rs
@@ -0,0 +1,16 @@
+// compile-pass
+// edition:2018
+
+#![allow(non_camel_case_types)]
+#![feature(async_await)]
+
+mod outer_mod {
+    pub mod await {
+        pub struct await;
+    }
+}
+use self::outer_mod::await::await;
+
+fn main() {
+    match await { await => () }
+}
diff --git a/src/test/ui/await-keyword/post_expansion_error.rs b/src/test/ui/await-keyword/post_expansion_error.rs
new file mode 100644
index 00000000000..580ca3b3a4f
--- /dev/null
+++ b/src/test/ui/await-keyword/post_expansion_error.rs
@@ -0,0 +1,9 @@
+// edition:2018
+
+macro_rules! r#await {
+    () => { println!("Hello, world!") }
+}
+
+fn main() {
+    await!()
+}
diff --git a/src/test/ui/await-keyword/post_expansion_error.stderr b/src/test/ui/await-keyword/post_expansion_error.stderr
new file mode 100644
index 00000000000..76ae35b7517
--- /dev/null
+++ b/src/test/ui/await-keyword/post_expansion_error.stderr
@@ -0,0 +1,9 @@
+error[E0721]: `await` is a keyword in the 2018 edition
+  --> $DIR/post_expansion_error.rs:8:5
+   |
+LL |     await!()
+   |     ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0721`.