Skip to content

Commit 15de3dd

Browse files
Add a note if the function is behind a cfg
1 parent d09c8a9 commit 15de3dd

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

clippy_lints/src/needless_pass_by_ref_mut.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ use rustc_lint::{LateContext, LateLintPass};
1212
use rustc_middle::hir::map::associated_body;
1313
use rustc_middle::hir::nested_filter::OnlyBodies;
1414
use rustc_middle::mir::FakeReadCause;
15-
use rustc_middle::ty::{self, Ty, UpvarId, UpvarPath};
15+
use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath};
1616
use rustc_session::{declare_tool_lint, impl_lint_pass};
17-
use rustc_span::def_id::LocalDefId;
17+
use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID};
1818
use rustc_span::symbol::kw;
19-
use rustc_span::Span;
19+
use rustc_span::{sym, Span};
2020
use rustc_target::spec::abi::Abi;
2121

2222
declare_clippy_lint! {
@@ -93,6 +93,16 @@ fn should_skip<'tcx>(
9393
is_from_proc_macro(cx, &input)
9494
}
9595

96+
fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
97+
if def_id == CRATE_DEF_ID {
98+
false
99+
} else if tcx.has_attr(def_id, sym::cfg) {
100+
true
101+
} else {
102+
inherits_cfg(tcx, tcx.parent_module_from_def_id(def_id))
103+
}
104+
}
105+
96106
impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
97107
fn check_fn(
98108
&mut self,
@@ -192,10 +202,12 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
192202
let show_semver_warning =
193203
self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(*fn_def_id);
194204

205+
let mut is_cfged = None;
195206
for input in unused {
196207
// If the argument is never used mutably, we emit the warning.
197208
let sp = input.span;
198209
if let rustc_hir::TyKind::Ref(_, inner_ty) = input.kind {
210+
let is_cfged = is_cfged.get_or_insert_with(|| inherits_cfg(cx.tcx, *fn_def_id));
199211
span_lint_hir_and_then(
200212
cx,
201213
NEEDLESS_PASS_BY_REF_MUT,
@@ -212,6 +224,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
212224
if show_semver_warning {
213225
diag.warn("changing this function will impact semver compatibility");
214226
}
227+
if *is_cfged {
228+
diag.note("this is cfg-gated and may require further changes");
229+
}
215230
},
216231
);
217232
}

tests/ui/needless_pass_by_ref_mut.rs

+10
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ 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+
// Should warn with note.
189+
fn cfg_warn(s: &mut u32) {}
190+
191+
#[cfg(not(feature = "a"))]
192+
mod foo {
193+
// Should warn with note.
194+
fn cfg_warn(s: &mut u32) {}
195+
}
196+
187197
fn main() {
188198
let mut u = 0;
189199
let mut v = vec![0];

tests/ui/needless_pass_by_ref_mut.stderr

+17-1
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,21 @@ error: this argument is a mutable reference, but not used mutably
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:189: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)