@@ -2570,11 +2570,16 @@ fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map
2570
2570
// lint if caller of `.map().flatten()` is an Iterator
2571
2571
if match_trait_method ( cx, expr, & paths:: ITERATOR ) {
2572
2572
let map_closure_ty = cx. typeck_results ( ) . expr_ty ( & map_args[ 1 ] ) ;
2573
- let is_map_to_option = if let ty:: Closure ( _def_id, substs) = map_closure_ty. kind {
2574
- let map_closure_return_ty = cx. tcx . erase_late_bound_regions ( & substs. as_closure ( ) . sig ( ) . output ( ) ) ;
2575
- is_type_diagnostic_item ( cx, map_closure_return_ty, sym ! ( option_type) )
2576
- } else {
2577
- false
2573
+ let is_map_to_option = match map_closure_ty. kind {
2574
+ ty:: Closure ( _, _) | ty:: FnDef ( _, _) | ty:: FnPtr ( _) => {
2575
+ let map_closure_sig = match map_closure_ty. kind {
2576
+ ty:: Closure ( _, substs) => substs. as_closure ( ) . sig ( ) ,
2577
+ _ => map_closure_ty. fn_sig ( cx. tcx ) ,
2578
+ } ;
2579
+ let map_closure_return_ty = cx. tcx . erase_late_bound_regions ( & map_closure_sig. output ( ) ) ;
2580
+ is_type_diagnostic_item ( cx, map_closure_return_ty, sym ! ( option_type) )
2581
+ } ,
2582
+ _ => false ,
2578
2583
} ;
2579
2584
2580
2585
let method_to_use = if is_map_to_option {
@@ -2584,19 +2589,13 @@ fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map
2584
2589
// `(...).map(...)` has type `impl Iterator<Item=impl Iterator<...>>
2585
2590
"flat_map"
2586
2591
} ;
2587
- let msg = & format ! (
2588
- "called `map(..).flatten()` on an `Iterator`. \
2589
- This is more succinctly expressed by calling `.{}(..)`",
2590
- method_to_use
2591
- ) ;
2592
- let self_snippet = snippet ( cx, map_args[ 0 ] . span , ".." ) ;
2593
2592
let func_snippet = snippet ( cx, map_args[ 1 ] . span , ".." ) ;
2594
- let hint = format ! ( "{0}. {1}({2})" , self_snippet , method_to_use, func_snippet) ;
2593
+ let hint = format ! ( ". {0}( {1})" , method_to_use, func_snippet) ;
2595
2594
span_lint_and_sugg (
2596
2595
cx,
2597
2596
MAP_FLATTEN ,
2598
- expr. span ,
2599
- msg ,
2597
+ expr. span . with_lo ( map_args [ 0 ] . span . hi ( ) ) ,
2598
+ "called `map(..).flatten()` on an `Iterator`" ,
2600
2599
& format ! ( "try using `{}` instead" , method_to_use) ,
2601
2600
hint,
2602
2601
Applicability :: MachineApplicable ,
@@ -2605,16 +2604,13 @@ fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map
2605
2604
2606
2605
// lint if caller of `.map().flatten()` is an Option
2607
2606
if is_type_diagnostic_item ( cx, cx. typeck_results ( ) . expr_ty ( & map_args[ 0 ] ) , sym ! ( option_type) ) {
2608
- let msg = "called `map(..).flatten()` on an `Option`. \
2609
- This is more succinctly expressed by calling `.and_then(..)`";
2610
- let self_snippet = snippet ( cx, map_args[ 0 ] . span , ".." ) ;
2611
2607
let func_snippet = snippet ( cx, map_args[ 1 ] . span , ".." ) ;
2612
- let hint = format ! ( "{0} .and_then({1 })" , self_snippet , func_snippet) ;
2608
+ let hint = format ! ( ".and_then({})" , func_snippet) ;
2613
2609
span_lint_and_sugg (
2614
2610
cx,
2615
2611
MAP_FLATTEN ,
2616
- expr. span ,
2617
- msg ,
2612
+ expr. span . with_lo ( map_args [ 0 ] . span . hi ( ) ) ,
2613
+ "called `map(..).flatten()` on an `Option`" ,
2618
2614
"try using `and_then` instead" ,
2619
2615
hint,
2620
2616
Applicability :: MachineApplicable ,
0 commit comments