Skip to content

Commit 4cf720a

Browse files
committed
Move lint_map_unwrap_or to its own file
1 parent 54ab22f commit 4cf720a

File tree

2 files changed

+51
-44
lines changed

2 files changed

+51
-44
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use syntax::ast;
2222
use syntax::source_map::{BytePos, Span};
2323
use syntax::symbol::LocalInternedString;
2424

25+
mod option_map_unwrap_or;
2526
mod unnecessary_filter_map;
2627

2728
#[derive(Clone)]
@@ -836,7 +837,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
836837
["unwrap", "get_mut"] => lint_get_unwrap(cx, expr, arg_lists[1], true),
837838
["unwrap", ..] => lint_unwrap(cx, expr, arg_lists[0]),
838839
["expect", "ok"] => lint_ok_expect(cx, expr, arg_lists[1]),
839-
["unwrap_or", "map"] => lint_map_unwrap_or(cx, expr, arg_lists[1], arg_lists[0]),
840+
["unwrap_or", "map"] => option_map_unwrap_or::lint(cx, expr, arg_lists[1], arg_lists[0]),
840841
["unwrap_or_else", "map"] => lint_map_unwrap_or_else(cx, expr, arg_lists[1], arg_lists[0]),
841842
["map_or", ..] => lint_map_or_none(cx, expr, arg_lists[0]),
842843
["next", "filter"] => lint_filter_next(cx, expr, arg_lists[1]),
@@ -1769,49 +1770,6 @@ fn lint_ok_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr, ok_args: &[hir::Ex
17691770
}
17701771
}
17711772

1772-
/// lint use of `map().unwrap_or()` for `Option`s
1773-
fn lint_map_unwrap_or(cx: &LateContext<'_, '_>, expr: &hir::Expr, map_args: &[hir::Expr], unwrap_args: &[hir::Expr]) {
1774-
// lint if the caller of `map()` is an `Option`
1775-
let unwrap_ty = cx.tables.expr_ty(&unwrap_args[1]);
1776-
if match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION) && is_copy(cx, unwrap_ty) {
1777-
// get snippets for args to map() and unwrap_or()
1778-
let map_snippet = snippet(cx, map_args[1].span, "..");
1779-
let unwrap_snippet = snippet(cx, unwrap_args[1].span, "..");
1780-
// lint message
1781-
// comparing the snippet from source to raw text ("None") below is safe
1782-
// because we already have checked the type.
1783-
let arg = if unwrap_snippet == "None" { "None" } else { "a" };
1784-
let suggest = if unwrap_snippet == "None" {
1785-
"and_then(f)"
1786-
} else {
1787-
"map_or(a, f)"
1788-
};
1789-
let msg = &format!(
1790-
"called `map(f).unwrap_or({})` on an Option value. \
1791-
This can be done more directly by calling `{}` instead",
1792-
arg, suggest
1793-
);
1794-
// lint, with note if neither arg is > 1 line and both map() and
1795-
// unwrap_or() have the same span
1796-
let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1;
1797-
let same_span = map_args[1].span.ctxt() == unwrap_args[1].span.ctxt();
1798-
if same_span && !multiline {
1799-
let suggest = if unwrap_snippet == "None" {
1800-
format!("and_then({})", map_snippet)
1801-
} else {
1802-
format!("map_or({}, {})", unwrap_snippet, map_snippet)
1803-
};
1804-
let note = format!(
1805-
"replace `map({}).unwrap_or({})` with `{}`",
1806-
map_snippet, unwrap_snippet, suggest
1807-
);
1808-
span_note_and_lint(cx, OPTION_MAP_UNWRAP_OR, expr.span, msg, expr.span, &note);
1809-
} else if same_span && multiline {
1810-
span_lint(cx, OPTION_MAP_UNWRAP_OR, expr.span, msg);
1811-
};
1812-
}
1813-
}
1814-
18151773
/// lint use of `map().flatten()` for `Iterators`
18161774
fn lint_map_flatten<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, map_args: &'tcx [hir::Expr]) {
18171775
// lint if caller of `.map().flatten()` is an Iterator
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use crate::utils::paths;
2+
use crate::utils::{is_copy, match_type, snippet, span_lint, span_note_and_lint};
3+
use rustc::hir;
4+
use rustc::lint::LateContext;
5+
6+
use super::OPTION_MAP_UNWRAP_OR;
7+
8+
/// lint use of `map().unwrap_or()` for `Option`s
9+
pub(super) fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr, map_args: &[hir::Expr], unwrap_args: &[hir::Expr]) {
10+
// lint if the caller of `map()` is an `Option`
11+
let unwrap_ty = cx.tables.expr_ty(&unwrap_args[1]);
12+
if match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION) && is_copy(cx, unwrap_ty) {
13+
// get snippets for args to map() and unwrap_or()
14+
let map_snippet = snippet(cx, map_args[1].span, "..");
15+
let unwrap_snippet = snippet(cx, unwrap_args[1].span, "..");
16+
// lint message
17+
// comparing the snippet from source to raw text ("None") below is safe
18+
// because we already have checked the type.
19+
let arg = if unwrap_snippet == "None" { "None" } else { "a" };
20+
let suggest = if unwrap_snippet == "None" {
21+
"and_then(f)"
22+
} else {
23+
"map_or(a, f)"
24+
};
25+
let msg = &format!(
26+
"called `map(f).unwrap_or({})` on an Option value. \
27+
This can be done more directly by calling `{}` instead",
28+
arg, suggest
29+
);
30+
// lint, with note if neither arg is > 1 line and both map() and
31+
// unwrap_or() have the same span
32+
let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1;
33+
let same_span = map_args[1].span.ctxt() == unwrap_args[1].span.ctxt();
34+
if same_span && !multiline {
35+
let suggest = if unwrap_snippet == "None" {
36+
format!("and_then({})", map_snippet)
37+
} else {
38+
format!("map_or({}, {})", unwrap_snippet, map_snippet)
39+
};
40+
let note = format!(
41+
"replace `map({}).unwrap_or({})` with `{}`",
42+
map_snippet, unwrap_snippet, suggest
43+
);
44+
span_note_and_lint(cx, OPTION_MAP_UNWRAP_OR, expr.span, msg, expr.span, &note);
45+
} else if same_span && multiline {
46+
span_lint(cx, OPTION_MAP_UNWRAP_OR, expr.span, msg);
47+
};
48+
}
49+
}

0 commit comments

Comments
 (0)