@@ -2,13 +2,13 @@ use super::FILTER_MAP_BOOL_THEN;
22use clippy_utils:: diagnostics:: span_lint_and_sugg;
33use clippy_utils:: paths:: BOOL_THEN ;
44use 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 } ;
66use clippy_utils:: { is_from_proc_macro, is_trait_method, match_def_path, peel_blocks} ;
77use rustc_errors:: Applicability ;
88use rustc_hir:: { Expr , ExprKind } ;
99use rustc_lint:: { LateContext , LintContext } ;
1010use rustc_middle:: lint:: in_external_macro;
11- use rustc_middle:: ty:: { self , Binder } ;
11+ use rustc_middle:: ty:: Binder ;
1212use rustc_span:: { sym, Span } ;
1313
1414pub ( 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: &
3636 && let Some ( def_id) = cx. typeck_results ( ) . type_dependent_def_id ( value. hir_id )
3737 && match_def_path ( cx, def_id, & BOOL_THEN )
3838 && !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) )
4044 && let Some ( param_snippet) = snippet_opt ( cx, param. span )
4145 && let Some ( filter) = snippet_opt ( cx, recv. span )
4246 && 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: &
4751 call_span,
4852 "usage of `bool::then` in `filter_map`" ,
4953 "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+ ) ,
5158 Applicability :: MachineApplicable ,
5259 ) ;
5360 }
0 commit comments