diff --git a/clippy_lints/src/arithmetic.rs b/clippy_lints/src/arithmetic.rs
index 104c693350a..7c1042e5237 100644
--- a/clippy_lints/src/arithmetic.rs
+++ b/clippy_lints/src/arithmetic.rs
@@ -59,7 +59,7 @@ impl LateLintPass for Arithmetic {
                     hir::BiShr | hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => return,
                     _ => (),
                 }
-                let (l_ty, r_ty) = (cx.tcx.expr_ty(l), cx.tcx.expr_ty(r));
+                let (l_ty, r_ty) = (cx.tcx.tables().expr_ty(l), cx.tcx.tables().expr_ty(r));
                 if l_ty.is_integral() && r_ty.is_integral() {
                     span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
                     self.span = Some(expr.span);
@@ -69,7 +69,7 @@ impl LateLintPass for Arithmetic {
                 }
             }
             hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => {
-                let ty = cx.tcx.expr_ty(arg);
+                let ty = cx.tcx.tables().expr_ty(arg);
                 if ty.is_integral() {
                     span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
                     self.span = Some(expr.span);
diff --git a/clippy_lints/src/array_indexing.rs b/clippy_lints/src/array_indexing.rs
index 4d8f3de5e04..eb84f459e98 100644
--- a/clippy_lints/src/array_indexing.rs
+++ b/clippy_lints/src/array_indexing.rs
@@ -59,7 +59,7 @@ impl LateLintPass for ArrayIndexing {
     fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
         if let hir::ExprIndex(ref array, ref index) = e.node {
             // Array with known size can be checked statically
-            let ty = cx.tcx.expr_ty(array);
+            let ty = cx.tcx.tables().expr_ty(array);
             if let ty::TyArray(_, size) = ty.sty {
                 let size = ConstInt::Infer(size as u64);
 
diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs
index 36814808a2b..9e702fe3b4e 100644
--- a/clippy_lints/src/assign_ops.rs
+++ b/clippy_lints/src/assign_ops.rs
@@ -81,11 +81,11 @@ impl LateLintPass for AssignOps {
                 if let hir::ExprBinary(binop, ref l, ref r) = rhs.node {
                     if op.node == binop.node {
                         let lint = |assignee: &hir::Expr, rhs: &hir::Expr| {
-                            let ty = cx.tcx.expr_ty(assignee);
+                            let ty = cx.tcx.tables().expr_ty(assignee);
                             if ty.walk_shallow().next().is_some() {
                                 return; // implements_trait does not work with generics
                             }
-                            let rty = cx.tcx.expr_ty(rhs);
+                            let rty = cx.tcx.tables().expr_ty(rhs);
                             if rty.walk_shallow().next().is_some() {
                                 return; // implements_trait does not work with generics
                             }
@@ -116,11 +116,11 @@ impl LateLintPass for AssignOps {
             hir::ExprAssign(ref assignee, ref e) => {
                 if let hir::ExprBinary(op, ref l, ref r) = e.node {
                     let lint = |assignee: &hir::Expr, rhs: &hir::Expr| {
-                        let ty = cx.tcx.expr_ty(assignee);
+                        let ty = cx.tcx.tables().expr_ty(assignee);
                         if ty.walk_shallow().next().is_some() {
                             return; // implements_trait does not work with generics
                         }
-                        let rty = cx.tcx.expr_ty(rhs);
+                        let rty = cx.tcx.tables().expr_ty(rhs);
                         if rty.walk_shallow().next().is_some() {
                             return; // implements_trait does not work with generics
                         }
diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs
index fbbbf497d59..1af2273dc78 100644
--- a/clippy_lints/src/attrs.rs
+++ b/clippy_lints/src/attrs.rs
@@ -152,8 +152,8 @@ impl LateLintPass for AttrPass {
 }
 
 fn is_relevant_item(cx: &LateContext, item: &Item) -> bool {
-    if let ItemFn(_, _, _, _, _, ref block) = item.node {
-        is_relevant_block(cx, block)
+    if let ItemFn(_, _, _, _, _, ref expr) = item.node {
+        is_relevant_expr(cx, expr)
     } else {
         false
     }
@@ -161,7 +161,7 @@ fn is_relevant_item(cx: &LateContext, item: &Item) -> bool {
 
 fn is_relevant_impl(cx: &LateContext, item: &ImplItem) -> bool {
     match item.node {
-        ImplItemKind::Method(_, ref block) => is_relevant_block(cx, block),
+        ImplItemKind::Method(_, ref expr) => is_relevant_expr(cx, expr),
         _ => false,
     }
 }
@@ -169,7 +169,7 @@ fn is_relevant_impl(cx: &LateContext, item: &ImplItem) -> bool {
 fn is_relevant_trait(cx: &LateContext, item: &TraitItem) -> bool {
     match item.node {
         MethodTraitItem(_, None) => true,
-        MethodTraitItem(_, Some(ref block)) => is_relevant_block(cx, block),
+        MethodTraitItem(_, Some(ref expr)) => is_relevant_expr(cx, expr),
         _ => false,
     }
 }
diff --git a/clippy_lints/src/block_in_if_condition.rs b/clippy_lints/src/block_in_if_condition.rs
index 3f506e4f26d..2212ac21bab 100644
--- a/clippy_lints/src/block_in_if_condition.rs
+++ b/clippy_lints/src/block_in_if_condition.rs
@@ -55,17 +55,9 @@ struct ExVisitor<'v> {
 
 impl<'v> Visitor<'v> for ExVisitor<'v> {
     fn visit_expr(&mut self, expr: &'v Expr) {
-        if let ExprClosure(_, _, ref block, _) = expr.node {
+        if let ExprClosure(_, _, ref expr, _) = expr.node {
             let complex = {
-                if block.stmts.is_empty() {
-                    if let Some(ref ex) = block.expr {
-                        matches!(ex.node, ExprBlock(_))
-                    } else {
-                        false
-                    }
-                } else {
-                    true
-                }
+                matches!(expr.node, ExprBlock(_))
             };
             if complex {
                 self.found_block = Some(expr);
diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs
index b27984d9d2b..21ac913253b 100644
--- a/clippy_lints/src/booleans.rs
+++ b/clippy_lints/src/booleans.rs
@@ -392,7 +392,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for NonminimalBoolVisitor<'a, 'tcx> {
         match e.node {
             ExprBinary(binop, _, _) if binop.node == BiOr || binop.node == BiAnd => self.bool_expr(e),
             ExprUnary(UnNot, ref inner) => {
-                if self.0.tcx.node_types()[&inner.id].is_bool() {
+                if self.0.tcx.tables.borrow().node_types[&inner.id].is_bool() {
                     self.bool_expr(e);
                 } else {
                     walk_expr(self, e);
diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs
index 1245ec97051..4d403329979 100644
--- a/clippy_lints/src/copies.rs
+++ b/clippy_lints/src/copies.rs
@@ -120,8 +120,8 @@ impl LateLintPass for CopyAndPaste {
             }
 
             let (conds, blocks) = if_sequence(expr);
-            lint_same_then_else(cx, blocks.as_slice());
-            lint_same_cond(cx, conds.as_slice());
+            lint_same_then_else(cx, &blocks);
+            lint_same_cond(cx, &conds);
             lint_match_arms(cx, expr);
         }
     }
@@ -219,8 +219,8 @@ fn lint_match_arms(cx: &LateContext, expr: &Expr) {
 /// Eg. would return `([a, b], [c, d, e])` for the expression
 /// `if a { c } else if b { d } else { e }`.
 fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) {
-    let mut conds = SmallVector::zero();
-    let mut blocks = SmallVector::zero();
+    let mut conds = SmallVector::new();
+    let mut blocks = SmallVector::new();
 
     while let ExprIf(ref cond, ref then_block, ref else_expr) = expr.node {
         conds.push(&**cond);
@@ -256,7 +256,7 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap<Interned
             }
             PatKind::Binding(_, ref ident, ref as_pat) => {
                 if let Entry::Vacant(v) = map.entry(ident.node.as_str()) {
-                    v.insert(cx.tcx.pat_ty(pat));
+                    v.insert(cx.tcx.tables().pat_ty(pat));
                 }
                 if let Some(ref as_pat) = *as_pat {
                     bindings_impl(cx, as_pat, map);
diff --git a/clippy_lints/src/cyclomatic_complexity.rs b/clippy_lints/src/cyclomatic_complexity.rs
index faa56bccb22..f7758e3af23 100644
--- a/clippy_lints/src/cyclomatic_complexity.rs
+++ b/clippy_lints/src/cyclomatic_complexity.rs
@@ -42,12 +42,12 @@ impl LintPass for CyclomaticComplexity {
 }
 
 impl CyclomaticComplexity {
-    fn check<'a, 'tcx>(&mut self, cx: &'a LateContext<'a, 'tcx>, block: &Block, span: Span) {
+    fn check<'a, 'tcx>(&mut self, cx: &'a LateContext<'a, 'tcx>, expr: &Expr, span: Span) {
         if in_macro(cx, span) {
             return;
         }
 
-        let cfg = CFG::new(cx.tcx, block);
+        let cfg = CFG::new(cx.tcx, expr);
         let n = cfg.graph.len_nodes() as u64;
         let e = cfg.graph.len_edges() as u64;
         if e + 2 < n {
@@ -62,9 +62,9 @@ impl CyclomaticComplexity {
             returns: 0,
             tcx: &cx.tcx,
         };
-        helper.visit_block(block);
+        helper.visit_expr(expr);
         let CCHelper { match_arms, divergence, short_circuits, returns, .. } = helper;
-        let ret_ty = cx.tcx.node_id_to_type(block.id);
+        let ret_ty = cx.tcx.tables().node_id_to_type(expr.id);
         let ret_adjust = if match_type(cx, ret_ty, &paths::RESULT) {
             returns
         } else {
@@ -92,22 +92,22 @@ impl CyclomaticComplexity {
 
 impl LateLintPass for CyclomaticComplexity {
     fn check_item(&mut self, cx: &LateContext, item: &Item) {
-        if let ItemFn(_, _, _, _, _, ref block) = item.node {
+        if let ItemFn(_, _, _, _, _, ref expr) = item.node {
             if !attr::contains_name(&item.attrs, "test") {
-                self.check(cx, block, item.span);
+                self.check(cx, expr, item.span);
             }
         }
     }
 
     fn check_impl_item(&mut self, cx: &LateContext, item: &ImplItem) {
-        if let ImplItemKind::Method(_, ref block) = item.node {
-            self.check(cx, block, item.span);
+        if let ImplItemKind::Method(_, ref expr) = item.node {
+            self.check(cx, expr, item.span);
         }
     }
 
     fn check_trait_item(&mut self, cx: &LateContext, item: &TraitItem) {
-        if let MethodTraitItem(_, Some(ref block)) = item.node {
-            self.check(cx, block, item.span);
+        if let MethodTraitItem(_, Some(ref expr)) = item.node {
+            self.check(cx, expr, item.span);
         }
     }
 
@@ -139,7 +139,7 @@ impl<'a, 'b, 'tcx, 'gcx> Visitor<'a> for CCHelper<'b, 'gcx, 'tcx> {
             }
             ExprCall(ref callee, _) => {
                 walk_expr(self, e);
-                let ty = self.tcx.node_id_to_type(callee.id);
+                let ty = self.tcx.tables().node_id_to_type(callee.id);
                 match ty.sty {
                     ty::TyFnDef(_, _, ty) |
                     ty::TyFnPtr(ty) if ty.sig.skip_binder().output.sty == ty::TyNever => {
diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs
index d95c72c58f4..59687aa191b 100644
--- a/clippy_lints/src/derive.rs
+++ b/clippy_lints/src/derive.rs
@@ -73,7 +73,7 @@ impl LintPass for Derive {
 impl LateLintPass for Derive {
     fn check_item(&mut self, cx: &LateContext, item: &Item) {
         if let ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
-            let ty = cx.tcx.lookup_item_type(cx.tcx.map.local_def_id(item.id)).ty;
+            let ty = cx.tcx.item_type(cx.tcx.map.local_def_id(item.id));
             let is_automatically_derived = is_automatically_derived(&*item.attrs);
 
             check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
diff --git a/clippy_lints/src/drop_ref.rs b/clippy_lints/src/drop_ref.rs
index 88739bb6d78..4fb4009dd2f 100644
--- a/clippy_lints/src/drop_ref.rs
+++ b/clippy_lints/src/drop_ref.rs
@@ -52,7 +52,7 @@ impl LateLintPass for Pass {
 }
 
 fn check_drop_arg(cx: &LateContext, call_span: Span, arg: &Expr) {
-    let arg_ty = cx.tcx.expr_ty(arg);
+    let arg_ty = cx.tcx.tables().expr_ty(arg);
     if let ty::TyRef(..) = arg_ty.sty {
         span_note_and_lint(cx,
                            DROP_REF,
diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs
index 2a56ba1f22d..50bf299a3c3 100644
--- a/clippy_lints/src/entry.rs
+++ b/clippy_lints/src/entry.rs
@@ -86,7 +86,7 @@ fn check_cond<'a, 'tcx, 'b>(cx: &'a LateContext<'a, 'tcx>, check: &'b Expr) -> O
         let ExprAddrOf(_, ref key) = params[1].node
     ], {
         let map = &params[0];
-        let obj_ty = walk_ptrs_ty(cx.tcx.expr_ty(map));
+        let obj_ty = walk_ptrs_ty(cx.tcx.tables().expr_ty(map));
 
         return if match_type(cx, obj_ty, &paths::BTREEMAP) {
             Some(("BTreeMap", map, key))
diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs
index 30c7e067d28..703e37e77b0 100644
--- a/clippy_lints/src/escape.rs
+++ b/clippy_lints/src/escape.rs
@@ -5,7 +5,6 @@ use rustc::infer::InferCtxt;
 use rustc::lint::*;
 use rustc::middle::expr_use_visitor::*;
 use rustc::middle::mem_categorization::{cmt, Categorization};
-use rustc::ty::adjustment::AutoAdjustment;
 use rustc::ty;
 use rustc::ty::layout::TargetDataLayout;
 use rustc::util::nodemap::NodeSet;
@@ -62,7 +61,7 @@ impl LintPass for Pass {
 }
 
 impl LateLintPass for Pass {
-    fn check_fn(&mut self, cx: &LateContext, _: visit::FnKind, decl: &FnDecl, body: &Block, _: Span, id: NodeId) {
+    fn check_fn(&mut self, cx: &LateContext, _: visit::FnKind, decl: &FnDecl, body: &Expr, _: Span, id: NodeId) {
         let param_env = ty::ParameterEnvironment::for_item(cx.tcx, id);
 
         let infcx = cx.tcx.borrowck_fake_infer_ctxt(param_env);
@@ -146,17 +145,19 @@ impl<'a, 'tcx: 'a+'gcx, 'gcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx, 'g
     }
     fn borrow(&mut self, borrow_id: NodeId, _: Span, cmt: cmt<'tcx>, _: &ty::Region, _: ty::BorrowKind,
               loan_cause: LoanCause) {
+        use rustc::ty::adjustment::Adjust;
 
         if let Categorization::Local(lid) = cmt.cat {
             if self.set.contains(&lid) {
-                if let Some(&AutoAdjustment::AdjustDerefRef(adj)) = self.tcx
+                if let Some(&Adjust::DerefRef { autoderefs, .. }) = self.tcx
                                                                         .tables
                                                                         .borrow()
                                                                         .adjustments
-                                                                        .get(&borrow_id) {
+                                                                        .get(&borrow_id)
+                                                                        .map(|a| &a.kind) {
                     if LoanCause::AutoRef == loan_cause {
                         // x.foo()
-                        if adj.autoderefs == 0 {
+                        if autoderefs == 0 {
                             self.set.remove(&lid); // Used without autodereffing (i.e. x.clone())
                         }
                     } else {
@@ -164,14 +165,15 @@ impl<'a, 'tcx: 'a+'gcx, 'gcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx, 'g
                     }
                 } else if LoanCause::AddrOf == loan_cause {
                     // &x
-                    if let Some(&AutoAdjustment::AdjustDerefRef(adj)) = self.tcx
+                    if let Some(&Adjust::DerefRef { autoderefs, .. }) = self.tcx
                                                                             .tables
                                                                             .borrow()
                                                                             .adjustments
                                                                             .get(&self.tcx
-                                                                                      .map
-                                                                                      .get_parent_node(borrow_id)) {
-                        if adj.autoderefs <= 1 {
+                                                                            .map
+                                                                            .get_parent_node(borrow_id))
+                                                                            .map(|a| &a.kind) {
+                        if autoderefs <= 1 {
                             // foo(&x) where no extra autoreffing is happening
                             self.set.remove(&lid);
                         }
diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs
index ad7da71eab0..ee0767f57df 100644
--- a/clippy_lints/src/eta_reduction.rs
+++ b/clippy_lints/src/eta_reduction.rs
@@ -48,60 +48,53 @@ impl LateLintPass for EtaPass {
 }
 
 fn check_closure(cx: &LateContext, expr: &Expr) {
-    if let ExprClosure(_, ref decl, ref blk, _) = expr.node {
-        if !blk.stmts.is_empty() {
-            // || {foo(); bar()}; can't be reduced here
-            return;
-        }
-
-        if let Some(ref ex) = blk.expr {
-            if let ExprCall(ref caller, ref args) = ex.node {
-                if args.len() != decl.inputs.len() {
-                    // Not the same number of arguments, there
-                    // is no way the closure is the same as the function
-                    return;
+    if let ExprClosure(_, ref decl, ref ex, _) = expr.node {
+        if let ExprCall(ref caller, ref args) = ex.node {
+            if args.len() != decl.inputs.len() {
+                // Not the same number of arguments, there
+                // is no way the closure is the same as the function
+                return;
+            }
+            if is_adjusted(cx, ex) || args.iter().any(|arg| is_adjusted(cx, arg)) {
+                // Are the expression or the arguments type-adjusted? Then we need the closure
+                return;
+            }
+            let fn_ty = cx.tcx.tables().expr_ty(caller);
+            match fn_ty.sty {
+                // Is it an unsafe function? They don't implement the closure traits
+                ty::TyFnDef(_, _, fn_ty) |
+                ty::TyFnPtr(fn_ty) => {
+                    if fn_ty.unsafety == Unsafety::Unsafe ||
+                       fn_ty.sig.skip_binder().output.sty == ty::TyNever {
+                        return;
+                    }
                 }
-                if is_adjusted(cx, ex) || args.iter().any(|arg| is_adjusted(cx, arg)) {
-                    // Are the expression or the arguments type-adjusted? Then we need the closure
-                    return;
-                }
-                let fn_ty = cx.tcx.expr_ty(caller);
-                match fn_ty.sty {
-                    // Is it an unsafe function? They don't implement the closure traits
-                    ty::TyFnDef(_, _, fn_ty) |
-                    ty::TyFnPtr(fn_ty) => {
-                        if fn_ty.unsafety == Unsafety::Unsafe ||
-                           fn_ty.sig.skip_binder().output.sty == ty::TyNever {
+                _ => (),
+            }
+            for (a1, a2) in decl.inputs.iter().zip(args) {
+                if let PatKind::Binding(_, ident, _) = a1.pat.node {
+                    // XXXManishearth Should I be checking the binding mode here?
+                    if let ExprPath(None, ref p) = a2.node {
+                        if p.segments.len() != 1 {
+                            // If it's a proper path, it can't be a local variable
                             return;
                         }
-                    }
-                    _ => (),
-                }
-                for (a1, a2) in decl.inputs.iter().zip(args) {
-                    if let PatKind::Binding(_, ident, _) = a1.pat.node {
-                        // XXXManishearth Should I be checking the binding mode here?
-                        if let ExprPath(None, ref p) = a2.node {
-                            if p.segments.len() != 1 {
-                                // If it's a proper path, it can't be a local variable
-                                return;
-                            }
-                            if p.segments[0].name != ident.node {
-                                // The two idents should be the same
-                                return;
-                            }
-                        } else {
+                        if p.segments[0].name != ident.node {
+                            // The two idents should be the same
                             return;
                         }
                     } else {
                         return;
                     }
+                } else {
+                    return;
                 }
-                span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found", |db| {
-                    if let Some(snippet) = snippet_opt(cx, caller.span) {
-                        db.span_suggestion(expr.span, "remove closure as shown:", snippet);
-                    }
-                });
             }
+            span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found", |db| {
+                if let Some(snippet) = snippet_opt(cx, caller.span) {
+                    db.span_suggestion(expr.span, "remove closure as shown:", snippet);
+                }
+            });
         }
     }
 }
diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs
index 451ad50f310..be5e67391ab 100644
--- a/clippy_lints/src/eval_order_dependence.rs
+++ b/clippy_lints/src/eval_order_dependence.rs
@@ -126,7 +126,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DivergenceVisitor<'a, 'tcx> {
             ExprAgain(_) |
             ExprBreak(_) |
             ExprRet(_) => self.report_diverging_sub_expr(e),
-            ExprCall(ref func, _) => match self.0.tcx.expr_ty(func).sty {
+            ExprCall(ref func, _) => match self.0.tcx.tables().expr_ty(func).sty {
                 ty::TyFnDef(_, _, fn_ty) |
                 ty::TyFnPtr(fn_ty) => if let ty::TyNever = self.0.tcx.erase_late_bound_regions(&fn_ty.sig).output.sty {
                     self.report_diverging_sub_expr(e);
diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs
index 7b178281415..2013b406f2b 100644
--- a/clippy_lints/src/format.rs
+++ b/clippy_lints/src/format.rs
@@ -132,7 +132,7 @@ fn check_arg_is_display(cx: &LateContext, expr: &Expr) -> bool {
         let Some(fun) = resolve_node(cx, args[1].id),
         match_def_path(cx, fun.def_id(), &paths::DISPLAY_FMT_METHOD),
     ], {
-        let ty = walk_ptrs_ty(cx.tcx.pat_ty(&pat[0]));
+        let ty = walk_ptrs_ty(cx.tcx.tables().pat_ty(&pat[0]));
 
         return ty.sty == TypeVariants::TyStr || match_type(cx, ty, &paths::STRING);
     }}
diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs
index eadbd01e4ea..c6f17b615b6 100644
--- a/clippy_lints/src/functions.rs
+++ b/clippy_lints/src/functions.rs
@@ -69,7 +69,7 @@ impl LintPass for Functions {
 }
 
 impl LateLintPass for Functions {
-    fn check_fn(&mut self, cx: &LateContext, kind: intravisit::FnKind, decl: &hir::FnDecl, block: &hir::Block, span: Span, nodeid: ast::NodeId) {
+    fn check_fn(&mut self, cx: &LateContext, kind: intravisit::FnKind, decl: &hir::FnDecl, expr: &hir::Expr, span: Span, nodeid: ast::NodeId) {
         use rustc::hir::map::Node::*;
 
         let is_impl = if let Some(NodeItem(item)) = cx.tcx.map.find(cx.tcx.map.get_parent_node(nodeid)) {
@@ -94,18 +94,18 @@ impl LateLintPass for Functions {
             }
         }
 
-        self.check_raw_ptr(cx, unsafety, decl, block, nodeid);
+        self.check_raw_ptr(cx, unsafety, decl, expr, nodeid);
     }
 
     fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
-        if let hir::MethodTraitItem(ref sig, ref block) = item.node {
+        if let hir::MethodTraitItem(ref sig, ref expr) = item.node {
             // don't lint extern functions decls, it's not their fault
             if sig.abi == Abi::Rust {
                 self.check_arg_number(cx, &sig.decl, item.span);
             }
 
-            if let Some(ref block) = *block {
-                self.check_raw_ptr(cx, sig.unsafety, &sig.decl, block, item.id);
+            if let Some(ref expr) = *expr {
+                self.check_raw_ptr(cx, sig.unsafety, &sig.decl, expr, item.id);
             }
         }
     }
@@ -122,7 +122,7 @@ impl Functions {
         }
     }
 
-    fn check_raw_ptr(&self, cx: &LateContext, unsafety: hir::Unsafety, decl: &hir::FnDecl, block: &hir::Block, nodeid: ast::NodeId) {
+    fn check_raw_ptr(&self, cx: &LateContext, unsafety: hir::Unsafety, decl: &hir::FnDecl, expr: &hir::Expr, nodeid: ast::NodeId) {
         if unsafety == hir::Unsafety::Normal && cx.access_levels.is_exported(nodeid) {
             let raw_ptrs = decl.inputs.iter().filter_map(|arg| raw_ptr_arg(cx, arg)).collect::<HashSet<_>>();
 
@@ -132,7 +132,7 @@ impl Functions {
                     ptrs: raw_ptrs,
                 };
 
-                hir::intravisit::walk_block(&mut v, block);
+                hir::intravisit::walk_expr(&mut v, expr);
             }
         }
     }
@@ -155,7 +155,7 @@ impl<'a, 'tcx, 'v> hir::intravisit::Visitor<'v> for DerefVisitor<'a, 'tcx> {
     fn visit_expr(&mut self, expr: &'v hir::Expr) {
         match expr.node {
             hir::ExprCall(ref f, ref args) => {
-                let ty = self.cx.tcx.expr_ty(f);
+                let ty = self.cx.tcx.tables().expr_ty(f);
 
                 if type_is_unsafe_function(ty) {
                     for arg in args {
diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index 7ca24208fdf..269936776f7 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/clippy_lints/src/len_zero.rs
@@ -1,6 +1,6 @@
 use rustc::lint::*;
 use rustc::hir::def_id::DefId;
-use rustc::ty::{self, ImplOrTraitItem};
+use rustc::ty;
 use rustc::hir::*;
 use syntax::ast::{Lit, LitKind, Name};
 use syntax::codemap::{Span, Spanned};
@@ -133,7 +133,8 @@ fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItem]) {
 
     if let Some(i) = impl_items.iter().find(|i| is_named_self(i, "len")) {
         if cx.access_levels.is_exported(i.id) {
-            let ty = cx.tcx.node_id_to_type(item.id);
+            let def_id = cx.tcx.map.local_def_id(item.id);
+            let ty = cx.tcx.item_type(def_id);
 
             span_lint(cx,
                       LEN_WITHOUT_IS_EMPTY,
@@ -183,10 +184,15 @@ fn check_len_zero(cx: &LateContext, span: Span, name: &Name, args: &[P<Expr>], l
 
 /// Check if this type has an `is_empty` method.
 fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool {
-    /// Get an `ImplOrTraitItem` and return true if it matches `is_empty(self)`.
-    fn is_is_empty(item: &ImplOrTraitItem) -> bool {
-        if let ty::MethodTraitItem(ref method) = *item {
-            method.name.as_str() == "is_empty" && method.fty.sig.skip_binder().inputs.len() == 1
+    /// Get an `AssociatedItem` and return true if it matches `is_empty(self)`.
+    fn is_is_empty(cx: &LateContext, item: &ty::AssociatedItem) -> bool {
+        if let ty::AssociatedKind::Method = item.kind {
+            if item.name.as_str() == "is_empty" {
+                let ty = cx.tcx.item_type(item.def_id).fn_sig().skip_binder();
+                ty.inputs.len() == 1
+            } else {
+                false
+            }
         } else {
             false
         }
@@ -195,19 +201,18 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool {
     /// Check the inherent impl's items for an `is_empty(self)` method.
     fn has_is_empty_impl(cx: &LateContext, id: DefId) -> bool {
         cx.tcx.inherent_impls.borrow().get(&id).map_or(false, |impls| impls.iter().any(|imp| {
-            cx.tcx.impl_or_trait_items(*imp).iter().any(|item| {
-                is_is_empty(&cx.tcx.impl_or_trait_item(*item))
+            cx.tcx.associated_items(*imp).any(|item| {
+                is_is_empty(cx, &item)
             })
         }))
     }
 
-    let ty = &walk_ptrs_ty(cx.tcx.expr_ty(expr));
+    let ty = &walk_ptrs_ty(cx.tcx.tables().expr_ty(expr));
     match ty.sty {
         ty::TyTrait(_) => {
             cx.tcx
-              .impl_or_trait_items(ty.ty_to_def_id().expect("trait impl not found"))
-              .iter()
-              .any(|item| is_is_empty(&cx.tcx.impl_or_trait_item(*item)))
+              .associated_items(ty.ty_to_def_id().expect("trait impl not found"))
+              .any(|item| is_is_empty(cx, &item))
         }
         ty::TyProjection(_) => ty.ty_to_def_id().map_or(false, |id| has_is_empty_impl(cx, id)),
         ty::TyAdt(id, _) => has_is_empty_impl(cx, id.did),
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 8d5edb03682..07ec1f3f244 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -3,7 +3,6 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(custom_attribute)]
-#![feature(dotdot_in_tuple_patterns)]
 #![feature(rustc_private)]
 #![feature(slice_patterns)]
 #![feature(stmt_expr_attributes)]
diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs
index c0455fa3c67..8f1ef44bf1c 100644
--- a/clippy_lints/src/lifetimes.rs
+++ b/clippy_lints/src/lifetimes.rs
@@ -247,8 +247,8 @@ impl<'v, 't> RefVisitor<'v, 't> {
                     match def {
                         Def::TyAlias(def_id) |
                         Def::Struct(def_id) => {
-                            let type_scheme = self.cx.tcx.lookup_item_type(def_id);
-                            for _ in type_scheme.generics.regions.as_slice() {
+                            let generics = self.cx.tcx.item_generics(def_id);
+                            for _ in generics.regions.as_slice() {
                                 self.record(&None);
                             }
                         }
diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index fad72db74ed..de4eee22573 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -623,7 +623,7 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
 
 /// Check for `for` loops over `Option`s and `Results`
 fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) {
-    let ty = cx.tcx.expr_ty(arg);
+    let ty = cx.tcx.tables().expr_ty(arg);
     if match_type(cx, ty, &paths::OPTION) {
         span_help_and_lint(cx,
                            FOR_LOOP_OVER_OPTION,
@@ -709,7 +709,7 @@ fn check_for_loop_over_map_kv(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Ex
                 _ => (arg.span, arg),
             };
 
-            let ty = walk_ptrs_ty(cx.tcx.expr_ty(arg));
+            let ty = walk_ptrs_ty(cx.tcx.tables().expr_ty(arg));
             if match_type(cx, ty, &paths::HASHMAP) || match_type(cx, ty, &paths::BTREEMAP) {
                 span_lint_and_then(cx,
                                    FOR_KV_MAP,
@@ -854,7 +854,7 @@ impl<'v, 't> Visitor<'v> for VarUsedAfterLoopVisitor<'v, 't> {
 fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool {
     // no walk_ptrs_ty: calling iter() on a reference can make sense because it
     // will allow further borrows afterwards
-    let ty = cx.tcx.expr_ty(e);
+    let ty = cx.tcx.tables().expr_ty(e);
     is_iterable_array(ty) ||
     match_type(cx, ty, &paths::VEC) ||
     match_type(cx, ty, &paths::LINKED_LIST) ||
diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs
index 39b0c7d80a5..17975ed3768 100644
--- a/clippy_lints/src/map_clone.rs
+++ b/clippy_lints/src/map_clone.rs
@@ -30,11 +30,8 @@ impl LateLintPass for Pass {
         if let ExprMethodCall(name, _, ref args) = expr.node {
             if name.node.as_str() == "map" && args.len() == 2 {
                 match args[1].node {
-                    ExprClosure(_, ref decl, ref blk, _) => {
+                    ExprClosure(_, ref decl, ref closure_expr, _) => {
                         if_let_chain! {[
-                            // just one expression in the closure
-                            blk.stmts.is_empty(),
-                            let Some(ref closure_expr) = blk.expr,
                             // nothing special in the argument, besides reference bindings
                             // (e.g. .map(|&x| x) )
                             let Some(arg_ident) = get_arg_name(&*decl.inputs[0].pat),
@@ -44,7 +41,7 @@ impl LateLintPass for Pass {
                             // look for derefs, for .map(|x| *x)
                             if only_derefs(cx, &*closure_expr, arg_ident) &&
                                 // .cloned() only removes one level of indirection, don't lint on more
-                                walk_ptrs_ty_depth(cx.tcx.pat_ty(&*decl.inputs[0].pat)).1 == 1
+                                walk_ptrs_ty_depth(cx.tcx.tables().pat_ty(&*decl.inputs[0].pat)).1 == 1
                             {
                                 span_help_and_lint(cx, MAP_CLONE, expr.span, &format!(
                                     "you seem to be using .map() to clone the contents of an {}, consider \
@@ -101,7 +98,7 @@ fn expr_eq_name(expr: &Expr, id: ast::Name) -> bool {
 fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static str> {
     if match_trait_method(cx, expr, &paths::ITERATOR) {
         Some("iterator")
-    } else if match_type(cx, walk_ptrs_ty(cx.tcx.expr_ty(arg)), &paths::OPTION) {
+    } else if match_type(cx, walk_ptrs_ty(cx.tcx.tables().expr_ty(arg)), &paths::OPTION) {
         Some("Option")
     } else {
         None
diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs
index a3a4b7155f5..844715835b9 100644
--- a/clippy_lints/src/matches.rs
+++ b/clippy_lints/src/matches.rs
@@ -159,7 +159,7 @@ fn check_single_match(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
             // allow match arms with just expressions
             return;
         };
-        let ty = cx.tcx.expr_ty(ex);
+        let ty = cx.tcx.tables().expr_ty(ex);
         if ty.sty != ty::TyBool || cx.current_level(MATCH_BOOL) == Allow {
             check_single_match_single_pattern(cx, ex, arms, expr, els);
             check_single_match_opt_like(cx, ex, arms, expr, ty, els);
@@ -243,7 +243,7 @@ fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr:
 
 fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
     // type of expression == bool
-    if cx.tcx.expr_ty(ex).sty == ty::TyBool {
+    if cx.tcx.tables().expr_ty(ex).sty == ty::TyBool {
         span_lint_and_then(cx,
                            MATCH_BOOL,
                            expr.span,
@@ -296,7 +296,7 @@ fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
 }
 
 fn check_overlapping_arms(cx: &LateContext, ex: &Expr, arms: &[Arm]) {
-    if arms.len() >= 2 && cx.tcx.expr_ty(ex).is_integral() {
+    if arms.len() >= 2 && cx.tcx.tables().expr_ty(ex).is_integral() {
         let ranges = all_ranges(cx, arms);
         let type_ranges = type_ranges(&ranges);
         if !type_ranges.is_empty() {
diff --git a/clippy_lints/src/mem_forget.rs b/clippy_lints/src/mem_forget.rs
index 41151835ce1..492962def6a 100644
--- a/clippy_lints/src/mem_forget.rs
+++ b/clippy_lints/src/mem_forget.rs
@@ -33,7 +33,7 @@ impl LateLintPass for MemForget {
             if let ExprPath(None, _) = path_expr.node {
                 let def_id = cx.tcx.expect_def(path_expr.id).def_id();
                 if match_def_path(cx, def_id, &paths::MEM_FORGET) {
-                    let forgot_ty = cx.tcx.expr_ty(&args[0]);
+                    let forgot_ty = cx.tcx.tables().expr_ty(&args[0]);
 
                     if match forgot_ty.ty_adt_def() {
                         Some(def) => def.has_dtor(),
diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs
index 70ae2e6a189..a0c64c23bb9 100644
--- a/clippy_lints/src/methods.rs
+++ b/clippy_lints/src/methods.rs
@@ -573,7 +573,7 @@ impl LateLintPass for Pass {
 
                 lint_or_fun_call(cx, expr, &name.node.as_str(), args);
 
-                let self_ty = cx.tcx.expr_ty_adjusted(&args[0]);
+                let self_ty = cx.tcx.tables().expr_ty_adjusted(&args[0]);
                 if args.len() == 1 && name.node.as_str() == "clone" {
                     lint_clone_on_copy(cx, expr, &args[0], self_ty);
                 }
@@ -623,7 +623,7 @@ impl LateLintPass for Pass {
             }
 
             // check conventions w.r.t. conversion method names and predicates
-            let ty = cx.tcx.lookup_item_type(cx.tcx.map.local_def_id(item.id)).ty;
+            let ty = cx.tcx.item_type(cx.tcx.map.local_def_id(item.id));
             let is_copy = is_copy(cx, ty, item.id);
             for &(ref conv, self_kinds) in &CONVENTIONS {
                 if_let_chain! {[
@@ -680,7 +680,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[P<hi
                                       .as_str();
 
                 if ["default", "new"].contains(&path) {
-                    let arg_ty = cx.tcx.expr_ty(arg);
+                    let arg_ty = cx.tcx.tables().expr_ty(arg);
                     let default_trait_id = if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT) {
                         default_trait_id
                     } else {
@@ -724,7 +724,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[P<hi
                                                    "else"),
                                                   (&paths::RESULT, true, &["or", "unwrap_or"], "else")];
 
-        let self_ty = cx.tcx.expr_ty(self_expr);
+        let self_ty = cx.tcx.tables().expr_ty(self_expr);
 
         let (fn_has_arguments, poss, suffix) = if let Some(&(_, fn_has_arguments, poss, suffix)) =
                                                       know_types.iter().find(|&&i| match_type(cx, self_ty, i.0)) {
@@ -762,7 +762,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[P<hi
 
 /// Checks for the `CLONE_ON_COPY` lint.
 fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_ty: ty::Ty) {
-    let ty = cx.tcx.expr_ty(expr);
+    let ty = cx.tcx.tables().expr_ty(expr);
     let parent = cx.tcx.map.get_parent(expr.id);
     let parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, parent);
     if let ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) = arg_ty.sty {
@@ -785,7 +785,7 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t
                            expr.span,
                            "using `clone` on a `Copy` type",
                            |db| if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) {
-                               if let ty::TyRef(..) = cx.tcx.expr_ty(arg).sty {
+                               if let ty::TyRef(..) = cx.tcx.tables().expr_ty(arg).sty {
                                    db.span_suggestion(expr.span, "try dereferencing it", format!("{}", snip.deref()));
                                } else {
                                    db.span_suggestion(expr.span, "try removing the `clone` call", format!("{}", snip));
@@ -795,11 +795,11 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t
 }
 
 fn lint_extend(cx: &LateContext, expr: &hir::Expr, args: &MethodArgs) {
-    let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&args[0]));
+    let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&args[0]));
     if !match_type(cx, obj_ty, &paths::VEC) {
         return;
     }
-    let arg_ty = cx.tcx.expr_ty(&args[1]);
+    let arg_ty = cx.tcx.tables().expr_ty(&args[1]);
     if let Some(slice) = derefs_to_slice(cx, &args[1], arg_ty) {
         span_lint_and_then(cx, EXTEND_FROM_SLICE, expr.span, "use of `extend` to extend a Vec by a slice", |db| {
             db.span_suggestion(expr.span,
@@ -831,13 +831,13 @@ fn lint_cstring_as_ptr(cx: &LateContext, expr: &hir::Expr, new: &hir::Expr, unwr
 // Type of MethodArgs is potentially a Vec
 fn lint_iter_nth(cx: &LateContext, expr: &hir::Expr, iter_args: &MethodArgs, is_mut: bool){
     let mut_str = if is_mut { "_mut" } else {""};
-    let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.tcx.expr_ty(&iter_args[0])).is_some() {
+    let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.tcx.tables().expr_ty(&iter_args[0])).is_some() {
         "slice"
     }
-    else if match_type(cx, cx.tcx.expr_ty(&iter_args[0]), &paths::VEC) {
+    else if match_type(cx, cx.tcx.tables().expr_ty(&iter_args[0]), &paths::VEC) {
         "Vec"
     }
-    else if match_type(cx, cx.tcx.expr_ty(&iter_args[0]), &paths::VEC_DEQUE) {
+    else if match_type(cx, cx.tcx.tables().expr_ty(&iter_args[0]), &paths::VEC_DEQUE) {
         "VecDeque"
     }
     else {
@@ -856,7 +856,7 @@ fn lint_iter_nth(cx: &LateContext, expr: &hir::Expr, iter_args: &MethodArgs, is_
 fn lint_get_unwrap(cx: &LateContext, expr: &hir::Expr, get_args: &MethodArgs, is_mut: bool) {
     // Note: we don't want to lint `get_mut().unwrap` for HashMap or BTreeMap,
     // because they do not implement `IndexMut`
-    let expr_ty = cx.tcx.expr_ty(&get_args[0]);
+    let expr_ty = cx.tcx.tables().expr_ty(&get_args[0]);
     let caller_type = if derefs_to_slice(cx, &get_args[0], expr_ty).is_some() {
         "slice"
     } else if match_type(cx, expr_ty, &paths::VEC) {
@@ -915,7 +915,7 @@ fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: ty::Ty) -> Option<sug
     }
 
     if let hir::ExprMethodCall(name, _, ref args) = expr.node {
-        if &name.node.as_str() == &"iter" && may_slice(cx, cx.tcx.expr_ty(&args[0])) {
+        if &name.node.as_str() == &"iter" && may_slice(cx, cx.tcx.tables().expr_ty(&args[0])) {
             sugg::Sugg::hir_opt(cx, &*args[0]).map(|sugg| {
                 sugg.addr()
             })
@@ -942,7 +942,7 @@ fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: ty::Ty) -> Option<sug
 // Type of MethodArgs is potentially a Vec
 /// lint use of `unwrap()` for `Option`s and `Result`s
 fn lint_unwrap(cx: &LateContext, expr: &hir::Expr, unwrap_args: &MethodArgs) {
-    let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&unwrap_args[0]));
+    let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&unwrap_args[0]));
 
     let mess = if match_type(cx, obj_ty, &paths::OPTION) {
         Some((OPTION_UNWRAP_USED, "an Option", "None"))
@@ -969,8 +969,8 @@ fn lint_unwrap(cx: &LateContext, expr: &hir::Expr, unwrap_args: &MethodArgs) {
 /// lint use of `ok().expect()` for `Result`s
 fn lint_ok_expect(cx: &LateContext, expr: &hir::Expr, ok_args: &MethodArgs) {
     // lint if the caller of `ok()` is a `Result`
-    if match_type(cx, cx.tcx.expr_ty(&ok_args[0]), &paths::RESULT) {
-        let result_type = cx.tcx.expr_ty(&ok_args[0]);
+    if match_type(cx, cx.tcx.tables().expr_ty(&ok_args[0]), &paths::RESULT) {
+        let result_type = cx.tcx.tables().expr_ty(&ok_args[0]);
         if let Some(error_type) = get_error_type(cx, result_type) {
             if has_debug_impl(error_type, cx) {
                 span_lint(cx,
@@ -987,7 +987,7 @@ fn lint_ok_expect(cx: &LateContext, expr: &hir::Expr, ok_args: &MethodArgs) {
 /// lint use of `map().unwrap_or()` for `Option`s
 fn lint_map_unwrap_or(cx: &LateContext, expr: &hir::Expr, map_args: &MethodArgs, unwrap_args: &MethodArgs) {
     // lint if the caller of `map()` is an `Option`
-    if match_type(cx, cx.tcx.expr_ty(&map_args[0]), &paths::OPTION) {
+    if match_type(cx, cx.tcx.tables().expr_ty(&map_args[0]), &paths::OPTION) {
         // lint message
         let msg = "called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling \
                    `map_or(a, f)` instead";
@@ -1018,7 +1018,7 @@ fn lint_map_unwrap_or(cx: &LateContext, expr: &hir::Expr, map_args: &MethodArgs,
 /// lint use of `map().unwrap_or_else()` for `Option`s
 fn lint_map_unwrap_or_else(cx: &LateContext, expr: &hir::Expr, map_args: &MethodArgs, unwrap_args: &MethodArgs) {
     // lint if the caller of `map()` is an `Option`
-    if match_type(cx, cx.tcx.expr_ty(&map_args[0]), &paths::OPTION) {
+    if match_type(cx, cx.tcx.tables().expr_ty(&map_args[0]), &paths::OPTION) {
         // lint message
         let msg = "called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling \
                    `map_or_else(g, f)` instead";
@@ -1147,7 +1147,7 @@ fn lint_chars_next(cx: &LateContext, expr: &hir::Expr, chain: &hir::Expr, other:
         let hir::ExprPath(None, ref path) = fun.node,
         path.segments.len() == 1 && path.segments[0].name.as_str() == "Some"
     ], {
-        let self_ty = walk_ptrs_ty(cx.tcx.expr_ty_adjusted(&args[0][0]));
+        let self_ty = walk_ptrs_ty(cx.tcx.tables().expr_ty_adjusted(&args[0][0]));
 
         if self_ty.sty != ty::TyStr {
             return false;
diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs
index afe9a6fee0b..62aec0a718d 100644
--- a/clippy_lints/src/misc.rs
+++ b/clippy_lints/src/misc.rs
@@ -168,7 +168,7 @@ impl LintPass for Pass {
 }
 
 impl LateLintPass for Pass {
-    fn check_fn(&mut self, cx: &LateContext, k: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) {
+    fn check_fn(&mut self, cx: &LateContext, k: FnKind, decl: &FnDecl, _: &Expr, _: Span, _: NodeId) {
         if let FnKind::Closure(_) = k {
             // Does not apply to closures
             return;
@@ -353,14 +353,14 @@ fn is_allowed(cx: &LateContext, expr: &Expr) -> bool {
 }
 
 fn is_float(cx: &LateContext, expr: &Expr) -> bool {
-    matches!(walk_ptrs_ty(cx.tcx.expr_ty(expr)).sty, ty::TyFloat(_))
+    matches!(walk_ptrs_ty(cx.tcx.tables().expr_ty(expr)).sty, ty::TyFloat(_))
 }
 
 fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: Span) {
     let (arg_ty, snip) = match expr.node {
         ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) if args.len() == 1 => {
             if name.as_str() == "to_string" || name.as_str() == "to_owned" && is_str_arg(cx, args) {
-                (cx.tcx.expr_ty(&args[0]), snippet(cx, args[0].span, ".."))
+                (cx.tcx.tables().expr_ty(&args[0]), snippet(cx, args[0].span, ".."))
             } else {
                 return;
             }
@@ -368,7 +368,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S
         ExprCall(ref path, ref v) if v.len() == 1 => {
             if let ExprPath(None, ref path) = path.node {
                 if match_path(path, &["String", "from_str"]) || match_path(path, &["String", "from"]) {
-                    (cx.tcx.expr_ty(&v[0]), snippet(cx, v[0].span, ".."))
+                    (cx.tcx.tables().expr_ty(&v[0]), snippet(cx, v[0].span, ".."))
                 } else {
                     return;
                 }
@@ -379,7 +379,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S
         _ => return,
     };
 
-    let other_ty = cx.tcx.expr_ty(other);
+    let other_ty = cx.tcx.tables().expr_ty(other);
     let partial_eq_trait_id = match cx.tcx.lang_items.eq_trait() {
         Some(id) => id,
         None => return,
@@ -413,7 +413,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S
 
 fn is_str_arg(cx: &LateContext, args: &[P<Expr>]) -> bool {
     args.len() == 1 &&
-        matches!(walk_ptrs_ty(cx.tcx.expr_ty(&args[0])).sty, ty::TyStr)
+        matches!(walk_ptrs_ty(cx.tcx.tables().expr_ty(&args[0])).sty, ty::TyStr)
 }
 
 /// Heuristic to see if an expression is used. Should be compatible with `unused_variables`'s idea
diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs
index 61e4530a1df..abb9d0fcb49 100644
--- a/clippy_lints/src/misc_early.rs
+++ b/clippy_lints/src/misc_early.rs
@@ -239,7 +239,7 @@ impl EarlyLintPass for MiscEarly {
         }
     }
 
-    fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) {
+    fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, decl: &FnDecl, _: Span, _: NodeId) {
         let mut registered_names: HashMap<String, Span> = HashMap::new();
 
         for arg in &decl.inputs {
diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs
index 454f591756b..7ca00500475 100644
--- a/clippy_lints/src/missing_doc.rs
+++ b/clippy_lints/src/missing_doc.rs
@@ -147,10 +147,7 @@ impl LateLintPass for MissingDoc {
     fn check_impl_item(&mut self, cx: &LateContext, impl_item: &hir::ImplItem) {
         // If the method is an impl for a trait, don't doc.
         let def_id = cx.tcx.map.local_def_id(impl_item.id);
-        match cx.tcx.impl_or_trait_items.borrow()
-                                         .get(&def_id)
-                                         .expect("missing method descriptor?!")
-                                         .container() {
+        match cx.tcx.associated_item(def_id).container {
             ty::TraitContainer(_) => return,
             ty::ImplContainer(cid) => {
                 if cx.tcx.impl_trait_ref(cid).is_some() {
diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs
index 24eb8dfc363..fe430a539a0 100644
--- a/clippy_lints/src/mut_mut.rs
+++ b/clippy_lints/src/mut_mut.rs
@@ -65,7 +65,7 @@ impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for MutVisitor<'a, 'tcx> {
         } else if let hir::ExprAddrOf(hir::MutMutable, ref e) = expr.node {
             if let hir::ExprAddrOf(hir::MutMutable, _) = e.node {
                 span_lint(self.cx, MUT_MUT, expr.span, "generally you want to avoid `&mut &mut _` if possible");
-            } else if let TyRef(_, TypeAndMut { mutbl: hir::MutMutable, .. }) = self.cx.tcx.expr_ty(e).sty {
+            } else if let TyRef(_, TypeAndMut { mutbl: hir::MutMutable, .. }) = self.cx.tcx.tables().expr_ty(e).sty {
                 span_lint(self.cx,
                           MUT_MUT,
                           expr.span,
diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs
index a2117656f9d..bdf0ad2af98 100644
--- a/clippy_lints/src/mutex_atomic.rs
+++ b/clippy_lints/src/mutex_atomic.rs
@@ -56,7 +56,7 @@ pub struct MutexAtomic;
 
 impl LateLintPass for MutexAtomic {
     fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
-        let ty = cx.tcx.expr_ty(expr);
+        let ty = cx.tcx.tables().expr_ty(expr);
         if let ty::TyAdt(_, subst) = ty.sty {
             if match_type(cx, ty, &paths::MUTEX) {
                 let mutex_param = &subst.type_at(0).sty;
diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs
index 29691504b82..b2199c226e9 100644
--- a/clippy_lints/src/needless_borrow.rs
+++ b/clippy_lints/src/needless_borrow.rs
@@ -4,9 +4,8 @@
 
 use rustc::lint::*;
 use rustc::hir::{ExprAddrOf, Expr, MutImmutable, Pat, PatKind, BindingMode};
-use rustc::ty::TyRef;
+use rustc::ty;
 use utils::{span_lint, in_macro};
-use rustc::ty::adjustment::AutoAdjustment::AdjustDerefRef;
 
 /// **What it does:** Checks for address of operations (`&`) that are going to
 /// be dereferenced immediately by the compiler.
@@ -41,9 +40,9 @@ impl LateLintPass for NeedlessBorrow {
             return;
         }
         if let ExprAddrOf(MutImmutable, ref inner) = e.node {
-            if let TyRef(..) = cx.tcx.expr_ty(inner).sty {
-                if let Some(&AdjustDerefRef(ref deref)) = cx.tcx.tables.borrow().adjustments.get(&e.id) {
-                    if deref.autoderefs > 1 && deref.autoref.is_some() {
+            if let ty::TyRef(..) = cx.tcx.tables().expr_ty(inner).sty {
+                if let Some(&ty::adjustment::Adjust::DerefRef { autoderefs, autoref, .. }) = cx.tcx.tables.borrow().adjustments.get(&e.id).map(|a| &a.kind) {
+                    if autoderefs > 1 && autoref.is_some() {
                         span_lint(cx,
                                   NEEDLESS_BORROW,
                                   e.span,
@@ -59,9 +58,9 @@ impl LateLintPass for NeedlessBorrow {
             return;
         }
         if let PatKind::Binding(BindingMode::BindByRef(MutImmutable), _, _) = pat.node {
-            if let TyRef(_, ref tam) = cx.tcx.pat_ty(pat).sty {
+            if let ty::TyRef(_, ref tam) = cx.tcx.tables().pat_ty(pat).sty {
                 if tam.mutbl == MutImmutable {
-                    if let TyRef(..) = tam.ty.sty {
+                    if let ty::TyRef(..) = tam.ty.sty {
                         span_lint(cx,
                                   NEEDLESS_BORROW,
                                   pat.span,
diff --git a/clippy_lints/src/needless_update.rs b/clippy_lints/src/needless_update.rs
index 9f607f4350d..cdd266ec2e8 100644
--- a/clippy_lints/src/needless_update.rs
+++ b/clippy_lints/src/needless_update.rs
@@ -33,7 +33,7 @@ impl LintPass for Pass {
 impl LateLintPass for Pass {
     fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
         if let ExprStruct(_, ref fields, Some(ref base)) = expr.node {
-            let ty = cx.tcx.expr_ty(expr);
+            let ty = cx.tcx.tables().expr_ty(expr);
             if let TyAdt(def, _) = ty.sty {
                 if fields.len() == def.struct_variant().fields.len() {
                     span_lint(cx,
diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs
index 3749b36540c..5ca6172b6bc 100644
--- a/clippy_lints/src/neg_multiply.rs
+++ b/clippy_lints/src/neg_multiply.rs
@@ -50,7 +50,7 @@ fn check_mul(cx: &LateContext, span: Span, lit: &Expr, exp: &Expr) {
         let Constant::Int(ref ci) = consts::lit_to_constant(&l.node),
         let Some(val) = ci.to_u64(),
         val == 1,
-        cx.tcx.expr_ty(exp).is_integral()
+        cx.tcx.tables().expr_ty(exp).is_integral()
     ], {
         span_lint(cx,
                   NEG_MULTIPLY,
diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs
index 538d3abd5ea..66420f00c67 100644
--- a/clippy_lints/src/new_without_default.rs
+++ b/clippy_lints/src/new_without_default.rs
@@ -90,7 +90,7 @@ impl LintPass for NewWithoutDefault {
 }
 
 impl LateLintPass for NewWithoutDefault {
-    fn check_fn(&mut self, cx: &LateContext, kind: FnKind, decl: &hir::FnDecl, _: &hir::Block, span: Span, id: ast::NodeId) {
+    fn check_fn(&mut self, cx: &LateContext, kind: FnKind, decl: &hir::FnDecl, _: &hir::Expr, span: Span, id: ast::NodeId) {
         if in_external_macro(cx, span) {
             return;
         }
@@ -102,8 +102,7 @@ impl LateLintPass for NewWithoutDefault {
             }
             if decl.inputs.is_empty() && name.as_str() == "new" && cx.access_levels.is_reachable(id) {
                 let self_ty = cx.tcx
-                    .lookup_item_type(cx.tcx.map.local_def_id(cx.tcx.map.get_parent(id)))
-                    .ty;
+                    .item_type(cx.tcx.map.local_def_id(cx.tcx.map.get_parent(id)));
                 if_let_chain!{[
                     self_ty.walk_shallow().next().is_none(), // implements_trait does not work with generics
                     same_tys(cx, self_ty, return_ty(cx, id), id),
diff --git a/clippy_lints/src/ok_if_let.rs b/clippy_lints/src/ok_if_let.rs
index 09e3fa641f9..1fdfe43b684 100644
--- a/clippy_lints/src/ok_if_let.rs
+++ b/clippy_lints/src/ok_if_let.rs
@@ -50,7 +50,7 @@ impl LateLintPass for Pass {
             method_chain_args(op, &["ok"]).is_some() //test to see if using ok() methoduse std::marker::Sized;
 
         ], {
-            let is_result_type = match_type(cx, cx.tcx.expr_ty(&result_types[0]), &paths::RESULT);
+            let is_result_type = match_type(cx, cx.tcx.tables().expr_ty(&result_types[0]), &paths::RESULT);
             let some_expr_string = snippet(cx, y[0].span, "");
             if print::path_to_string(x) == "Some" && is_result_type {
                 span_help_and_lint(cx, IF_LET_SOME_RESULT, expr.span,
diff --git a/clippy_lints/src/open_options.rs b/clippy_lints/src/open_options.rs
index 42851c1fe24..51d961e9fe6 100644
--- a/clippy_lints/src/open_options.rs
+++ b/clippy_lints/src/open_options.rs
@@ -35,7 +35,7 @@ impl LintPass for NonSensical {
 impl LateLintPass for NonSensical {
     fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
         if let ExprMethodCall(ref name, _, ref arguments) = e.node {
-            let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&arguments[0]));
+            let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&arguments[0]));
             if name.node.as_str() == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
                 let mut options = Vec::new();
                 get_open_options(cx, &arguments[0], &mut options);
@@ -63,7 +63,7 @@ enum OpenOption {
 
 fn get_open_options(cx: &LateContext, argument: &Expr, options: &mut Vec<(OpenOption, Argument)>) {
     if let ExprMethodCall(ref name, _, ref arguments) = argument.node {
-        let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&arguments[0]));
+        let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&arguments[0]));
 
         // Only proceed if this is a call on some object of type std::fs::OpenOptions
         if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && arguments.len() >= 2 {
diff --git a/clippy_lints/src/overflow_check_conditional.rs b/clippy_lints/src/overflow_check_conditional.rs
index 24bccf687f1..98c2b986d20 100644
--- a/clippy_lints/src/overflow_check_conditional.rs
+++ b/clippy_lints/src/overflow_check_conditional.rs
@@ -39,8 +39,8 @@ impl LateLintPass for OverflowCheckConditional {
             let Expr_::ExprPath(_, ref path2) = ident2.node,
             let Expr_::ExprPath(_, ref path3) = second.node,
             &path1.segments[0] == &path3.segments[0] || &path2.segments[0] == &path3.segments[0],
-            cx.tcx.expr_ty(ident1).is_integral(),
-            cx.tcx.expr_ty(ident2).is_integral()
+            cx.tcx.tables().expr_ty(ident1).is_integral(),
+            cx.tcx.tables().expr_ty(ident2).is_integral()
         ], {
             if let BinOp_::BiLt = op.node {
                 if let BinOp_::BiAdd = op2.node {
@@ -61,8 +61,8 @@ impl LateLintPass for OverflowCheckConditional {
             let Expr_::ExprPath(_, ref path2) = ident2.node,
             let Expr_::ExprPath(_, ref path3) = first.node,
             &path1.segments[0] == &path3.segments[0] || &path2.segments[0] == &path3.segments[0],
-            cx.tcx.expr_ty(ident1).is_integral(),
-            cx.tcx.expr_ty(ident2).is_integral()
+            cx.tcx.tables().expr_ty(ident1).is_integral(),
+            cx.tcx.tables().expr_ty(ident2).is_integral()
         ], {
             if let BinOp_::BiGt = op.node {
                 if let BinOp_::BiAdd = op2.node {
diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs
index dea950ac063..2863b14b112 100644
--- a/clippy_lints/src/ptr.rs
+++ b/clippy_lints/src/ptr.rs
@@ -91,7 +91,8 @@ impl LateLintPass for PointerPass {
 }
 
 fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId) {
-    let fn_ty = cx.tcx.node_id_to_type(fn_id).fn_sig().skip_binder();
+    let fn_def_id = cx.tcx.map.local_def_id(fn_id);
+    let fn_ty = cx.tcx.item_type(fn_def_id).fn_sig().skip_binder();
 
     for (arg, ty) in decl.inputs.iter().zip(&fn_ty.inputs) {
         if let ty::TyRef(_, ty::TypeAndMut { ty, mutbl: MutImmutable }) = ty.sty {
diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs
index 2e9a72e54a9..45886a90394 100644
--- a/clippy_lints/src/ranges.rs
+++ b/clippy_lints/src/ranges.rs
@@ -89,7 +89,7 @@ impl LateLintPass for StepByZero {
 fn has_step_by(cx: &LateContext, expr: &Expr) -> bool {
     // No need for walk_ptrs_ty here because step_by moves self, so it
     // can't be called on a borrowed range.
-    let ty = cx.tcx.expr_ty(expr);
+    let ty = cx.tcx.tables().expr_ty(expr);
 
     // Note: `RangeTo`, `RangeToInclusive` and `RangeFull` don't have step_by
     match_type(cx, ty, &paths::RANGE)
diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs
index ab0c4f237c2..fef03d19cc7 100644
--- a/clippy_lints/src/regex.rs
+++ b/clippy_lints/src/regex.rs
@@ -91,7 +91,7 @@ impl LateLintPass for Pass {
         if_let_chain!{[
             self.last.is_none(),
             let Some(ref expr) = block.expr,
-            match_type(cx, cx.tcx.expr_ty(expr), &paths::REGEX),
+            match_type(cx, cx.tcx.tables().expr_ty(expr), &paths::REGEX),
             let Some(span) = is_expn_of(cx, expr.span, "regex"),
         ], {
             if !self.spans.contains(&span) {
diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs
index 456f17e74a7..0e6de0d39b2 100644
--- a/clippy_lints/src/returns.rs
+++ b/clippy_lints/src/returns.rs
@@ -1,5 +1,5 @@
 use rustc::lint::*;
-use syntax::ast::*;
+use syntax::ast;
 use syntax::codemap::{Span, Spanned};
 use syntax::visit::FnKind;
 
@@ -45,10 +45,10 @@ pub struct ReturnPass;
 
 impl ReturnPass {
     // Check the final stmt or expr in a block for unnecessary return.
-    fn check_block_return(&mut self, cx: &EarlyContext, block: &Block) {
+    fn check_block_return(&mut self, cx: &EarlyContext, block: &ast::Block) {
         if let Some(stmt) = block.stmts.last() {
             match stmt.node {
-                StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => {
+                ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
                     self.check_final_expr(cx, expr, Some(stmt.span));
                 }
                 _ => (),
@@ -57,25 +57,25 @@ impl ReturnPass {
     }
 
     // Check a the final expression in a block if it's a return.
-    fn check_final_expr(&mut self, cx: &EarlyContext, expr: &Expr, span: Option<Span>) {
+    fn check_final_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr, span: Option<Span>) {
         match expr.node {
             // simple return is always "bad"
-            ExprKind::Ret(Some(ref inner)) => {
+            ast::ExprKind::Ret(Some(ref inner)) => {
                 self.emit_return_lint(cx, span.expect("`else return` is not possible"), inner.span);
             }
             // a whole block? check it!
-            ExprKind::Block(ref block) => {
+            ast::ExprKind::Block(ref block) => {
                 self.check_block_return(cx, block);
             }
             // an if/if let expr, check both exprs
             // note, if without else is going to be a type checking error anyways
             // (except for unit type functions) so we don't match it
-            ExprKind::If(_, ref ifblock, Some(ref elsexpr)) => {
+            ast::ExprKind::If(_, ref ifblock, Some(ref elsexpr)) => {
                 self.check_block_return(cx, ifblock);
                 self.check_final_expr(cx, elsexpr, None);
             }
             // a match expr, check all arms
-            ExprKind::Match(_, ref arms) => {
+            ast::ExprKind::Match(_, ref arms) => {
                 for arm in arms {
                     self.check_final_expr(cx, &arm.body, Some(arm.body.span));
                 }
@@ -96,18 +96,18 @@ impl ReturnPass {
     }
 
     // Check for "let x = EXPR; x"
-    fn check_let_return(&mut self, cx: &EarlyContext, block: &Block) {
+    fn check_let_return(&mut self, cx: &EarlyContext, block: &ast::Block) {
         let mut it = block.stmts.iter();
 
         // we need both a let-binding stmt and an expr
         if_let_chain! {[
             let Some(ref retexpr) = it.next_back(),
-            let StmtKind::Expr(ref retexpr) = retexpr.node,
+            let ast::StmtKind::Expr(ref retexpr) = retexpr.node,
             let Some(stmt) = it.next_back(),
-            let StmtKind::Local(ref local) = stmt.node,
+            let ast::StmtKind::Local(ref local) = stmt.node,
             let Some(ref initexpr) = local.init,
-            let PatKind::Ident(_, Spanned { node: id, .. }, _) = local.pat.node,
-            let ExprKind::Path(_, ref path) = retexpr.node,
+            let ast::PatKind::Ident(_, Spanned { node: id, .. }, _) = local.pat.node,
+            let ast::ExprKind::Path(_, ref path) = retexpr.node,
             match_path_ast(path, &[&id.name.as_str()]),
             !in_external_macro(cx, initexpr.span),
         ], {
@@ -129,11 +129,14 @@ impl LintPass for ReturnPass {
 }
 
 impl EarlyLintPass for ReturnPass {
-    fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, _: &FnDecl, block: &Block, _: Span, _: NodeId) {
-        self.check_block_return(cx, block);
+    fn check_fn(&mut self, cx: &EarlyContext, kind: FnKind, _: &ast::FnDecl, _: Span, _: ast::NodeId) {
+        match kind {
+            FnKind::ItemFn(.., block) | FnKind::Method(.., block) => self.check_block_return(cx, block),
+            FnKind::Closure(body) => self.check_final_expr(cx, body, None),
+        }
     }
 
-    fn check_block(&mut self, cx: &EarlyContext, block: &Block) {
+    fn check_block(&mut self, cx: &EarlyContext, block: &ast::Block) {
         self.check_let_return(cx, block);
     }
 }
diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs
index 53ee8295768..b57ec1d052a 100644
--- a/clippy_lints/src/shadow.rs
+++ b/clippy_lints/src/shadow.rs
@@ -81,22 +81,22 @@ impl LintPass for Pass {
 }
 
 impl LateLintPass for Pass {
-    fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, block: &Block, _: Span, _: NodeId) {
-        if in_external_macro(cx, block.span) {
+    fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, expr: &Expr, _: Span, _: NodeId) {
+        if in_external_macro(cx, expr.span) {
             return;
         }
-        check_fn(cx, decl, block);
+        check_fn(cx, decl, expr);
     }
 }
 
-fn check_fn(cx: &LateContext, decl: &FnDecl, block: &Block) {
+fn check_fn(cx: &LateContext, decl: &FnDecl, expr: &Expr) {
     let mut bindings = Vec::new();
     for arg in &decl.inputs {
         if let PatKind::Binding(_, ident, _) = arg.pat.node {
             bindings.push((ident.node, ident.span))
         }
     }
-    check_block(cx, block, &mut bindings);
+    check_expr(cx, expr, &mut bindings);
 }
 
 fn check_block(cx: &LateContext, block: &Block, bindings: &mut Vec<(Name, Span)>) {
diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs
index 28e61cf2e20..9fd09eab2dd 100644
--- a/clippy_lints/src/strings.rs
+++ b/clippy_lints/src/strings.rs
@@ -114,7 +114,7 @@ impl LateLintPass for StringAdd {
 }
 
 fn is_string(cx: &LateContext, e: &Expr) -> bool {
-    match_type(cx, walk_ptrs_ty(cx.tcx.expr_ty(e)), &paths::STRING)
+    match_type(cx, walk_ptrs_ty(cx.tcx.tables().expr_ty(e)), &paths::STRING)
 }
 
 fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool {
diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs
index 584bcb0d866..278df3bad35 100644
--- a/clippy_lints/src/swap.rs
+++ b/clippy_lints/src/swap.rs
@@ -85,7 +85,7 @@ fn check_manual_swap(cx: &LateContext, block: &Block) {
                 if let ExprIndex(ref lhs1, ref idx1) = lhs1.node {
                     if let ExprIndex(ref lhs2, ref idx2) = lhs2.node {
                         if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, lhs2) {
-                            let ty = walk_ptrs_ty(cx.tcx.expr_ty(lhs1));
+                            let ty = walk_ptrs_ty(cx.tcx.tables().expr_ty(lhs1));
 
                             if matches!(ty.sty, ty::TySlice(_)) ||
                                 matches!(ty.sty, ty::TyArray(_, _)) ||
diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs
index 5e9931c3bd2..b4505c89f3b 100644
--- a/clippy_lints/src/transmute.rs
+++ b/clippy_lints/src/transmute.rs
@@ -91,8 +91,8 @@ impl LateLintPass for Transmute {
                 let def_id = cx.tcx.expect_def(path_expr.id).def_id();
 
                 if match_def_path(cx, def_id, &paths::TRANSMUTE) {
-                    let from_ty = cx.tcx.expr_ty(&args[0]);
-                    let to_ty = cx.tcx.expr_ty(e);
+                    let from_ty = cx.tcx.tables().expr_ty(&args[0]);
+                    let to_ty = cx.tcx.tables().expr_ty(e);
 
                     match (&from_ty.sty, &to_ty.sty) {
                         _ if from_ty == to_ty => span_lint(
diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs
index 40bd87f08cd..de8fbdcc5d7 100644
--- a/clippy_lints/src/types.rs
+++ b/clippy_lints/src/types.rs
@@ -126,7 +126,7 @@ declare_lint! {
 
 fn check_let_unit(cx: &LateContext, decl: &Decl) {
     if let DeclLocal(ref local) = decl.node {
-        let bindtype = &cx.tcx.pat_ty(&local.pat).sty;
+        let bindtype = &cx.tcx.tables().pat_ty(&local.pat).sty;
         match *bindtype {
             ty::TyTuple(slice) if slice.is_empty() => {
                 if in_external_macro(cx, decl.span) || in_macro(cx, local.pat.span) {
@@ -197,7 +197,7 @@ impl LateLintPass for UnitCmp {
         if let ExprBinary(ref cmp, ref left, _) = expr.node {
             let op = cmp.node;
             if op.is_comparison() {
-                let sty = &cx.tcx.expr_ty(left).sty;
+                let sty = &cx.tcx.tables().expr_ty(left).sty;
                 match *sty {
                     ty::TyTuple(slice) if slice.is_empty() => {
                         let result = match op {
@@ -449,7 +449,7 @@ impl LintPass for CastPass {
 impl LateLintPass for CastPass {
     fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
         if let ExprCast(ref ex, _) = expr.node {
-            let (cast_from, cast_to) = (cx.tcx.expr_ty(ex), cx.tcx.expr_ty(expr));
+            let (cast_from, cast_to) = (cx.tcx.tables().expr_ty(ex), cx.tcx.tables().expr_ty(expr));
             if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx, expr.span) {
                 match (cast_from.is_integral(), cast_to.is_integral()) {
                     (true, false) => {
@@ -535,7 +535,7 @@ impl LintPass for TypeComplexityPass {
 }
 
 impl LateLintPass for TypeComplexityPass {
-    fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) {
+    fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, _: &Expr, _: Span, _: NodeId) {
         self.check_fndecl(cx, decl);
     }
 
@@ -683,7 +683,7 @@ impl LateLintPass for CharLitAsU8 {
         if let ExprCast(ref e, _) = expr.node {
             if let ExprLit(ref l) = e.node {
                 if let LitKind::Char(_) = l.node {
-                    if ty::TyUint(UintTy::U8) == cx.tcx.expr_ty(expr).sty && !in_macro(cx, expr.span) {
+                    if ty::TyUint(UintTy::U8) == cx.tcx.tables().expr_ty(expr).sty && !in_macro(cx, expr.span) {
                         let msg = "casting character literal to u8. `char`s \
                                    are 4 bytes wide in rust, so casting to u8 \
                                    truncates them";
@@ -791,7 +791,7 @@ fn detect_extreme_expr<'a>(cx: &LateContext, expr: &'a Expr) -> Option<ExtremeEx
     use rustc_const_eval::*;
     use types::ExtremeType::*;
 
-    let ty = &cx.tcx.expr_ty(expr).sty;
+    let ty = &cx.tcx.tables().expr_ty(expr).sty;
 
     match *ty {
         ty::TyBool | ty::TyInt(_) | ty::TyUint(_) => (),
@@ -953,7 +953,7 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(
     use std::*;
 
     if let ExprCast(ref cast_exp, _) = expr.node {
-        match cx.tcx.expr_ty(cast_exp).sty {
+        match cx.tcx.tables().expr_ty(cast_exp).sty {
             TyInt(int_ty) => {
                 Some(match int_ty {
                     IntTy::I8 => (FullInt::S(i8::min_value() as i64), FullInt::S(i8::max_value() as i64)),
diff --git a/clippy_lints/src/unused_label.rs b/clippy_lints/src/unused_label.rs
index 899fc940cf1..63a6321f0ea 100644
--- a/clippy_lints/src/unused_label.rs
+++ b/clippy_lints/src/unused_label.rs
@@ -47,7 +47,7 @@ impl LintPass for UnusedLabel {
 }
 
 impl LateLintPass for UnusedLabel {
-    fn check_fn(&mut self, cx: &LateContext, kind: FnKind, decl: &hir::FnDecl, body: &hir::Block, span: Span, fn_id: ast::NodeId) {
+    fn check_fn(&mut self, cx: &LateContext, kind: FnKind, decl: &hir::FnDecl, body: &hir::Expr, span: Span, fn_id: ast::NodeId) {
         if in_macro(cx, span) {
             return;
         }
diff --git a/clippy_lints/src/utils/hir.rs b/clippy_lints/src/utils/hir.rs
index b1be2ebb883..bd9969714a4 100644
--- a/clippy_lints/src/utils/hir.rs
+++ b/clippy_lints/src/utils/hir.rs
@@ -368,11 +368,11 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
                 self.hash_expr(e);
                 // TODO: _ty
             }
-            ExprClosure(cap, _, ref b, _) => {
+            ExprClosure(cap, _, ref e, _) => {
                 let c: fn(_, _, _, _) -> _ = ExprClosure;
                 c.hash(&mut self.s);
                 cap.hash(&mut self.s);
-                self.hash_block(b);
+                self.hash_expr(e);
             }
             ExprField(ref e, ref f) => {
                 let c: fn(_, _) -> _ = ExprField;
diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs
index a4d9e8452e6..15bae8a7b1f 100644
--- a/clippy_lints/src/utils/inspector.rs
+++ b/clippy_lints/src/utils/inspector.rs
@@ -135,7 +135,7 @@ fn has_attr(attrs: &[Attribute]) -> bool {
 fn print_decl(cx: &LateContext, decl: &hir::Decl) {
     match decl.node {
         hir::DeclLocal(ref local) => {
-            println!("local variable of type {}", cx.tcx.node_id_to_type(local.id));
+            println!("local variable of type {}", cx.tcx.tables().node_id_to_type(local.id));
             println!("pattern:");
             print_pat(cx, &local.pat, 0);
             if let Some(ref e) = local.init {
@@ -149,7 +149,7 @@ fn print_decl(cx: &LateContext, decl: &hir::Decl) {
 
 fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
     let ind = "  ".repeat(indent);
-    let ty = cx.tcx.node_id_to_type(expr.id);
+    let ty = cx.tcx.tables().node_id_to_type(expr.id);
     println!("{}+", ind);
     match expr.node {
         hir::ExprBox(ref e) => {
@@ -350,25 +350,25 @@ fn print_item(cx: &LateContext, item: &hir::Item) {
             }
         }
         hir::ItemUse(ref path) => println!("{:?}", path.node),
-        hir::ItemStatic(..) => println!("static item: {:#?}", cx.tcx.opt_lookup_item_type(did)),
-        hir::ItemConst(..) => println!("const item: {:#?}", cx.tcx.opt_lookup_item_type(did)),
+        hir::ItemStatic(..) => (), //println!("static item: {:#?}", cx.tcx.opt_lookup_item_type(did)),
+        hir::ItemConst(..) => (), //println!("const item: {:#?}", cx.tcx.opt_lookup_item_type(did)),
         hir::ItemFn(..) => {
-            let item_ty = cx.tcx.opt_lookup_item_type(did);
-            println!("function: {:#?}", item_ty);
+            //let item_ty = cx.tcx.opt_lookup_item_type(did);
+            //println!("function: {:#?}", item_ty);
         },
         hir::ItemMod(..) => println!("module"),
         hir::ItemForeignMod(ref fm) => println!("foreign module with abi: {}", fm.abi),
         hir::ItemTy(..) => {
-            println!("type alias: {:?}", cx.tcx.opt_lookup_item_type(did));
+            //println!("type alias: {:?}", cx.tcx.opt_lookup_item_type(did));
         },
         hir::ItemEnum(..) => {
-            println!("enum definition: {:?}", cx.tcx.opt_lookup_item_type(did));
+            //println!("enum definition: {:?}", cx.tcx.opt_lookup_item_type(did));
         },
         hir::ItemStruct(..) => {
-            println!("struct definition: {:?}", cx.tcx.opt_lookup_item_type(did));
+            //println!("struct definition: {:?}", cx.tcx.opt_lookup_item_type(did));
         },
         hir::ItemUnion(..) => {
-            println!("union definition: {:?}", cx.tcx.opt_lookup_item_type(did));
+            //println!("union definition: {:?}", cx.tcx.opt_lookup_item_type(did));
         },
         hir::ItemTrait(..) => {
             println!("trait decl");
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index 276ff8f065e..f273233b947 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -429,7 +429,12 @@ pub fn get_enclosing_block<'c>(cx: &'c LateContext, node: NodeId) -> Option<&'c
     if let Some(node) = enclosing_node {
         match node {
             Node::NodeBlock(block) => Some(block),
-            Node::NodeItem(&Item { node: ItemFn(_, _, _, _, _, ref block), .. }) => Some(block),
+            Node::NodeItem(&Item { node: ItemFn(_, _, _, _, _, ref expr), .. }) => {
+                match expr.node {
+                    ExprBlock(ref block) => Some(block),
+                    _ => None,
+                }
+            }
             _ => None,
         }
     } else {
@@ -696,8 +701,9 @@ pub fn camel_case_from(s: &str) -> usize {
 /// Convenience function to get the return type of a function
 pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: NodeId) -> ty::Ty<'tcx> {
     let parameter_env = ty::ParameterEnvironment::for_item(cx.tcx, fn_item);
-    let fn_sig = cx.tcx.node_id_to_type(fn_item).fn_sig().subst(cx.tcx, parameter_env.free_substs);
-    let fn_sig = cx.tcx.liberate_late_bound_regions(parameter_env.free_id_outlive, &fn_sig);
+    let fn_def_id = cx.tcx.map.local_def_id(fn_item);
+    let fn_sig = cx.tcx.item_type(fn_def_id).fn_sig();
+    let fn_sig = cx.tcx.liberate_late_bound_regions(parameter_env.free_id_outlive, fn_sig);
     fn_sig.output
 }
 
diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs
index 06d3d040ccd..f847c397da8 100644
--- a/clippy_lints/src/vec.rs
+++ b/clippy_lints/src/vec.rs
@@ -36,7 +36,7 @@ impl LateLintPass for Pass {
     fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
         // search for `&vec![_]` expressions where the adjusted type is `&[_]`
         if_let_chain!{[
-            let ty::TypeVariants::TyRef(_, ref ty) = cx.tcx.expr_ty_adjusted(expr).sty,
+            let ty::TypeVariants::TyRef(_, ref ty) = cx.tcx.tables().expr_ty_adjusted(expr).sty,
             let ty::TypeVariants::TySlice(..) = ty.ty.sty,
             let ExprAddrOf(_, ref addressee) = expr.node,
             let Some(vec_args) = higher::vec_macro(cx, addressee),
@@ -48,7 +48,7 @@ impl LateLintPass for Pass {
         if_let_chain!{[
             let Some((_, arg, _)) = higher::for_loop(expr),
             let Some(vec_args) = higher::vec_macro(cx, arg),
-            is_copy(cx, vec_type(cx.tcx.expr_ty_adjusted(arg)), cx.tcx.map.get_parent(expr.id)),
+            is_copy(cx, vec_type(cx.tcx.tables().expr_ty_adjusted(arg)), cx.tcx.map.get_parent(expr.id)),
         ], {
             // report the error around the `vec!` not inside `<std macros>:`
             let span = cx.sess().codemap().source_callsite(arg.span);
diff --git a/tests/compile-fail/copies.rs b/tests/compile-fail/copies.rs
index d9eb842d680..3e65d1aeec4 100644
--- a/tests/compile-fail/copies.rs
+++ b/tests/compile-fail/copies.rs
@@ -1,5 +1,4 @@
 #![feature(plugin, inclusive_range_syntax)]
-#![feature(dotdot_in_tuple_patterns)]
 #![plugin(clippy)]
 
 #![allow(dead_code, no_effect, unnecessary_operation)]
diff --git a/tests/compile-fail/diverging_sub_expression.rs b/tests/compile-fail/diverging_sub_expression.rs
index f9a6e66da42..e7daebfdf2f 100644
--- a/tests/compile-fail/diverging_sub_expression.rs
+++ b/tests/compile-fail/diverging_sub_expression.rs
@@ -1,6 +1,7 @@
 #![feature(plugin, never_type)]
 #![plugin(clippy)]
 #![deny(diverging_sub_expression)]
+#![allow(match_same_arms, logic_bug)]
 
 #[allow(empty_loop)]
 fn diverge() -> ! { loop {} }
@@ -16,8 +17,6 @@ fn main() {
     let b = true;
     b || diverge(); //~ ERROR sub-expression diverges
     b || A.foo(); //~ ERROR sub-expression diverges
-    let y = (5, diverge(), 6); //~ ERROR sub-expression diverges
-    println!("{}", y.1);
 }
 
 #[allow(dead_code, unused_variables)]
@@ -26,16 +25,16 @@ fn foobar() {
         let x = match 5 {
             4 => return,
             5 => continue,
-            6 => (println!("foo"), return), //~ ERROR sub-expression diverges
-            7 => (println!("bar"), continue), //~ ERROR sub-expression diverges
+            6 => true || return, //~ ERROR sub-expression diverges
+            7 => true || continue, //~ ERROR sub-expression diverges
             8 => break,
             9 => diverge(),
-            3 => (println!("moo"), diverge()), //~ ERROR sub-expression diverges
+            3 => true || diverge(), //~ ERROR sub-expression diverges
             10 => match 42 {
                 99 => return,
-                _ => ((), panic!("boo")),
+                _ => true || panic!("boo"),
             },
-            _ => (println!("boo"), break), //~ ERROR sub-expression diverges
+            _ => true || break, //~ ERROR sub-expression diverges
         };
     }
 }
diff --git a/tests/compile-fail/eq_op.rs b/tests/compile-fail/eq_op.rs
index 768eadd00eb..f0502a71796 100644
--- a/tests/compile-fail/eq_op.rs
+++ b/tests/compile-fail/eq_op.rs
@@ -43,8 +43,8 @@ fn main() {
     true || true; //~ERROR equal expressions
     //~|ERROR this boolean expression can be simplified
 
-    let a: u32 = unimplemented!();
-    let b: u32 = unimplemented!();
+    let a: u32 = 0;
+    let b: u32 = 0;
 
     a == b && b == a; //~ERROR equal expressions
     //~|ERROR this boolean expression can be simplified