@@ -56,9 +56,11 @@ declare_clippy_lint! {
56
56
/// let b = &*a;
57
57
/// ```
58
58
///
59
- /// This lint excludes:
59
+ /// This lint excludes all of :
60
60
/// ```rust,ignore
61
61
/// let _ = d.unwrap().deref();
62
+ /// let _ = Foo::deref(&foo);
63
+ /// let _ = <Foo as Deref>::deref(&foo);
62
64
/// ```
63
65
#[ clippy:: version = "1.44.0" ]
64
66
pub EXPLICIT_DEREF_METHODS ,
@@ -155,7 +157,7 @@ impl_lint_pass!(Dereferencing<'_> => [
155
157
156
158
#[ derive( Default ) ]
157
159
pub struct Dereferencing < ' tcx > {
158
- state : Option < ( State < ' tcx > , StateData ) > ,
160
+ state : Option < ( State , StateData ) > ,
159
161
160
162
// While parsing a `deref` method call in ufcs form, the path to the function is itself an
161
163
// expression. This is to store the id of that expression so it can be skipped when
@@ -210,13 +212,12 @@ struct DerefedBorrow {
210
212
}
211
213
212
214
#[ derive( Debug ) ]
213
- enum State < ' tcx > {
215
+ enum State {
214
216
// Any number of deref method calls.
215
217
DerefMethod {
216
218
// The number of calls in a sequence which changed the referenced type
217
219
ty_changed_count : usize ,
218
220
is_final_ufcs : bool ,
219
- call_args : Option < & ' tcx [ Expr < ' tcx > ] > ,
220
221
/// The required mutability
221
222
target_mut : Mutability ,
222
223
} ,
@@ -313,16 +314,10 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
313
314
&& position. lint_explicit_deref ( ) =>
314
315
{
315
316
let ty_changed_count = usize:: from ( !deref_method_same_type ( expr_ty, typeck. expr_ty ( sub_expr) ) ) ;
316
- let ( is_final_ufcs, call_args) = if let ExprKind :: Call ( _, args) = expr. kind {
317
- ( true , Some ( args) )
318
- } else {
319
- ( false , None )
320
- } ;
321
317
self . state = Some ( (
322
318
State :: DerefMethod {
323
319
ty_changed_count,
324
- is_final_ufcs,
325
- call_args,
320
+ is_final_ufcs : matches ! ( expr. kind, ExprKind :: Call ( ..) ) ,
326
321
target_mut,
327
322
} ,
328
323
StateData {
@@ -445,7 +440,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
445
440
ty_changed_count + 1
446
441
} ,
447
442
is_final_ufcs : matches ! ( expr. kind, ExprKind :: Call ( ..) ) ,
448
- call_args : None ,
449
443
target_mut,
450
444
} ,
451
445
data,
@@ -1480,16 +1474,15 @@ fn ty_contains_field(ty: Ty<'_>, name: Symbol) -> bool {
1480
1474
}
1481
1475
1482
1476
#[ expect( clippy:: needless_pass_by_value, clippy:: too_many_lines) ]
1483
- fn report < ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > , state : State < ' _ > , data : StateData ) {
1477
+ fn report < ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > , state : State , data : StateData ) {
1484
1478
match state {
1485
1479
State :: DerefMethod {
1486
1480
ty_changed_count,
1487
1481
is_final_ufcs,
1488
- call_args,
1489
1482
target_mut,
1490
1483
} => {
1491
1484
let mut app = Applicability :: MachineApplicable ;
1492
- let ( expr_str, expr_is_macro_call ) = snippet_with_context ( cx, expr. span , data. span . ctxt ( ) , ".." , & mut app) ;
1485
+ let ( expr_str, _expr_is_macro_call ) = snippet_with_context ( cx, expr. span , data. span . ctxt ( ) , ".." , & mut app) ;
1493
1486
let ty = cx. typeck_results ( ) . expr_ty ( expr) ;
1494
1487
let ( _, ref_count) = peel_mid_ty_refs ( ty) ;
1495
1488
let deref_str = if ty_changed_count >= ref_count && ref_count != 0 {
@@ -1512,23 +1505,19 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State<'_>,
1512
1505
"&"
1513
1506
} ;
1514
1507
1515
- let mut expr_str = if !expr_is_macro_call && is_final_ufcs && expr. precedence ( ) . order ( ) < PREC_PREFIX {
1516
- format ! ( "({expr_str})" )
1508
+ // expr_str (the suggestion) is never shown if is_final_ufcs is true, since it's
1509
+ // `expr.kind == ExprKind::Call`. Therefore, this is, afaik, always unnecessary.
1510
+ /*
1511
+ expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence().order() < PREC_PREFIX {
1512
+ Cow::Owned(format!("({expr_str})"))
1517
1513
} else {
1518
- expr_str. into_owned ( )
1514
+ expr_str
1519
1515
};
1516
+ */
1520
1517
1521
- // Fix #10850, changes suggestion if it's `Foo::deref` instead of `foo.deref`. Since `Foo::deref` is
1522
- // a `Call` instead of a `MethodCall` this should catch all instances of this, even if it's fully
1523
- // qualified or whatnot.
1524
- if is_final_ufcs && let Some ( args) = call_args {
1525
- // Remove ref if it's there
1526
- let arg = if let ExprKind :: AddrOf ( .., arg) = args[ 0 ] . kind {
1527
- arg
1528
- } else {
1529
- & args[ 0 ]
1530
- } ;
1531
- expr_str = snippet_with_applicability ( cx, arg. span , "{ .. }" , & mut app) . to_string ( ) ;
1518
+ // Fix #10850, do not lint if it's `Foo::deref` instead of `foo.deref()`.
1519
+ if is_final_ufcs {
1520
+ return ;
1532
1521
}
1533
1522
1534
1523
span_lint_and_sugg (
0 commit comments