diff --git a/Cargo.lock b/Cargo.lock index 6ea4cd8f5aca4..0460248dd3461 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4033,6 +4033,7 @@ dependencies = [ "rustc_hir", "rustc_hir_pretty", "rustc_index", + "rustc_lint_defs", "rustc_macros", "rustc_query_system", "rustc_serialize", diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 94a00ab1a047e..b2cd75ad8f06e 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -223,7 +223,7 @@ impl AttrItem { self.args.span().map_or(self.path.span, |args_span| self.path.span.to(args_span)) } - fn meta_item_list(&self) -> Option> { + pub fn meta_item_list(&self) -> Option> { match &self.args { AttrArgs::Delimited(args) if args.delim == Delimiter::Parenthesis => { MetaItemKind::list_from_tokens(args.tokens.clone()) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 779b98d073dab..f7b803b1f07b7 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -895,7 +895,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { tcx.ensure().check_mod_privacy(module); }); }); - } + } // { sess.time("mir_checking", || { tcx.hir().mir_for }) } ); // This check has to be run after all lints are done processing. We don't diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index d8482567bbe5b..266a8bc715eaa 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -20,6 +20,7 @@ //! If you define a new `LateLintPass`, you will also need to add it to the //! `late_lint_methods!` invocation in `lib.rs`. +use std::default::Default; use std::fmt::Write; use ast::token::TokenKind; @@ -73,6 +74,10 @@ use crate::{ fluent_generated as fluent, EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext, }; +// use std::fmt::Write; + +// hardwired lints from rustc_lint_defs +// pub use rustc_session::lint::builtin::*; declare_lint! { /// The `while_true` lint detects `while true { }`. @@ -242,7 +247,8 @@ declare_lint! { /// behavior. UNSAFE_CODE, Allow, - "usage of `unsafe` code and other potentially unsound constructs" + "usage of `unsafe` code and other potentially unsound constructs", + [loadbearing: true] } declare_lint_pass!(UnsafeCode => [UNSAFE_CODE]); @@ -390,6 +396,7 @@ declare_lint! { report_in_external_macro } +#[derive(Default)] pub struct MissingDoc; impl_lint_pass!(MissingDoc => [MISSING_DOCS]); @@ -830,8 +837,8 @@ pub struct DeprecatedAttr { impl_lint_pass!(DeprecatedAttr => []); -impl DeprecatedAttr { - pub fn new() -> DeprecatedAttr { +impl Default for DeprecatedAttr { + fn default() -> Self { DeprecatedAttr { depr_attrs: deprecated_attributes() } } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 0ee9dda1fefa2..a0e6ef814e7ef 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -312,6 +312,9 @@ impl LintPass for RuntimeCombinedEarlyLintPass<'_> { fn name(&self) -> &'static str { panic!() } + fn get_lints(&self) -> crate::LintVec { + panic!() + } } macro_rules! impl_early_lint_pass { diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 65571815019ea..2c5e052653f1c 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -395,7 +395,8 @@ declare_tool_lint! { pub rustc::UNTRANSLATABLE_DIAGNOSTIC, Deny, "prevent creation of diagnostics which cannot be translated", - report_in_external_macro: true + report_in_external_macro: true, + [loadbearing: true] } declare_tool_lint! { @@ -408,7 +409,8 @@ declare_tool_lint! { pub rustc::DIAGNOSTIC_OUTSIDE_OF_IMPL, Deny, "prevent diagnostic creation outside of `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls", - report_in_external_macro: true + report_in_external_macro: true, + [loadbearing: true] } declare_lint_pass!(Diagnostics => [UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE_OF_IMPL]); diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index cb369d99a8450..017c3bf517243 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -24,13 +24,14 @@ use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::{intravisit as hir_visit, HirId}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, TyCtxt}; +use rustc_session::lint::builtin::HardwiredLints; use rustc_session::lint::LintPass; use rustc_session::Session; use rustc_span::Span; use tracing::debug; use crate::passes::LateLintPassObject; -use crate::{LateContext, LateLintPass, LintStore}; +use crate::{LateContext, LateLintPass, LintId, LintStore}; /// Extract the [`LintStore`] from [`Session`]. /// @@ -327,6 +328,9 @@ impl LintPass for RuntimeCombinedLateLintPass<'_, '_> { fn name(&self) -> &'static str { panic!() } + fn get_lints(&self) -> crate::LintVec { + panic!() + } } macro_rules! impl_late_lint_pass { @@ -362,13 +366,33 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>( // Note: `passes` is often empty. In that case, it's faster to run // `builtin_lints` directly rather than bundling it up into the // `RuntimeCombinedLateLintPass`. - let late_module_passes = &unerased_lint_store(tcx.sess).late_module_passes; - if late_module_passes.is_empty() { + let store = unerased_lint_store(tcx.sess); + + if store.late_module_passes.is_empty() { late_lint_mod_inner(tcx, module_def_id, context, builtin_lints); } else { - let mut passes: Vec<_> = late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect(); - passes.push(Box::new(builtin_lints)); - let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] }; + let passes: Vec<_> = + store.late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect(); + // Filter unused lints + let lints_that_dont_need_to_run = tcx.lints_that_dont_need_to_run(()); + let mut filtered_passes: Vec>> = passes + .into_iter() + .filter(|pass| { + let lints = LintPass::get_lints(pass); + if lints.is_empty() { + true + } else { + lints + .iter() + .any(|lint| !lints_that_dont_need_to_run.contains(&LintId::of(lint))) + } + }) + .collect(); + + filtered_passes.push(Box::new(builtin_lints)); + filtered_passes.push(Box::new(HardwiredLints)); + + let pass = RuntimeCombinedLateLintPass { passes: &mut filtered_passes[..] }; late_lint_mod_inner(tcx, module_def_id, context, pass); } } @@ -399,7 +423,7 @@ fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>( fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) { // Note: `passes` is often empty. - let mut passes: Vec<_> = + let passes: Vec<_> = unerased_lint_store(tcx.sess).late_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect(); if passes.is_empty() { @@ -417,7 +441,30 @@ fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) { only_module: false, }; - let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] }; + let lints_that_dont_need_to_run = tcx.lints_that_dont_need_to_run(()); + + // dbg!(&lints_that_dont_need_to_run); + let mut filtered_passes: Vec>> = passes + .into_iter() + .filter(|pass| { + let lints = LintPass::get_lints(pass); + !lints.iter().all(|lint| lints_that_dont_need_to_run.contains(&LintId::of(lint))) + }) + .collect(); + + filtered_passes.push(Box::new(HardwiredLints)); + + // let mut filtered_passes: Vec>> = passes + // .into_iter() + // .filter(|pass| { + // let lints = LintPass::get_lints(pass); + // lints.iter() + // .any(|lint| + // !lints_that_dont_need_to_run.contains(&LintId::of(lint))) + // }).collect(); + // + + let pass = RuntimeCombinedLateLintPass { passes: &mut filtered_passes[..] }; late_lint_crate_inner(tcx, context, pass); } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 07ac63ec96cf1..361865c6afd76 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1,5 +1,5 @@ use rustc_ast_pretty::pprust; -use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{Diag, LintDiagnostic, MultiSpan}; use rustc_feature::{Features, GateIssue}; use rustc_hir::intravisit::{self, Visitor}; @@ -31,7 +31,7 @@ use crate::errors::{ OverruledAttributeSub, RequestedLevel, UnknownToolInScopedLint, UnsupportedGroup, }; use crate::fluent_generated as fluent; -use crate::late::unerased_lint_store; +use crate::late::{unerased_lint_store /*name_without_tool*/}; use crate::lints::{ DeprecatedLintName, DeprecatedLintNameFromCommandLine, IgnoredUnlessCrateSpecified, OverruledAttributeLint, RemovedLint, RemovedLintFromCommandLine, RenamedLint, @@ -143,6 +143,43 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp builder.provider.expectations } +fn lints_that_dont_need_to_run(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { + let store = unerased_lint_store(&tcx.sess); + + let dont_need_to_run: FxIndexSet = store + .get_lints() + .into_iter() + .filter_map(|lint| { + if !lint.loadbearing && lint.default_level(tcx.sess.edition()) == Level::Allow { + Some(LintId::of(lint)) + } else { + None + } + }) + .collect(); + + let mut visitor = LintLevelMaximum { tcx, dont_need_to_run }; + visitor.process_opts(); + tcx.hir().walk_attributes(&mut visitor); + + // let lint_groups = store.get_lint_groups(); + // for group in lint_groups { + // let binding = group.0.to_lowercase(); + // let group_name = name_without_tool(&binding).to_string(); + // if visitor.lints_that_actually_run.contains(&group_name) { + // for lint in group.1 { + // visitor.lints_that_actually_run.insert(name_without_tool(&lint.to_string()).to_string()); + // } + // } else if visitor.lints_allowed.contains(&group_name) { + // for lint in &group.1 { + // visitor.lints_allowed.insert(name_without_tool(&lint.to_string()).to_string()); + // } + // } + // } + + visitor.dont_need_to_run +} + #[instrument(level = "trace", skip(tcx), ret)] fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap { let store = unerased_lint_store(tcx.sess); @@ -245,7 +282,7 @@ impl LintLevelsProvider for LintLevelQueryMap<'_> { } } -struct QueryMapExpectationsWrapper<'tcx> { +pub(crate) struct QueryMapExpectationsWrapper<'tcx> { tcx: TyCtxt<'tcx>, /// HirId of the currently investigated element. cur: HirId, @@ -442,6 +479,122 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<' } } +/// Visitor with the only function of visiting every item-like in a crate and +/// computing the highest level that every lint gets put to. +/// +/// E.g., if a crate has a global #![allow(lint)] attribute, but a single item +/// uses #[warn(lint)], this visitor will set that lint level as `Warn` +struct LintLevelMaximum<'tcx> { + tcx: TyCtxt<'tcx>, + /// The actual list of detected lints. + dont_need_to_run: FxIndexSet, +} + +impl<'tcx> LintLevelMaximum<'tcx> { + fn process_opts(&mut self) { + let store = unerased_lint_store(self.tcx.sess); + for (lint_group, level) in &self.tcx.sess.opts.lint_opts { + if *level != Level::Allow { + let Ok(lints) = store.find_lints(lint_group) else { + return; + }; + for lint in lints { + self.dont_need_to_run.swap_remove(&lint); + } + } + } + } +} + +impl<'tcx> Visitor<'tcx> for LintLevelMaximum<'tcx> { + type NestedFilter = nested_filter::All; + + fn nested_visit_map(&mut self) -> Self::Map { + self.tcx.hir() + } + + fn visit_attribute(&mut self, attribute: &'tcx ast::Attribute) { + match Level::from_attr(attribute) { + Some( + Level::Warn + | Level::Deny + | Level::Forbid + | Level::Expect(..) + | Level::ForceWarn(..), + ) => { + let store = unerased_lint_store(self.tcx.sess); + let Some(meta) = attribute.meta() else { return }; + // SAFETY: Lint attributes are always a metalist inside a + // metalist (even with just one lint). + let Some(meta_item_list) = meta.meta_item_list() else { return }; + + for meta_list in meta_item_list { + // Convert Path to String + let Some(meta_item) = meta_list.meta_item() else { return }; + let ident: &str = &meta_item + .path + .segments + .iter() + .map(|segment| segment.ident.as_str()) + .collect::>() + .join("::"); + let Ok(lints) = store.find_lints( + // SAFETY: Lint attributes can only have literals + ident, + ) else { + return; + }; + for lint in lints { + self.dont_need_to_run.swap_remove(&lint); + } + // // If it's a tool lint (e.g. clippy::my_clippy_lint) + // if let ast::NestedMetaItem::MetaItem(meta_item) = meta_list { + // if meta_item.path.segments.len() == 1 { + // let Ok(lints) = store.find_lints( + // // SAFETY: Lint attributes can only have literals + // meta_list.ident().unwrap().name.as_str(), + // ) else { + // return; + // }; + // for lint in lints { + // dbg!("LINT REMOVED", &lint); + // self.dont_need_to_run.swap_remove(&lint); + // } + // } else { + // let Ok(lints) = store.find_lints( + // // SAFETY: Lint attributes can only have literals + // meta_item.path.segments[1].ident.name.as_str(), + // ) else { + // return; + // }; + // for lint in lints { + // dbg!("LINT REMOVED", &lint); + // self.dont_need_to_run.swap_remove(&lint); + // } + // } + } + // We handle #![allow]s differently, as these remove checking rather than adding. + } // Some(Level::Allow) if ast::AttrStyle::Inner == attribute.style => { + // for meta_list in meta.meta_item_list().unwrap() { + // // If it's a tool lint (e.g. clippy::my_clippy_lint) + // if let ast::NestedMetaItem::MetaItem(meta_item) = meta_list { + // if meta_item.path.segments.len() == 1 { + // self.lints_allowed + // .insert(meta_list.name_or_empty().as_str().to_string()); + // } else { + // self.lints_allowed + // .insert(meta_item.path.segments[1].ident.name.as_str().to_string()); + // } + // } + // } + // } + _ => { + return; + } + } + } +} + pub struct LintLevelsBuilder<'s, P> { sess: &'s Session, features: &'s Features, @@ -1100,7 +1253,12 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { } pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { shallow_lint_levels_on, lint_expectations, ..*providers }; + *providers = Providers { + shallow_lint_levels_on, + lint_expectations, + lints_that_dont_need_to_run, + ..*providers + }; } pub(crate) fn parse_lint_and_tool_name(lint_name: &str) -> (Option, &str) { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c5a5c5b30afef..ea7c7a48d84ce 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -30,6 +30,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(array_windows)] +#![feature(box_into_inner)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(extract_if)] @@ -164,7 +165,7 @@ early_lint_methods!( [ pub BuiltinCombinedEarlyLintPass, [ - UnusedParens: UnusedParens::new(), + UnusedParens: UnusedParens::default(), UnusedBraces: UnusedBraces, UnusedImportBraces: UnusedImportBraces, UnsafeCode: UnsafeCode, @@ -172,7 +173,7 @@ early_lint_methods!( AnonymousParameters: AnonymousParameters, EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(), NonCamelCaseTypes: NonCamelCaseTypes, - DeprecatedAttr: DeprecatedAttr::new(), + DeprecatedAttr: DeprecatedAttr::default(), WhileTrue: WhileTrue, NonAsciiIdents: NonAsciiIdents, HiddenUnicodeCodepoints: HiddenUnicodeCodepoints, @@ -193,7 +194,6 @@ late_lint_methods!( ForLoopsOverFallibles: ForLoopsOverFallibles, DerefIntoDynSupertrait: DerefIntoDynSupertrait, DropForgetUseless: DropForgetUseless, - HardwiredLints: HardwiredLints, ImproperCTypesDeclarations: ImproperCTypesDeclarations, ImproperCTypesDefinitions: ImproperCTypesDefinitions, InvalidFromUtf8: InvalidFromUtf8, @@ -271,6 +271,7 @@ fn register_builtins(store: &mut LintStore) { store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints()); store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints()); store.register_lints(&foreign_modules::get_lints()); + store.register_lints(&HardwiredLints::default().get_lints()); add_lint_group!( "nonstandard_style", @@ -578,25 +579,25 @@ fn register_builtins(store: &mut LintStore) { } fn register_internals(store: &mut LintStore) { - store.register_lints(&LintPassImpl::get_lints()); + store.register_lints(&LintPassImpl::default().get_lints()); store.register_early_pass(|| Box::new(LintPassImpl)); - store.register_lints(&DefaultHashTypes::get_lints()); + store.register_lints(&DefaultHashTypes::default().get_lints()); store.register_late_mod_pass(|_| Box::new(DefaultHashTypes)); - store.register_lints(&QueryStability::get_lints()); + store.register_lints(&QueryStability::default().get_lints()); store.register_late_mod_pass(|_| Box::new(QueryStability)); - store.register_lints(&ExistingDocKeyword::get_lints()); + store.register_lints(&ExistingDocKeyword::default().get_lints()); store.register_late_mod_pass(|_| Box::new(ExistingDocKeyword)); - store.register_lints(&TyTyKind::get_lints()); + store.register_lints(&TyTyKind::default().get_lints()); store.register_late_mod_pass(|_| Box::new(TyTyKind)); - store.register_lints(&TypeIr::get_lints()); + store.register_lints(&TypeIr::default().get_lints()); store.register_late_mod_pass(|_| Box::new(TypeIr)); - store.register_lints(&Diagnostics::get_lints()); + store.register_lints(&Diagnostics::default().get_lints()); store.register_late_mod_pass(|_| Box::new(Diagnostics)); - store.register_lints(&BadOptAccess::get_lints()); + store.register_lints(&BadOptAccess::default().get_lints()); store.register_late_mod_pass(|_| Box::new(BadOptAccess)); - store.register_lints(&PassByValue::get_lints()); + store.register_lints(&PassByValue::default().get_lints()); store.register_late_mod_pass(|_| Box::new(PassByValue)); - store.register_lints(&SpanUseEqCtxt::get_lints()); + store.register_lints(&SpanUseEqCtxt::default().get_lints()); store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt)); // FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and // `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index bf16e3b7d150f..dda2ae399f438 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -68,7 +68,18 @@ macro_rules! declare_late_lint_pass { // for all the `check_*` methods. late_lint_methods!(declare_late_lint_pass, []); -impl LateLintPass<'_> for HardwiredLints {} +impl LateLintPass<'_> for HardwiredLints { + fn check_fn( + &mut self, + _: &LateContext<'_>, + _: rustc_hir::intravisit::FnKind<'_>, + _: &'_ rustc_hir::FnDecl<'_>, + _: &'_ rustc_hir::Body<'_>, + _: rustc_span::Span, + _: rustc_span::def_id::LocalDefId, + ) { + } +} #[macro_export] macro_rules! expand_combined_late_lint_pass_method { @@ -108,7 +119,7 @@ macro_rules! declare_combined_late_lint_pass { $v fn get_lints() -> $crate::LintVec { let mut lints = Vec::new(); - $(lints.extend_from_slice(&$pass::get_lints());)* + $(lints.extend_from_slice(&$pass::default().get_lints());)* lints } } @@ -122,6 +133,9 @@ macro_rules! declare_combined_late_lint_pass { fn name(&self) -> &'static str { panic!() } + fn get_lints(&self) -> LintVec { + panic!() + } } ) } @@ -218,7 +232,7 @@ macro_rules! declare_combined_early_lint_pass { $v fn get_lints() -> $crate::LintVec { let mut lints = Vec::new(); - $(lints.extend_from_slice(&$pass::get_lints());)* + $(lints.extend_from_slice(&$pass::default().get_lints());)* lints } } @@ -232,6 +246,9 @@ macro_rules! declare_combined_early_lint_pass { fn name(&self) -> &'static str { panic!() } + fn get_lints(&self) -> LintVec { + panic!() + } } ) } diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs index bb9c7d85c2efc..7c38849c1bb25 100644 --- a/compiler/rustc_lint/src/shadowed_into_iter.rs +++ b/compiler/rustc_lint/src/shadowed_into_iter.rs @@ -64,7 +64,7 @@ declare_lint! { }; } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Default)] pub(crate) struct ShadowedIntoIter; impl_lint_pass!(ShadowedIntoIter => [ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER]); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index f2f7c0eaa4df8..074ffcc273501 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -164,7 +164,7 @@ declare_lint! { "detects ambiguous wide pointer comparisons" } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Default)] pub(crate) struct TypeLimits { /// Id of the last visited negated expression negated_expr_id: Option, diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index c3b80e01c3624..288210345c0cc 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1026,8 +1026,8 @@ pub(crate) struct UnusedParens { parens_in_cast_in_lt: Vec, } -impl UnusedParens { - pub(crate) fn new() -> Self { +impl Default for UnusedParens { + fn default() -> Self { Self { with_self_ty_parens: false, parens_in_cast_in_lt: Vec::new() } } } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 04fd7c9c627e4..14a5f60514863 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -12,8 +12,6 @@ use rustc_span::edition::Edition; use crate::{declare_lint, declare_lint_pass, FutureIncompatibilityReason}; declare_lint_pass! { - /// Does nothing as a lint pass, but registers some `Lint`s - /// that are used by other parts of the compiler. HardwiredLints => [ // tidy-alphabetical-start ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, @@ -377,7 +375,8 @@ declare_lint! { /// will not overflow. pub ARITHMETIC_OVERFLOW, Deny, - "arithmetic operation overflows" + "arithmetic operation overflows", + [loadbearing: true] } declare_lint! { @@ -401,7 +400,8 @@ declare_lint! { /// `panic!` or `unreachable!` macro instead in case the panic is intended. pub UNCONDITIONAL_PANIC, Deny, - "operation will cause a panic at runtime" + "operation will cause a panic at runtime", + [loadbearing: true] } declare_lint! { @@ -632,7 +632,8 @@ declare_lint! { /// is only available in a newer version. pub UNKNOWN_LINTS, Warn, - "unrecognized lint attribute" + "unrecognized lint attribute", + [loadbearing: true] } declare_lint! { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index c17b85db3b044..af3cf7a3b6233 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -333,6 +333,10 @@ pub struct Lint { pub feature_gate: Option, pub crate_level_only: bool, + + /// `true` if this lint should not be filtered out under any circustamces + /// (e.g. the unknown_attributes lint) + pub loadbearing: bool, } /// Extra information for a future incompatibility lint. @@ -477,6 +481,7 @@ impl Lint { future_incompatible: None, feature_gate: None, crate_level_only: false, + loadbearing: false, } } @@ -872,7 +877,7 @@ macro_rules! declare_lint { $(#[$attr])* $vis $NAME, $Level, $desc, ); ); - ($(#[$attr:meta])* $vis: vis $NAME: ident, $Level: ident, $desc: expr, + ($(#[$attr:meta])* $vis: vis $NAME: ident, $Level: ident, $desc: expr, $([loadbearing: $loadbearing: literal])? $(@feature_gate = $gate:ident;)? $(@future_incompatible = FutureIncompatibleInfo { reason: $reason:expr, @@ -894,6 +899,7 @@ macro_rules! declare_lint { ..$crate::FutureIncompatibleInfo::default_fields_for_macro() }),)? $(edition_lint_opts: Some(($crate::Edition::$lint_edition, $crate::$edition_level)),)? + $(loadbearing: $loadbearing,)? ..$crate::Lint::default_fields_for_macro() }; ); @@ -904,6 +910,7 @@ macro_rules! declare_tool_lint { ( $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level: ident, $desc: expr $(, @feature_gate = $gate:ident;)? + $(, [loadbearing: $loadbearing: literal])? ) => ( $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false $(, @feature_gate = $gate;)?} ); @@ -911,6 +918,7 @@ macro_rules! declare_tool_lint { $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr, report_in_external_macro: $rep:expr $(, @feature_gate = $gate:ident;)? + $(, [loadbearing: $loadbearing: literal])? ) => ( $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep $(, @feature_gate = $gate;)?} ); @@ -918,6 +926,7 @@ macro_rules! declare_tool_lint { $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr, $external:expr $(, @feature_gate = $gate:ident;)? + $(, [loadbearing: $loadbearing: literal])? ) => ( $(#[$attr])* $vis static $NAME: &$crate::Lint = &$crate::Lint { @@ -930,6 +939,7 @@ macro_rules! declare_tool_lint { is_externally_loaded: true, $(feature_gate: Some(rustc_span::symbol::sym::$gate),)? crate_level_only: false, + $(loadbearing: $loadbearing,)? ..$crate::Lint::default_fields_for_macro() }; ); @@ -939,6 +949,7 @@ pub type LintVec = Vec<&'static Lint>; pub trait LintPass { fn name(&self) -> &'static str; + fn get_lints(&self) -> LintVec; } /// Implements `LintPass for $ty` with the given list of `Lint` statics. @@ -947,9 +958,7 @@ macro_rules! impl_lint_pass { ($ty:ty => [$($lint:expr),* $(,)?]) => { impl $crate::LintPass for $ty { fn name(&self) -> &'static str { stringify!($ty) } - } - impl $ty { - pub fn get_lints() -> $crate::LintVec { vec![$($lint),*] } + fn get_lints(&self) -> $crate::LintVec { vec![$($lint),*] } } }; } @@ -959,7 +968,18 @@ macro_rules! impl_lint_pass { #[macro_export] macro_rules! declare_lint_pass { ($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => { - $(#[$m])* #[derive(Copy, Clone)] pub struct $name; + $(#[$m])* #[derive(Copy, Clone, Default)] pub struct $name; $crate::impl_lint_pass!($name => [$($lint),*]); }; } + +#[allow(rustc::lint_pass_impl_without_macro)] +impl LintPass for Box

