Skip to content

Generalize async_idents to all new keywords #53685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,7 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> {
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);
}
}
Expand Down
79 changes: 46 additions & 33 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ use syntax::tokenstream::{TokenTree, TokenStream};
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;
Expand Down Expand Up @@ -1876,30 +1877,33 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestFunctions {
}

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) => {
Expand All @@ -1908,38 +1912,47 @@ impl Async2018 {
}
}
}
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());
}
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()
}
}
5 changes: 3 additions & 2 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
}

add_pre_expansion_builtin!(sess,
Async2018,
KeywordIdents,
);

add_early_builtin!(sess,
Expand Down Expand Up @@ -240,7 +240,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
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),
},
Expand Down Expand Up @@ -349,6 +349,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
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");
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/editions/auxiliary/edition-kw-macro-2015.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

// edition:2015

#![allow(async_idents)]
#![allow(keyword_idents)]

#[macro_export]
macro_rules! produces_async {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/editions/auxiliary/edition-kw-macro-2018.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

// edition:2018

#![allow(async_idents)]
#![allow(keyword_idents)]

#[macro_export]
macro_rules! produces_async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/rust-2018/async-ident-allowed.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/rust-2018/async-ident.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/rust-2018/async-ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/rust-2018/async-ident.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
21 changes: 21 additions & 0 deletions src/test/ui/rust-2018/try-ident.fixed
Original file line number Diff line number Diff line change
@@ -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() {
}
21 changes: 21 additions & 0 deletions src/test/ui/rust-2018/try-ident.rs
Original file line number Diff line number Diff line change
@@ -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() {
}
24 changes: 24 additions & 0 deletions src/test/ui/rust-2018/try-ident.stderr
Original file line number Diff line number Diff line change
@@ -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>