3 use utils
::{match_type, method_chain_args, paths, snippet, span_help_and_lint}
;
5 /// **What it does:*** Checks for unnecessary `ok()` in if let.
7 /// **Why is this bad?** Calling `ok()` in if let is unnecessary, instead match
10 /// **Known problems:** None.
14 /// for result in iter {
15 /// if let Some(bench) = try!(result).parse().ok() {
23 /// for result in iter {
24 /// if let Ok(bench) = try!(result).parse() {
30 pub IF_LET_SOME_RESULT
,
32 "usage of `ok()` in `if let Some(pat)` statements is unnecessary, match on `Ok(pat)` instead"
35 #[derive(Copy, Clone)]
38 impl LintPass
for Pass
{
39 fn get_lints(&self) -> LintArray
{
40 lint_array
!(IF_LET_SOME_RESULT
)
44 impl<'a
, 'tcx
> LateLintPass
<'a
, 'tcx
> for Pass
{
45 fn check_expr(&mut self, cx
: &LateContext
<'a
, 'tcx
>, expr
: &'tcx Expr
) {
46 if_chain
! { //begin checking variables
47 if let ExprMatch(ref op
, ref body
, ref source
) = expr
.node
; //test if expr is a match
48 if let MatchSource
::IfLetDesugar { .. }
= *source
; //test if it is an If Let
49 if let ExprMethodCall(_
, _
, ref result_types
) = op
.node
; //check is expr.ok() has type Result<T,E>.ok()
50 if let PatKind
::TupleStruct(QPath
::Resolved(_
, ref x
), ref y
, _
) = body
[0].pats
[0].node
; //get operation
51 if method_chain_args(op
, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized;
54 let is_result_type
= match_type(cx
, cx
.tables
.expr_ty(&result_types
[0]), &paths
::RESULT
);
55 let some_expr_string
= snippet(cx
, y
[0].span
, "");
56 if print
::to_string(print
::NO_ANN
, |s
| s
.print_path(x
, false)) == "Some" && is_result_type
{
57 span_help_and_lint(cx
, IF_LET_SOME_RESULT
, expr
.span
,
58 "Matching on `Some` with `ok()` is redundant",
59 &format
!("Consider matching on `Ok({})` and removing the call to `ok` instead", some_expr_string
));