1- use crate :: utils:: paths;
2- use crate :: utils:: { is_copy, match_type, snippet, span_lint , span_note_and_lint } ;
1+ use crate :: utils:: { paths, span_lint_and_then } ;
2+ use crate :: utils:: { is_copy, match_type, snippet} ;
33use rustc:: hir:: intravisit:: { walk_path, NestedVisitorMap , Visitor } ;
44use rustc:: hir:: { self , * } ;
55use rustc:: lint:: LateContext ;
66use rustc_data_structures:: fx:: FxHashSet ;
77use syntax_pos:: symbol:: Symbol ;
8+ use syntax:: source_map:: Span ;
9+ use rustc_errors:: Applicability ;
810
911use super :: OPTION_MAP_UNWRAP_OR ;
1012
@@ -14,6 +16,7 @@ pub(super) fn lint<'a, 'tcx>(
1416 expr : & hir:: Expr ,
1517 map_args : & ' tcx [ hir:: Expr ] ,
1618 unwrap_args : & ' tcx [ hir:: Expr ] ,
19+ map_span : Span ,
1720) {
1821 // lint if the caller of `map()` is an `Option`
1922 if match_type ( cx, cx. tables . expr_ty ( & map_args[ 0 ] ) , & paths:: OPTION ) {
@@ -39,8 +42,8 @@ pub(super) fn lint<'a, 'tcx>(
3942 }
4043 }
4144
42- // get snippets for args to map() and unwrap_or()
43- let map_snippet = snippet ( cx , map_args [ 1 ] . span , ".." ) ;
45+ let map_arg_span = map_args [ 1 ] . span ;
46+ // get snippet for unwrap_or()
4447 let unwrap_snippet = snippet ( cx, unwrap_args[ 1 ] . span , ".." ) ;
4548 // lint message
4649 // comparing the snippet from source to raw text ("None") below is safe
@@ -56,24 +59,19 @@ pub(super) fn lint<'a, 'tcx>(
5659 This can be done more directly by calling `{}` instead",
5760 arg, suggest
5861 ) ;
59- // lint, with note if neither arg is > 1 line and both map() and
60- // unwrap_or() have the same span
61- let multiline = map_snippet. lines ( ) . count ( ) > 1 || unwrap_snippet. lines ( ) . count ( ) > 1 ;
62- let same_span = map_args[ 1 ] . span . ctxt ( ) == unwrap_args[ 1 ] . span . ctxt ( ) ;
63- if same_span && !multiline {
64- let suggest = if unwrap_snippet == "None" {
65- format ! ( "and_then({})" , map_snippet)
66- } else {
67- format ! ( "map_or({}, {})" , unwrap_snippet, map_snippet)
68- } ;
69- let note = format ! (
70- "replace `map({}).unwrap_or({})` with `{}`" ,
71- map_snippet, unwrap_snippet, suggest
72- ) ;
73- span_note_and_lint ( cx, OPTION_MAP_UNWRAP_OR , expr. span , msg, expr. span , & note) ;
74- } else if same_span && multiline {
75- span_lint ( cx, OPTION_MAP_UNWRAP_OR , expr. span , msg) ;
76- } ;
62+
63+ span_lint_and_then ( cx, OPTION_MAP_UNWRAP_OR , expr. span , msg, |db| {
64+ db. multipart_suggestion (
65+ "use this instead" ,
66+ vec ! [
67+ ( map_span, String :: from( "map_or" ) ) ,
68+ ( expr. span. with_lo( unwrap_args[ 0 ] . span. hi( ) ) , String :: from( "" ) ) ,
69+ ( map_arg_span. with_hi( map_arg_span. lo( ) ) , format!( "{}, " , unwrap_snippet) )
70+ ] ,
71+ Applicability :: MaybeIncorrect
72+ ) ;
73+ }
74+ ) ;
7775 }
7876}
7977
0 commit comments