Auto merge of #111916 - fee1-dead-contrib:noop-method-call-warn, r=compiler-errors
make `noop_method_call` warn by default r? `@compiler-errors`
This commit is contained in:
commit
4734ac0943
@ -410,8 +410,8 @@ lint_non_upper_case_global = {$sort} `{$name}` should have an upper case name
|
|||||||
.label = 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
|
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 `{$receiver_ty}` which `{$method}` is being called on is the same as the type returned from `{$method}`, so the method call does not do anything and can be removed
|
.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`
|
lint_only_cast_u8_to_char = only `u8` can be cast into `char`
|
||||||
.suggestion = use a `char` literal instead
|
.suggestion = use a `char` literal instead
|
||||||
|
@ -1231,8 +1231,9 @@ pub enum NonUpperCaseGlobalSub {
|
|||||||
#[note]
|
#[note]
|
||||||
pub struct NoopMethodCallDiag<'a> {
|
pub struct NoopMethodCallDiag<'a> {
|
||||||
pub method: Symbol,
|
pub method: Symbol,
|
||||||
pub receiver_ty: Ty<'a>,
|
pub orig_ty: Ty<'a>,
|
||||||
#[label]
|
pub trait_: Symbol,
|
||||||
|
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||||
pub label: Span,
|
pub label: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ declare_lint! {
|
|||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![allow(unused)]
|
/// # #![allow(unused)]
|
||||||
/// #![warn(noop_method_call)]
|
|
||||||
/// struct Foo;
|
/// struct Foo;
|
||||||
/// let foo = &Foo;
|
/// let foo = &Foo;
|
||||||
/// let clone: &Foo = foo.clone();
|
/// let clone: &Foo = foo.clone();
|
||||||
@ -34,7 +33,7 @@ declare_lint! {
|
|||||||
/// calling `clone` on a `&T` where `T` does not implement clone, actually doesn't do anything
|
/// calling `clone` on a `&T` where `T` does not implement clone, actually doesn't do anything
|
||||||
/// as references are copy. This lint detects these calls and warns the user about them.
|
/// as references are copy. This lint detects these calls and warns the user about them.
|
||||||
pub NOOP_METHOD_CALL,
|
pub NOOP_METHOD_CALL,
|
||||||
Allow,
|
Warn,
|
||||||
"detects the use of well-known noop methods"
|
"detects the use of well-known noop methods"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,10 +85,9 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
|
|||||||
|
|
||||||
let Some(trait_id) = cx.tcx.trait_of_item(did) else { return };
|
let Some(trait_id) = cx.tcx.trait_of_item(did) else { return };
|
||||||
|
|
||||||
if !matches!(
|
let Some(trait_) = cx.tcx.get_diagnostic_name(trait_id) else { return };
|
||||||
cx.tcx.get_diagnostic_name(trait_id),
|
|
||||||
Some(sym::Borrow | sym::Clone | sym::Deref)
|
if !matches!(trait_, sym::Borrow | sym::Clone | sym::Deref) {
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -114,11 +112,13 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
|
|||||||
let expr_span = expr.span;
|
let expr_span = expr.span;
|
||||||
let span = expr_span.with_lo(receiver.span.hi());
|
let span = expr_span.with_lo(receiver.span.hi());
|
||||||
|
|
||||||
|
let orig_ty = expr_ty.peel_refs();
|
||||||
|
|
||||||
if receiver_ty == expr_ty {
|
if receiver_ty == expr_ty {
|
||||||
cx.emit_spanned_lint(
|
cx.emit_spanned_lint(
|
||||||
NOOP_METHOD_CALL,
|
NOOP_METHOD_CALL,
|
||||||
span,
|
span,
|
||||||
NoopMethodCallDiag { method: call.ident.name, receiver_ty, label: span },
|
NoopMethodCallDiag { method: call.ident.name, orig_ty, trait_, label: span },
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
match name {
|
match name {
|
||||||
|
@ -41,7 +41,6 @@ use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP};
|
|||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
use super::InferCtxtPrivExt;
|
use super::InferCtxtPrivExt;
|
||||||
use crate::infer::InferCtxtExt as _;
|
use crate::infer::InferCtxtExt as _;
|
||||||
@ -3577,7 +3576,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
// to an associated type (as seen from `trait_pred`) in the predicate. Like in
|
// to an associated type (as seen from `trait_pred`) in the predicate. Like in
|
||||||
// trait_pred `S: Sum<<Self as Iterator>::Item>` and predicate `i32: Sum<&()>`
|
// trait_pred `S: Sum<<Self as Iterator>::Item>` and predicate `i32: Sum<&()>`
|
||||||
let mut type_diffs = vec![];
|
let mut type_diffs = vec![];
|
||||||
if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = parent_code.deref()
|
if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = parent_code
|
||||||
&& let Some(node_args) = typeck_results.node_args_opt(call_hir_id)
|
&& let Some(node_args) = typeck_results.node_args_opt(call_hir_id)
|
||||||
&& let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args)
|
&& let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args)
|
||||||
&& let Some(where_pred) = where_clauses.predicates.get(*idx)
|
&& let Some(where_pred) = where_clauses.predicates.get(*idx)
|
||||||
|
@ -473,6 +473,7 @@ fn bench_next_chunk_copied(b: &mut Bencher) {
|
|||||||
|
|
||||||
/// Exercises the TrustedRandomAccess specialization in ArrayChunks
|
/// Exercises the TrustedRandomAccess specialization in ArrayChunks
|
||||||
#[bench]
|
#[bench]
|
||||||
|
#[allow(noop_method_call)]
|
||||||
fn bench_next_chunk_trusted_random_access(b: &mut Bencher) {
|
fn bench_next_chunk_trusted_random_access(b: &mut Bencher) {
|
||||||
let v = vec![1u8; 1024];
|
let v = vec![1u8; 1024];
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#![allow(
|
#![allow(
|
||||||
clippy::borrow_deref_ref,
|
clippy::borrow_deref_ref,
|
||||||
suspicious_double_ref_op,
|
suspicious_double_ref_op,
|
||||||
|
noop_method_call,
|
||||||
clippy::explicit_auto_deref,
|
clippy::explicit_auto_deref,
|
||||||
clippy::needless_borrow,
|
clippy::needless_borrow,
|
||||||
clippy::no_effect,
|
clippy::no_effect,
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#![allow(
|
#![allow(
|
||||||
clippy::borrow_deref_ref,
|
clippy::borrow_deref_ref,
|
||||||
suspicious_double_ref_op,
|
suspicious_double_ref_op,
|
||||||
|
noop_method_call,
|
||||||
clippy::explicit_auto_deref,
|
clippy::explicit_auto_deref,
|
||||||
clippy::needless_borrow,
|
clippy::needless_borrow,
|
||||||
clippy::no_effect,
|
clippy::no_effect,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:54:19
|
--> $DIR/explicit_deref_methods.rs:55:19
|
||||||
|
|
|
|
||||||
LL | let b: &str = a.deref();
|
LL | let b: &str = a.deref();
|
||||||
| ^^^^^^^^^ help: try: `&*a`
|
| ^^^^^^^^^ help: try: `&*a`
|
||||||
@ -7,67 +7,67 @@ LL | let b: &str = a.deref();
|
|||||||
= note: `-D clippy::explicit-deref-methods` implied by `-D warnings`
|
= note: `-D clippy::explicit-deref-methods` implied by `-D warnings`
|
||||||
|
|
||||||
error: explicit `deref_mut` method call
|
error: explicit `deref_mut` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:56:23
|
--> $DIR/explicit_deref_methods.rs:57:23
|
||||||
|
|
|
|
||||||
LL | let b: &mut str = a.deref_mut();
|
LL | let b: &mut str = a.deref_mut();
|
||||||
| ^^^^^^^^^^^^^ help: try: `&mut **a`
|
| ^^^^^^^^^^^^^ help: try: `&mut **a`
|
||||||
|
|
||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:59:39
|
--> $DIR/explicit_deref_methods.rs:60:39
|
||||||
|
|
|
|
||||||
LL | let b: String = format!("{}, {}", a.deref(), a.deref());
|
LL | let b: String = format!("{}, {}", a.deref(), a.deref());
|
||||||
| ^^^^^^^^^ help: try: `&*a`
|
| ^^^^^^^^^ help: try: `&*a`
|
||||||
|
|
||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:59:50
|
--> $DIR/explicit_deref_methods.rs:60:50
|
||||||
|
|
|
|
||||||
LL | let b: String = format!("{}, {}", a.deref(), a.deref());
|
LL | let b: String = format!("{}, {}", a.deref(), a.deref());
|
||||||
| ^^^^^^^^^ help: try: `&*a`
|
| ^^^^^^^^^ help: try: `&*a`
|
||||||
|
|
||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:61:20
|
--> $DIR/explicit_deref_methods.rs:62:20
|
||||||
|
|
|
|
||||||
LL | println!("{}", a.deref());
|
LL | println!("{}", a.deref());
|
||||||
| ^^^^^^^^^ help: try: `&*a`
|
| ^^^^^^^^^ help: try: `&*a`
|
||||||
|
|
||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:64:11
|
--> $DIR/explicit_deref_methods.rs:65:11
|
||||||
|
|
|
|
||||||
LL | match a.deref() {
|
LL | match a.deref() {
|
||||||
| ^^^^^^^^^ help: try: `&*a`
|
| ^^^^^^^^^ help: try: `&*a`
|
||||||
|
|
||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:68:28
|
--> $DIR/explicit_deref_methods.rs:69:28
|
||||||
|
|
|
|
||||||
LL | let b: String = concat(a.deref());
|
LL | let b: String = concat(a.deref());
|
||||||
| ^^^^^^^^^ help: try: `&*a`
|
| ^^^^^^^^^ help: try: `&*a`
|
||||||
|
|
||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:70:13
|
--> $DIR/explicit_deref_methods.rs:71:13
|
||||||
|
|
|
|
||||||
LL | let b = just_return(a).deref();
|
LL | let b = just_return(a).deref();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)`
|
||||||
|
|
||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:72:28
|
--> $DIR/explicit_deref_methods.rs:73:28
|
||||||
|
|
|
|
||||||
LL | let b: String = concat(just_return(a).deref());
|
LL | let b: String = concat(just_return(a).deref());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)`
|
||||||
|
|
||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:74:19
|
--> $DIR/explicit_deref_methods.rs:75:19
|
||||||
|
|
|
|
||||||
LL | let b: &str = a.deref().deref();
|
LL | let b: &str = a.deref().deref();
|
||||||
| ^^^^^^^^^^^^^^^^^ help: try: `&**a`
|
| ^^^^^^^^^^^^^^^^^ help: try: `&**a`
|
||||||
|
|
||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:77:13
|
--> $DIR/explicit_deref_methods.rs:78:13
|
||||||
|
|
|
|
||||||
LL | let b = opt_a.unwrap().deref();
|
LL | let b = opt_a.unwrap().deref();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*opt_a.unwrap()`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*opt_a.unwrap()`
|
||||||
|
|
||||||
error: explicit `deref` method call
|
error: explicit `deref` method call
|
||||||
--> $DIR/explicit_deref_methods.rs:114:31
|
--> $DIR/explicit_deref_methods.rs:115:31
|
||||||
|
|
|
|
||||||
LL | let b: &str = expr_deref!(a.deref());
|
LL | let b: &str = expr_deref!(a.deref());
|
||||||
| ^^^^^^^^^ help: try: `&*a`
|
| ^^^^^^^^^ help: try: `&*a`
|
||||||
|
@ -1119,7 +1119,7 @@ fn check_overlapping_tests(found_paths: &BTreeSet<PathBuf>) {
|
|||||||
for path in found_paths {
|
for path in found_paths {
|
||||||
for ancestor in path.ancestors().skip(1) {
|
for ancestor in path.ancestors().skip(1) {
|
||||||
if found_paths.contains(ancestor) {
|
if found_paths.contains(ancestor) {
|
||||||
collisions.push((path, ancestor.clone()));
|
collisions.push((path, ancestor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
|
#![allow(noop_method_call)]
|
||||||
|
|
||||||
struct NoClone;
|
struct NoClone;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
51
tests/ui/lint/noop-method-call.fixed
Normal file
51
tests/ui/lint/noop-method-call.fixed
Normal file
@ -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
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
// check-pass
|
// check-pass
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
#![warn(noop_method_call)]
|
|
||||||
|
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
@ -11,45 +11,41 @@ struct PlainType<T>(T);
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct CloneType<T>(T);
|
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() {
|
fn main() {
|
||||||
let non_clone_type_ref = &PlainType(1u32);
|
let non_clone_type_ref = &PlainType(1u32);
|
||||||
let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
|
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 = &CloneType(1u32);
|
||||||
let clone_type_ref_clone: CloneType<u32> = clone_type_ref.clone();
|
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 = &PlainType(1u32);
|
||||||
let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
|
let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
|
||||||
//~^ WARNING call to `.deref()` on a reference in this situation does nothing
|
//~^ WARN 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>`
|
|
||||||
|
|
||||||
let non_borrow_type = &PlainType(1u32);
|
let non_borrow_type = &PlainType(1u32);
|
||||||
let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
|
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
|
// Borrowing a &&T does not warn since it has collapsed the double reference
|
||||||
let non_borrow_type = &&PlainType(1u32);
|
let non_borrow_type = &&PlainType(1u32);
|
||||||
let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
|
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>) {
|
fn generic<T>(non_clone_type: &PlainType<T>) {
|
||||||
non_clone_type.clone();
|
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>) {
|
fn non_generic(non_clone_type: &PlainType<u32>) {
|
||||||
non_clone_type.clone();
|
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
|
||||||
}
|
}
|
||||||
|
@ -1,67 +1,59 @@
|
|||||||
warning: call to `.clone()` on a reference in this situation does nothing
|
warning: call to `.clone()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:16:71
|
--> $DIR/noop-method-call.rs:15:25
|
||||||
|
|
|
||||||
|
LL | let _ = &mut encoded.clone();
|
||||||
|
| ^^^^^^^^ help: remove this redundant 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: `#[warn(noop_method_call)]` on by default
|
||||||
|
|
||||||
|
warning: call to `.clone()` on a reference in this situation does nothing
|
||||||
|
--> $DIR/noop-method-call.rs:17:21
|
||||||
|
|
|
||||||
|
LL | let _ = &encoded.clone();
|
||||||
|
| ^^^^^^^^ help: remove this redundant 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
|
||||||
|
|
||||||
|
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<u32> = non_clone_type_ref.clone();
|
LL | let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
|
||||||
| ^^^^^^^^ unnecessary method call
|
| ^^^^^^^^ help: remove this redundant call
|
||||||
|
|
|
|
||||||
= note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call 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
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/noop-method-call.rs:4:9
|
|
||||||
|
|
|
||||||
LL | #![warn(noop_method_call)]
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
warning: using `.clone()` on a double reference, which returns `&CloneType<u32>` instead of cloning the inner type
|
|
||||||
--> $DIR/noop-method-call.rs:23:63
|
|
||||||
|
|
|
||||||
LL | let clone_type_ref_clone: &CloneType<u32> = clone_type_ref.clone();
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: `#[warn(suspicious_double_ref_op)]` on by default
|
|
||||||
|
|
||||||
warning: call to `.deref()` on a reference in this situation does nothing
|
warning: call to `.deref()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:27:63
|
|
||||||
|
|
|
||||||
LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
|
|
||||||
| ^^^^^^^^ unnecessary method call
|
|
||||||
|
|
|
||||||
= note: the type `&PlainType<u32>` which `deref` is being called on is the same as the type returned from `deref`, so the method call 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:31:63
|
--> $DIR/noop-method-call.rs:31:63
|
||||||
|
|
|
|
||||||
LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
|
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
|
warning: call to `.borrow()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:35:66
|
--> $DIR/noop-method-call.rs:35:66
|
||||||
|
|
|
|
||||||
LL | let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
|
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>` which `borrow` is being called on is the same as the type returned from `borrow`, so the method call does not do anything and can be removed
|
= 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:43: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
|
warning: call to `.clone()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:48:19
|
--> $DIR/noop-method-call.rs:44:19
|
||||||
|
|
|
|
||||||
LL | non_clone_type.clone();
|
LL | non_clone_type.clone();
|
||||||
| ^^^^^^^^ unnecessary method call
|
| ^^^^^^^^ help: remove this redundant call
|
||||||
|
|
|
|
||||||
= note: the type `&PlainType<T>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed
|
= 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
|
warning: call to `.clone()` on a reference in this situation does nothing
|
||||||
--> $DIR/noop-method-call.rs:53:19
|
--> $DIR/noop-method-call.rs:49:19
|
||||||
|
|
|
|
||||||
LL | non_clone_type.clone();
|
LL | non_clone_type.clone();
|
||||||
| ^^^^^^^^ unnecessary method call
|
| ^^^^^^^^ help: remove this redundant call
|
||||||
|
|
|
|
||||||
= note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call 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: 8 warnings emitted
|
warning: 7 warnings emitted
|
||||||
|
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
#![feature(lazy_cell)]
|
#![feature(lazy_cell)]
|
||||||
#![deny(suspicious_double_ref_op, noop_method_call)]
|
#![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() {
|
pub fn clone_on_double_ref() {
|
||||||
let x = vec![1];
|
let x = vec![1];
|
||||||
let y = &&x;
|
let y = &&x;
|
||||||
@ -20,11 +28,16 @@ fn rust_clippy_issue_9272() {
|
|||||||
println!("{str}")
|
println!("{str}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check(mut encoded: &[u8]) {
|
fn main() {
|
||||||
let _ = &mut encoded.clone();
|
let clone_type_ref = &&CloneType(1u32);
|
||||||
//~^ ERROR call to `.clone()` on a reference in this situation does nothing
|
let clone_type_ref_clone: &CloneType<u32> = clone_type_ref.clone();
|
||||||
let _ = &encoded.clone();
|
//~^ ERROR using `.clone()` on a double reference, which returns `&CloneType<u32>`
|
||||||
//~^ ERROR call to `.clone()` on a reference in this situation does nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
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>`
|
||||||
|
|
||||||
|
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`
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: using `.clone()` on a double reference, which returns `&Vec<i32>` instead of cloning the inner type
|
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();
|
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)]
|
LL | #![deny(suspicious_double_ref_op, noop_method_call)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: call to `.clone()` on a reference in this situation does nothing
|
error: using `.clone()` on a double reference, which returns `&CloneType<u32>` instead of cloning the inner type
|
||||||
--> $DIR/suspicious-double-ref-op.rs:24:25
|
--> $DIR/suspicious-double-ref-op.rs:33:63
|
||||||
|
|
|
|
||||||
LL | let _ = &mut encoded.clone();
|
LL | let clone_type_ref_clone: &CloneType<u32> = clone_type_ref.clone();
|
||||||
| ^^^^^^^^ unnecessary method call
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
= note: the type `&[u8]` which `clone` is being called on is the same as the type returned from `clone`, so the method call 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)]
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: call to `.clone()` on a reference in this situation does nothing
|
error: using `.deref()` on a double reference, which returns `&PlainType<u32>` instead of dereferencing the inner type
|
||||||
--> $DIR/suspicious-double-ref-op.rs:26:21
|
--> $DIR/suspicious-double-ref-op.rs:37:63
|
||||||
|
|
|
|
||||||
LL | let _ = &encoded.clone();
|
LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
|
||||||
| ^^^^^^^^ unnecessary method call
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
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]` which `clone` is being called on is the same as the type returned from `clone`, so the method call 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
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
|
#![allow(noop_method_call)]
|
||||||
|
|
||||||
mod x {
|
mod x {
|
||||||
pub use crate::y::*;
|
pub use crate::y::*;
|
||||||
pub use std::ops::Deref as _;
|
pub use std::ops::Deref as _;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
|
#![allow(noop_method_call)]
|
||||||
|
|
||||||
mod x {
|
mod x {
|
||||||
pub use std::ops::Deref as _;
|
pub use std::ops::Deref as _;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user