From 2a76c570d6115230af9df0888a721de9fb2c88bc Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 23 Jul 2023 09:56:56 +0000 Subject: [PATCH] add suggestion --- compiler/rustc_lint/messages.ftl | 2 +- compiler/rustc_lint/src/lints.rs | 2 +- tests/ui/lint/noop-method-call.fixed | 51 +++++++++++++++++ tests/ui/lint/noop-method-call.rs | 29 +++++----- tests/ui/lint/noop-method-call.stderr | 56 +++++++++---------- tests/ui/lint/suspicious-double-ref-op.rs | 27 ++++++--- tests/ui/lint/suspicious-double-ref-op.stderr | 33 +++++------ 7 files changed, 127 insertions(+), 73 deletions(-) create mode 100644 tests/ui/lint/noop-method-call.fixed diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 598373a8301..797504c0e8e 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -412,7 +412,7 @@ lint_non_upper_case_global = {$sort} `{$name}` should have an upper case name .label = should have an UPPER_CASE name lint_noop_method_call = call to `.{$method}()` on a reference in this situation does nothing - .label = unnecessary method call + .suggestion = remove this redundant call .note = the type `{$orig_ty}` does not implement `{$trait_}`, so calling `{$method}` on `&{$orig_ty}` copies the reference, which does not do anything and can be removed lint_only_cast_u8_to_char = only `u8` can be cast into `char` diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 322a3b6583d..981b39ba1c8 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1233,7 +1233,7 @@ pub struct NoopMethodCallDiag<'a> { pub method: Symbol, pub orig_ty: Ty<'a>, pub trait_: Symbol, - #[label] + #[suggestion(code = "", applicability = "machine-applicable")] pub label: Span, } diff --git a/tests/ui/lint/noop-method-call.fixed b/tests/ui/lint/noop-method-call.fixed new file mode 100644 index 00000000000..eeb80279fd8 --- /dev/null +++ b/tests/ui/lint/noop-method-call.fixed @@ -0,0 +1,51 @@ +// check-pass +// run-rustfix + +#![allow(unused)] + +use std::borrow::Borrow; +use std::ops::Deref; + +struct PlainType(T); + +#[derive(Clone)] +struct CloneType(T); + +fn check(mut encoded: &[u8]) { + let _ = &mut encoded; + //~^ WARN call to `.clone()` on a reference in this situation does nothing + let _ = &encoded; + //~^ WARN call to `.clone()` on a reference in this situation does nothing +} + +fn main() { + let non_clone_type_ref = &PlainType(1u32); + let non_clone_type_ref_clone: &PlainType = non_clone_type_ref; + //~^ WARN call to `.clone()` on a reference in this situation does nothing + + let clone_type_ref = &CloneType(1u32); + let clone_type_ref_clone: CloneType = clone_type_ref.clone(); + + + let non_deref_type = &PlainType(1u32); + let non_deref_type_deref: &PlainType = non_deref_type; + //~^ WARN call to `.deref()` on a reference in this situation does nothing + + let non_borrow_type = &PlainType(1u32); + let non_borrow_type_borrow: &PlainType = non_borrow_type; + //~^ WARN call to `.borrow()` on a reference in this situation does nothing + + // Borrowing a &&T does not warn since it has collapsed the double reference + let non_borrow_type = &&PlainType(1u32); + let non_borrow_type_borrow: &PlainType = non_borrow_type.borrow(); +} + +fn generic(non_clone_type: &PlainType) { + non_clone_type; + //~^ WARN call to `.clone()` on a reference in this situation does nothing +} + +fn non_generic(non_clone_type: &PlainType) { + non_clone_type; + //~^ WARN call to `.clone()` on a reference in this situation does nothing +} diff --git a/tests/ui/lint/noop-method-call.rs b/tests/ui/lint/noop-method-call.rs index 8ce6c859b24..9569a0dfc61 100644 --- a/tests/ui/lint/noop-method-call.rs +++ b/tests/ui/lint/noop-method-call.rs @@ -1,4 +1,5 @@ // check-pass +// run-rustfix #![allow(unused)] @@ -10,45 +11,41 @@ struct PlainType(T); #[derive(Clone)] struct CloneType(T); +fn check(mut encoded: &[u8]) { + let _ = &mut encoded.clone(); + //~^ WARN call to `.clone()` on a reference in this situation does nothing + let _ = &encoded.clone(); + //~^ WARN call to `.clone()` on a reference in this situation does nothing +} + fn main() { let non_clone_type_ref = &PlainType(1u32); let non_clone_type_ref_clone: &PlainType = non_clone_type_ref.clone(); - //~^ WARNING call to `.clone()` on a reference in this situation does nothing + //~^ WARN call to `.clone()` on a reference in this situation does nothing let clone_type_ref = &CloneType(1u32); let clone_type_ref_clone: CloneType = clone_type_ref.clone(); - let clone_type_ref = &&CloneType(1u32); - let clone_type_ref_clone: &CloneType = clone_type_ref.clone(); - //~^ WARNING using `.clone()` on a double reference, which returns `&CloneType` let non_deref_type = &PlainType(1u32); let non_deref_type_deref: &PlainType = non_deref_type.deref(); - //~^ WARNING call to `.deref()` on a reference in this situation does nothing - - let non_deref_type = &&PlainType(1u32); - let non_deref_type_deref: &PlainType = non_deref_type.deref(); - //~^ WARNING using `.deref()` on a double reference, which returns `&PlainType` + //~^ WARN call to `.deref()` on a reference in this situation does nothing let non_borrow_type = &PlainType(1u32); let non_borrow_type_borrow: &PlainType = non_borrow_type.borrow(); - //~^ WARNING call to `.borrow()` on a reference in this situation does nothing + //~^ WARN call to `.borrow()` on a reference in this situation does nothing // Borrowing a &&T does not warn since it has collapsed the double reference let non_borrow_type = &&PlainType(1u32); let non_borrow_type_borrow: &PlainType = non_borrow_type.borrow(); - - let xs = ["a", "b", "c"]; - let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // could use `*x` instead - //~^ WARNING using `.clone()` on a double reference, which returns `&str` } fn generic(non_clone_type: &PlainType) { non_clone_type.clone(); - //~^ WARNING call to `.clone()` on a reference in this situation does nothing + //~^ WARN call to `.clone()` on a reference in this situation does nothing } fn non_generic(non_clone_type: &PlainType) { non_clone_type.clone(); - //~^ WARNING call to `.clone()` on a reference in this situation does nothing + //~^ WARN call to `.clone()` on a reference in this situation does nothing } diff --git a/tests/ui/lint/noop-method-call.stderr b/tests/ui/lint/noop-method-call.stderr index fb02c6f361e..aefc2706fd5 100644 --- a/tests/ui/lint/noop-method-call.stderr +++ b/tests/ui/lint/noop-method-call.stderr @@ -1,63 +1,59 @@ warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:15:71 + --> $DIR/noop-method-call.rs:15:25 | -LL | let non_clone_type_ref_clone: &PlainType = non_clone_type_ref.clone(); - | ^^^^^^^^ unnecessary method call +LL | let _ = &mut encoded.clone(); + | ^^^^^^^^ help: remove this redundant call | - = note: the type `PlainType` does not implement `Clone`, so calling `clone` on `&PlainType` copies the reference, which does not do anything and can be removed + = note: the type `[u8]` does not implement `Clone`, so calling `clone` on `&[u8]` copies the reference, which does not do anything and can be removed = note: `#[warn(noop_method_call)]` on by default -warning: using `.clone()` on a double reference, which returns `&CloneType` instead of cloning the inner type - --> $DIR/noop-method-call.rs:22:63 +warning: call to `.clone()` on a reference in this situation does nothing + --> $DIR/noop-method-call.rs:17:21 | -LL | let clone_type_ref_clone: &CloneType = clone_type_ref.clone(); - | ^^^^^^^^ +LL | let _ = &encoded.clone(); + | ^^^^^^^^ help: remove this redundant call | - = note: `#[warn(suspicious_double_ref_op)]` on by default + = note: the type `[u8]` does not implement `Clone`, so calling `clone` on `&[u8]` copies the reference, which does not do anything and can be removed + +warning: call to `.clone()` on a reference in this situation does nothing + --> $DIR/noop-method-call.rs:23:71 + | +LL | let non_clone_type_ref_clone: &PlainType = non_clone_type_ref.clone(); + | ^^^^^^^^ help: remove this redundant call + | + = note: the type `PlainType` does not implement `Clone`, so calling `clone` on `&PlainType` copies the reference, which does not do anything and can be removed warning: call to `.deref()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:26:63 + --> $DIR/noop-method-call.rs:31:63 | LL | let non_deref_type_deref: &PlainType = non_deref_type.deref(); - | ^^^^^^^^ unnecessary method call + | ^^^^^^^^ help: remove this redundant call | = note: the type `PlainType` does not implement `Deref`, so calling `deref` on `&PlainType` copies the reference, which does not do anything and can be removed -warning: using `.deref()` on a double reference, which returns `&PlainType` instead of dereferencing the inner type - --> $DIR/noop-method-call.rs:30:63 - | -LL | let non_deref_type_deref: &PlainType = non_deref_type.deref(); - | ^^^^^^^^ - warning: call to `.borrow()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:34:66 + --> $DIR/noop-method-call.rs:35:66 | LL | let non_borrow_type_borrow: &PlainType = non_borrow_type.borrow(); - | ^^^^^^^^^ unnecessary method call + | ^^^^^^^^^ help: remove this redundant call | = note: the type `PlainType` does not implement `Borrow`, so calling `borrow` on `&PlainType` copies the reference, which does not do anything and can be removed -warning: using `.clone()` on a double reference, which returns `&str` instead of cloning the inner type - --> $DIR/noop-method-call.rs:42:44 - | -LL | let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // could use `*x` instead - | ^^^^^^^^ - warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:47:19 + --> $DIR/noop-method-call.rs:44:19 | LL | non_clone_type.clone(); - | ^^^^^^^^ unnecessary method call + | ^^^^^^^^ help: remove this redundant call | = note: the type `PlainType` does not implement `Clone`, so calling `clone` on `&PlainType` copies the reference, which does not do anything and can be removed warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:52:19 + --> $DIR/noop-method-call.rs:49:19 | LL | non_clone_type.clone(); - | ^^^^^^^^ unnecessary method call + | ^^^^^^^^ help: remove this redundant call | = note: the type `PlainType` does not implement `Clone`, so calling `clone` on `&PlainType` copies the reference, which does not do anything and can be removed -warning: 8 warnings emitted +warning: 7 warnings emitted diff --git a/tests/ui/lint/suspicious-double-ref-op.rs b/tests/ui/lint/suspicious-double-ref-op.rs index b9bcd31c2a8..bc8c23c7b89 100644 --- a/tests/ui/lint/suspicious-double-ref-op.rs +++ b/tests/ui/lint/suspicious-double-ref-op.rs @@ -1,6 +1,14 @@ #![feature(lazy_cell)] #![deny(suspicious_double_ref_op, noop_method_call)] +use std::borrow::Borrow; +use std::ops::Deref; + +struct PlainType(T); + +#[derive(Clone)] +struct CloneType(T); + pub fn clone_on_double_ref() { let x = vec![1]; let y = &&x; @@ -20,11 +28,16 @@ fn rust_clippy_issue_9272() { println!("{str}") } -fn check(mut encoded: &[u8]) { - let _ = &mut encoded.clone(); - //~^ ERROR call to `.clone()` on a reference in this situation does nothing - let _ = &encoded.clone(); - //~^ ERROR call to `.clone()` on a reference in this situation does nothing -} +fn main() { + let clone_type_ref = &&CloneType(1u32); + let clone_type_ref_clone: &CloneType = clone_type_ref.clone(); + //~^ ERROR using `.clone()` on a double reference, which returns `&CloneType` -fn main() {} + let non_deref_type = &&PlainType(1u32); + let non_deref_type_deref: &PlainType = non_deref_type.deref(); + //~^ ERROR using `.deref()` on a double reference, which returns `&PlainType` + + let xs = ["a", "b", "c"]; + let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // could use `*x` instead + //~^ ERROR using `.clone()` on a double reference, which returns `&str` +} diff --git a/tests/ui/lint/suspicious-double-ref-op.stderr b/tests/ui/lint/suspicious-double-ref-op.stderr index f2128f2a0ed..f5a71d40fc1 100644 --- a/tests/ui/lint/suspicious-double-ref-op.stderr +++ b/tests/ui/lint/suspicious-double-ref-op.stderr @@ -1,5 +1,5 @@ error: using `.clone()` on a double reference, which returns `&Vec` instead of cloning the inner type - --> $DIR/suspicious-double-ref-op.rs:7:23 + --> $DIR/suspicious-double-ref-op.rs:15:23 | LL | let z: &Vec<_> = y.clone(); | ^^^^^^^^ @@ -10,26 +10,23 @@ note: the lint level is defined here LL | #![deny(suspicious_double_ref_op, noop_method_call)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: call to `.clone()` on a reference in this situation does nothing - --> $DIR/suspicious-double-ref-op.rs:24:25 +error: using `.clone()` on a double reference, which returns `&CloneType` instead of cloning the inner type + --> $DIR/suspicious-double-ref-op.rs:33:63 | -LL | let _ = &mut encoded.clone(); - | ^^^^^^^^ unnecessary method call - | - = note: the type `[u8]` does not implement `Clone`, so calling `clone` on `&[u8]` copies the reference, which does not do anything and can be removed -note: the lint level is defined here - --> $DIR/suspicious-double-ref-op.rs:2:35 - | -LL | #![deny(suspicious_double_ref_op, noop_method_call)] - | ^^^^^^^^^^^^^^^^ +LL | let clone_type_ref_clone: &CloneType = clone_type_ref.clone(); + | ^^^^^^^^ -error: call to `.clone()` on a reference in this situation does nothing - --> $DIR/suspicious-double-ref-op.rs:26:21 +error: using `.deref()` on a double reference, which returns `&PlainType` instead of dereferencing the inner type + --> $DIR/suspicious-double-ref-op.rs:37:63 | -LL | let _ = &encoded.clone(); - | ^^^^^^^^ unnecessary method call +LL | let non_deref_type_deref: &PlainType = non_deref_type.deref(); + | ^^^^^^^^ + +error: using `.clone()` on a double reference, which returns `&str` instead of cloning the inner type + --> $DIR/suspicious-double-ref-op.rs:41:44 | - = note: the type `[u8]` does not implement `Clone`, so calling `clone` on `&[u8]` copies the reference, which does not do anything and can be removed +LL | let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // could use `*x` instead + | ^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors