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;
}
--- /dev/null
+// 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
+}
#![feature(rustc_diagnostic_macros)]
#![feature(macro_at_most_once_rep)]
+#[macro_use]
extern crate syntax;
#[macro_use]
extern crate rustc;
use lint::LintId;
use lint::FutureIncompatibleInfo;
+mod diagnostics;
mod nonstandard_style;
pub mod builtin;
mod types;
--- /dev/null
+// 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 => {} }
+}
--- /dev/null
+// 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 => {} }
+}
--- /dev/null
+// 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 => {} }
+}
--- /dev/null
+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
+
--- /dev/null
+// 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 => () }
+}
--- /dev/null
+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`.
--- /dev/null
+// 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 => () }
+}
--- /dev/null
+// edition:2018
+
+macro_rules! r#await {
+ () => { println!("Hello, world!") }
+}
+
+fn main() {
+ await!()
+}
--- /dev/null
+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`.