[explicit_deref_methods]: do not lint on method chains (#14921)

changelog: [`explicit_deref_methods`]: do not lint on method chains
fixes rust-lang/rust-clippy#14593
This commit is contained in:
Samuel Tardieu 2025-05-30 15:02:47 +00:00 committed by GitHub
commit 010c2d3793
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 15 additions and 25 deletions

View file

@ -305,7 +305,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
RefOp::Method { mutbl, is_ufcs }
if !is_lint_allowed(cx, EXPLICIT_DEREF_METHODS, expr.hir_id)
// Allow explicit deref in method chains. e.g. `foo.deref().bar()`
&& (is_ufcs || !in_postfix_position(cx, expr)) =>
&& (is_ufcs || !is_in_method_chain(cx, expr)) =>
{
let ty_changed_count = usize::from(!deref_method_same_type(expr_ty, typeck.expr_ty(sub_expr)));
self.state = Some((
@ -728,7 +728,13 @@ fn deref_method_same_type<'tcx>(result_ty: Ty<'tcx>, arg_ty: Ty<'tcx>) -> bool {
}
}
fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
fn is_in_method_chain<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
if let ExprKind::MethodCall(_, recv, _, _) = e.kind
&& matches!(recv.kind, ExprKind::MethodCall(..))
{
return true;
}
if let Some(parent) = get_parent_expr(cx, e)
&& parent.span.eq_ctxt(e.span)
{

View file

@ -81,12 +81,10 @@ fn main() {
let b: String = concat(just_return(a));
//~^ explicit_deref_methods
let b: &str = &**a;
//~^ explicit_deref_methods
let b: &str = a.deref().deref();
let opt_a = Some(a.clone());
let b = &*opt_a.unwrap();
//~^ explicit_deref_methods
let b = opt_a.unwrap().deref();
Aaa::deref(&Aaa);
Aaa::deref_mut(&mut Aaa);

View file

@ -82,11 +82,9 @@ fn main() {
//~^ explicit_deref_methods
let b: &str = a.deref().deref();
//~^ explicit_deref_methods
let opt_a = Some(a.clone());
let b = opt_a.unwrap().deref();
//~^ explicit_deref_methods
Aaa::deref(&Aaa);
Aaa::deref_mut(&mut Aaa);

View file

@ -56,40 +56,28 @@ LL | let b: String = concat(just_return(a).deref());
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)`
error: explicit `deref` method call
--> tests/ui/explicit_deref_methods.rs:84:19
|
LL | let b: &str = a.deref().deref();
| ^^^^^^^^^^^^^^^^^ help: try: `&**a`
error: explicit `deref` method call
--> tests/ui/explicit_deref_methods.rs:88:13
|
LL | let b = opt_a.unwrap().deref();
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*opt_a.unwrap()`
error: explicit `deref` method call
--> tests/ui/explicit_deref_methods.rs:123:31
--> tests/ui/explicit_deref_methods.rs:121:31
|
LL | let b: &str = expr_deref!(a.deref());
| ^^^^^^^^^ help: try: `&*a`
error: explicit `deref` method call
--> tests/ui/explicit_deref_methods.rs:141:14
--> tests/ui/explicit_deref_methods.rs:139:14
|
LL | let _ = &Deref::deref(&"foo");
| ^^^^^^^^^^^^^^^^^^^^ help: try: `*&"foo"`
error: explicit `deref_mut` method call
--> tests/ui/explicit_deref_methods.rs:143:14
--> tests/ui/explicit_deref_methods.rs:141:14
|
LL | let _ = &DerefMut::deref_mut(&mut x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut **&mut x`
error: explicit `deref_mut` method call
--> tests/ui/explicit_deref_methods.rs:144:14
--> tests/ui/explicit_deref_methods.rs:142:14
|
LL | let _ = &DerefMut::deref_mut((&mut &mut x).deref_mut());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut ***(&mut &mut x)`
error: aborting due to 15 previous errors
error: aborting due to 13 previous errors