uplift clippy::clone_double_ref as suspicious_double_ref_op

This commit is contained in:
Deadbeef 2023-04-28 17:17:46 +00:00
parent 1a6ae3d692
commit 5c99175a9e
19 changed files with 230 additions and 199 deletions

View File

@ -40,7 +40,6 @@ use regex::Regex;
use tempfile::Builder as TempFileBuilder; use tempfile::Builder as TempFileBuilder;
use itertools::Itertools; use itertools::Itertools;
use std::borrow::Borrow;
use std::cell::OnceCell; use std::cell::OnceCell;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::ffi::OsString; use std::ffi::OsString;
@ -573,17 +572,17 @@ fn link_dwarf_object<'a>(
impl<Relocations> ThorinSession<Relocations> { impl<Relocations> ThorinSession<Relocations> {
fn alloc_mmap(&self, data: Mmap) -> &Mmap { fn alloc_mmap(&self, data: Mmap) -> &Mmap {
(*self.arena_mmap.alloc(data)).borrow() &*self.arena_mmap.alloc(data)
} }
} }
impl<Relocations> thorin::Session<Relocations> for ThorinSession<Relocations> { impl<Relocations> thorin::Session<Relocations> for ThorinSession<Relocations> {
fn alloc_data(&self, data: Vec<u8>) -> &[u8] { fn alloc_data(&self, data: Vec<u8>) -> &[u8] {
(*self.arena_data.alloc(data)).borrow() &*self.arena_data.alloc(data)
} }
fn alloc_relocation(&self, data: Relocations) -> &Relocations { fn alloc_relocation(&self, data: Relocations) -> &Relocations {
(*self.arena_relocations.alloc(data)).borrow() &*self.arena_relocations.alloc(data)
} }
fn read_input(&self, path: &Path) -> std::io::Result<&[u8]> { fn read_input(&self, path: &Path) -> std::io::Result<&[u8]> {

View File

@ -50,6 +50,9 @@ lint_deprecated_lint_name =
lint_renamed_or_removed_lint = {$msg} lint_renamed_or_removed_lint = {$msg}
.suggestion = use the new name .suggestion = use the new name
lint_suspicious_double_ref_op =
using `.{$call}()` on a double reference, which returns `{$ty}` instead of {$op} the inner type
lint_unknown_lint = lint_unknown_lint =
unknown lint: `{$name}` unknown lint: `{$name}`
.suggestion = did you mean .suggestion = did you mean

View File

@ -1150,6 +1150,14 @@ pub struct NoopMethodCallDiag<'a> {
pub label: Span, pub label: Span,
} }
#[derive(LintDiagnostic)]
#[diag(lint_suspicious_double_ref_op)]
pub struct SuspiciousDoubleRefDiag<'a> {
pub call: Symbol,
pub ty: Ty<'a>,
pub op: &'static str,
}
// pass_by_value.rs // pass_by_value.rs
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[diag(lint_pass_by_value)] #[diag(lint_pass_by_value)]

View File

@ -1,10 +1,11 @@
use crate::context::LintContext; use crate::context::LintContext;
use crate::lints::NoopMethodCallDiag; use crate::lints::{NoopMethodCallDiag, SuspiciousDoubleRefDiag};
use crate::LateContext; use crate::LateContext;
use crate::LateLintPass; use crate::LateLintPass;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::adjustment::Adjust;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
declare_lint! { declare_lint! {
@ -35,14 +36,44 @@ declare_lint! {
"detects the use of well-known noop methods" "detects the use of well-known noop methods"
} }
declare_lint_pass!(NoopMethodCall => [NOOP_METHOD_CALL]); declare_lint! {
/// The `suspicious_double_ref_op` lint checks for usage of `.clone()`/`.borrow()`/`.deref()`
/// on an `&&T` when `T: !Deref/Borrow/Clone`, which means the call will return the inner `&T`,
/// instead of performing the operation on the underlying `T` and can be confusing.
///
/// ### Example
///
/// ```rust
/// # #![allow(unused)]
/// struct Foo;
/// let foo = &&Foo;
/// let clone: &Foo = foo.clone();
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Since `Foo` doesn't implement `Clone`, running `.clone()` only dereferences the double
/// reference, instead of cloning the inner type which should be what was intended.
pub SUSPICIOUS_DOUBLE_REF_OP,
Warn,
"suspicious call of trait method on `&&T`"
}
declare_lint_pass!(NoopMethodCall => [NOOP_METHOD_CALL, SUSPICIOUS_DOUBLE_REF_OP]);
impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// We only care about method calls. // We only care about method calls.
let ExprKind::MethodCall(call, receiver, ..) = &expr.kind else { let ExprKind::MethodCall(call, receiver, _, call_span) = &expr.kind else {
return return;
}; };
if call_span.from_expansion() {
return;
}
// We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow` // We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
// traits and ignore any other method call. // traits and ignore any other method call.
let did = match cx.typeck_results().type_dependent_def(expr.hir_id) { let did = match cx.typeck_results().type_dependent_def(expr.hir_id) {
@ -70,25 +101,39 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
}; };
// (Re)check that it implements the noop diagnostic. // (Re)check that it implements the noop diagnostic.
let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return }; let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return };
if !matches!(
name, let op = match name {
sym::noop_method_borrow | sym::noop_method_clone | sym::noop_method_deref sym::noop_method_borrow => "borrowing",
) { sym::noop_method_clone => "cloning",
return; sym::noop_method_deref => "dereferencing",
} _ => return,
};
let receiver_ty = cx.typeck_results().expr_ty(receiver); let receiver_ty = cx.typeck_results().expr_ty(receiver);
let expr_ty = cx.typeck_results().expr_ty_adjusted(expr); let expr_ty = cx.typeck_results().expr_ty_adjusted(expr);
if receiver_ty != expr_ty { let arg_adjustments = cx.typeck_results().expr_adjustments(receiver);
// This lint will only trigger if the receiver type and resulting expression \
// type are the same, implying that the method call is unnecessary. // If there is any user defined auto-deref step, then we don't want to warn.
// https://github.com/rust-lang/rust-clippy/issues/9272
if arg_adjustments.iter().any(|adj| matches!(adj.kind, Adjust::Deref(Some(_)))) {
return; return;
} }
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());
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, receiver_ty, label: span },
); );
} else {
cx.emit_spanned_lint(
SUSPICIOUS_DOUBLE_REF_OP,
span,
SuspiciousDoubleRefDiag { call: call.ident.name, ty: expr_ty, op },
)
}
} }
} }

