Skip to content

Commit 2153c0f

Browse files
committed
Auto merge of rust-lang#11226 - GuillaumeGomez:needless-ref-mut-cfg, r=llogiq
Needless ref mut cfg Fixes rust-lang/rust-clippy#11185. cc `@Centri3` changelog: Emit note if function is behind a cfg for `NEEDLESS_PASS_BY_REF_MUT` lint.
2 parents 70c5798 + 1c9772c commit 2153c0f

File tree

4 files changed

+71
-27
lines changed

4 files changed

+71
-27
lines changed

clippy_lints/src/needless_pass_by_ref_mut.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::needless_pass_by_value::requires_exact_signature;
22
use clippy_utils::diagnostics::span_lint_hir_and_then;
33
use clippy_utils::source::snippet;
4-
use clippy_utils::{get_parent_node, is_from_proc_macro, is_self};
4+
use clippy_utils::{get_parent_node, inherits_cfg, is_from_proc_macro, is_self};
55
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
66
use rustc_errors::Applicability;
77
use rustc_hir::intravisit::{walk_qpath, FnKind, Visitor};
@@ -192,10 +192,12 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
192192
let show_semver_warning =
193193
self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(*fn_def_id);
194194

195+
let mut is_cfged = None;
195196
for input in unused {
196197
// If the argument is never used mutably, we emit the warning.
197198
let sp = input.span;
198199
if let rustc_hir::TyKind::Ref(_, inner_ty) = input.kind {
200+
let is_cfged = is_cfged.get_or_insert_with(|| inherits_cfg(cx.tcx, *fn_def_id));
199201
span_lint_hir_and_then(
200202
cx,
201203
NEEDLESS_PASS_BY_REF_MUT,
@@ -212,6 +214,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
212214
if show_semver_warning {
213215
diag.warn("changing this function will impact semver compatibility");
214216
}
217+
if *is_cfged {
218+
diag.note("this is cfg-gated and may require further changes");
219+
}
215220
},
216221
);
217222
}

clippy_utils/src/lib.rs

+11
Original file line numberDiff line numberDiff line change
@@ -2451,6 +2451,17 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
24512451
.any(is_cfg_test)
24522452
}
24532453

2454+
/// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied.
2455+
pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
2456+
let hir = tcx.hir();
2457+
2458+
tcx.has_attr(def_id, sym::cfg)
2459+
|| hir
2460+
.parent_iter(hir.local_def_id_to_hir_id(def_id))
2461+
.flat_map(|(parent_id, _)| hir.attrs(parent_id))
2462+
.any(|attr| attr.has_name(sym::cfg))
2463+
}
2464+
24542465
/// Checks whether item either has `test` attribute applied, or
24552466
/// is a module with `test` in its name.
24562467
///

tests/ui/needless_pass_by_ref_mut.rs

+24-12
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
use std::ptr::NonNull;
55

6-
// Should only warn for `s`.
76
fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {
7+
//~^ ERROR: this argument is a mutable reference, but not used mutably
88
*x += *b + s.len() as u32;
99
}
1010

@@ -28,8 +28,8 @@ fn foo5(s: &mut Vec<u32>) {
2828
foo2(s);
2929
}
3030

31-
// Should warn.
3231
fn foo6(s: &mut Vec<u32>) {
32+
//~^ ERROR: this argument is a mutable reference, but not used mutably
3333
non_mut_ref(s);
3434
}
3535

@@ -41,13 +41,13 @@ impl Bar {
4141
// Should not warn on `&mut self`.
4242
fn bar(&mut self) {}
4343

44-
// Should warn about `vec`
4544
fn mushroom(&self, vec: &mut Vec<i32>) -> usize {
45+
//~^ ERROR: this argument is a mutable reference, but not used mutably
4646
vec.len()
4747
}
4848

49-
// Should warn about `vec` (and not `self`).
5049
fn badger(&mut self, vec: &mut Vec<i32>) -> usize {
50+
//~^ ERROR: this argument is a mutable reference, but not used mutably
5151
vec.len()
5252
}
5353
}
@@ -123,36 +123,36 @@ async fn f7(x: &mut i32, y: i32, z: &mut i32, a: i32) {
123123
*z += 1;
124124
}
125125

