diff --git a/Cargo.lock b/Cargo.lock index 476f5578187b4..66b7f24e2560c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4095,6 +4095,7 @@ dependencies = [ "rustc_graphviz", "rustc_hir", "rustc_index", + "rustc_lint_defs", "rustc_macros", "rustc_query_system", "rustc_serialize", diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 536f78a73edb6..4a48b3c32fd38 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -7,10 +7,7 @@ //! To add a new lint to rustc, declare it here using `declare_lint!()`. //! Then add code to emit the new lint in the appropriate circumstances. //! You can do that in an existing `LintPass` if it makes sense, or in a -//! new `LintPass`, or using `Session::add_lint` elsewhere in the -//! compiler. Only do the latter if the check can't be written cleanly as a -//! `LintPass` (also, note that such lints will need to be defined in -//! `rustc_session::lint::builtin`, not here). +//! new `LintPass`. //! //! If you define a new `EarlyLintPass`, you will also need to add it to the //! `add_early_builtin!` or `add_early_builtin_with_new!` invocation in @@ -39,13 +36,14 @@ use crate::{ BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub, BuiltinWhileTrue, SuggestChangingAssocTypes, }, - EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext, + EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext, LintId, }; use rustc_ast::attr; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::visit::{FnCtxt, FnKind}; use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust::{self, expr_to_string}; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, DecorateLint, MultiSpan}; use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability}; use rustc_hir as hir; @@ -1523,6 +1521,9 @@ declare_lint_pass!( /// unused within this crate, even though downstream crates can't use it /// without producing an error. UnusedBrokenConst => [] + fn is_enabled(&self, _: &FxHashSet) -> bool { + true + } ); impl<'tcx> LateLintPass<'tcx> for UnusedBrokenConst { diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 3c5cde4309b44..48e4607a453c8 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -509,6 +509,9 @@ pub struct LateContext<'tcx> { /// We are only looking at one module pub only_module: bool, + + #[cfg(debug_assertions)] + pub(super) permitted_lints: Cell>, } /// Context for lint checking of the AST, after expansion, before lowering to HIR. @@ -1067,6 +1070,15 @@ impl<'tcx> LintContext for LateContext<'tcx> { &'b mut DiagnosticBuilder<'a, ()>, ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { + #[cfg(debug_assertions)] + if let Some(permitted) = self.permitted_lints.get() { + assert!( + permitted.contains(&lint.name), + "unexpected lint {} emitted from pass. permitted: {permitted:?}", + lint.name + ); + } + let hir_id = self.last_node_with_lint_attrs; match span { diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 4b803621f71ce..2c16a79a4a94e 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -13,7 +13,6 @@ use rustc_hir::{def_id::DefId, Expr, ExprKind, GenericArg, PatKind, Path, PathSe use rustc_hir::{HirId, Impl, Item, ItemKind, Node, Pat, Ty, TyKind}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; @@ -284,18 +283,11 @@ impl EarlyLintPass for LintPassImpl { if let ast::ItemKind::Impl(box ast::Impl { of_trait: Some(lint_pass), .. }) = &item.kind { if let Some(last) = lint_pass.path.segments.last() { if last.ident.name == sym::LintPass { - let expn_data = lint_pass.path.span.ctxt().outer_expn_data(); - let call_site = expn_data.call_site; - if expn_data.kind != ExpnKind::Macro(MacroKind::Bang, sym::impl_lint_pass) - && call_site.ctxt().outer_expn_data().kind - != ExpnKind::Macro(MacroKind::Bang, sym::declare_lint_pass) - { - cx.emit_spanned_lint( - LINT_PASS_IMPL_WITHOUT_MACRO, - lint_pass.path.span, - LintPassByHand, - ); - } + cx.emit_spanned_lint( + LINT_PASS_IMPL_WITHOUT_MACRO, + lint_pass.path.span, + LintPassByHand, + ); } } } diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 6c8b60c8d7413..ece1515e04c9c 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -14,14 +14,16 @@ //! upon. As the ast is traversed, this keeps track of the current lint level //! for all lint attributes. -use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore}; +use crate::{passes::LateLintPassObject, LateContext, LateLintPass, Level, LintId, LintStore}; use rustc_ast as ast; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::join; use rustc_hir as hir; use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit as hir_visit; use rustc_middle::hir::nested_filter; +use rustc_middle::lint::{reveal_actual_level, LintLevelSource}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::LintPass; use rustc_span::Span; @@ -315,8 +317,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas // Combines multiple lint passes into a single pass, at runtime. Each // `check_foo` method in `$methods` within this pass simply calls `check_foo` -// once per `$pass`. Compare with `declare_combined_late_lint_pass`, which is -// similar, but combines lint passes at compile time. +// once per `$pass`. struct RuntimeCombinedLateLintPass<'a, 'tcx> { passes: &'a mut [LateLintPassObject<'tcx>], } @@ -333,6 +334,8 @@ macro_rules! impl_late_lint_pass { impl<'tcx> LateLintPass<'tcx> for RuntimeCombinedLateLintPass<'_, 'tcx> { $(fn $f(&mut self, context: &LateContext<'tcx>, $($param: $arg),*) { for pass in self.passes.iter_mut() { + #[cfg(debug_assertions)] + context.permitted_lints.set(pass.lint_names()); pass.$f(context, $($param),*); } })* @@ -342,11 +345,7 @@ macro_rules! impl_late_lint_pass { crate::late_lint_methods!(impl_late_lint_pass, []); -pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>( - tcx: TyCtxt<'tcx>, - module_def_id: LocalModDefId, - builtin_lints: T, -) { +pub fn late_lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let context = LateContext { tcx, enclosing_body: None, @@ -357,20 +356,20 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>( last_node_with_lint_attrs: tcx.hir().local_def_id_to_hir_id(module_def_id), generics: None, only_module: true, + #[cfg(debug_assertions)] + permitted_lints: Cell::new(None), }; - // 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 mut passes: Vec<_> = - unerased_lint_store(tcx).late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect(); - if passes.is_empty() { - late_lint_mod_inner(tcx, module_def_id, context, builtin_lints); - } else { - passes.push(Box::new(builtin_lints)); - let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] }; - late_lint_mod_inner(tcx, module_def_id, context, pass); - } + let enabled_lints = tcx.enabled_lints(()); + + let mut passes: Vec<_> = unerased_lint_store(tcx) + .late_module_passes + .iter() + .map(|mk_pass| (mk_pass)(tcx)) + .filter(|pass| pass.is_enabled(enabled_lints)) + .collect(); + let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] }; + late_lint_mod_inner(tcx, module_def_id, context, pass); } fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>( @@ -398,9 +397,18 @@ fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>( } fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) { + // Trigger check for duplicate diagnostic items + let _ = tcx.all_diagnostic_items(()); + + let enabled_lints = tcx.enabled_lints(()); + // Note: `passes` is often empty. - let mut passes: Vec<_> = - unerased_lint_store(tcx).late_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect(); + let mut passes: Vec<_> = unerased_lint_store(tcx) + .late_passes + .iter() + .map(|mk_pass| (mk_pass)(tcx)) + .filter(|pass| pass.is_enabled(enabled_lints)) + .collect(); if passes.is_empty() { return; @@ -416,6 +424,8 @@ fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) { last_node_with_lint_attrs: hir::CRATE_HIR_ID, generics: None, only_module: false, + #[cfg(debug_assertions)] + permitted_lints: Cell::new(None), }; let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] }; @@ -456,3 +466,47 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) { }, ); } + +pub(crate) fn enabled_lints(tcx: TyCtxt<'_>) -> FxHashSet { + let get_level = |spec: Option<&FxHashMap<_, _>>, lint| match spec.and_then(|m| m.get(&lint)) { + Some(&(level, source)) => (Some(level), source), + None => (None, LintLevelSource::Default), + }; + let may_lint_shallow = |spec: Option<&FxHashMap<_, _>>, level, mut source, lint| { + let actual = + reveal_actual_level(level, &mut source, tcx.sess, lint, |lint| get_level(spec, lint)); + + actual > Level::Allow + }; + + let root_lints = + tcx.shallow_lint_levels_on(hir::CRATE_OWNER_ID).specs.get(&hir::CRATE_HIR_ID.local_id); + + let mut enabled: FxHashSet<_> = unerased_lint_store(tcx) + .get_lints() + .iter() + .map(|lint| LintId::of(lint)) + .filter(|&lint| { + let (level, source) = get_level(root_lints, lint); + may_lint_shallow(root_lints, level, source, lint) + }) + .collect(); + + for (def_id, maybe_owner) in tcx.hir().krate().owners.iter_enumerated() { + if let hir::MaybeOwner::Owner(_) = maybe_owner { + enabled.extend( + tcx.shallow_lint_levels_on(hir::OwnerId { def_id }) + .specs + .values() + .flat_map(|spec| { + spec.iter().filter(|&(&lint, &(level, source))| { + may_lint_shallow(Some(spec), Some(level), source, lint) + }) + }) + .map(|(&lint, _)| lint), + ); + } + } + + enabled +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 72c103f2d4a1e..0dfe118382b88 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -88,9 +88,7 @@ pub use array_into_iter::ARRAY_INTO_ITER; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; -use rustc_hir::def_id::LocalModDefId; use rustc_middle::query::Providers; -use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, }; @@ -138,11 +136,11 @@ pub fn provide(providers: &mut Providers) { levels::provide(providers); expect::provide(providers); foreign_modules::provide(providers); - *providers = Providers { lint_mod, ..*providers }; -} - -fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { - late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new()); + *providers = Providers { + lint_mod: late_lint_mod, + enabled_lints: |tcx, ()| late::enabled_lints(tcx), + ..*providers + }; } early_lint_methods!( @@ -180,64 +178,6 @@ early_lint_methods!( ] ); -late_lint_methods!( - declare_combined_late_lint_pass, - [ - BuiltinCombinedModuleLateLintPass, - [ - ForLoopsOverFallibles: ForLoopsOverFallibles, - DerefIntoDynSupertrait: DerefIntoDynSupertrait, - DropForgetUseless: DropForgetUseless, - HardwiredLints: HardwiredLints, - ImproperCTypesDeclarations: ImproperCTypesDeclarations, - ImproperCTypesDefinitions: ImproperCTypesDefinitions, - InvalidFromUtf8: InvalidFromUtf8, - VariantSizeDifferences: VariantSizeDifferences, - BoxPointers: BoxPointers, - PathStatements: PathStatements, - LetUnderscore: LetUnderscore, - InvalidReferenceCasting: InvalidReferenceCasting, - // Depends on referenced function signatures in expressions - UnusedResults: UnusedResults, - NonUpperCaseGlobals: NonUpperCaseGlobals, - NonShorthandFieldPatterns: NonShorthandFieldPatterns, - UnusedAllocation: UnusedAllocation, - // Depends on types used in type definitions - MissingCopyImplementations: MissingCopyImplementations, - // Depends on referenced function signatures in expressions - PtrNullChecks: PtrNullChecks, - MutableTransmutes: MutableTransmutes, - TypeAliasBounds: TypeAliasBounds, - TrivialConstraints: TrivialConstraints, - TypeLimits: TypeLimits::new(), - NonSnakeCase: NonSnakeCase, - InvalidNoMangleItems: InvalidNoMangleItems, - // Depends on effective visibilities - UnreachablePub: UnreachablePub, - ExplicitOutlivesRequirements: ExplicitOutlivesRequirements, - InvalidValue: InvalidValue, - DerefNullPtr: DerefNullPtr, - // May Depend on constants elsewhere - UnusedBrokenConst: UnusedBrokenConst, - UnstableFeatures: UnstableFeatures, - UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller, - ArrayIntoIter: ArrayIntoIter::default(), - DropTraitConstraints: DropTraitConstraints, - TemporaryCStringAsPtr: TemporaryCStringAsPtr, - NonPanicFmt: NonPanicFmt, - NoopMethodCall: NoopMethodCall, - EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums, - InvalidAtomicOrdering: InvalidAtomicOrdering, - NamedAsmLabels: NamedAsmLabels, - OpaqueHiddenInferredBound: OpaqueHiddenInferredBound, - MultipleSupertraitUpcastable: MultipleSupertraitUpcastable, - MapUnitFn: MapUnitFn, - MissingDebugImplementations: MissingDebugImplementations, - MissingDoc: MissingDoc, - ] - ] -); - pub fn new_lint_store(internal_lints: bool) -> LintStore { let mut lint_store = LintStore::new(); @@ -259,10 +199,70 @@ fn register_builtins(store: &mut LintStore) { ) } + macro_rules! register_late_mode_passes { + [$($pass:ident: $constructor:expr,)*] => {{ + $( + store.register_lints(&$pass::get_lints()); + store.register_late_mod_pass(|_| Box::new($constructor)); + )* + }} + } + + register_late_mode_passes! { + ForLoopsOverFallibles: ForLoopsOverFallibles, + DerefIntoDynSupertrait: DerefIntoDynSupertrait, + DropForgetUseless: DropForgetUseless, + ImproperCTypesDeclarations: ImproperCTypesDeclarations, + ImproperCTypesDefinitions: ImproperCTypesDefinitions, + InvalidFromUtf8: InvalidFromUtf8, + VariantSizeDifferences: VariantSizeDifferences, + BoxPointers: BoxPointers, + PathStatements: PathStatements, + LetUnderscore: LetUnderscore, + InvalidReferenceCasting: InvalidReferenceCasting, + // Depends on referenced function signatures in expressions + UnusedResults: UnusedResults, + NonUpperCaseGlobals: NonUpperCaseGlobals, + NonShorthandFieldPatterns: NonShorthandFieldPatterns, + UnusedAllocation: UnusedAllocation, + // Depends on types used in type definitions + MissingCopyImplementations: MissingCopyImplementations, + // Depends on referenced function signatures in expressions + PtrNullChecks: PtrNullChecks, + MutableTransmutes: MutableTransmutes, + TypeAliasBounds: TypeAliasBounds, + TrivialConstraints: TrivialConstraints, + TypeLimits: TypeLimits::new(), + NonSnakeCase: NonSnakeCase, + InvalidNoMangleItems: InvalidNoMangleItems, + // Depends on effective visibilities + UnreachablePub: UnreachablePub, + ExplicitOutlivesRequirements: ExplicitOutlivesRequirements, + InvalidValue: InvalidValue, + DerefNullPtr: DerefNullPtr, + // May Depend on constants elsewhere + UnusedBrokenConst: UnusedBrokenConst, + UnstableFeatures: UnstableFeatures, + UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller, + ArrayIntoIter: ArrayIntoIter::default(), + DropTraitConstraints: DropTraitConstraints, + TemporaryCStringAsPtr: TemporaryCStringAsPtr, + NonPanicFmt: NonPanicFmt, + NoopMethodCall: NoopMethodCall, + EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums, + InvalidAtomicOrdering: InvalidAtomicOrdering, + NamedAsmLabels: NamedAsmLabels, + OpaqueHiddenInferredBound: OpaqueHiddenInferredBound, + MultipleSupertraitUpcastable: MultipleSupertraitUpcastable, + MapUnitFn: MapUnitFn, + MissingDebugImplementations: MissingDebugImplementations, + MissingDoc: MissingDoc, + } + store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints()); store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints()); - store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints()); store.register_lints(&foreign_modules::get_lints()); + store.register_lints(&HardwiredLints::get_lints()); add_lint_group!( "nonstandard_style", diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 508f3e1ec3106..0c6cf0a023bc0 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -1,6 +1,5 @@ use crate::context::{EarlyContext, LateContext}; -use rustc_session::lint::builtin::HardwiredLints; use rustc_session::lint::LintPass; #[macro_export] @@ -73,8 +72,6 @@ macro_rules! declare_late_lint_pass { // for all the `check_*` methods. late_lint_methods!(declare_late_lint_pass, []); -impl LateLintPass<'_> for HardwiredLints {} - #[macro_export] macro_rules! expand_combined_late_lint_pass_method { ([$($pass:ident),*], $self: ident, $name: ident, $params:tt) => ({ diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 7ba589c3b5a39..1d71b1d25dd86 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -8,7 +8,7 @@ extern crate rustc_macros; pub use self::Level::*; use rustc_ast::node_id::NodeId; use rustc_ast::{AttrId, Attribute}; -use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_error_messages::{DiagnosticMessage, MultiSpan}; use rustc_hir::HashStableContext; @@ -444,7 +444,7 @@ impl std::hash::Hash for LintId { impl LintId { /// Gets the `LintId` for a `Lint`. - pub fn of(lint: &'static Lint) -> LintId { + pub const fn of(lint: &'static Lint) -> LintId { LintId { lint } } @@ -789,14 +789,41 @@ pub type LintVec = Vec<&'static Lint>; pub trait LintPass { fn name(&self) -> &'static str; + + fn is_enabled(&self, _enabled_lints: &FxHashSet) -> bool { + true + } + + #[cfg(debug_assertions)] + fn lint_names(&self) -> Option<&'static [&'static str]> { + None + } } /// Implements `LintPass for $ty` with the given list of `Lint` statics. #[macro_export] macro_rules! impl_lint_pass { ($ty:ty => [$($lint:expr),* $(,)?]) => { + $crate::impl_lint_pass! { + $ty => [$($lint),*] + fn is_enabled(&self, enabled_lints: &rustc_data_structures::fx::FxHashSet<$crate::LintId>) -> bool { + [$($lint),*].into_iter() + .any(|lint| enabled_lints.contains(&$crate::LintId::of(lint))) + } + } + }; + ($ty:ty => [$($lint:expr),* $(,)?] $($method:tt)+) => { + #[allow(rustc::lint_pass_impl_without_macro)] impl $crate::LintPass for $ty { fn name(&self) -> &'static str { stringify!($ty) } + + $($method)+ + + #[cfg(debug_assertions)] + fn lint_names(&self) -> Option<&'static [&'static str]> { + static NAMES: &[&str] = &[$($lint.name),*]; + Some(NAMES) + } } impl $ty { pub fn get_lints() -> $crate::LintVec { vec![$($lint),*] } @@ -808,8 +835,11 @@ macro_rules! impl_lint_pass { /// To the right of `=>` a comma separated list of `Lint` statics is given. #[macro_export] macro_rules! declare_lint_pass { - ($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => { + ($(#[$m:meta])* $name:ident => [$($lint:path),* $(,)?] $($tt:tt)*) => { $(#[$m])* #[derive(Copy, Clone)] pub struct $name; - $crate::impl_lint_pass!($name => [$($lint),*]); + $crate::impl_lint_pass!( + $name => [$($lint),*] + $($tt)* + ); }; } diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index bb8e774cea3d1..8a2a6ad7a8f69 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -26,6 +26,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } 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-rayon-core = { version = "0.5.0", optional = true } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 340c5a769dbc4..ab29c8b392f57 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -55,7 +55,7 @@ use rustc_ast as ast; use rustc_ast::expand::{allocator::AllocatorKind, StrippedCfgItem}; use rustc_attr as attr; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; @@ -70,6 +70,7 @@ use rustc_hir::def_id::{ use rustc_hir::lang_items::{LangItem, LanguageItems}; use rustc_hir::{Crate, ItemLocalId, TraitCandidate}; use rustc_index::IndexVec; +use rustc_lint_defs::LintId; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{try_get_cached, CacheSelector, QueryCache, QueryMode, QueryState}; use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; @@ -915,6 +916,12 @@ rustc_queries! { desc { |tcx| "linting {}", describe_as_module(key, tcx) } } + query enabled_lints(key: ()) -> &'tcx FxHashSet { + arena_cache + no_hash + desc { "computing enabled lints" } + } + query check_unused_traits(_: ()) -> () { desc { "checking unused trait imports in crate" } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 3e6066c78fba2..264cf00377ec4 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -10,7 +10,8 @@ use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{HirId, Path}; use rustc_interface::interface; -use rustc_lint::{late_lint_mod, MissingDoc}; +use rustc_lint::builtin::MISSING_DOCS; +use rustc_lint::LintId; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_session::config::{self, CrateType, ErrorOutputType, ResolveDocLinks}; @@ -266,7 +267,7 @@ pub(crate) fn create_config( override_queries: Some(|_sess, providers| { // We do not register late module lints, so this only runs `MissingDoc`. // Most lints will require typechecking, so just don't run them. - providers.lint_mod = |tcx, module_def_id| late_lint_mod(tcx, module_def_id, MissingDoc); + providers.enabled_lints = |_, _| FxHashSet::from_iter([LintId::of(MISSING_DOCS)]); // hack so that `used_trait_imports` won't try to call typeck providers.used_trait_imports = |_, _| { static EMPTY_SET: LazyLock> = LazyLock::new(UnordSet::default); diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index e7fcef9e9de27..8b2b8f98a165a 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -3776,6 +3776,7 @@ impl_lint_pass!(Methods => [ ITER_OUT_OF_BOUNDS, PATH_ENDS_WITH_EXT, REDUNDANT_AS_STR, + crate::redundant_clone::REDUNDANT_CLONE, ]); /// Extracts a method call name, args, and `Span` of the method name. diff --git a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs index 17c1b03d88c61..c74ec80f16357 100644 --- a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs +++ b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs @@ -35,8 +35,6 @@ fn main() { x[const { idx4() }]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays. const { &ARR[idx()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. - // - //~^^ ERROR: failed let y = &x; y[0]; // Ok, referencing shouldn't affect this lint. See the issue 6021 diff --git a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr index f8ace7995939a..d56d6d2bb92ba 100644 --- a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr +++ b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr @@ -1,15 +1,3 @@ -error[E0080]: evaluation of `main::{constant#3}` failed - --> $DIR/test.rs:37:14 - | -LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. - | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 - -note: erroneous constant encountered - --> $DIR/test.rs:37:5 - | -LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true. - | ^^^^^^^^^^^^^^^^^^^^^^ - error: indexing may panic --> $DIR/test.rs:28:5 | @@ -21,7 +9,7 @@ LL | x[index]; = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]` error: indexing may panic - --> $DIR/test.rs:46:5 + --> $DIR/test.rs:44:5 | LL | v[0]; | ^^^^ @@ -29,7 +17,7 @@ LL | v[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/test.rs:47:5 + --> $DIR/test.rs:45:5 | LL | v[10]; | ^^^^^ @@ -37,7 +25,7 @@ LL | v[10]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/test.rs:48:5 + --> $DIR/test.rs:46:5 | LL | v[1 << 3]; | ^^^^^^^^^ @@ -45,7 +33,7 @@ LL | v[1 << 3]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/test.rs:54:5 + --> $DIR/test.rs:52:5 | LL | v[N]; | ^^^^ @@ -53,7 +41,7 @@ LL | v[N]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> $DIR/test.rs:55:5 + --> $DIR/test.rs:53:5 | LL | v[M]; | ^^^^ @@ -66,6 +54,6 @@ error[E0080]: evaluation of constant value failed LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts. | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/tools/clippy/tests/ui/author.stdout b/src/tools/clippy/tests/ui/author.stdout deleted file mode 100644 index 27ad538f24d8c..0000000000000 --- a/src/tools/clippy/tests/ui/author.stdout +++ /dev/null @@ -1,12 +0,0 @@ -if let StmtKind::Local(local) = stmt.kind - && let Some(init) = local.init - && let ExprKind::Cast(expr, cast_ty) = init.kind - && let TyKind::Path(ref qpath) = cast_ty.kind - && match_qpath(qpath, &["char"]) - && let ExprKind::Lit(ref lit) = expr.kind - && let LitKind::Int(69, LitIntType::Unsuffixed) = lit.node - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind - && name.as_str() == "x" -{ - // report your lint here -} diff --git a/src/tools/clippy/tests/ui/author/blocks.stdout b/src/tools/clippy/tests/ui/author/blocks.stdout deleted file mode 100644 index eb3e5189c8238..0000000000000 --- a/src/tools/clippy/tests/ui/author/blocks.stdout +++ /dev/null @@ -1,54 +0,0 @@ -if let ExprKind::Block(block, None) = expr.kind - && block.stmts.len() == 3 - && let StmtKind::Local(local) = block.stmts[0].kind - && let Some(init) = local.init - && let ExprKind::Lit(ref lit) = init.kind - && let LitKind::Int(42, LitIntType::Signed(IntTy::I32)) = lit.node - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind - && name.as_str() == "x" - && let StmtKind::Local(local1) = block.stmts[1].kind - && let Some(init1) = local1.init - && let ExprKind::Lit(ref lit1) = init1.kind - && let LitKind::Float(_, LitFloatType::Suffixed(FloatTy::F32)) = lit1.node - && let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local1.pat.kind - && name1.as_str() == "_t" - && let StmtKind::Semi(e) = block.stmts[2].kind - && let ExprKind::Unary(UnOp::Neg, inner) = e.kind - && let ExprKind::Path(ref qpath) = inner.kind - && match_qpath(qpath, &["x"]) - && block.expr.is_none() -{ - // report your lint here -} -if let ExprKind::Block(block, None) = expr.kind - && block.stmts.len() == 1 - && let StmtKind::Local(local) = block.stmts[0].kind - && let Some(init) = local.init - && let ExprKind::Call(func, args) = init.kind - && let ExprKind::Path(ref qpath) = func.kind - && match_qpath(qpath, &["String", "new"]) - && args.is_empty() - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind - && name.as_str() == "expr" - && let Some(trailing_expr) = block.expr - && let ExprKind::Call(func1, args1) = trailing_expr.kind - && let ExprKind::Path(ref qpath1) = func1.kind - && match_qpath(qpath1, &["drop"]) - && args1.len() == 1 - && let ExprKind::Path(ref qpath2) = args1[0].kind - && match_qpath(qpath2, &["expr"]) -{ - // report your lint here -} -if let ExprKind::Closure(CaptureBy::Value, fn_decl, body_id, _, None) = expr.kind - && let FnRetTy::DefaultReturn(_) = fn_decl.output - && expr1 = &cx.tcx.hir().body(body_id).value - && let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = expr1.kind - && let FnRetTy::DefaultReturn(_) = fn_decl1.output - && expr2 = &cx.tcx.hir().body(body_id1).value - && let ExprKind::Block(block, None) = expr2.kind - && block.stmts.is_empty() - && block.expr.is_none() -{ - // report your lint here -} diff --git a/src/tools/clippy/tests/ui/author/call.stdout b/src/tools/clippy/tests/ui/author/call.stdout deleted file mode 100644 index f040f6330a64d..0000000000000 --- a/src/tools/clippy/tests/ui/author/call.stdout +++ /dev/null @@ -1,14 +0,0 @@ -if let StmtKind::Local(local) = stmt.kind - && let Some(init) = local.init - && let ExprKind::Call(func, args) = init.kind - && let ExprKind::Path(ref qpath) = func.kind - && match_qpath(qpath, &["{{root}}", "std", "cmp", "min"]) - && args.len() == 2 - && let ExprKind::Lit(ref lit) = args[0].kind - && let LitKind::Int(3, LitIntType::Unsuffixed) = lit.node - && let ExprKind::Lit(ref lit1) = args[1].kind - && let LitKind::Int(4, LitIntType::Unsuffixed) = lit1.node - && let PatKind::Wild = local.pat.kind -{ - // report your lint here -} diff --git a/src/tools/clippy/tests/ui/author/if.stdout b/src/tools/clippy/tests/ui/author/if.stdout deleted file mode 100644 index 5d79618820d80..0000000000000 --- a/src/tools/clippy/tests/ui/author/if.stdout +++ /dev/null @@ -1,46 +0,0 @@ -if let StmtKind::Local(local) = stmt.kind - && let Some(init) = local.init - && let ExprKind::If(cond, then, Some(else_expr)) = init.kind - && let ExprKind::DropTemps(expr) = cond.kind - && let ExprKind::Lit(ref lit) = expr.kind - && let LitKind::Bool(true) = lit.node - && let ExprKind::Block(block, None) = then.kind - && block.stmts.len() == 1 - && let StmtKind::Semi(e) = block.stmts[0].kind - && let ExprKind::Binary(op, left, right) = e.kind - && BinOpKind::Eq == op.node - && let ExprKind::Lit(ref lit1) = left.kind - && let LitKind::Int(1, LitIntType::Unsuffixed) = lit1.node - && let ExprKind::Lit(ref lit2) = right.kind - && let LitKind::Int(1, LitIntType::Unsuffixed) = lit2.node - && block.expr.is_none() - && let ExprKind::Block(block1, None) = else_expr.kind - && block1.stmts.len() == 1 - && let StmtKind::Semi(e1) = block1.stmts[0].kind - && let ExprKind::Binary(op1, left1, right1) = e1.kind - && BinOpKind::Eq == op1.node - && let ExprKind::Lit(ref lit3) = left1.kind - && let LitKind::Int(2, LitIntType::Unsuffixed) = lit3.node - && let ExprKind::Lit(ref lit4) = right1.kind - && let LitKind::Int(2, LitIntType::Unsuffixed) = lit4.node - && block1.expr.is_none() - && let PatKind::Wild = local.pat.kind -{ - // report your lint here -} -if let ExprKind::If(cond, then, Some(else_expr)) = expr.kind - && let ExprKind::Let(let_expr) = cond.kind - && let PatKind::Lit(lit_expr) = let_expr.pat.kind - && let ExprKind::Lit(ref lit) = lit_expr.kind - && let LitKind::Bool(true) = lit.node - && let ExprKind::Path(ref qpath) = let_expr.init.kind - && match_qpath(qpath, &["a"]) - && let ExprKind::Block(block, None) = then.kind - && block.stmts.is_empty() - && block.expr.is_none() - && let ExprKind::Block(block1, None) = else_expr.kind - && block1.stmts.is_empty() - && block1.expr.is_none() -{ - // report your lint here -} diff --git a/src/tools/clippy/tests/ui/author/issue_3849.stdout b/src/tools/clippy/tests/ui/author/issue_3849.stdout deleted file mode 100644 index 32a3127b85a3e..0000000000000 --- a/src/tools/clippy/tests/ui/author/issue_3849.stdout +++ /dev/null @@ -1,12 +0,0 @@ -if let StmtKind::Local(local) = stmt.kind - && let Some(init) = local.init - && let ExprKind::Call(func, args) = init.kind - && let ExprKind::Path(ref qpath) = func.kind - && match_qpath(qpath, &["std", "mem", "transmute"]) - && args.len() == 1 - && let ExprKind::Path(ref qpath1) = args[0].kind - && match_qpath(qpath1, &["ZPTR"]) - && let PatKind::Wild = local.pat.kind -{ - // report your lint here -} diff --git a/src/tools/clippy/tests/ui/author/loop.stdout b/src/tools/clippy/tests/ui/author/loop.stdout deleted file mode 100644 index 94a6436ed5479..0000000000000 --- a/src/tools/clippy/tests/ui/author/loop.stdout +++ /dev/null @@ -1,101 +0,0 @@ -if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr) - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = pat.kind - && name.as_str() == "y" - && let ExprKind::Struct(qpath, fields, None) = arg.kind - && matches!(qpath, QPath::LangItem(LangItem::Range, _)) - && fields.len() == 2 - && fields[0].ident.as_str() == "start" - && let ExprKind::Lit(ref lit) = fields[0].expr.kind - && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node - && fields[1].ident.as_str() == "end" - && let ExprKind::Lit(ref lit1) = fields[1].expr.kind - && let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node - && let ExprKind::Block(block, None) = body.kind - && block.stmts.len() == 1 - && let StmtKind::Local(local) = block.stmts[0].kind - && let Some(init) = local.init - && let ExprKind::Path(ref qpath1) = init.kind - && match_qpath(qpath1, &["y"]) - && let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local.pat.kind - && name1.as_str() == "z" - && block.expr.is_none() -{ - // report your lint here -} -if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr) - && let PatKind::Wild = pat.kind - && let ExprKind::Struct(qpath, fields, None) = arg.kind - && matches!(qpath, QPath::LangItem(LangItem::Range, _)) - && fields.len() == 2 - && fields[0].ident.as_str() == "start" - && let ExprKind::Lit(ref lit) = fields[0].expr.kind - && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node - && fields[1].ident.as_str() == "end" - && let ExprKind::Lit(ref lit1) = fields[1].expr.kind - && let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node - && let ExprKind::Block(block, None) = body.kind - && block.stmts.len() == 1 - && let StmtKind::Semi(e) = block.stmts[0].kind - && let ExprKind::Break(destination, None) = e.kind - && destination.label.is_none() - && block.expr.is_none() -{ - // report your lint here -} -if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr) - && let PatKind::Wild = pat.kind - && let ExprKind::Struct(qpath, fields, None) = arg.kind - && matches!(qpath, QPath::LangItem(LangItem::Range, _)) - && fields.len() == 2 - && fields[0].ident.as_str() == "start" - && let ExprKind::Lit(ref lit) = fields[0].expr.kind - && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node - && fields[1].ident.as_str() == "end" - && let ExprKind::Lit(ref lit1) = fields[1].expr.kind - && let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node - && let ExprKind::Block(block, None) = body.kind - && block.stmts.len() == 1 - && let StmtKind::Semi(e) = block.stmts[0].kind - && let ExprKind::Break(destination, None) = e.kind - && let Some(label) = destination.label - && label.ident.as_str() == "'label" - && block.expr.is_none() -{ - // report your lint here -} -if let Some(higher::While { condition: condition, body: body }) = higher::While::hir(expr) - && let ExprKind::Path(ref qpath) = condition.kind - && match_qpath(qpath, &["a"]) - && let ExprKind::Block(block, None) = body.kind - && block.stmts.len() == 1 - && let StmtKind::Semi(e) = block.stmts[0].kind - && let ExprKind::Break(destination, None) = e.kind - && destination.label.is_none() - && block.expr.is_none() -{ - // report your lint here -} -if let Some(higher::WhileLet { let_pat: let_pat, let_expr: let_expr, if_then: if_then }) = higher::WhileLet::hir(expr) - && let PatKind::Lit(lit_expr) = let_pat.kind - && let ExprKind::Lit(ref lit) = lit_expr.kind - && let LitKind::Bool(true) = lit.node - && let ExprKind::Path(ref qpath) = let_expr.kind - && match_qpath(qpath, &["a"]) - && let ExprKind::Block(block, None) = if_then.kind - && block.stmts.len() == 1 - && let StmtKind::Semi(e) = block.stmts[0].kind - && let ExprKind::Break(destination, None) = e.kind - && destination.label.is_none() - && block.expr.is_none() -{ - // report your lint here -} -if let ExprKind::Loop(body, None, LoopSource::Loop, _) = expr.kind - && body.stmts.len() == 1 - && let StmtKind::Semi(e) = body.stmts[0].kind - && let ExprKind::Break(destination, None) = e.kind - && destination.label.is_none() - && body.expr.is_none() -{ - // report your lint here -} diff --git a/src/tools/clippy/tests/ui/author/matches.stdout b/src/tools/clippy/tests/ui/author/matches.stdout deleted file mode 100644 index 88e2ca656a4f6..0000000000000 --- a/src/tools/clippy/tests/ui/author/matches.stdout +++ /dev/null @@ -1,36 +0,0 @@ -if let StmtKind::Local(local) = stmt.kind - && let Some(init) = local.init - && let ExprKind::Match(scrutinee, arms, MatchSource::Normal) = init.kind - && let ExprKind::Lit(ref lit) = scrutinee.kind - && let LitKind::Int(42, LitIntType::Unsuffixed) = lit.node - && arms.len() == 3 - && let PatKind::Lit(lit_expr) = arms[0].pat.kind - && let ExprKind::Lit(ref lit1) = lit_expr.kind - && let LitKind::Int(16, LitIntType::Unsuffixed) = lit1.node - && arms[0].guard.is_none() - && let ExprKind::Lit(ref lit2) = arms[0].body.kind - && let LitKind::Int(5, LitIntType::Unsuffixed) = lit2.node - && let PatKind::Lit(lit_expr1) = arms[1].pat.kind - && let ExprKind::Lit(ref lit3) = lit_expr1.kind - && let LitKind::Int(17, LitIntType::Unsuffixed) = lit3.node - && arms[1].guard.is_none() - && let ExprKind::Block(block, None) = arms[1].body.kind - && block.stmts.len() == 1 - && let StmtKind::Local(local1) = block.stmts[0].kind - && let Some(init1) = local1.init - && let ExprKind::Lit(ref lit4) = init1.kind - && let LitKind::Int(3, LitIntType::Unsuffixed) = lit4.node - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local1.pat.kind - && name.as_str() == "x" - && let Some(trailing_expr) = block.expr - && let ExprKind::Path(ref qpath) = trailing_expr.kind - && match_qpath(qpath, &["x"]) - && let PatKind::Wild = arms[2].pat.kind - && arms[2].guard.is_none() - && let ExprKind::Lit(ref lit5) = arms[2].body.kind - && let LitKind::Int(1, LitIntType::Unsuffixed) = lit5.node - && let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local.pat.kind - && name1.as_str() == "a" -{ - // report your lint here -} diff --git a/src/tools/clippy/tests/ui/author/repeat.stdout b/src/tools/clippy/tests/ui/author/repeat.stdout deleted file mode 100644 index c2a369610cc1b..0000000000000 --- a/src/tools/clippy/tests/ui/author/repeat.stdout +++ /dev/null @@ -1,10 +0,0 @@ -if let ExprKind::Repeat(value, length) = expr.kind - && let ExprKind::Lit(ref lit) = value.kind - && let LitKind::Int(1, LitIntType::Unsigned(UintTy::U8)) = lit.node - && let ArrayLen::Body(anon_const) = length - && expr1 = &cx.tcx.hir().body(anon_const.body).value - && let ExprKind::Lit(ref lit1) = expr1.kind - && let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node -{ - // report your lint here -} diff --git a/src/tools/clippy/tests/ui/author/struct.stdout b/src/tools/clippy/tests/ui/author/struct.stdout deleted file mode 100644 index 0b332d5e7d0e1..0000000000000 --- a/src/tools/clippy/tests/ui/author/struct.stdout +++ /dev/null @@ -1,56 +0,0 @@ -if let ExprKind::Struct(qpath, fields, None) = expr.kind - && match_qpath(qpath, &["Test"]) - && fields.len() == 1 - && fields[0].ident.as_str() == "field" - && let ExprKind::If(cond, then, Some(else_expr)) = fields[0].expr.kind - && let ExprKind::DropTemps(expr1) = cond.kind - && let ExprKind::Lit(ref lit) = expr1.kind - && let LitKind::Bool(true) = lit.node - && let ExprKind::Block(block, None) = then.kind - && block.stmts.is_empty() - && let Some(trailing_expr) = block.expr - && let ExprKind::Lit(ref lit1) = trailing_expr.kind - && let LitKind::Int(1, LitIntType::Unsuffixed) = lit1.node - && let ExprKind::Block(block1, None) = else_expr.kind - && block1.stmts.is_empty() - && let Some(trailing_expr1) = block1.expr - && let ExprKind::Lit(ref lit2) = trailing_expr1.kind - && let LitKind::Int(0, LitIntType::Unsuffixed) = lit2.node -{ - // report your lint here -} -if let PatKind::Struct(ref qpath, fields, false) = arm.pat.kind - && match_qpath(qpath, &["Test"]) - && fields.len() == 1 - && fields[0].ident.as_str() == "field" - && let PatKind::Lit(lit_expr) = fields[0].pat.kind - && let ExprKind::Lit(ref lit) = lit_expr.kind - && let LitKind::Int(1, LitIntType::Unsuffixed) = lit.node - && arm.guard.is_none() - && let ExprKind::Block(block, None) = arm.body.kind - && block.stmts.is_empty() - && block.expr.is_none() -{ - // report your lint here -} -if let PatKind::TupleStruct(ref qpath, fields, None) = arm.pat.kind - && match_qpath(qpath, &["TestTuple"]) - && fields.len() == 1 - && let PatKind::Lit(lit_expr) = fields[0].kind - && let ExprKind::Lit(ref lit) = lit_expr.kind - && let LitKind::Int(1, LitIntType::Unsuffixed) = lit.node - && arm.guard.is_none() - && let ExprKind::Block(block, None) = arm.body.kind - && block.stmts.is_empty() - && block.expr.is_none() -{ - // report your lint here -} -if let ExprKind::MethodCall(method_name, receiver, args, _) = expr.kind - && method_name.ident.as_str() == "test" - && let ExprKind::Path(ref qpath) = receiver.kind - && match_qpath(qpath, &["test_method_call"]) - && args.is_empty() -{ - // report your lint here -} diff --git a/src/tools/clippy/tests/ui/crashes/ice-9463.rs b/src/tools/clippy/tests/ui/crashes/ice-9463.rs index fa83d25b3942d..99cb0253d55c1 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-9463.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-9463.rs @@ -1,9 +1,6 @@ #![deny(arithmetic_overflow)] fn main() { let _x = -1_i32 >> -1; - //~^ ERROR: this arithmetic operation will overflow let _y = 1u32 >> 10000000000000u32; - //~^ ERROR: this arithmetic operation will overflow - //~| ERROR: literal out of range for `u32` - //~| NOTE: the literal `10000000000000u32` does not fit into the type `u32` whose rang + //~^ ERROR: literal out of range for `u32` } diff --git a/src/tools/clippy/tests/ui/crashes/ice-9463.stderr b/src/tools/clippy/tests/ui/crashes/ice-9463.stderr index 911795694c38e..b01e4e268e0db 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-9463.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-9463.stderr @@ -1,23 +1,5 @@ -error: this arithmetic operation will overflow - --> $DIR/ice-9463.rs:3:14 - | -LL | let _x = -1_i32 >> -1; - | ^^^^^^^^^^^^ attempt to shift right by `-1_i32`, which would overflow - | -note: the lint level is defined here - --> $DIR/ice-9463.rs:1:9 - | -LL | #![deny(arithmetic_overflow)] - | ^^^^^^^^^^^^^^^^^^^ - -error: this arithmetic operation will overflow - --> $DIR/ice-9463.rs:5:14 - | -LL | let _y = 1u32 >> 10000000000000u32; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to shift right by `1316134912_u32`, which would overflow - error: literal out of range for `u32` - --> $DIR/ice-9463.rs:5:22 + --> $DIR/ice-9463.rs:4:22 | LL | let _y = 1u32 >> 10000000000000u32; | ^^^^^^^^^^^^^^^^^ @@ -25,5 +7,5 @@ LL | let _y = 1u32 >> 10000000000000u32; = note: the literal `10000000000000u32` does not fit into the type `u32` whose range is `0..=4294967295` = note: `#[deny(overflowing_literals)]` on by default -error: aborting due to 3 previous errors +error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr index 1c34875d2b8ab..7c84160b8aad7 100644 --- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr +++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr @@ -18,18 +18,6 @@ LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts. = help: consider using `.get(n)` or `.get_mut(n)` instead = note: the suggestion might not be applicable in constant blocks -error[E0080]: evaluation of `main::{constant#3}` failed - --> $DIR/indexing_slicing_index.rs:48:14 - | -LL | const { &ARR[idx4()] }; - | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 - -note: erroneous constant encountered - --> $DIR/indexing_slicing_index.rs:48:5 - | -LL | const { &ARR[idx4()] }; - | ^^^^^^^^^^^^^^^^^^^^^^ - error: indexing may panic --> $DIR/indexing_slicing_index.rs:29:5 | @@ -102,6 +90,6 @@ error[E0080]: evaluation of constant value failed LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts. | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 -error: aborting due to 12 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/tools/clippy/tests/ui/modulo_one.rs b/src/tools/clippy/tests/ui/modulo_one.rs index c1dbe9d9a8787..74c3ac113d7d1 100644 --- a/src/tools/clippy/tests/ui/modulo_one.rs +++ b/src/tools/clippy/tests/ui/modulo_one.rs @@ -13,9 +13,7 @@ fn main() { 10 % 2; // also caught by rustc i32::MIN % (-1); - //~^ ERROR: this operation will panic at runtime - //~| NOTE: `#[deny(unconditional_panic)]` on by default - //~| ERROR: any number modulo -1 will panic/overflow or result in 0 + //~^ ERROR: any number modulo -1 will panic/overflow or result in 0 const ONE: u32 = 1 * 1; const NEG_ONE: i64 = 1 - 2; @@ -31,9 +29,7 @@ fn main() { 5 % STATIC_NEG_ONE; // also caught by rustc INT_MIN % NEG_ONE; - //~^ ERROR: this operation will panic at runtime - //~| ERROR: any number modulo -1 will panic/overflow or result in 0 + //~^ ERROR: any number modulo -1 will panic/overflow or result in 0 // ONLY caught by rustc INT_MIN % STATIC_NEG_ONE; - //~^ ERROR: this operation will panic at runtime } diff --git a/src/tools/clippy/tests/ui/modulo_one.stderr b/src/tools/clippy/tests/ui/modulo_one.stderr index cc211ab6cd345..01c9c9c279800 100644 --- a/src/tools/clippy/tests/ui/modulo_one.stderr +++ b/src/tools/clippy/tests/ui/modulo_one.stderr @@ -1,23 +1,3 @@ -error: this operation will panic at runtime - --> $DIR/modulo_one.rs:15:5 - | -LL | i32::MIN % (-1); - | ^^^^^^^^^^^^^^^ attempt to compute `i32::MIN % -1_i32`, which would overflow - | - = note: `#[deny(unconditional_panic)]` on by default - -error: this operation will panic at runtime - --> $DIR/modulo_one.rs:33:5 - | -LL | INT_MIN % NEG_ONE; - | ^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow - -error: this operation will panic at runtime - --> $DIR/modulo_one.rs:37:5 - | -LL | INT_MIN % STATIC_NEG_ONE; - | ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow - error: any number modulo 1 will be 0 --> $DIR/modulo_one.rs:8:5 | @@ -40,22 +20,22 @@ LL | i32::MIN % (-1); | ^^^^^^^^^^^^^^^ error: any number modulo 1 will be 0 - --> $DIR/modulo_one.rs:24:5 + --> $DIR/modulo_one.rs:22:5 | LL | 2 % ONE; | ^^^^^^^ error: any number modulo -1 will panic/overflow or result in 0 - --> $DIR/modulo_one.rs:28:5 + --> $DIR/modulo_one.rs:26:5 | LL | 2 % NEG_ONE; | ^^^^^^^^^^^ error: any number modulo -1 will panic/overflow or result in 0 - --> $DIR/modulo_one.rs:33:5 + --> $DIR/modulo_one.rs:31:5 | LL | INT_MIN % NEG_ONE; | ^^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error: aborting due to 6 previous errors 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 fa6734b6c6c30..3d3946761f434 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 @@ -3,6 +3,7 @@ #![feature(rustc_private)] #![deny(rustc::lint_pass_impl_without_macro)] +extern crate rustc_data_structures; extern crate rustc_middle; extern crate rustc_session; 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..96c67c2577724 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 @@ -1,5 +1,5 @@ error: implementing `LintPass` by hand - --> $DIR/lint_pass_impl_without_macro.rs:20:6 + --> $DIR/lint_pass_impl_without_macro.rs:21:6 | LL | impl LintPass for Foo { | ^^^^^^^^ @@ -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:31:14 | LL | impl LintPass for Custom { | ^^^^^^^^ diff --git a/tests/ui-fulldeps/lint-pass-macros.rs b/tests/ui-fulldeps/lint-pass-macros.rs index 4c61783418fb0..e74bee6a490f7 100644 --- a/tests/ui-fulldeps/lint-pass-macros.rs +++ b/tests/ui-fulldeps/lint-pass-macros.rs @@ -3,6 +3,7 @@ #![feature(rustc_private)] +extern crate rustc_data_structures; extern crate rustc_session; use rustc_session::lint::{LintPass, LintVec}; diff --git a/tests/ui-fulldeps/plugin/auxiliary/issue-40001-plugin.rs b/tests/ui-fulldeps/plugin/auxiliary/issue-40001-plugin.rs index 3f6caecaa5ad0..4716f0078b09c 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/issue-40001-plugin.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/issue-40001-plugin.rs @@ -2,6 +2,7 @@ #![crate_type = "dylib"] extern crate rustc_ast_pretty; +extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_hir; extern crate rustc_lint; diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-for-crate.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-for-crate.rs index 6304c07d2c7ce..48e46c36d18dc 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/lint-for-crate.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-for-crate.rs @@ -2,6 +2,7 @@ #![feature(rustc_private)] +extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_hir; extern crate rustc_lint; diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs index 150f0c6b9a2da..62af4dab95695 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs @@ -2,6 +2,7 @@ #![feature(rustc_private)] +extern crate rustc_data_structures; // Load rustc as a plugin to get macros. extern crate rustc_driver; extern crate rustc_hir; diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs index acc5fe76051b9..8c6fdea616694 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs @@ -3,7 +3,7 @@ #![feature(rustc_private)] extern crate rustc_ast; - +extern crate rustc_data_structures; // Load rustc as a plugin to get macros extern crate rustc_driver; extern crate rustc_lint; diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs index 21de4aa7008fd..3ef39c67e4187 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs @@ -1,7 +1,7 @@ #![feature(rustc_private)] extern crate rustc_ast; - +extern crate rustc_data_structures; // Load rustc as a plugin to get macros extern crate rustc_driver; extern crate rustc_lint; diff --git a/tests/ui/print_type_sizes/multiple_types.rs b/tests/ui/print_type_sizes/multiple_types.rs deleted file mode 100644 index 9159038924719..0000000000000 --- a/tests/ui/print_type_sizes/multiple_types.rs +++ /dev/null @@ -1,13 +0,0 @@ -// compile-flags: -Z print-type-sizes --crate-type=lib -// build-pass - -// This file illustrates that when multiple structural types occur in -// a function, every one of them is included in the output. - -pub struct SevenBytes([u8; 7]); -pub struct FiftyBytes([u8; 50]); - -pub enum Enum { - Small(SevenBytes), - Large(FiftyBytes), -} diff --git a/tests/ui/print_type_sizes/multiple_types.stdout b/tests/ui/print_type_sizes/multiple_types.stdout deleted file mode 100644 index 6411881545843..0000000000000 --- a/tests/ui/print_type_sizes/multiple_types.stdout +++ /dev/null @@ -1,10 +0,0 @@ -print-type-size type: `Enum`: 51 bytes, alignment: 1 bytes -print-type-size discriminant: 1 bytes -print-type-size variant `Large`: 50 bytes -print-type-size field `.0`: 50 bytes -print-type-size variant `Small`: 7 bytes -print-type-size field `.0`: 7 bytes -print-type-size type: `FiftyBytes`: 50 bytes, alignment: 1 bytes -print-type-size field `.0`: 50 bytes -print-type-size type: `SevenBytes`: 7 bytes, alignment: 1 bytes -print-type-size field `.0`: 7 bytes diff --git a/tests/ui/print_type_sizes/padding.rs b/tests/ui/print_type_sizes/padding.rs deleted file mode 100644 index f41c677dc6c08..0000000000000 --- a/tests/ui/print_type_sizes/padding.rs +++ /dev/null @@ -1,28 +0,0 @@ -// compile-flags: -Z print-type-sizes --crate-type=lib -// build-pass - -// This file illustrates how padding is handled: alignment -// requirements can lead to the introduction of padding, either before -// fields or at the end of the structure as a whole. -// -// It avoids using u64/i64 because on some targets that is only 4-byte -// aligned (while on most it is 8-byte aligned) and so the resulting -// padding and overall computed sizes can be quite different. - -#![allow(dead_code)] - -struct S { - a: bool, - b: bool, - g: i32, -} - -enum E1 { - A(i32, i8), - B(S), -} - -enum E2 { - A(i8, i32), - B(S), -} diff --git a/tests/ui/print_type_sizes/padding.stdout b/tests/ui/print_type_sizes/padding.stdout deleted file mode 100644 index 9afdf76245df7..0000000000000 --- a/tests/ui/print_type_sizes/padding.stdout +++ /dev/null @@ -1,23 +0,0 @@ -print-type-size type: `E1`: 12 bytes, alignment: 4 bytes -print-type-size discriminant: 1 bytes -print-type-size variant `B`: 11 bytes -print-type-size padding: 3 bytes -print-type-size field `.0`: 8 bytes, alignment: 4 bytes -print-type-size variant `A`: 7 bytes -print-type-size field `.1`: 1 bytes -print-type-size padding: 2 bytes -print-type-size field `.0`: 4 bytes, alignment: 4 bytes -print-type-size type: `E2`: 12 bytes, alignment: 4 bytes -print-type-size discriminant: 1 bytes -print-type-size variant `B`: 11 bytes -print-type-size padding: 3 bytes -print-type-size field `.0`: 8 bytes, alignment: 4 bytes -print-type-size variant `A`: 7 bytes -print-type-size field `.0`: 1 bytes -print-type-size padding: 2 bytes -print-type-size field `.1`: 4 bytes, alignment: 4 bytes -print-type-size type: `S`: 8 bytes, alignment: 4 bytes -print-type-size field `.g`: 4 bytes -print-type-size field `.a`: 1 bytes -print-type-size field `.b`: 1 bytes -print-type-size end padding: 2 bytes diff --git a/tests/ui/print_type_sizes/repr-align.rs b/tests/ui/print_type_sizes/repr-align.rs index 0bd11ebc95843..0457a39152530 100644 --- a/tests/ui/print_type_sizes/repr-align.rs +++ b/tests/ui/print_type_sizes/repr-align.rs @@ -30,3 +30,5 @@ pub struct S { c: A, d: i8, } + +fn f(a: A, e: E, s: S) {} diff --git a/tests/ui/print_type_sizes/repr_int_c.rs b/tests/ui/print_type_sizes/repr_int_c.rs deleted file mode 100644 index 6b103776a30d3..0000000000000 --- a/tests/ui/print_type_sizes/repr_int_c.rs +++ /dev/null @@ -1,19 +0,0 @@ -// compile-flags: -Z print-type-sizes --crate-type=lib -// build-pass - -// This test makes sure that the tag is not grown for `repr(C)` or `repr(u8)` -// variants (see https://github.com/rust-lang/rust/issues/50098 for the original bug). - -#![allow(dead_code)] - -#[repr(C, u8)] -enum ReprCu8 { - A(u16), - B, -} - -#[repr(u8)] -enum Repru8 { - A(u16), - B, -} diff --git a/tests/ui/print_type_sizes/repr_int_c.stdout b/tests/ui/print_type_sizes/repr_int_c.stdout deleted file mode 100644 index 254b3c7a8531e..0000000000000 --- a/tests/ui/print_type_sizes/repr_int_c.stdout +++ /dev/null @@ -1,12 +0,0 @@ -print-type-size type: `ReprCu8`: 4 bytes, alignment: 2 bytes -print-type-size discriminant: 1 bytes -print-type-size variant `A`: 3 bytes -print-type-size padding: 1 bytes -print-type-size field `.0`: 2 bytes, alignment: 2 bytes -print-type-size variant `B`: 1 bytes -print-type-size type: `Repru8`: 4 bytes, alignment: 2 bytes -print-type-size discriminant: 1 bytes -print-type-size variant `A`: 3 bytes -print-type-size padding: 1 bytes -print-type-size field `.0`: 2 bytes, alignment: 2 bytes -print-type-size variant `B`: 0 bytes diff --git a/tests/ui/print_type_sizes/variants.rs b/tests/ui/print_type_sizes/variants.rs deleted file mode 100644 index 5a3020520265d..0000000000000 --- a/tests/ui/print_type_sizes/variants.rs +++ /dev/null @@ -1,18 +0,0 @@ -// compile-flags: -Z print-type-sizes --crate-type=lib -// build-pass - -// This file illustrates two things: -// -// 1. Only types that appear in a monomorphized function appear in the -// print-type-sizes output, and -// -// 2. For an enum, the print-type-sizes output will also include the -// size of each variant. - -pub struct SevenBytes([u8; 7]); -pub struct FiftyBytes([u8; 50]); - -pub enum Enum { - Small(SevenBytes), - Large(FiftyBytes), -} diff --git a/tests/ui/print_type_sizes/variants.stdout b/tests/ui/print_type_sizes/variants.stdout deleted file mode 100644 index 6411881545843..0000000000000 --- a/tests/ui/print_type_sizes/variants.stdout +++ /dev/null @@ -1,10 +0,0 @@ -print-type-size type: `Enum`: 51 bytes, alignment: 1 bytes -print-type-size discriminant: 1 bytes -print-type-size variant `Large`: 50 bytes -print-type-size field `.0`: 50 bytes -print-type-size variant `Small`: 7 bytes -print-type-size field `.0`: 7 bytes -print-type-size type: `FiftyBytes`: 50 bytes, alignment: 1 bytes -print-type-size field `.0`: 50 bytes -print-type-size type: `SevenBytes`: 7 bytes, alignment: 1 bytes -print-type-size field `.0`: 7 bytes