]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/utils/higher.rs
Auto merge of #3680 - g-bartoszek:needless-bool-else-if-brackets, r=oli-obk
[rust.git] / clippy_lints / src / utils / higher.rs
index 3f0243a91c07a820495aa166e6aed96563473b69..537cdf55eb146d5fff6cd0933aaa8877bab3db8f 100644 (file)
@@ -1,12 +1,13 @@
 //! This module contains functions for retrieve the original AST from lowered
 //! `hir`.
 
-#![deny(missing_docs_in_private_items)]
+#![deny(clippy::missing_docs_in_private_items)]
 
-use rustc::{hir, ty};
+use crate::utils::{is_expn_of, match_def_path, match_qpath, opt_def_id, paths, resolve_node};
+use if_chain::if_chain;
 use rustc::lint::LateContext;
+use rustc::{hir, ty};
 use syntax::ast;
-use crate::utils::{is_expn_of, match_def_path, match_qpath, opt_def_id, paths, resolve_node};
 
 /// Convert a hir binary operator to the corresponding `ast` type.
 pub fn binop(op: hir::BinOpKind) -> ast::BinOpKind {
@@ -45,9 +46,16 @@ pub struct Range<'a> {
 
 /// Higher a `hir` range to something similar to `ast::ExprKind::Range`.
 pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> Option<Range<'b>> {
+    /// Find the field named `name` in the field. Always return `Some` for
+    /// convenience.
+    fn get_field<'a>(name: &str, fields: &'a [hir::Field]) -> Option<&'a hir::Expr> {
+        let expr = &fields.iter().find(|field| field.ident.name == name)?.expr;
+
+        Some(expr)
+    }
 
     let def_path = match cx.tables.expr_ty(expr).sty {
-        ty::TyAdt(def, _) => cx.tcx.def_path(def.did),
+        ty::Adt(def, _) => cx.tcx.def_path(def.did),
         _ => return None,
     };
 
@@ -74,14 +82,6 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> O
         return None;
     }
 
-    /// Find the field named `name` in the field. Always return `Some` for
-    /// convenience.
-    fn get_field<'a>(name: &str, fields: &'a [hir::Field]) -> Option<&'a hir::Expr> {
-        let expr = &fields.iter().find(|field| field.ident.name == name)?.expr;
-
-        Some(expr)
-    }
-
     // The range syntax is expanded to literal paths starting with `core` or `std`
     // depending on
     // `#[no_std]`. Testing both instead of resolving the paths.
@@ -98,64 +98,67 @@ fn get_field<'a>(name: &str, fields: &'a [hir::Field]) -> Option<&'a hir::Expr>
                 None
             }
         },
-        hir::ExprKind::Call(ref path, ref args) => if let hir::ExprKind::Path(ref path) = path.node {
-            if match_qpath(path, &paths::RANGE_INCLUSIVE_STD_NEW) || match_qpath(path, &paths::RANGE_INCLUSIVE_NEW) {
+        hir::ExprKind::Call(ref path, ref args) => {
+            if let hir::ExprKind::Path(ref path) = path.node {
+                if match_qpath(path, &paths::RANGE_INCLUSIVE_STD_NEW) || match_qpath(path, &paths::RANGE_INCLUSIVE_NEW)
+                {
+                    Some(Range {
+                        start: Some(&args[0]),
+                        end: Some(&args[1]),
+                        limits: ast::RangeLimits::Closed,
+                    })
+                } else {
+                    None
+                }
+            } else {
+                None
+            }
+        },
+        hir::ExprKind::Struct(ref path, ref fields, None) => {
+            if match_qpath(path, &paths::RANGE_FROM_STD) || match_qpath(path, &paths::RANGE_FROM) {
+                Some(Range {
+                    start: Some(get_field("start", fields)?),
+                    end: None,
+                    limits: ast::RangeLimits::HalfOpen,
+                })
+            } else if match_qpath(path, &paths::RANGE_STD) || match_qpath(path, &paths::RANGE) {
+                Some(Range {
+                    start: Some(get_field("start", fields)?),
+                    end: Some(get_field("end", fields)?),
+                    limits: ast::RangeLimits::HalfOpen,
+                })
+            } else if match_qpath(path, &paths::RANGE_TO_INCLUSIVE_STD) || match_qpath(path, &paths::RANGE_TO_INCLUSIVE)
+            {
                 Some(Range {
-                    start: Some(&args[0]),
-                    end: Some(&args[1]),
+                    start: None,
+                    end: Some(get_field("end", fields)?),
                     limits: ast::RangeLimits::Closed,
                 })
+            } else if match_qpath(path, &paths::RANGE_TO_STD) || match_qpath(path, &paths::RANGE_TO) {
+                Some(Range {
+                    start: None,
+                    end: Some(get_field("end", fields)?),
+                    limits: ast::RangeLimits::HalfOpen,
+                })
             } else {
                 None
             }
-        } else {
-            None
-        },
-        hir::ExprKind::Struct(ref path, ref fields, None) => if match_qpath(path, &paths::RANGE_FROM_STD)
-            || match_qpath(path, &paths::RANGE_FROM)
-        {
-            Some(Range {
-                start: Some(get_field("start", fields)?),
-                end: None,
-                limits: ast::RangeLimits::HalfOpen,
-            })
-        } else if match_qpath(path, &paths::RANGE_STD) || match_qpath(path, &paths::RANGE) {
-            Some(Range {
-                start: Some(get_field("start", fields)?),
-                end: Some(get_field("end", fields)?),
-                limits: ast::RangeLimits::HalfOpen,
-            })
-        } else if match_qpath(path, &paths::RANGE_TO_INCLUSIVE_STD) || match_qpath(path, &paths::RANGE_TO_INCLUSIVE) {
-            Some(Range {
-                start: None,
-                end: Some(get_field("end", fields)?),
-                limits: ast::RangeLimits::Closed,
-            })
-        } else if match_qpath(path, &paths::RANGE_TO_STD) || match_qpath(path, &paths::RANGE_TO) {
-            Some(Range {
-                start: None,
-                end: Some(get_field("end", fields)?),
-                limits: ast::RangeLimits::HalfOpen,
-            })
-        } else {
-            None
         },
         _ => None,
     }
 }
 
