diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 843aa6a40f09..21e5189aed92 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -678,7 +678,7 @@ define_Conf! { lint_inconsistent_struct_field_initializers: bool = false, /// The lower bound for linting decimal literals #[lints(decimal_literal_representation)] - literal_representation_threshold: u64 = 16384, + literal_representation_threshold: u64 = 0x4000, /// Whether the matches should be considered by the lint, and whether there should /// be filtering for common types. #[lints(manual_let_else)] diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs index 0dd65dfcfd6e..cc547f0c4908 100644 --- a/clippy_config/src/types.rs +++ b/clippy_config/src/types.rs @@ -508,7 +508,7 @@ impl Serialize for SourceItemOrderingModuleItemGroupings { } /// Represents all kinds of trait associated items. -#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, PartialOrd, Serialize)] #[serde(rename_all = "snake_case")] pub enum SourceItemOrderingTraitAssocItemKind { Const, diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs index a14afd8c5f41..087a8457302b 100644 --- a/clippy_dev/src/new_lint.rs +++ b/clippy_dev/src/new_lint.rs @@ -6,7 +6,7 @@ use std::fs::{self, OpenOptions}; use std::io::{self, Write as _}; use std::path::{Path, PathBuf}; -#[derive(Clone, Copy, PartialEq, ValueEnum)] +#[derive(Clone, Copy, PartialEq, Eq, ValueEnum)] pub enum Pass { Early, Late, diff --git a/clippy_dev/src/utils.rs b/clippy_dev/src/utils.rs index 057951d0e33b..04e048bd3d9f 100644 --- a/clippy_dev/src/utils.rs +++ b/clippy_dev/src/utils.rs @@ -58,7 +58,7 @@ pub struct File<'a> { impl<'a> File<'a> { /// Opens a file panicking on failure. #[track_caller] - pub fn open(path: &'a (impl AsRef + ?Sized), options: &mut OpenOptions) -> Self { + pub fn open(path: &'a (impl AsRef + ?Sized), options: &OpenOptions) -> Self { let path = path.as_ref(); Self { inner: expect_action(options.open(path), ErrAction::Open, path), @@ -68,7 +68,7 @@ impl<'a> File<'a> { /// Opens a file if it exists, panicking on any other failure. #[track_caller] - pub fn open_if_exists(path: &'a (impl AsRef + ?Sized), options: &mut OpenOptions) -> Option { + pub fn open_if_exists(path: &'a (impl AsRef + ?Sized), options: &OpenOptions) -> Option { let path = path.as_ref(); match options.open(path) { Ok(inner) => Some(Self { inner, path }), diff --git a/clippy_lints/src/arc_with_non_send_sync.rs b/clippy_lints/src/arc_with_non_send_sync.rs index 085029a744be..c5df22d06dc0 100644 --- a/clippy_lints/src/arc_with_non_send_sync.rs +++ b/clippy_lints/src/arc_with_non_send_sync.rs @@ -54,11 +54,10 @@ impl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync { }) && let Some(send) = cx.tcx.get_diagnostic_item(sym::Send) && let Some(sync) = cx.tcx.lang_items().sync_trait() - && let [is_send, is_sync] = [send, sync].map(|id| implements_trait(cx, arg_ty, id, &[])) - && let reason = match (is_send, is_sync) { - (false, false) => "neither `Send` nor `Sync`", - (false, true) => "not `Send`", - (true, false) => "not `Sync`", + && let reason = match [send, sync].map(|id| implements_trait(cx, arg_ty, id, &[])) { + [false, false] => "neither `Send` nor `Sync`", + [false, true] => "not `Send`", + [true, false] => "not `Sync`", _ => return, } && !is_from_proc_macro(cx, expr) diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index 528cc64fa7bc..2a7fb54409ad 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -37,16 +37,14 @@ pub(super) fn check<'tcx>( { // If the block contains a break or continue, or if the loop has a label, `MachineApplicable` is not // appropriate. - let mut app = if !contains_any_break_or_continue(block) && label.is_none() { + let app = if !contains_any_break_or_continue(block) && label.is_none() { Applicability::MachineApplicable + } else if !never_spans.is_empty() { + Applicability::HasPlaceholders } else { Applicability::Unspecified }; - if !never_spans.is_empty() { - app = Applicability::HasPlaceholders; - } - let mut suggestions = vec![( for_span.with_hi(iterator.span.hi()), for_to_if_let_sugg(cx, iterator, pat), diff --git a/clippy_lints/src/matches/match_like_matches.rs b/clippy_lints/src/matches/match_like_matches.rs index 5816da5695eb..0babc993d652 100644 --- a/clippy_lints/src/matches/match_like_matches.rs +++ b/clippy_lints/src/matches/match_like_matches.rs @@ -113,12 +113,14 @@ where }; // strip potential borrows (#6503), but only if the type is a reference - let mut ex_new = ex; - if let ExprKind::AddrOf(BorrowKind::Ref, .., ex_inner) = ex.kind + let ex_new = if let ExprKind::AddrOf(BorrowKind::Ref, .., ex_inner) = ex.kind && let ty::Ref(..) = cx.typeck_results().expr_ty(ex_inner).kind() { - ex_new = ex_inner; - } + ex_inner + } else { + ex + }; + span_lint_and_sugg( cx, MATCH_LIKE_MATCHES_MACRO, diff --git a/clippy_lints/src/needless_for_each.rs b/clippy_lints/src/needless_for_each.rs index 3a6ccc2bca99..0cd7b70b01b8 100644 --- a/clippy_lints/src/needless_for_each.rs +++ b/clippy_lints/src/needless_for_each.rs @@ -76,6 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach { // and suggesting `for … in … { unsafe { } }` is a little ugly. && !matches!(body.value.kind, ExprKind::Block(Block { rules: BlockCheckMode::UnsafeBlock(_), .. }, ..)) { + #[expect(clippy::useless_let_if_seq, reason = "suggestion is less readable")] let mut applicability = Applicability::MachineApplicable; // If any closure parameter has an explicit type specified, applying the lint would necessarily diff --git a/clippy_lints/src/operators/cmp_owned.rs b/clippy_lints/src/operators/cmp_owned.rs index 604f8f5da0b8..e0d531bd4b26 100644 --- a/clippy_lints/src/operators/cmp_owned.rs +++ b/clippy_lints/src/operators/cmp_owned.rs @@ -93,6 +93,7 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) let arg_snip = snippet(cx, arg_span, ".."); let expr_snip; + #[expect(clippy::useless_let_if_seq, reason = "too complicated to fix")] let eq_impl; if with_deref.is_implemented() && !arg_ty.peel_refs().is_str() { expr_snip = format!("*{arg_snip}"); diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 9eed46460a61..0d1098c11af8 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -691,7 +691,7 @@ fn matches_preds<'tcx>( .iter() .all(|&p| match cx.tcx.instantiate_bound_regions_with_erased(p) { ExistentialPredicate::Trait(p) => infcx - .type_implements_trait(p.def_id, [ty.into()].into_iter().chain(p.args.iter()), cx.param_env) + .type_implements_trait(p.def_id, iter::once(ty.into()).chain(p.args.iter()), cx.param_env) .must_apply_modulo_regions(), ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new( cx.tcx, diff --git a/clippy_lints/src/redundant_type_annotations.rs b/clippy_lints/src/redundant_type_annotations.rs index 7bd4d6e993b4..c73ae1780eba 100644 --- a/clippy_lints/src/redundant_type_annotations.rs +++ b/clippy_lints/src/redundant_type_annotations.rs @@ -151,14 +151,12 @@ impl LateLintPass<'_> for RedundantTypeAnnotations { } }, hir::ExprKind::MethodCall(_, _, _, _) => { - let mut is_ref = false; - let mut ty_kind = &ty.kind; - // If the annotation is a ref we "peel" it - if let hir::TyKind::Ref(_, mut_ty) = &ty.kind { - is_ref = true; - ty_kind = &mut_ty.ty.kind; - } + let (is_ref, ty_kind) = if let hir::TyKind::Ref(_, mut_ty) = &ty.kind { + (true, &mut_ty.ty.kind) + } else { + (false, &ty.kind) + }; if let hir::TyKind::Path(ty_path) = ty_kind && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 52b30ddce12b..ddca100d9685 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -106,7 +106,7 @@ enum VecToArray { impl UselessVec { /// Checks if the surrounding environment requires this expression to actually be of type /// `Vec<_>`, or if it can be changed to `&[]`/`[]` without causing type errors. - fn expr_usage_requires_vec(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) -> VecToArray { + fn expr_usage_requires_vec(&self, cx: &LateContext<'_>, expr: &Expr<'_>) -> VecToArray { match cx.tcx.parent_hir_node(expr.hir_id) { // search for `let foo = vec![_]` expressions where all uses of `foo` // adjust to slices or call a method that exist on slices (e.g. len) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 9ae366305772..1791bb91a3ab 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -85,7 +85,7 @@ use core::mem; use core::ops::ControlFlow; use std::collections::hash_map::Entry; use std::iter::{once, repeat_n, zip}; -use std::sync::{Mutex, MutexGuard, OnceLock}; +use std::sync::{Mutex, OnceLock}; use itertools::Itertools; use rustc_abi::Integer; @@ -2421,9 +2421,7 @@ static TEST_ITEM_NAMES_CACHE: OnceLock, module: LocalModDefId, f: impl FnOnce(&[Symbol]) -> bool) -> bool { let cache = TEST_ITEM_NAMES_CACHE.get_or_init(|| Mutex::new(FxHashMap::default())); - let mut map: MutexGuard<'_, FxHashMap>> = cache.lock().unwrap(); - let value = map.entry(module); - match value { + match cache.lock().unwrap().entry(module) { Entry::Occupied(entry) => f(entry.get()), Entry::Vacant(entry) => { let mut names = Vec::new(); diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 5ab8e16d88ed..05cde2404fea 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -20,7 +20,7 @@ use std::sync::OnceLock; /// Specifies whether to resolve a path in the [`TypeNS`], [`ValueNS`], [`MacroNS`] or in an /// arbitrary namespace -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum PathNS { Type, Value, diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs index c48b5b7c171f..1451ba15acc9 100644 --- a/clippy_utils/src/ty/mod.rs +++ b/clippy_utils/src/ty/mod.rs @@ -291,7 +291,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>( .map(|arg| arg.into().unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into())) .collect::>(); - let trait_ref = TraitRef::new(tcx, trait_id, [GenericArg::from(ty)].into_iter().chain(args)); + let trait_ref = TraitRef::new(tcx, trait_id, iter::once(GenericArg::from(ty)).chain(args)); debug_assert_matches!( tcx.def_kind(trait_id), diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 1ac688935278..a3f618804316 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -356,14 +356,13 @@ fn main() { _ => panic!("unknown speedtest: {speedtest} || accepted speedtests are: [ui, cargo, toml, internal]"), }; - let iterations; - if let Ok(iterations_str) = std::env::var("SPEEDTEST_ITERATIONS") { - iterations = iterations_str + let iterations = if let Ok(iterations_str) = std::env::var("SPEEDTEST_ITERATIONS") { + iterations_str .parse::() - .unwrap_or_else(|_| panic!("Couldn't parse `{iterations_str}`, please use a valid u64")); + .unwrap_or_else(|_| panic!("Couldn't parse `{iterations_str}`, please use a valid u64")) } else { - iterations = 1000; - } + 1000 + }; let mut sum = 0; for _ in 0..iterations { diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 389616801fca..a089120ad8dc 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -57,6 +57,28 @@ fn dogfood() { ); } +const DENY_LINTS: &[&str] = &[ + "unfulfilled_lint_expectations", + "clippy::all", + "clippy::nursery", + "clippy::pedantic", + "clippy::dbg_macro", + "clippy::decimal_literal_representation", +]; + +const ALLOW_LINTS: &[&str] = &[ + "clippy::equatable_if_let", + "clippy::iter_on_empty_collections", + "clippy::iter_with_drain", + "clippy::missing_const_for_fn", + "clippy::option_if_let_else", + "clippy::or_fun_call", + "clippy::redundant_clone", + "clippy::redundant_pub_crate", + "clippy::too_long_first_doc_paragraph", + "clippy::use_self", +]; + #[must_use] fn run_clippy_for_package(project: &str) -> bool { let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -82,7 +104,15 @@ fn run_clippy_for_package(project: &str) -> bool { command.arg("--"); command.arg("-Cdebuginfo=0"); // disable debuginfo to generate less data in the target dir - command.args(["-D", "clippy::all", "-D", "clippy::pedantic", "-D", "clippy::dbg_macro"]); + + for lint in DENY_LINTS { + command.args(["-D", lint]); + } + + for lint in ALLOW_LINTS { + command.args(["-A", lint]); + } + if !cfg!(feature = "internal") { // running a clippy built without internal lints on the clippy source // that contains e.g. `allow(clippy::symbol_as_str)`