From beb0c74950ec51582b58e3f13e5b2a47b14f524d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 18 Jan 2019 07:40:55 +0100 Subject: [PATCH 1/2] Combine all builtin early lints and use a separate walk for plugin lints. Add a -Z no-interleave-lints option to allow benchmarking lints --- src/librustc/lint/builtin.rs | 4 + src/librustc/lint/context.rs | 323 ++++++++++++++++--------- src/librustc/lint/mod.rs | 191 +++++++++++---- src/librustc/session/config.rs | 2 + src/librustc_driver/driver.rs | 10 +- src/librustc_lint/builtin.rs | 96 ++++++++ src/librustc_lint/lib.rs | 93 +++---- src/librustc_lint/nonstandard_style.rs | 12 + src/librustc_lint/types.rs | 12 + src/librustc_lint/unused.rs | 24 ++ 10 files changed, 551 insertions(+), 216 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index c8d137a42b2e8..0d2dc8382024f 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -374,6 +374,10 @@ declare_lint! { pub struct HardwiredLints; impl LintPass for HardwiredLints { + fn name(&self) -> &'static str { + "HardwiredLints" + } + fn get_lints(&self) -> LintArray { lint_array!( ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index f5a7919ef09c8..e426858349368 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -18,8 +18,8 @@ use self::TargetLint::*; use std::slice; use rustc_data_structures::sync::ReadGuard; -use lint::{EarlyLintPassObject, LateLintPassObject}; -use lint::{Level, Lint, LintId, LintPass, LintBuffer}; +use lint::{EarlyLintPass, EarlyLintPassObject, LateLintPassObject}; +use lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; use lint::builtin::BuiltinLintDiagnostics; use lint::levels::{LintLevelSets, LintLevelsBuilder}; use middle::privacy::AccessLevels; @@ -28,6 +28,7 @@ use session::{config, early_error, Session}; use ty::{self, TyCtxt, Ty}; use ty::layout::{LayoutError, LayoutOf, TyLayout}; use util::nodemap::FxHashMap; +use util::common::time; use std::default::Default as StdDefault; use syntax::ast; @@ -74,7 +75,6 @@ pub struct LintSession<'a, PassObject> { passes: Option>, } - /// Lints that are buffered up early on in the `Session` before the /// `LintLevels` is calculated #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] @@ -175,18 +175,25 @@ impl LintStore { pub fn register_early_pass(&mut self, sess: Option<&Session>, from_plugin: bool, + register_only: bool, pass: EarlyLintPassObject) { self.push_pass(sess, from_plugin, &pass); - self.early_passes.as_mut().unwrap().push(pass); + if !register_only { + self.early_passes.as_mut().unwrap().push(pass); + } } pub fn register_pre_expansion_pass( &mut self, sess: Option<&Session>, + from_plugin: bool, + register_only: bool, pass: EarlyLintPassObject, ) { - self.push_pass(sess, false, &pass); - self.pre_expansion_passes.as_mut().unwrap().push(pass); + self.push_pass(sess, from_plugin, &pass); + if !register_only { + self.pre_expansion_passes.as_mut().unwrap().push(pass); + } } pub fn register_late_pass(&mut self, @@ -535,6 +542,11 @@ pub struct EarlyContext<'a> { buffered: LintBuffer, } +pub struct EarlyContextAndPass<'a, T: EarlyLintPass> { + context: EarlyContext<'a>, + pass: T, +} + /// Convenience macro for calling a `LintPass` method on every pass in the context. macro_rules! run_lints { ($cx:expr, $f:ident, $($args:expr),*) => ({ // Move the vector of passes out of `$cx` so that we can @@ -560,8 +572,6 @@ pub trait LintContext<'tcx>: Sized { fn lints(&self) -> &LintStore; fn lint_sess(&self) -> &LintSession<'tcx, Self::PassObject>; fn lint_sess_mut(&mut self) -> &mut LintSession<'tcx, Self::PassObject>; - fn enter_attrs(&mut self, attrs: &'tcx [ast::Attribute]); - fn exit_attrs(&mut self, attrs: &'tcx [ast::Attribute]); fn lookup_and_emit>(&self, lint: &'static Lint, @@ -624,15 +634,6 @@ pub trait LintContext<'tcx>: Sized { fn lint(&self, lint: &'static Lint, msg: &str) { self.lookup_and_emit(lint, None as Option, msg); } - - /// Merge the lints specified by any lint attributes into the - /// current lint context, call the provided function, then reset the - /// lints in effect to their previous state. - fn with_lint_attrs(&mut self, - id: ast::NodeId, - attrs: &'tcx [ast::Attribute], - f: F) - where F: FnOnce(&mut Self); } @@ -640,7 +641,6 @@ impl<'a> EarlyContext<'a> { fn new( sess: &'a Session, krate: &'a ast::Crate, - passes: Option>, buffered: LintBuffer, ) -> EarlyContext<'a> { EarlyContext { @@ -648,21 +648,56 @@ impl<'a> EarlyContext<'a> { krate, lint_sess: LintSession { lints: sess.lint_store.borrow(), - passes, + passes: None, }, builder: LintLevelSets::builder(sess), buffered, } } +} +macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({ + $cx.pass.$f(&$cx.context, $($args),*); +}) } + +impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { fn check_id(&mut self, id: ast::NodeId) { - for early_lint in self.buffered.take(id) { - self.lookup_and_emit_with_diagnostics(early_lint.lint_id.lint, - Some(early_lint.span.clone()), - &early_lint.msg, - early_lint.diagnostic); + for early_lint in self.context.buffered.take(id) { + self.context.lookup_and_emit_with_diagnostics( + early_lint.lint_id.lint, + Some(early_lint.span.clone()), + &early_lint.msg, + early_lint.diagnostic + ); } } + + /// Merge the lints specified by any lint attributes into the + /// current lint context, call the provided function, then reset the + /// lints in effect to their previous state. + fn with_lint_attrs(&mut self, + id: ast::NodeId, + attrs: &'a [ast::Attribute], + f: F) + where F: FnOnce(&mut Self) + { + let push = self.context.builder.push(attrs); + self.check_id(id); + self.enter_attrs(attrs); + f(self); + self.exit_attrs(attrs); + self.context.builder.pop(push); + } + + fn enter_attrs(&mut self, attrs: &'a [ast::Attribute]) { + debug!("early context: enter_attrs({:?})", attrs); + run_early_pass!(self, enter_lint_attrs, attrs); + } + + fn exit_attrs(&mut self, attrs: &'a [ast::Attribute]) { + debug!("early context: exit_attrs({:?})", attrs); + run_early_pass!(self, exit_lint_attrs, attrs); + } } impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> { @@ -685,16 +720,6 @@ impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> { &mut self.lint_sess } - fn enter_attrs(&mut self, attrs: &'tcx [ast::Attribute]) { - debug!("late context: enter_attrs({:?})", 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, attrs); - } - fn lookup>(&self, lint: &'static Lint, span: Option, @@ -706,20 +731,6 @@ impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> { None => self.tcx.struct_lint_node(lint, id, msg), } } - - fn with_lint_attrs(&mut self, - id: ast::NodeId, - attrs: &'tcx [ast::Attribute], - f: F) - where F: FnOnce(&mut Self) - { - let prev = self.last_ast_node_with_lint_attrs; - self.last_ast_node_with_lint_attrs = id; - self.enter_attrs(attrs); - f(self); - self.exit_attrs(attrs); - self.last_ast_node_with_lint_attrs = prev; - } } impl<'a> LintContext<'a> for EarlyContext<'a> { @@ -742,16 +753,6 @@ impl<'a> LintContext<'a> for EarlyContext<'a> { &mut self.lint_sess } - fn enter_attrs(&mut self, attrs: &'a [ast::Attribute]) { - debug!("early context: enter_attrs({:?})", 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, attrs); - } - fn lookup>(&self, lint: &'static Lint, span: Option, @@ -759,23 +760,36 @@ impl<'a> LintContext<'a> for EarlyContext<'a> { -> DiagnosticBuilder<'_> { self.builder.struct_lint(lint, span.map(|s| s.into()), msg) } +} +impl<'a, 'tcx> LateContext<'a, 'tcx> { + /// Merge the lints specified by any lint attributes into the + /// current lint context, call the provided function, then reset the + /// lints in effect to their previous state. fn with_lint_attrs(&mut self, id: ast::NodeId, - attrs: &'a [ast::Attribute], + attrs: &'tcx [ast::Attribute], f: F) where F: FnOnce(&mut Self) { - let push = self.builder.push(attrs); - self.check_id(id); + let prev = self.last_ast_node_with_lint_attrs; + self.last_ast_node_with_lint_attrs = id; self.enter_attrs(attrs); f(self); self.exit_attrs(attrs); - self.builder.pop(push); + self.last_ast_node_with_lint_attrs = prev; + } + + fn enter_attrs(&mut self, attrs: &'tcx [ast::Attribute]) { + debug!("late context: enter_attrs({:?})", 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, attrs); } -} -impl<'a, 'tcx> LateContext<'a, 'tcx> { fn with_param_env(&mut self, id: ast::NodeId, f: F) where F: FnOnce(&mut Self), { @@ -1008,26 +1022,26 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { } } -impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> { +impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> { fn visit_item(&mut self, it: &'a ast::Item) { self.with_lint_attrs(it.id, &it.attrs, |cx| { - run_lints!(cx, check_item, it); + run_early_pass!(cx, check_item, it); ast_visit::walk_item(cx, it); - run_lints!(cx, check_item_post, it); + run_early_pass!(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, it); + run_early_pass!(cx, check_foreign_item, it); ast_visit::walk_foreign_item(cx, it); - run_lints!(cx, check_foreign_item_post, it); + run_early_pass!(cx, check_foreign_item_post, it); }) } fn visit_pat(&mut self, p: &'a ast::Pat) { let mut visit_subpats = true; - run_lints!(self, check_pat, p, &mut visit_subpats); + run_early_pass!(self, check_pat, p, &mut visit_subpats); self.check_id(p.id); if visit_subpats { ast_visit::walk_pat(self, p); @@ -1036,23 +1050,23 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> { fn visit_expr(&mut self, e: &'a ast::Expr) { self.with_lint_attrs(e.id, &e.attrs, |cx| { - run_lints!(cx, check_expr, e); + run_early_pass!(cx, check_expr, e); ast_visit::walk_expr(cx, e); }) } fn visit_stmt(&mut self, s: &'a ast::Stmt) { - run_lints!(self, check_stmt, s); + run_early_pass!(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, fk, decl, span, id); + run_early_pass!(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, fk, decl, span, id); + run_early_pass!(self, check_fn_post, fk, decl, span, id); } fn visit_variant_data(&mut self, @@ -1061,120 +1075,120 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> { g: &'a ast::Generics, item_id: ast::NodeId, _: Span) { - run_lints!(self, check_struct_def, s, ident, g, item_id); + run_early_pass!(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, s, ident, g, item_id); + run_early_pass!(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, s); + run_early_pass!(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, v, g); + run_early_pass!(cx, check_variant, v, g); ast_visit::walk_variant(cx, v, g, item_id); - run_lints!(cx, check_variant_post, v, g); + run_early_pass!(cx, check_variant_post, v, g); }) } fn visit_ty(&mut self, t: &'a ast::Ty) { - run_lints!(self, check_ty, t); + run_early_pass!(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, ident); + run_early_pass!(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, m, s, n); + run_early_pass!(self, check_mod, m, s, n); self.check_id(n); ast_visit::walk_mod(self, m); - run_lints!(self, check_mod_post, m, s, n); + run_early_pass!(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, l); + run_early_pass!(cx, check_local, l); ast_visit::walk_local(cx, l); }) } fn visit_block(&mut self, b: &'a ast::Block) { - run_lints!(self, check_block, b); + run_early_pass!(self, check_block, b); self.check_id(b.id); ast_visit::walk_block(self, b); - run_lints!(self, check_block_post, b); + run_early_pass!(self, check_block_post, b); } fn visit_arm(&mut self, a: &'a ast::Arm) { - run_lints!(self, check_arm, a); + run_early_pass!(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, e); + run_early_pass!(self, check_expr_post, e); } fn visit_generic_param(&mut self, param: &'a ast::GenericParam) { - run_lints!(self, check_generic_param, param); + run_early_pass!(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, g); + run_early_pass!(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, p); + run_early_pass!(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, t, m); + run_early_pass!(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, trait_item); + run_early_pass!(cx, check_trait_item, trait_item); ast_visit::walk_trait_item(cx, trait_item); - run_lints!(cx, check_trait_item_post, trait_item); + run_early_pass!(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, impl_item); + run_early_pass!(cx, check_impl_item, impl_item); ast_visit::walk_impl_item(cx, impl_item); - run_lints!(cx, check_impl_item_post, impl_item); + run_early_pass!(cx, check_impl_item_post, impl_item); }); } fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) { - run_lints!(self, check_lifetime, lt); + run_early_pass!(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, p, id); + run_early_pass!(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, attr); + run_early_pass!(self, check_attribute, attr); } fn visit_mac_def(&mut self, mac: &'a ast::MacroDef, id: ast::NodeId) { - run_lints!(self, check_mac_def, mac, id); + run_early_pass!(self, check_mac_def, mac, id); self.check_id(id); } @@ -1186,7 +1200,7 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> { // want to get #53686 fixed quickly. -nmatsakis ast_visit::walk_path(self, &mac.node.path); - run_lints!(self, check_mac, mac); + run_early_pass!(self, check_mac, mac); } } @@ -1231,43 +1245,112 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.sess.lint_store.borrow_mut().late_passes = passes; } -pub fn check_ast_crate( +struct EarlyLintPassObjects<'a> { + lints: &'a mut [EarlyLintPassObject], +} + +impl LintPass for EarlyLintPassObjects<'_> { + fn name(&self) -> &'static str { + panic!() + } + + fn get_lints(&self) -> LintArray { + panic!() + } +} + +macro_rules! expand_early_lint_pass_impl_methods { + ([$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( + $(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) { + for obj in self.lints.iter_mut() { + obj.$name(context, $($param),*); + } + })* + ) +} + +macro_rules! early_lint_pass_impl { + ([], [$($methods:tt)*]) => ( + impl EarlyLintPass for EarlyLintPassObjects<'_> { + expand_early_lint_pass_impl_methods!([$($methods)*]); + } + ) +} + +early_lint_methods!(early_lint_pass_impl, []); + + +fn early_lint_crate( + sess: &Session, + krate: &ast::Crate, + pass: T, + buffered: LintBuffer, +) -> LintBuffer { + let mut cx = EarlyContextAndPass { + context: EarlyContext::new(sess, krate, buffered), + pass, + }; + + // 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_early_pass!(cx, check_crate, krate); + + ast_visit::walk_crate(cx, krate); + + run_early_pass!(cx, check_crate_post, krate); + }); + cx.context.buffered +} + +pub fn check_ast_crate( sess: &Session, krate: &ast::Crate, pre_expansion: bool, + builtin_lints: T, ) { - let (passes, buffered) = if pre_expansion { + let (mut passes, mut buffered) = if pre_expansion { ( - sess.lint_store.borrow_mut().pre_expansion_passes.take(), + sess.lint_store.borrow_mut().pre_expansion_passes.take().unwrap(), LintBuffer::default(), ) } else { ( - sess.lint_store.borrow_mut().early_passes.take(), + sess.lint_store.borrow_mut().early_passes.take().unwrap(), 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, krate); + if !sess.opts.debugging_opts.no_interleave_lints { + buffered = early_lint_crate(sess, krate, builtin_lints, buffered); - ast_visit::walk_crate(cx, krate); - - run_lints!(cx, check_crate_post, krate); - }); - (cx.lint_sess.passes, cx.buffered) - }; + if !passes.is_empty() { + buffered = early_lint_crate( + sess, + krate, + EarlyLintPassObjects { lints: &mut passes[..] }, + buffered, + ); + } + } else { + for pass in &mut passes { + buffered = time(sess, &format!("running lint: {}", pass.name()), || { + early_lint_crate( + sess, + krate, + EarlyLintPassObjects { lints: slice::from_mut(pass) }, + buffered, + ) + }); + } + } // Put the lint store levels and passes back in the session. if pre_expansion { - sess.lint_store.borrow_mut().pre_expansion_passes = passes; + sess.lint_store.borrow_mut().pre_expansion_passes = Some(passes); } else { - sess.lint_store.borrow_mut().early_passes = passes; + sess.lint_store.borrow_mut().early_passes = Some(passes); } // All of the buffered lints should have been emitted at this point. diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 730ce919bd295..0f20081270f46 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -36,7 +36,6 @@ use syntax::source_map::{MultiSpan, ExpnFormat}; use syntax::early_buffered_lints::BufferedEarlyLintId; use syntax::edition::Edition; use syntax::symbol::Symbol; -use syntax::visit as ast_visit; use syntax_pos::Span; use ty::TyCtxt; use ty::query::Providers; @@ -162,6 +161,8 @@ macro_rules! lint_array { pub type LintArray = Vec<&'static Lint>; pub trait LintPass { + fn name(&self) -> &'static str; + /// Get descriptions of the lints this `LintPass` object can emit. /// /// N.B., there is no enforcement that the object only emits lints it registered. @@ -308,6 +309,10 @@ macro_rules! declare_combined_late_lint_pass { } impl LintPass for $name { + fn name(&self) -> &'static str { + panic!() + } + fn get_lints(&self) -> LintArray { let mut lints = Vec::new(); $(lints.extend_from_slice(&self.$passes.get_lints());)* @@ -317,57 +322,139 @@ macro_rules! declare_combined_late_lint_pass { ) } -pub trait EarlyLintPass: LintPass { - fn check_ident(&mut self, _: &EarlyContext<'_>, _: ast::Ident) { } - fn check_crate(&mut self, _: &EarlyContext<'_>, _: &ast::Crate) { } - fn check_crate_post(&mut self, _: &EarlyContext<'_>, _: &ast::Crate) { } - fn check_mod(&mut self, _: &EarlyContext<'_>, _: &ast::Mod, _: Span, _: ast::NodeId) { } - fn check_mod_post(&mut self, _: &EarlyContext<'_>, _: &ast::Mod, _: Span, _: ast::NodeId) { } - fn check_foreign_item(&mut self, _: &EarlyContext<'_>, _: &ast::ForeignItem) { } - fn check_foreign_item_post(&mut self, _: &EarlyContext<'_>, _: &ast::ForeignItem) { } - fn check_item(&mut self, _: &EarlyContext<'_>, _: &ast::Item) { } - fn check_item_post(&mut self, _: &EarlyContext<'_>, _: &ast::Item) { } - fn check_local(&mut self, _: &EarlyContext<'_>, _: &ast::Local) { } - fn check_block(&mut self, _: &EarlyContext<'_>, _: &ast::Block) { } - fn check_block_post(&mut self, _: &EarlyContext<'_>, _: &ast::Block) { } - fn check_stmt(&mut self, _: &EarlyContext<'_>, _: &ast::Stmt) { } - fn check_arm(&mut self, _: &EarlyContext<'_>, _: &ast::Arm) { } - fn check_pat(&mut self, _: &EarlyContext<'_>, _: &ast::Pat, _: &mut bool) { } - fn check_expr(&mut self, _: &EarlyContext<'_>, _: &ast::Expr) { } - fn check_expr_post(&mut self, _: &EarlyContext<'_>, _: &ast::Expr) { } - fn check_ty(&mut self, _: &EarlyContext<'_>, _: &ast::Ty) { } - fn check_generic_param(&mut self, _: &EarlyContext<'_>, _: &ast::GenericParam) { } - fn check_generics(&mut self, _: &EarlyContext<'_>, _: &ast::Generics) { } - fn check_where_predicate(&mut self, _: &EarlyContext<'_>, _: &ast::WherePredicate) { } - fn check_poly_trait_ref(&mut self, _: &EarlyContext<'_>, _: &ast::PolyTraitRef, - _: &ast::TraitBoundModifier) { } - fn check_fn(&mut self, _: &EarlyContext<'_>, - _: ast_visit::FnKind<'_>, _: &ast::FnDecl, _: Span, _: ast::NodeId) { } - fn check_fn_post(&mut self, _: &EarlyContext<'_>, - _: ast_visit::FnKind<'_>, _: &ast::FnDecl, _: Span, _: ast::NodeId) { } - fn check_trait_item(&mut self, _: &EarlyContext<'_>, _: &ast::TraitItem) { } - fn check_trait_item_post(&mut self, _: &EarlyContext<'_>, _: &ast::TraitItem) { } - fn check_impl_item(&mut self, _: &EarlyContext<'_>, _: &ast::ImplItem) { } - fn check_impl_item_post(&mut self, _: &EarlyContext<'_>, _: &ast::ImplItem) { } - fn check_struct_def(&mut self, _: &EarlyContext<'_>, - _: &ast::VariantData, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { } - fn check_struct_def_post(&mut self, _: &EarlyContext<'_>, - _: &ast::VariantData, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { } - fn check_struct_field(&mut self, _: &EarlyContext<'_>, _: &ast::StructField) { } - fn check_variant(&mut self, _: &EarlyContext<'_>, _: &ast::Variant, _: &ast::Generics) { } - fn check_variant_post(&mut self, _: &EarlyContext<'_>, _: &ast::Variant, _: &ast::Generics) { } - 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. - fn enter_lint_attrs(&mut self, _: &EarlyContext<'_>, _: &[ast::Attribute]) { } - - /// Counterpart to `enter_lint_attrs`. - fn exit_lint_attrs(&mut self, _: &EarlyContext<'_>, _: &[ast::Attribute]) { } +#[macro_export] +macro_rules! early_lint_methods { + ($macro:path, $args:tt) => ( + $macro!($args, [ + fn check_ident(a: ast::Ident); + fn check_crate(a: &ast::Crate); + fn check_crate_post(a: &ast::Crate); + fn check_mod(a: &ast::Mod, b: Span, c: ast::NodeId); + fn check_mod_post(a: &ast::Mod, b: Span, c: ast::NodeId); + fn check_foreign_item(a: &ast::ForeignItem); + fn check_foreign_item_post(a: &ast::ForeignItem); + fn check_item(a: &ast::Item); + fn check_item_post(a: &ast::Item); + fn check_local(a: &ast::Local); + fn check_block(a: &ast::Block); + fn check_block_post(a: &ast::Block); + fn check_stmt(a: &ast::Stmt); + fn check_arm(a: &ast::Arm); + fn check_pat(a: &ast::Pat, b: &mut bool); // FIXME: &mut bool looks just broken + fn check_expr(a: &ast::Expr); + fn check_expr_post(a: &ast::Expr); + fn check_ty(a: &ast::Ty); + fn check_generic_param(a: &ast::GenericParam); + fn check_generics(a: &ast::Generics); + fn check_where_predicate(a: &ast::WherePredicate); + fn check_poly_trait_ref(a: &ast::PolyTraitRef, + b: &ast::TraitBoundModifier); + fn check_fn(a: syntax::visit::FnKind<'_>, b: &ast::FnDecl, c: Span, d_: ast::NodeId); + fn check_fn_post( + a: syntax::visit::FnKind<'_>, + b: &ast::FnDecl, + c: Span, + d: ast::NodeId + ); + fn check_trait_item(a: &ast::TraitItem); + fn check_trait_item_post(a: &ast::TraitItem); + fn check_impl_item(a: &ast::ImplItem); + fn check_impl_item_post(a: &ast::ImplItem); + fn check_struct_def( + a: &ast::VariantData, + b: ast::Ident, + c: &ast::Generics, + d: ast::NodeId + ); + fn check_struct_def_post( + a: &ast::VariantData, + b: ast::Ident, + c: &ast::Generics, + d: ast::NodeId + ); + fn check_struct_field(a: &ast::StructField); + fn check_variant(a: &ast::Variant, b: &ast::Generics); + fn check_variant_post(a: &ast::Variant, b: &ast::Generics); + fn check_lifetime(a: &ast::Lifetime); + fn check_path(a: &ast::Path, b: ast::NodeId); + fn check_attribute(a: &ast::Attribute); + fn check_mac_def(a: &ast::MacroDef, b: ast::NodeId); + fn check_mac(a: &ast::Mac); + + /// Called when entering a syntax node that can have lint attributes such + /// as `#[allow(...)]`. Called with *all* the attributes of that node. + fn enter_lint_attrs(a: &[ast::Attribute]); + + /// Counterpart to `enter_lint_attrs`. + fn exit_lint_attrs(a: &[ast::Attribute]); + ]); + ) +} + +macro_rules! expand_early_lint_pass_methods { + ($context:ty, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( + $(#[inline(always)] fn $name(&mut self, _: $context, $(_: $arg),*) {})* + ) +} + +macro_rules! declare_early_lint_pass { + ([], [$($methods:tt)*]) => ( + pub trait EarlyLintPass: LintPass { + expand_early_lint_pass_methods!(&EarlyContext<'_>, [$($methods)*]); + } + ) +} + +early_lint_methods!(declare_early_lint_pass, []); + +#[macro_export] +macro_rules! expand_combined_early_lint_pass_method { + ([$($passes:ident),*], $self: ident, $name: ident, $params:tt) => ({ + $($self.$passes.$name $params;)* + }) +} + +#[macro_export] +macro_rules! expand_combined_early_lint_pass_methods { + ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => ( + $(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) { + expand_combined_early_lint_pass_method!($passes, self, $name, (context, $($param),*)); + })* + ) +} + +#[macro_export] +macro_rules! declare_combined_early_lint_pass { + ([$v:vis $name:ident, [$($passes:ident: $constructor:expr,)*]], $methods:tt) => ( + #[allow(non_snake_case)] + $v struct $name { + $($passes: $passes,)* + } + + impl $name { + $v fn new() -> Self { + Self { + $($passes: $constructor,)* + } + } + } + + impl EarlyLintPass for $name { + expand_combined_early_lint_pass_methods!([$($passes),*], $methods); + } + + impl LintPass for $name { + fn name(&self) -> &'static str { + panic!() + } + + fn get_lints(&self) -> LintArray { + let mut lints = Vec::new(); + $(lints.extend_from_slice(&self.$passes.get_lints());)* + lints + } + } + ) } /// A lint pass boxed up as a trait object. diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 42adc6a87fdba..ffd6525e6e70d 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1364,6 +1364,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"), no_leak_check: bool = (false, parse_bool, [UNTRACKED], "disables the 'leak check' for subtyping; unsound, but useful for tests"), + no_interleave_lints: bool = (false, parse_bool, [UNTRACKED], + "don't interleave execution of lints; allows benchmarking individual lints"), crate_attr: Vec = (Vec::new(), parse_string_push, [TRACKED], "inject the given attribute in the crate"), self_profile: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1ecb8ef112c9e..495df73e5e9c9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -898,7 +898,7 @@ where sess.track_errors(|| { let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(Some(sess), true, pass); + ls.register_early_pass(Some(sess), true, false, pass); } for pass in late_lint_passes { ls.register_late_pass(Some(sess), true, pass); @@ -919,7 +919,11 @@ where } time(sess, "pre ast expansion lint checks", || { - lint::check_ast_crate(sess, &krate, true) + lint::check_ast_crate( + sess, + &krate, + true, + rustc_lint::BuiltinCombinedPreExpansionLintPass::new()); }); let mut resolver = Resolver::new( @@ -1131,7 +1135,7 @@ where }); time(sess, "early lint checks", || { - lint::check_ast_crate(sess, &krate, false) + lint::check_ast_crate(sess, &krate, false, rustc_lint::BuiltinCombinedEarlyLintPass::new()) }); // Discard hygiene data, which isn't required after lowering to HIR. diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index f895542e43ada..7b48ab459748d 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -60,6 +60,10 @@ declare_lint! { pub struct WhileTrue; impl LintPass for WhileTrue { + fn name(&self) -> &'static str { + "WhileTrue" + } + fn get_lints(&self) -> LintArray { lint_array!(WHILE_TRUE) } @@ -109,6 +113,10 @@ impl BoxPointers { } impl LintPass for BoxPointers { + fn name(&self) -> &'static str { + "BoxPointers" + } + fn get_lints(&self) -> LintArray { lint_array!(BOX_POINTERS) } @@ -158,6 +166,10 @@ declare_lint! { pub struct NonShorthandFieldPatterns; impl LintPass for NonShorthandFieldPatterns { + fn name(&self) -> &'static str { + "NonShorthandFieldPatterns" + } + fn get_lints(&self) -> LintArray { lint_array!(NON_SHORTHAND_FIELD_PATTERNS) } @@ -211,6 +223,10 @@ declare_lint! { pub struct UnsafeCode; impl LintPass for UnsafeCode { + fn name(&self) -> &'static str { + "UnsafeCode" + } + fn get_lints(&self) -> LintArray { lint_array!(UNSAFE_CODE) } @@ -373,6 +389,10 @@ impl MissingDoc { } impl LintPass for MissingDoc { + fn name(&self) -> &'static str { + "MissingDoc" + } + fn get_lints(&self) -> LintArray { lint_array!(MISSING_DOCS) } @@ -519,6 +539,10 @@ declare_lint! { pub struct MissingCopyImplementations; impl LintPass for MissingCopyImplementations { + fn name(&self) -> &'static str { + "MissingCopyImplementations" + } + fn get_lints(&self) -> LintArray { lint_array!(MISSING_COPY_IMPLEMENTATIONS) } @@ -586,6 +610,10 @@ impl MissingDebugImplementations { } impl LintPass for MissingDebugImplementations { + fn name(&self) -> &'static str { + "MissingDebugImplementations" + } + fn get_lints(&self) -> LintArray { lint_array!(MISSING_DEBUG_IMPLEMENTATIONS) } @@ -643,6 +671,10 @@ declare_lint! { pub struct AnonymousParameters; impl LintPass for AnonymousParameters { + fn name(&self) -> &'static str { + "AnonymousParameters" + } + fn get_lints(&self) -> LintArray { lint_array!(ANONYMOUS_PARAMETERS) } @@ -707,6 +739,10 @@ impl DeprecatedAttr { } impl LintPass for DeprecatedAttr { + fn name(&self) -> &'static str { + "DeprecatedAttr" + } + fn get_lints(&self) -> LintArray { lint_array!() } @@ -747,6 +783,10 @@ declare_lint! { pub struct UnusedDocComment; impl LintPass for UnusedDocComment { + fn name(&self) -> &'static str { + "UnusedDocComment" + } + fn get_lints(&self) -> LintArray { lint_array![UNUSED_DOC_COMMENTS] } @@ -787,6 +827,10 @@ declare_lint! { pub struct PluginAsLibrary; impl LintPass for PluginAsLibrary { + fn name(&self) -> &'static str { + "PluginAsLibrary" + } + fn get_lints(&self) -> LintArray { lint_array![PLUGIN_AS_LIBRARY] } @@ -839,6 +883,10 @@ declare_lint! { pub struct InvalidNoMangleItems; impl LintPass for InvalidNoMangleItems { + fn name(&self) -> &'static str { + "InvalidNoMangleItems" + } + fn get_lints(&self) -> LintArray { lint_array!(NO_MANGLE_CONST_ITEMS, NO_MANGLE_GENERIC_ITEMS) @@ -910,6 +958,10 @@ declare_lint! { } impl LintPass for MutableTransmutes { + fn name(&self) -> &'static str { + "MutableTransmutes" + } + fn get_lints(&self) -> LintArray { lint_array!(MUTABLE_TRANSMUTES) } @@ -970,6 +1022,10 @@ declare_lint! { } impl LintPass for UnstableFeatures { + fn name(&self) -> &'static str { + "UnstableFeatures" + } + fn get_lints(&self) -> LintArray { lint_array!(UNSTABLE_FEATURES) } @@ -997,6 +1053,10 @@ declare_lint! { } impl LintPass for UnionsWithDropFields { + fn name(&self) -> &'static str { + "UnionsWithDropFields" + } + fn get_lints(&self) -> LintArray { lint_array!(UNIONS_WITH_DROP_FIELDS) } @@ -1029,6 +1089,10 @@ declare_lint! { } impl LintPass for UnreachablePub { + fn name(&self) -> &'static str { + "UnreachablePub" + } + fn get_lints(&self) -> LintArray { lint_array!(UNREACHABLE_PUB) } @@ -1099,6 +1163,10 @@ declare_lint! { } impl LintPass for TypeAliasBounds { + fn name(&self) -> &'static str { + "TypeAliasBounds" + } + fn get_lints(&self) -> LintArray { lint_array!(TYPE_ALIAS_BOUNDS) } @@ -1203,6 +1271,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { pub struct UnusedBrokenConst; impl LintPass for UnusedBrokenConst { + fn name(&self) -> &'static str { + "UnusedBrokenConst" + } + fn get_lints(&self) -> LintArray { lint_array!() } @@ -1249,6 +1321,10 @@ declare_lint! { } impl LintPass for TrivialConstraints { + fn name(&self) -> &'static str { + "TrivialConstraints" + } + fn get_lints(&self) -> LintArray { lint_array!(TRIVIAL_BOUNDS) } @@ -1303,6 +1379,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints { pub struct SoftLints; impl LintPass for SoftLints { + fn name(&self) -> &'static str { + "SoftLints" + } + fn get_lints(&self) -> LintArray { lint_array!( WHILE_TRUE, @@ -1337,6 +1417,10 @@ declare_lint! { pub struct EllipsisInclusiveRangePatterns; impl LintPass for EllipsisInclusiveRangePatterns { + fn name(&self) -> &'static str { + "EllipsisInclusiveRangePatterns" + } + fn get_lints(&self) -> LintArray { lint_array!(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS) } @@ -1411,6 +1495,10 @@ impl UnnameableTestItems { } impl LintPass for UnnameableTestItems { + fn name(&self) -> &'static str { + "UnnameableTestItems" + } + fn get_lints(&self) -> LintArray { lint_array!(UNNAMEABLE_TEST_ITEMS) } @@ -1454,6 +1542,10 @@ declare_lint! { pub struct KeywordIdents; impl LintPass for KeywordIdents { + fn name(&self) -> &'static str { + "KeywordIdents" + } + fn get_lints(&self) -> LintArray { lint_array!(KEYWORD_IDENTS) } @@ -1559,6 +1651,10 @@ impl EarlyLintPass for KeywordIdents { pub struct ExplicitOutlivesRequirements; impl LintPass for ExplicitOutlivesRequirements { + fn name(&self) -> &'static str { + "ExplicitOutlivesRequirements" + } + fn get_lints(&self) -> LintArray { lint_array![EXPLICIT_OUTLIVES_REQUIREMENTS] } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 2d764d11c66aa..fedc0410f2402 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -39,7 +39,7 @@ mod types; mod unused; use rustc::lint; -use rustc::lint::{LateContext, LateLintPass, LintPass, LintArray}; +use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray}; use rustc::lint::builtin::{ BARE_TRAIT_OBJECTS, ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, @@ -71,57 +71,68 @@ use unused::*; /// Useful for other parts of the compiler. pub use builtin::SoftLints; +macro_rules! pre_expansion_lint_passes { + ($macro:path, $args:tt) => ( + $macro!($args, [ + KeywordIdents: KeywordIdents, + ]); + ) +} + +macro_rules! early_lint_passes { + ($macro:path, $args:tt) => ( + $macro!($args, [ + UnusedParens: UnusedParens, + UnusedImportBraces: UnusedImportBraces, + UnsafeCode: UnsafeCode, + AnonymousParameters: AnonymousParameters, + UnusedDocComment: UnusedDocComment, + EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns, + NonCamelCaseTypes: NonCamelCaseTypes, + DeprecatedAttr: DeprecatedAttr::new(), + ]); + ) +} + +macro_rules! declare_combined_early_pass { + ([$name:ident], $passes:tt) => ( + early_lint_methods!(declare_combined_early_lint_pass, [pub $name, $passes]); + ) +} + +pre_expansion_lint_passes!(declare_combined_early_pass, [BuiltinCombinedPreExpansionLintPass]); +early_lint_passes!(declare_combined_early_pass, [BuiltinCombinedEarlyLintPass]); + /// Tell the `LintStore` about all the built-in lints (the ones /// defined in this crate and the ones defined in /// `rustc::lint::builtin`). pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { - macro_rules! add_early_builtin { - ($sess:ident, $($name:ident),*,) => ( - {$( - store.register_early_pass($sess, false, box $name); - )*} - ) - } - - macro_rules! add_pre_expansion_builtin { - ($sess:ident, $($name:ident),*,) => ( - {$( - store.register_pre_expansion_pass($sess, box $name); - )*} - ) - } - - macro_rules! add_early_builtin_with_new { - ($sess:ident, $($name:ident),*,) => ( - {$( - store.register_early_pass($sess, false, box $name::new()); - )*} - ) - } - macro_rules! add_lint_group { ($sess:ident, $name:expr, $($lint:ident),*) => ( store.register_group($sess, false, $name, None, vec![$(LintId::of($lint)),*]); ) } - add_pre_expansion_builtin!(sess, - KeywordIdents, - ); - - add_early_builtin!(sess, - UnusedParens, - UnusedImportBraces, - UnsafeCode, - AnonymousParameters, - UnusedDocComment, - EllipsisInclusiveRangePatterns, - NonCamelCaseTypes, - ); + macro_rules! register_passes { + ([$method:ident], [$($passes:ident: $constructor:expr,)*]) => ( + $( + store.$method(sess, false, false, box $constructor); + )* + ) + } - add_early_builtin_with_new!(sess, - DeprecatedAttr, - ); + if sess.map(|sess| sess.opts.debugging_opts.no_interleave_lints).unwrap_or(false) { + pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass]); + early_lint_passes!(register_passes, [register_early_pass]); + } else { + store.register_pre_expansion_pass( + sess, + false, + true, + box BuiltinCombinedPreExpansionLintPass::new() + ); + store.register_early_pass(sess, false, true, box BuiltinCombinedEarlyLintPass::new()); + } late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedLateLintPass, [ HardwiredLints: HardwiredLints, diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index a4a3fa552e988..256d28a39794e 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -105,6 +105,10 @@ impl NonCamelCaseTypes { } impl LintPass for NonCamelCaseTypes { + fn name(&self) -> &'static str { + "NonCamelCaseTypes" + } + fn get_lints(&self) -> LintArray { lint_array!(NON_CAMEL_CASE_TYPES) } @@ -235,6 +239,10 @@ impl NonSnakeCase { } impl LintPass for NonSnakeCase { + fn name(&self) -> &'static str { + "NonSnakeCase" + } + fn get_lints(&self) -> LintArray { lint_array!(NON_SNAKE_CASE) } @@ -381,6 +389,10 @@ impl NonUpperCaseGlobals { } impl LintPass for NonUpperCaseGlobals { + fn name(&self) -> &'static str { + "NonUpperCaseGlobals" + } + fn get_lints(&self) -> LintArray { lint_array!(NON_UPPER_CASE_GLOBALS) } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 642681a73a8a0..aa6f396145473 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -53,6 +53,10 @@ impl TypeLimits { } impl LintPass for TypeLimits { + fn name(&self) -> &'static str { + "TypeLimits" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_COMPARISONS, OVERFLOWING_LITERALS) @@ -783,6 +787,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { pub struct ImproperCTypes; impl LintPass for ImproperCTypes { + fn name(&self) -> &'static str { + "ImproperCTypes" + } + fn get_lints(&self) -> LintArray { lint_array!(IMPROPER_CTYPES) } @@ -809,6 +817,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes { pub struct VariantSizeDifferences; impl LintPass for VariantSizeDifferences { + fn name(&self) -> &'static str { + "VariantSizeDifferences" + } + fn get_lints(&self) -> LintArray { lint_array!(VARIANT_SIZE_DIFFERENCES) } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index bc29020e79f2a..a05ad95a49de7 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -33,6 +33,10 @@ declare_lint! { pub struct UnusedResults; impl LintPass for UnusedResults { + fn name(&self) -> &'static str { + "UnusedResults" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_MUST_USE, UNUSED_RESULTS) } @@ -198,6 +202,10 @@ declare_lint! { pub struct PathStatements; impl LintPass for PathStatements { + fn name(&self) -> &'static str { + "PathStatements" + } + fn get_lints(&self) -> LintArray { lint_array!(PATH_STATEMENTS) } @@ -223,6 +231,10 @@ declare_lint! { pub struct UnusedAttributes; impl LintPass for UnusedAttributes { + fn name(&self) -> &'static str { + "UnusedAttributes" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_ATTRIBUTES) } @@ -365,6 +377,10 @@ impl UnusedParens { } impl LintPass for UnusedParens { + fn name(&self) -> &'static str { + "UnusedParens" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_PARENS) } @@ -483,6 +499,10 @@ impl UnusedImportBraces { } impl LintPass for UnusedImportBraces { + fn name(&self) -> &'static str { + "UnusedImportBraces" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_IMPORT_BRACES) } @@ -506,6 +526,10 @@ declare_lint! { pub struct UnusedAllocation; impl LintPass for UnusedAllocation { + fn name(&self) -> &'static str { + "UnusedAllocation" + } + fn get_lints(&self) -> LintArray { lint_array!(UNUSED_ALLOCATION) } From 9b5535a6f38340d3be8fcae1822a04ba3febf82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 19 Jan 2019 06:26:34 +0100 Subject: [PATCH 2/2] Fix lints in tests --- .../compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs | 4 ++++ src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs | 4 ++++ src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs | 4 ++++ src/test/ui-fulldeps/auxiliary/lint_for_crate.rs | 4 ++++ src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs | 4 ++++ src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs | 4 ++++ src/test/ui-fulldeps/auxiliary/lint_tool_test.rs | 4 ++++ 7 files changed, 28 insertions(+) diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs index bca1d7a72b4ab..16630e2b31285 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs @@ -19,6 +19,10 @@ declare_lint!(PLEASE_LINT, Warn, "Warn about items named 'pleaselintme'"); struct Pass; impl LintPass for Pass { + fn name(&self) -> &'static str { + "Pass" + } + fn get_lints(&self) -> LintArray { lint_array!(TEST_LINT, PLEASE_LINT) } diff --git a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs index 3e0e4e60e0db8..efa3de9a686b8 100644 --- a/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/issue-40001-plugin.rs @@ -32,6 +32,10 @@ declare_lint!(MISSING_WHITELISTED_ATTR, Deny, struct MissingWhitelistedAttrPass; impl LintPass for MissingWhitelistedAttrPass { + fn name(&self) -> &'static str { + "MissingWhitelistedAttrPass" + } + fn get_lints(&self) -> LintArray { lint_array!(MISSING_WHITELISTED_ATTR) } diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs index b6c517f2764bd..f34e10218d455 100644 --- a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs +++ b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs @@ -17,6 +17,10 @@ macro_rules! fake_lint_pass { struct $struct; impl LintPass for $struct { + fn name(&self) -> &'static str { + stringify!($struct) + } + fn get_lints(&self) -> LintArray { $lints } diff --git a/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs b/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs index 23bda04f9b328..82aa28b26b648 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_for_crate.rs @@ -17,6 +17,10 @@ declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]"); struct Pass; impl LintPass for Pass { + fn name(&self) -> &'static str { + "Pass" + } + fn get_lints(&self) -> LintArray { lint_array!(CRATE_NOT_OKAY) } diff --git a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs index bca1d7a72b4ab..16630e2b31285 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs @@ -19,6 +19,10 @@ declare_lint!(PLEASE_LINT, Warn, "Warn about items named 'pleaselintme'"); struct Pass; impl LintPass for Pass { + fn name(&self) -> &'static str { + "Pass" + } + fn get_lints(&self) -> LintArray { lint_array!(TEST_LINT, PLEASE_LINT) } diff --git a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs index 9b0127ea5c006..4e45189b42427 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs @@ -19,6 +19,10 @@ declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); struct Pass; impl LintPass for Pass { + fn name(&self) -> &'static str { + "Pass" + } + fn get_lints(&self) -> LintArray { lint_array!(TEST_LINT) } diff --git a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs index 5c9569ddc6575..1a9bd9e66dbac 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs @@ -18,6 +18,10 @@ declare_tool_lint!(pub clippy::TEST_GROUP, Warn, "Warn about other stuff"); struct Pass; impl LintPass for Pass { + fn name(&self) -> &'static str { + "Pass" + } + fn get_lints(&self) -> LintArray { lint_array!(TEST_LINT, TEST_GROUP) }