126-
// Should warn.
127126
async fn a1(x: &mut i32) {
127+
//~^ ERROR: this argument is a mutable reference, but not used mutably
128128
println!("{:?}", x);
129129
}
130-
// Should warn.
131130
async fn a2(x: &mut i32, y: String) {
131+
//~^ ERROR: this argument is a mutable reference, but not used mutably
132132
println!("{:?}", x);
133133
}
134-
// Should warn.
135134
async fn a3(x: &mut i32, y: String, z: String) {
135+
//~^ ERROR: this argument is a mutable reference, but not used mutably
136136
println!("{:?}", x);
137137
}
138-
// Should warn.
139138
async fn a4(x: &mut i32, y: i32) {
139+
//~^ ERROR: this argument is a mutable reference, but not used mutably
140140
println!("{:?}", x);
141141
}
142-
// Should warn.
143142
async fn a5(x: i32, y: &mut i32) {
143+
//~^ ERROR: this argument is a mutable reference, but not used mutably
144144
println!("{:?}", x);
145145
}
146-
// Should warn.
147146
async fn a6(x: i32, y: &mut i32) {
147+
//~^ ERROR: this argument is a mutable reference, but not used mutably
148148
println!("{:?}", x);
149149
}
150-
// Should warn.
151150
async fn a7(x: i32, y: i32, z: &mut i32) {
151+
//~^ ERROR: this argument is a mutable reference, but not used mutably
152152
println!("{:?}", z);
153153
}
154-
// Should warn.
155154
async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
155+
//~^ ERROR: this argument is a mutable reference, but not used mutably
156156
println!("{:?}", z);
157157
}
158158

@@ -184,6 +184,18 @@ fn used_as_path(s: &mut u32) {}
184184
#[expect(clippy::needless_pass_by_ref_mut)]
185185
fn lint_attr(s: &mut u32) {}
186186

