@@ -17,6 +17,7 @@ use tracing::debug;
17
17
use triomphe:: Arc ;
18
18
use typed_arena:: Arena ;
19
19
20
+ use crate :: Interner ;
20
21
use crate :: {
21
22
db:: HirDatabase ,
22
23
diagnostics:: match_check:: {
@@ -149,17 +150,18 @@ impl ExprValidator {
149
150
None => return ,
150
151
} ;
151
152
152
- if filter_map_next_checker
153
- . get_or_insert_with ( || {
154
- FilterMapNextChecker :: new ( & self . owner . resolver ( db. upcast ( ) ) , db)
155
- } )
156
- . check ( call_id, receiver, & callee)
157
- . is_some ( )
158
- {
153
+ let checker = filter_map_next_checker. get_or_insert_with ( || {
154
+ FilterMapNextChecker :: new ( & self . owner . resolver ( db. upcast ( ) ) , db)
155
+ } ) ;
156
+
157
+ if checker. check ( call_id, receiver, & callee) . is_some ( ) {
159
158
self . diagnostics . push ( BodyValidationDiagnostic :: ReplaceFilterMapNextWithFindMap {
160
159
method_call_expr : call_id,
161
160
} ) ;
162
161
}
162
+
163
+ let receiver_ty = self . infer [ * receiver] . clone ( ) ;
164
+ checker. prev_receiver_ty = Some ( receiver_ty) ;
163
165
}
164
166
}
165
167
@@ -393,6 +395,7 @@ struct FilterMapNextChecker {
393
395
filter_map_function_id : Option < hir_def:: FunctionId > ,
394
396
next_function_id : Option < hir_def:: FunctionId > ,
395
397
prev_filter_map_expr_id : Option < ExprId > ,
398
+ prev_receiver_ty : Option < chalk_ir:: Ty < Interner > > ,
396
399
}
397
400
398
401
impl FilterMapNextChecker {
@@ -417,7 +420,12 @@ impl FilterMapNextChecker {
417
420
) ,
418
421
None => ( None , None ) ,
419
422
} ;
420
- Self { filter_map_function_id, next_function_id, prev_filter_map_expr_id : None }
423
+ Self {
424
+ filter_map_function_id,
425
+ next_function_id,
426
+ prev_filter_map_expr_id : None ,
427
+ prev_receiver_ty : None ,
428
+ }
421
429
}
422
430
423
431
// check for instances of .filter_map(..).next()
@@ -434,7 +442,11 @@ impl FilterMapNextChecker {
434
442
435
443
if * function_id == self . next_function_id ? {
436
444
if let Some ( prev_filter_map_expr_id) = self . prev_filter_map_expr_id {
437
- if * receiver_expr_id == prev_filter_map_expr_id {
445
+ let is_dyn_trait = self
446
+ . prev_receiver_ty
447
+ . as_ref ( )
448
+ . map_or ( false , |it| it. strip_references ( ) . dyn_trait ( ) . is_some ( ) ) ;
449
+ if * receiver_expr_id == prev_filter_map_expr_id && !is_dyn_trait {
438
450
return Some ( ( ) ) ;
439
451
}
440
452
}
0 commit comments