diff options
| -rw-r--r-- | clippy_lints/src/needless_pass_by_ref_mut.rs | 7 | ||||
| -rw-r--r-- | clippy_utils/src/lib.rs | 11 | ||||
| -rw-r--r-- | tests/ui/needless_pass_by_ref_mut.rs | 36 | ||||
| -rw-r--r-- | tests/ui/needless_pass_by_ref_mut.stderr | 44 |
4 files changed, 71 insertions, 27 deletions
diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 3299dca09c3..0e2a101a977 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -1,7 +1,7 @@ use super::needless_pass_by_value::requires_exact_signature; use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::snippet; -use clippy_utils::{get_parent_node, is_from_proc_macro, is_self}; +use clippy_utils::{get_parent_node, inherits_cfg, is_from_proc_macro, is_self}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_qpath, FnKind, Visitor}; @@ -192,10 +192,12 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { let show_semver_warning = self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(*fn_def_id); + let mut is_cfged = None; for input in unused { // If the argument is never used mutably, we emit the warning. let sp = input.span; if let rustc_hir::TyKind::Ref(_, inner_ty) = input.kind { + let is_cfged = is_cfged.get_or_insert_with(|| inherits_cfg(cx.tcx, *fn_def_id)); span_lint_hir_and_then( cx, NEEDLESS_PASS_BY_REF_MUT, @@ -212,6 +214,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { if show_semver_warning { diag.warn("changing this function will impact semver compatibility"); } + if *is_cfged { + diag.note("this is cfg-gated and may require further changes"); + } }, ); } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 8429192437c..beff0e6e1ab 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -2451,6 +2451,17 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { .any(is_cfg_test) } +/// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied. +pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { + let hir = tcx.hir(); + + tcx.has_attr(def_id, sym::cfg) + || hir + .parent_iter(hir.local_def_id_to_hir_id(def_id)) + .flat_map(|(parent_id, _)| hir.attrs(parent_id)) + .any(|attr| attr.has_name(sym::cfg)) +} + /// Checks whether item either has `test` attribute applied, or /// is a module with `test` in its name. /// diff --git a/tests/ui/needless_pass_by_ref_mut.rs b/tests/ui/needless_pass_by_ref_mut.rs index 49f88978bff..ae7b018d0e2 100644 --- a/tests/ui/needless_pass_by_ref_mut.rs +++ b/tests/ui/needless_pass_by_ref_mut.rs @@ -3,8 +3,8 @@ use std::ptr::NonNull; -// Should only warn for `s`. fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably *x += *b + s.len() as u32; } @@ -28,8 +28,8 @@ fn foo5(s: &mut Vec<u32>) { foo2(s); } -// Should warn. fn foo6(s: &mut Vec<u32>) { + //~^ ERROR: this argument is a mutable reference, but not used mutably non_mut_ref(s); } @@ -41,13 +41,13 @@ impl Bar { // Should not warn on `&mut self`. fn bar(&mut self) {} - // Should warn about `vec` fn mushroom(&self, vec: &mut Vec<i32>) -> usize { + //~^ ERROR: this argument is a mutable reference, but not used mutably vec.len() } - // Should warn about `vec` (and not `self`). fn badger(&mut self, vec: &mut Vec<i32>) -> usize { + //~^ ERROR: this argument is a mutable reference, but not used mutably vec.len() } } @@ -123,36 +123,36 @@ async fn f7(x: &mut i32, y: i32, z: &mut i32, a: i32) { *z += 1; } -// Should warn. async fn a1(x: &mut i32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably println!("{:?}", x); } -// Should warn. async fn a2(x: &mut i32, y: String) { + //~^ ERROR: this argument is a mutable reference, but not used mutably println!("{:?}", x); } -// Should warn. async fn a3(x: &mut i32, y: String, z: String) { + //~^ ERROR: this argument is a mutable reference, but not used mutably println!("{:?}", x); } -// Should warn. async fn a4(x: &mut i32, y: i32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably println!("{:?}", x); } -// Should warn. async fn a5(x: i32, y: &mut i32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably println!("{:?}", x); } -// Should warn. async fn a6(x: i32, y: &mut i32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably println!("{:?}", x); } -// Should warn. async fn a7(x: i32, y: i32, z: &mut i32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably println!("{:?}", z); } -// Should warn. async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably println!("{:?}", z); } @@ -184,6 +184,18 @@ fn used_as_path(s: &mut u32) {} #[expect(clippy::needless_pass_by_ref_mut)] fn lint_attr(s: &mut u32) {} +#[cfg(not(feature = "a"))] +fn cfg_warn(s: &mut u32) {} +//~^ ERROR: this argument is a mutable reference, but not used mutably +//~| NOTE: this is cfg-gated and may require further changes + +#[cfg(not(feature = "a"))] +mod foo { + fn cfg_warn(s: &mut u32) {} + //~^ ERROR: this argument is a mutable reference, but not used mutably + //~| NOTE: this is cfg-gated and may require further changes +} + fn main() { let mut u = 0; let mut v = vec![0]; diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr index 4ab5b5675ca..0d426ce32f9 100644 --- a/tests/ui/needless_pass_by_ref_mut.stderr +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -1,5 +1,5 @@ error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:7:11 + --> $DIR/needless_pass_by_ref_mut.rs:6:11 | LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>` @@ -7,76 +7,92 @@ LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) { = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:32:12 + --> $DIR/needless_pass_by_ref_mut.rs:31:12 | LL | fn foo6(s: &mut Vec<u32>) { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:45:29 + --> $DIR/needless_pass_by_ref_mut.rs:44:29 | LL | fn mushroom(&self, vec: &mut Vec<i32>) -> usize { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:50:31 + --> $DIR/needless_pass_by_ref_mut.rs:49:31 | LL | fn badger(&mut self, vec: &mut Vec<i32>) -> usize { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:127:16 + --> $DIR/needless_pass_by_ref_mut.rs:126:16 | LL | async fn a1(x: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:131:16 + --> $DIR/needless_pass_by_ref_mut.rs:130:16 | LL | async fn a2(x: &mut i32, y: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:135:16 + --> $DIR/needless_pass_by_ref_mut.rs:134:16 | LL | async fn a3(x: &mut i32, y: String, z: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:139:16 + --> $DIR/needless_pass_by_ref_mut.rs:138:16 | LL | async fn a4(x: &mut i32, y: i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:143:24 + --> $DIR/needless_pass_by_ref_mut.rs:142:24 | LL | async fn a5(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:147:24 + --> $DIR/needless_pass_by_ref_mut.rs:146:24 | LL | async fn a6(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:151:32 + --> $DIR/needless_pass_by_ref_mut.rs:150:32 | LL | async fn a7(x: i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:155:24 + --> $DIR/needless_pass_by_ref_mut.rs:154:24 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> $DIR/needless_pass_by_ref_mut.rs:155:45 + --> $DIR/needless_pass_by_ref_mut.rs:154:45 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` -error: aborting due to 13 previous errors +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:188:16 + | +LL | fn cfg_warn(s: &mut u32) {} + | ^^^^^^^^ help: consider changing to: `&u32` + | + = note: this is cfg-gated and may require further changes + +error: this argument is a mutable reference, but not used mutably + --> $DIR/needless_pass_by_ref_mut.rs:194:20 + | +LL | fn cfg_warn(s: &mut u32) {} + | ^^^^^^^^ help: consider changing to: `&u32` + | + = note: this is cfg-gated and may require further changes + +error: aborting due to 15 previous errors |