{ + fn name(&self) -> &'static str { + (**self).name() + } + + fn get_lints(&self) -> LintVec { + (**self).get_lints() + } +} diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 69e3b703ccee1..1b46ebbf99af9 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -26,6 +26,7 @@ rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_index = { path = "../rustc_index" } +rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } rustc_query_system = { path = "../rustc_query_system" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 8c27cac1ea858..0c2cf30888d3a 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -116,7 +116,7 @@ impl ShallowLintLevelMap { /// This lint level is not usable for diagnostics, it needs to be corrected by /// `reveal_actual_level` beforehand. #[instrument(level = "trace", skip(self, tcx), ret)] - fn probe_for_lint_level( + pub fn probe_for_lint_level( &self, tcx: TyCtxt<'_>, id: LintId, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b6443778c936b..2c578a2c7b859 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -28,6 +28,7 @@ use rustc_hir::def_id::{ use rustc_hir::lang_items::{LangItem, LanguageItems}; use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, TraitCandidate}; use rustc_index::IndexVec; +use rustc_lint_defs::LintId; use rustc_macros::rustc_queries; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{try_get_cached, QueryCache, QueryMode, QueryState}; @@ -420,6 +421,11 @@ rustc_queries! { desc { "computing `#[expect]`ed lints in this crate" } } + query lints_that_dont_need_to_run(_: ()) -> &'tcx FxIndexSet { + arena_cache + desc { "Computing all lints that are explicitly enabled or with a default level greater than Allow" } + } + query expn_that_defined(key: DefId) -> rustc_span::ExpnId { desc { |tcx| "getting the expansion that defined `{}`", tcx.def_path_str(key) } separate_provide_extern diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 70430d82ab55b..7f86d855d00cf 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -186,6 +186,7 @@ pub struct Session { /// errors. pub ctfe_backtrace: Lock, + // pub force_ctfe: bool, /// This tracks where `-Zunleash-the-miri-inside-of-you` was used to get around a /// const check, optionally with the relevant feature gate. We use this to /// warn about unleashing, but with a single diagnostic instead of dozens that diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs index 754ba58648df6..84d70a7439beb 100644 --- a/src/librustdoc/lint.rs +++ b/src/librustdoc/lint.rs @@ -2,7 +2,7 @@ use std::sync::LazyLock as Lazy; use rustc_data_structures::fx::FxHashMap; use rustc_lint::LintStore; -use rustc_lint_defs::{declare_tool_lint, Lint, LintId}; +use rustc_lint_defs::{declare_tool_lint, Lint, LintId, LintPass}; use rustc_session::{lint, Session}; /// This function is used to setup the lint initialization. By default, in rustdoc, everything @@ -31,9 +31,10 @@ where allowed_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned()); let lints = || { - lint::builtin::HardwiredLints::get_lints() + lint::builtin::HardwiredLints::default() + .get_lints() .into_iter() - .chain(rustc_lint::SoftLints::get_lints()) + .chain(rustc_lint::SoftLints::default().get_lints()) }; let lint_opts = lints() diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs index 0099eefbc8dc1..ed0a0eb106b79 100644 --- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs @@ -8,30 +8,44 @@ use core::ops::ControlFlow; use rustc_ast::ast::Attribute; use rustc_hir::intravisit::FnKind; use rustc_hir::{Body, Expr, ExprKind, FnDecl}; -use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_lint::Level::Allow; +use rustc_lint::{LateContext, LateLintPass, Lint, LintContext}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::{sym, Span}; -declare_clippy_lint! { - /// ### What it does - /// Checks for methods with high cognitive complexity. - /// - /// ### Why is this bad? - /// Methods of high cognitive complexity tend to be hard to - /// both read and maintain. Also LLVM will tend to optimize small methods better. - /// - /// ### Known problems - /// Sometimes it's hard to find a way to reduce the - /// complexity. - /// - /// ### Example - /// You'll see it when you get the warning. - #[clippy::version = "1.35.0"] - pub COGNITIVE_COMPLEXITY, - nursery, - "functions that should be split up into multiple functions" -} +use crate::LintInfo; + +pub static COGNITIVE_COMPLEXITY: &Lint = &Lint { + name: &"clippy::COGNITIVE_COMPLEXITY", + default_level: Allow, + desc: "functions that should be split up into multiple functions", + edition_lint_opts: None, + report_in_external_macro: true, + future_incompatible: None, + is_externally_loaded: true, + crate_level_only: false, + loadbearing: true, + ..Lint::default_fields_for_macro() +}; +pub(crate) static COGNITIVE_COMPLEXITY_INFO: &'static LintInfo = &LintInfo { + lint: &COGNITIVE_COMPLEXITY, + category: crate::LintCategory::Nursery, + explanation: r"### What it does +Checks for methods with high cognitive complexity. + +### Why is this bad? +Methods of high cognitive complexity tend to be hard to both read and maintain. +Also LLVM will tend to optimize small methods better. + +### Known problems +Sometimes it's hard to find a way to reduce the complexity. + +### Example +You'll see it when you get the warning.", + version: Some("1.35.0"), + location: "#L0", +}; pub struct CognitiveComplexity { limit: LimitStack, diff --git a/src/tools/clippy/clippy_lints/src/ctfe.rs b/src/tools/clippy/clippy_lints/src/ctfe.rs new file mode 100644 index 0000000000000..7b9f71810a999 --- /dev/null +++ b/src/tools/clippy/clippy_lints/src/ctfe.rs @@ -0,0 +1,54 @@ +use rustc_hir::def_id::LocalDefId; +use rustc_hir::intravisit::FnKind; +use rustc_hir::{Body, FnDecl}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::declare_lint_pass; +use rustc_span::Span; + +declare_clippy_lint! { + /// ### What it does + /// Checks for comparisons where one side of the relation is + /// either the minimum or maximum value for its type and warns if it involves a + /// case that is always true or always false. Only integer and boolean types are + /// checked. + /// + /// ### Why is this bad? + /// An expression like `min <= x` may misleadingly imply + /// that it is possible for `x` to be less than the minimum. Expressions like + /// `max < x` are probably mistakes. + /// + /// ### Known problems + /// For `usize` the size of the current compile target will + /// be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such + /// a comparison to detect target pointer width will trigger this lint. One can + /// use `mem::sizeof` and compare its value or conditional compilation + /// attributes + /// like `#[cfg(target_pointer_width = "64")] ..` instead. + /// + /// ### Example + /// ```no_run + /// let vec: Vec = Vec::new(); + /// if vec.len() <= 0 {} + /// if 100 > i32::MAX {} + /// ``` + #[clippy::version = "1.82.0"] + pub CLIPPY_CTFE, + correctness, + "a comparison with a maximum or minimum value that is always true or false" +} + +declare_lint_pass! { ClippyCtfe => [CLIPPY_CTFE] } + +impl<'tcx> LateLintPass<'tcx> for ClippyCtfe { + fn check_fn( + &mut self, + cx: &LateContext<'_>, + _: FnKind<'tcx>, + _: &'tcx FnDecl<'tcx>, + _: &'tcx Body<'tcx>, + _: Span, + defid: LocalDefId, + ) { + cx.tcx.ensure().mir_drops_elaborated_and_const_checked(defid); // Lint + } +} diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 2ac06b360bea4..5a1bd5d4c340b 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -66,6 +66,7 @@ extern crate declare_clippy_lint; #[cfg_attr(feature = "internal", allow(clippy::missing_clippy_version_attribute))] mod utils; +pub mod ctfe; // VERY important lint (rust#125116) pub mod declared_lints; pub mod deprecated_lints; @@ -597,6 +598,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { }); } + store.register_late_pass(|_| Box::new(ctfe::ClippyCtfe)); + store.register_late_pass(move |_| Box::new(operators::arithmetic_side_effects::ArithmeticSideEffects::new(conf))); store.register_late_pass(|_| Box::new(utils::dump_hir::DumpHir)); store.register_late_pass(|_| Box::new(utils::author::Author)); diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 0cce45290cfe7..40b03af31e566 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -798,3 +798,4 @@ fn path_to_string(path: &QPath<'_>) -> Result { inner(&mut s, path)?; Ok(s) } + diff --git a/src/tools/clippy/declare_clippy_lint/src/lib.rs b/src/tools/clippy/declare_clippy_lint/src/lib.rs index 6aa24329b0659..9cda154189363 100644 --- a/src/tools/clippy/declare_clippy_lint/src/lib.rs +++ b/src/tools/clippy/declare_clippy_lint/src/lib.rs @@ -1,6 +1,7 @@ #![feature(let_chains, proc_macro_span)] // warn on lints, that are included in `rust-lang/rust`s bootstrap #![warn(rust_2018_idioms, unused_lifetimes)] +#![allow(warnings)] use proc_macro::TokenStream; use quote::{format_ident, quote}; diff --git a/src/tools/clippy/tests/ui/author.rs b/src/tools/clippy/tests/ui-internal/author.rs similarity index 72% rename from src/tools/clippy/tests/ui/author.rs rename to src/tools/clippy/tests/ui-internal/author.rs index 0a1be35689670..eb1f3e3f8704c 100644 --- a/src/tools/clippy/tests/ui/author.rs +++ b/src/tools/clippy/tests/ui-internal/author.rs @@ -1,3 +1,5 @@ +#![warn(clippy::author)] + fn main() { #[clippy::author] let x: char = 0x45 as char; diff --git a/src/tools/clippy/tests/ui/author.stdout b/src/tools/clippy/tests/ui-internal/author.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author.stdout rename to src/tools/clippy/tests/ui-internal/author.stdout diff --git a/src/tools/clippy/tests/ui/author/blocks.rs b/src/tools/clippy/tests/ui-internal/author/blocks.rs similarity index 100% rename from src/tools/clippy/tests/ui/author/blocks.rs rename to src/tools/clippy/tests/ui-internal/author/blocks.rs diff --git a/src/tools/clippy/tests/ui/author/blocks.stdout b/src/tools/clippy/tests/ui-internal/author/blocks.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author/blocks.stdout rename to src/tools/clippy/tests/ui-internal/author/blocks.stdout diff --git a/src/tools/clippy/tests/ui/author/call.rs b/src/tools/clippy/tests/ui-internal/author/call.rs similarity index 100% rename from src/tools/clippy/tests/ui/author/call.rs rename to src/tools/clippy/tests/ui-internal/author/call.rs diff --git a/src/tools/clippy/tests/ui/author/call.stdout b/src/tools/clippy/tests/ui-internal/author/call.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author/call.stdout rename to src/tools/clippy/tests/ui-internal/author/call.stdout diff --git a/src/tools/clippy/tests/ui/author/if.rs b/src/tools/clippy/tests/ui-internal/author/if.rs similarity index 100% rename from src/tools/clippy/tests/ui/author/if.rs rename to src/tools/clippy/tests/ui-internal/author/if.rs diff --git a/src/tools/clippy/tests/ui/author/if.stdout b/src/tools/clippy/tests/ui-internal/author/if.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author/if.stdout rename to src/tools/clippy/tests/ui-internal/author/if.stdout diff --git a/src/tools/clippy/tests/ui/author/issue_3849.rs b/src/tools/clippy/tests/ui-internal/author/issue_3849.rs similarity index 100% rename from src/tools/clippy/tests/ui/author/issue_3849.rs rename to src/tools/clippy/tests/ui-internal/author/issue_3849.rs diff --git a/src/tools/clippy/tests/ui/author/issue_3849.stdout b/src/tools/clippy/tests/ui-internal/author/issue_3849.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author/issue_3849.stdout rename to src/tools/clippy/tests/ui-internal/author/issue_3849.stdout diff --git a/src/tools/clippy/tests/ui/author/loop.rs b/src/tools/clippy/tests/ui-internal/author/loop.rs similarity index 100% rename from src/tools/clippy/tests/ui/author/loop.rs rename to src/tools/clippy/tests/ui-internal/author/loop.rs diff --git a/src/tools/clippy/tests/ui/author/loop.stdout b/src/tools/clippy/tests/ui-internal/author/loop.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author/loop.stdout rename to src/tools/clippy/tests/ui-internal/author/loop.stdout diff --git a/src/tools/clippy/tests/ui/author/macro_in_closure.rs b/src/tools/clippy/tests/ui-internal/author/macro_in_closure.rs similarity index 100% rename from src/tools/clippy/tests/ui/author/macro_in_closure.rs rename to src/tools/clippy/tests/ui-internal/author/macro_in_closure.rs diff --git a/src/tools/clippy/tests/ui/author/macro_in_closure.stdout b/src/tools/clippy/tests/ui-internal/author/macro_in_closure.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author/macro_in_closure.stdout rename to src/tools/clippy/tests/ui-internal/author/macro_in_closure.stdout diff --git a/src/tools/clippy/tests/ui/author/macro_in_loop.rs b/src/tools/clippy/tests/ui-internal/author/macro_in_loop.rs similarity index 100% rename from src/tools/clippy/tests/ui/author/macro_in_loop.rs rename to src/tools/clippy/tests/ui-internal/author/macro_in_loop.rs diff --git a/src/tools/clippy/tests/ui/author/macro_in_loop.stdout b/src/tools/clippy/tests/ui-internal/author/macro_in_loop.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author/macro_in_loop.stdout rename to src/tools/clippy/tests/ui-internal/author/macro_in_loop.stdout diff --git a/src/tools/clippy/tests/ui/author/matches.rs b/src/tools/clippy/tests/ui-internal/author/matches.rs similarity index 100% rename from src/tools/clippy/tests/ui/author/matches.rs rename to src/tools/clippy/tests/ui-internal/author/matches.rs diff --git a/src/tools/clippy/tests/ui/author/matches.stdout b/src/tools/clippy/tests/ui-internal/author/matches.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author/matches.stdout rename to src/tools/clippy/tests/ui-internal/author/matches.stdout diff --git a/src/tools/clippy/tests/ui/author/repeat.rs b/src/tools/clippy/tests/ui-internal/author/repeat.rs similarity index 100% rename from src/tools/clippy/tests/ui/author/repeat.rs rename to src/tools/clippy/tests/ui-internal/author/repeat.rs diff --git a/src/tools/clippy/tests/ui/author/repeat.stdout b/src/tools/clippy/tests/ui-internal/author/repeat.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author/repeat.stdout rename to src/tools/clippy/tests/ui-internal/author/repeat.stdout diff --git a/src/tools/clippy/tests/ui/author/struct.rs b/src/tools/clippy/tests/ui-internal/author/struct.rs similarity index 100% rename from src/tools/clippy/tests/ui/author/struct.rs rename to src/tools/clippy/tests/ui-internal/author/struct.rs diff --git a/src/tools/clippy/tests/ui/author/struct.stdout b/src/tools/clippy/tests/ui-internal/author/struct.stdout similarity index 100% rename from src/tools/clippy/tests/ui/author/struct.stdout rename to src/tools/clippy/tests/ui-internal/author/struct.stdout diff --git a/src/tools/clippy/tests/ui/no_lints.rs b/src/tools/clippy/tests/ui/no_lints.rs new file mode 100644 index 0000000000000..a8467bb6ef786 --- /dev/null +++ b/src/tools/clippy/tests/ui/no_lints.rs @@ -0,0 +1,3 @@ +#![deny(clippy::all)] + +fn main() {} \ No newline at end of file diff --git a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs index c3df917ed12d0..6eb698c96f672 100644 --- a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs +++ b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs @@ -6,7 +6,7 @@ extern crate rustc_middle; extern crate rustc_session; -use rustc_session::lint::{LintPass, LintVec}; +use rustc_session::lint::{LintPass, LintVec, Lint}; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; declare_lint! { @@ -21,6 +21,10 @@ impl LintPass for Foo { //~ERROR implementing `LintPass` by hand fn name(&self) -> &'static str { "Foo" } + + fn get_lints(&self) -> Vec<&'static Lint> { + vec![TEST_LINT] + } } macro_rules! custom_lint_pass_macro { @@ -31,6 +35,10 @@ macro_rules! custom_lint_pass_macro { fn name(&self) -> &'static str { "Custom" } + + fn get_lints(&self) -> Vec<&'static Lint> { + vec![TEST_LINT] + } } }; } diff --git a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index ad6e93334cdc4..824eb35424d96 100644 --- a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -12,7 +12,7 @@ LL | #![deny(rustc::lint_pass_impl_without_macro)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: implementing `LintPass` by hand - --> $DIR/lint_pass_impl_without_macro.rs:30:14 + --> $DIR/lint_pass_impl_without_macro.rs:34:14 | LL | impl LintPass for Custom { | ^^^^^^^^