-/// Checks if a `let` decl is from a `for` loop desugaring.
-pub fn is_from_for_desugar(decl: &hir::Decl) -> bool {
+/// Checks if a `let` statement is from a `for` loop desugaring.
+pub fn is_from_for_desugar(local: &hir::Local) -> bool {
     // This will detect plain for-loops without an actual variable binding:
     //
     // ```
     // for x in some_vec {
-    //   // do stuff
+    //     // do stuff
     // }
     // ```
     if_chain! {
-        if let hir::DeclKind::Local(ref loc) = decl.node;
-        if let Some(ref expr) = loc.init;
+        if let Some(ref expr) = local.init;
         if let hir::ExprKind::Match(_, _, hir::MatchSource::ForLoopDesugar) = expr.node;
         then {
             return true;
@@ -167,15 +170,11 @@ pub fn is_from_for_desugar(decl: &hir::Decl) -> bool {
     //
     // ```
     // for _ in vec![()] {
-    //   // anything
+    //     // anything
     // }
     // ```
-    if_chain! {
-        if let hir::DeclKind::Local(ref loc) = decl.node;
-        if let hir::LocalSource::ForLoopDesugar = loc.source;
-        then {
-            return true;
-        }
+    if let hir::LocalSource::ForLoopDesugar = local.source {
+        return true;
     }
 
     false
@@ -191,11 +190,10 @@ pub fn for_loop(expr: &hir::Expr) -> Option<(&hir::Pat, &hir::Expr, &hir::Expr)>
         if let hir::ExprKind::Loop(ref block, _, _) = arms[0].body.node;
         if block.expr.is_none();
         if let [ _, _, ref let_stmt, ref body ] = *block.stmts;
-        if let hir::StmtKind::Decl(ref decl, _) = let_stmt.node;
-        if let hir::DeclKind::Local(ref decl) = decl.node;
-        if let hir::StmtKind::Expr(ref expr, _) = body.node;
+        if let hir::StmtKind::Local(ref local) = let_stmt.node;
+        if let hir::StmtKind::Expr(ref expr) = body.node;
         then {
-            return Some((&*decl.pat, &iterargs[0], expr));
+            return Some((&*local.pat, &iterargs[0], expr));
         }
     }
     None
@@ -211,7 +209,7 @@ pub enum VecArgs<'a> {
 
 /// Returns the arguments of the `vec!` macro if this expression was expanded
 /// from `vec!`.
-pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option<VecArgs<'e>> {
+pub fn vec_macro<'e>(cx: &LateContext<'_, '_>, expr: &'e hir::Expr) -> Option<VecArgs<'e>> {
     if_chain! {
         if let hir::ExprKind::Call(ref fun, ref args) = expr.node;
         if let hir::ExprKind::Path(ref path) = fun.node;