rustup to 2017-01-12

This commit is contained in:
Oliver Schneider 2017-01-13 17:04:56 +01:00
parent d93b96949d
commit d944d7df9a
No known key found for this signature in database
GPG Key ID: 56D6EEA0FC67AC46
56 changed files with 245 additions and 239 deletions

View File

@ -1,6 +1,9 @@
# Change Log # Change Log
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## 0.0.108 — 2017-01-12
* Update to *rustc 1.16.0-nightly (2782e8f8f 2017-01-12)*
## 0.0.107 — 2017-01-11 ## 0.0.107 — 2017-01-11
* Update regex dependency * Update regex dependency
* Fix FP when matching `&&mut` by `&ref` * Fix FP when matching `&&mut` by `&ref`

View File

@ -1,6 +1,6 @@
[package] [package]
name = "clippy" name = "clippy"
version = "0.0.107" version = "0.0.108"
authors = [ authors = [
"Manish Goregaokar <manishsmail@gmail.com>", "Manish Goregaokar <manishsmail@gmail.com>",
"Andre Bogus <bogusandre@gmail.com>", "Andre Bogus <bogusandre@gmail.com>",
@ -25,7 +25,7 @@ test = false
[dependencies] [dependencies]
# begin automatic update # begin automatic update
clippy_lints = { version = "0.0.107", path = "clippy_lints" } clippy_lints = { version = "0.0.108", path = "clippy_lints" }
# end automatic update # end automatic update
[dev-dependencies] [dev-dependencies]

View File

@ -1,7 +1,7 @@
[package] [package]
name = "clippy_lints" name = "clippy_lints"
# begin automatic update # begin automatic update
version = "0.0.107" version = "0.0.108"
# end automatic update # end automatic update
authors = [ authors = [
"Manish Goregaokar <manishsmail@gmail.com>", "Manish Goregaokar <manishsmail@gmail.com>",

View File

@ -59,7 +59,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
hir::BiShr | hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => return, hir::BiShr | hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => return,
_ => (), _ => (),
} }
let (l_ty, r_ty) = (cx.tcx.tables().expr_ty(l), cx.tcx.tables().expr_ty(r)); let (l_ty, r_ty) = (cx.tables.expr_ty(l), cx.tables.expr_ty(r));
if l_ty.is_integral() && r_ty.is_integral() { if l_ty.is_integral() && r_ty.is_integral() {
span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
self.span = Some(expr.span); self.span = Some(expr.span);
@ -69,7 +69,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
} }
}, },
hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => { hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => {
let ty = cx.tcx.tables().expr_ty(arg); let ty = cx.tables.expr_ty(arg);
if ty.is_integral() { if ty.is_integral() {
span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
self.span = Some(expr.span); self.span = Some(expr.span);

View File

@ -2,7 +2,7 @@ use rustc::lint::*;
use rustc::middle::const_val::ConstVal; use rustc::middle::const_val::ConstVal;
use rustc::ty; use rustc::ty;
use rustc_const_eval::EvalHint::ExprTypeChecked; use rustc_const_eval::EvalHint::ExprTypeChecked;
use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::ConstContext;
use rustc_const_math::ConstInt; use rustc_const_math::ConstInt;
use rustc::hir; use rustc::hir;
use syntax::ast::RangeLimits; use syntax::ast::RangeLimits;
@ -59,12 +59,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIndexing {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr) {
if let hir::ExprIndex(ref array, ref index) = e.node { if let hir::ExprIndex(ref array, ref index) = e.node {
// Array with known size can be checked statically // Array with known size can be checked statically
let ty = cx.tcx.tables().expr_ty(array); let ty = cx.tables.expr_ty(array);
if let ty::TyArray(_, size) = ty.sty { if let ty::TyArray(_, size) = ty.sty {
let size = ConstInt::Infer(size as u128); let size = ConstInt::Infer(size as u128);
let constcx = ConstContext::with_tables(cx.tcx, cx.tables);
// Index is a constant uint // Index is a constant uint
let const_index = eval_const_expr_partial(cx.tcx, index, ExprTypeChecked, None); let const_index = constcx.eval(index, ExprTypeChecked);
if let Ok(ConstVal::Integral(const_index)) = const_index { if let Ok(ConstVal::Integral(const_index)) = const_index {
if size <= const_index { if size <= const_index {
utils::span_lint(cx, OUT_OF_BOUNDS_INDEXING, e.span, "const index is out of bounds"); utils::span_lint(cx, OUT_OF_BOUNDS_INDEXING, e.span, "const index is out of bounds");
@ -76,10 +77,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIndexing {
// Index is a constant range // Index is a constant range
if let Some(range) = higher::range(index) { if let Some(range) = higher::range(index) {
let start = range.start let start = range.start
.map(|start| eval_const_expr_partial(cx.tcx, start, ExprTypeChecked, None)) .map(|start| constcx.eval(start, ExprTypeChecked))
.map(|v| v.ok()); .map(|v| v.ok());
let end = range.end let end = range.end
.map(|end| eval_const_expr_partial(cx.tcx, end, ExprTypeChecked, None)) .map(|end| constcx.eval(end, ExprTypeChecked))
.map(|v| v.ok()); .map(|v| v.ok());
if let Some((start, end)) = to_const_range(start, end, range.limits, size) { if let Some((start, end)) = to_const_range(start, end, range.limits, size) {

View File

@ -82,11 +82,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
if let hir::ExprBinary(binop, ref l, ref r) = rhs.node { if let hir::ExprBinary(binop, ref l, ref r) = rhs.node {
if op.node == binop.node { if op.node == binop.node {
let lint = |assignee: &hir::Expr, rhs: &hir::Expr| { let lint = |assignee: &hir::Expr, rhs: &hir::Expr| {
let ty = cx.tcx.tables().expr_ty(assignee); let ty = cx.tables.expr_ty(assignee);
if ty.walk_shallow().next().is_some() { if ty.walk_shallow().next().is_some() {
return; // implements_trait does not work with generics return; // implements_trait does not work with generics
} }
let rty = cx.tcx.tables().expr_ty(rhs); let rty = cx.tables.expr_ty(rhs);
if rty.walk_shallow().next().is_some() { if rty.walk_shallow().next().is_some() {
return; // implements_trait does not work with generics return; // implements_trait does not work with generics
} }
@ -116,12 +116,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
}, },
hir::ExprAssign(ref assignee, ref e) => { hir::ExprAssign(ref assignee, ref e) => {
if let hir::ExprBinary(op, ref l, ref r) = e.node { if let hir::ExprBinary(op, ref l, ref r) = e.node {
#[allow(cyclomatic_complexity)]
let lint = |assignee: &hir::Expr, rhs: &hir::Expr| { let lint = |assignee: &hir::Expr, rhs: &hir::Expr| {
let ty = cx.tcx.tables().expr_ty(assignee); let ty = cx.tables.expr_ty(assignee);
if ty.walk_shallow().next().is_some() { if ty.walk_shallow().next().is_some() {
return; // implements_trait does not work with generics return; // implements_trait does not work with generics
} }
let rty = cx.tcx.tables().expr_ty(rhs); let rty = cx.tables.expr_ty(rhs);
if rty.walk_shallow().next().is_some() { if rty.walk_shallow().next().is_some() {
return; // implements_trait does not work with generics return; // implements_trait does not work with generics
} }

View File

@ -3,10 +3,11 @@
use reexport::*; use reexport::*;
use rustc::lint::*; use rustc::lint::*;
use rustc::hir::*; use rustc::hir::*;
use rustc::ty;
use semver::Version; use semver::Version;
use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind}; use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
use syntax::codemap::Span; use syntax::codemap::Span;
use utils::{in_macro, match_def_path, resolve_node, paths, span_lint, span_lint_and_then, snippet_opt}; use utils::{in_macro, match_def_path, paths, span_lint, span_lint_and_then, snippet_opt};
/// **What it does:** Checks for items annotated with `#[inline(always)]`, /// **What it does:** Checks for items annotated with `#[inline(always)]`,
/// unless the annotated function is empty or simply panics. /// unless the annotated function is empty or simply panics.
@ -102,7 +103,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
} }
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
if is_relevant_item(cx, item) { if is_relevant_item(cx.tcx, item) {
check_attrs(cx, item.span, &item.name, &item.attrs) check_attrs(cx, item.span, &item.name, &item.attrs)
} }
match item.node { match item.node {
@ -143,64 +144,66 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
} }
fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem) { fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem) {
if is_relevant_impl(cx, item) { if is_relevant_impl(cx.tcx, item) {
check_attrs(cx, item.span, &item.name, &item.attrs) check_attrs(cx, item.span, &item.name, &item.attrs)
} }
} }
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem) { fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem) {
if is_relevant_trait(cx, item) { if is_relevant_trait(cx.tcx, item) {
check_attrs(cx, item.span, &item.name, &item.attrs) check_attrs(cx, item.span, &item.name, &item.attrs)
} }
} }
} }
fn is_relevant_item(cx: &LateContext, item: &Item) -> bool { fn is_relevant_item(tcx: ty::TyCtxt, item: &Item) -> bool {
if let ItemFn(_, _, _, _, _, eid) = item.node { if let ItemFn(_, _, _, _, _, eid) = item.node {
is_relevant_expr(cx, &cx.tcx.map.body(eid).value) is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.map.body(eid).value)
} else { } else {
false false
} }
} }
fn is_relevant_impl(cx: &LateContext, item: &ImplItem) -> bool { fn is_relevant_impl(tcx: ty::TyCtxt, item: &ImplItem) -> bool {
match item.node { match item.node {
ImplItemKind::Method(_, eid) => is_relevant_expr(cx, &cx.tcx.map.body(eid).value), ImplItemKind::Method(_, eid) => is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.map.body(eid).value),
_ => false, _ => false,
} }
} }
fn is_relevant_trait(cx: &LateContext, item: &TraitItem) -> bool { fn is_relevant_trait(tcx: ty::TyCtxt, item: &TraitItem) -> bool {
match item.node { match item.node {
TraitItemKind::Method(_, TraitMethod::Required(_)) => true, TraitItemKind::Method(_, TraitMethod::Required(_)) => true,
TraitItemKind::Method(_, TraitMethod::Provided(eid)) => is_relevant_expr(cx, &cx.tcx.map.body(eid).value), TraitItemKind::Method(_, TraitMethod::Provided(eid)) => {
is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.map.body(eid).value)
},
_ => false, _ => false,
} }
} }
fn is_relevant_block(cx: &LateContext, block: &Block) -> bool { fn is_relevant_block(tcx: ty::TyCtxt, tables: &ty::Tables, block: &Block) -> bool {
for stmt in &block.stmts { for stmt in &block.stmts {
match stmt.node { match stmt.node {
StmtDecl(_, _) => return true, StmtDecl(_, _) => return true,
StmtExpr(ref expr, _) | StmtExpr(ref expr, _) |
StmtSemi(ref expr, _) => { StmtSemi(ref expr, _) => {
return is_relevant_expr(cx, expr); return is_relevant_expr(tcx, tables, expr);
}, },
} }
} }
block.expr.as_ref().map_or(false, |e| is_relevant_expr(cx, e)) block.expr.as_ref().map_or(false, |e| is_relevant_expr(tcx, tables, e))
} }
fn is_relevant_expr(cx: &LateContext, expr: &Expr) -> bool { fn is_relevant_expr(tcx: ty::TyCtxt, tables: &ty::Tables, expr: &Expr) -> bool {
match expr.node { match expr.node {
ExprBlock(ref block) => is_relevant_block(cx, block), ExprBlock(ref block) => is_relevant_block(tcx, tables, block),
ExprRet(Some(ref e)) => is_relevant_expr(cx, e), ExprRet(Some(ref e)) => is_relevant_expr(tcx, tables, e),
ExprRet(None) | ExprRet(None) |
ExprBreak(_, None) => false, ExprBreak(_, None) => false,
ExprCall(ref path_expr, _) => { ExprCall(ref path_expr, _) => {
if let ExprPath(ref qpath) = path_expr.node { if let ExprPath(ref qpath) = path_expr.node {
let fun_id = resolve_node(cx, qpath, path_expr.id).def_id(); let fun_id = tables.qpath_def(qpath, path_expr.id).def_id();
!match_def_path(cx, fun_id, &paths::BEGIN_PANIC) !match_def_path(tcx, fun_id, &paths::BEGIN_PANIC)
} else { } else {
true true
} }

View File

@ -246,9 +246,9 @@ fn fetch_int_literal(cx: &LateContext, lit: &Expr) -> Option<u128> {
} }
}, },
ExprPath(ref qpath) => { ExprPath(ref qpath) => {
let def = cx.tcx.tables().qpath_def(qpath, lit.id); let def = cx.tables.qpath_def(qpath, lit.id);
if let Def::Const(def_id) = def { if let Def::Const(def_id) = def {
lookup_const_by_id(cx.tcx, def_id, None).and_then(|(l, _ty)| fetch_int_literal(cx, l)) lookup_const_by_id(cx.tcx, def_id, None).and_then(|(l, _tab, _ty)| fetch_int_literal(cx, l))
} else { } else {
None None
} }

View File

@ -1,8 +1,8 @@
use rustc::lint::{LintArray, LateLintPass, LateContext, LintPass}; use rustc::lint::{LintArray, LateLintPass, LateContext, LintPass};
use rustc::hir::*; use rustc::hir::*;
use rustc::hir::intravisit::*; use rustc::hir::intravisit::*;
use syntax::ast::{LitKind, DUMMY_NODE_ID}; use syntax::ast::{LitKind, DUMMY_NODE_ID, NodeId};
use syntax::codemap::{DUMMY_SP, dummy_spanned}; use syntax::codemap::{DUMMY_SP, dummy_spanned, Span};
use syntax::util::ThinVec; use syntax::util::ThinVec;
use utils::{span_lint_and_then, in_macro, snippet_opt, SpanlessEq}; use utils::{span_lint_and_then, in_macro, snippet_opt, SpanlessEq};
@ -54,8 +54,16 @@ impl LintPass for NonminimalBool {
} }
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonminimalBool { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonminimalBool {
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { fn check_fn(
NonminimalBoolVisitor { cx: cx }.visit_item(item) &mut self,
cx: &LateContext<'a, 'tcx>,
_: intravisit::FnKind<'tcx>,
_: &'tcx FnDecl,
body: &'tcx Body,
_: Span,
_: NodeId
) {
NonminimalBoolVisitor { cx: cx }.visit_body(body)
} }
} }
@ -394,7 +402,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
match e.node { match e.node {
ExprBinary(binop, _, _) if binop.node == BiOr || binop.node == BiAnd => self.bool_expr(e), ExprBinary(binop, _, _) if binop.node == BiOr || binop.node == BiAnd => self.bool_expr(e),
ExprUnary(UnNot, ref inner) => { ExprUnary(UnNot, ref inner) => {
if self.cx.tcx.tables.borrow().node_types[&inner.id].is_bool() { if self.cx.tables.node_types[&inner.id].is_bool() {
self.bool_expr(e); self.bool_expr(e);
} else { } else {
walk_expr(self, e); walk_expr(self, e);
@ -404,6 +412,6 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
} }
} }
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::All(&self.cx.tcx.map) NestedVisitorMap::None
} }
} }

View File

@ -295,15 +295,14 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
/// lookup a possibly constant expression from a ExprPath /// lookup a possibly constant expression from a ExprPath
fn fetch_path(&mut self, qpath: &QPath, id: NodeId) -> Option<Constant> { fn fetch_path(&mut self, qpath: &QPath, id: NodeId) -> Option<Constant> {
if let Some(lcx) = self.lcx { if let Some(lcx) = self.lcx {
let def = lcx.tcx.tables().qpath_def(qpath, id); let def = lcx.tables.qpath_def(qpath, id);
match def { match def {
Def::Const(def_id) | Def::Const(def_id) |
Def::AssociatedConst(def_id) => { Def::AssociatedConst(def_id) => {
let substs = Some(lcx.tcx let substs = Some(lcx.tables
.tables()
.node_id_item_substs(id) .node_id_item_substs(id)
.unwrap_or_else(|| lcx.tcx.intern_substs(&[]))); .unwrap_or_else(|| lcx.tcx.intern_substs(&[])));
if let Some((const_expr, _ty)) = lookup_const_by_id(lcx.tcx, def_id, substs) { if let Some((const_expr, _tab, _ty)) = lookup_const_by_id(lcx.tcx, def_id, substs) {
let ret = self.expr(const_expr); let ret = self.expr(const_expr);
if ret.is_some() { if ret.is_some() {
self.needed_resolution = true; self.needed_resolution = true;

View File

@ -263,7 +263,7 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap<Interned
}, },
PatKind::Binding(_, _, ref ident, ref as_pat) => { PatKind::Binding(_, _, ref ident, ref as_pat) => {
if let Entry::Vacant(v) = map.entry(ident.node.as_str()) { if let Entry::Vacant(v) = map.entry(ident.node.as_str()) {
v.insert(cx.tcx.tables().pat_ty(pat)); v.insert(cx.tables.pat_ty(pat));
} }
if let Some(ref as_pat) = *as_pat { if let Some(ref as_pat) = *as_pat {
bindings_impl(cx, as_pat, map); bindings_impl(cx, as_pat, map);

View File

@ -2,11 +2,10 @@
use rustc::cfg::CFG; use rustc::cfg::CFG;
use rustc::lint::*; use rustc::lint::*;
use rustc::ty;
use rustc::hir::*; use rustc::hir::*;
use rustc::ty;
use rustc::hir::intravisit::{Visitor, walk_expr, NestedVisitorMap}; use rustc::hir::intravisit::{Visitor, walk_expr, NestedVisitorMap};
use syntax::ast::Attribute; use syntax::ast::{Attribute, NodeId};
use syntax::attr;
use syntax::codemap::Span; use syntax::codemap::Span;
use utils::{in_macro, LimitStack, span_help_and_lint, paths, match_type}; use utils::{in_macro, LimitStack, span_help_and_lint, paths, match_type};
@ -64,7 +63,7 @@ impl CyclomaticComplexity {
}; };
helper.visit_expr(expr); helper.visit_expr(expr);
let CCHelper { match_arms, divergence, short_circuits, returns, .. } = helper; let CCHelper { match_arms, divergence, short_circuits, returns, .. } = helper;
let ret_ty = cx.tcx.tables().node_id_to_type(expr.id); let ret_ty = cx.tables.node_id_to_type(expr.id);
let ret_adjust = if match_type(cx, ret_ty, &paths::RESULT) { let ret_adjust = if match_type(cx, ret_ty, &paths::RESULT) {
returns returns
} else { } else {
@ -91,23 +90,18 @@ impl CyclomaticComplexity {
} }
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CyclomaticComplexity { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CyclomaticComplexity {
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { fn check_fn(
if let ItemFn(_, _, _, _, _, eid) = item.node { &mut self,
if !attr::contains_name(&item.attrs, "test") { cx: &LateContext<'a, 'tcx>,
self.check(cx, &cx.tcx.map.body(eid).value, item.span); _: intravisit::FnKind<'tcx>,
} _: &'tcx FnDecl,
} body: &'tcx Body,
} span: Span,
node_id: NodeId
fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem) { ) {
if let ImplItemKind::Method(_, eid) = item.node { let def_id = cx.tcx.map.local_def_id(node_id);
self.check(cx, &cx.tcx.map.body(eid).value, item.span); if !cx.tcx.has_attr(def_id, "test") {
} self.check(cx, &body.value, span);
}
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem) {
if let TraitItemKind::Method(_, TraitMethod::Provided(eid)) = item.node {
self.check(cx, &cx.tcx.map.body(eid).value, item.span);
} }
} }
@ -139,7 +133,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> {
}, },
ExprCall(ref callee, _) => { ExprCall(ref callee, _) => {
walk_expr(self, e); walk_expr(self, e);
let ty = self.cx.tcx.tables().node_id_to_type(callee.id); let ty = self.cx.tables.node_id_to_type(callee.id);
match ty.sty { match ty.sty {
ty::TyFnDef(_, _, ty) | ty::TyFnDef(_, _, ty) |
ty::TyFnPtr(ty) if ty.sig.skip_binder().output().sty == ty::TyNever => { ty::TyFnPtr(ty) if ty.sig.skip_binder().output().sty == ty::TyNever => {

View File

@ -61,14 +61,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
let ExprPath(ref qpath) = path.node, let ExprPath(ref qpath) = path.node,
args.len() == 1, args.len() == 1,
], { ], {
let def_id = cx.tcx.tables().qpath_def(qpath, path.id).def_id(); let def_id = cx.tables.qpath_def(qpath, path.id).def_id();
let lint; let lint;
let msg; let msg;
if match_def_path(cx, def_id, &paths::DROP) { if match_def_path(cx.tcx, def_id, &paths::DROP) {
lint = DROP_REF; lint = DROP_REF;
msg = "call to `std::mem::drop` with a reference argument. \ msg = "call to `std::mem::drop` with a reference argument. \
Dropping a reference does nothing"; Dropping a reference does nothing";
} else if match_def_path(cx, def_id, &paths::MEM_FORGET) { } else if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) {
lint = FORGET_REF; lint = FORGET_REF;
msg = "call to `std::mem::forget` with a reference argument. \ msg = "call to `std::mem::forget` with a reference argument. \
Forgetting a reference does nothing"; Forgetting a reference does nothing";
@ -76,7 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
return; return;
} }
let arg = &args[0]; let arg = &args[0];
let arg_ty = cx.tcx.tables().expr_ty(arg); let arg_ty = cx.tables.expr_ty(arg);
if let ty::TyRef(..) = arg_ty.sty { if let ty::TyRef(..) = arg_ty.sty {
span_note_and_lint(cx, span_note_and_lint(cx,
lint, lint,

View File

@ -89,7 +89,7 @@ fn check_cond<'a, 'tcx, 'b>(
let ExprAddrOf(_, ref key) = params[1].node let ExprAddrOf(_, ref key) = params[1].node
], { ], {
let map = &params[0]; let map = &params[0];
let obj_ty = walk_ptrs_ty(cx.tcx.tables().expr_ty(map)); let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(map));
return if match_type(cx, obj_ty, &paths::BTREEMAP) { return if match_type(cx, obj_ty, &paths::BTREEMAP) {
Some(("BTreeMap", map, key)) Some(("BTreeMap", map, key))

View File

@ -44,10 +44,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnportableVariant {
let variant = &var.node; let variant = &var.node;
if let Some(body_id) = variant.disr_expr { if let Some(body_id) = variant.disr_expr {
use rustc_const_eval::*; use rustc_const_eval::*;
let bad = match eval_const_expr_partial(cx.tcx, let constcx = ConstContext::new(cx.tcx, body_id);
&cx.tcx.map.body(body_id).value, let bad = match constcx.eval(&cx.tcx.map.body(body_id).value, EvalHint::ExprTypeChecked) {
EvalHint::ExprTypeChecked,
None) {
Ok(ConstVal::Integral(Usize(Us64(i)))) => i as u32 as u64 != i, Ok(ConstVal::Integral(Usize(Us64(i)))) => i as u32 as u64 != i,
Ok(ConstVal::Integral(Isize(Is64(i)))) => i as i32 as i64 != i, Ok(ConstVal::Integral(Isize(Is64(i)))) => i as i32 as i64 != i,
_ => false, _ => false,

View File

@ -49,6 +49,7 @@ fn is_non_trait_box(ty: ty::Ty) -> bool {
struct EscapeDelegate<'a, 'tcx: 'a> { struct EscapeDelegate<'a, 'tcx: 'a> {
set: NodeSet, set: NodeSet,
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::Tables<'tcx>,
target: TargetDataLayout, target: TargetDataLayout,
too_large_for_stack: u64, too_large_for_stack: u64,
} }
@ -67,19 +68,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
_: &'tcx FnDecl, _: &'tcx FnDecl,
body: &'tcx Body, body: &'tcx Body,
_: Span, _: Span,
id: NodeId _id: NodeId
) { ) {
// we store the infcx because it is expensive to recreate // we store the infcx because it is expensive to recreate
// the context each time. // the context each time.
let mut v = EscapeDelegate { let mut v = EscapeDelegate {
set: NodeSet(), set: NodeSet(),
tcx: cx.tcx, tcx: cx.tcx,
tables: cx.tables,
target: TargetDataLayout::parse(cx.sess()), target: TargetDataLayout::parse(cx.sess()),
too_large_for_stack: self.too_large_for_stack, too_large_for_stack: self.too_large_for_stack,
}; };
let param_env = ty::ParameterEnvironment::for_item(cx.tcx, id);
let infcx = cx.tcx.borrowck_fake_infer_ctxt(param_env); let infcx = cx.tcx.borrowck_fake_infer_ctxt(body.id());
{ {
let mut vis = ExprUseVisitor::new(&mut v, &infcx); let mut vis = ExprUseVisitor::new(&mut v, &infcx);
vis.consume_body(body); vis.consume_body(body);
@ -161,9 +162,7 @@ impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
if let Categorization::Local(lid) = cmt.cat { if let Categorization::Local(lid) = cmt.cat {
if self.set.contains(&lid) { if self.set.contains(&lid) {
if let Some(&Adjust::DerefRef { autoderefs, .. }) = if let Some(&Adjust::DerefRef { autoderefs, .. }) =
self.tcx self.tables
.tables
.borrow()
.adjustments .adjustments
.get(&borrow_id) .get(&borrow_id)
.map(|a| &a.kind) { .map(|a| &a.kind) {
@ -178,9 +177,7 @@ impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
} else if LoanCause::AddrOf == loan_cause { } else if LoanCause::AddrOf == loan_cause {
// &x // &x
if let Some(&Adjust::DerefRef { autoderefs, .. }) = if let Some(&Adjust::DerefRef { autoderefs, .. }) =
self.tcx self.tables
.tables
.borrow()
.adjustments .adjustments
.get(&self.tcx .get(&self.tcx
.map .map
@ -209,7 +206,7 @@ impl<'a, 'tcx: 'a> EscapeDelegate<'a, 'tcx> {
// overflows. // overflows.
match ty.sty { match ty.sty {
ty::TyBox(inner) => { ty::TyBox(inner) => {
self.tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| { self.tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
if let Ok(layout) = inner.layout(&infcx) { if let Ok(layout) = inner.layout(&infcx) {
let size = layout.size(&self.target); let size = layout.size(&self.target);
size.bytes() > self.too_large_for_stack size.bytes() > self.too_large_for_stack

View File

@ -61,7 +61,7 @@ fn check_closure(cx: &LateContext, expr: &Expr) {
// Are the expression or the arguments type-adjusted? Then we need the closure // Are the expression or the arguments type-adjusted? Then we need the closure
return; return;
} }
let fn_ty = cx.tcx.tables().expr_ty(caller); let fn_ty = cx.tables.expr_ty(caller);
match fn_ty.sty { match fn_ty.sty {
// Is it an unsafe function? They don't implement the closure traits // Is it an unsafe function? They don't implement the closure traits
ty::TyFnDef(_, _, fn_ty) | ty::TyFnDef(_, _, fn_ty) |

View File

@ -65,7 +65,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence {
if let ExprPath(ref qpath) = lhs.node { if let ExprPath(ref qpath) = lhs.node {
if let QPath::Resolved(_, ref path) = *qpath { if let QPath::Resolved(_, ref path) = *qpath {
if path.segments.len() == 1 { if path.segments.len() == 1 {
let var = cx.tcx.tables().qpath_def(qpath, lhs.id).def_id(); let var = cx.tables.qpath_def(qpath, lhs.id).def_id();
let mut visitor = ReadVisitor { let mut visitor = ReadVisitor {
cx: cx, cx: cx,
var: var, var: var,
@ -126,7 +126,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
match e.node { match e.node {
ExprAgain(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e), ExprAgain(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e),
ExprCall(ref func, _) => { ExprCall(ref func, _) => {
match self.cx.tcx.tables().expr_ty(func).sty { match self.cx.tables.expr_ty(func).sty {
ty::TyFnDef(_, _, fn_ty) | ty::TyFnDef(_, _, fn_ty) |
ty::TyFnPtr(fn_ty) => { ty::TyFnPtr(fn_ty) => {
if let ty::TyNever = self.cx.tcx.erase_late_bound_regions(&fn_ty.sig).output().sty { if let ty::TyNever = self.cx.tcx.erase_late_bound_regions(&fn_ty.sig).output().sty {
@ -138,7 +138,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
}, },
ExprMethodCall(..) => { ExprMethodCall(..) => {
let method_call = ty::MethodCall::expr(e.id); let method_call = ty::MethodCall::expr(e.id);
let borrowed_table = self.cx.tcx.tables.borrow(); let borrowed_table = self.cx.tables;
let method_type = borrowed_table.method_map.get(&method_call).expect("This should never happen."); let method_type = borrowed_table.method_map.get(&method_call).expect("This should never happen.");
let result_ty = method_type.ty.fn_ret(); let result_ty = method_type.ty.fn_ret();
if let ty::TyNever = self.cx.tcx.erase_late_bound_regions(&result_ty).sty { if let ty::TyNever = self.cx.tcx.erase_late_bound_regions(&result_ty).sty {
@ -302,7 +302,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
match expr.node { match expr.node {
ExprPath(ref qpath) => { ExprPath(ref qpath) => {
if let QPath::Resolved(None, ref path) = *qpath { if let QPath::Resolved(None, ref path) = *qpath {
if path.segments.len() == 1 && self.cx.tcx.tables().qpath_def(qpath, expr.id).def_id() == self.var { if path.segments.len() == 1 && self.cx.tables.qpath_def(qpath, expr.id).def_id() == self.var {
if is_in_assignment_position(self.cx, expr) { if is_in_assignment_position(self.cx, expr) {
// This is a write, not a read. // This is a write, not a read.
} else { } else {

View File

@ -47,7 +47,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
if_let_chain!{[ if_let_chain!{[
let ExprPath(ref qpath) = fun.node, let ExprPath(ref qpath) = fun.node,
args.len() == 2, args.len() == 2,
match_def_path(cx, resolve_node(cx, qpath, fun.id).def_id(), &paths::FMT_ARGUMENTS_NEWV1), match_def_path(cx.tcx, resolve_node(cx, qpath, fun.id).def_id(), &paths::FMT_ARGUMENTS_NEWV1),
// ensure the format string is `"{..}"` with only one argument and no text // ensure the format string is `"{..}"` with only one argument and no text
check_static_str(cx, &args[0]), check_static_str(cx, &args[0]),
// ensure the format argument is `{}` ie. Display with no fancy option // ensure the format argument is `{}` ie. Display with no fancy option
@ -128,9 +128,9 @@ fn check_arg_is_display(cx: &LateContext, expr: &Expr) -> bool {
let ExprCall(_, ref args) = exprs[0].node, let ExprCall(_, ref args) = exprs[0].node,
args.len() == 2, args.len() == 2,
let ExprPath(ref qpath) = args[1].node, let ExprPath(ref qpath) = args[1].node,
match_def_path(cx, resolve_node(cx, qpath, args[1].id).def_id(), &paths::DISPLAY_FMT_METHOD), match_def_path(cx.tcx, resolve_node(cx, qpath, args[1].id).def_id(), &paths::DISPLAY_FMT_METHOD),
], { ], {
let ty = walk_ptrs_ty(cx.tcx.tables().pat_ty(&pat[0])); let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
return ty.sty == TypeVariants::TyStr || match_type(cx, ty, &paths::STRING); return ty.sty == TypeVariants::TyStr || match_type(cx, ty, &paths::STRING);
}} }}

View File

@ -175,7 +175,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) { fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
match expr.node { match expr.node {
hir::ExprCall(ref f, ref args) => { hir::ExprCall(ref f, ref args) => {
let ty = self.cx.tcx.tables().expr_ty(f); let ty = self.cx.tables.expr_ty(f);
if type_is_unsafe_function(ty) { if type_is_unsafe_function(ty) {
for arg in args { for arg in args {
@ -185,7 +185,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
}, },
hir::ExprMethodCall(_, _, ref args) => { hir::ExprMethodCall(_, _, ref args) => {
let method_call = ty::MethodCall::expr(expr.id); let method_call = ty::MethodCall::expr(expr.id);
let base_type = self.cx.tcx.tables.borrow().method_map[&method_call].ty; let base_type = self.cx.tables.method_map[&method_call].ty;
if type_is_unsafe_function(base_type) { if type_is_unsafe_function(base_type) {
for arg in args { for arg in args {
@ -207,7 +207,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
impl<'a, 'tcx: 'a> DerefVisitor<'a, 'tcx> { impl<'a, 'tcx: 'a> DerefVisitor<'a, 'tcx> {
fn check_arg(&self, ptr: &hir::Expr) { fn check_arg(&self, ptr: &hir::Expr) {
if let hir::ExprPath(ref qpath) = ptr.node { if let hir::ExprPath(ref qpath) = ptr.node {
let def = self.cx.tcx.tables().qpath_def(qpath, ptr.id); let def = self.cx.tables.qpath_def(qpath, ptr.id);
if self.ptrs.contains(&def.def_id()) { if self.ptrs.contains(&def.def_id()) {
span_lint(self.cx, span_lint(self.cx,
NOT_UNSAFE_PTR_ARG_DEREF, NOT_UNSAFE_PTR_ARG_DEREF,

View File

@ -203,7 +203,7 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool {
}) })
} }
let ty = &walk_ptrs_ty(cx.tcx.tables().expr_ty(expr)); let ty = &walk_ptrs_ty(cx.tables.expr_ty(expr));
match ty.sty { match ty.sty {
ty::TyDynamic(..) => { ty::TyDynamic(..) => {
cx.tcx cx.tcx

View File

@ -137,7 +137,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UsedVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) { fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
if_let_chain! {[ if_let_chain! {[
let hir::ExprPath(ref qpath) = expr.node, let hir::ExprPath(ref qpath) = expr.node,
self.id == self.cx.tcx.tables().qpath_def(qpath, expr.id).def_id(), self.id == self.cx.tables.qpath_def(qpath, expr.id).def_id(),
], { ], {
self.used = true; self.used = true;
return; return;
@ -160,7 +160,7 @@ fn check_assign<'a, 'tcx>(
let hir::StmtSemi(ref expr, _) = expr.node, let hir::StmtSemi(ref expr, _) = expr.node,
let hir::ExprAssign(ref var, ref value) = expr.node, let hir::ExprAssign(ref var, ref value) = expr.node,
let hir::ExprPath(ref qpath) = var.node, let hir::ExprPath(ref qpath) = var.node,
decl == cx.tcx.tables().qpath_def(qpath, var.id).def_id(), decl == cx.tables.qpath_def(qpath, var.id).def_id(),
], { ], {
let mut v = UsedVisitor { let mut v = UsedVisitor {
cx: cx, cx: cx,

View File

@ -4,6 +4,7 @@
#![feature(collections)] #![feature(collections)]
#![feature(custom_attribute)] #![feature(custom_attribute)]
#![feature(i128_type)] #![feature(i128_type)]
#![feature(i128)]
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(slice_patterns)] #![feature(slice_patterns)]
#![feature(stmt_expr_attributes)] #![feature(stmt_expr_attributes)]
@ -17,6 +18,7 @@
extern crate syntax; extern crate syntax;
#[macro_use] #[macro_use]
extern crate rustc; extern crate rustc;
extern crate rustc_data_structures;
extern crate toml; extern crate toml;

View File

@ -246,7 +246,7 @@ impl<'v, 't> RefVisitor<'v, 't> {
let last_path_segment = &last_path_segment(qpath).parameters; let last_path_segment = &last_path_segment(qpath).parameters;
if let AngleBracketedParameters(ref params) = *last_path_segment { if let AngleBracketedParameters(ref params) = *last_path_segment {
if params.lifetimes.is_empty() { if params.lifetimes.is_empty() {
match self.cx.tcx.tables().qpath_def(qpath, ty.id) { match self.cx.tables.qpath_def(qpath, ty.id) {
Def::TyAlias(def_id) | Def::TyAlias(def_id) |
Def::Struct(def_id) => { Def::Struct(def_id) => {
let generics = self.cx.tcx.item_generics(def_id); let generics = self.cx.tcx.item_generics(def_id);

View File

@ -9,7 +9,7 @@ use rustc::middle::const_val::ConstVal;
use rustc::middle::region::CodeExtent; use rustc::middle::region::CodeExtent;
use rustc::ty; use rustc::ty;
use rustc_const_eval::EvalHint::ExprTypeChecked; use rustc_const_eval::EvalHint::ExprTypeChecked;
use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::ConstContext;
use std::collections::HashMap; use std::collections::HashMap;
use syntax::ast; use syntax::ast;
use utils::sugg; use utils::sugg;
@ -529,8 +529,9 @@ fn check_for_loop_reverse_range(cx: &LateContext, arg: &Expr, expr: &Expr) {
// if this for loop is iterating over a two-sided range... // if this for loop is iterating over a two-sided range...
if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::range(arg) { if let Some(higher::Range { start: Some(start), end: Some(end), limits }) = higher::range(arg) {
// ...and both sides are compile-time constant integers... // ...and both sides are compile-time constant integers...
if let Ok(start_idx) = eval_const_expr_partial(cx.tcx, start, ExprTypeChecked, None) { let constcx = ConstContext::with_tables(cx.tcx, cx.tables);
if let Ok(end_idx) = eval_const_expr_partial(cx.tcx, end, ExprTypeChecked, None) { if let Ok(start_idx) = constcx.eval(start, ExprTypeChecked) {
if let Ok(end_idx) = constcx.eval(end, ExprTypeChecked) {
// ...and the start index is greater than the end index, // ...and the start index is greater than the end index,
// this loop will never run. This is often confusing for developers // this loop will never run. This is often confusing for developers
// who think that this will iterate from the larger value to the // who think that this will iterate from the larger value to the
@ -627,7 +628,7 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
/// Check for `for` loops over `Option`s and `Results` /// Check for `for` loops over `Option`s and `Results`
fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) { fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) {
let ty = cx.tcx.tables().expr_ty(arg); let ty = cx.tables.expr_ty(arg);
if match_type(cx, ty, &paths::OPTION) { if match_type(cx, ty, &paths::OPTION) {
span_help_and_lint(cx, span_help_and_lint(cx,
FOR_LOOP_OVER_OPTION, FOR_LOOP_OVER_OPTION,
@ -713,7 +714,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>(
if let PatKind::Tuple(ref pat, _) = pat.node { if let PatKind::Tuple(ref pat, _) = pat.node {
if pat.len() == 2 { if pat.len() == 2 {
let arg_span = arg.span; let arg_span = arg.span;
let (new_pat_span, kind, ty, mutbl) = match cx.tcx.tables().expr_ty(arg).sty { let (new_pat_span, kind, ty, mutbl) = match cx.tables.expr_ty(arg).sty {
ty::TyRef(_, ref tam) => { ty::TyRef(_, ref tam) => {
match (&pat[0].node, &pat[1].node) { match (&pat[0].node, &pat[1].node) {
(key, _) if pat_is_wild(cx, key, body) => (pat[1].span, "value", tam.ty, tam.mutbl), (key, _) if pat_is_wild(cx, key, body) => (pat[1].span, "value", tam.ty, tam.mutbl),
@ -800,7 +801,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr) { fn visit_expr(&mut self, expr: &'tcx Expr) {
if let ExprPath(ref qpath) = expr.node { if let ExprPath(ref qpath) = expr.node {
if let QPath::Resolved(None, ref path) = *qpath { if let QPath::Resolved(None, ref path) = *qpath {
if path.segments.len() == 1 && self.cx.tcx.tables().qpath_def(qpath, expr.id).def_id() == self.var { if path.segments.len() == 1 && self.cx.tables.qpath_def(qpath, expr.id).def_id() == self.var {
// we are referencing our variable! now check if it's as an index // we are referencing our variable! now check if it's as an index
if_let_chain! {[ if_let_chain! {[
let Some(parexpr) = get_parent_expr(self.cx, expr), let Some(parexpr) = get_parent_expr(self.cx, expr),
@ -809,7 +810,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
let QPath::Resolved(None, ref seqvar) = *seqpath, let QPath::Resolved(None, ref seqvar) = *seqpath,
seqvar.segments.len() == 1 seqvar.segments.len() == 1
], { ], {
let def = self.cx.tcx.tables().qpath_def(seqpath, seqexpr.id); let def = self.cx.tables.qpath_def(seqpath, seqexpr.id);
match def { match def {
Def::Local(..) | Def::Upvar(..) => { Def::Local(..) | Def::Upvar(..) => {
let def_id = def.def_id(); let def_id = def.def_id();
@ -888,7 +889,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor<'a, 'tcx> {
fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool { fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool {
// no walk_ptrs_ty: calling iter() on a reference can make sense because it // no walk_ptrs_ty: calling iter() on a reference can make sense because it
// will allow further borrows afterwards // will allow further borrows afterwards
let ty = cx.tcx.tables().expr_ty(e); let ty = cx.tables.expr_ty(e);
is_iterable_array(ty) || is_iterable_array(ty) ||
match_type(cx, ty, &paths::VEC) || match_type(cx, ty, &paths::VEC) ||
match_type(cx, ty, &paths::LINKED_LIST) || match_type(cx, ty, &paths::LINKED_LIST) ||
@ -1113,7 +1114,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
fn var_def_id(cx: &LateContext, expr: &Expr) -> Option<NodeId> { fn var_def_id(cx: &LateContext, expr: &Expr) -> Option<NodeId> {
if let ExprPath(ref qpath) = expr.node { if let ExprPath(ref qpath) = expr.node {
let path_res = cx.tcx.tables().qpath_def(qpath, expr.id); let path_res = cx.tables.qpath_def(qpath, expr.id);
if let Def::Local(def_id) = path_res { if let Def::Local(def_id) = path_res {
let node_id = cx.tcx.map.as_local_node_id(def_id).expect("That DefId should be valid"); let node_id = cx.tcx.map.as_local_node_id(def_id).expect("That DefId should be valid");
return Some(node_id); return Some(node_id);

View File

@ -44,7 +44,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
// look for derefs, for .map(|x| *x) // look for derefs, for .map(|x| *x)
if only_derefs(cx, &*closure_expr, arg_ident) && if only_derefs(cx, &*closure_expr, arg_ident) &&
// .cloned() only removes one level of indirection, don't lint on more // .cloned() only removes one level of indirection, don't lint on more
walk_ptrs_ty_depth(cx.tcx.tables().pat_ty(&first_arg.pat)).1 == 1 walk_ptrs_ty_depth(cx.tables.pat_ty(&first_arg.pat)).1 == 1
{ {
span_help_and_lint(cx, MAP_CLONE, expr.span, &format!( span_help_and_lint(cx, MAP_CLONE, expr.span, &format!(
"you seem to be using .map() to clone the contents of an {}, consider \ "you seem to be using .map() to clone the contents of an {}, consider \
@ -101,7 +101,7 @@ fn expr_eq_name(expr: &Expr, id: ast::Name) -> bool {
fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static str> { fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static str> {
if match_trait_method(cx, expr, &paths::ITERATOR) { if match_trait_method(cx, expr, &paths::ITERATOR) {
Some("iterator") Some("iterator")
} else if match_type(cx, walk_ptrs_ty(cx.tcx.tables().expr_ty(arg)), &paths::OPTION) { } else if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(arg)), &paths::OPTION) {
Some("Option") Some("Option")
} else { } else {
None None

View File

@ -3,7 +3,7 @@ use rustc::lint::*;
use rustc::middle::const_val::ConstVal; use rustc::middle::const_val::ConstVal;
use rustc::ty; use rustc::ty;
use rustc_const_eval::EvalHint::ExprTypeChecked; use rustc_const_eval::EvalHint::ExprTypeChecked;
use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::ConstContext;
use rustc_const_math::ConstInt; use rustc_const_math::ConstInt;
use std::cmp::Ordering; use std::cmp::Ordering;
use syntax::ast::LitKind; use syntax::ast::LitKind;
@ -163,7 +163,7 @@ fn check_single_match(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
// allow match arms with just expressions // allow match arms with just expressions
return; return;
}; };
let ty = cx.tcx.tables().expr_ty(ex); let ty = cx.tables.expr_ty(ex);
if ty.sty != ty::TyBool || cx.current_level(MATCH_BOOL) == Allow { if ty.sty != ty::TyBool || cx.current_level(MATCH_BOOL) == Allow {
check_single_match_single_pattern(cx, ex, arms, expr, els); check_single_match_single_pattern(cx, ex, arms, expr, els);
check_single_match_opt_like(cx, ex, arms, expr, ty, els); check_single_match_opt_like(cx, ex, arms, expr, ty, els);
@ -254,7 +254,7 @@ fn check_single_match_opt_like(
fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
// type of expression == bool // type of expression == bool
if cx.tcx.tables().expr_ty(ex).sty == ty::TyBool { if cx.tables.expr_ty(ex).sty == ty::TyBool {
span_lint_and_then(cx, span_lint_and_then(cx,
MATCH_BOOL, MATCH_BOOL,
expr.span, expr.span,
@ -305,7 +305,7 @@ fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
} }
fn check_overlapping_arms(cx: &LateContext, ex: &Expr, arms: &[Arm]) { fn check_overlapping_arms(cx: &LateContext, ex: &Expr, arms: &[Arm]) {
if arms.len() >= 2 && cx.tcx.tables().expr_ty(ex).is_integral() { if arms.len() >= 2 && cx.tables.expr_ty(ex).is_integral() {
let ranges = all_ranges(cx, arms); let ranges = all_ranges(cx, arms);
let type_ranges = type_ranges(&ranges); let type_ranges = type_ranges(&ranges);
if !type_ranges.is_empty() { if !type_ranges.is_empty() {
@ -351,6 +351,7 @@ fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], source: Match
/// Get all arms that are unbounded `PatRange`s. /// Get all arms that are unbounded `PatRange`s.
fn all_ranges(cx: &LateContext, arms: &[Arm]) -> Vec<SpannedRange<ConstVal>> { fn all_ranges(cx: &LateContext, arms: &[Arm]) -> Vec<SpannedRange<ConstVal>> {
let constcx = ConstContext::with_tables(cx.tcx, cx.tables);
arms.iter() arms.iter()
.flat_map(|arm| { .flat_map(|arm| {
if let Arm { ref pats, guard: None, .. } = *arm { if let Arm { ref pats, guard: None, .. } = *arm {
@ -361,15 +362,15 @@ fn all_ranges(cx: &LateContext, arms: &[Arm]) -> Vec<SpannedRange<ConstVal>> {
.filter_map(|pat| { .filter_map(|pat| {
if_let_chain! {[ if_let_chain! {[
let PatKind::Range(ref lhs, ref rhs) = pat.node, let PatKind::Range(ref lhs, ref rhs) = pat.node,
let Ok(lhs) = eval_const_expr_partial(cx.tcx, lhs, ExprTypeChecked, None), let Ok(lhs) = constcx.eval(lhs, ExprTypeChecked),
let Ok(rhs) = eval_const_expr_partial(cx.tcx, rhs, ExprTypeChecked, None) let Ok(rhs) = constcx.eval(rhs, ExprTypeChecked)
], { ], {
return Some(SpannedRange { span: pat.span, node: (lhs, rhs) }); return Some(SpannedRange { span: pat.span, node: (lhs, rhs) });
}} }}
if_let_chain! {[ if_let_chain! {[
let PatKind::Lit(ref value) = pat.node, let PatKind::Lit(ref value) = pat.node,
let Ok(value) = eval_const_expr_partial(cx.tcx, value, ExprTypeChecked, None) let Ok(value) = constcx.eval(value, ExprTypeChecked)
], { ], {
return Some(SpannedRange { span: pat.span, node: (value.clone(), value) }); return Some(SpannedRange { span: pat.span, node: (value.clone(), value) });
}} }}

View File

@ -31,9 +31,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemForget {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
if let ExprCall(ref path_expr, ref args) = e.node { if let ExprCall(ref path_expr, ref args) = e.node {
if let ExprPath(ref qpath) = path_expr.node { if let ExprPath(ref qpath) = path_expr.node {
let def_id = cx.tcx.tables().qpath_def(qpath, path_expr.id).def_id(); let def_id = cx.tables.qpath_def(qpath, path_expr.id).def_id();
if match_def_path(cx, def_id, &paths::MEM_FORGET) { if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) {
let forgot_ty = cx.tcx.tables().expr_ty(&args[0]); let forgot_ty = cx.tables.expr_ty(&args[0]);
if match forgot_ty.ty_adt_def() { if match forgot_ty.ty_adt_def() {
Some(def) => def.has_dtor(), Some(def) => def.has_dtor(),

View File

@ -4,7 +4,7 @@ use rustc::middle::const_val::ConstVal;
use rustc::ty; use rustc::ty;
use rustc::hir::def::Def; use rustc::hir::def::Def;
use rustc_const_eval::EvalHint::ExprTypeChecked; use rustc_const_eval::EvalHint::ExprTypeChecked;
use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::ConstContext;
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt; use std::fmt;
use syntax::codemap::Span; use syntax::codemap::Span;
@ -603,7 +603,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
lint_or_fun_call(cx, expr, &name.node.as_str(), args); lint_or_fun_call(cx, expr, &name.node.as_str(), args);
let self_ty = cx.tcx.tables().expr_ty_adjusted(&args[0]); let self_ty = cx.tables.expr_ty_adjusted(&args[0]);
if args.len() == 1 && &*name.node.as_str() == "clone" { if args.len() == 1 && &*name.node.as_str() == "clone" {
lint_clone_on_copy(cx, expr, &args[0], self_ty); lint_clone_on_copy(cx, expr, &args[0], self_ty);
} }
@ -712,7 +712,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir:
let path: &str = &*last_path_segment(qpath).name.as_str(); let path: &str = &*last_path_segment(qpath).name.as_str();
if ["default", "new"].contains(&path) { if ["default", "new"].contains(&path) {
let arg_ty = cx.tcx.tables().expr_ty(arg); let arg_ty = cx.tables.expr_ty(arg);
let default_trait_id = if let Some(default_trait_id) = let default_trait_id = if let Some(default_trait_id) =
get_trait_def_id(cx, &paths::DEFAULT_TRAIT) { get_trait_def_id(cx, &paths::DEFAULT_TRAIT) {
default_trait_id default_trait_id
@ -768,7 +768,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir:
(&paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"), (&paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"),
(&paths::RESULT, true, &["or", "unwrap_or"], "else")]; (&paths::RESULT, true, &["or", "unwrap_or"], "else")];
let self_ty = cx.tcx.tables().expr_ty(self_expr); let self_ty = cx.tables.expr_ty(self_expr);
let (fn_has_arguments, poss, suffix) = if let Some(&(_, fn_has_arguments, poss, suffix)) = 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)) { know_types.iter().find(|&&i| match_type(cx, self_ty, i.0)) {
@ -810,7 +810,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir:
/// Checks for the `CLONE_ON_COPY` lint. /// Checks for the `CLONE_ON_COPY` lint.
fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_ty: ty::Ty) { fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_ty: ty::Ty) {
let ty = cx.tcx.tables().expr_ty(expr); let ty = cx.tables.expr_ty(expr);
let parent = cx.tcx.map.get_parent(expr.id); let parent = cx.tcx.map.get_parent(expr.id);
let parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, parent); let parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, parent);
if let ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) = arg_ty.sty { if let ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) = arg_ty.sty {
@ -835,7 +835,7 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t
expr.span, expr.span,
"using `clone` on a `Copy` type", "using `clone` on a `Copy` type",
|db| if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) { |db| if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) {
if let ty::TyRef(..) = cx.tcx.tables().expr_ty(arg).sty { if let ty::TyRef(..) = cx.tables.expr_ty(arg).sty {
db.span_suggestion(expr.span, "try dereferencing it", format!("{}", snip.deref())); db.span_suggestion(expr.span, "try dereferencing it", format!("{}", snip.deref()));
} else { } else {
db.span_suggestion(expr.span, "try removing the `clone` call", format!("{}", snip)); db.span_suggestion(expr.span, "try removing the `clone` call", format!("{}", snip));
@ -845,7 +845,7 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t
} }
fn lint_vec_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) { fn lint_vec_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) {
let arg_ty = cx.tcx.tables().expr_ty(&args[1]); let arg_ty = cx.tables.expr_ty(&args[1]);
if let Some(slice) = derefs_to_slice(cx, &args[1], arg_ty) { if let Some(slice) = derefs_to_slice(cx, &args[1], arg_ty) {
span_lint_and_then(cx, span_lint_and_then(cx,
EXTEND_FROM_SLICE, EXTEND_FROM_SLICE,
@ -863,7 +863,7 @@ fn lint_string_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) {
let arg = &args[1]; let arg = &args[1];
if let Some(arglists) = method_chain_args(arg, &["chars"]) { if let Some(arglists) = method_chain_args(arg, &["chars"]) {
let target = &arglists[0][0]; let target = &arglists[0][0];
let (self_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(target)); let (self_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(target));
let ref_str = if self_ty.sty == ty::TyStr { let ref_str = if self_ty.sty == ty::TyStr {
"" ""
} else if match_type(cx, self_ty, &paths::STRING) { } else if match_type(cx, self_ty, &paths::STRING) {
@ -884,7 +884,7 @@ fn lint_string_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) {
} }
fn lint_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) { fn lint_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) {
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&args[0])); let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(&args[0]));
if match_type(cx, obj_ty, &paths::VEC) { if match_type(cx, obj_ty, &paths::VEC) {
lint_vec_extend(cx, expr, args); lint_vec_extend(cx, expr, args);
} else if match_type(cx, obj_ty, &paths::STRING) { } else if match_type(cx, obj_ty, &paths::STRING) {
@ -897,8 +897,8 @@ fn lint_cstring_as_ptr(cx: &LateContext, expr: &hir::Expr, new: &hir::Expr, unwr
let hir::ExprCall(ref fun, ref args) = new.node, let hir::ExprCall(ref fun, ref args) = new.node,
args.len() == 1, args.len() == 1,
let hir::ExprPath(ref path) = fun.node, let hir::ExprPath(ref path) = fun.node,
let Def::Method(did) = cx.tcx.tables().qpath_def(path, fun.id), let Def::Method(did) = cx.tables.qpath_def(path, fun.id),
match_def_path(cx, did, &paths::CSTRING_NEW) match_def_path(cx.tcx, did, &paths::CSTRING_NEW)
], { ], {
span_lint_and_then(cx, TEMPORARY_CSTRING_AS_PTR, expr.span, span_lint_and_then(cx, TEMPORARY_CSTRING_AS_PTR, expr.span,
"you are getting the inner pointer of a temporary `CString`", "you are getting the inner pointer of a temporary `CString`",
@ -911,11 +911,11 @@ fn lint_cstring_as_ptr(cx: &LateContext, expr: &hir::Expr, new: &hir::Expr, unwr
fn lint_iter_nth(cx: &LateContext, expr: &hir::Expr, iter_args: &[hir::Expr], is_mut: bool) { fn lint_iter_nth(cx: &LateContext, expr: &hir::Expr, iter_args: &[hir::Expr], is_mut: bool) {
let mut_str = if is_mut { "_mut" } else { "" }; let mut_str = if is_mut { "_mut" } else { "" };
let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.tcx.tables().expr_ty(&iter_args[0])).is_some() { let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])).is_some() {
"slice" "slice"
} else if match_type(cx, cx.tcx.tables().expr_ty(&iter_args[0]), &paths::VEC) { } else if match_type(cx, cx.tables.expr_ty(&iter_args[0]), &paths::VEC) {
"Vec" "Vec"
} else if match_type(cx, cx.tcx.tables().expr_ty(&iter_args[0]), &paths::VEC_DEQUE) { } else if match_type(cx, cx.tables.expr_ty(&iter_args[0]), &paths::VEC_DEQUE) {
"VecDeque" "VecDeque"
} else { } else {
return; // caller is not a type that we want to lint return; // caller is not a type that we want to lint
@ -932,7 +932,7 @@ fn lint_iter_nth(cx: &LateContext, expr: &hir::Expr, iter_args: &[hir::Expr], is
fn lint_get_unwrap(cx: &LateContext, expr: &hir::Expr, get_args: &[hir::Expr], is_mut: bool) { fn lint_get_unwrap(cx: &LateContext, expr: &hir::Expr, get_args: &[hir::Expr], is_mut: bool) {
// Note: we don't want to lint `get_mut().unwrap` for HashMap or BTreeMap, // Note: we don't want to lint `get_mut().unwrap` for HashMap or BTreeMap,
// because they do not implement `IndexMut` // because they do not implement `IndexMut`
let expr_ty = cx.tcx.tables().expr_ty(&get_args[0]); let expr_ty = cx.tables.expr_ty(&get_args[0]);
let caller_type = if derefs_to_slice(cx, &get_args[0], expr_ty).is_some() { let caller_type = if derefs_to_slice(cx, &get_args[0], expr_ty).is_some() {
"slice" "slice"
} else if match_type(cx, expr_ty, &paths::VEC) { } else if match_type(cx, expr_ty, &paths::VEC) {
@ -988,7 +988,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 let hir::ExprMethodCall(name, _, ref args) = expr.node {
if &*name.node.as_str() == "iter" && may_slice(cx, cx.tcx.tables().expr_ty(&args[0])) { if &*name.node.as_str() == "iter" && may_slice(cx, cx.tables.expr_ty(&args[0])) {
sugg::Sugg::hir_opt(cx, &args[0]).map(|sugg| sugg.addr()) sugg::Sugg::hir_opt(cx, &args[0]).map(|sugg| sugg.addr())
} else { } else {
None None
@ -1011,7 +1011,7 @@ fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: ty::Ty) -> Option<sug
/// lint use of `unwrap()` for `Option`s and `Result`s /// lint use of `unwrap()` for `Option`s and `Result`s
fn lint_unwrap(cx: &LateContext, expr: &hir::Expr, unwrap_args: &[hir::Expr]) { fn lint_unwrap(cx: &LateContext, expr: &hir::Expr, unwrap_args: &[hir::Expr]) {
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&unwrap_args[0])); let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(&unwrap_args[0]));
let mess = if match_type(cx, obj_ty, &paths::OPTION) { let mess = if match_type(cx, obj_ty, &paths::OPTION) {
Some((OPTION_UNWRAP_USED, "an Option", "None")) Some((OPTION_UNWRAP_USED, "an Option", "None"))
@ -1036,8 +1036,8 @@ fn lint_unwrap(cx: &LateContext, expr: &hir::Expr, unwrap_args: &[hir::Expr]) {
/// lint use of `ok().expect()` for `Result`s /// lint use of `ok().expect()` for `Result`s
fn lint_ok_expect(cx: &LateContext, expr: &hir::Expr, ok_args: &[hir::Expr]) { fn lint_ok_expect(cx: &LateContext, expr: &hir::Expr, ok_args: &[hir::Expr]) {
// lint if the caller of `ok()` is a `Result` // lint if the caller of `ok()` is a `Result`
if match_type(cx, cx.tcx.tables().expr_ty(&ok_args[0]), &paths::RESULT) { if match_type(cx, cx.tables.expr_ty(&ok_args[0]), &paths::RESULT) {
let result_type = cx.tcx.tables().expr_ty(&ok_args[0]); let result_type = cx.tables.expr_ty(&ok_args[0]);
if let Some(error_type) = get_error_type(cx, result_type) { if let Some(error_type) = get_error_type(cx, result_type) {
if has_debug_impl(error_type, cx) { if has_debug_impl(error_type, cx) {
span_lint(cx, span_lint(cx,
@ -1052,7 +1052,7 @@ fn lint_ok_expect(cx: &LateContext, expr: &hir::Expr, ok_args: &[hir::Expr]) {
/// lint use of `map().unwrap_or()` for `Option`s /// lint use of `map().unwrap_or()` for `Option`s
fn lint_map_unwrap_or(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr], unwrap_args: &[hir::Expr]) { fn lint_map_unwrap_or(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr], unwrap_args: &[hir::Expr]) {
// lint if the caller of `map()` is an `Option` // lint if the caller of `map()` is an `Option`
if match_type(cx, cx.tcx.tables().expr_ty(&map_args[0]), &paths::OPTION) { if match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION) {
// lint message // lint message
let msg = "called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling \ 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"; `map_or(a, f)` instead";
@ -1081,7 +1081,7 @@ fn lint_map_unwrap_or(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr]
/// lint use of `map().unwrap_or_else()` for `Option`s /// lint use of `map().unwrap_or_else()` for `Option`s
fn lint_map_unwrap_or_else(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr], unwrap_args: &[hir::Expr]) { fn lint_map_unwrap_or_else(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr], unwrap_args: &[hir::Expr]) {
// lint if the caller of `map()` is an `Option` // lint if the caller of `map()` is an `Option`
if match_type(cx, cx.tcx.tables().expr_ty(&map_args[0]), &paths::OPTION) { if match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION) {
// lint message // lint message
let msg = "called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling \ 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"; `map_or_else(g, f)` instead";
@ -1208,7 +1208,7 @@ fn lint_chars_next(cx: &LateContext, expr: &hir::Expr, chain: &hir::Expr, other:
let Some(segment) = single_segment_path(qpath), let Some(segment) = single_segment_path(qpath),
&*segment.name.as_str() == "Some" &*segment.name.as_str() == "Some"
], { ], {
let self_ty = walk_ptrs_ty(cx.tcx.tables().expr_ty_adjusted(&args[0][0])); let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0]));
if self_ty.sty != ty::TyStr { if self_ty.sty != ty::TyStr {
return false; return false;
@ -1236,7 +1236,7 @@ fn lint_chars_next(cx: &LateContext, expr: &hir::Expr, chain: &hir::Expr, other:
/// lint for length-1 `str`s for methods in `PATTERN_METHODS` /// lint for length-1 `str`s for methods in `PATTERN_METHODS`
fn lint_single_char_pattern(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr) { fn lint_single_char_pattern(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr) {
if let Ok(ConstVal::Str(r)) = eval_const_expr_partial(cx.tcx, arg, ExprTypeChecked, None) { if let Ok(ConstVal::Str(r)) = ConstContext::with_tables(cx.tcx, cx.tables).eval(arg, ExprTypeChecked) {
if r.len() == 1 { if r.len() == 1 {
let hint = snippet(cx, expr.span, "..").replace(&format!("\"{}\"", r), &format!("'{}'", r)); let hint = snippet(cx, expr.span, "..").replace(&format!("\"{}\"", r), &format!("'{}'", r));
span_lint_and_then(cx, span_lint_and_then(cx,

View File

@ -62,11 +62,11 @@ enum MinMax {
fn min_max<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(MinMax, Constant, &'a Expr)> { fn min_max<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(MinMax, Constant, &'a Expr)> {
if let ExprCall(ref path, ref args) = expr.node { if let ExprCall(ref path, ref args) = expr.node {
if let ExprPath(ref qpath) = path.node { if let ExprPath(ref qpath) = path.node {
let def_id = cx.tcx.tables().qpath_def(qpath, path.id).def_id(); let def_id = cx.tables.qpath_def(qpath, path.id).def_id();
if match_def_path(cx, def_id, &paths::CMP_MIN) { if match_def_path(cx.tcx, def_id, &paths::CMP_MIN) {
fetch_const(args, MinMax::Min) fetch_const(args, MinMax::Min)
} else if match_def_path(cx, def_id, &paths::CMP_MAX) { } else if match_def_path(cx.tcx, def_id, &paths::CMP_MAX) {
fetch_const(args, MinMax::Max) fetch_const(args, MinMax::Max)
} else { } else {
None None

View File

@ -5,7 +5,7 @@ use rustc::lint::*;
use rustc::middle::const_val::ConstVal; use rustc::middle::const_val::ConstVal;
use rustc::ty; use rustc::ty;
use rustc_const_eval::EvalHint::ExprTypeChecked; use rustc_const_eval::EvalHint::ExprTypeChecked;
use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::ConstContext;
use rustc_const_math::ConstFloat; use rustc_const_math::ConstFloat;
use syntax::codemap::{Span, Spanned, ExpnFormat}; use syntax::codemap::{Span, Spanned, ExpnFormat};
use utils::{get_item_name, get_parent_expr, implements_trait, in_macro, is_integer_literal, match_path, snippet, use utils::{get_item_name, get_parent_expr, implements_trait, in_macro, is_integer_literal, match_path, snippet,
@ -312,7 +312,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
&*binding != "_result" && // FIXME: #944 &*binding != "_result" && // FIXME: #944
is_used(cx, expr) && is_used(cx, expr) &&
// don't lint if the declaration is in a macro // don't lint if the declaration is in a macro
non_macro_local(cx, &cx.tcx.tables().qpath_def(qpath, expr.id)) { non_macro_local(cx, &cx.tables.qpath_def(qpath, expr.id)) {
Some(binding) Some(binding)
} else { } else {
None None
@ -362,7 +362,7 @@ fn check_nan(cx: &LateContext, path: &Path, span: Span) {
} }
fn is_allowed(cx: &LateContext, expr: &Expr) -> bool { fn is_allowed(cx: &LateContext, expr: &Expr) -> bool {
let res = eval_const_expr_partial(cx.tcx, expr, ExprTypeChecked, None); let res = ConstContext::with_tables(cx.tcx, cx.tables).eval(expr, ExprTypeChecked);
if let Ok(ConstVal::Float(val)) = res { if let Ok(ConstVal::Float(val)) = res {
use std::cmp::Ordering; use std::cmp::Ordering;
@ -389,7 +389,7 @@ fn is_allowed(cx: &LateContext, expr: &Expr) -> bool {
} }
fn is_float(cx: &LateContext, expr: &Expr) -> bool { fn is_float(cx: &LateContext, expr: &Expr) -> bool {
matches!(walk_ptrs_ty(cx.tcx.tables().expr_ty(expr)).sty, ty::TyFloat(_)) matches!(walk_ptrs_ty(cx.tables.expr_ty(expr)).sty, ty::TyFloat(_))
} }
fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: Span) { fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: Span) {
@ -397,7 +397,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S
ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) if args.len() == 1 => { ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) if args.len() == 1 => {
let name = &*name.as_str(); let name = &*name.as_str();
if name == "to_string" || name == "to_owned" && is_str_arg(cx, args) { if name == "to_string" || name == "to_owned" && is_str_arg(cx, args) {
(cx.tcx.tables().expr_ty(&args[0]), snippet(cx, args[0].span, "..")) (cx.tables.expr_ty(&args[0]), snippet(cx, args[0].span, ".."))
} else { } else {
return; return;
} }
@ -405,7 +405,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S
ExprCall(ref path, ref v) if v.len() == 1 => { ExprCall(ref path, ref v) if v.len() == 1 => {
if let ExprPath(ref path) = path.node { if let ExprPath(ref path) = path.node {
if match_path(path, &["String", "from_str"]) || match_path(path, &["String", "from"]) { if match_path(path, &["String", "from_str"]) || match_path(path, &["String", "from"]) {
(cx.tcx.tables().expr_ty(&v[0]), snippet(cx, v[0].span, "..")) (cx.tables.expr_ty(&v[0]), snippet(cx, v[0].span, ".."))
} else { } else {
return; return;
} }
@ -416,7 +416,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S
_ => return, _ => return,
}; };
let other_ty = cx.tcx.tables().expr_ty(other); let other_ty = cx.tables.expr_ty(other);
let partial_eq_trait_id = match cx.tcx.lang_items.eq_trait() { let partial_eq_trait_id = match cx.tcx.lang_items.eq_trait() {
Some(id) => id, Some(id) => id,
None => return, None => return,
@ -449,7 +449,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S
} }
fn is_str_arg(cx: &LateContext, args: &[Expr]) -> bool { fn is_str_arg(cx: &LateContext, args: &[Expr]) -> bool {
args.len() == 1 && matches!(walk_ptrs_ty(cx.tcx.tables().expr_ty(&args[0])).sty, ty::TyStr) args.len() == 1 && matches!(walk_ptrs_ty(cx.tables.expr_ty(&args[0])).sty, ty::TyStr)
} }
/// Heuristic to see if an expression is used. Should be compatible with `unused_variables`'s idea /// Heuristic to see if an expression is used. Should be compatible with `unused_variables`'s idea

View File

@ -68,7 +68,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
MUT_MUT, MUT_MUT,
expr.span, expr.span,
"generally you want to avoid `&mut &mut _` if possible"); "generally you want to avoid `&mut &mut _` if possible");
} else if let TyRef(_, TypeAndMut { mutbl: hir::MutMutable, .. }) = self.cx.tcx.tables().expr_ty(e).sty { } else if let TyRef(_, TypeAndMut { mutbl: hir::MutMutable, .. }) = self.cx.tables.expr_ty(e).sty {
span_lint(self.cx, span_lint(self.cx,
MUT_MUT, MUT_MUT,
expr.span, expr.span,

View File

@ -34,7 +34,7 @@ impl LintPass for UnnecessaryMutPassed {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
let borrowed_table = cx.tcx.tables.borrow(); let borrowed_table = cx.tables;
match e.node { match e.node {
ExprCall(ref fn_expr, ref arguments) => { ExprCall(ref fn_expr, ref arguments) => {
let function_type = borrowed_table.node_types let function_type = borrowed_table.node_types

View File

@ -56,7 +56,7 @@ pub struct MutexAtomic;
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutexAtomic { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutexAtomic {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
let ty = cx.tcx.tables().expr_ty(expr); let ty = cx.tables.expr_ty(expr);
if let ty::TyAdt(_, subst) = ty.sty { if let ty::TyAdt(_, subst) = ty.sty {
if match_type(cx, ty, &paths::MUTEX) { if match_type(cx, ty, &paths::MUTEX) {
let mutex_param = &subst.type_at(0).sty; let mutex_param = &subst.type_at(0).sty;

View File

@ -40,9 +40,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
return; return;
} }
if let ExprAddrOf(MutImmutable, ref inner) = e.node { if let ExprAddrOf(MutImmutable, ref inner) = e.node {
if let ty::TyRef(..) = cx.tcx.tables().expr_ty(inner).sty { if let ty::TyRef(..) = cx.tables.expr_ty(inner).sty {
if let Some(&ty::adjustment::Adjust::DerefRef { autoderefs, autoref, .. }) = if let Some(&ty::adjustment::Adjust::DerefRef { autoderefs, autoref, .. }) =
cx.tcx.tables.borrow().adjustments.get(&e.id).map(|a| &a.kind) { cx.tables.adjustments.get(&e.id).map(|a| &a.kind) {
if autoderefs > 1 && autoref.is_some() { if autoderefs > 1 && autoref.is_some() {
span_lint(cx, span_lint(cx,
NEEDLESS_BORROW, NEEDLESS_BORROW,
@ -60,7 +60,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
} }
if_let_chain! {[ if_let_chain! {[
let PatKind::Binding(BindingMode::BindByRef(MutImmutable), _, _, _) = pat.node, let PatKind::Binding(BindingMode::BindByRef(MutImmutable), _, _, _) = pat.node,
let ty::TyRef(_, ref tam) = cx.tcx.tables().pat_ty(pat).sty, let ty::TyRef(_, ref tam) = cx.tables.pat_ty(pat).sty,
tam.mutbl == MutImmutable, tam.mutbl == MutImmutable,
let ty::TyRef(_, ref tam) = tam.ty.sty, let ty::TyRef(_, ref tam) = tam.ty.sty,
// only lint immutable refs, because borrowed `&mut T` cannot be moved out // only lint immutable refs, because borrowed `&mut T` cannot be moved out

View File

@ -33,7 +33,7 @@ impl LintPass for Pass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
if let ExprStruct(_, ref fields, Some(ref base)) = expr.node { if let ExprStruct(_, ref fields, Some(ref base)) = expr.node {
let ty = cx.tcx.tables().expr_ty(expr); let ty = cx.tables.expr_ty(expr);
if let TyAdt(def, _) = ty.sty { if let TyAdt(def, _) = ty.sty {
if fields.len() == def.struct_variant().fields.len() { if fields.len() == def.struct_variant().fields.len() {
span_lint(cx, span_lint(cx,

View File

@ -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 Constant::Int(ref ci) = consts::lit_to_constant(&l.node),
let Some(val) = ci.to_u64(), let Some(val) = ci.to_u64(),
val == 1, val == 1,
cx.tcx.tables().expr_ty(exp).is_integral() cx.tables.expr_ty(exp).is_integral()
], { ], {
span_lint(cx, span_lint(cx,
NEG_MULTIPLY, NEG_MULTIPLY,

View File

@ -69,7 +69,7 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool {
}, },
Expr_::ExprCall(ref callee, ref args) => { Expr_::ExprCall(ref callee, ref args) => {
if let Expr_::ExprPath(ref qpath) = callee.node { if let Expr_::ExprPath(ref qpath) = callee.node {
let def = cx.tcx.tables().qpath_def(qpath, callee.id); let def = cx.tables.qpath_def(qpath, callee.id);
match def { match def {
Def::Struct(..) | Def::Struct(..) |
Def::Variant(..) | Def::Variant(..) |
@ -153,7 +153,7 @@ fn reduce_expression<'a>(cx: &LateContext, expr: &'a Expr) -> Option<Vec<&'a Exp
}, },
Expr_::ExprCall(ref callee, ref args) => { Expr_::ExprCall(ref callee, ref args) => {
if let Expr_::ExprPath(ref qpath) = callee.node { if let Expr_::ExprPath(ref qpath) = callee.node {
let def = cx.tcx.tables().qpath_def(qpath, callee.id); let def = cx.tables.qpath_def(qpath, callee.id);
match def { match def {
Def::Struct(..) | Def::Struct(..) |
Def::Variant(..) | Def::Variant(..) |

View File

@ -50,7 +50,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
method_chain_args(op, &["ok"]).is_some() //test to see if using ok() methoduse std::marker::Sized; 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.tables().expr_ty(&result_types[0]), &paths::RESULT); let is_result_type = match_type(cx, cx.tables.expr_ty(&result_types[0]), &paths::RESULT);
let some_expr_string = snippet(cx, y[0].span, ""); let some_expr_string = snippet(cx, y[0].span, "");
if print::to_string(print::NO_ANN, |s| s.print_path(x, false)) == "Some" && is_result_type { if print::to_string(print::NO_ANN, |s| s.print_path(x, false)) == "Some" && is_result_type {
span_help_and_lint(cx, IF_LET_SOME_RESULT, expr.span, span_help_and_lint(cx, IF_LET_SOME_RESULT, expr.span,

View File

@ -35,7 +35,7 @@ impl LintPass for NonSensical {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSensical { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSensical {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
if let ExprMethodCall(ref name, _, ref arguments) = e.node { if let ExprMethodCall(ref name, _, ref arguments) = e.node {
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&arguments[0])); let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(&arguments[0]));
if &*name.node.as_str() == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) { if &*name.node.as_str() == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
let mut options = Vec::new(); let mut options = Vec::new();
get_open_options(cx, &arguments[0], &mut options); 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)>) { fn get_open_options(cx: &LateContext, argument: &Expr, options: &mut Vec<(OpenOption, Argument)>) {
if let ExprMethodCall(ref name, _, ref arguments) = argument.node { if let ExprMethodCall(ref name, _, ref arguments) = argument.node {
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&arguments[0])); let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(&arguments[0]));
// Only proceed if this is a call on some object of type std::fs::OpenOptions // 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 { if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && arguments.len() >= 2 {

View File

@ -39,8 +39,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional {
let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node, let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node,
let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = second.node, let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = second.node,
&path1.segments[0] == &path3.segments[0] || &path2.segments[0] == &path3.segments[0], &path1.segments[0] == &path3.segments[0] || &path2.segments[0] == &path3.segments[0],
cx.tcx.tables().expr_ty(ident1).is_integral(), cx.tables.expr_ty(ident1).is_integral(),
cx.tcx.tables().expr_ty(ident2).is_integral() cx.tables.expr_ty(ident2).is_integral()
], { ], {
if let BinOp_::BiLt = op.node { if let BinOp_::BiLt = op.node {
if let BinOp_::BiAdd = op2.node { if let BinOp_::BiAdd = op2.node {
@ -63,8 +63,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional {
let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node, let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node,
let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = first.node, let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = first.node,
&path1.segments[0] == &path3.segments[0] || &path2.segments[0] == &path3.segments[0], &path1.segments[0] == &path3.segments[0] || &path2.segments[0] == &path3.segments[0],
cx.tcx.tables().expr_ty(ident1).is_integral(), cx.tables.expr_ty(ident1).is_integral(),
cx.tcx.tables().expr_ty(ident2).is_integral() cx.tables.expr_ty(ident2).is_integral()
], { ], {
if let BinOp_::BiGt = op.node { if let BinOp_::BiGt = op.node {
if let BinOp_::BiAdd = op2.node { if let BinOp_::BiAdd = op2.node {

View File

@ -40,7 +40,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
let ExprCall(ref fun, ref params) = ex.node, let ExprCall(ref fun, ref params) = ex.node,
params.len() == 2, params.len() == 2,
let ExprPath(ref qpath) = fun.node, let ExprPath(ref qpath) = fun.node,
match_def_path(cx, resolve_node(cx, qpath, fun.id).def_id(), &paths::BEGIN_PANIC), match_def_path(cx.tcx, resolve_node(cx, qpath, fun.id).def_id(), &paths::BEGIN_PANIC),
let ExprLit(ref lit) = params[0].node, let ExprLit(ref lit) = params[0].node,
is_direct_expn_of(cx, params[0].span, "panic").is_some(), is_direct_expn_of(cx, params[0].span, "panic").is_some(),
let LitKind::Str(ref string, _) = lit.node, let LitKind::Str(ref string, _) = lit.node,

View File

@ -76,7 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
// Search for `std::io::_print(..)` which is unique in a // Search for `std::io::_print(..)` which is unique in a
// `print!` expansion. // `print!` expansion.
if match_def_path(cx, fun_id, &paths::IO_PRINT) { if match_def_path(cx.tcx, fun_id, &paths::IO_PRINT) {
if let Some(span) = is_expn_of(cx, expr.span, "print") { if let Some(span) = is_expn_of(cx, expr.span, "print") {
// `println!` uses `print!`. // `println!` uses `print!`.
let (span, name) = match is_expn_of(cx, span, "println") { let (span, name) = match is_expn_of(cx, span, "println") {
@ -94,7 +94,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
args.len() == 1, args.len() == 1,
let ExprCall(ref args_fun, ref args_args) = args[0].node, let ExprCall(ref args_fun, ref args_args) = args[0].node,
let ExprPath(ref qpath) = args_fun.node, let ExprPath(ref qpath) = args_fun.node,
match_def_path(cx, resolve_node(cx, qpath, args_fun.id).def_id(), &paths::FMT_ARGUMENTS_NEWV1), match_def_path(cx.tcx,
resolve_node(cx, qpath, args_fun.id).def_id(),
&paths::FMT_ARGUMENTS_NEWV1),
args_args.len() == 2, args_args.len() == 2,
let ExprAddrOf(_, ref match_expr) = args_args[1].node, let ExprAddrOf(_, ref match_expr) = args_args[1].node,
let ExprMatch(ref args, _, _) = match_expr.node, let ExprMatch(ref args, _, _) = match_expr.node,
@ -119,10 +121,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
} }
// Search for something like // Search for something like
// `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)` // `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)`
else if args.len() == 2 && match_def_path(cx, fun_id, &paths::FMT_ARGUMENTV1_NEW) { else if args.len() == 2 && match_def_path(cx.tcx, fun_id, &paths::FMT_ARGUMENTV1_NEW) {
if let ExprPath(ref qpath) = args[1].node { if let ExprPath(ref qpath) = args[1].node {
let def_id = cx.tcx.tables().qpath_def(qpath, args[1].id).def_id(); let def_id = cx.tables.qpath_def(qpath, args[1].id).def_id();
if match_def_path(cx, def_id, &paths::DEBUG_FMT_METHOD) && !is_in_debug_impl(cx, expr) && if match_def_path(cx.tcx, def_id, &paths::DEBUG_FMT_METHOD) && !is_in_debug_impl(cx, expr) &&
is_expn_of(cx, expr.span, "panic").is_none() { is_expn_of(cx, expr.span, "panic").is_none() {
span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting"); span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting");
} }

View File

@ -90,7 +90,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StepByZero {
fn has_step_by(cx: &LateContext, expr: &Expr) -> bool { fn has_step_by(cx: &LateContext, expr: &Expr) -> bool {
// No need for walk_ptrs_ty here because step_by moves self, so it // No need for walk_ptrs_ty here because step_by moves self, so it
// can't be called on a borrowed range. // can't be called on a borrowed range.
let ty = cx.tcx.tables().expr_ty(expr); let ty = cx.tables.expr_ty(expr);
// Note: `RangeTo`, `RangeToInclusive` and `RangeFull` don't have step_by // Note: `RangeTo`, `RangeToInclusive` and `RangeFull` don't have step_by
match_type(cx, ty, &paths::RANGE) || match_type(cx, ty, &paths::RANGE_FROM) || match_type(cx, ty, &paths::RANGE) || match_type(cx, ty, &paths::RANGE_FROM) ||

View File

@ -3,7 +3,7 @@ use rustc::hir::*;
use rustc::lint::*; use rustc::lint::*;
use rustc::middle::const_val::ConstVal; use rustc::middle::const_val::ConstVal;
use rustc_const_eval::EvalHint::ExprTypeChecked; use rustc_const_eval::EvalHint::ExprTypeChecked;
use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::ConstContext;
use std::collections::HashSet; use std::collections::HashSet;
use std::error::Error; use std::error::Error;
use syntax::ast::{LitKind, NodeId}; use syntax::ast::{LitKind, NodeId};
@ -91,7 +91,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
if_let_chain!{[ if_let_chain!{[
self.last.is_none(), self.last.is_none(),
let Some(ref expr) = block.expr, let Some(ref expr) = block.expr,
match_type(cx, cx.tcx.tables().expr_ty(expr), &paths::REGEX), match_type(cx, cx.tables.expr_ty(expr), &paths::REGEX),
let Some(span) = is_expn_of(cx, expr.span, "regex"), let Some(span) = is_expn_of(cx, expr.span, "regex"),
], { ], {
if !self.spans.contains(&span) { if !self.spans.contains(&span) {
@ -118,16 +118,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
let ExprPath(ref qpath) = fun.node, let ExprPath(ref qpath) = fun.node,
args.len() == 1, args.len() == 1,
], { ], {
let def_id = cx.tcx.tables().qpath_def(qpath, fun.id).def_id(); let def_id = cx.tables.qpath_def(qpath, fun.id).def_id();
if match_def_path(cx, def_id, &paths::REGEX_NEW) || if match_def_path(cx.tcx, def_id, &paths::REGEX_NEW) ||
match_def_path(cx, def_id, &paths::REGEX_BUILDER_NEW) { match_def_path(cx.tcx, def_id, &paths::REGEX_BUILDER_NEW) {
check_regex(cx, &args[0], true); check_regex(cx, &args[0], true);
} else if match_def_path(cx, def_id, &paths::REGEX_BYTES_NEW) || } else if match_def_path(cx.tcx, def_id, &paths::REGEX_BYTES_NEW) ||
match_def_path(cx, def_id, &paths::REGEX_BYTES_BUILDER_NEW) { match_def_path(cx.tcx, def_id, &paths::REGEX_BYTES_BUILDER_NEW) {
check_regex(cx, &args[0], false); check_regex(cx, &args[0], false);
} else if match_def_path(cx, def_id, &paths::REGEX_SET_NEW) { } else if match_def_path(cx.tcx, def_id, &paths::REGEX_SET_NEW) {
check_set(cx, &args[0], true); check_set(cx, &args[0], true);
} else if match_def_path(cx, def_id, &paths::REGEX_BYTES_SET_NEW) { } else if match_def_path(cx.tcx, def_id, &paths::REGEX_BYTES_SET_NEW) {
check_set(cx, &args[0], false); check_set(cx, &args[0], false);
} }
}} }}
@ -151,7 +151,7 @@ fn str_span(base: Span, s: &str, c: usize) -> Span {
} }
fn const_str(cx: &LateContext, e: &Expr) -> Option<InternedString> { fn const_str(cx: &LateContext, e: &Expr) -> Option<InternedString> {
match eval_const_expr_partial(cx.tcx, e, ExprTypeChecked, None) { match ConstContext::with_tables(cx.tcx, cx.tables).eval(e, ExprTypeChecked) {
Ok(ConstVal::Str(r)) => Some(r), Ok(ConstVal::Str(r)) => Some(r),
_ => None, _ => None,
} }

View File

@ -143,7 +143,7 @@ fn check_decl<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, decl: &'tcx Decl, bindings:
} }
fn is_binding(cx: &LateContext, pat_id: NodeId) -> bool { fn is_binding(cx: &LateContext, pat_id: NodeId) -> bool {
let var_ty = cx.tcx.tables().node_id_to_type(pat_id); let var_ty = cx.tables.node_id_to_type(pat_id);
match var_ty.sty { match var_ty.sty {
ty::TyAdt(..) => false, ty::TyAdt(..) => false,
_ => true, _ => true,

View File

@ -114,7 +114,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
} }
fn is_string(cx: &LateContext, e: &Expr) -> bool { fn is_string(cx: &LateContext, e: &Expr) -> bool {
match_type(cx, walk_ptrs_ty(cx.tcx.tables().expr_ty(e)), &paths::STRING) match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(e)), &paths::STRING)
} }
fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool { fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool {

View File

@ -89,7 +89,7 @@ fn check_manual_swap(cx: &LateContext, block: &Block) {
if let ExprIndex(ref lhs1, ref idx1) = lhs1.node { if let ExprIndex(ref lhs1, ref idx1) = lhs1.node {
if let ExprIndex(ref lhs2, ref idx2) = lhs2.node { if let ExprIndex(ref lhs2, ref idx2) = lhs2.node {
if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, lhs2) { if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, lhs2) {
let ty = walk_ptrs_ty(cx.tcx.tables().expr_ty(lhs1)); let ty = walk_ptrs_ty(cx.tables.expr_ty(lhs1));
if matches!(ty.sty, ty::TySlice(_)) || if matches!(ty.sty, ty::TySlice(_)) ||
matches!(ty.sty, ty::TyArray(_, _)) || matches!(ty.sty, ty::TyArray(_, _)) ||

View File

@ -88,11 +88,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
if let ExprCall(ref path_expr, ref args) = e.node { if let ExprCall(ref path_expr, ref args) = e.node {
if let ExprPath(ref qpath) = path_expr.node { if let ExprPath(ref qpath) = path_expr.node {
let def_id = cx.tcx.tables().qpath_def(qpath, path_expr.id).def_id(); let def_id = cx.tables.qpath_def(qpath, path_expr.id).def_id();
if match_def_path(cx, def_id, &paths::TRANSMUTE) { if match_def_path(cx.tcx, def_id, &paths::TRANSMUTE) {
let from_ty = cx.tcx.tables().expr_ty(&args[0]); let from_ty = cx.tables.expr_ty(&args[0]);
let to_ty = cx.tcx.tables().expr_ty(e); let to_ty = cx.tables.expr_ty(e);
match (&from_ty.sty, &to_ty.sty) { match (&from_ty.sty, &to_ty.sty) {
_ if from_ty == to_ty => { _ if from_ty == to_ty => {

View File

@ -111,7 +111,7 @@ fn check_ty(cx: &LateContext, ast_ty: &Ty) {
} }
match ast_ty.node { match ast_ty.node {
TyPath(ref qpath) => { TyPath(ref qpath) => {
let def = cx.tcx.tables().qpath_def(qpath, ast_ty.id); let def = cx.tables.qpath_def(qpath, ast_ty.id);
if let Some(def_id) = opt_def_id(def) { if let Some(def_id) = opt_def_id(def) {
if Some(def_id) == cx.tcx.lang_items.owned_box() { if Some(def_id) == cx.tcx.lang_items.owned_box() {
let last = last_path_segment(qpath); let last = last_path_segment(qpath);
@ -119,9 +119,9 @@ fn check_ty(cx: &LateContext, ast_ty: &Ty) {
let PathParameters::AngleBracketedParameters(ref ag) = last.parameters, let PathParameters::AngleBracketedParameters(ref ag) = last.parameters,
let Some(ref vec) = ag.types.get(0), let Some(ref vec) = ag.types.get(0),
let TyPath(ref qpath) = vec.node, let TyPath(ref qpath) = vec.node,
let def::Def::Struct(..) = cx.tcx.tables().qpath_def(qpath, vec.id), let def::Def::Struct(..) = cx.tables.qpath_def(qpath, vec.id),
let Some(did) = opt_def_id(cx.tcx.tables().qpath_def(qpath, vec.id)), let Some(did) = opt_def_id(cx.tables.qpath_def(qpath, vec.id)),
match_def_path(cx, did, &paths::VEC), match_def_path(cx.tcx, did, &paths::VEC),
], { ], {
span_help_and_lint(cx, span_help_and_lint(cx,
BOX_VEC, BOX_VEC,
@ -130,7 +130,7 @@ fn check_ty(cx: &LateContext, ast_ty: &Ty) {
"`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation."); "`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.");
return; // don't recurse into the type return; // don't recurse into the type
}} }}
} else if match_def_path(cx, def_id, &paths::LINKED_LIST) { } else if match_def_path(cx.tcx, def_id, &paths::LINKED_LIST) {
span_help_and_lint(cx, span_help_and_lint(cx,
LINKEDLIST, LINKEDLIST,
ast_ty.span, ast_ty.span,
@ -195,7 +195,7 @@ declare_lint! {
fn check_let_unit(cx: &LateContext, decl: &Decl) { fn check_let_unit(cx: &LateContext, decl: &Decl) {
if let DeclLocal(ref local) = decl.node { if let DeclLocal(ref local) = decl.node {
let bindtype = &cx.tcx.tables().pat_ty(&local.pat).sty; let bindtype = &cx.tables.pat_ty(&local.pat).sty;
match *bindtype { match *bindtype {
ty::TyTuple(slice) if slice.is_empty() => { ty::TyTuple(slice) if slice.is_empty() => {
if in_external_macro(cx, decl.span) || in_macro(cx, local.pat.span) { if in_external_macro(cx, decl.span) || in_macro(cx, local.pat.span) {
@ -266,7 +266,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp {
if let ExprBinary(ref cmp, ref left, _) = expr.node { if let ExprBinary(ref cmp, ref left, _) = expr.node {
let op = cmp.node; let op = cmp.node;
if op.is_comparison() { if op.is_comparison() {
let sty = &cx.tcx.tables().expr_ty(left).sty; let sty = &cx.tables.expr_ty(left).sty;
match *sty { match *sty {
ty::TyTuple(slice) if slice.is_empty() => { ty::TyTuple(slice) if slice.is_empty() => {
let result = match op { let result = match op {
@ -510,7 +510,7 @@ impl LintPass for CastPass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
if let ExprCast(ref ex, _) = expr.node { if let ExprCast(ref ex, _) = expr.node {
let (cast_from, cast_to) = (cx.tcx.tables().expr_ty(ex), cx.tcx.tables().expr_ty(expr)); let (cast_from, cast_to) = (cx.tables.expr_ty(ex), cx.tables.expr_ty(expr));
if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx, expr.span) { if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx, expr.span) {
match (cast_from.is_integral(), cast_to.is_integral()) { match (cast_from.is_integral(), cast_to.is_integral()) {
(true, false) => { (true, false) => {
@ -754,7 +754,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CharLitAsU8 {
if let ExprCast(ref e, _) = expr.node { if let ExprCast(ref e, _) = expr.node {
if let ExprLit(ref l) = e.node { if let ExprLit(ref l) = e.node {
if let LitKind::Char(_) = l.node { if let LitKind::Char(_) = l.node {
if ty::TyUint(UintTy::U8) == cx.tcx.tables().expr_ty(expr).sty && !in_macro(cx, expr.span) { if ty::TyUint(UintTy::U8) == cx.tables.expr_ty(expr).sty && !in_macro(cx, expr.span) {
let msg = "casting character literal to u8. `char`s \ let msg = "casting character literal to u8. `char`s \
are 4 bytes wide in rust, so casting to u8 \ are 4 bytes wide in rust, so casting to u8 \
truncates them"; truncates them";
@ -827,7 +827,7 @@ fn detect_absurd_comparison<'a>(
// absurd comparison only makes sense on primitive types // absurd comparison only makes sense on primitive types
// primitive types don't implement comparison operators with each other // primitive types don't implement comparison operators with each other
if cx.tcx.tables().expr_ty(lhs) != cx.tcx.tables().expr_ty(rhs) { if cx.tables.expr_ty(lhs) != cx.tables.expr_ty(rhs) {
return None; return None;
} }
@ -869,14 +869,14 @@ fn detect_extreme_expr<'a>(cx: &LateContext, expr: &'a Expr) -> Option<ExtremeEx
use rustc_const_eval::*; use rustc_const_eval::*;
use types::ExtremeType::*; use types::ExtremeType::*;
let ty = &cx.tcx.tables().expr_ty(expr).sty; let ty = &cx.tables.expr_ty(expr).sty;
match *ty { match *ty {
ty::TyBool | ty::TyInt(_) | ty::TyUint(_) => (), ty::TyBool | ty::TyInt(_) | ty::TyUint(_) => (),
_ => return None, _ => return None,
}; };
let cv = match eval_const_expr_partial(cx.tcx, expr, ExprTypeChecked, None) { let cv = match ConstContext::with_tables(cx.tcx, cx.tables).eval(expr, ExprTypeChecked) {
Ok(val) => val, Ok(val) => val,
Err(_) => return None, Err(_) => return None,
}; };
@ -1035,7 +1035,7 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(
use std::*; use std::*;
if let ExprCast(ref cast_exp, _) = expr.node { if let ExprCast(ref cast_exp, _) = expr.node {
match cx.tcx.tables().expr_ty(cast_exp).sty { match cx.tables.expr_ty(cast_exp).sty {
TyInt(int_ty) => { TyInt(int_ty) => {
Some(match int_ty { Some(match int_ty {
IntTy::I8 => (FullInt::S(i8::min_value() as i128), FullInt::S(i8::max_value() as i128)), IntTy::I8 => (FullInt::S(i8::min_value() as i128), FullInt::S(i8::max_value() as i128)),
@ -1066,10 +1066,10 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(
fn node_as_const_fullint(cx: &LateContext, expr: &Expr) -> Option<FullInt> { fn node_as_const_fullint(cx: &LateContext, expr: &Expr) -> Option<FullInt> {
use rustc::middle::const_val::ConstVal::*; use rustc::middle::const_val::ConstVal::*;
use rustc_const_eval::EvalHint::ExprTypeChecked; use rustc_const_eval::EvalHint::ExprTypeChecked;
use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::ConstContext;
use rustc_const_math::ConstInt; use rustc_const_math::ConstInt;
match eval_const_expr_partial(cx.tcx, expr, ExprTypeChecked, None) { match ConstContext::with_tables(cx.tcx, cx.tables).eval(expr, ExprTypeChecked) {
Ok(val) => { Ok(val) => {
if let Integral(const_int) = val { if let Integral(const_int) = val {
Some(match const_int.erase_type() { Some(match const_int.erase_type() {

View File

@ -159,11 +159,11 @@ pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option<VecArgs<'e
is_expn_of(cx, fun.span, "vec").is_some(), is_expn_of(cx, fun.span, "vec").is_some(),
], { ], {
let fun_def = resolve_node(cx, path, fun.id); let fun_def = resolve_node(cx, path, fun.id);
return if match_def_path(cx, fun_def.def_id(), &paths::VEC_FROM_ELEM) && args.len() == 2 { return if match_def_path(cx.tcx, fun_def.def_id(), &paths::VEC_FROM_ELEM) && args.len() == 2 {
// `vec![elem; size]` case // `vec![elem; size]` case
Some(VecArgs::Repeat(&args[0], &args[1])) Some(VecArgs::Repeat(&args[0], &args[1]))
} }
else if match_def_path(cx, fun_def.def_id(), &paths::SLICE_INTO_VEC) && args.len() == 1 { else if match_def_path(cx.tcx, fun_def.def_id(), &paths::SLICE_INTO_VEC) && args.len() == 1 {
// `vec![a, b, c]` case // `vec![a, b, c]` case
if_let_chain!{[ if_let_chain!{[
let hir::ExprBox(ref boxed) = args[0].node, let hir::ExprBox(ref boxed) = args[0].node,

View File

@ -527,7 +527,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
self.hash_name(&path.name); self.hash_name(&path.name);
}, },
} }
// self.cx.tcx.tables().qpath_def(p, id).hash(&mut self.s); // self.cx.tables.qpath_def(p, id).hash(&mut self.s);
} }
pub fn hash_path(&mut self, p: &Path) { pub fn hash_path(&mut self, p: &Path) {

View File

@ -138,7 +138,7 @@ fn has_attr(attrs: &[Attribute]) -> bool {
fn print_decl(cx: &LateContext, decl: &hir::Decl) { fn print_decl(cx: &LateContext, decl: &hir::Decl) {
match decl.node { match decl.node {
hir::DeclLocal(ref local) => { hir::DeclLocal(ref local) => {
println!("local variable of type {}", cx.tcx.tables().node_id_to_type(local.id)); println!("local variable of type {}", cx.tables.node_id_to_type(local.id));
println!("pattern:"); println!("pattern:");
print_pat(cx, &local.pat, 0); print_pat(cx, &local.pat, 0);
if let Some(ref e) = local.init { if let Some(ref e) = local.init {
@ -152,7 +152,7 @@ fn print_decl(cx: &LateContext, decl: &hir::Decl) {
fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
let ind = " ".repeat(indent); let ind = " ".repeat(indent);
let ty = cx.tcx.tables().node_id_to_type(expr.id); let ty = cx.tables.node_id_to_type(expr.id);
println!("{}+", ind); println!("{}+", ind);
match expr.node { match expr.node {
hir::ExprBox(ref e) => { hir::ExprBox(ref e) => {

View File

@ -141,11 +141,11 @@ pub fn in_external_macro<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool {
/// ///
/// # Examples /// # Examples
/// ```rust,ignore /// ```rust,ignore
/// match_def_path(cx, id, &["core", "option", "Option"]) /// match_def_path(cx.tcx, id, &["core", "option", "Option"])
/// ``` /// ```
/// ///
/// See also the `paths` module. /// See also the `paths` module.
pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool { pub fn match_def_path(tcx: ty::TyCtxt, def_id: DefId, path: &[&str]) -> bool {
use syntax::symbol; use syntax::symbol;
struct AbsolutePathBuffer { struct AbsolutePathBuffer {
@ -165,7 +165,7 @@ pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool {
let mut apb = AbsolutePathBuffer { names: vec![] }; let mut apb = AbsolutePathBuffer { names: vec![] };
cx.tcx.push_item_path(&mut apb, def_id); tcx.push_item_path(&mut apb, def_id);
apb.names.len() == path.len() && apb.names.iter().zip(path.iter()).all(|(a, &b)| &**a == b) apb.names.len() == path.len() && apb.names.iter().zip(path.iter()).all(|(a, &b)| &**a == b)
} }
@ -173,7 +173,7 @@ pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool {
/// Check if type is struct, enum or union type with given def path. /// Check if type is struct, enum or union type with given def path.
pub fn match_type(cx: &LateContext, ty: ty::Ty, path: &[&str]) -> bool { pub fn match_type(cx: &LateContext, ty: ty::Ty, path: &[&str]) -> bool {
match ty.sty { match ty.sty {
ty::TyAdt(adt, _) => match_def_path(cx, adt.did, path), ty::TyAdt(adt, _) => match_def_path(cx.tcx, adt.did, path),
_ => false, _ => false,
} }
} }
@ -182,14 +182,12 @@ pub fn match_type(cx: &LateContext, ty: ty::Ty, path: &[&str]) -> bool {
pub fn match_impl_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool { pub fn match_impl_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool {
let method_call = ty::MethodCall::expr(expr.id); let method_call = ty::MethodCall::expr(expr.id);
let trt_id = cx.tcx let trt_id = cx.tables
.tables
.borrow()
.method_map .method_map
.get(&method_call) .get(&method_call)
.and_then(|callee| cx.tcx.impl_of_method(callee.def_id)); .and_then(|callee| cx.tcx.impl_of_method(callee.def_id));
if let Some(trt_id) = trt_id { if let Some(trt_id) = trt_id {
match_def_path(cx, trt_id, path) match_def_path(cx.tcx, trt_id, path)
} else { } else {
false false
} }
@ -199,14 +197,12 @@ pub fn match_impl_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool {
pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool { pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool {
let method_call = ty::MethodCall::expr(expr.id); let method_call = ty::MethodCall::expr(expr.id);
let trt_id = cx.tcx let trt_id = cx.tables
.tables
.borrow()
.method_map .method_map
.get(&method_call) .get(&method_call)
.and_then(|callee| cx.tcx.trait_of_item(callee.def_id)); .and_then(|callee| cx.tcx.trait_of_item(callee.def_id));
if let Some(trt_id) = trt_id { if let Some(trt_id) = trt_id {
match_def_path(cx, trt_id, path) match_def_path(cx.tcx, trt_id, path)
} else { } else {
false false
} }
@ -327,7 +323,7 @@ pub fn implements_trait<'a, 'tcx>(
cx.tcx.populate_implementations_for_trait_if_necessary(trait_id); cx.tcx.populate_implementations_for_trait_if_necessary(trait_id);
let ty = cx.tcx.erase_regions(&ty); let ty = cx.tcx.erase_regions(&ty);
cx.tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| { cx.tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
let obligation = cx.tcx.predicate_for_trait_def(traits::ObligationCause::dummy(), trait_id, 0, ty, &ty_params); let obligation = cx.tcx.predicate_for_trait_def(traits::ObligationCause::dummy(), trait_id, 0, ty, &ty_params);
traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation) traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation)
@ -336,7 +332,7 @@ pub fn implements_trait<'a, 'tcx>(
/// Resolve the definition of a node from its `NodeId`. /// Resolve the definition of a node from its `NodeId`.
pub fn resolve_node(cx: &LateContext, qpath: &QPath, id: NodeId) -> def::Def { pub fn resolve_node(cx: &LateContext, qpath: &QPath, id: NodeId) -> def::Def {
cx.tcx.tables().qpath_def(qpath, id) cx.tables.qpath_def(qpath, id)
} }
/// Match an `Expr` against a chain of methods, and return the matched `Expr`s. /// Match an `Expr` against a chain of methods, and return the matched `Expr`s.
@ -622,7 +618,7 @@ pub fn is_integer_literal(expr: &Expr, value: u128) -> bool {
} }
pub fn is_adjusted(cx: &LateContext, e: &Expr) -> bool { pub fn is_adjusted(cx: &LateContext, e: &Expr) -> bool {
cx.tcx.tables.borrow().adjustments.get(&e.id).is_some() cx.tables.adjustments.get(&e.id).is_some()
} }
pub struct LimitStack { pub struct LimitStack {
@ -787,7 +783,7 @@ pub fn same_tys<'a, 'tcx>(
parameter_item: NodeId parameter_item: NodeId
) -> bool { ) -> bool {
let parameter_env = ty::ParameterEnvironment::for_item(cx.tcx, parameter_item); let parameter_env = ty::ParameterEnvironment::for_item(cx.tcx, parameter_item);
cx.tcx.infer_ctxt(None, Some(parameter_env), Reveal::All).enter(|infcx| { cx.tcx.infer_ctxt(parameter_env, Reveal::All).enter(|infcx| {
let new_a = a.subst(infcx.tcx, infcx.parameter_environment.free_substs); let new_a = a.subst(infcx.tcx, infcx.parameter_environment.free_substs);
let new_b = b.subst(infcx.tcx, infcx.parameter_environment.free_substs); let new_b = b.subst(infcx.tcx, infcx.parameter_environment.free_substs);
infcx.can_equate(&new_a, &new_b).is_ok() infcx.can_equate(&new_a, &new_b).is_ok()
@ -811,7 +807,7 @@ pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>, env: Node
/// Return whether a pattern is refutable. /// Return whether a pattern is refutable.
pub fn is_refutable(cx: &LateContext, pat: &Pat) -> bool { pub fn is_refutable(cx: &LateContext, pat: &Pat) -> bool {
fn is_enum_variant(cx: &LateContext, qpath: &QPath, did: NodeId) -> bool { fn is_enum_variant(cx: &LateContext, qpath: &QPath, did: NodeId) -> bool {
matches!(cx.tcx.tables().qpath_def(qpath, did), matches!(cx.tables.qpath_def(qpath, did),
def::Def::Variant(..) | def::Def::VariantCtor(..)) def::Def::Variant(..) | def::Def::VariantCtor(..))
} }

View File

@ -2,7 +2,7 @@ use rustc::hir::*;
use rustc::lint::*; use rustc::lint::*;
use rustc::ty; use rustc::ty;
use rustc_const_eval::EvalHint::ExprTypeChecked; use rustc_const_eval::EvalHint::ExprTypeChecked;
use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::ConstContext;
use syntax::codemap::Span; use syntax::codemap::Span;
use utils::{higher, is_copy, snippet, span_lint_and_then}; use utils::{higher, is_copy, snippet, span_lint_and_then};
@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
// search for `&vec![_]` expressions where the adjusted type is `&[_]` // search for `&vec![_]` expressions where the adjusted type is `&[_]`
if_let_chain!{[ if_let_chain!{[
let ty::TypeVariants::TyRef(_, ref ty) = cx.tcx.tables().expr_ty_adjusted(expr).sty, let ty::TypeVariants::TyRef(_, ref ty) = cx.tables.expr_ty_adjusted(expr).sty,
let ty::TypeVariants::TySlice(..) = ty.ty.sty, let ty::TypeVariants::TySlice(..) = ty.ty.sty,
let ExprAddrOf(_, ref addressee) = expr.node, let ExprAddrOf(_, ref addressee) = expr.node,
let Some(vec_args) = higher::vec_macro(cx, addressee), let Some(vec_args) = higher::vec_macro(cx, addressee),
@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
if_let_chain!{[ if_let_chain!{[
let Some((_, arg, _)) = higher::for_loop(expr), let Some((_, arg, _)) = higher::for_loop(expr),
let Some(vec_args) = higher::vec_macro(cx, arg), let Some(vec_args) = higher::vec_macro(cx, arg),
is_copy(cx, vec_type(cx.tcx.tables().expr_ty_adjusted(arg)), cx.tcx.map.get_parent(expr.id)), is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg)), cx.tcx.map.get_parent(expr.id)),
], { ], {
// report the error around the `vec!` not inside `<std macros>:` // report the error around the `vec!` not inside `<std macros>:`
let span = cx.sess().codemap().source_callsite(arg.span); let span = cx.sess().codemap().source_callsite(arg.span);
@ -60,7 +60,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_vec_macro(cx: &LateContext, vec_args: &higher::VecArgs, span: Span) { fn check_vec_macro(cx: &LateContext, vec_args: &higher::VecArgs, span: Span) {
let snippet = match *vec_args { let snippet = match *vec_args {
higher::VecArgs::Repeat(elem, len) => { higher::VecArgs::Repeat(elem, len) => {
if eval_const_expr_partial(cx.tcx, len, ExprTypeChecked, None).is_ok() { if ConstContext::with_tables(cx.tcx, cx.tables).eval(len, ExprTypeChecked).is_ok() {
format!("&[{}; {}]", snippet(cx, elem.span, "elem"), snippet(cx, len.span, "len")).into() format!("&[{}; {}]", snippet(cx, elem.span, "elem"), snippet(cx, len.span, "len")).into()
} else { } else {
return; return;

View File

@ -146,7 +146,7 @@ fn lots_of_short_circuits2() -> bool { //~ ERROR: the function has a cyclomatic
#[cyclomatic_complexity = "0"] #[cyclomatic_complexity = "0"]
fn baa() { //~ ERROR: the function has a cyclomatic complexity of 2 fn baa() { //~ ERROR: the function has a cyclomatic complexity of 2
let x = || match 99 { let x = || match 99 { //~ ERROR: the function has a cyclomatic complexity of 2
0 => 0, 0 => 0,
1 => 1, 1 => 1,
2 => 2, 2 => 2,