@@ -1150,29 +1150,37 @@ fn lint_ok_expect(cx: &LateContext, expr: &hir::Expr, ok_args: &[hir::Expr]) {
1150
1150
fn lint_map_unwrap_or ( cx : & LateContext , expr : & hir:: Expr , map_args : & [ hir:: Expr ] , unwrap_args : & [ hir:: Expr ] ) {
1151
1151
// lint if the caller of `map()` is an `Option`
1152
1152
if match_type ( cx, cx. tables . expr_ty ( & map_args[ 0 ] ) , & paths:: OPTION ) {
1153
- // lint message
1154
- let msg = "called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling \
1155
- `map_or(a, f)` instead";
1156
1153
// get snippets for args to map() and unwrap_or()
1157
1154
let map_snippet = snippet ( cx, map_args[ 1 ] . span , ".." ) ;
1158
1155
let unwrap_snippet = snippet ( cx, unwrap_args[ 1 ] . span , ".." ) ;
1156
+ // lint message
1157
+ // comparing the snippet from source to raw text ("None") below is safe
1158
+ // because we already have checked the type.
1159
+ let arg = if unwrap_snippet == "None" { "None" } else { "a" } ;
1160
+ let suggest = if unwrap_snippet == "None" { "and_then(f)" } else { "map_or(a, f)" } ;
1161
+ let msg = & format ! (
1162
+ "called `map(f).unwrap_or({})` on an Option value. \
1163
+ This can be done more directly by calling `{}` instead",
1164
+ arg,
1165
+ suggest
1166
+ ) ;
1159
1167
// lint, with note if neither arg is > 1 line and both map() and
1160
1168
// unwrap_or() have the same span
1161
1169
let multiline = map_snippet. lines ( ) . count ( ) > 1 || unwrap_snippet. lines ( ) . count ( ) > 1 ;
1162
1170
let same_span = map_args[ 1 ] . span . ctxt ( ) == unwrap_args[ 1 ] . span . ctxt ( ) ;
1163
1171
if same_span && !multiline {
1164
- span_note_and_lint (
1165
- cx,
1166
- OPTION_MAP_UNWRAP_OR ,
1167
- expr. span ,
1168
- msg,
1169
- expr. span ,
1170
- & format ! (
1171
- "replace `map({0}).unwrap_or({1})` with `map_or({1}, {0})`" ,
1172
- map_snippet,
1173
- unwrap_snippet
1174
- ) ,
1172
+ let suggest = if unwrap_snippet == "None" {
1173
+ format ! ( "and_then({})" , map_snippet)
1174
+ } else {
1175
+ format ! ( "map_or({}, {})" , unwrap_snippet, map_snippet)
1176
+ } ;
1177
+ let note = format ! (
1178
+ "replace `map({}).unwrap_or({})` with `{}`" ,
1179
+ map_snippet,
1180
+ unwrap_snippet,
1181
+ suggest
1175
1182
) ;
1183
+ span_note_and_lint ( cx, OPTION_MAP_UNWRAP_OR , expr. span , msg, expr. span , & note) ;
1176
1184
} else if same_span && multiline {
1177
1185
span_lint ( cx, OPTION_MAP_UNWRAP_OR , expr. span , msg) ;
1178
1186
} ;
0 commit comments