Skip to content

Commit db7d837

Browse files
Rollup merge of #112517 - fee1-dead-contrib:sus-op-no-borrow, r=compiler-errors
`suspicious_double_ref_op`: don't lint on `.borrow()` closes #112489
2 parents ab314a5 + 1caed51 commit db7d837

File tree

4 files changed

+64
-39
lines changed

4 files changed

+64
-39
lines changed

compiler/rustc_lint/messages.ftl

+5-7
Original file line numberDiff line numberDiff line change
@@ -479,13 +479,11 @@ lint_requested_level = requested on the command line with `{$level} {$lint_name}
479479
lint_supertrait_as_deref_target = `{$t}` implements `Deref` with supertrait `{$target_principal}` as target
480480
.label = target type is set here
481481
482-
lint_suspicious_double_ref_op =
483-
using `.{$call}()` on a double reference, which returns `{$ty}` instead of {$op ->
484-
*[should_not_happen] [{$op}]
485-
[deref] dereferencing
486-
[borrow] borrowing
487-
[clone] cloning
488-
} the inner type
482+
lint_suspicious_double_ref_clone =
483+
using `.clone()` on a double reference, which returns `{$ty}` instead of cloning the inner type
484+
485+
lint_suspicious_double_ref_deref =
486+
using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type
489487
490488
lint_trivial_untranslatable_diag = diagnostic with static strings only
491489

compiler/rustc_lint/src/lints.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -1231,11 +1231,15 @@ pub struct NoopMethodCallDiag<'a> {
12311231
}
12321232

12331233
#[derive(LintDiagnostic)]
1234-
#[diag(lint_suspicious_double_ref_op)]
1235-
pub struct SuspiciousDoubleRefDiag<'a> {
1236-
pub call: Symbol,
1234+
#[diag(lint_suspicious_double_ref_deref)]
1235+
pub struct SuspiciousDoubleRefDerefDiag<'a> {
1236+
pub ty: Ty<'a>,
1237+
}
1238+
1239+
#[derive(LintDiagnostic)]
1240+
#[diag(lint_suspicious_double_ref_clone)]
1241+
pub struct SuspiciousDoubleRefCloneDiag<'a> {
12371242
pub ty: Ty<'a>,
1238-
pub op: &'static str,
12391243
}
12401244

12411245
// pass_by_value.rs

compiler/rustc_lint/src/noop_method_call.rs

+34-28
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::context::LintContext;
2-
use crate::lints::{NoopMethodCallDiag, SuspiciousDoubleRefDiag};
2+
use crate::lints::{
3+
NoopMethodCallDiag, SuspiciousDoubleRefCloneDiag, SuspiciousDoubleRefDerefDiag,
4+
};
35
use crate::LateContext;
46
use crate::LateLintPass;
57
use rustc_hir::def::DefKind;
@@ -76,22 +78,22 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
7678

7779
// We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
7880
// traits and ignore any other method call.
79-
let did = match cx.typeck_results().type_dependent_def(expr.hir_id) {
80-
// Verify we are dealing with a method/associated function.
81-
Some((DefKind::AssocFn, did)) => match cx.tcx.trait_of_item(did) {
82-
// Check that we're dealing with a trait method for one of the traits we care about.
83-
Some(trait_id)
84-
if matches!(
85-
cx.tcx.get_diagnostic_name(trait_id),
86-
Some(sym::Borrow | sym::Clone | sym::Deref)
87-
) =>
88-
{
89-
did
90-
}
91-
_ => return,
92-
},
93-
_ => return,
81+
82+
let Some((DefKind::AssocFn, did)) =
83+
cx.typeck_results().type_dependent_def(expr.hir_id)
84+
else {
85+
return;
86+
};
87+
88+
let Some(trait_id) = cx.tcx.trait_of_item(did) else { return };
89+
90+
if !matches!(
91+
cx.tcx.get_diagnostic_name(trait_id),
92+
Some(sym::Borrow | sym::Clone | sym::Deref)
93+
) {
94+
return;
9495
};
96+
9597
let substs = cx
9698
.tcx
9799
.normalize_erasing_regions(cx.param_env, cx.typeck_results().node_substs(expr.hir_id));
@@ -102,13 +104,6 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
102104
// (Re)check that it implements the noop diagnostic.
103105
let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return };
104106

105-
let op = match name {
106-
sym::noop_method_borrow => "borrow",
107-
sym::noop_method_clone => "clone",
108-
sym::noop_method_deref => "deref",
109-
_ => return,
110-
};
111-
112107
let receiver_ty = cx.typeck_results().expr_ty(receiver);
113108
let expr_ty = cx.typeck_results().expr_ty_adjusted(expr);
114109
let arg_adjustments = cx.typeck_results().expr_adjustments(receiver);
@@ -129,11 +124,22 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
129124
NoopMethodCallDiag { method: call.ident.name, receiver_ty, label: span },
130125
);
131126
} else {
132-
cx.emit_spanned_lint(
133-
SUSPICIOUS_DOUBLE_REF_OP,
134-
span,
135-
SuspiciousDoubleRefDiag { call: call.ident.name, ty: expr_ty, op },
136-
)
127+
match name {
128+
// If `type_of(x) == T` and `x.borrow()` is used to get `&T`,
129+
// then that should be allowed
130+
sym::noop_method_borrow => return,
131+
sym::noop_method_clone => cx.emit_spanned_lint(
132+
SUSPICIOUS_DOUBLE_REF_OP,
133+
span,
134+
SuspiciousDoubleRefCloneDiag { ty: expr_ty },
135+
),
136+
sym::noop_method_deref => cx.emit_spanned_lint(
137+
SUSPICIOUS_DOUBLE_REF_OP,
138+
span,
139+
SuspiciousDoubleRefDerefDiag { ty: expr_ty },
140+
),
141+
_ => return,
142+
}
137143
}
138144
}
139145
}

tests/ui/lint/issue-112489.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// check-pass
2+
use std::borrow::Borrow;
3+
4+
struct S;
5+
6+
trait T: Sized {
7+
fn foo(self) {}
8+
}
9+
10+
impl T for S {}
11+
impl T for &S {}
12+
13+
fn main() {
14+
let s = S;
15+
s.borrow().foo();
16+
s.foo();
17+
}

0 commit comments

Comments
 (0)