Auto merge of #52375 - oli-obk:the_early_lint_pass_gets_the_worm, r=Manishearth
Lint `async` identifiers in 2018 preparation mode r? @Manishearth fixes https://github.com/rust-lang/rust/issues/49716
This commit is contained in:
commit
12ed235adc
|
@ -27,7 +27,7 @@
|
|||
use self::TargetLint::*;
|
||||
|
||||
use std::slice;
|
||||
use rustc_data_structures::sync::{RwLock, ReadGuard};
|
||||
use rustc_data_structures::sync::ReadGuard;
|
||||
use lint::{EarlyLintPassObject, LateLintPassObject};
|
||||
use lint::{Level, Lint, LintId, LintPass, LintBuffer};
|
||||
use lint::builtin::BuiltinLintDiagnostics;
|
||||
|
@ -59,8 +59,8 @@ pub struct LintStore {
|
|||
lints: Vec<(&'static Lint, bool)>,
|
||||
|
||||
/// Trait objects for each lint pass.
|
||||
/// This is only `None` while performing a lint pass. See the definition
|
||||
/// of `LintSession::new`.
|
||||
/// This is only `None` while performing a lint pass.
|
||||
pre_expansion_passes: Option<Vec<EarlyLintPassObject>>,
|
||||
early_passes: Option<Vec<EarlyLintPassObject>>,
|
||||
late_passes: Option<Vec<LateLintPassObject>>,
|
||||
|
||||
|
@ -139,6 +139,7 @@ impl LintStore {
|
|||
pub fn new() -> LintStore {
|
||||
LintStore {
|
||||
lints: vec![],
|
||||
pre_expansion_passes: Some(vec![]),
|
||||
early_passes: Some(vec![]),
|
||||
late_passes: Some(vec![]),
|
||||
by_name: FxHashMap(),
|
||||
|
@ -165,6 +166,15 @@ impl LintStore {
|
|||
self.early_passes.as_mut().unwrap().push(pass);
|
||||
}
|
||||
|
||||
pub fn register_pre_expansion_pass(
|
||||
&mut self,
|
||||
sess: Option<&Session>,
|
||||
pass: EarlyLintPassObject,
|
||||
) {
|
||||
self.push_pass(sess, false, &pass);
|
||||
self.pre_expansion_passes.as_mut().unwrap().push(pass);
|
||||
}
|
||||
|
||||
pub fn register_late_pass(&mut self,
|
||||
sess: Option<&Session>,
|
||||
from_plugin: bool,
|
||||
|
@ -334,28 +344,6 @@ impl LintStore {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, PassObject: LintPassObject> LintSession<'a, PassObject> {
|
||||
/// Creates a new `LintSession`, by moving out the `LintStore`'s initial
|
||||
/// lint levels and pass objects. These can be restored using the `restore`
|
||||
/// method.
|
||||
fn new(store: &'a RwLock<LintStore>) -> LintSession<'a, PassObject> {
|
||||
let mut s = store.borrow_mut();
|
||||
let passes = PassObject::take_passes(&mut *s);
|
||||
drop(s);
|
||||
LintSession {
|
||||
lints: store.borrow(),
|
||||
passes,
|
||||
}
|
||||
}
|
||||
|
||||
/// Restores the levels back to the original lint store.
|
||||
fn restore(self, store: &RwLock<LintStore>) {
|
||||
drop(self.lints);
|
||||
let mut s = store.borrow_mut();
|
||||
PassObject::restore_passes(&mut *s, self.passes);
|
||||
}
|
||||
}
|
||||
|
||||
/// Context for lint checking after type checking.
|
||||
pub struct LateContext<'a, 'tcx: 'a> {
|
||||
/// Type context we're checking in.
|
||||
|
@ -397,7 +385,7 @@ pub struct EarlyContext<'a> {
|
|||
}
|
||||
|
||||
/// Convenience macro for calling a `LintPass` method on every pass in the context.
|
||||
macro_rules! run_lints { ($cx:expr, $f:ident, $ps:ident, $($args:expr),*) => ({
|
||||
macro_rules! run_lints { ($cx:expr, $f:ident, $($args:expr),*) => ({
|
||||
// Move the vector of passes out of `$cx` so that we can
|
||||
// iterate over it mutably while passing `$cx` to the methods.
|
||||
let mut passes = $cx.lint_sess_mut().passes.take().unwrap();
|
||||
|
@ -407,30 +395,11 @@ macro_rules! run_lints { ($cx:expr, $f:ident, $ps:ident, $($args:expr),*) => ({
|
|||
$cx.lint_sess_mut().passes = Some(passes);
|
||||
}) }
|
||||
|
||||
pub trait LintPassObject: Sized {
|
||||
fn take_passes(store: &mut LintStore) -> Option<Vec<Self>>;
|
||||
fn restore_passes(store: &mut LintStore, passes: Option<Vec<Self>>);
|
||||
}
|
||||
pub trait LintPassObject: Sized {}
|
||||
|
||||
impl LintPassObject for EarlyLintPassObject {
|
||||
fn take_passes(store: &mut LintStore) -> Option<Vec<Self>> {
|
||||
store.early_passes.take()
|
||||
}
|
||||
impl LintPassObject for EarlyLintPassObject {}
|
||||
|
||||
fn restore_passes(store: &mut LintStore, passes: Option<Vec<Self>>) {
|
||||
store.early_passes = passes;
|
||||
}
|
||||
}
|
||||
|
||||
impl LintPassObject for LateLintPassObject {
|
||||
fn take_passes(store: &mut LintStore) -> Option<Vec<Self>> {
|
||||
store.late_passes.take()
|
||||
}
|
||||
|
||||
fn restore_passes(store: &mut LintStore, passes: Option<Vec<Self>>) {
|
||||
store.late_passes = passes;
|
||||
}
|
||||
}
|
||||
impl LintPassObject for LateLintPassObject {}
|
||||
|
||||
|
||||
pub trait LintContext<'tcx>: Sized {
|
||||
|
@ -517,14 +486,21 @@ pub trait LintContext<'tcx>: Sized {
|
|||
|
||||
|
||||
impl<'a> EarlyContext<'a> {
|
||||
fn new(sess: &'a Session,
|
||||
krate: &'a ast::Crate) -> EarlyContext<'a> {
|
||||
fn new(
|
||||
sess: &'a Session,
|
||||
krate: &'a ast::Crate,
|
||||
passes: Option<Vec<EarlyLintPassObject>>,
|
||||
buffered: LintBuffer,
|
||||
) -> EarlyContext<'a> {
|
||||
EarlyContext {
|
||||
sess,
|
||||
krate,
|
||||
lint_sess: LintSession::new(&sess.lint_store),
|
||||
lint_sess: LintSession {
|
||||
lints: sess.lint_store.borrow(),
|
||||
passes,
|
||||
},
|
||||
builder: LintLevelSets::builder(sess),
|
||||
buffered: sess.buffered_lints.borrow_mut().take().unwrap(),
|
||||
buffered,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -560,12 +536,12 @@ impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> {
|
|||
|
||||
fn enter_attrs(&mut self, attrs: &'tcx [ast::Attribute]) {
|
||||
debug!("late context: enter_attrs({:?})", attrs);
|
||||
run_lints!(self, enter_lint_attrs, late_passes, attrs);
|
||||
run_lints!(self, enter_lint_attrs, attrs);
|
||||
}
|
||||
|
||||
fn exit_attrs(&mut self, attrs: &'tcx [ast::Attribute]) {
|
||||
debug!("late context: exit_attrs({:?})", attrs);
|
||||
run_lints!(self, exit_lint_attrs, late_passes, attrs);
|
||||
run_lints!(self, exit_lint_attrs, attrs);
|
||||
}
|
||||
|
||||
fn lookup<S: Into<MultiSpan>>(&self,
|
||||
|
@ -617,12 +593,12 @@ impl<'a> LintContext<'a> for EarlyContext<'a> {
|
|||
|
||||
fn enter_attrs(&mut self, attrs: &'a [ast::Attribute]) {
|
||||
debug!("early context: enter_attrs({:?})", attrs);
|
||||
run_lints!(self, enter_lint_attrs, early_passes, attrs);
|
||||
run_lints!(self, enter_lint_attrs, attrs);
|
||||
}
|
||||
|
||||
fn exit_attrs(&mut self, attrs: &'a [ast::Attribute]) {
|
||||
debug!("early context: exit_attrs({:?})", attrs);
|
||||
run_lints!(self, exit_lint_attrs, early_passes, attrs);
|
||||
run_lints!(self, exit_lint_attrs, attrs);
|
||||
}
|
||||
|
||||
fn lookup<S: Into<MultiSpan>>(&self,
|
||||
|
@ -688,9 +664,9 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_body(&mut self, body: &'tcx hir::Body) {
|
||||
run_lints!(self, check_body, late_passes, body);
|
||||
run_lints!(self, check_body, body);
|
||||
hir_visit::walk_body(self, body);
|
||||
run_lints!(self, check_body_post, late_passes, body);
|
||||
run_lints!(self, check_body_post, body);
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, it: &'tcx hir::Item) {
|
||||
|
@ -698,9 +674,9 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
|||
self.generics = it.node.generics();
|
||||
self.with_lint_attrs(it.id, &it.attrs, |cx| {
|
||||
cx.with_param_env(it.id, |cx| {
|
||||
run_lints!(cx, check_item, late_passes, it);
|
||||
run_lints!(cx, check_item, it);
|
||||
hir_visit::walk_item(cx, it);
|
||||
run_lints!(cx, check_item_post, late_passes, it);
|
||||
run_lints!(cx, check_item_post, it);
|
||||
});
|
||||
});
|
||||
self.generics = generics;
|
||||
|
@ -709,23 +685,23 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
|||
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem) {
|
||||
self.with_lint_attrs(it.id, &it.attrs, |cx| {
|
||||
cx.with_param_env(it.id, |cx| {
|
||||
run_lints!(cx, check_foreign_item, late_passes, it);
|
||||
run_lints!(cx, check_foreign_item, it);
|
||||
hir_visit::walk_foreign_item(cx, it);
|
||||
run_lints!(cx, check_foreign_item_post, late_passes, it);
|
||||
run_lints!(cx, check_foreign_item_post, it);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, p: &'tcx hir::Pat) {
|
||||
run_lints!(self, check_pat, late_passes, p);
|
||||
run_lints!(self, check_pat, p);
|
||||
hir_visit::walk_pat(self, p);
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, e: &'tcx hir::Expr) {
|
||||
self.with_lint_attrs(e.id, &e.attrs, |cx| {
|
||||
run_lints!(cx, check_expr, late_passes, e);
|
||||
run_lints!(cx, check_expr, e);
|
||||
hir_visit::walk_expr(cx, e);
|
||||
run_lints!(cx, check_expr_post, late_passes, e);
|
||||
run_lints!(cx, check_expr_post, e);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -735,7 +711,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
|||
// - local
|
||||
// - expression
|
||||
// so we keep track of lint levels there
|
||||
run_lints!(self, check_stmt, late_passes, s);
|
||||
run_lints!(self, check_stmt, s);
|
||||
hir_visit::walk_stmt(self, s);
|
||||
}
|
||||
|
||||
|
@ -746,9 +722,9 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
|||
let old_tables = self.tables;
|
||||
self.tables = self.tcx.body_tables(body_id);
|
||||
let body = self.tcx.hir.body(body_id);
|
||||
run_lints!(self, check_fn, late_passes, fk, decl, body, span, id);
|
||||
run_lints!(self, check_fn, fk, decl, body, span, id);
|
||||
hir_visit::walk_fn(self, fk, decl, body_id, span, id);
|
||||
run_lints!(self, check_fn_post, late_passes, fk, decl, body, span, id);
|
||||
run_lints!(self, check_fn_post, fk, decl, body, span, id);
|
||||
self.tables = old_tables;
|
||||
}
|
||||
|
||||
|
@ -758,14 +734,14 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
|||
g: &'tcx hir::Generics,
|
||||
item_id: ast::NodeId,
|
||||
_: Span) {
|
||||
run_lints!(self, check_struct_def, late_passes, s, name, g, item_id);
|
||||
run_lints!(self, check_struct_def, s, name, g, item_id);
|
||||
hir_visit::walk_struct_def(self, s);
|
||||
run_lints!(self, check_struct_def_post, late_passes, s, name, g, item_id);
|
||||
run_lints!(self, check_struct_def_post, s, name, g, item_id);
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
|
||||
self.with_lint_attrs(s.id, &s.attrs, |cx| {
|
||||
run_lints!(cx, check_struct_field, late_passes, s);
|
||||
run_lints!(cx, check_struct_field, s);
|
||||
hir_visit::walk_struct_field(cx, s);
|
||||
})
|
||||
}
|
||||
|
@ -775,68 +751,68 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
|||
g: &'tcx hir::Generics,
|
||||
item_id: ast::NodeId) {
|
||||
self.with_lint_attrs(v.node.data.id(), &v.node.attrs, |cx| {
|
||||
run_lints!(cx, check_variant, late_passes, v, g);
|
||||
run_lints!(cx, check_variant, v, g);
|
||||
hir_visit::walk_variant(cx, v, g, item_id);
|
||||
run_lints!(cx, check_variant_post, late_passes, v, g);
|
||||
run_lints!(cx, check_variant_post, v, g);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: &'tcx hir::Ty) {
|
||||
run_lints!(self, check_ty, late_passes, t);
|
||||
run_lints!(self, check_ty, t);
|
||||
hir_visit::walk_ty(self, t);
|
||||
}
|
||||
|
||||
fn visit_name(&mut self, sp: Span, name: ast::Name) {
|
||||
run_lints!(self, check_name, late_passes, sp, name);
|
||||
run_lints!(self, check_name, sp, name);
|
||||
}
|
||||
|
||||
fn visit_mod(&mut self, m: &'tcx hir::Mod, s: Span, n: ast::NodeId) {
|
||||
run_lints!(self, check_mod, late_passes, m, s, n);
|
||||
run_lints!(self, check_mod, m, s, n);
|
||||
hir_visit::walk_mod(self, m, n);
|
||||
run_lints!(self, check_mod_post, late_passes, m, s, n);
|
||||
run_lints!(self, check_mod_post, m, s, n);
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &'tcx hir::Local) {
|
||||
self.with_lint_attrs(l.id, &l.attrs, |cx| {
|
||||
run_lints!(cx, check_local, late_passes, l);
|
||||
run_lints!(cx, check_local, l);
|
||||
hir_visit::walk_local(cx, l);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, b: &'tcx hir::Block) {
|
||||
run_lints!(self, check_block, late_passes, b);
|
||||
run_lints!(self, check_block, b);
|
||||
hir_visit::walk_block(self, b);
|
||||
run_lints!(self, check_block_post, late_passes, b);
|
||||
run_lints!(self, check_block_post, b);
|
||||
}
|
||||
|
||||
fn visit_arm(&mut self, a: &'tcx hir::Arm) {
|
||||
run_lints!(self, check_arm, late_passes, a);
|
||||
run_lints!(self, check_arm, a);
|
||||
hir_visit::walk_arm(self, a);
|
||||
}
|
||||
|
||||
fn visit_decl(&mut self, d: &'tcx hir::Decl) {
|
||||
run_lints!(self, check_decl, late_passes, d);
|
||||
run_lints!(self, check_decl, d);
|
||||
hir_visit::walk_decl(self, d);
|
||||
}
|
||||
|
||||
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam) {
|
||||
run_lints!(self, check_generic_param, late_passes, p);
|
||||
run_lints!(self, check_generic_param, p);
|
||||
hir_visit::walk_generic_param(self, p);
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, g: &'tcx hir::Generics) {
|
||||
run_lints!(self, check_generics, late_passes, g);
|
||||
run_lints!(self, check_generics, g);
|
||||
hir_visit::walk_generics(self, g);
|
||||
}
|
||||
|
||||
fn visit_where_predicate(&mut self, p: &'tcx hir::WherePredicate) {
|
||||
run_lints!(self, check_where_predicate, late_passes, p);
|
||||
run_lints!(self, check_where_predicate, p);
|
||||
hir_visit::walk_where_predicate(self, p);
|
||||
}
|
||||
|
||||
fn visit_poly_trait_ref(&mut self, t: &'tcx hir::PolyTraitRef,
|
||||
m: hir::TraitBoundModifier) {
|
||||
run_lints!(self, check_poly_trait_ref, late_passes, t, m);
|
||||
run_lints!(self, check_poly_trait_ref, t, m);
|
||||
hir_visit::walk_poly_trait_ref(self, t, m);
|
||||
}
|
||||
|
||||
|
@ -845,9 +821,9 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
|||
self.generics = Some(&trait_item.generics);
|
||||
self.with_lint_attrs(trait_item.id, &trait_item.attrs, |cx| {
|
||||
cx.with_param_env(trait_item.id, |cx| {
|
||||
run_lints!(cx, check_trait_item, late_passes, trait_item);
|
||||
run_lints!(cx, check_trait_item, trait_item);
|
||||
hir_visit::walk_trait_item(cx, trait_item);
|
||||
run_lints!(cx, check_trait_item_post, late_passes, trait_item);
|
||||
run_lints!(cx, check_trait_item_post, trait_item);
|
||||
});
|
||||
});
|
||||
self.generics = generics;
|
||||
|
@ -858,71 +834,71 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
|||
self.generics = Some(&impl_item.generics);
|
||||
self.with_lint_attrs(impl_item.id, &impl_item.attrs, |cx| {
|
||||
cx.with_param_env(impl_item.id, |cx| {
|
||||
run_lints!(cx, check_impl_item, late_passes, impl_item);
|
||||
run_lints!(cx, check_impl_item, impl_item);
|
||||
hir_visit::walk_impl_item(cx, impl_item);
|
||||
run_lints!(cx, check_impl_item_post, late_passes, impl_item);
|
||||
run_lints!(cx, check_impl_item_post, impl_item);
|
||||
});
|
||||
});
|
||||
self.generics = generics;
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
|
||||
run_lints!(self, check_lifetime, late_passes, lt);
|
||||
run_lints!(self, check_lifetime, lt);
|
||||
hir_visit::walk_lifetime(self, lt);
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, p: &'tcx hir::Path, id: ast::NodeId) {
|
||||
run_lints!(self, check_path, late_passes, p, id);
|
||||
run_lints!(self, check_path, p, id);
|
||||
hir_visit::walk_path(self, p);
|
||||
}
|
||||
|
||||
fn visit_attribute(&mut self, attr: &'tcx ast::Attribute) {
|
||||
run_lints!(self, check_attribute, late_passes, attr);
|
||||
run_lints!(self, check_attribute, attr);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> {
|
||||
fn visit_item(&mut self, it: &'a ast::Item) {
|
||||
self.with_lint_attrs(it.id, &it.attrs, |cx| {
|
||||
run_lints!(cx, check_item, early_passes, it);
|
||||
run_lints!(cx, check_item, it);
|
||||
ast_visit::walk_item(cx, it);
|
||||
run_lints!(cx, check_item_post, early_passes, it);
|
||||
run_lints!(cx, check_item_post, it);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, it: &'a ast::ForeignItem) {
|
||||
self.with_lint_attrs(it.id, &it.attrs, |cx| {
|
||||
run_lints!(cx, check_foreign_item, early_passes, it);
|
||||
run_lints!(cx, check_foreign_item, it);
|
||||
ast_visit::walk_foreign_item(cx, it);
|
||||
run_lints!(cx, check_foreign_item_post, early_passes, it);
|
||||
run_lints!(cx, check_foreign_item_post, it);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, p: &'a ast::Pat) {
|
||||
run_lints!(self, check_pat, early_passes, p);
|
||||
run_lints!(self, check_pat, p);
|
||||
self.check_id(p.id);
|
||||
ast_visit::walk_pat(self, p);
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, e: &'a ast::Expr) {
|
||||
self.with_lint_attrs(e.id, &e.attrs, |cx| {
|
||||
run_lints!(cx, check_expr, early_passes, e);
|
||||
run_lints!(cx, check_expr, e);
|
||||
ast_visit::walk_expr(cx, e);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_stmt(&mut self, s: &'a ast::Stmt) {
|
||||
run_lints!(self, check_stmt, early_passes, s);
|
||||
run_lints!(self, check_stmt, s);
|
||||
self.check_id(s.id);
|
||||
ast_visit::walk_stmt(self, s);
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: ast_visit::FnKind<'a>, decl: &'a ast::FnDecl,
|
||||
span: Span, id: ast::NodeId) {
|
||||
run_lints!(self, check_fn, early_passes, fk, decl, span, id);
|
||||
run_lints!(self, check_fn, fk, decl, span, id);
|
||||
self.check_id(id);
|
||||
ast_visit::walk_fn(self, fk, decl, span);
|
||||
run_lints!(self, check_fn_post, early_passes, fk, decl, span, id);
|
||||
run_lints!(self, check_fn_post, fk, decl, span, id);
|
||||
}
|
||||
|
||||
fn visit_variant_data(&mut self,
|
||||
|
@ -931,121 +907,126 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> {
|
|||
g: &'a ast::Generics,
|
||||
item_id: ast::NodeId,
|
||||
_: Span) {
|
||||
run_lints!(self, check_struct_def, early_passes, s, ident, g, item_id);
|
||||
run_lints!(self, check_struct_def, s, ident, g, item_id);
|
||||
self.check_id(s.id());
|
||||
ast_visit::walk_struct_def(self, s);
|
||||
run_lints!(self, check_struct_def_post, early_passes, s, ident, g, item_id);
|
||||
run_lints!(self, check_struct_def_post, s, ident, g, item_id);
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, s: &'a ast::StructField) {
|
||||
self.with_lint_attrs(s.id, &s.attrs, |cx| {
|
||||
run_lints!(cx, check_struct_field, early_passes, s);
|
||||
run_lints!(cx, check_struct_field, s);
|
||||
ast_visit::walk_struct_field(cx, s);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, v: &'a ast::Variant, g: &'a ast::Generics, item_id: ast::NodeId) {
|
||||
self.with_lint_attrs(item_id, &v.node.attrs, |cx| {
|
||||
run_lints!(cx, check_variant, early_passes, v, g);
|
||||
run_lints!(cx, check_variant, v, g);
|
||||
ast_visit::walk_variant(cx, v, g, item_id);
|
||||
run_lints!(cx, check_variant_post, early_passes, v, g);
|
||||
run_lints!(cx, check_variant_post, v, g);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: &'a ast::Ty) {
|
||||
run_lints!(self, check_ty, early_passes, t);
|
||||
run_lints!(self, check_ty, t);
|
||||
self.check_id(t.id);
|
||||
ast_visit::walk_ty(self, t);
|
||||
}
|
||||
|
||||
fn visit_ident(&mut self, ident: ast::Ident) {
|
||||
run_lints!(self, check_ident, early_passes, ident);
|
||||
run_lints!(self, check_ident, ident);
|
||||
}
|
||||
|
||||
fn visit_mod(&mut self, m: &'a ast::Mod, s: Span, _a: &[ast::Attribute], n: ast::NodeId) {
|
||||
run_lints!(self, check_mod, early_passes, m, s, n);
|
||||
run_lints!(self, check_mod, m, s, n);
|
||||
self.check_id(n);
|
||||
ast_visit::walk_mod(self, m);
|
||||
run_lints!(self, check_mod_post, early_passes, m, s, n);
|
||||
run_lints!(self, check_mod_post, m, s, n);
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &'a ast::Local) {
|
||||
self.with_lint_attrs(l.id, &l.attrs, |cx| {
|
||||
run_lints!(cx, check_local, early_passes, l);
|
||||
run_lints!(cx, check_local, l);
|
||||
ast_visit::walk_local(cx, l);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, b: &'a ast::Block) {
|
||||
run_lints!(self, check_block, early_passes, b);
|
||||
run_lints!(self, check_block, b);
|
||||
self.check_id(b.id);
|
||||
ast_visit::walk_block(self, b);
|
||||
run_lints!(self, check_block_post, early_passes, b);
|
||||
run_lints!(self, check_block_post, b);
|
||||
}
|
||||
|
||||
fn visit_arm(&mut self, a: &'a ast::Arm) {
|
||||
run_lints!(self, check_arm, early_passes, a);
|
||||
run_lints!(self, check_arm, a);
|
||||
ast_visit::walk_arm(self, a);
|
||||
}
|
||||
|
||||
fn visit_expr_post(&mut self, e: &'a ast::Expr) {
|
||||
run_lints!(self, check_expr_post, early_passes, e);
|
||||
run_lints!(self, check_expr_post, e);
|
||||
}
|
||||
|
||||
fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
|
||||
run_lints!(self, check_generic_param, early_passes, param);
|
||||
run_lints!(self, check_generic_param, param);
|
||||
ast_visit::walk_generic_param(self, param);
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, g: &'a ast::Generics) {
|
||||
run_lints!(self, check_generics, early_passes, g);
|
||||
run_lints!(self, check_generics, g);
|
||||
ast_visit::walk_generics(self, g);
|
||||
}
|
||||
|
||||
fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
|
||||
run_lints!(self, check_where_predicate, early_passes, p);
|
||||
run_lints!(self, check_where_predicate, p);
|
||||
ast_visit::walk_where_predicate(self, p);
|
||||
}
|
||||
|
||||
fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef, m: &'a ast::TraitBoundModifier) {
|
||||
run_lints!(self, check_poly_trait_ref, early_passes, t, m);
|
||||
run_lints!(self, check_poly_trait_ref, t, m);
|
||||
ast_visit::walk_poly_trait_ref(self, t, m);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, trait_item: &'a ast::TraitItem) {
|
||||
self.with_lint_attrs(trait_item.id, &trait_item.attrs, |cx| {
|
||||
run_lints!(cx, check_trait_item, early_passes, trait_item);
|
||||
run_lints!(cx, check_trait_item, trait_item);
|
||||
ast_visit::walk_trait_item(cx, trait_item);
|
||||
run_lints!(cx, check_trait_item_post, early_passes, trait_item);
|
||||
run_lints!(cx, check_trait_item_post, trait_item);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &'a ast::ImplItem) {
|
||||
self.with_lint_attrs(impl_item.id, &impl_item.attrs, |cx| {
|
||||
run_lints!(cx, check_impl_item, early_passes, impl_item);
|
||||
run_lints!(cx, check_impl_item, impl_item);
|
||||
ast_visit::walk_impl_item(cx, impl_item);
|
||||
run_lints!(cx, check_impl_item_post, early_passes, impl_item);
|
||||
run_lints!(cx, check_impl_item_post, impl_item);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) {
|
||||
run_lints!(self, check_lifetime, early_passes, lt);
|
||||
run_lints!(self, check_lifetime, lt);
|
||||
self.check_id(lt.id);
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, p: &'a ast::Path, id: ast::NodeId) {
|
||||
run_lints!(self, check_path, early_passes, p, id);
|
||||
run_lints!(self, check_path, p, id);
|
||||
self.check_id(id);
|
||||
ast_visit::walk_path(self, p);
|
||||
}
|
||||
|
||||
fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
|
||||
run_lints!(self, check_attribute, early_passes, attr);
|
||||
run_lints!(self, check_attribute, attr);
|
||||
}
|
||||
|
||||
fn visit_mac_def(&mut self, _mac: &'a ast::MacroDef, id: ast::NodeId) {
|
||||
fn visit_mac_def(&mut self, mac: &'a ast::MacroDef, id: ast::NodeId) {
|
||||
run_lints!(self, check_mac_def, mac, id);
|
||||
self.check_id(id);
|
||||
}
|
||||
|
||||
fn visit_mac(&mut self, mac: &'ast ast::Mac) {
|
||||
run_lints!(self, check_mac, mac);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1056,48 +1037,77 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
|
||||
|
||||
let krate = tcx.hir.krate();
|
||||
let passes = tcx.sess.lint_store.borrow_mut().late_passes.take();
|
||||
|
||||
let mut cx = LateContext {
|
||||
tcx,
|
||||
tables: &ty::TypeckTables::empty(None),
|
||||
param_env: ty::ParamEnv::empty(),
|
||||
access_levels,
|
||||
lint_sess: LintSession::new(&tcx.sess.lint_store),
|
||||
last_ast_node_with_lint_attrs: ast::CRATE_NODE_ID,
|
||||
generics: None,
|
||||
let passes = {
|
||||
let mut cx = LateContext {
|
||||
tcx,
|
||||
tables: &ty::TypeckTables::empty(None),
|
||||
param_env: ty::ParamEnv::empty(),
|
||||
access_levels,
|
||||
lint_sess: LintSession {
|
||||
passes,
|
||||
lints: tcx.sess.lint_store.borrow(),
|
||||
},
|
||||
last_ast_node_with_lint_attrs: ast::CRATE_NODE_ID,
|
||||
generics: None,
|
||||
};
|
||||
|
||||
// Visit the whole crate.
|
||||
cx.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |cx| {
|
||||
// since the root module isn't visited as an item (because it isn't an
|
||||
// item), warn for it here.
|
||||
run_lints!(cx, check_crate, krate);
|
||||
|
||||
hir_visit::walk_crate(cx, krate);
|
||||
|
||||
run_lints!(cx, check_crate_post, krate);
|
||||
});
|
||||
cx.lint_sess.passes
|
||||
};
|
||||
|
||||
// Visit the whole crate.
|
||||
cx.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |cx| {
|
||||
// since the root module isn't visited as an item (because it isn't an
|
||||
// item), warn for it here.
|
||||
run_lints!(cx, check_crate, late_passes, krate);
|
||||
|
||||
hir_visit::walk_crate(cx, krate);
|
||||
|
||||
run_lints!(cx, check_crate_post, late_passes, krate);
|
||||
});
|
||||
|
||||
// Put the lint store levels and passes back in the session.
|
||||
cx.lint_sess.restore(&tcx.sess.lint_store);
|
||||
tcx.sess.lint_store.borrow_mut().late_passes = passes;
|
||||
}
|
||||
|
||||
pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
|
||||
let mut cx = EarlyContext::new(sess, krate);
|
||||
pub fn check_ast_crate(
|
||||
sess: &Session,
|
||||
krate: &ast::Crate,
|
||||
pre_expansion: bool,
|
||||
) {
|
||||
let (passes, buffered) = if pre_expansion {
|
||||
(
|
||||
sess.lint_store.borrow_mut().pre_expansion_passes.take(),
|
||||
LintBuffer::new(),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
sess.lint_store.borrow_mut().early_passes.take(),
|
||||
sess.buffered_lints.borrow_mut().take().unwrap(),
|
||||
)
|
||||
};
|
||||
let (passes, buffered) = {
|
||||
let mut cx = EarlyContext::new(sess, krate, passes, buffered);
|
||||
|
||||
// Visit the whole crate.
|
||||
cx.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |cx| {
|
||||
// since the root module isn't visited as an item (because it isn't an
|
||||
// item), warn for it here.
|
||||
run_lints!(cx, check_crate, early_passes, krate);
|
||||
// Visit the whole crate.
|
||||
cx.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |cx| {
|
||||
// since the root module isn't visited as an item (because it isn't an
|
||||
// item), warn for it here.
|
||||
run_lints!(cx, check_crate, krate);
|
||||
|
||||
ast_visit::walk_crate(cx, krate);
|
||||
ast_visit::walk_crate(cx, krate);
|
||||
|
||||
run_lints!(cx, check_crate_post, early_passes, krate);
|
||||
});
|
||||
run_lints!(cx, check_crate_post, krate);
|
||||
});
|
||||
(cx.lint_sess.passes, cx.buffered)
|
||||
};
|
||||
|
||||
// Put the lint store levels and passes back in the session.
|
||||
cx.lint_sess.restore(&sess.lint_store);
|
||||
if pre_expansion {
|
||||
sess.lint_store.borrow_mut().pre_expansion_passes = passes;
|
||||
} else {
|
||||
sess.lint_store.borrow_mut().early_passes = passes;
|
||||
}
|
||||
|
||||
// All of the buffered lints should have been emitted at this point.
|
||||
// If not, that means that we somehow buffered a lint for a node id
|
||||
|
@ -1109,7 +1119,7 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
|
|||
// unused_macro lint) anymore. So we only run this check
|
||||
// when we're not in rustdoc mode. (see issue #47639)
|
||||
if !sess.opts.actually_rustdoc {
|
||||
for (_id, lints) in cx.buffered.map {
|
||||
for (_id, lints) in buffered.map {
|
||||
for early_lint in lints {
|
||||
sess.delay_span_bug(early_lint.span, "failed to process buffered lint here");
|
||||
}
|
||||
|
|
|
@ -327,6 +327,8 @@ pub trait EarlyLintPass: LintPass {
|
|||
fn check_lifetime(&mut self, _: &EarlyContext, _: &ast::Lifetime) { }
|
||||
fn check_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { }
|
||||
fn check_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { }
|
||||
fn check_mac_def(&mut self, _: &EarlyContext, _: &ast::MacroDef, _id: ast::NodeId) { }
|
||||
fn check_mac(&mut self, _: &EarlyContext, _: &ast::Mac) { }
|
||||
|
||||
/// Called when entering a syntax node that can have lint attributes such
|
||||
/// as `#[allow(...)]`. Called with *all* the attributes of that node.
|
||||
|
@ -341,6 +343,8 @@ pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync +
|
|||
pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + sync::Send
|
||||
+ sync::Sync + 'static>;
|
||||
|
||||
|
||||
|
||||
/// Identifies a lint known to the compiler.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct LintId {
|
||||
|
|
|
@ -922,6 +922,10 @@ where
|
|||
return Err(CompileIncomplete::Stopped);
|
||||
}
|
||||
|
||||
time(sess, "pre ast expansion lint checks", || {
|
||||
lint::check_ast_crate(sess, &krate, true)
|
||||
});
|
||||
|
||||
let mut resolver = Resolver::new(
|
||||
sess,
|
||||
cstore,
|
||||
|
@ -1134,7 +1138,7 @@ where
|
|||
});
|
||||
|
||||
time(sess, "early lint checks", || {
|
||||
lint::check_ast_crate(sess, &krate)
|
||||
lint::check_ast_crate(sess, &krate, false)
|
||||
});
|
||||
|
||||
// Discard hygiene data, which isn't required after lowering to HIR.
|
||||
|
|
|
@ -41,6 +41,7 @@ use lint::{LintPass, LateLintPass, EarlyLintPass, EarlyContext};
|
|||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use syntax::tokenstream::{TokenTree, TokenStream};
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Spanned;
|
||||
|
@ -1784,3 +1785,70 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestFunctions {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub ASYNC_IDENTS,
|
||||
Allow,
|
||||
"detects `async` being used as an identifier"
|
||||
}
|
||||
|
||||
/// Checks for uses of `async` as an identifier
|
||||
#[derive(Clone)]
|
||||
pub struct Async2018;
|
||||
|
||||
impl LintPass for Async2018 {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(ASYNC_IDENTS)
|
||||
}
|
||||
}
|
||||
|
||||
impl Async2018 {
|
||||
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))
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
TokenTree::Delimited(_, ref delim) => {
|
||||
self.check_tokens(cx, delim.tts.clone().into())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
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",
|
||||
);
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,14 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||
)
|
||||
}
|
||||
|
||||
macro_rules! add_pre_expansion_builtin {
|
||||
($sess:ident, $($name:ident),*,) => (
|
||||
{$(
|
||||
store.register_early_pass($sess, false, box $name);
|
||||
)*}
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! add_early_builtin_with_new {
|
||||
($sess:ident, $($name:ident),*,) => (
|
||||
{$(
|
||||
|
@ -97,6 +105,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||
)
|
||||
}
|
||||
|
||||
add_pre_expansion_builtin!(sess,
|
||||
Async2018,
|
||||
);
|
||||
|
||||
add_early_builtin!(sess,
|
||||
UnusedParens,
|
||||
UnusedImportBraces,
|
||||
|
@ -215,6 +227,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||
reference: "issue #35896 <https://github.com/rust-lang/rust/issues/35896>",
|
||||
edition: Some(Edition::Edition2018),
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(ASYNC_IDENTS),
|
||||
reference: "issue #49716 <https://github.com/rust-lang/rust/issues/49716>",
|
||||
edition: Some(Edition::Edition2018),
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(SAFE_EXTERN_STATICS),
|
||||
reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
error[E0453]: allow(test_lint) overruled by outer forbid(test_lint)
|
||||
--> $DIR/lint-plugin-forbid-attrs.rs:20:9
|
||||
|
|
||||
LL | #![forbid(test_lint)]
|
||||
| --------- `forbid` level set here
|
||||
...
|
||||
LL | #[allow(test_lint)]
|
||||
| ^^^^^^^^^ overruled by previous forbid
|
||||
|
||||
error: item is named 'lintme'
|
||||
--> $DIR/lint-plugin-forbid-attrs.rs:18:1
|
||||
|
|
||||
|
@ -10,15 +19,6 @@ note: lint level defined here
|
|||
LL | #![forbid(test_lint)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0453]: allow(test_lint) overruled by outer forbid(test_lint)
|
||||
--> $DIR/lint-plugin-forbid-attrs.rs:20:9
|
||||
|
|
||||
LL | #![forbid(test_lint)]
|
||||
| --------- `forbid` level set here
|
||||
...
|
||||
LL | #[allow(test_lint)]
|
||||
| ^^^^^^^^^ overruled by previous forbid
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0453`.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
// edition:2015
|
||||
|
||||
#![feature(raw_identifiers)]
|
||||
#![allow(async_idents)]
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! produces_async {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
// edition:2018
|
||||
|
||||
#![feature(raw_identifiers)]
|
||||
#![allow(async_idents)]
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! produces_async {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// compile-pass
|
||||
|
||||
#![feature(raw_identifiers)]
|
||||
#![allow(async_idents)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate edition_kw_macro_2015;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// compile-pass
|
||||
|
||||
#![feature(raw_identifiers)]
|
||||
#![allow(async_idents)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate edition_kw_macro_2015;
|
||||
|
|
|
@ -1,17 +1,3 @@
|
|||
warning: macro_escape is a deprecated synonym for macro_use
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:1
|
||||
|
|
||||
LL | #[macro_escape]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
warning: macro_escape is a deprecated synonym for macro_use
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:503:17
|
||||
|
|
||||
LL | mod inner { #![macro_escape] }
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider an outer attribute, #[macro_use] mod ...
|
||||
|
||||
warning: unknown lint: `x5400`
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:49:33
|
||||
|
|
||||
|
@ -186,6 +172,20 @@ warning: unknown lint: `x5100`
|
|||
LL | #[deny(x5100)] impl S { }
|
||||
| ^^^^^
|
||||
|
||||
warning: macro_escape is a deprecated synonym for macro_use
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:1
|
||||
|
|
||||
LL | #[macro_escape]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
warning: macro_escape is a deprecated synonym for macro_use
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:503:17
|
||||
|
|
||||
LL | mod inner { #![macro_escape] }
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider an outer attribute, #[macro_use] mod ...
|
||||
|
||||
warning: `repr` attribute isn't configurable with a literal
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:17
|
||||
|
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#![feature(raw_identifiers)]
|
||||
#![allow(dead_code, unused_variables, non_camel_case_types, non_upper_case_globals)]
|
||||
#![deny(async_idents)]
|
||||
|
||||
// edition:2015
|
||||
// run-rustfix
|
||||
|
||||
fn r#async() {} //~ ERROR async
|
||||
//~^ WARN hard error in the 2018 edition
|
||||
|
||||
macro_rules! foo {
|
||||
($foo:ident) => {};
|
||||
($r#async:expr, r#async) => {};
|
||||
//~^ ERROR async
|
||||
//~| ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
foo!(async);
|
||||
|
||||
mod dont_lint_raw {
|
||||
fn r#async() {}
|
||||
}
|
||||
|
||||
mod async_trait {
|
||||
trait r#async {}
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
struct MyStruct;
|
||||
impl r#async for MyStruct {}
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
mod async_static {
|
||||
static r#async: u32 = 0;
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
mod async_const {
|
||||
const r#async: u32 = 0;
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
impl Foo { fn r#async() {} }
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
|
||||
fn main() {
|
||||
struct r#async {}
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
let r#async: r#async = r#async {};
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
//~| ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
//~| ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! produces_async {
|
||||
() => (pub fn r#async() {})
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! consumes_async {
|
||||
(r#async) => (1)
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#![feature(raw_identifiers)]
|
||||
#![allow(dead_code, unused_variables, non_camel_case_types, non_upper_case_globals)]
|
||||
#![deny(async_idents)]
|
||||
|
||||
// edition:2015
|
||||
// run-rustfix
|
||||
|
||||
fn async() {} //~ ERROR async
|
||||
//~^ WARN hard error in the 2018 edition
|
||||
|
||||
macro_rules! foo {
|
||||
($foo:ident) => {};
|
||||
($async:expr, async) => {};
|
||||
//~^ ERROR async
|
||||
//~| ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
foo!(async);
|
||||
|
||||
mod dont_lint_raw {
|
||||
fn r#async() {}
|
||||
}
|
||||
|
||||
mod async_trait {
|
||||
trait async {}
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
struct MyStruct;
|
||||
impl async for MyStruct {}
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
mod async_static {
|
||||
static async: u32 = 0;
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
mod async_const {
|
||||
const async: u32 = 0;
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
impl Foo { fn async() {} }
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
|
||||
fn main() {
|
||||
struct async {}
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
let async: async = async {};
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
//~| ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
//~| ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! produces_async {
|
||||
() => (pub fn async() {})
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! consumes_async {
|
||||
(async) => (1)
|
||||
//~^ ERROR async
|
||||
//~| WARN hard error in the 2018 edition
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
error: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:18:4
|
||||
|
|
||||
LL | fn async() {} //~ ERROR async
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/async-ident.rs:13:9
|
||||
|
|
||||
LL | #![deny(async_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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:23:7
|
||||
|
|
||||
LL | ($async:expr, async) => {};
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:23:19
|
||||
|
|
||||
LL | ($async:expr, async) => {};
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:37:11
|
||||
|
|
||||
LL | trait async {}
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:41:10
|
||||
|
|
||||
LL | impl async for MyStruct {}
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:47:12
|
||||
|
|
||||
LL | static async: u32 = 0;
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:53:11
|
||||
|
|
||||
LL | const async: u32 = 0;
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:59:15
|
||||
|
|
||||
LL | impl Foo { fn async() {} }
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:64:12
|
||||
|
|
||||
LL | struct async {}
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:67:9
|
||||
|
|
||||
LL | let async: async = async {};
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:67:16
|
||||
|
|
||||
LL | let async: async = async {};
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:67:24
|
||||
|
|
||||
LL | let async: async = async {};
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:78:19
|
||||
|
|
||||
LL | () => (pub fn async() {})
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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: `async` is a keyword in the 2018 edition
|
||||
--> $DIR/async-ident.rs:85:6
|
||||
|
|
||||
LL | (async) => (1)
|
||||
| ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
|
||||
|
|
||||
= 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 14 previous errors
|
||||
|
Loading…
Reference in New Issue