]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/loops/for_loops_over_fallibles.rs
Merge remote-tracking branch 'upstream/master' into rustup
[rust.git] / clippy_lints / src / loops / for_loops_over_fallibles.rs
1 use super::FOR_LOOPS_OVER_FALLIBLES;
2 use clippy_utils::diagnostics::span_lint_and_help;
3 use clippy_utils::source::snippet;
4 use clippy_utils::ty::is_type_diagnostic_item;
5 use rustc_hir::{Expr, Pat};
6 use rustc_lint::LateContext;
7 use rustc_span::symbol::sym;
8
9 /// Checks for `for` loops over `Option`s and `Result`s.
10 pub(super) fn check(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) {
11     let ty = cx.typeck_results().expr_ty(arg);
12     if is_type_diagnostic_item(cx, ty, sym::option_type) {
13         span_lint_and_help(
14             cx,
15             FOR_LOOPS_OVER_FALLIBLES,
16             arg.span,
17             &format!(
18                 "for loop over `{0}`, which is an `Option`. This is more readably written as an \
19                 `if let` statement",
20                 snippet(cx, arg.span, "_")
21             ),
22             None,
23             &format!(
24                 "consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`",
25                 snippet(cx, pat.span, "_"),
26                 snippet(cx, arg.span, "_")
27             ),
28         );
29     } else if is_type_diagnostic_item(cx, ty, sym::result_type) {
30         span_lint_and_help(
31             cx,
32             FOR_LOOPS_OVER_FALLIBLES,
33             arg.span,
34             &format!(
35                 "for loop over `{0}`, which is a `Result`. This is more readably written as an \
36                 `if let` statement",
37                 snippet(cx, arg.span, "_")
38             ),
39             None,
40             &format!(
41                 "consider replacing `for {0} in {1}` with `if let Ok({0}) = {1}`",
42                 snippet(cx, pat.span, "_"),
43                 snippet(cx, arg.span, "_")
44             ),
45         );
46     }
47 }