Skip to content

Commit 9f1caef

Browse files
committed
only lint once on 3+ &muts
for some reason this seems to already be the case with exprs, so only do it for tys
1 parent 203dd7b commit 9f1caef

File tree

5 files changed

+22
-16
lines changed

5 files changed

+22
-16
lines changed

clippy_lints/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
481481
store.register_late_pass(|_| Box::new(needless_for_each::NeedlessForEach));
482482
store.register_late_pass(|_| Box::new(misc::LintPass));
483483
store.register_late_pass(|_| Box::new(eta_reduction::EtaReduction));
484-
store.register_late_pass(|_| Box::new(mut_mut::MutMut));
484+
store.register_late_pass(|_| Box::new(mut_mut::MutMut::default()));
485485
store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed));
486486
store.register_late_pass(|_| Box::<significant_drop_tightening::SignificantDropTightening<'_>>::default());
487487
store.register_late_pass(|_| Box::new(len_zero::LenZero));

clippy_lints/src/mut_mut.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
22
use clippy_utils::higher;
33
use clippy_utils::source::snippet_with_applicability;
44
use clippy_utils::sugg::Sugg;
5+
use rustc_data_structures::fx::FxHashSet;
56
use rustc_errors::Applicability;
6-
use rustc_hir::{self as hir, AmbigArg, intravisit};
7+
use rustc_hir::{self as hir, AmbigArg, HirId, intravisit};
78
use rustc_lint::{LateContext, LateLintPass, LintContext};
89
use rustc_middle::ty;
9-
use rustc_session::declare_lint_pass;
10+
use rustc_session::impl_lint_pass;
1011

1112
declare_clippy_lint! {
1213
/// ### What it does
@@ -28,7 +29,12 @@ declare_clippy_lint! {
2829
"usage of double-mut refs, e.g., `&mut &mut ...`"
2930
}
3031

31-
declare_lint_pass!(MutMut => [MUT_MUT]);
32+
impl_lint_pass!(MutMut => [MUT_MUT]);
33+
34+
#[derive(Default)]
35+
pub(crate) struct MutMut {
36+
seen_tys: FxHashSet<HirId>,
37+
}
3238

3339
impl<'tcx> LateLintPass<'tcx> for MutMut {
3440
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
@@ -42,6 +48,14 @@ impl<'tcx> LateLintPass<'tcx> for MutMut {
4248
&& mty2.mutbl == hir::Mutability::Mut
4349
&& !ty.span.in_external_macro(cx.sess().source_map())
4450
{
51+
// we have 2+ `&mut`s, e.g., `&mut &mut &mut x`
52+
// and we have already flagged on the outermost `&mut &mut (&mut x)`,
53+
// so don't flag the inner `&mut &mut (x)`
54+
if self.seen_tys.contains(&ty.hir_id) {
55+
return;
56+
}
57+
self.seen_tys.insert(mty.ty.hir_id);
58+
4559
let mut applicability = Applicability::MaybeIncorrect;
4660
let sugg = snippet_with_applicability(cx.sess(), mty.ty.span, "..", &mut applicability);
4761
span_lint_and_sugg(

tests/ui/mut_mut.fixed

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
extern crate proc_macros;
1313
use proc_macros::{external, inline_macros};
1414

15-
fn fun(x: &mut &mut u32) {
15+
fn fun(x: &mut u32) {
1616
//~^ mut_mut
1717
}
1818

@@ -37,16 +37,15 @@ fn main() {
3737
}
3838

3939
{
40-
let y: &mut &mut u32 = &mut 2;
40+
let y: &mut u32 = &mut 2;
4141
//~^ mut_mut
4242
//~| mut_mut
4343
}
4444

4545
{
46-
let y: &mut &mut &mut u32 = &mut &mut 2;
46+
let y: &mut &mut u32 = &mut &mut 2;
4747
//~^ mut_mut
4848
//~| mut_mut
49-
//~| mut_mut
5049
}
5150

5251
let mut z = inline!(&mut $(&mut 3u32));

tests/ui/mut_mut.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ fn main() {
4646
let y: &mut &mut &mut u32 = &mut &mut &mut 2;
4747
//~^ mut_mut
4848
//~| mut_mut
49-
//~| mut_mut
5049
}
5150

5251
let mut z = inline!(&mut $(&mut 3u32));

tests/ui/mut_mut.stderr

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,5 @@ error: a type of form `&mut &mut _`
4343
LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2;
4444
| ^^^^^^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut &mut u32`
4545

46-
error: a type of form `&mut &mut _`
47-
--> tests/ui/mut_mut.rs:46:21
48-
|
49-
LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2;
50-
| ^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut u32`
51-
52-
error: aborting due to 8 previous errors
46+
error: aborting due to 7 previous errors
5347

0 commit comments

Comments
 (0)