View File

@ -313,7 +313,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::methods::CHARS_NEXT_CMP_INFO, crate::methods::CHARS_NEXT_CMP_INFO,
crate::methods::CLEAR_WITH_DRAIN_INFO, crate::methods::CLEAR_WITH_DRAIN_INFO,
crate::methods::CLONED_INSTEAD_OF_COPIED_INFO, crate::methods::CLONED_INSTEAD_OF_COPIED_INFO,
crate::methods::CLONE_DOUBLE_REF_INFO,
crate::methods::CLONE_ON_COPY_INFO, crate::methods::CLONE_ON_COPY_INFO,
crate::methods::CLONE_ON_REF_PTR_INFO, crate::methods::CLONE_ON_REF_PTR_INFO,
crate::methods::COLLAPSIBLE_STR_REPLACE_INFO, crate::methods::COLLAPSIBLE_STR_REPLACE_INFO,

View File

@ -1,7 +1,6 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::get_parent_node; use clippy_utils::get_parent_node;
use clippy_utils::source::snippet_with_context; use clippy_utils::source::snippet_with_context;
use clippy_utils::sugg;
use clippy_utils::ty::is_copy; use clippy_utils::ty::is_copy;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, MatchSource, Node, PatKind, QPath}; use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, MatchSource, Node, PatKind, QPath};
@ -9,7 +8,6 @@ use rustc_lint::LateContext;
use rustc_middle::ty::{self, adjustment::Adjust, print::with_forced_trimmed_paths}; use rustc_middle::ty::{self, adjustment::Adjust, print::with_forced_trimmed_paths};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use super::CLONE_DOUBLE_REF;
use super::CLONE_ON_COPY; use super::CLONE_ON_COPY;
/// Checks for the `CLONE_ON_COPY` lint. /// Checks for the `CLONE_ON_COPY` lint.
@ -42,41 +40,7 @@ pub(super) fn check(
let ty = cx.typeck_results().expr_ty(expr); let ty = cx.typeck_results().expr_ty(expr);
if let ty::Ref(_, inner, _) = arg_ty.kind() { if let ty::Ref(_, inner, _) = arg_ty.kind() {
if let ty::Ref(_, innermost, _) = inner.kind() { if let ty::Ref(..) = inner.kind() {
span_lint_and_then(
cx,
CLONE_DOUBLE_REF,
expr.span,
&with_forced_trimmed_paths!(format!(
"using `clone` on a double-reference; \
this will copy the reference of type `{ty}` instead of cloning the inner type"
)),
|diag| {
if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) {
let mut ty = innermost;
let mut n = 0;
while let ty::Ref(_, inner, _) = ty.kind() {
ty = inner;
n += 1;
}
let refs = "&".repeat(n + 1);
let derefs = "*".repeat(n);
let explicit = with_forced_trimmed_paths!(format!("<{refs}{ty}>::clone({snip})"));
diag.span_suggestion(
expr.span,
"try dereferencing it",
with_forced_trimmed_paths!(format!("{refs}({derefs}{}).clone()", snip.deref())),
Applicability::MaybeIncorrect,
);
diag.span_suggestion(
expr.span,
"or try being explicit if you are sure, that you want to clone a reference",
explicit,
Applicability::MaybeIncorrect,
);
}
},
);
return; // don't report clone_on_copy return; // don't report clone_on_copy
} }
} }

