@@ -5,7 +5,7 @@ use clippy_utils::{get_parent_expr_for_hir, is_trait_method, strip_pat_refs};
55use if_chain:: if_chain;
66use rustc_errors:: Applicability ;
77use rustc_hir as hir;
8- use rustc_hir:: { self , Expr , ExprKind , HirId , PatKind } ;
8+ use rustc_hir:: { self , ExprKind , HirId , PatKind } ;
99use rustc_infer:: infer:: TyCtxtInferExt ;
1010use rustc_lint:: LateContext ;
1111use rustc_middle:: hir:: place:: ProjectionKind ;
@@ -229,26 +229,23 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
229229 } else {
230230 // cases where a parent call is using the item
231231 // i.e.: suggest `.contains(&x)` for `.find(|x| [1, 2, 3].contains(x)).is_none()`
232- let parent_expr = get_parent_expr_for_hir ( self . cx , cmt. hir_id ) ;
233- if let Some ( Expr { hir_id : _, kind, .. } ) = parent_expr {
234- if let ExprKind :: Call ( _, args) | ExprKind :: MethodCall ( _, _, args, _) = kind {
235- let args_to_handle = args. iter ( ) . filter ( |arg| arg. hir_id == cmt. hir_id ) . collect :: < Vec < _ > > ( ) ;
236- if !args_to_handle. is_empty ( ) {
237- for arg in & args_to_handle {
238- let arg_ty_kind = self . cx . typeck_results ( ) . expr_ty ( arg) . kind ( ) ;
239- if matches ! ( arg_ty_kind, ty:: Ref ( _, _, Mutability :: Not ) ) {
240- let start_span = Span :: new ( self . next_pos , span. lo ( ) , span. ctxt ( ) ) ;
241- let start_snip =
242- snippet_with_applicability ( self . cx , start_span, ".." , & mut self . applicability ) ;
232+ if let Some ( parent_expr) = get_parent_expr_for_hir ( self . cx , cmt. hir_id ) {
233+ if let ExprKind :: Call ( ..) | ExprKind :: MethodCall ( ..) = parent_expr. kind {
234+ let expr = self . cx . tcx . hir ( ) . expect_expr ( cmt. hir_id ) ;
235+ let arg_ty_kind = self . cx . typeck_results ( ) . expr_ty ( expr) . kind ( ) ;
243236
244- self . suggestion_start . push_str ( & format ! ( "{}&{}" , start_snip, ident_str) ) ;
245- self . next_pos = span. hi ( ) ;
246- } else {
247- self . applicability = Applicability :: Unspecified ;
248- }
249- }
250- return ;
237+ // Note: this should always be true, as `find` only gives us a reference which are not mutable
238+ if matches ! ( arg_ty_kind, ty:: Ref ( _, _, Mutability :: Not ) ) {
239+ let start_span = Span :: new ( self . next_pos , span. lo ( ) , span. ctxt ( ) ) ;
240+ let start_snip =
241+ snippet_with_applicability ( self . cx , start_span, ".." , & mut self . applicability ) ;
242+
243+ self . suggestion_start . push_str ( & format ! ( "{}&{}" , start_snip, ident_str) ) ;
244+ self . next_pos = span. hi ( ) ;
245+ } else {
246+ self . applicability = Applicability :: Unspecified ;
251247 }
248+ return ;
252249 }
253250 }
254251
@@ -290,17 +287,17 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
290287 } ,
291288 _ => false ,
292289 } ,
293- ProjectionKind :: Index => false , /* handled previously */
294- // note: unable to capture `Subslice` kind in tests
295- ProjectionKind :: Subslice => false ,
290+ // handled previously
291+ ProjectionKind :: Index |
292+ // note: unable to trigger `Subslice` kind in tests
293+ ProjectionKind :: Subslice => false ,
296294 ProjectionKind :: Deref => {
297295 // explicit deref for arrays should be avoided in the suggestion
298296 // i.e.: `|sub| *sub[1..4].len() == 3` is not expected
299297 match cmt. place . ty_before_projection ( i) . kind ( ) {
300298 // dereferencing an array (i.e.: `|sub| sub[1..4].len() == 3`)
301- ty:: Ref ( _, inner, _) => match inner. kind ( ) {
302- ty:: Ref ( _, innermost, _) if innermost. is_array ( ) => true ,
303- _ => false ,
299+ ty:: Ref ( _, inner, _) => {
300+ matches ! ( inner. kind( ) , ty:: Ref ( _, innermost, _) if innermost. is_array( ) )
304301 } ,
305302 _ => false ,
306303 }
0 commit comments