about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-05-11 11:35:54 +0000
committerbors <bors@rust-lang.org>2019-05-11 11:35:54 +0000
commit3710ec59962295336ab4aed100267b584dd7df7d (patch)
treea618fe591066924cdc16ae2483a4b15b59a45bf0
parentc74aac9d0c8e35b17659198844ae71a58d685daf (diff)
parent19cfb84405d4891ae4baf5cc6b9cec3c9d29619d (diff)
downloadrust-3710ec59962295336ab4aed100267b584dd7df7d.tar.gz
rust-3710ec59962295336ab4aed100267b584dd7df7d.zip
Auto merge of #4080 - rust-lang:rustup, r=oli-obk
Rustup to rustc 1.36.0-nightly (acc7e652f 2019-05-10)

Fixes breakages from https://github.com/rust-lang/rust/pull/59288

Not finished yet, help appreciated.

Todo:

 - [x] Needs to build
 - [x] Util should handle DropTemps, https://github.com/rust-lang/rust-clippy/pull/4080#discussion_r283079202
 - [x] Author lint should spit out higher::if_block checks
 - [x] Unsure what to do in consts.rs
 - [x] Needs to pass tests
-rw-r--r--clippy_lints/src/block_in_if_condition.rs2
-rw-r--r--clippy_lints/src/consts.rs11
-rw-r--r--clippy_lints/src/copies.rs16
-rw-r--r--clippy_lints/src/entry.rs4
-rw-r--r--clippy_lints/src/implicit_return.rs7
-rw-r--r--clippy_lints/src/let_if_seq.rs4
-rw-r--r--clippy_lints/src/loops.rs10
-rw-r--r--clippy_lints/src/methods/mod.rs1
-rw-r--r--clippy_lints/src/methods/unnecessary_filter_map.rs6
-rw-r--r--clippy_lints/src/needless_bool.rs6
-rw-r--r--clippy_lints/src/question_mark.rs4
-rw-r--r--clippy_lints/src/shadow.rs7
-rw-r--r--clippy_lints/src/unwrap.rs4
-rw-r--r--clippy_lints/src/utils/author.rs51
-rw-r--r--clippy_lints/src/utils/higher.rs21
-rw-r--r--clippy_lints/src/utils/hir_utils.rs12
-rw-r--r--clippy_lints/src/utils/inspector.rs9
-rw-r--r--clippy_lints/src/utils/mod.rs11
-rw-r--r--clippy_lints/src/utils/sugg.rs1
-rw-r--r--tests/ui/author/if.rs10
-rw-r--r--tests/ui/author/if.stderr0
-rw-r--r--tests/ui/author/if.stdout27
-rw-r--r--tests/ui/into_iter_on_ref.fixed2
-rw-r--r--tests/ui/into_iter_on_ref.stderr14
24 files changed, 136 insertions, 104 deletions
diff --git a/clippy_lints/src/block_in_if_condition.rs b/clippy_lints/src/block_in_if_condition.rs
index 1f20f5c41fc..05d3ea6b274 100644
--- a/clippy_lints/src/block_in_if_condition.rs
+++ b/clippy_lints/src/block_in_if_condition.rs
@@ -72,7 +72,7 @@ const COMPLEX_BLOCK_MESSAGE: &str = "in an 'if' condition, avoid complex blocks
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlockInIfCondition {
     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
-        if let ExprKind::If(check, then, _) = &expr.node {
+        if let Some((check, then, _)) = higher::if_block(&expr) {
             if let ExprKind::Block(block, _) = &check.node {
                 if block.rules == DefaultBlock {
                     if block.stmts.is_empty() {
diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs
index 3cdd0f727fb..c96c7e7e857 100644
--- a/clippy_lints/src/consts.rs
+++ b/clippy_lints/src/consts.rs
@@ -1,6 +1,6 @@
 #![allow(clippy::float_cmp)]
 
-use crate::utils::{clip, sext, unsext};
+use crate::utils::{clip, higher, sext, unsext};
 use if_chain::if_chain;
 use rustc::hir::def::{DefKind, Res};
 use rustc::hir::*;
@@ -15,7 +15,6 @@ use std::convert::TryFrom;
 use std::convert::TryInto;
 use std::hash::{Hash, Hasher};
 use syntax::ast::{FloatTy, LitKind};
-use syntax::ptr::P;
 use syntax_pos::symbol::{LocalInternedString, Symbol};
 
 /// A `LitKind`-like enum to fold constant `Expr`s into.
@@ -222,10 +221,12 @@ pub struct ConstEvalLateContext<'a, 'tcx: 'a> {
 impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
     /// Simple constant folding: Insert an expression, get a constant or none.
     pub fn expr(&mut self, e: &Expr) -> Option<Constant> {
+        if let Some((ref cond, ref then, otherwise)) = higher::if_block(&e) {
+            return self.ifthenelse(cond, then, otherwise);
+        }
         match e.node {
             ExprKind::Path(ref qpath) => self.fetch_path(qpath, e.hir_id),
             ExprKind::Block(ref block, _) => self.block(block),
-            ExprKind::If(ref cond, ref then, ref otherwise) => self.ifthenelse(cond, then, otherwise),
             ExprKind::Lit(ref lit) => Some(lit_to_constant(&lit.node, self.tables.expr_ty(e))),
             ExprKind::Array(ref vec) => self.multi(vec).map(Constant::Vec),
             ExprKind::Tup(ref tup) => self.multi(tup).map(Constant::Tuple),
@@ -358,10 +359,10 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
         }
     }
 
-    fn ifthenelse(&mut self, cond: &Expr, then: &P<Expr>, otherwise: &Option<P<Expr>>) -> Option<Constant> {
+    fn ifthenelse(&mut self, cond: &Expr, then: &Expr, otherwise: Option<&Expr>) -> Option<Constant> {
         if let Some(Constant::Bool(b)) = self.expr(cond) {
             if b {
-                self.expr(&**then)
+                self.expr(&*then)
             } else {
                 otherwise.as_ref().and_then(|expr| self.expr(expr))
             }
diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs
index d1163e10279..c08d6851aa0 100644
--- a/clippy_lints/src/copies.rs
+++ b/clippy_lints/src/copies.rs
@@ -1,4 +1,4 @@
-use crate::utils::{get_parent_expr, in_macro, snippet, span_lint_and_then, span_note_and_lint};
+use crate::utils::{get_parent_expr, higher, in_macro, snippet, span_lint_and_then, span_note_and_lint};
 use crate::utils::{SpanlessEq, SpanlessHash};
 use rustc::hir::*;
 use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
@@ -109,13 +109,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyAndPaste {
     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
         if !in_macro(expr.span) {
             // skip ifs directly in else, it will be checked in the parent if
-            if let Some(&Expr {
-                node: ExprKind::If(_, _, Some(ref else_expr)),
-                ..
-            }) = get_parent_expr(cx, expr)
-            {
-                if else_expr.hir_id == expr.hir_id {
-                    return;
+            if let Some(expr) = get_parent_expr(cx, expr) {
+                if let Some((_, _, Some(ref else_expr))) = higher::if_block(&expr) {
+                    if else_expr.hir_id == expr.hir_id {
+                        return;
+                    }
                 }
             }
 
@@ -236,7 +234,7 @@ fn if_sequence(mut expr: &Expr) -> (SmallVec<[&Expr; 1]>, SmallVec<[&Block; 1]>)
     let mut conds = SmallVec::new();
     let mut blocks: SmallVec<[&Block; 1]> = SmallVec::new();
 
-    while let ExprKind::If(ref cond, ref then_expr, ref else_expr) = expr.node {
+    while let Some((ref cond, ref then_expr, ref else_expr)) = higher::if_block(&expr) {
         conds.push(&**cond);
         if let ExprKind::Block(ref block, _) = then_expr.node {
             blocks.push(block);
diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs
index c74232a906e..551e0bb848d 100644
--- a/clippy_lints/src/entry.rs
+++ b/clippy_lints/src/entry.rs
@@ -1,5 +1,5 @@
 use crate::utils::SpanlessEq;
-use crate::utils::{get_item_name, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty};
+use crate::utils::{get_item_name, higher, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty};
 use if_chain::if_chain;
 use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
 use rustc::hir::*;
@@ -41,7 +41,7 @@ declare_lint_pass!(HashMapPass => [MAP_ENTRY]);
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HashMapPass {
     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
-        if let ExprKind::If(ref check, ref then_block, ref else_block) = expr.node {
+        if let Some((ref check, ref then_block, ref else_block)) = higher::if_block(&expr) {
             if let ExprKind::Unary(UnOp::UnNot, ref check) = check.node {
                 if let Some((ty, map, key)) = check_cond(cx, check) {
                     // in case of `if !m.contains_key(&k) { m.insert(k, v); }`
diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs
index 559b0942d2b..8e0fa1bf2e2 100644
--- a/clippy_lints/src/implicit_return.rs
+++ b/clippy_lints/src/implicit_return.rs
@@ -74,13 +74,6 @@ impl ImplicitReturn {
                     Self::lint(cx, expr.span, break_expr.span, "change `break` to `return` as shown");
                 }
             },
-            ExprKind::If(.., if_expr, else_expr) => {
-                Self::expr_match(cx, if_expr);
-
-                if let Some(else_expr) = else_expr {
-                    Self::expr_match(cx, else_expr);
-                }
-            },
             ExprKind::Match(.., arms, source) => {
                 let check_all_arms = match source {
                     MatchSource::IfLetDesugar {
diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs
index 8a6456925a3..990d8facd13 100644
--- a/clippy_lints/src/let_if_seq.rs
+++ b/clippy_lints/src/let_if_seq.rs
@@ -1,4 +1,4 @@
-use crate::utils::{snippet, span_lint_and_then};
+use crate::utils::{higher, snippet, span_lint_and_then};
 use if_chain::if_chain;
 use rustc::hir;
 use rustc::hir::def::Res;
@@ -63,7 +63,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq {
                 if let hir::StmtKind::Local(ref local) = stmt.node;
                 if let hir::PatKind::Binding(mode, canonical_id, ident, None) = local.pat.node;
                 if let hir::StmtKind::Expr(ref if_) = expr.node;
-                if let hir::ExprKind::If(ref cond, ref then, ref else_) = if_.node;
+                if let Some((ref cond, ref then, ref else_)) = higher::if_block(&if_);
                 if !used_in_expr(cx, canonical_id, cond);
                 if let hir::ExprKind::Block(ref then, _) = then.node;
                 if let Some(value) = check_assign(cx, canonical_id, &*then);
diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index 362f3ebdf5c..c67edc00e6b 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -686,14 +686,6 @@ fn never_loop_expr(expr: &Expr, main_loop_id: HirId) -> NeverLoopResult {
         | ExprKind::Assign(ref e1, ref e2)
         | ExprKind::AssignOp(_, ref e1, ref e2)
         | ExprKind::Index(ref e1, ref e2) => never_loop_expr_all(&mut [&**e1, &**e2].iter().cloned(), main_loop_id),
-        ExprKind::If(ref e, ref e2, ref e3) => {
-            let e1 = never_loop_expr(e, main_loop_id);
-            let e2 = never_loop_expr(e2, main_loop_id);
-            let e3 = e3
-                .as_ref()
-                .map_or(NeverLoopResult::Otherwise, |e| never_loop_expr(e, main_loop_id));
-            combine_seq(e1, combine_branches(e2, e3))
-        },
         ExprKind::Loop(ref b, _, _) => {
             // Break can come from the inner loop so remove them.
             absorb_break(&never_loop_block(b, main_loop_id))
@@ -2204,7 +2196,7 @@ fn is_loop(expr: &Expr) -> bool {
 
 fn is_conditional(expr: &Expr) -> bool {
     match expr.node {
-        ExprKind::If(..) | ExprKind::Match(..) => true,
+        ExprKind::Match(..) => true,
         _ => false,
     }
 }
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 2e342ee165a..f8cde663d89 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -1266,7 +1266,6 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
             hir::ExprKind::Call(..)
             | hir::ExprKind::MethodCall(..)
             // These variants are debatable or require further examination
-            | hir::ExprKind::If(..)
             | hir::ExprKind::Match(..)
             | hir::ExprKind::Block{ .. } => true,
             _ => false,
diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs
index fde58b4ff7f..a28e6fa88bb 100644
--- a/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -89,12 +89,6 @@ fn check_expression<'a, 'tcx: 'a>(
                 (false, false)
             }
         },
-        // There must be an else_arm or there will be a type error
-        hir::ExprKind::If(_, ref if_arm, Some(ref else_arm)) => {
-            let if_check = check_expression(cx, arg_id, if_arm);
-            let else_check = check_expression(cx, arg_id, else_arm);
-            (if_check.0 | else_check.0, if_check.1 | else_check.1)
-        },
         hir::ExprKind::Match(_, ref arms, _) => {
             let mut found_mapping = false;
             let mut found_filtering = false;
diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs
index 94febdbd8a7..0404bc41570 100644
--- a/clippy_lints/src/needless_bool.rs
+++ b/clippy_lints/src/needless_bool.rs
@@ -3,7 +3,7 @@
 //! This lint is **warn** by default
 
 use crate::utils::sugg::Sugg;
-use crate::utils::{in_macro, span_lint, span_lint_and_sugg};
+use crate::utils::{higher, in_macro, span_lint, span_lint_and_sugg};
 use rustc::hir::*;
 use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
 use rustc::{declare_lint_pass, declare_tool_lint};
@@ -59,7 +59,7 @@ declare_lint_pass!(NeedlessBool => [NEEDLESS_BOOL]);
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool {
     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
         use self::Expression::*;
-        if let ExprKind::If(ref pred, ref then_block, Some(ref else_expr)) = e.node {
+        if let Some((ref pred, ref then_block, Some(ref else_expr))) = higher::if_block(&e) {
             let reduce = |ret, not| {
                 let mut applicability = Applicability::MachineApplicable;
                 let snip = Sugg::hir_with_applicability(cx, pred, "<predicate>", &mut applicability);
@@ -119,7 +119,7 @@ fn parent_node_is_if_expr<'a, 'b>(expr: &Expr, cx: &LateContext<'a, 'b>) -> bool
     let parent_node = cx.tcx.hir().get_by_hir_id(parent_id);
 
     if let rustc::hir::Node::Expr(e) = parent_node {
-        if let ExprKind::If(_, _, _) = e.node {
+        if higher::if_block(&e).is_some() {
             return true;
         }
     }
diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs
index 9377ff3e3a0..743c0c4224a 100644
--- a/clippy_lints/src/question_mark.rs
+++ b/clippy_lints/src/question_mark.rs
@@ -8,7 +8,7 @@ use syntax::ptr::P;
 
 use crate::utils::paths::*;
 use crate::utils::sugg::Sugg;
-use crate::utils::{match_type, span_lint_and_then, SpanlessEq};
+use crate::utils::{higher, match_type, span_lint_and_then, SpanlessEq};
 
 declare_clippy_lint! {
     /// **What it does:** Checks for expressions that could be replaced by the question mark operator.
@@ -48,7 +48,7 @@ impl QuestionMark {
     /// If it matches, it will suggest to use the question mark operator instead
     fn check_is_none_and_early_return_none(cx: &LateContext<'_, '_>, expr: &Expr) {
         if_chain! {
-            if let ExprKind::If(if_expr, body, else_) = &expr.node;
+            if let Some((if_expr, body, else_)) = higher::if_block(&expr);
             if let ExprKind::MethodCall(segment, _, args) = &if_expr.node;
             if segment.ident.name == "is_none";
             if Self::expression_returns_none(cx, body);
diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs
index 63d75be1da2..2d85189d111 100644
--- a/clippy_lints/src/shadow.rs
+++ b/clippy_lints/src/shadow.rs
@@ -319,13 +319,6 @@ fn check_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, bindings:
                 check_expr(cx, e, bindings)
             }
         },
-        ExprKind::If(ref cond, ref then, ref otherwise) => {
-            check_expr(cx, cond, bindings);
-            check_expr(cx, &**then, bindings);
-            if let Some(ref o) = *otherwise {
-                check_expr(cx, o, bindings);
-            }
-        },
         ExprKind::While(ref cond, ref block, _) => {
             check_expr(cx, cond, bindings);
             check_block(cx, block, bindings);
diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs
index 9f7cdf98648..348579f75d1 100644
--- a/clippy_lints/src/unwrap.rs
+++ b/clippy_lints/src/unwrap.rs
@@ -2,7 +2,7 @@ use if_chain::if_chain;
 use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
 use rustc::{declare_lint_pass, declare_tool_lint};
 
-use crate::utils::{in_macro, match_type, paths, span_lint_and_then, usage::is_potentially_mutated};
+use crate::utils::{higher::if_block, in_macro, match_type, paths, span_lint_and_then, usage::is_potentially_mutated};
 use rustc::hir::intravisit::*;
 use rustc::hir::*;
 use syntax::source_map::Span;
@@ -130,7 +130,7 @@ impl<'a, 'tcx: 'a> UnwrappableVariablesVisitor<'a, 'tcx> {
 
 impl<'a, 'tcx: 'a> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr) {
-        if let ExprKind::If(cond, then, els) = &expr.node {
+        if let Some((cond, then, els)) = if_block(&expr) {
             walk_expr(self, cond);
             self.visit_branch(cond, then, false);
             if let Some(els) = els {
diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs
index ec8079f1824..5b88494ae7b 100644
--- a/clippy_lints/src/utils/author.rs
+++ b/clippy_lints/src/utils/author.rs
@@ -1,7 +1,7 @@
 //! A group of attributes that can be attached to Rust code in order
 //! to generate a clippy lint detecting said code automatically.
 
-use crate::utils::get_attr;
+use crate::utils::{get_attr, higher};
 use rustc::hir;
 use rustc::hir::intravisit::{NestedVisitorMap, Visitor};
 use rustc::hir::{BindingAnnotation, Expr, ExprKind, Pat, PatKind, QPath, Stmt, StmtKind, TyKind};
@@ -187,6 +187,32 @@ struct PrintVisitor {
 impl<'tcx> Visitor<'tcx> for PrintVisitor {
     #[allow(clippy::too_many_lines)]
     fn visit_expr(&mut self, expr: &Expr) {
+        // handle if desugarings
+        // TODO add more desugarings here
+        if let Some((cond, then, opt_else)) = higher::if_block(&expr) {
+            let cond_pat = self.next("cond");
+            let then_pat = self.next("then");
+            if let Some(else_) = opt_else {
+                let else_pat = self.next("else_");
+                println!(
+                    "    if let Some((ref {}, ref {}, Some({}))) = higher::if_block(&{});",
+                    cond_pat, then_pat, else_pat, self.current
+                );
+                self.current = else_pat;
+                self.visit_expr(else_);
+            } else {
+                println!(
+                    "    if let Some((ref {}, ref {}, None)) = higher::if_block(&{});",
+                    cond_pat, then_pat, self.current
+                );
+            }
+            self.current = cond_pat;
+            self.visit_expr(cond);
+            self.current = then_pat;
+            self.visit_expr(then);
+            return;
+        }
+
         print!("    if let ExprKind::");
         let current = format!("{}.node", self.current);
         match expr.node {
@@ -296,25 +322,6 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
                 self.current = cast_pat;
                 self.visit_expr(expr);
             },
-            ExprKind::If(ref cond, ref then, ref opt_else) => {
-                let cond_pat = self.next("cond");
-                let then_pat = self.next("then");
-                if let Some(ref else_) = *opt_else {
-                    let else_pat = self.next("else_");
-                    println!(
-                        "If(ref {}, ref {}, Some(ref {})) = {};",
-                        cond_pat, then_pat, else_pat, current
-                    );
-                    self.current = else_pat;
-                    self.visit_expr(else_);
-                } else {
-                    println!("If(ref {}, ref {}, None) = {};", cond_pat, then_pat, current);
-                }
-                self.current = cond_pat;
-                self.visit_expr(cond);
-                self.current = then_pat;
-                self.visit_expr(then);
-            },
             ExprKind::While(ref cond, ref body, _) => {
                 let cond_pat = self.next("cond");
                 let body_pat = self.next("body");
@@ -684,6 +691,10 @@ fn desugaring_name(des: hir::MatchSource) -> String {
             "MatchSource::IfLetDesugar {{ contains_else_clause: {} }}",
             contains_else_clause
         ),
+        hir::MatchSource::IfDesugar { contains_else_clause } => format!(
+            "MatchSource::IfDesugar {{ contains_else_clause: {} }}",
+            contains_else_clause
+        ),
         hir::MatchSource::AwaitDesugar => "MatchSource::AwaitDesugar".to_string(),
     }
 }
diff --git a/clippy_lints/src/utils/higher.rs b/clippy_lints/src/utils/higher.rs
index 6bb45b2c73f..5c9f5e25f4d 100644
--- a/clippy_lints/src/utils/higher.rs
+++ b/clippy_lints/src/utils/higher.rs
@@ -199,6 +199,27 @@ pub fn for_loop(expr: &hir::Expr) -> Option<(&hir::Pat, &hir::Expr, &hir::Expr)>
     None
 }
 
+/// Recover the essential nodes of a desugared if block
+/// `if cond { then } else { els }` becomes `(cond, then, Some(els))`
+pub fn if_block(expr: &hir::Expr) -> Option<(&hir::Expr, &hir::Expr, Option<&hir::Expr>)> {
+    if let hir::ExprKind::Match(ref cond, ref arms, hir::MatchSource::IfDesugar { contains_else_clause }) = expr.node {
+        let cond = if let hir::ExprKind::DropTemps(ref cond) = cond.node {
+            cond
+        } else {
+            panic!("If block desugar must contain DropTemps");
+        };
+        let then = &arms[0].body;
+        let els = if contains_else_clause {
+            Some(&*arms[1].body)
+        } else {
+            None
+        };
+        Some((cond, then, els))
+    } else {
+        None
+    }
+}
+
 /// Represent the pre-expansion arguments of a `vec!` invocation.
 pub enum VecArgs<'a> {
     /// `vec![elem; len]`
diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs
index e1ddc69f25e..de129900467 100644
--- a/clippy_lints/src/utils/hir_utils.rs
+++ b/clippy_lints/src/utils/hir_utils.rs
@@ -114,9 +114,6 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
             (&ExprKind::Index(ref la, ref li), &ExprKind::Index(ref ra, ref ri)) => {
                 self.eq_expr(la, ra) && self.eq_expr(li, ri)
             },
-            (&ExprKind::If(ref lc, ref lt, ref le), &ExprKind::If(ref rc, ref rt, ref re)) => {
-                self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r))
-            },
             (&ExprKind::Lit(ref l), &ExprKind::Lit(ref r)) => l.node == r.node,
             (&ExprKind::Loop(ref lb, ref ll, ref lls), &ExprKind::Loop(ref rb, ref rl, ref rls)) => {
                 lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.as_str() == r.ident.as_str())
@@ -493,15 +490,6 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
                 let c: fn(_, _, _) -> _ = ExprKind::InlineAsm;
                 c.hash(&mut self.s);
             },
-            ExprKind::If(ref cond, ref t, ref e) => {
-                let c: fn(_, _, _) -> _ = ExprKind::If;
-                c.hash(&mut self.s);
-                self.hash_expr(cond);
-                self.hash_expr(&**t);
-                if let Some(ref e) = *e {
-                    self.hash_expr(e);
-                }
-            },
             ExprKind::Lit(ref l) => {
                 let c: fn(_) -> _ = ExprKind::Lit;
                 c.hash(&mut self.s);
diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs
index cde911940dc..633ebb3dd42 100644
--- a/clippy_lints/src/utils/inspector.rs
+++ b/clippy_lints/src/utils/inspector.rs
@@ -209,15 +209,6 @@ fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr, indent: usize) {
             print_expr(cx, e, indent + 1);
             println!("{}target type: {:?}", ind, target);
         },
-        hir::ExprKind::If(ref e, _, ref els) => {
-            println!("{}If", ind);
-            println!("{}condition:", ind);
-            print_expr(cx, e, indent + 1);
-            if let Some(ref els) = *els {
-                println!("{}else:", ind);
-                print_expr(cx, els, indent + 1);
-            }
-        },
         hir::ExprKind::While(ref cond, _, _) => {
             println!("{}While", ind);
             println!("{}condition:", ind);
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index 56837109877..7ebaeb0951f 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -40,6 +40,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_errors::Applicability;
 use syntax::ast::{self, LitKind};
 use syntax::attr;
+use syntax::ext::hygiene::ExpnFormat;
 use syntax::source_map::{Span, DUMMY_SP};
 use syntax::symbol::{keywords, Symbol};
 
@@ -90,7 +91,15 @@ pub fn in_constant(cx: &LateContext<'_, '_>, id: HirId) -> bool {
 
 /// Returns `true` if this `expn_info` was expanded by any macro.
 pub fn in_macro(span: Span) -> bool {
-    span.ctxt().outer().expn_info().is_some()
+    if let Some(info) = span.ctxt().outer().expn_info() {
+        if let ExpnFormat::CompilerDesugaring(..) = info.format {
+            false
+        } else {
+            true
+        }
+    } else {
+        false
+    }
 }
 
 // If the snippet is empty, it's an attribute that was inserted during macro
diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs
index be6e6069402..7d029d0f61e 100644
--- a/clippy_lints/src/utils/sugg.rs
+++ b/clippy_lints/src/utils/sugg.rs
@@ -94,7 +94,6 @@ impl<'a> Sugg<'a> {
             hir::ExprKind::AddrOf(..)
             | hir::ExprKind::Box(..)
             | hir::ExprKind::Closure(.., _)
-            | hir::ExprKind::If(..)
             | hir::ExprKind::Unary(..)
             | hir::ExprKind::Match(..) => Sugg::MaybeParen(snippet),
             hir::ExprKind::Continue(..)
diff --git a/tests/ui/author/if.rs b/tests/ui/author/if.rs
new file mode 100644
index 00000000000..2e9cb1466d0
--- /dev/null
+++ b/tests/ui/author/if.rs
@@ -0,0 +1,10 @@
+#[allow(clippy::all)]
+
+fn main() {
+    #[clippy::author]
+    let _ = if true {
+        1 == 1;
+    } else {
+        2 == 2;
+    };
+}
diff --git a/tests/ui/author/if.stderr b/tests/ui/author/if.stderr
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/tests/ui/author/if.stderr
diff --git a/tests/ui/author/if.stdout b/tests/ui/author/if.stdout
new file mode 100644
index 00000000000..bff6546a931
--- /dev/null
+++ b/tests/ui/author/if.stdout
@@ -0,0 +1,27 @@
+if_chain! {
+    if let StmtKind::Local(ref local) = stmt.node;
+    if let Some(ref init) = local.init;
+    if let Some((ref cond, ref then, Some(else_))) = higher::if_block(&init);
+    if let ExprKind::Block(ref block) = else_.node;
+    if let StmtKind::Semi(ref e, _) = block.node
+    if let ExprKind::Binary(ref op, ref left, ref right) = e.node;
+    if BinOpKind::Eq == op.node;
+    if let ExprKind::Lit(ref lit) = left.node;
+    if let LitKind::Int(2, _) = lit.node;
+    if let ExprKind::Lit(ref lit1) = right.node;
+    if let LitKind::Int(2, _) = lit1.node;
+    if let ExprKind::Lit(ref lit2) = cond.node;
+    if let LitKind::Bool(true) = lit2.node;
+    if let ExprKind::Block(ref block1) = then.node;
+    if let StmtKind::Semi(ref e1, _) = block1.node
+    if let ExprKind::Binary(ref op1, ref left1, ref right1) = e1.node;
+    if BinOpKind::Eq == op1.node;
+    if let ExprKind::Lit(ref lit3) = left1.node;
+    if let LitKind::Int(1, _) = lit3.node;
+    if let ExprKind::Lit(ref lit4) = right1.node;
+    if let LitKind::Int(1, _) = lit4.node;
+    if let PatKind::Wild = local.pat.node;
+    then {
+        // report your lint here
+    }
+}
diff --git a/tests/ui/into_iter_on_ref.fixed b/tests/ui/into_iter_on_ref.fixed
index 659fd56f9a9..f5342be631b 100644
--- a/tests/ui/into_iter_on_ref.fixed
+++ b/tests/ui/into_iter_on_ref.fixed
@@ -10,7 +10,7 @@ fn main() {
     for _ in &[1, 2, 3] {}
     for _ in vec![X, X] {}
     for _ in &vec![X, X] {}
-    for _ in [1, 2, 3].into_iter() {} //~ ERROR equivalent to .iter()
+    for _ in [1, 2, 3].iter() {} //~ ERROR equivalent to .iter()
 
     let _ = [1, 2, 3].iter(); //~ ERROR equivalent to .iter()
     let _ = vec![1, 2, 3].into_iter();
diff --git a/tests/ui/into_iter_on_ref.stderr b/tests/ui/into_iter_on_ref.stderr
index c3e5c85618b..931e4880f93 100644
--- a/tests/ui/into_iter_on_ref.stderr
+++ b/tests/ui/into_iter_on_ref.stderr
@@ -1,8 +1,8 @@
 error: this .into_iter() call is equivalent to .iter() and will not move the array
-  --> $DIR/into_iter_on_ref.rs:15:23
+  --> $DIR/into_iter_on_ref.rs:13:24
    |
-LL |     let _ = [1, 2, 3].into_iter(); //~ ERROR equivalent to .iter()
-   |                       ^^^^^^^^^ help: call directly: `iter`
+LL |     for _ in [1, 2, 3].into_iter() {} //~ ERROR equivalent to .iter()
+   |                        ^^^^^^^^^ help: call directly: `iter`
    |
 note: lint level defined here
   --> $DIR/into_iter_on_ref.rs:4:9
@@ -10,6 +10,12 @@ note: lint level defined here
 LL | #![deny(clippy::into_iter_on_array)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: this .into_iter() call is equivalent to .iter() and will not move the array
+  --> $DIR/into_iter_on_ref.rs:15:23
+   |
+LL |     let _ = [1, 2, 3].into_iter(); //~ ERROR equivalent to .iter()
+   |                       ^^^^^^^^^ help: call directly: `iter`
+
 error: this .into_iter() call is equivalent to .iter() and will not move the Vec
   --> $DIR/into_iter_on_ref.rs:17:30
    |
@@ -168,5 +174,5 @@ error: this .into_iter() call is equivalent to .iter() and will not move the Pat
 LL |     let _ = std::path::PathBuf::from("12/34").into_iter(); //~ ERROR equivalent to .iter()
    |                                               ^^^^^^^^^ help: call directly: `iter`
 
-error: aborting due to 27 previous errors
+error: aborting due to 28 previous errors