Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
add suggestion
  • Loading branch information
fee1-dead committed Jul 23, 2023
commit 2a76c570d6115230af9df0888a721de9fb2c88bc
2 changes: 1 addition & 1 deletion compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down
51 changes: 51 additions & 0 deletions tests/ui/lint/noop-method-call.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// check-pass
// run-rustfix

#![allow(unused)]

use std::borrow::Borrow;
use std::ops::Deref;

struct PlainType<T>(T);

#[derive(Clone)]
struct CloneType<T>(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<u32> = 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<u32> = clone_type_ref.clone();


let non_deref_type = &PlainType(1u32);
let non_deref_type_deref: &PlainType<u32> = 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<u32> = 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<u32> = non_borrow_type.borrow();
}

fn generic<T>(non_clone_type: &PlainType<T>) {
non_clone_type;
//~^ WARN call to `.clone()` on a reference in this situation does nothing
}

fn non_generic(non_clone_type: &PlainType<u32>) {
non_clone_type;
//~^ WARN call to `.clone()` on a reference in this situation does nothing
}
29 changes: 13 additions & 16 deletions tests/ui/lint/noop-method-call.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// check-pass
// run-rustfix

#![allow(unused)]

Expand All @@ -10,45 +11,41 @@ struct PlainType<T>(T);
#[derive(Clone)]
struct CloneType<T>(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<u32> = 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<u32> = clone_type_ref.clone();

let clone_type_ref = &&CloneType(1u32);
let clone_type_ref_clone: &CloneType<u32> = clone_type_ref.clone();
//~^ WARNING using `.clone()` on a double reference, which returns `&CloneType<u32>`

let non_deref_type = &PlainType(1u32);
let non_deref_type_deref: &PlainType<u32> = 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<u32> = non_deref_type.deref();
//~^ WARNING using `.deref()` on a double reference, which returns `&PlainType<u32>`
//~^ WARN call to `.deref()` on a reference in this situation does nothing

let non_borrow_type = &PlainType(1u32);
let non_borrow_type_borrow: &PlainType<u32> = 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<u32> = 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<T>(non_clone_type: &PlainType<T>) {
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<u32>) {
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
}
56 changes: 26 additions & 30 deletions tests/ui/lint/noop-method-call.stderr
Original file line number Diff line number Diff line change
@@ -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<u32> = non_clone_type_ref.clone();
| ^^^^^^^^ unnecessary method call
LL | let _ = &mut encoded.clone();
| ^^^^^^^^ help: remove this redundant call
|
= note: the type `PlainType<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` 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<u32>` 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<u32> = 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 `.deref()` on a reference in this situation does nothing
--> $DIR/noop-method-call.rs:26:63
warning: call to `.clone()` on a reference in this situation does nothing
--> $DIR/noop-method-call.rs:23:71
|
LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
| ^^^^^^^^ unnecessary method call
LL | let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
| ^^^^^^^^ help: remove this redundant call
|
= note: the type `PlainType<u32>` does not implement `Deref`, so calling `deref` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
= note: the type `PlainType<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed

warning: using `.deref()` on a double reference, which returns `&PlainType<u32>` instead of dereferencing the inner type
--> $DIR/noop-method-call.rs:30:63
warning: call to `.deref()` on a reference in this situation does nothing
--> $DIR/noop-method-call.rs:31:63
|
LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
| ^^^^^^^^
| ^^^^^^^^ help: remove this redundant call
|
= note: the type `PlainType<u32>` does not implement `Deref`, so calling `deref` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed

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<u32> = non_borrow_type.borrow();
| ^^^^^^^^^ unnecessary method call
| ^^^^^^^^^ help: remove this redundant call
|
= note: the type `PlainType<u32>` does not implement `Borrow`, so calling `borrow` on `&PlainType<u32>` 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<T>` does not implement `Clone`, so calling `clone` on `&PlainType<T>` 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<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed

warning: 8 warnings emitted
warning: 7 warnings emitted

27 changes: 20 additions & 7 deletions tests/ui/lint/suspicious-double-ref-op.rs
Original file line number Diff line number Diff line change
@@ -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>(T);

#[derive(Clone)]
struct CloneType<T>(T);

pub fn clone_on_double_ref() {
let x = vec![1];
let y = &&x;
Expand All @@ -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<u32> = clone_type_ref.clone();
//~^ ERROR using `.clone()` on a double reference, which returns `&CloneType<u32>`

let non_deref_type = &&PlainType(1u32);
let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
//~^ ERROR using `.deref()` on a double reference, which returns `&PlainType<u32>`

fn main() {}
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`
}
33 changes: 15 additions & 18 deletions tests/ui/lint/suspicious-double-ref-op.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: using `.clone()` on a double reference, which returns `&Vec<i32>` 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();
| ^^^^^^^^
Expand All @@ -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<u32>` 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<u32> = 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<u32>` 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<u32> = 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