187+
#[cfg(not(feature = "a"))]
188+
fn cfg_warn(s: &mut u32) {}
189+
//~^ ERROR: this argument is a mutable reference, but not used mutably
190+
//~| NOTE: this is cfg-gated and may require further changes
191+
192+
#[cfg(not(feature = "a"))]
193+
mod foo {
194+
fn cfg_warn(s: &mut u32) {}
195+
//~^ ERROR: this argument is a mutable reference, but not used mutably
196+
//~| NOTE: this is cfg-gated and may require further changes
197+
}
198+
187199
fn main() {
188200
let mut u = 0;
189201
let mut v = vec![0];
+30-14
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,98 @@
11
error: this argument is a mutable reference, but not used mutably
2-
--> $DIR/needless_pass_by_ref_mut.rs:7:11
2+
--> $DIR/needless_pass_by_ref_mut.rs:6:11
33
|
44
LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {
55
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
66
|
77
= note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
88

99
error: this argument is a mutable reference, but not used mutably
10-
--> $DIR/needless_pass_by_ref_mut.rs:32:12
10+
--> $DIR/needless_pass_by_ref_mut.rs:31:12
1111
|
1212
LL | fn foo6(s: &mut Vec<u32>) {
1313
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
1414

1515
error: this argument is a mutable reference, but not used mutably
16-
--> $DIR/needless_pass_by_ref_mut.rs:45:29
16+
--> $DIR/needless_pass_by_ref_mut.rs:44:29
1717
|
1818
LL | fn mushroom(&self, vec: &mut Vec<i32>) -> usize {
1919
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
2020

2121
error: this argument is a mutable reference, but not used mutably
22-
--> $DIR/needless_pass_by_ref_mut.rs:50:31
22+
--> $DIR/needless_pass_by_ref_mut.rs:49:31
2323
|
2424
LL | fn badger(&mut self, vec: &mut Vec<i32>) -> usize {
2525
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
2626

2727
error: this argument is a mutable reference, but not used mutably
28-
--> $DIR/needless_pass_by_ref_mut.rs:127:16
28+
--> $DIR/needless_pass_by_ref_mut.rs:126:16
2929
|
3030
LL | async fn a1(x: &mut i32) {
3131
| ^^^^^^^^ help: consider changing to: `&i32`
3232

3333
error: this argument is a mutable reference, but not used mutably
34-
--> $DIR/needless_pass_by_ref_mut.rs:131:16
34+
--> $DIR/needless_pass_by_ref_mut.rs:130:16
3535
|
3636
LL | async fn a2(x: &mut i32, y: String) {
3737
| ^^^^^^^^ help: consider changing to: `&i32`
3838

3939
error: this argument is a mutable reference, but not used mutably
40-
--> $DIR/needless_pass_by_ref_mut.rs:135:16
40+
--> $DIR/needless_pass_by_ref_mut.rs:134:16
4141
|
4242
LL | async fn a3(x: &mut i32, y: String, z: String) {
4343
| ^^^^^^^^ help: consider changing to: `&i32`
4444

4545
error: this argument is a mutable reference, but not used mutably
46-
--> $DIR/needless_pass_by_ref_mut.rs:139:16
46+
--> $DIR/needless_pass_by_ref_mut.rs:138:16
4747
|
4848
LL | async fn a4(x: &mut i32, y: i32) {
4949
| ^^^^^^^^ help: consider changing to: `&i32`
5050

5151
error: this argument is a mutable reference, but not used mutably
52-
--> $DIR/needless_pass_by_ref_mut.rs:143:24
52+
--> $DIR/needless_pass_by_ref_mut.rs:142:24
5353
|
5454
LL | async fn a5(x: i32, y: &mut i32) {
5555
| ^^^^^^^^ help: consider changing to: `&i32`
5656

5757
error: this argument is a mutable reference, but not used mutably
58-
--> $DIR/needless_pass_by_ref_mut.rs:147:24
58+
--> $DIR/needless_pass_by_ref_mut.rs:146:24
5959
|
6060
LL | async fn a6(x: i32, y: &mut i32) {
6161
| ^^^^^^^^ help: consider changing to: `&i32`
6262

6363
error: this argument is a mutable reference, but not used mutably
64-
--> $DIR/needless_pass_by_ref_mut.rs:151:32
64+
--> $DIR/needless_pass_by_ref_mut.rs:150:32
6565
|
6666
LL | async fn a7(x: i32, y: i32, z: &mut i32) {
6767
| ^^^^^^^^ help: consider changing to: `&i32`
6868

6969
error: this argument is a mutable reference, but not used mutably
70-
--> $DIR/needless_pass_by_ref_mut.rs:155:24
70+
--> $DIR/needless_pass_by_ref_mut.rs:154:24
7171
|
7272
LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
7373
| ^^^^^^^^ help: consider changing to: `&i32`
7474

7575
error: this argument is a mutable reference, but not used mutably
76-
--> $DIR/needless_pass_by_ref_mut.rs:155:45
76+
--> $DIR/needless_pass_by_ref_mut.rs:154:45
7777
|
7878
LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
7979
| ^^^^^^^^ help: consider changing to: `&i32`
8080

81-
error: aborting due to 13 previous errors
81+
error: this argument is a mutable reference, but not used mutably
82+
--> $DIR/needless_pass_by_ref_mut.rs:188:16
83+
|
84+
LL | fn cfg_warn(s: &mut u32) {}
85+
| ^^^^^^^^ help: consider changing to: `&u32`
86+
|
87+
= note: this is cfg-gated and may require further changes
88+
89+
error: this argument is a mutable reference, but not used mutably
90+
--> $DIR/needless_pass_by_ref_mut.rs:194:20
91+
|
92+
LL | fn cfg_warn(s: &mut u32) {}
93+
| ^^^^^^^^ help: consider changing to: `&u32`
94+
|
95+
= note: this is cfg-gated and may require further changes
96+
97+
error: aborting due to 15 previous errors
8298

0 commit comments

Comments
 (0)