@@ -2570,11 +2570,16 @@ fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map
25702570 // lint if caller of `.map().flatten()` is an Iterator
25712571 if match_trait_method ( cx, expr, & paths:: ITERATOR ) {
25722572 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 ,
25782583 } ;
25792584
25802585 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
25842589 // `(...).map(...)` has type `impl Iterator<Item=impl Iterator<...>>
25852590 "flat_map"
25862591 } ;
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 , ".." ) ;
25932592 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) ;
25952594 span_lint_and_sugg (
25962595 cx,
25972596 MAP_FLATTEN ,
2598- expr. span ,
2599- msg ,
2597+ expr. span . with_lo ( map_args [ 0 ] . span . hi ( ) ) ,
2598+ "called `map(..).flatten()` on an `Iterator`" ,
26002599 & format ! ( "try using `{}` instead" , method_to_use) ,
26012600 hint,
26022601 Applicability :: MachineApplicable ,
@@ -2605,16 +2604,13 @@ fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map
26052604
26062605 // lint if caller of `.map().flatten()` is an Option
26072606 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 , ".." ) ;
26112607 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) ;
26132609 span_lint_and_sugg (
26142610 cx,
26152611 MAP_FLATTEN ,
2616- expr. span ,
2617- msg ,
2612+ expr. span . with_lo ( map_args [ 0 ] . span . hi ( ) ) ,
2613+ "called `map(..).flatten()` on an `Option`" ,
26182614 "try using `and_then` instead" ,
26192615 hint,
26202616 Applicability :: MachineApplicable ,
0 commit comments