Skip to content

Commit

Permalink
Auto merge of #54411 - cramertj:await-keyword-error, r=nikomatsakis
Browse files Browse the repository at this point in the history
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 #53834

r? @nikomatsakis
  • Loading branch information
bors committed Sep 25, 2018
2 parents ae36663 + fb14662 commit 31789a6
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 4 deletions.
40 changes: 36 additions & 4 deletions src/librustc_lint/builtin.rs
Expand Up @@ -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;
}

Expand Down
13 changes: 13 additions & 0 deletions 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
}
2 changes: 2 additions & 0 deletions src/librustc_lint/lib.rs
Expand Up @@ -32,6 +32,7 @@
#![feature(rustc_diagnostic_macros)]
#![feature(macro_at_most_once_rep)]

#[macro_use]
extern crate syntax;
#[macro_use]
extern crate rustc;
Expand Down Expand Up @@ -61,6 +62,7 @@ use syntax::edition::Edition;
use lint::LintId;
use lint::FutureIncompatibleInfo;

mod diagnostics;
mod nonstandard_style;
pub mod builtin;
mod types;
Expand Down
@@ -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 => {} }
}
15 changes: 15 additions & 0 deletions 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 => {} }
}
15 changes: 15 additions & 0 deletions 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 => {} }
}
61 changes: 61 additions & 0 deletions 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

13 changes: 13 additions & 0 deletions 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 => () }
}
39 changes: 39 additions & 0 deletions 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`.
@@ -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 => () }
}
9 changes: 9 additions & 0 deletions 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!()
}
9 changes: 9 additions & 0 deletions 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`.

0 comments on commit 31789a6

Please sign in to comment.