Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 4 additions & 2 deletions compiler/rustc_lint/src/noop_method_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,19 +145,21 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
},
);
} else {
// Report the method call's return type before adjustments required by its parent.
let unadjusted_expr_ty = cx.typeck_results().expr_ty(expr);
match name {
// If `type_of(x) == T` and `x.borrow()` is used to get `&T`,
// then that should be allowed
sym::noop_method_borrow => return,
sym::noop_method_clone => cx.emit_span_lint(
SUSPICIOUS_DOUBLE_REF_OP,
span,
SuspiciousDoubleRefCloneDiag { ty: expr_ty },
SuspiciousDoubleRefCloneDiag { ty: unadjusted_expr_ty },
),
sym::noop_method_deref => cx.emit_span_lint(
SUSPICIOUS_DOUBLE_REF_OP,
span,
SuspiciousDoubleRefDerefDiag { ty: expr_ty },
SuspiciousDoubleRefDerefDiag { ty: unadjusted_expr_ty },
),
_ => return,
}
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/lint/suspicious-double-ref-op.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![deny(suspicious_double_ref_op, noop_method_call)]

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

struct PlainType<T>(T);
Expand All @@ -27,6 +28,15 @@ fn rust_clippy_issue_9272() {
println!("{str}")
}

// https://github.com/rust-lang/rust/issues/146227
fn method_receiver_adjustment(file: &std::fs::File, double_ref: &&std::fs::File) {
let _ = file.clone().write(&[]);
//~^ ERROR using `.clone()` on a double reference, which returns `&File`

let _ = double_ref.deref().write(&[]);
//~^ ERROR using `.deref()` on a double reference, which returns `&File`
}

fn main() {
let clone_type_ref = &&CloneType(1u32);
let clone_type_ref_clone: &CloneType<u32> = clone_type_ref.clone();
Expand Down
22 changes: 17 additions & 5 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:14:23
--> $DIR/suspicious-double-ref-op.rs:15:23
|
LL | let z: &Vec<_> = y.clone();
| ^^^^^^^^
Expand All @@ -10,23 +10,35 @@ note: the lint level is defined here
LL | #![deny(suspicious_double_ref_op, noop_method_call)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: using `.clone()` on a double reference, which returns `&File` instead of cloning the inner type
--> $DIR/suspicious-double-ref-op.rs:33:17
|
LL | let _ = file.clone().write(&[]);
| ^^^^^^^^

error: using `.deref()` on a double reference, which returns `&File` instead of dereferencing the inner type
--> $DIR/suspicious-double-ref-op.rs:36:23
|
LL | let _ = double_ref.deref().write(&[]);
| ^^^^^^^^

error: using `.clone()` on a double reference, which returns `&CloneType<u32>` instead of cloning the inner type
--> $DIR/suspicious-double-ref-op.rs:32:63
--> $DIR/suspicious-double-ref-op.rs:42:63
|
LL | let clone_type_ref_clone: &CloneType<u32> = clone_type_ref.clone();
| ^^^^^^^^

error: using `.deref()` on a double reference, which returns `&PlainType<u32>` instead of dereferencing the inner type
--> $DIR/suspicious-double-ref-op.rs:36:63
--> $DIR/suspicious-double-ref-op.rs:46:63
|
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:40:44
--> $DIR/suspicious-double-ref-op.rs:50:44
|
LL | let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // could use `*x` instead
| ^^^^^^^^

error: aborting due to 4 previous errors
error: aborting due to 6 previous errors

Loading