View File

@ -984,29 +984,6 @@ declare_clippy_lint! {
"using 'clone' on a ref-counted pointer" "using 'clone' on a ref-counted pointer"
} }
declare_clippy_lint! {
/// ### What it does
/// Checks for usage of `.clone()` on an `&&T`.
///
/// ### Why is this bad?
/// Cloning an `&&T` copies the inner `&T`, instead of
/// cloning the underlying `T`.
///
/// ### Example
/// ```rust
/// fn main() {
/// let x = vec![1];
/// let y = &&x;
/// let z = y.clone();
/// println!("{:p} {:p}", *y, z); // prints out the same pointer
/// }
/// ```
#[clippy::version = "pre 1.29.0"]
pub CLONE_DOUBLE_REF,
correctness,
"using `clone` on `&&T`"
}
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
/// Checks for usage of `.to_string()` on an `&&T` where /// Checks for usage of `.to_string()` on an `&&T` where
@ -3258,7 +3235,6 @@ impl_lint_pass!(Methods => [
CHARS_LAST_CMP, CHARS_LAST_CMP,
CLONE_ON_COPY, CLONE_ON_COPY,
CLONE_ON_REF_PTR, CLONE_ON_REF_PTR,
CLONE_DOUBLE_REF,
COLLAPSIBLE_STR_REPLACE, COLLAPSIBLE_STR_REPLACE,
ITER_OVEREAGER_CLONED, ITER_OVEREAGER_CLONED,
CLONED_INSTEAD_OF_COPIED, CLONED_INSTEAD_OF_COPIED,

View File

@ -30,6 +30,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
("clippy::stutter", "clippy::module_name_repetitions"), ("clippy::stutter", "clippy::module_name_repetitions"),
("clippy::to_string_in_display", "clippy::recursive_format_impl"), ("clippy::to_string_in_display", "clippy::recursive_format_impl"),
("clippy::zero_width_space", "clippy::invisible_characters"), ("clippy::zero_width_space", "clippy::invisible_characters"),
("clippy::clone_double_ref", "suspicious_double_ref_op"),
("clippy::drop_bounds", "drop_bounds"), ("clippy::drop_bounds", "drop_bounds"),
("clippy::for_loop_over_option", "for_loops_over_fallibles"), ("clippy::for_loop_over_option", "for_loops_over_fallibles"),
("clippy::for_loop_over_result", "for_loops_over_fallibles"), ("clippy::for_loop_over_result", "for_loops_over_fallibles"),

View File

@ -3,7 +3,7 @@
#![allow(unused_variables)] #![allow(unused_variables)]
#![allow( #![allow(
clippy::borrow_deref_ref, clippy::borrow_deref_ref,
clippy::clone_double_ref, suspicious_double_ref_op,
clippy::explicit_auto_deref, clippy::explicit_auto_deref,
clippy::needless_borrow, clippy::needless_borrow,
clippy::uninlined_format_args clippy::uninlined_format_args

View File

@ -3,7 +3,7 @@
#![allow(unused_variables)] #![allow(unused_variables)]
#![allow( #![allow(
clippy::borrow_deref_ref, clippy::borrow_deref_ref,
clippy::clone_double_ref, suspicious_double_ref_op,
clippy::explicit_auto_deref, clippy::explicit_auto_deref,
clippy::needless_borrow, clippy::needless_borrow,
clippy::uninlined_format_args clippy::uninlined_format_args

View File

@ -36,6 +36,7 @@
#![allow(enum_intrinsics_non_enums)] #![allow(enum_intrinsics_non_enums)]
#![allow(non_fmt_panics)] #![allow(non_fmt_panics)]
#![allow(named_arguments_used_positionally)] #![allow(named_arguments_used_positionally)]
#![allow(suspicious_double_ref_op)]
#![allow(temporary_cstring_as_ptr)] #![allow(temporary_cstring_as_ptr)]
#![allow(unknown_lints)] #![allow(unknown_lints)]
#![allow(unused_labels)] #![allow(unused_labels)]
@ -67,6 +68,7 @@
#![warn(clippy::module_name_repetitions)] #![warn(clippy::module_name_repetitions)]
#![warn(clippy::recursive_format_impl)] #![warn(clippy::recursive_format_impl)]
#![warn(clippy::invisible_characters)] #![warn(clippy::invisible_characters)]
#![warn(suspicious_double_ref_op)]
#![warn(drop_bounds)] #![warn(drop_bounds)]
#![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)]
#![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)]

View File

@ -36,6 +36,7 @@
#![allow(enum_intrinsics_non_enums)] #![allow(enum_intrinsics_non_enums)]
#![allow(non_fmt_panics)] #![allow(non_fmt_panics)]
#![allow(named_arguments_used_positionally)] #![allow(named_arguments_used_positionally)]
#![allow(suspicious_double_ref_op)]
#![allow(temporary_cstring_as_ptr)] #![allow(temporary_cstring_as_ptr)]
#![allow(unknown_lints)] #![allow(unknown_lints)]
#![allow(unused_labels)] #![allow(unused_labels)]
@ -67,6 +68,7 @@
#![warn(clippy::stutter)] #![warn(clippy::stutter)]
#![warn(clippy::to_string_in_display)] #![warn(clippy::to_string_in_display)]
#![warn(clippy::zero_width_space)] #![warn(clippy::zero_width_space)]
#![warn(clippy::clone_double_ref)]
#![warn(clippy::drop_bounds)] #![warn(clippy::drop_bounds)]
#![warn(clippy::for_loop_over_option)] #![warn(clippy::for_loop_over_option)]
#![warn(clippy::for_loop_over_result)] #![warn(clippy::for_loop_over_result)]

View File

@ -1,5 +1,5 @@
error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range`
--> $DIR/rename.rs:42:9 --> $DIR/rename.rs:43:9
| |
LL | #![warn(clippy::almost_complete_letter_range)] LL | #![warn(clippy::almost_complete_letter_range)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
@ -7,250 +7,256 @@ LL | #![warn(clippy::almost_complete_letter_range)]
= note: `-D renamed-and-removed-lints` implied by `-D warnings` = note: `-D renamed-and-removed-lints` implied by `-D warnings`
error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
--> $DIR/rename.rs:43:9 --> $DIR/rename.rs:44:9
| |
LL | #![warn(clippy::blacklisted_name)] LL | #![warn(clippy::blacklisted_name)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
--> $DIR/rename.rs:44:9 --> $DIR/rename.rs:45:9
| |
LL | #![warn(clippy::block_in_if_condition_expr)] LL | #![warn(clippy::block_in_if_condition_expr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
--> $DIR/rename.rs:45:9 --> $DIR/rename.rs:46:9
| |
LL | #![warn(clippy::block_in_if_condition_stmt)] LL | #![warn(clippy::block_in_if_condition_stmt)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
--> $DIR/rename.rs:46:9 --> $DIR/rename.rs:47:9
| |
LL | #![warn(clippy::box_vec)] LL | #![warn(clippy::box_vec)]
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
--> $DIR/rename.rs:47:9 --> $DIR/rename.rs:48:9
| |
LL | #![warn(clippy::const_static_lifetime)] LL | #![warn(clippy::const_static_lifetime)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
--> $DIR/rename.rs:48:9 --> $DIR/rename.rs:49:9
| |
LL | #![warn(clippy::cyclomatic_complexity)] LL | #![warn(clippy::cyclomatic_complexity)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq`
--> $DIR/rename.rs:49:9 --> $DIR/rename.rs:50:9
| |
LL | #![warn(clippy::derive_hash_xor_eq)] LL | #![warn(clippy::derive_hash_xor_eq)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq`
error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
--> $DIR/rename.rs:50:9 --> $DIR/rename.rs:51:9
| |
LL | #![warn(clippy::disallowed_method)] LL | #![warn(clippy::disallowed_method)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
--> $DIR/rename.rs:51:9 --> $DIR/rename.rs:52:9
| |
LL | #![warn(clippy::disallowed_type)] LL | #![warn(clippy::disallowed_type)]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`
--> $DIR/rename.rs:52:9 --> $DIR/rename.rs:53:9
| |
LL | #![warn(clippy::eval_order_dependence)] LL | #![warn(clippy::eval_order_dependence)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
--> $DIR/rename.rs:53:9 --> $DIR/rename.rs:54:9
| |
LL | #![warn(clippy::identity_conversion)] LL | #![warn(clippy::identity_conversion)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
--> $DIR/rename.rs:54:9 --> $DIR/rename.rs:55:9
| |
LL | #![warn(clippy::if_let_some_result)] LL | #![warn(clippy::if_let_some_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
--> $DIR/rename.rs:55:9 --> $DIR/rename.rs:56:9
| |
LL | #![warn(clippy::logic_bug)] LL | #![warn(clippy::logic_bug)]
| ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`
error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
--> $DIR/rename.rs:56:9 --> $DIR/rename.rs:57:9
| |
LL | #![warn(clippy::new_without_default_derive)] LL | #![warn(clippy::new_without_default_derive)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
--> $DIR/rename.rs:57:9 --> $DIR/rename.rs:58:9
| |
LL | #![warn(clippy::option_and_then_some)] LL | #![warn(clippy::option_and_then_some)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
--> $DIR/rename.rs:58:9 --> $DIR/rename.rs:59:9
| |
LL | #![warn(clippy::option_expect_used)] LL | #![warn(clippy::option_expect_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
--> $DIR/rename.rs:59:9 --> $DIR/rename.rs:60:9
| |
LL | #![warn(clippy::option_map_unwrap_or)] LL | #![warn(clippy::option_map_unwrap_or)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
--> $DIR/rename.rs:60:9 --> $DIR/rename.rs:61:9
| |
LL | #![warn(clippy::option_map_unwrap_or_else)] LL | #![warn(clippy::option_map_unwrap_or_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
--> $DIR/rename.rs:61:9 --> $DIR/rename.rs:62:9
| |
LL | #![warn(clippy::option_unwrap_used)] LL | #![warn(clippy::option_unwrap_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
--> $DIR/rename.rs:62:9 --> $DIR/rename.rs:63:9
| |
LL | #![warn(clippy::ref_in_deref)] LL | #![warn(clippy::ref_in_deref)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
--> $DIR/rename.rs:63:9 --> $DIR/rename.rs:64:9
| |
LL | #![warn(clippy::result_expect_used)] LL | #![warn(clippy::result_expect_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
--> $DIR/rename.rs:64:9 --> $DIR/rename.rs:65:9
| |
LL | #![warn(clippy::result_map_unwrap_or_else)] LL | #![warn(clippy::result_map_unwrap_or_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
--> $DIR/rename.rs:65:9 --> $DIR/rename.rs:66:9
| |
LL | #![warn(clippy::result_unwrap_used)] LL | #![warn(clippy::result_unwrap_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
--> $DIR/rename.rs:66:9 --> $DIR/rename.rs:67:9
| |
LL | #![warn(clippy::single_char_push_str)] LL | #![warn(clippy::single_char_push_str)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
--> $DIR/rename.rs:67:9 --> $DIR/rename.rs:68:9
| |
LL | #![warn(clippy::stutter)] LL | #![warn(clippy::stutter)]
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
--> $DIR/rename.rs:68:9 --> $DIR/rename.rs:69:9
| |
LL | #![warn(clippy::to_string_in_display)] LL | #![warn(clippy::to_string_in_display)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
--> $DIR/rename.rs:69:9 --> $DIR/rename.rs:70:9
| |
LL | #![warn(clippy::zero_width_space)] LL | #![warn(clippy::zero_width_space)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
--> $DIR/rename.rs:71:9
|
LL | #![warn(clippy::clone_double_ref)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`
error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
--> $DIR/rename.rs:70:9 --> $DIR/rename.rs:72:9
| |
LL | #![warn(clippy::drop_bounds)] LL | #![warn(clippy::drop_bounds)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
--> $DIR/rename.rs:71:9 --> $DIR/rename.rs:73:9
| |
LL | #![warn(clippy::for_loop_over_option)] LL | #![warn(clippy::for_loop_over_option)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
--> $DIR/rename.rs:72:9 --> $DIR/rename.rs:74:9
| |
LL | #![warn(clippy::for_loop_over_result)] LL | #![warn(clippy::for_loop_over_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
--> $DIR/rename.rs:73:9 --> $DIR/rename.rs:75:9
| |
LL | #![warn(clippy::for_loops_over_fallibles)] LL | #![warn(clippy::for_loops_over_fallibles)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
--> $DIR/rename.rs:74:9 --> $DIR/rename.rs:76:9
| |
LL | #![warn(clippy::into_iter_on_array)] LL | #![warn(clippy::into_iter_on_array)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
--> $DIR/rename.rs:75:9 --> $DIR/rename.rs:77:9
| |
LL | #![warn(clippy::invalid_atomic_ordering)] LL | #![warn(clippy::invalid_atomic_ordering)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
error: lint `clippy::invalid_ref` has been renamed to `invalid_value` error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
--> $DIR/rename.rs:76:9 --> $DIR/rename.rs:78:9
| |
LL | #![warn(clippy::invalid_ref)] LL | #![warn(clippy::invalid_ref)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
--> $DIR/rename.rs:77:9 --> $DIR/rename.rs:79:9
| |
LL | #![warn(clippy::let_underscore_drop)] LL | #![warn(clippy::let_underscore_drop)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
--> $DIR/rename.rs:78:9 --> $DIR/rename.rs:80:9
| |
LL | #![warn(clippy::mem_discriminant_non_enum)] LL | #![warn(clippy::mem_discriminant_non_enum)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
--> $DIR/rename.rs:79:9 --> $DIR/rename.rs:81:9
| |
LL | #![warn(clippy::panic_params)] LL | #![warn(clippy::panic_params)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
--> $DIR/rename.rs:80:9 --> $DIR/rename.rs:82:9
| |
LL | #![warn(clippy::positional_named_format_parameters)] LL | #![warn(clippy::positional_named_format_parameters)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
--> $DIR/rename.rs:81:9 --> $DIR/rename.rs:83:9
| |
LL | #![warn(clippy::temporary_cstring_as_ptr)] LL | #![warn(clippy::temporary_cstring_as_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
--> $DIR/rename.rs:82:9 --> $DIR/rename.rs:84:9
| |
LL | #![warn(clippy::unknown_clippy_lints)] LL | #![warn(clippy::unknown_clippy_lints)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
error: lint `clippy::unused_label` has been renamed to `unused_labels` error: lint `clippy::unused_label` has been renamed to `unused_labels`
--> $DIR/rename.rs:83:9 --> $DIR/rename.rs:85:9
| |
LL | #![warn(clippy::unused_label)] LL | #![warn(clippy::unused_label)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
error: aborting due to 42 previous errors error: aborting due to 43 previous errors

View File

@ -42,14 +42,6 @@ fn clone_on_copy_generic<T: Copy>(t: T) {
Some(t).clone(); Some(t).clone();
} }
fn clone_on_double_ref() {
let x = vec![1];
let y = &&x;
let z: &Vec<_> = y.clone();
println!("{:p} {:p}", *y, z);
}
mod many_derefs { mod many_derefs {
struct A; struct A;
struct B; struct B;
@ -84,11 +76,6 @@ mod many_derefs {
let _: E = a.clone(); let _: E = a.clone();
let _: E = *****a; let _: E = *****a;
} }
fn check(mut encoded: &[u8]) {
let _ = &mut encoded.clone();
let _ = &encoded.clone();
}
} }
mod issue2076 { mod issue2076 {

View File

@ -44,63 +44,17 @@ error: using `clone` on type `Option<T>` which implements the `Copy` trait
LL | Some(t).clone(); LL | Some(t).clone();
| ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)` | ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)`
error: using `clone` on a double-reference; this will copy the reference of type `&Vec<i32>` instead of cloning the inner type
--> $DIR/unnecessary_clone.rs:48:22
|
LL | let z: &Vec<_> = y.clone();
| ^^^^^^^^^
|
= note: `#[deny(clippy::clone_double_ref)]` on by default
help: try dereferencing it
|
LL | let z: &Vec<_> = &(*y).clone();
| ~~~~~~~~~~~~~
help: or try being explicit if you are sure, that you want to clone a reference
|
LL | let z: &Vec<_> = <&Vec<i32>>::clone(y);
| ~~~~~~~~~~~~~~~~~~~~~
error: using `clone` on type `E` which implements the `Copy` trait error: using `clone` on type `E` which implements the `Copy` trait
--> $DIR/unnecessary_clone.rs:84:20 --> $DIR/unnecessary_clone.rs:76:20
| |
LL | let _: E = a.clone(); LL | let _: E = a.clone();
| ^^^^^^^^^ help: try dereferencing it: `*****a` | ^^^^^^^^^ help: try dereferencing it: `*****a`
error: using `clone` on a double-reference; this will copy the reference of type `&[u8]` instead of cloning the inner type
--> $DIR/unnecessary_clone.rs:89:22
|
LL | let _ = &mut encoded.clone();
| ^^^^^^^^^^^^^^^
|
help: try dereferencing it
|
LL | let _ = &mut &(*encoded).clone();
| ~~~~~~~~~~~~~~~~~~~
help: or try being explicit if you are sure, that you want to clone a reference
|
LL | let _ = &mut <&[u8]>::clone(encoded);
| ~~~~~~~~~~~~~~~~~~~~~~~
error: using `clone` on a double-reference; this will copy the reference of type `&[u8]` instead of cloning the inner type
--> $DIR/unnecessary_clone.rs:90:18
|
LL | let _ = &encoded.clone();
| ^^^^^^^^^^^^^^^
|
help: try dereferencing it
|
LL | let _ = &&(*encoded).clone();
| ~~~~~~~~~~~~~~~~~~~
help: or try being explicit if you are sure, that you want to clone a reference
|
LL | let _ = &<&[u8]>::clone(encoded);
| ~~~~~~~~~~~~~~~~~~~~~~~
error: using `.clone()` on a ref-counted pointer error: using `.clone()` on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:108:14 --> $DIR/unnecessary_clone.rs:95:14
| |
LL | Some(try_opt!(Some(rc)).clone()) LL | Some(try_opt!(Some(rc)).clone())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Rc::<u8>::clone(&try_opt!(Some(rc)))` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Rc::<u8>::clone(&try_opt!(Some(rc)))`
error: aborting due to 12 previous errors error: aborting due to 9 previous errors

View File

@ -19,18 +19,17 @@ fn main() {
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();
// Calling clone on a double reference doesn't warn since the method call itself
// peels the outer reference off
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();
//~^ 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 //~^ WARNING call to `.deref()` on a reference in this situation does nothing
// Dereferencing a &&T does not warn since it has collapsed the double reference
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 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();
@ -41,7 +40,8 @@ fn main() {
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 xs = ["a", "b", "c"];
let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // ok, but could use `*x` instead 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>) {

View File

@ -11,22 +11,42 @@ note: the lint level is defined here
LL | #![warn(noop_method_call)] 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:28:63 --> $DIR/noop-method-call.rs:27: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();
| ^^^^^^^^ unnecessary method call | ^^^^^^^^ 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 = 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
|
LL | let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
| ^^^^^^^^
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:36: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 | ^^^^^^^^^ unnecessary method 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>` 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
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:48:19
| |
@ -43,5 +63,5 @@ LL | non_clone_type.clone();
| |
= 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>` 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
warning: 5 warnings emitted warning: 8 warnings emitted

View File

@ -0,0 +1,30 @@
#![feature(lazy_cell)]
#![deny(suspicious_double_ref_op, noop_method_call)]
pub fn clone_on_double_ref() {
let x = vec![1];
let y = &&x;
let z: &Vec<_> = y.clone();
//~^ ERROR using `.clone()` on a double reference, which returns `&Vec<i32>`
println!("{:p} {:p}", *y, z);
}
use std::sync::LazyLock;
pub static STRS: LazyLock<&str> = LazyLock::new(|| "First");
// https://github.com/rust-lang/rust-clippy/issues/9272
fn rust_clippy_issue_9272() {
let str = STRS.clone();
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() {}

View File

@ -0,0 +1,35 @@
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
|
LL | let z: &Vec<_> = y.clone();
| ^^^^^^^^
|
note: the lint level is defined here
--> $DIR/suspicious-double-ref-op.rs:2:9
|
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
|
LL | let _ = &mut encoded.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
--> $DIR/suspicious-double-ref-op.rs:26:21
|
LL | let _ = &encoded.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
error: aborting due to 3 previous errors