@@ -2,13 +2,13 @@ use super::FILTER_MAP_BOOL_THEN;
2
2
use clippy_utils:: diagnostics:: span_lint_and_sugg;
3
3
use clippy_utils:: paths:: BOOL_THEN ;
4
4
use clippy_utils:: source:: snippet_opt;
5
- use clippy_utils:: ty:: is_copy;
5
+ use clippy_utils:: ty:: { is_copy, peel_mid_ty_refs_is_mutable } ;
6
6
use clippy_utils:: { is_from_proc_macro, is_trait_method, match_def_path, peel_blocks} ;
7
7
use rustc_errors:: Applicability ;
8
8
use rustc_hir:: { Expr , ExprKind } ;
9
9
use rustc_lint:: { LateContext , LintContext } ;
10
10
use rustc_middle:: lint:: in_external_macro;
11
- use rustc_middle:: ty:: { self , Binder } ;
11
+ use rustc_middle:: ty:: Binder ;
12
12
use rustc_span:: { sym, Span } ;
13
13
14
14
pub ( super ) fn check < ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > , arg : & Expr < ' _ > , call_span : Span ) {
@@ -36,7 +36,11 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
36
36
&& let Some ( def_id) = cx. typeck_results ( ) . type_dependent_def_id ( value. hir_id )
37
37
&& match_def_path ( cx, def_id, & BOOL_THEN )
38
38
&& !is_from_proc_macro ( cx, expr)
39
- && let ref_bool = matches ! ( cx. typeck_results( ) . expr_ty( recv) . kind( ) , ty:: Ref ( ..) )
39
+ // Peel all refs (e.g. `&&&&mut &&&bool` -> `bool`) and get its count so we can suggest the exact
40
+ // amount of derefs to get to the bool in the filter.
41
+ // `peel_mid_ty_refs` alone doesn't handle mutable reference, so we use `_is_mutable`
42
+ // instead which counts them too and just ignore the resulting mutability
43
+ && let ( _, needed_derefs, _) = peel_mid_ty_refs_is_mutable ( cx. typeck_results ( ) . expr_ty ( recv) )
40
44
&& let Some ( param_snippet) = snippet_opt ( cx, param. span )
41
45
&& let Some ( filter) = snippet_opt ( cx, recv. span )
42
46
&& let Some ( map) = snippet_opt ( cx, then_body. span )
@@ -47,7 +51,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
47
51
call_span,
48
52
"usage of `bool::then` in `filter_map`" ,
49
53
"use `filter` then `map` instead" ,
50
- format ! ( "filter(|&{param_snippet}| {}{filter}).map(|{param_snippet}| {map})" , if ref_bool { "*" } else { "" } ) ,
54
+ format ! (
55
+ "filter(|&{param_snippet}| {derefs}{filter}).map(|{param_snippet}| {map})" ,
56
+ derefs="*" . repeat( needed_derefs)
57
+ ) ,
51
58
Applicability :: MachineApplicable ,
52
59
) ;
53
60
}
0 commit comments