mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-27 07:00:55 +00:00
Implement flat_map lint
This commit is contained in:
parent
1fd617d6df
commit
c7da4c26fb
4 changed files with 55 additions and 0 deletions
|
@ -947,6 +947,7 @@ Released 2018-09-13
|
|||
[`filter_map_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next
|
||||
[`filter_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_next
|
||||
[`find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#find_map
|
||||
[`flat_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#flat_map
|
||||
[`float_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_arithmetic
|
||||
[`float_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp
|
||||
[`float_cmp_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp_const
|
||||
|
|
|
@ -637,6 +637,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
methods::FILTER_MAP,
|
||||
methods::FILTER_MAP_NEXT,
|
||||
methods::FIND_MAP,
|
||||
methods::FLAT_MAP,
|
||||
methods::MAP_FLATTEN,
|
||||
methods::OPTION_MAP_UNWRAP_OR,
|
||||
methods::OPTION_MAP_UNWRAP_OR_ELSE,
|
||||
|
|
|
@ -312,6 +312,26 @@ declare_clippy_lint! {
|
|||
"using combination of `filter_map` and `next` which can usually be written as a single method call"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `flat_map(|x| x)`.
|
||||
///
|
||||
/// **Why is this bad?** Readability, this can be written more concisely by using `flatten`.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// iter.flat_map(|x| x)
|
||||
/// ```
|
||||
/// Can be written as
|
||||
/// ```rust
|
||||
/// iter.flatten()
|
||||
/// ```
|
||||
pub FLAT_MAP,
|
||||
pedantic,
|
||||
"call to `flat_map` where `flatten` is sufficient"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `_.find(_).map(_)`.
|
||||
///
|
||||
|
@ -844,6 +864,7 @@ declare_lint_pass!(Methods => [
|
|||
FILTER_NEXT,
|
||||
FILTER_MAP,
|
||||
FILTER_MAP_NEXT,
|
||||
FLAT_MAP,
|
||||
FIND_MAP,
|
||||
MAP_FLATTEN,
|
||||
ITER_NTH,
|
||||
|
@ -884,6 +905,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
|
|||
["map", "find"] => lint_find_map(cx, expr, arg_lists[1], arg_lists[0]),
|
||||
["flat_map", "filter"] => lint_filter_flat_map(cx, expr, arg_lists[1], arg_lists[0]),
|
||||
["flat_map", "filter_map"] => lint_filter_map_flat_map(cx, expr, arg_lists[1], arg_lists[0]),
|
||||
["flat_map", ..] => lint_flat_map(cx, expr, arg_lists[0]),
|
||||
["flatten", "map"] => lint_map_flatten(cx, expr, arg_lists[1]),
|
||||
["is_some", "find"] => lint_search_is_some(cx, expr, "find", arg_lists[1], arg_lists[0]),
|
||||
["is_some", "position"] => lint_search_is_some(cx, expr, "position", arg_lists[1], arg_lists[0]),
|
||||
|
@ -2092,6 +2114,30 @@ fn lint_filter_map_flat_map<'a, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// lint use of `flat_map` for `Iterators` where `flatten` would be sufficient
|
||||
fn lint_flat_map<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, flat_map_args: &'tcx [hir::Expr]) {
|
||||
if_chain! {
|
||||
if match_trait_method(cx, expr, &paths::ITERATOR);
|
||||
|
||||
if flat_map_args.len() == 2;
|
||||
if let hir::ExprKind::Closure(_, _, body_id, _, _) = flat_map_args[1].node;
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
|
||||
if body.arguments.len() == 1;
|
||||
if let hir::PatKind::Binding(_, _, binding_ident, _) = body.arguments[0].pat.node;
|
||||
if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = body.value.node;
|
||||
|
||||
if path.segments.len() == 1;
|
||||
if path.segments[0].ident.as_str() == binding_ident.as_str();
|
||||
|
||||
then {
|
||||
let msg = "called `flat_map(|x| x)` on an `Iterator`. \
|
||||
This can be simplified by calling `flatten().`";
|
||||
span_lint(cx, FLAT_MAP, expr.span, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// lint searching an Iterator followed by `is_some()`
|
||||
fn lint_search_is_some<'a, 'tcx>(
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
|
|
|
@ -553,6 +553,13 @@ pub const ALL_LINTS: [Lint; 306] = [
|
|||
deprecation: None,
|
||||
module: "methods",
|
||||
},
|
||||
Lint {
|
||||
name: "flat_map",
|
||||
group: "pedantic",
|
||||
desc: "call to `flat_map` where `flatten` is sufficient",
|
||||
deprecation: None,
|
||||
module: "methods",
|
||||
},
|
||||
Lint {
|
||||
name: "float_arithmetic",
|
||||
group: "restriction",
|
||||
|
|
Loading…
Reference in a new issue